lbcd/wire/netaddress_test.go
Dave Collins 2eef3720a9 Import btcwire repo into wire directory.
This commit contains the entire btcwire repository along with several
changes needed to move all of the files into the wire directory in
order to prepare it for merging.  This does NOT update btcd or any of the
other packages to use the new location as that will be done separately.

- All import paths in the old btcwire test files have been changed to the
  new location
- All references to btcwire as the package name have been chagned to
  wire
- The coveralls badge has been removed since it unfortunately doesn't
  support coverage of sub-packages

This is ongoing work toward #214.
2015-01-31 14:59:57 -06:00

294 lines
8.7 KiB
Go

// Copyright (c) 2013-2015 Conformal Systems LLC.
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.
package wire_test
import (
"bytes"
"io"
"net"
"reflect"
"testing"
"time"
"github.com/btcsuite/btcd/wire"
"github.com/davecgh/go-spew/spew"
)
// TestNetAddress tests the NetAddress API.
func TestNetAddress(t *testing.T) {
ip := net.ParseIP("127.0.0.1")
port := 8333
// Test NewNetAddress.
tcpAddr := &net.TCPAddr{
IP: ip,
Port: port,
}
na, err := wire.NewNetAddress(tcpAddr, 0)
if err != nil {
t.Errorf("NewNetAddress: %v", err)
}
// Ensure we get the same ip, port, and services back out.
if !na.IP.Equal(ip) {
t.Errorf("NetNetAddress: wrong ip - got %v, want %v", na.IP, ip)
}
if na.Port != uint16(port) {
t.Errorf("NetNetAddress: wrong port - got %v, want %v", na.Port,
port)
}
if na.Services != 0 {
t.Errorf("NetNetAddress: wrong services - got %v, want %v",
na.Services, 0)
}
if na.HasService(wire.SFNodeNetwork) {
t.Errorf("HasService: SFNodeNetwork service is set")
}
// Ensure adding the full service node flag works.
na.AddService(wire.SFNodeNetwork)
if na.Services != wire.SFNodeNetwork {
t.Errorf("AddService: wrong services - got %v, want %v",
na.Services, wire.SFNodeNetwork)
}
if !na.HasService(wire.SFNodeNetwork) {
t.Errorf("HasService: SFNodeNetwork service not set")
}
// Ensure max payload is expected value for latest protocol version.
pver := wire.ProtocolVersion
wantPayload := uint32(30)
maxPayload := wire.TstMaxNetAddressPayload(wire.ProtocolVersion)
if maxPayload != wantPayload {
t.Errorf("maxNetAddressPayload: wrong max payload length for "+
"protocol version %d - got %v, want %v", pver,
maxPayload, wantPayload)
}
// Protocol version before NetAddressTimeVersion when timestamp was
// added. Ensure max payload is expected value for it.
pver = wire.NetAddressTimeVersion - 1
wantPayload = 26
maxPayload = wire.TstMaxNetAddressPayload(pver)
if maxPayload != wantPayload {
t.Errorf("maxNetAddressPayload: wrong max payload length for "+
"protocol version %d - got %v, want %v", pver,
maxPayload, wantPayload)
}
// Check for expected failure on wrong address type.
udpAddr := &net.UDPAddr{}
_, err = wire.NewNetAddress(udpAddr, 0)
if err != wire.ErrInvalidNetAddr {
t.Errorf("NewNetAddress: expected error not received - "+
"got %v, want %v", err, wire.ErrInvalidNetAddr)
}
}
// TestNetAddressWire tests the NetAddress wire encode and decode for various
// protocol versions and timestamp flag combinations.
func TestNetAddressWire(t *testing.T) {
// baseNetAddr is used in the various tests as a baseline NetAddress.
baseNetAddr := wire.NetAddress{
Timestamp: time.Unix(0x495fab29, 0), // 2009-01-03 12:15:05 -0600 CST
Services: wire.SFNodeNetwork,
IP: net.ParseIP("127.0.0.1"),
Port: 8333,
}
// baseNetAddrNoTS is baseNetAddr with a zero value for the timestamp.
baseNetAddrNoTS := baseNetAddr
baseNetAddrNoTS.Timestamp = time.Time{}
// baseNetAddrEncoded is the wire encoded bytes of baseNetAddr.
baseNetAddrEncoded := []byte{
0x29, 0xab, 0x5f, 0x49, // Timestamp
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // SFNodeNetwork
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0xff, 0xff, 0x7f, 0x00, 0x00, 0x01, // IP 127.0.0.1
0x20, 0x8d, // Port 8333 in big-endian
}
// baseNetAddrNoTSEncoded is the wire encoded bytes of baseNetAddrNoTS.
baseNetAddrNoTSEncoded := []byte{
// No timestamp
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // SFNodeNetwork
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0xff, 0xff, 0x7f, 0x00, 0x00, 0x01, // IP 127.0.0.1
0x20, 0x8d, // Port 8333 in big-endian
}
tests := []struct {
in wire.NetAddress // NetAddress to encode
out wire.NetAddress // Expected decoded NetAddress
ts bool // Include timestamp?
buf []byte // Wire encoding
pver uint32 // Protocol version for wire encoding
}{
// Latest protocol version without ts flag.
{
baseNetAddr,
baseNetAddrNoTS,
false,
baseNetAddrNoTSEncoded,
wire.ProtocolVersion,
},
// Latest protocol version with ts flag.
{
baseNetAddr,
baseNetAddr,
true,
baseNetAddrEncoded,
wire.ProtocolVersion,
},
// Protocol version NetAddressTimeVersion without ts flag.
{
baseNetAddr,
baseNetAddrNoTS,
false,
baseNetAddrNoTSEncoded,
wire.NetAddressTimeVersion,
},
// Protocol version NetAddressTimeVersion with ts flag.
{
baseNetAddr,
baseNetAddr,
true,
baseNetAddrEncoded,
wire.NetAddressTimeVersion,
},
// Protocol version NetAddressTimeVersion-1 without ts flag.
{
baseNetAddr,
baseNetAddrNoTS,
false,
baseNetAddrNoTSEncoded,
wire.NetAddressTimeVersion - 1,
},
// Protocol version NetAddressTimeVersion-1 with timestamp.
// Even though the timestamp flag is set, this shouldn't have a
// timestamp since it is a protocol version before it was
// added.
{
baseNetAddr,
baseNetAddrNoTS,
true,
baseNetAddrNoTSEncoded,
wire.NetAddressTimeVersion - 1,
},
}
t.Logf("Running %d tests", len(tests))
for i, test := range tests {
// Encode to wire format.
var buf bytes.Buffer
err := wire.TstWriteNetAddress(&buf, test.pver, &test.in, test.ts)
if err != nil {
t.Errorf("writeNetAddress #%d error %v", i, err)
continue
}
if !bytes.Equal(buf.Bytes(), test.buf) {
t.Errorf("writeNetAddress #%d\n got: %s want: %s", i,
spew.Sdump(buf.Bytes()), spew.Sdump(test.buf))
continue
}
// Decode the message from wire format.
var na wire.NetAddress
rbuf := bytes.NewReader(test.buf)
err = wire.TstReadNetAddress(rbuf, test.pver, &na, test.ts)
if err != nil {
t.Errorf("readNetAddress #%d error %v", i, err)
continue
}
if !reflect.DeepEqual(na, test.out) {
t.Errorf("readNetAddress #%d\n got: %s want: %s", i,
spew.Sdump(na), spew.Sdump(test.out))
continue
}
}
}
// TestNetAddressWireErrors performs negative tests against wire encode and
// decode NetAddress to confirm error paths work correctly.
func TestNetAddressWireErrors(t *testing.T) {
pver := wire.ProtocolVersion
pverNAT := wire.NetAddressTimeVersion - 1
// baseNetAddr is used in the various tests as a baseline NetAddress.
baseNetAddr := wire.NetAddress{
Timestamp: time.Unix(0x495fab29, 0), // 2009-01-03 12:15:05 -0600 CST
Services: wire.SFNodeNetwork,
IP: net.ParseIP("127.0.0.1"),
Port: 8333,
}
tests := []struct {
in *wire.NetAddress // Value to encode
buf []byte // Wire encoding
pver uint32 // Protocol version for wire encoding
ts bool // Include timestamp flag
max int // Max size of fixed buffer to induce errors
writeErr error // Expected write error
readErr error // Expected read error
}{
// Latest protocol version with timestamp and intentional
// read/write errors.
// Force errors on timestamp.
{&baseNetAddr, []byte{}, pver, true, 0, io.ErrShortWrite, io.EOF},
// Force errors on services.
{&baseNetAddr, []byte{}, pver, true, 4, io.ErrShortWrite, io.EOF},
// Force errors on ip.
{&baseNetAddr, []byte{}, pver, true, 12, io.ErrShortWrite, io.EOF},
// Force errors on port.
{&baseNetAddr, []byte{}, pver, true, 28, io.ErrShortWrite, io.EOF},
// Latest protocol version with no timestamp and intentional
// read/write errors.
// Force errors on services.
{&baseNetAddr, []byte{}, pver, false, 0, io.ErrShortWrite, io.EOF},
// Force errors on ip.
{&baseNetAddr, []byte{}, pver, false, 8, io.ErrShortWrite, io.EOF},
// Force errors on port.
{&baseNetAddr, []byte{}, pver, false, 24, io.ErrShortWrite, io.EOF},
// Protocol version before NetAddressTimeVersion with timestamp
// flag set (should not have timestamp due to old protocol
// version) and intentional read/write errors.
// Force errors on services.
{&baseNetAddr, []byte{}, pverNAT, true, 0, io.ErrShortWrite, io.EOF},
// Force errors on ip.
{&baseNetAddr, []byte{}, pverNAT, true, 8, io.ErrShortWrite, io.EOF},
// Force errors on port.
{&baseNetAddr, []byte{}, pverNAT, true, 24, io.ErrShortWrite, io.EOF},
}
t.Logf("Running %d tests", len(tests))
for i, test := range tests {
// Encode to wire format.
w := newFixedWriter(test.max)
err := wire.TstWriteNetAddress(w, test.pver, test.in, test.ts)
if err != test.writeErr {
t.Errorf("writeNetAddress #%d wrong error got: %v, want: %v",
i, err, test.writeErr)
continue
}
// Decode from wire format.
var na wire.NetAddress
r := newFixedReader(test.max, test.buf)
err = wire.TstReadNetAddress(r, test.pver, &na, test.ts)
if err != test.readErr {
t.Errorf("readNetAddress #%d wrong error got: %v, want: %v",
i, err, test.readErr)
continue
}
}
}