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