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