1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package wal
16
17 import (
18 "bytes"
19 "errors"
20 "hash/crc32"
21 "io"
22 "os"
23 "reflect"
24 "testing"
25
26 "go.etcd.io/etcd/client/pkg/v3/fileutil"
27 "go.etcd.io/etcd/server/v3/wal/walpb"
28 )
29
30 var (
31 infoData = []byte("\b\xef\xfd\x02")
32 infoRecord = append([]byte("\x0e\x00\x00\x00\x00\x00\x00\x00\b\x01\x10\x99\xb5\xe4\xd0\x03\x1a\x04"), infoData...)
33 )
34
35 func TestReadRecord(t *testing.T) {
36 badInfoRecord := make([]byte, len(infoRecord))
37 copy(badInfoRecord, infoRecord)
38 badInfoRecord[len(badInfoRecord)-1] = 'a'
39
40 tests := []struct {
41 data []byte
42 wr *walpb.Record
43 we error
44 }{
45 {infoRecord, &walpb.Record{Type: 1, Crc: crc32.Checksum(infoData, crcTable), Data: infoData}, nil},
46 {[]byte(""), &walpb.Record{}, io.EOF},
47 {infoRecord[:14], &walpb.Record{}, io.ErrUnexpectedEOF},
48 {infoRecord[:len(infoRecord)-len(infoData)], &walpb.Record{}, io.ErrUnexpectedEOF},
49 {infoRecord[:len(infoRecord)-8], &walpb.Record{}, io.ErrUnexpectedEOF},
50 {badInfoRecord, &walpb.Record{}, walpb.ErrCRCMismatch},
51 }
52
53 rec := &walpb.Record{}
54 for i, tt := range tests {
55 buf := bytes.NewBuffer(tt.data)
56 f, err := createFileWithData(t, buf)
57 if err != nil {
58 t.Errorf("Unexpected error: %v", err)
59 }
60 decoder := newDecoder(fileutil.NewFileReader(f))
61 e := decoder.decode(rec)
62 if !reflect.DeepEqual(rec, tt.wr) {
63 t.Errorf("#%d: block = %v, want %v", i, rec, tt.wr)
64 }
65 if !errors.Is(e, tt.we) {
66 t.Errorf("#%d: err = %v, want %v", i, e, tt.we)
67 }
68 rec = &walpb.Record{}
69 }
70 }
71
72 func TestWriteRecord(t *testing.T) {
73 b := &walpb.Record{}
74 typ := int64(0xABCD)
75 d := []byte("Hello world!")
76 buf := new(bytes.Buffer)
77 e := newEncoder(buf, 0, 0)
78 e.encode(&walpb.Record{Type: typ, Data: d})
79 e.flush()
80 f, err := createFileWithData(t, buf)
81 if err != nil {
82 t.Errorf("Unexpected error: %v", err)
83 }
84 decoder := newDecoder(fileutil.NewFileReader(f))
85 err = decoder.decode(b)
86 if err != nil {
87 t.Errorf("err = %v, want nil", err)
88 }
89 if b.Type != typ {
90 t.Errorf("type = %d, want %d", b.Type, typ)
91 }
92 if !reflect.DeepEqual(b.Data, d) {
93 t.Errorf("data = %v, want %v", b.Data, d)
94 }
95 }
96
97 func createFileWithData(t *testing.T, bf *bytes.Buffer) (*os.File, error) {
98 f, err := os.CreateTemp(t.TempDir(), "wal")
99 if err != nil {
100 return nil, err
101 }
102 if _, err := f.Write(bf.Bytes()); err != nil {
103 return nil, err
104 }
105 f.Seek(0, 0)
106 return f, nil
107 }
108
View as plain text