msgpong_test.go raw

   1  package wire
   2  
   3  import (
   4  	"bytes"
   5  	"io"
   6  	"reflect"
   7  	"testing"
   8  	
   9  	"github.com/davecgh/go-spew/spew"
  10  )
  11  
  12  // TestPongLatest tests the MsgPong API against the latest protocol version.
  13  func TestPongLatest(t *testing.T) {
  14  	enc := BaseEncoding
  15  	pver := ProtocolVersion
  16  	nonce, e := RandomUint64()
  17  	if e != nil {
  18  		t.Errorf("RandomUint64: error generating nonce: %v", e)
  19  	}
  20  	msg := NewMsgPong(nonce)
  21  	if msg.Nonce != nonce {
  22  		t.Errorf("NewMsgPong: wrong nonce - got %v, want %v",
  23  			msg.Nonce, nonce,
  24  		)
  25  	}
  26  	// Ensure the command is expected value.
  27  	wantCmd := "pong"
  28  	if cmd := msg.Command(); cmd != wantCmd {
  29  		t.Errorf("NewMsgPong: wrong command - got %v want %v",
  30  			cmd, wantCmd,
  31  		)
  32  	}
  33  	// Ensure max payload is expected value for latest protocol version.
  34  	wantPayload := uint32(8)
  35  	maxPayload := msg.MaxPayloadLength(pver)
  36  	if maxPayload != wantPayload {
  37  		t.Errorf("MaxPayloadLength: wrong max payload length for "+
  38  			"protocol version %d - got %v, want %v", pver,
  39  			maxPayload, wantPayload,
  40  		)
  41  	}
  42  	// Test encode with latest protocol version.
  43  	var buf bytes.Buffer
  44  	e = msg.BtcEncode(&buf, pver, enc)
  45  	if e != nil {
  46  		t.Errorf("encode of MsgPong failed %v e <%v>", msg, e)
  47  	}
  48  	// Test decode with latest protocol version.
  49  	readmsg := NewMsgPong(0)
  50  	e = readmsg.BtcDecode(&buf, pver, enc)
  51  	if e != nil {
  52  		t.Errorf("decode of MsgPong failed [%v] e <%v>", buf, e)
  53  	}
  54  	// Ensure nonce is the same.
  55  	if msg.Nonce != readmsg.Nonce {
  56  		t.Errorf("Should get same nonce for protocol version %d", pver)
  57  	}
  58  }
  59  
  60  // TestPongBIP0031 tests the MsgPong API against the protocol version BIP0031Version.
  61  func TestPongBIP0031(t *testing.T) {
  62  	// Use the protocol version just prior to BIP0031Version changes.
  63  	pver := BIP0031Version
  64  	enc := BaseEncoding
  65  	nonce, e := RandomUint64()
  66  	if e != nil {
  67  		t.Errorf("Error generating nonce: %v", e)
  68  	}
  69  	msg := NewMsgPong(nonce)
  70  	if msg.Nonce != nonce {
  71  		t.Errorf("Should get same nonce back out.")
  72  	}
  73  	// Ensure max payload is expected value for old protocol version.
  74  	size := msg.MaxPayloadLength(pver)
  75  	if size != 0 {
  76  		t.Errorf("Max length should be 0 for pong protocol version %d.",
  77  			pver,
  78  		)
  79  	}
  80  	// Test encode with old protocol version.
  81  	var buf bytes.Buffer
  82  	e = msg.BtcEncode(&buf, pver, enc)
  83  	if e == nil {
  84  		t.Errorf("encode of MsgPong succeeded when it shouldn't have %v",
  85  			msg,
  86  		)
  87  	}
  88  	// Test decode with old protocol version.
  89  	readmsg := NewMsgPong(0)
  90  	e = readmsg.BtcDecode(&buf, pver, enc)
  91  	if e == nil {
  92  		t.Errorf("decode of MsgPong succeeded when it shouldn't have %v",
  93  			spew.Sdump(buf),
  94  		)
  95  	}
  96  	// Since this protocol version doesn't support pong, make sure the nonce didn't get encoded and decoded back out.
  97  	if msg.Nonce == readmsg.Nonce {
  98  		t.Errorf("Should not get same nonce for protocol version %d", pver)
  99  	}
 100  }
 101  
 102  // TestPongCrossProtocol tests the MsgPong API when encoding with the latest protocol version and decoding with
 103  // BIP0031Version.
 104  func TestPongCrossProtocol(t *testing.T) {
 105  	nonce, e := RandomUint64()
 106  	if e != nil {
 107  		t.Errorf("Error generating nonce: %v", e)
 108  	}
 109  	msg := NewMsgPong(nonce)
 110  	if msg.Nonce != nonce {
 111  		t.Errorf("Should get same nonce back out.")
 112  	}
 113  	// Encode with latest protocol version.
 114  	var buf bytes.Buffer
 115  	e = msg.BtcEncode(&buf, ProtocolVersion, BaseEncoding)
 116  	if e != nil {
 117  		t.Errorf("encode of MsgPong failed %v e <%v>", msg, e)
 118  	}
 119  	// Decode with old protocol version.
 120  	readmsg := NewMsgPong(0)
 121  	e = readmsg.BtcDecode(&buf, BIP0031Version, BaseEncoding)
 122  	if e == nil {
 123  		t.Errorf("encode of MsgPong succeeded when it shouldn't have %v",
 124  			msg,
 125  		)
 126  	}
 127  	// Since one of the protocol versions doesn't support the pong message, make sure the nonce didn't get encoded and
 128  	// decoded back out.
 129  	if msg.Nonce == readmsg.Nonce {
 130  		t.Error("Should not get same nonce for cross protocol")
 131  	}
 132  }
 133  
 134  // TestPongWire tests the MsgPong wire encode and decode for various protocol versions.
 135  func TestPongWire(t *testing.T) {
 136  	tests := []struct {
 137  		in   MsgPong         // Message to encode
 138  		out  MsgPong         // Expected decoded message
 139  		buf  []byte          // Wire encoding
 140  		pver uint32          // Protocol version for wire encoding
 141  		enc  MessageEncoding // Message encoding format
 142  	}{
 143  		// Latest protocol version.
 144  		{
 145  			MsgPong{Nonce: 123123}, // 0x1e0f3
 146  			MsgPong{Nonce: 123123}, // 0x1e0f3
 147  			[]byte{0xf3, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00},
 148  			ProtocolVersion,
 149  			BaseEncoding,
 150  		},
 151  		// Protocol version BIP0031Version+1
 152  		{
 153  			MsgPong{Nonce: 456456}, // 0x6f708
 154  			MsgPong{Nonce: 456456}, // 0x6f708
 155  			[]byte{0x08, 0xf7, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00},
 156  			BIP0031Version + 1,
 157  			BaseEncoding,
 158  		},
 159  	}
 160  	t.Logf("Running %d tests", len(tests))
 161  	for i, test := range tests {
 162  		// Encode the message to wire format.
 163  		var buf bytes.Buffer
 164  		e := test.in.BtcEncode(&buf, test.pver, test.enc)
 165  		if e != nil {
 166  			t.Errorf("BtcEncode #%d error %v", i, e)
 167  			continue
 168  		}
 169  		if !bytes.Equal(buf.Bytes(), test.buf) {
 170  			t.Errorf("BtcEncode #%d\n got: %s want: %s", i,
 171  				spew.Sdump(buf.Bytes()), spew.Sdump(test.buf),
 172  			)
 173  			continue
 174  		}
 175  		// Decode the message from wire format.
 176  		var msg MsgPong
 177  		rbuf := bytes.NewReader(test.buf)
 178  		e = msg.BtcDecode(rbuf, test.pver, test.enc)
 179  		if e != nil {
 180  			t.Errorf("BtcDecode #%d error %v", i, e)
 181  			continue
 182  		}
 183  		if !reflect.DeepEqual(msg, test.out) {
 184  			t.Errorf("BtcDecode #%d\n got: %s want: %s", i,
 185  				spew.Sdump(msg), spew.Sdump(test.out),
 186  			)
 187  			continue
 188  		}
 189  	}
 190  }
 191  
 192  // TestPongWireErrors performs negative tests against wire encode and decode of MsgPong to confirm error paths work
 193  // correctly.
 194  func TestPongWireErrors(t *testing.T) {
 195  	pver := ProtocolVersion
 196  	pverNoPong := BIP0031Version
 197  	wireErr := &MessageError{}
 198  	basePong := NewMsgPong(123123) // 0x1e0f3
 199  	basePongEncoded := []byte{
 200  		0xf3, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
 201  	}
 202  	tests := []struct {
 203  		in       *MsgPong        // value to encode
 204  		buf      []byte          // Wire encoding
 205  		pver     uint32          // Protocol version for wire encoding
 206  		enc      MessageEncoding // Message encoding format
 207  		max      int             // Max size of fixed buffer to induce errors
 208  		writeErr error           // Expected write error
 209  		readErr  error           // Expected read error
 210  	}{
 211  		// Latest protocol version with intentional read/write errors. Force error in nonce.
 212  		{basePong, basePongEncoded, pver, BaseEncoding, 0, io.ErrShortWrite, io.EOF},
 213  		// Force error due to unsupported protocol version.
 214  		{basePong, basePongEncoded, pverNoPong, BaseEncoding, 4, wireErr, wireErr},
 215  	}
 216  	t.Logf("Running %d tests", len(tests))
 217  	for i, test := range tests {
 218  		// Encode to wire format.
 219  		w := newFixedWriter(test.max)
 220  		e := test.in.BtcEncode(w, test.pver, test.enc)
 221  		if reflect.TypeOf(e) != reflect.TypeOf(test.writeErr) {
 222  			t.Errorf("BtcEncode #%d wrong error got: %v, want: %v",
 223  				i, e, test.writeErr,
 224  			)
 225  			continue
 226  		}
 227  		// For errors which are not of type MessageError, check them for equality.
 228  		if _, ok := e.(*MessageError); !ok {
 229  			if e != test.writeErr {
 230  				t.Errorf("BtcEncode #%d wrong error got: %v, "+
 231  					"want: %v", i, e, test.writeErr,
 232  				)
 233  				continue
 234  			}
 235  		}
 236  		// Decode from wire format.
 237  		var msg MsgPong
 238  		r := newFixedReader(test.max, test.buf)
 239  		e = msg.BtcDecode(r, test.pver, test.enc)
 240  		if reflect.TypeOf(e) != reflect.TypeOf(test.readErr) {
 241  			t.Errorf("BtcDecode #%d wrong error got: %v, want: %v",
 242  				i, e, test.readErr,
 243  			)
 244  			continue
 245  		}
 246  		// For errors which are not of type MessageError, check them for equality.
 247  		if _, ok := e.(*MessageError); !ok {
 248  			if e != test.readErr {
 249  				t.Errorf("BtcDecode #%d wrong error got: %v, "+
 250  					"want: %v", i, e, test.readErr,
 251  				)
 252  				continue
 253  			}
 254  		}
 255  	}
 256  }
 257