-
Notifications
You must be signed in to change notification settings - Fork 10
/
codec_test.go
94 lines (73 loc) · 2.42 KB
/
codec_test.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
// Copyright (c) HashiCorp, Inc
// SPDX-License-Identifier: MPL-2.0
package wal
import (
"bytes"
"testing"
"time"
fuzz "github.com/google/gofuzz"
"github.com/hashicorp/raft"
"github.com/stretchr/testify/require"
)
// TestBinaryCodecFuzz tests that our codec can decode whatever it encoded.
// Because we are using a reflection-based fuzzer to assign random values to all
// fields this test will also catch any changes in a later version of raft that
// add new fields since our codec will "loose" them.
func TestBinaryCodecFuzz(t *testing.T) {
rounds := 1000
f := fuzz.New().Funcs(
// Stub time since gofuzz generates unencodable times depending on your
// local timezone! On my computer in GMT timezone, it will generate Times
// that are unencodable for some reason I don't understand. All it's doing
// is picking a random UnixTimestamp but for some reason that is sometimes
// unencodable?
func(t *time.Time, c fuzz.Continue) {
// This is copied from fuzzTime in gofuzz but with a fix until it's
// accepted upstream.
var sec, nsec int64
// Allow for about 1000 years of random time values, which keeps things
// like JSON parsing reasonably happy.
sec = c.Rand.Int63n(1000 * 365 * 24 * 60 * 60)
nsec = c.Rand.Int63n(999_999_999)
*t = time.Unix(sec, nsec)
},
)
c := BinaryCodec{}
require.Equal(t, CodecBinaryV1, c.ID())
var buf bytes.Buffer
for i := 0; i < rounds; i++ {
var log, log2 raft.Log
f.Fuzz(&log)
buf.Reset()
err := c.Encode(&log, &buf)
require.NoError(t, err)
err = c.Decode(buf.Bytes(), &log2)
require.NoError(t, err)
t.Logf("log %#v. Binary: % x", log, buf.Bytes())
require.Equal(t, log, log2)
}
}
func TestBinaryCodecCopysOnDecode(t *testing.T) {
var in, out raft.Log
in.Index = 1234
in.Term = 2
in.Type = raft.LogCommand
in.Data = []byte("foo")
in.Extensions = []byte("ext")
c := BinaryCodec{}
var buf bytes.Buffer
require.NoError(t, c.Encode(&in, &buf))
rawBytes := buf.Bytes()
require.NoError(t, c.Decode(rawBytes, &out))
// Make sure the decoded data is the same
require.Equal(t, string(out.Data), "foo")
require.Equal(t, string(out.Extensions), "ext")
// Intentionally mangle the buffer contents
for i := 0; i < len(rawBytes); i++ {
rawBytes[i] = 'x'
}
// Make sure the decoded data is still the same (i.e. didn't refer to the
// underlying bytes)
require.Equal(t, string(out.Data), "foo")
require.Equal(t, string(out.Extensions), "ext")
}