github.com/pslzym/go-ethereum@v1.8.17-0.20180926104442-4b6824e07b1b/rpc/json_test.go (about)

     1  // Copyright 2015 The go-ethereum Authors
     2  // This file is part of the go-ethereum library.
     3  //
     4  // The go-ethereum library is free software: you can redistribute it and/or modify
     5  // it under the terms of the GNU Lesser General Public License as published by
     6  // the Free Software Foundation, either version 3 of the License, or
     7  // (at your option) any later version.
     8  //
     9  // The go-ethereum library is distributed in the hope that it will be useful,
    10  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    11  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    12  // GNU Lesser General Public License for more details.
    13  //
    14  // You should have received a copy of the GNU Lesser General Public License
    15  // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
    16  
    17  package rpc
    18  
    19  import (
    20  	"bufio"
    21  	"bytes"
    22  	"encoding/json"
    23  	"reflect"
    24  	"strconv"
    25  	"testing"
    26  )
    27  
    28  type RWC struct {
    29  	*bufio.ReadWriter
    30  }
    31  
    32  func (rwc *RWC) Close() error {
    33  	return nil
    34  }
    35  
    36  func TestJSONRequestParsing(t *testing.T) {
    37  	server := NewServer()
    38  	service := new(Service)
    39  
    40  	if err := server.RegisterName("calc", service); err != nil {
    41  		t.Fatalf("%v", err)
    42  	}
    43  
    44  	req := bytes.NewBufferString(`{"id": 1234, "jsonrpc": "2.0", "method": "calc_add", "params": [11, 22]}`)
    45  	var str string
    46  	reply := bytes.NewBufferString(str)
    47  	rw := &RWC{bufio.NewReadWriter(bufio.NewReader(req), bufio.NewWriter(reply))}
    48  
    49  	codec := NewJSONCodec(rw)
    50  
    51  	requests, batch, err := codec.ReadRequestHeaders()
    52  	if err != nil {
    53  		t.Fatalf("%v", err)
    54  	}
    55  
    56  	if batch {
    57  		t.Fatalf("Request isn't a batch")
    58  	}
    59  
    60  	if len(requests) != 1 {
    61  		t.Fatalf("Expected 1 request but got %d requests - %v", len(requests), requests)
    62  	}
    63  
    64  	if requests[0].service != "calc" {
    65  		t.Fatalf("Expected service 'calc' but got '%s'", requests[0].service)
    66  	}
    67  
    68  	if requests[0].method != "add" {
    69  		t.Fatalf("Expected method 'Add' but got '%s'", requests[0].method)
    70  	}
    71  
    72  	if rawId, ok := requests[0].id.(*json.RawMessage); ok {
    73  		id, e := strconv.ParseInt(string(*rawId), 0, 64)
    74  		if e != nil {
    75  			t.Fatalf("%v", e)
    76  		}
    77  		if id != 1234 {
    78  			t.Fatalf("Expected id 1234 but got %d", id)
    79  		}
    80  	} else {
    81  		t.Fatalf("invalid request, expected *json.RawMesage got %T", requests[0].id)
    82  	}
    83  
    84  	var arg int
    85  	args := []reflect.Type{reflect.TypeOf(arg), reflect.TypeOf(arg)}
    86  
    87  	v, err := codec.ParseRequestArguments(args, requests[0].params)
    88  	if err != nil {
    89  		t.Fatalf("%v", err)
    90  	}
    91  
    92  	if len(v) != 2 {
    93  		t.Fatalf("Expected 2 argument values, got %d", len(v))
    94  	}
    95  
    96  	if v[0].Int() != 11 || v[1].Int() != 22 {
    97  		t.Fatalf("expected %d == 11 && %d == 22", v[0].Int(), v[1].Int())
    98  	}
    99  }
   100  
   101  func TestJSONRequestParamsParsing(t *testing.T) {
   102  
   103  	var (
   104  		stringT = reflect.TypeOf("")
   105  		intT    = reflect.TypeOf(0)
   106  		intPtrT = reflect.TypeOf(new(int))
   107  
   108  		stringV = reflect.ValueOf("abc")
   109  		i       = 1
   110  		intV    = reflect.ValueOf(i)
   111  		intPtrV = reflect.ValueOf(&i)
   112  	)
   113  
   114  	var validTests = []struct {
   115  		input    string
   116  		argTypes []reflect.Type
   117  		expected []reflect.Value
   118  	}{
   119  		{`[]`, []reflect.Type{}, []reflect.Value{}},
   120  		{`[]`, []reflect.Type{intPtrT}, []reflect.Value{intPtrV}},
   121  		{`[1]`, []reflect.Type{intT}, []reflect.Value{intV}},
   122  		{`[1,"abc"]`, []reflect.Type{intT, stringT}, []reflect.Value{intV, stringV}},
   123  		{`[null]`, []reflect.Type{intPtrT}, []reflect.Value{intPtrV}},
   124  		{`[null,"abc"]`, []reflect.Type{intPtrT, stringT, intPtrT}, []reflect.Value{intPtrV, stringV, intPtrV}},
   125  		{`[null,"abc",null]`, []reflect.Type{intPtrT, stringT, intPtrT}, []reflect.Value{intPtrV, stringV, intPtrV}},
   126  	}
   127  
   128  	codec := jsonCodec{}
   129  
   130  	for _, test := range validTests {
   131  		params := (json.RawMessage)([]byte(test.input))
   132  		args, err := codec.ParseRequestArguments(test.argTypes, params)
   133  
   134  		if err != nil {
   135  			t.Fatal(err)
   136  		}
   137  
   138  		var match []interface{}
   139  		json.Unmarshal([]byte(test.input), &match)
   140  
   141  		if len(args) != len(test.argTypes) {
   142  			t.Fatalf("expected %d parsed args, got %d", len(test.argTypes), len(args))
   143  		}
   144  
   145  		for i, arg := range args {
   146  			expected := test.expected[i]
   147  
   148  			if arg.Kind() != expected.Kind() {
   149  				t.Errorf("expected type for param %d in %s", i, test.input)
   150  			}
   151  
   152  			if arg.Kind() == reflect.Int && arg.Int() != expected.Int() {
   153  				t.Errorf("expected int(%d), got int(%d) in %s", expected.Int(), arg.Int(), test.input)
   154  			}
   155  
   156  			if arg.Kind() == reflect.String && arg.String() != expected.String() {
   157  				t.Errorf("expected string(%s), got string(%s) in %s", expected.String(), arg.String(), test.input)
   158  			}
   159  		}
   160  	}
   161  
   162  	var invalidTests = []struct {
   163  		input    string
   164  		argTypes []reflect.Type
   165  	}{
   166  		{`[]`, []reflect.Type{intT}},
   167  		{`[null]`, []reflect.Type{intT}},
   168  		{`[1]`, []reflect.Type{stringT}},
   169  		{`[1,2]`, []reflect.Type{stringT}},
   170  		{`["abc", null]`, []reflect.Type{stringT, intT}},
   171  	}
   172  
   173  	for i, test := range invalidTests {
   174  		if _, err := codec.ParseRequestArguments(test.argTypes, test.input); err == nil {
   175  			t.Errorf("expected test %d - %s to fail", i, test.input)
   176  		}
   177  	}
   178  }