github.com/btcsuite/btcd@v0.24.0/wire/msgping_test.go (about)

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