github.com/btcsuite/btcd@v0.24.0/btcjson/btcdextcmds_test.go (about)

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