// TestVarIntWireErrors performs negative tests against wire encode and decode // of variable length integers to confirm error paths work correctly. func TestVarIntWireErrors(t *testing.T) { pver := btcwire.ProtocolVersion tests := []struct { in uint64 // Value to encode buf []byte // Wire encoding pver uint32 // Protocol version for wire encoding max int // Max size of fixed buffer to induce errors writeErr error // Expected write error readErr error // Expected read error }{ // Latest protocol version with intentional read/write errors. // Force errors on discriminant. {0, []byte{0x00}, pver, 0, io.ErrShortWrite, io.EOF}, // Force errors on 2-byte read/write. {0xfd, []byte{0xfd}, pver, 2, io.ErrShortWrite, io.ErrUnexpectedEOF}, // Force errors on 4-byte read/write. {0x10000, []byte{0xfe}, pver, 2, io.ErrShortWrite, io.ErrUnexpectedEOF}, // Force errors on 8-byte read/write. {0x100000000, []byte{0xff}, pver, 2, io.ErrShortWrite, io.ErrUnexpectedEOF}, } t.Logf("Running %d tests", len(tests)) for i, test := range tests { // Encode to wire format. w := newFixedWriter(test.max) err := btcwire.TstWriteVarInt(w, test.pver, test.in) if err != test.writeErr { t.Errorf("writeVarInt #%d wrong error got: %v, want: %v", i, err, test.writeErr) continue } // Decode from wire format. r := newFixedReader(test.max, test.buf) _, err = btcwire.TstReadVarInt(r, test.pver) if err != test.readErr { t.Errorf("readVarInt #%d wrong error got: %v, want: %v", i, err, test.readErr) continue } } }
// TestVarIntWire tests wire encode and decode for variable length integers. func TestVarIntWire(t *testing.T) { pver := btcwire.ProtocolVersion tests := []struct { in uint64 // Value to encode out uint64 // Expected decoded value buf []byte // Wire encoding pver uint32 // Protocol version for wire encoding }{ // Latest protocol version. // Single byte {0, 0, []byte{0x00}, pver}, // Max single byte {0xfc, 0xfc, []byte{0xfc}, pver}, // Min 2-byte {0xfd, 0xfd, []byte{0xfd, 0x0fd, 0x00}, pver}, // Max 2-byte {0xffff, 0xffff, []byte{0xfd, 0xff, 0xff}, pver}, // Min 4-byte {0x10000, 0x10000, []byte{0xfe, 0x00, 0x00, 0x01, 0x00}, pver}, // Max 4-byte {0xffffffff, 0xffffffff, []byte{0xfe, 0xff, 0xff, 0xff, 0xff}, pver}, // Min 8-byte { 0x100000000, 0x100000000, []byte{0xff, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00}, pver, }, // Max 8-byte { 0xffffffffffffffff, 0xffffffffffffffff, []byte{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}, pver, }, } t.Logf("Running %d tests", len(tests)) for i, test := range tests { // Encode to wire format. var buf bytes.Buffer err := btcwire.TstWriteVarInt(&buf, test.pver, test.in) if err != nil { t.Errorf("writeVarInt #%d error %v", i, err) continue } if !bytes.Equal(buf.Bytes(), test.buf) { t.Errorf("writeVarInt #%d\n got: %s want: %s", i, spew.Sdump(buf.Bytes()), spew.Sdump(test.buf)) continue } // Decode from wire format. rbuf := bytes.NewBuffer(test.buf) val, err := btcwire.TstReadVarInt(rbuf, test.pver) if err != nil { t.Errorf("readVarInt #%d error %v", i, err) continue } if val != test.out { t.Errorf("readVarInt #%d\n got: %d want: %d", i, val, test.out) continue } } }
// BenchmarkReadVarInt9 performs a benchmark on how long it takes to read // a nine byte variable length integer. func BenchmarkReadVarInt9(b *testing.B) { buf := []byte{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff} for i := 0; i < b.N; i++ { btcwire.TstReadVarInt(bytes.NewBuffer(buf), 0) } }
// BenchmarkReadVarInt1 performs a benchmark on how long it takes to read // a single byte variable length integer. func BenchmarkReadVarInt1(b *testing.B) { buf := []byte{0x01} for i := 0; i < b.N; i++ { btcwire.TstReadVarInt(bytes.NewReader(buf), 0) } }