github.com/ethereum/go-ethereum@v1.14.3/internal/era/e2store/e2store_test.go (about) 1 // Copyright 2023 The go-ethereum Authors 2 // This file is part of go-ethereum. 3 // 4 // go-ethereum is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // go-ethereum is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU General Public License for more details. 13 // 14 // You should have received a copy of the GNU General Public License 15 // along with go-ethereum. If not, see <http://www.gnu.org/licenses/>. 16 17 package e2store 18 19 import ( 20 "bytes" 21 "errors" 22 "io" 23 "testing" 24 25 "github.com/ethereum/go-ethereum/common" 26 ) 27 28 func TestEncode(t *testing.T) { 29 for _, test := range []struct { 30 entries []Entry 31 want string 32 name string 33 }{ 34 { 35 name: "emptyEntry", 36 entries: []Entry{{0xffff, nil}}, 37 want: "ffff000000000000", 38 }, 39 { 40 name: "beef", 41 entries: []Entry{{42, common.Hex2Bytes("beef")}}, 42 want: "2a00020000000000beef", 43 }, 44 { 45 name: "twoEntries", 46 entries: []Entry{ 47 {42, common.Hex2Bytes("beef")}, 48 {9, common.Hex2Bytes("abcdabcd")}, 49 }, 50 want: "2a00020000000000beef0900040000000000abcdabcd", 51 }, 52 } { 53 tt := test 54 t.Run(tt.name, func(t *testing.T) { 55 t.Parallel() 56 var ( 57 b = bytes.NewBuffer(nil) 58 w = NewWriter(b) 59 ) 60 for _, e := range tt.entries { 61 if _, err := w.Write(e.Type, e.Value); err != nil { 62 t.Fatalf("encoding error: %v", err) 63 } 64 } 65 if want, have := common.FromHex(tt.want), b.Bytes(); !bytes.Equal(want, have) { 66 t.Fatalf("encoding mismatch (want %x, have %x", want, have) 67 } 68 r := NewReader(bytes.NewReader(b.Bytes())) 69 for _, want := range tt.entries { 70 have, err := r.Read() 71 if err != nil { 72 t.Fatalf("decoding error: %v", err) 73 } 74 if have.Type != want.Type { 75 t.Fatalf("decoded entry does type mismatch (want %v, got %v)", want.Type, have.Type) 76 } 77 if !bytes.Equal(have.Value, want.Value) { 78 t.Fatalf("decoded entry does not match (want %#x, got %#x)", want.Value, have.Value) 79 } 80 } 81 }) 82 } 83 } 84 85 func TestDecode(t *testing.T) { 86 for i, tt := range []struct { 87 have string 88 err error 89 }{ 90 { // basic valid decoding 91 have: "ffff000000000000", 92 }, 93 { // basic invalid decoding 94 have: "ffff000000000001", 95 err: errors.New("reserved bytes are non-zero"), 96 }, 97 { // no more entries to read, returns EOF 98 have: "", 99 err: io.EOF, 100 }, 101 { // malformed type 102 have: "bad", 103 err: io.ErrUnexpectedEOF, 104 }, 105 { // malformed length 106 have: "badbeef", 107 err: io.ErrUnexpectedEOF, 108 }, 109 { // specified length longer than actual value 110 have: "beef010000000000", 111 err: io.ErrUnexpectedEOF, 112 }, 113 } { 114 r := NewReader(bytes.NewReader(common.FromHex(tt.have))) 115 if tt.err != nil { 116 _, err := r.Read() 117 if err == nil && tt.err != nil { 118 t.Fatalf("test %d, expected error, got none", i) 119 } 120 if err != nil && tt.err == nil { 121 t.Fatalf("test %d, expected no error, got %v", i, err) 122 } 123 if err != nil && tt.err != nil && err.Error() != tt.err.Error() { 124 t.Fatalf("expected error %v, got %v", tt.err, err) 125 } 126 continue 127 } 128 } 129 } 130 131 func FuzzCodec(f *testing.F) { 132 f.Fuzz(func(t *testing.T, input []byte) { 133 r := NewReader(bytes.NewReader(input)) 134 entry, err := r.Read() 135 if err != nil { 136 return 137 } 138 var ( 139 b = bytes.NewBuffer(nil) 140 w = NewWriter(b) 141 ) 142 w.Write(entry.Type, entry.Value) 143 output := b.Bytes() 144 // Only care about the input that was actually consumed 145 input = input[:r.offset] 146 if !bytes.Equal(input, output) { 147 t.Fatalf("decode-encode mismatch, input %#x output %#x", input, output) 148 } 149 }) 150 }