github.com/luckypickle/go-ethereum-vet@v1.14.2/rpc/server_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  	"context"
    21  	"encoding/json"
    22  	"net"
    23  	"reflect"
    24  	"testing"
    25  	"time"
    26  )
    27  
    28  type Service struct{}
    29  
    30  type Args struct {
    31  	S string
    32  }
    33  
    34  func (s *Service) NoArgsRets() {
    35  }
    36  
    37  type Result struct {
    38  	String string
    39  	Int    int
    40  	Args   *Args
    41  }
    42  
    43  func (s *Service) Echo(str string, i int, args *Args) Result {
    44  	return Result{str, i, args}
    45  }
    46  
    47  func (s *Service) EchoWithCtx(ctx context.Context, str string, i int, args *Args) Result {
    48  	return Result{str, i, args}
    49  }
    50  
    51  func (s *Service) Sleep(ctx context.Context, duration time.Duration) {
    52  	select {
    53  	case <-time.After(duration):
    54  	case <-ctx.Done():
    55  	}
    56  }
    57  
    58  func (s *Service) Rets() (string, error) {
    59  	return "", nil
    60  }
    61  
    62  func (s *Service) InvalidRets1() (error, string) {
    63  	return nil, ""
    64  }
    65  
    66  func (s *Service) InvalidRets2() (string, string) {
    67  	return "", ""
    68  }
    69  
    70  func (s *Service) InvalidRets3() (string, string, error) {
    71  	return "", "", nil
    72  }
    73  
    74  func (s *Service) Subscription(ctx context.Context) (*Subscription, error) {
    75  	return nil, nil
    76  }
    77  
    78  func TestServerRegisterName(t *testing.T) {
    79  	server := NewServer()
    80  	service := new(Service)
    81  
    82  	if err := server.RegisterName("calc", service); err != nil {
    83  		t.Fatalf("%v", err)
    84  	}
    85  
    86  	if len(server.services) != 2 {
    87  		t.Fatalf("Expected 2 service entries, got %d", len(server.services))
    88  	}
    89  
    90  	svc, ok := server.services["calc"]
    91  	if !ok {
    92  		t.Fatalf("Expected service calc to be registered")
    93  	}
    94  
    95  	if len(svc.callbacks) != 5 {
    96  		t.Errorf("Expected 5 callbacks for service 'calc', got %d", len(svc.callbacks))
    97  	}
    98  
    99  	if len(svc.subscriptions) != 1 {
   100  		t.Errorf("Expected 1 subscription for service 'calc', got %d", len(svc.subscriptions))
   101  	}
   102  }
   103  
   104  func testServerMethodExecution(t *testing.T, method string) {
   105  	server := NewServer()
   106  	service := new(Service)
   107  
   108  	if err := server.RegisterName("test", service); err != nil {
   109  		t.Fatalf("%v", err)
   110  	}
   111  
   112  	stringArg := "string arg"
   113  	intArg := 1122
   114  	argsArg := &Args{"abcde"}
   115  	params := []interface{}{stringArg, intArg, argsArg}
   116  
   117  	request := map[string]interface{}{
   118  		"id":      12345,
   119  		"method":  "test_" + method,
   120  		"version": "2.0",
   121  		"params":  params,
   122  	}
   123  
   124  	clientConn, serverConn := net.Pipe()
   125  	defer clientConn.Close()
   126  
   127  	go server.ServeCodec(NewJSONCodec(serverConn), OptionMethodInvocation)
   128  
   129  	out := json.NewEncoder(clientConn)
   130  	in := json.NewDecoder(clientConn)
   131  
   132  	if err := out.Encode(request); err != nil {
   133  		t.Fatal(err)
   134  	}
   135  
   136  	response := jsonSuccessResponse{Result: &Result{}}
   137  	if err := in.Decode(&response); err != nil {
   138  		t.Fatal(err)
   139  	}
   140  
   141  	if result, ok := response.Result.(*Result); ok {
   142  		if result.String != stringArg {
   143  			t.Errorf("expected %s, got : %s\n", stringArg, result.String)
   144  		}
   145  		if result.Int != intArg {
   146  			t.Errorf("expected %d, got %d\n", intArg, result.Int)
   147  		}
   148  		if !reflect.DeepEqual(result.Args, argsArg) {
   149  			t.Errorf("expected %v, got %v\n", argsArg, result)
   150  		}
   151  	} else {
   152  		t.Fatalf("invalid response: expected *Result - got: %T", response.Result)
   153  	}
   154  }
   155  
   156  func TestServerMethodExecution(t *testing.T) {
   157  	testServerMethodExecution(t, "echo")
   158  }
   159  
   160  func TestServerMethodWithCtx(t *testing.T) {
   161  	testServerMethodExecution(t, "echoWithCtx")
   162  }