btcdextcmds_test.go raw
1 package btcjson_test
2
3 import (
4 "bytes"
5 "encoding/json"
6 "fmt"
7 "reflect"
8 "testing"
9
10 "github.com/p9c/p9/pkg/btcjson"
11 )
12
13 // TestPodExtCmds tests all of the pod extended commands marshal and unmarshal into valid results include handling of
14 // optional fields being omitted in the marshalled command, while optional fields with defaults have the default
15 // assigned on unmarshalled commands.
16 func TestPodExtCmds(t *testing.T) {
17 t.Parallel()
18 testID := 1
19 tests := []struct {
20 name string
21 newCmd func() (interface{}, error)
22 staticCmd func() interface{}
23 marshalled string
24 unmarshalled interface{}
25 }{
26 {
27 name: "debuglevel",
28 newCmd: func() (interface{}, error) {
29 return btcjson.NewCmd("debuglevel", "trace")
30 },
31 staticCmd: func() interface{} {
32 return btcjson.NewDebugLevelCmd("trace")
33 },
34 marshalled: `{"jsonrpc":"1.0","method":"debuglevel","netparams":["trace"],"id":1}`,
35 unmarshalled: &btcjson.DebugLevelCmd{
36 LevelSpec: "trace",
37 },
38 },
39 {
40 name: "node",
41 newCmd: func() (interface{}, error) {
42 return btcjson.NewCmd("node", btcjson.NRemove, "1.1.1.1")
43 },
44 staticCmd: func() interface{} {
45 return btcjson.NewNodeCmd("remove", "1.1.1.1", nil)
46 },
47 marshalled: `{"jsonrpc":"1.0","method":"node","netparams":["remove","1.1.1.1"],"id":1}`,
48 unmarshalled: &btcjson.NodeCmd{
49 SubCmd: btcjson.NRemove,
50 Target: "1.1.1.1",
51 },
52 },
53 {
54 name: "node",
55 newCmd: func() (interface{}, error) {
56 return btcjson.NewCmd("node", btcjson.NDisconnect, "1.1.1.1")
57 },
58 staticCmd: func() interface{} {
59 return btcjson.NewNodeCmd("disconnect", "1.1.1.1", nil)
60 },
61 marshalled: `{"jsonrpc":"1.0","method":"node","netparams":["disconnect","1.1.1.1"],"id":1}`,
62 unmarshalled: &btcjson.NodeCmd{
63 SubCmd: btcjson.NDisconnect,
64 Target: "1.1.1.1",
65 },
66 },
67 {
68 name: "node",
69 newCmd: func() (interface{}, error) {
70 return btcjson.NewCmd("node", btcjson.NConnect, "1.1.1.1", "perm")
71 },
72 staticCmd: func() interface{} {
73 return btcjson.NewNodeCmd("connect", "1.1.1.1", btcjson.String("perm"))
74 },
75 marshalled: `{"jsonrpc":"1.0","method":"node","netparams":["connect","1.1.1.1","perm"],"id":1}`,
76 unmarshalled: &btcjson.NodeCmd{
77 SubCmd: btcjson.NConnect,
78 Target: "1.1.1.1",
79 ConnectSubCmd: btcjson.String("perm"),
80 },
81 },
82 {
83 name: "node",
84 newCmd: func() (interface{}, error) {
85 return btcjson.NewCmd("node", btcjson.NConnect, "1.1.1.1", "temp")
86 },
87 staticCmd: func() interface{} {
88 return btcjson.NewNodeCmd("connect", "1.1.1.1", btcjson.String("temp"))
89 },
90 marshalled: `{"jsonrpc":"1.0","method":"node","netparams":["connect","1.1.1.1","temp"],"id":1}`,
91 unmarshalled: &btcjson.NodeCmd{
92 SubCmd: btcjson.NConnect,
93 Target: "1.1.1.1",
94 ConnectSubCmd: btcjson.String("temp"),
95 },
96 },
97 {
98 name: "generate",
99 newCmd: func() (interface{}, error) {
100 return btcjson.NewCmd("generate", 1)
101 },
102 staticCmd: func() interface{} {
103 return btcjson.NewGenerateCmd(1)
104 },
105 marshalled: `{"jsonrpc":"1.0","method":"generate","netparams":[1],"id":1}`,
106 unmarshalled: &btcjson.GenerateCmd{
107 NumBlocks: 1,
108 },
109 },
110 {
111 name: "getbestblock",
112 newCmd: func() (interface{}, error) {
113 return btcjson.NewCmd("getbestblock")
114 },
115 staticCmd: func() interface{} {
116 return btcjson.NewGetBestBlockCmd()
117 },
118 marshalled: `{"jsonrpc":"1.0","method":"getbestblock","netparams":[],"id":1}`,
119 unmarshalled: &btcjson.GetBestBlockCmd{},
120 },
121 {
122 name: "getcurrentnet",
123 newCmd: func() (interface{}, error) {
124 return btcjson.NewCmd("getcurrentnet")
125 },
126 staticCmd: func() interface{} {
127 return btcjson.NewGetCurrentNetCmd()
128 },
129 marshalled: `{"jsonrpc":"1.0","method":"getcurrentnet","netparams":[],"id":1}`,
130 unmarshalled: &btcjson.GetCurrentNetCmd{},
131 },
132 {
133 name: "getheaders",
134 newCmd: func() (interface{}, error) {
135 return btcjson.NewCmd("getheaders", []string{}, "")
136 },
137 staticCmd: func() interface{} {
138 return btcjson.NewGetHeadersCmd(
139 []string{},
140 "",
141 )
142 },
143 marshalled: `{"jsonrpc":"1.0","method":"getheaders","netparams":[[],""],"id":1}`,
144 unmarshalled: &btcjson.GetHeadersCmd{
145 BlockLocators: []string{},
146 HashStop: "",
147 },
148 },
149 {
150 name: "getheaders - with arguments",
151 newCmd: func() (interface{}, error) {
152 return btcjson.NewCmd("getheaders", []string{
153 "000000000000000001f1739002418e2f9a84c47a4fd2a0eb7a787a6b7dc12f16",
154 "0000000000000000026f4b7f56eef057b32167eb5ad9ff62006f1807b7336d10",
155 }, "000000000000000000ba33b33e1fad70b69e234fc24414dd47113bff38f523f7",
156 )
157 },
158 staticCmd: func() interface{} {
159 return btcjson.NewGetHeadersCmd(
160 []string{
161 "000000000000000001f1739002418e2f9a84c47a4fd2a0eb7a787a6b7dc12f16",
162 "0000000000000000026f4b7f56eef057b32167eb5ad9ff62006f1807b7336d10",
163 },
164 "000000000000000000ba33b33e1fad70b69e234fc24414dd47113bff38f523f7",
165 )
166 },
167 marshalled: `{"jsonrpc":"1.0","method":"getheaders",
168 "netparams":[["000000000000000001f1739002418e2f9a84c47a4fd2a0eb7a787a6b7dc12f16","0000000000000000026f4b7f56eef057b32167eb5ad9ff62006f1807b7336d10"],"000000000000000000ba33b33e1fad70b69e234fc24414dd47113bff38f523f7"],"id":1}`,
169 unmarshalled: &btcjson.GetHeadersCmd{
170 BlockLocators: []string{
171 "000000000000000001f1739002418e2f9a84c47a4fd2a0eb7a787a6b7dc12f16",
172 "0000000000000000026f4b7f56eef057b32167eb5ad9ff62006f1807b7336d10",
173 },
174 HashStop: "000000000000000000ba33b33e1fad70b69e234fc24414dd47113bff38f523f7",
175 },
176 },
177 {
178 name: "version",
179 newCmd: func() (interface{}, error) {
180 return btcjson.NewCmd("version")
181 },
182 staticCmd: func() interface{} {
183 return btcjson.NewVersionCmd()
184 },
185 marshalled: `{"jsonrpc":"1.0","method":"version","netparams":[],"id":1}`,
186 unmarshalled: &btcjson.VersionCmd{},
187 },
188 }
189 t.Logf("Running %d tests", len(tests))
190 for i, test := range tests {
191 // Marshal the command as created by the new static command creation function.
192 marshalled, e := btcjson.MarshalCmd(testID, test.staticCmd())
193 if e != nil {
194 t.Errorf("MarshalCmd #%d (%s) unexpected error: %v", i,
195 test.name, e,
196 )
197 continue
198 }
199 if !bytes.Equal(marshalled, []byte(test.marshalled)) {
200 t.Errorf("Test #%d (%s) unexpected marshalled data - "+
201 "got %s, want %s", i, test.name, marshalled,
202 test.marshalled,
203 )
204 continue
205 }
206 // Ensure the command is created without error via the generic new command creation function.
207 cmd, e := test.newCmd()
208 if e != nil {
209 t.Errorf("Test #%d (%s) unexpected NewCmd error: %v ",
210 i, test.name, e,
211 )
212 }
213 // Marshal the command as created by the generic new command creation function.
214 marshalled, e = btcjson.MarshalCmd(testID, cmd)
215 if e != nil {
216 t.Errorf("MarshalCmd #%d (%s) unexpected error: %v", i,
217 test.name, e,
218 )
219 continue
220 }
221 if !bytes.Equal(marshalled, []byte(test.marshalled)) {
222 t.Errorf("Test #%d (%s) unexpected marshalled data - "+
223 "got %s, want %s", i, test.name, marshalled,
224 test.marshalled,
225 )
226 continue
227 }
228 var request btcjson.Request
229 if e = json.Unmarshal(marshalled, &request); E.Chk(e) {
230 t.Errorf("Test #%d (%s) unexpected error while "+
231 "unmarshalling JSON-RPC request: %v", i,
232 test.name, e,
233 )
234 continue
235 }
236 cmd, e = btcjson.UnmarshalCmd(&request)
237 if e != nil {
238 t.Errorf("UnmarshalCmd #%d (%s) unexpected error: %v", i,
239 test.name, e,
240 )
241 continue
242 }
243 if !reflect.DeepEqual(cmd, test.unmarshalled) {
244 t.Errorf("Test #%d (%s) unexpected unmarshalled command "+
245 "- got %s, want %s", i, test.name,
246 fmt.Sprintf("(%T) %+[1]v", cmd),
247 fmt.Sprintf("(%T) %+[1]v\n", test.unmarshalled),
248 )
249 continue
250 }
251 }
252 }
253