diff options
Diffstat (limited to 'srv/pow/pow_test.go')
-rw-r--r-- | srv/pow/pow_test.go | 120 |
1 files changed, 120 insertions, 0 deletions
diff --git a/srv/pow/pow_test.go b/srv/pow/pow_test.go new file mode 100644 index 0000000..4bc4141 --- /dev/null +++ b/srv/pow/pow_test.go @@ -0,0 +1,120 @@ +package pow + +import ( + "encoding/hex" + "strconv" + "testing" + "time" + + "github.com/stretchr/testify/assert" + "github.com/tilinna/clock" +) + +func TestChallengeParams(t *testing.T) { + tests := []challengeParams{ + {}, + { + Target: 1, + ExpiresAt: 3, + }, + { + Target: 2, + ExpiresAt: -10, + Random: []byte{0, 1, 2}, + }, + { + Random: []byte{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}, + }, + } + + t.Run("marshal_unmarshal", func(t *testing.T) { + for i, test := range tests { + t.Run(strconv.Itoa(i), func(t *testing.T) { + b, err := test.MarshalBinary() + assert.NoError(t, err) + + var c2 challengeParams + assert.NoError(t, c2.UnmarshalBinary(b)) + assert.Equal(t, test, c2) + + b2, err := c2.MarshalBinary() + assert.NoError(t, err) + assert.Equal(t, b, b2) + }) + } + }) + + secret := []byte("shhh") + + t.Run("to_from_seed", func(t *testing.T) { + + for i, test := range tests { + t.Run(strconv.Itoa(i), func(t *testing.T) { + seed, err := newSeed(test, secret) + assert.NoError(t, err) + + // generating seed should be deterministic + seed2, err := newSeed(test, secret) + assert.NoError(t, err) + assert.Equal(t, seed, seed2) + + c, err := challengeParamsFromSeed(seed, secret) + assert.NoError(t, err) + assert.Equal(t, test, c) + }) + } + }) + + t.Run("malformed_seed", func(t *testing.T) { + tests := []string{ + "", + "01", + "0000", + "00374a1ad84d6b7a93e68042c1f850cbb100000000000000000000000000000102030405060708A0", // changed one byte from a good seed + } + + for i, test := range tests { + t.Run(strconv.Itoa(i), func(t *testing.T) { + seed, err := hex.DecodeString(test) + if err != nil { + panic(err) + } + + _, err = challengeParamsFromSeed(seed, secret) + assert.ErrorIs(t, errMalformedSeed, err) + }) + } + }) +} + +func TestManager(t *testing.T) { + clock := clock.NewMock(time.Now().Truncate(time.Hour)) + + store := NewMemoryStore(clock) + defer store.Close() + + mgr := NewManager(ManagerParams{ + Clock: clock, + Store: store, + Secret: []byte("shhhh"), + Target: 0x00FFFFFF, + ChallengeTimeout: 1 * time.Second, + }) + + { + c := mgr.NewChallenge() + solution := Solve(c) + assert.NoError(t, mgr.CheckSolution(c.Seed, solution)) + + // doing again should fail, the seed should already be marked as solved + assert.ErrorIs(t, mgr.CheckSolution(c.Seed, solution), ErrSeedSolved) + } + + { + c := mgr.NewChallenge() + solution := Solve(c) + clock.Add(2 * time.Second) + assert.ErrorIs(t, mgr.CheckSolution(c.Seed, solution), ErrExpiredSolution) + } + +} |