github.com/ethereumproject/go-ethereum@v5.5.2+incompatible/cmd/geth/apicmd_test.go (about) 1 package main 2 3 import ( 4 "errors" 5 "flag" 6 "fmt" 7 "strings" 8 "testing" 9 10 "gopkg.in/urfave/cli.v1" 11 12 "github.com/ethereumproject/go-ethereum/rpc" 13 ) 14 15 const errorMsg = "client returned error" 16 const errorCode = 123 17 18 type fakeClient struct { 19 returnError bool 20 recvError bool 21 } 22 23 func (f *fakeClient) SupportedModules() (map[string]string, error) { 24 if f.returnError { 25 return nil, errors.New(errorMsg) 26 } 27 return map[string]string{ 28 "validModule": "1.0", 29 "otherModule": "2.0", 30 "thirdModule": "1.1", 31 "lastModule": "1.0", 32 }, nil 33 } 34 35 func (f *fakeClient) Send(req interface{}) error { 36 // noop 37 if f.returnError { 38 return errors.New(errorMsg) 39 } 40 return nil 41 } 42 43 func (f *fakeClient) Recv(msg interface{}) error { 44 // noop 45 if f.returnError { 46 return errors.New(errorMsg) 47 } 48 49 switch msg.(type) { 50 case *rpc.JSONResponse: 51 if f.recvError { 52 msg.(*rpc.JSONResponse).Error = &rpc.JSONError{Code: errorCode, Message: errorMsg} 53 } else { 54 msg.(*rpc.JSONResponse).Result = "fake result" 55 } 56 } 57 58 return nil 59 } 60 61 func (f *fakeClient) Close() { 62 // noop 63 } 64 65 func TestValidateArguments(t *testing.T) { 66 var testCases = []struct { 67 input []string // input arguments 68 expected string // error message or "" 69 }{ 70 {[]string{"validModule", "someMethod"}, ""}, 71 {[]string{"validModule", "someMethod", "arg"}, ""}, 72 {[]string{"validModule", "someMethod", "arg1", "arg2"}, ""}, 73 {[]string{"thirdModule", "someMethod"}, ""}, 74 {[]string{"invalidModule", "someMethod"}, "unknown API module: invalidModule"}, 75 {[]string{}, "api command requires at least 2 arguments (module and method), 0 provided"}, 76 {[]string{"validModule"}, "api command requires at least 2 arguments (module and method), 1 provided"}, 77 } 78 79 client := &fakeClient{false, false} 80 81 for _, tc := range testCases { 82 t.Run(strings.Join(tc.input, ","), func(t *testing.T) { 83 ctx := createContext(tc.input) 84 err := validateArguments(ctx, client) 85 if err != nil { 86 if tc.expected != err.Error() { 87 t.Fatalf("Expected error: '%s', got '%s'", tc.expected, err.Error()) 88 } 89 } else { 90 if tc.expected != "" { 91 t.Fatal("Expected no error") 92 } 93 } 94 }) 95 } 96 } 97 98 func TestValidateArgumentsClientError(t *testing.T) { 99 client := &fakeClient{true, false} 100 ctx := createContext([]string{"validModule", "method", "arg"}) 101 err := validateArguments(ctx, client) 102 if err == nil || errorMsg != err.Error() { 103 t.Fatalf("Expected client returned error!") 104 } 105 } 106 107 func TestCallRPC(t *testing.T) { 108 client := &fakeClient{false, false} 109 ctx := createContext([]string{"validModule", "method", "arg"}) 110 111 res, err := callRPC(ctx, client) 112 if err != nil { 113 t.Fatal("Expected no error, got: ", err) 114 } 115 116 if res == nil { 117 t.Fatal("Expected result") 118 } 119 } 120 121 func TestCallRPCError(t *testing.T) { 122 client := &fakeClient{true, false} 123 ctx := createContext([]string{"validModule", "method", "arg"}) 124 125 res, err := callRPC(ctx, client) 126 if err == nil || errorMsg != err.Error() { 127 t.Fatalf("Expected '%s', got '%s': ", errorMsg, err.Error()) 128 } 129 130 if res != nil { 131 t.Fatal("Expected no result") 132 } 133 134 } 135 136 func TestCallRPCMethodError(t *testing.T) { 137 client := &fakeClient{false, true} 138 ctx := createContext([]string{"validModule", "method", "arg"}) 139 140 res, err := callRPC(ctx, client) 141 if err == nil { 142 t.Fatal("Expected error") 143 } 144 145 if res != nil { 146 t.Fatal("Expected no result") 147 } 148 149 expected := fmt.Sprintf("error in validModule_method: %s (code: %d)", errorMsg, errorCode) 150 if expected != err.Error() { 151 t.Fail() 152 } 153 } 154 155 func createContext(args []string) *cli.Context { 156 var flags flag.FlagSet 157 flags.Parse(args) 158 return cli.NewContext(nil, &flags, nil) 159 }