kaspad/rpcmodel/register_test.go
stasatdaglabs f46dec449d [NOD-510] Change all references to Bitcoin to Kaspa (#531)
* [NOD-510] Change coinbase flags to kaspad.

* [NOD-510] Removed superfluous spaces after periods in comments.

* [NOD-510] Rename btcd -> kaspad in the root folder.

* [NOD-510] Rename BtcEncode -> KaspaEncode and BtcDecode -> KaspaDecode.

* [NOD-510] Rename BtcEncode -> KaspaEncode and BtcDecode -> KaspaDecode.

* [NOD-510] Continue renaming btcd -> kaspad.

* [NOD-510] Rename btcjson -> kaspajson.

* [NOD-510] Rename file names inside kaspajson.

* [NOD-510] Rename kaspajson -> jsonrpc.

* [NOD-510] Finish renaming in addrmgr.

* [NOD-510] Rename package btcec to ecc.

* [NOD-510] Finish renaming stuff in blockdag.

* [NOD-510] Rename stuff in cmd.

* [NOD-510] Rename stuff in config.

* [NOD-510] Rename stuff in connmgr.

* [NOD-510] Rename stuff in dagconfig.

* [NOD-510] Rename stuff in database.

* [NOD-510] Rename stuff in docker.

* [NOD-510] Rename stuff in integration.

* [NOD-510] Rename jsonrpc to rpcmodel.

* [NOD-510] Rename stuff in limits.

* [NOD-510] Rename stuff in logger.

* [NOD-510] Rename stuff in mempool.

* [NOD-510] Rename stuff in mining.

* [NOD-510] Rename stuff in netsync.

* [NOD-510] Rename stuff in peer.

* [NOD-510] Rename stuff in release.

* [NOD-510] Rename stuff in rpcclient.

* [NOD-510] Rename stuff in server.

* [NOD-510] Rename stuff in signal.

* [NOD-510] Rename stuff in txscript.

* [NOD-510] Rename stuff in util.

* [NOD-510] Rename stuff in wire.

* [NOD-510] Fix failing tests.

* [NOD-510] Fix merge errors.

* [NOD-510] Fix go vet errors.

* [NOD-510] Remove merged file that's no longer relevant.

* [NOD-510] Add a comment above Op0.

* [NOD-510] Fix some comments referencing Bitcoin Core.

* [NOD-510] Fix some more comments referencing Bitcoin Core.

* [NOD-510] Fix bitcoin -> kaspa.

* [NOD-510] Fix more bitcoin -> kaspa.

* [NOD-510] Fix comments, remove DisconnectBlock in addrindex.

* [NOD-510] Rename KSPD to KASD.

* [NOD-510] Fix comments and user agent.
2019-12-12 15:21:41 +02:00

263 lines
6.7 KiB
Go

// Copyright (c) 2014 The btcsuite developers
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.
package rpcmodel_test
import (
"reflect"
"sort"
"testing"
"github.com/kaspanet/kaspad/rpcmodel"
)
// TestUsageFlagStringer tests the stringized output for the UsageFlag type.
func TestUsageFlagStringer(t *testing.T) {
t.Parallel()
tests := []struct {
in rpcmodel.UsageFlag
want string
}{
{0, "0x0"},
{rpcmodel.UFWebsocketOnly, "UFWebsocketOnly"},
{rpcmodel.UFNotification, "UFNotification"},
{rpcmodel.UFWebsocketOnly | rpcmodel.UFNotification,
"UFWebsocketOnly|UFNotification"},
{rpcmodel.UFWebsocketOnly | rpcmodel.UFNotification | (1 << 31),
"UFWebsocketOnly|UFNotification|0x80000000"},
}
// Detect additional usage flags that don't have the stringer added.
numUsageFlags := 0
highestUsageFlagBit := rpcmodel.TstHighestUsageFlagBit
for highestUsageFlagBit > 1 {
numUsageFlags++
highestUsageFlagBit >>= 1
}
if len(tests)-3 != numUsageFlags {
t.Errorf("It appears a usage flag was added without adding " +
"an associated stringer test")
}
t.Logf("Running %d tests", len(tests))
for i, test := range tests {
result := test.in.String()
if result != test.want {
t.Errorf("String #%d\n got: %s want: %s", i, result,
test.want)
continue
}
}
}
// TestRegisterCmdErrors ensures the RegisterCmd function returns the expected
// error when provided with invalid types.
func TestRegisterCmdErrors(t *testing.T) {
t.Parallel()
tests := []struct {
name string
method string
cmdFunc func() interface{}
flags rpcmodel.UsageFlag
err rpcmodel.Error
}{
{
name: "duplicate method",
method: "getBlock",
cmdFunc: func() interface{} {
return struct{}{}
},
err: rpcmodel.Error{ErrorCode: rpcmodel.ErrDuplicateMethod},
},
{
name: "invalid usage flags",
method: "registerTestCmd",
cmdFunc: func() interface{} {
return 0
},
flags: rpcmodel.TstHighestUsageFlagBit,
err: rpcmodel.Error{ErrorCode: rpcmodel.ErrInvalidUsageFlags},
},
{
name: "invalid type",
method: "registerTestCmd",
cmdFunc: func() interface{} {
return 0
},
err: rpcmodel.Error{ErrorCode: rpcmodel.ErrInvalidType},
},
{
name: "invalid type 2",
method: "registerTestCmd",
cmdFunc: func() interface{} {
return &[]string{}
},
err: rpcmodel.Error{ErrorCode: rpcmodel.ErrInvalidType},
},
{
name: "embedded field",
method: "registerTestCmd",
cmdFunc: func() interface{} {
type test struct{ int }
return (*test)(nil)
},
err: rpcmodel.Error{ErrorCode: rpcmodel.ErrEmbeddedType},
},
{
name: "unexported field",
method: "registerTestCmd",
cmdFunc: func() interface{} {
type test struct{ a int }
return (*test)(nil)
},
err: rpcmodel.Error{ErrorCode: rpcmodel.ErrUnexportedField},
},
{
name: "unsupported field type 1",
method: "registerTestCmd",
cmdFunc: func() interface{} {
type test struct{ A **int }
return (*test)(nil)
},
err: rpcmodel.Error{ErrorCode: rpcmodel.ErrUnsupportedFieldType},
},
{
name: "unsupported field type 2",
method: "registerTestCmd",
cmdFunc: func() interface{} {
type test struct{ A chan int }
return (*test)(nil)
},
err: rpcmodel.Error{ErrorCode: rpcmodel.ErrUnsupportedFieldType},
},
{
name: "unsupported field type 3",
method: "registerTestCmd",
cmdFunc: func() interface{} {
type test struct{ A complex64 }
return (*test)(nil)
},
err: rpcmodel.Error{ErrorCode: rpcmodel.ErrUnsupportedFieldType},
},
{
name: "unsupported field type 4",
method: "registerTestCmd",
cmdFunc: func() interface{} {
type test struct{ A complex128 }
return (*test)(nil)
},
err: rpcmodel.Error{ErrorCode: rpcmodel.ErrUnsupportedFieldType},
},
{
name: "unsupported field type 5",
method: "registerTestCmd",
cmdFunc: func() interface{} {
type test struct{ A func() }
return (*test)(nil)
},
err: rpcmodel.Error{ErrorCode: rpcmodel.ErrUnsupportedFieldType},
},
{
name: "unsupported field type 6",
method: "registerTestCmd",
cmdFunc: func() interface{} {
type test struct{ A interface{} }
return (*test)(nil)
},
err: rpcmodel.Error{ErrorCode: rpcmodel.ErrUnsupportedFieldType},
},
{
name: "required after optional",
method: "registerTestCmd",
cmdFunc: func() interface{} {
type test struct {
A *int
B int
}
return (*test)(nil)
},
err: rpcmodel.Error{ErrorCode: rpcmodel.ErrNonOptionalField},
},
{
name: "non-optional with default",
method: "registerTestCmd",
cmdFunc: func() interface{} {
type test struct {
A int `jsonrpcdefault:"1"`
}
return (*test)(nil)
},
err: rpcmodel.Error{ErrorCode: rpcmodel.ErrNonOptionalDefault},
},
{
name: "mismatched default",
method: "registerTestCmd",
cmdFunc: func() interface{} {
type test struct {
A *int `jsonrpcdefault:"1.7"`
}
return (*test)(nil)
},
err: rpcmodel.Error{ErrorCode: rpcmodel.ErrMismatchedDefault},
},
}
t.Logf("Running %d tests", len(tests))
for i, test := range tests {
err := rpcmodel.RegisterCmd(test.method, test.cmdFunc(),
test.flags)
if reflect.TypeOf(err) != reflect.TypeOf(test.err) {
t.Errorf("Test #%d (%s) wrong error - got %T, "+
"want %T", i, test.name, err, test.err)
continue
}
gotErrorCode := err.(rpcmodel.Error).ErrorCode
if gotErrorCode != test.err.ErrorCode {
t.Errorf("Test #%d (%s) mismatched error code - got "+
"%v, want %v", i, test.name, gotErrorCode,
test.err.ErrorCode)
continue
}
}
}
// TestMustRegisterCmdPanic ensures the MustRegisterCommand function panics when
// used to register an invalid type.
func TestMustRegisterCmdPanic(t *testing.T) {
t.Parallel()
// Setup a defer to catch the expected panic to ensure it actually
// paniced.
defer func() {
if err := recover(); err == nil {
t.Error("MustRegisterCommand did not panic as expected")
}
}()
// Intentionally try to register an invalid type to force a panic.
rpcmodel.MustRegisterCommand("panicme", 0, 0)
}
// TestRegisteredCmdMethods tests the RegisteredCmdMethods function ensure it
// works as expected.
func TestRegisteredCmdMethods(t *testing.T) {
t.Parallel()
// Ensure the registered methods are returned.
methods := rpcmodel.RegisteredCmdMethods()
if len(methods) == 0 {
t.Fatal("RegisteredCmdMethods: no methods")
}
// Ensure the returned methods are sorted.
sortedMethods := make([]string, len(methods))
copy(sortedMethods, methods)
sort.Sort(sort.StringSlice(sortedMethods))
if !reflect.DeepEqual(sortedMethods, methods) {
t.Fatal("RegisteredCmdMethods: methods are not sorted")
}
}