| 
									
										
										
										
											2015-12-16 10:58:01 +01:00
										 |  |  | // Copyright 2015 The go-ethereum Authors | 
					
						
							|  |  |  | // This file is part of the go-ethereum library. | 
					
						
							|  |  |  | // | 
					
						
							|  |  |  | // The go-ethereum library is free software: you can redistribute it and/or modify | 
					
						
							|  |  |  | // it under the terms of the GNU Lesser General Public License as published by | 
					
						
							|  |  |  | // the Free Software Foundation, either version 3 of the License, or | 
					
						
							|  |  |  | // (at your option) any later version. | 
					
						
							|  |  |  | // | 
					
						
							|  |  |  | // The go-ethereum library is distributed in the hope that it will be useful, | 
					
						
							|  |  |  | // but WITHOUT ANY WARRANTY; without even the implied warranty of | 
					
						
							|  |  |  | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 
					
						
							|  |  |  | // GNU Lesser General Public License for more details. | 
					
						
							|  |  |  | // | 
					
						
							|  |  |  | // You should have received a copy of the GNU Lesser General Public License | 
					
						
							|  |  |  | // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | package rpc | 
					
						
							| 
									
										
										
										
											2015-10-15 16:07:19 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | import ( | 
					
						
							| 
									
										
										
										
											2017-03-22 18:20:33 +01:00
										 |  |  | 	"context" | 
					
						
							| 
									
										
										
										
											2015-10-15 16:07:19 +02:00
										 |  |  | 	"encoding/json" | 
					
						
							| 
									
										
										
										
											2016-03-14 09:38:54 +01:00
										 |  |  | 	"net" | 
					
						
							| 
									
										
										
										
											2015-10-15 16:07:19 +02:00
										 |  |  | 	"reflect" | 
					
						
							|  |  |  | 	"testing" | 
					
						
							| 
									
										
										
										
											2016-07-12 17:47:15 +02:00
										 |  |  | 	"time" | 
					
						
							| 
									
										
										
										
											2015-10-15 16:07:19 +02:00
										 |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | type Service struct{} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | type Args struct { | 
					
						
							|  |  |  | 	S string | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (s *Service) NoArgsRets() { | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | type Result struct { | 
					
						
							|  |  |  | 	String string | 
					
						
							|  |  |  | 	Int    int | 
					
						
							|  |  |  | 	Args   *Args | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (s *Service) Echo(str string, i int, args *Args) Result { | 
					
						
							|  |  |  | 	return Result{str, i, args} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-12-09 18:28:07 +01:00
										 |  |  | func (s *Service) EchoWithCtx(ctx context.Context, str string, i int, args *Args) Result { | 
					
						
							|  |  |  | 	return Result{str, i, args} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-07-12 17:47:15 +02:00
										 |  |  | func (s *Service) Sleep(ctx context.Context, duration time.Duration) { | 
					
						
							|  |  |  | 	select { | 
					
						
							|  |  |  | 	case <-time.After(duration): | 
					
						
							|  |  |  | 	case <-ctx.Done(): | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-15 16:07:19 +02:00
										 |  |  | func (s *Service) Rets() (string, error) { | 
					
						
							|  |  |  | 	return "", nil | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (s *Service) InvalidRets1() (error, string) { | 
					
						
							|  |  |  | 	return nil, "" | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (s *Service) InvalidRets2() (string, string) { | 
					
						
							|  |  |  | 	return "", "" | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (s *Service) InvalidRets3() (string, string, error) { | 
					
						
							|  |  |  | 	return "", "", nil | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-07-27 17:47:46 +02:00
										 |  |  | func (s *Service) Subscription(ctx context.Context) (*Subscription, error) { | 
					
						
							| 
									
										
										
										
											2016-03-29 15:07:40 +02:00
										 |  |  | 	return nil, nil | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-15 16:07:19 +02:00
										 |  |  | func TestServerRegisterName(t *testing.T) { | 
					
						
							|  |  |  | 	server := NewServer() | 
					
						
							|  |  |  | 	service := new(Service) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if err := server.RegisterName("calc", service); err != nil { | 
					
						
							|  |  |  | 		t.Fatalf("%v", err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if len(server.services) != 2 { | 
					
						
							|  |  |  | 		t.Fatalf("Expected 2 service entries, got %d", len(server.services)) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	svc, ok := server.services["calc"] | 
					
						
							|  |  |  | 	if !ok { | 
					
						
							|  |  |  | 		t.Fatalf("Expected service calc to be registered") | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-07-12 17:47:15 +02:00
										 |  |  | 	if len(svc.callbacks) != 5 { | 
					
						
							|  |  |  | 		t.Errorf("Expected 5 callbacks for service 'calc', got %d", len(svc.callbacks)) | 
					
						
							| 
									
										
										
										
											2015-10-15 16:07:19 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-03-14 09:38:54 +01:00
										 |  |  | 	if len(svc.subscriptions) != 1 { | 
					
						
							|  |  |  | 		t.Errorf("Expected 1 subscription for service 'calc', got %d", len(svc.subscriptions)) | 
					
						
							| 
									
										
										
										
											2015-10-15 16:07:19 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-03-14 09:38:54 +01:00
										 |  |  | func testServerMethodExecution(t *testing.T, method string) { | 
					
						
							|  |  |  | 	server := NewServer() | 
					
						
							|  |  |  | 	service := new(Service) | 
					
						
							| 
									
										
										
										
											2015-10-15 16:07:19 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-03-14 09:38:54 +01:00
										 |  |  | 	if err := server.RegisterName("test", service); err != nil { | 
					
						
							|  |  |  | 		t.Fatalf("%v", err) | 
					
						
							| 
									
										
										
										
											2015-10-15 16:07:19 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-03-14 09:38:54 +01:00
										 |  |  | 	stringArg := "string arg" | 
					
						
							|  |  |  | 	intArg := 1122 | 
					
						
							|  |  |  | 	argsArg := &Args{"abcde"} | 
					
						
							|  |  |  | 	params := []interface{}{stringArg, intArg, argsArg} | 
					
						
							| 
									
										
										
										
											2015-10-15 16:07:19 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-03-14 09:38:54 +01:00
										 |  |  | 	request := map[string]interface{}{ | 
					
						
							|  |  |  | 		"id":      12345, | 
					
						
							|  |  |  | 		"method":  "test_" + method, | 
					
						
							|  |  |  | 		"version": "2.0", | 
					
						
							|  |  |  | 		"params":  params, | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2015-10-15 16:07:19 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-03-14 09:38:54 +01:00
										 |  |  | 	clientConn, serverConn := net.Pipe() | 
					
						
							|  |  |  | 	defer clientConn.Close() | 
					
						
							| 
									
										
										
										
											2015-10-15 16:07:19 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-03-14 09:38:54 +01:00
										 |  |  | 	go server.ServeCodec(NewJSONCodec(serverConn), OptionMethodInvocation) | 
					
						
							| 
									
										
										
										
											2015-10-15 16:07:19 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-03-14 09:38:54 +01:00
										 |  |  | 	out := json.NewEncoder(clientConn) | 
					
						
							|  |  |  | 	in := json.NewDecoder(clientConn) | 
					
						
							| 
									
										
										
										
											2015-10-15 16:07:19 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-03-14 09:38:54 +01:00
										 |  |  | 	if err := out.Encode(request); err != nil { | 
					
						
							|  |  |  | 		t.Fatal(err) | 
					
						
							| 
									
										
										
										
											2015-10-15 16:07:19 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-07-12 17:47:15 +02:00
										 |  |  | 	response := jsonSuccessResponse{Result: &Result{}} | 
					
						
							| 
									
										
										
										
											2016-03-14 09:38:54 +01:00
										 |  |  | 	if err := in.Decode(&response); err != nil { | 
					
						
							|  |  |  | 		t.Fatal(err) | 
					
						
							| 
									
										
										
										
											2015-10-15 16:07:19 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-03-14 09:38:54 +01:00
										 |  |  | 	if result, ok := response.Result.(*Result); ok { | 
					
						
							|  |  |  | 		if result.String != stringArg { | 
					
						
							|  |  |  | 			t.Errorf("expected %s, got : %s\n", stringArg, result.String) | 
					
						
							| 
									
										
										
										
											2015-10-15 16:07:19 +02:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2016-03-14 09:38:54 +01:00
										 |  |  | 		if result.Int != intArg { | 
					
						
							|  |  |  | 			t.Errorf("expected %d, got %d\n", intArg, result.Int) | 
					
						
							| 
									
										
										
										
											2015-10-15 16:07:19 +02:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2016-03-14 09:38:54 +01:00
										 |  |  | 		if !reflect.DeepEqual(result.Args, argsArg) { | 
					
						
							|  |  |  | 			t.Errorf("expected %v, got %v\n", argsArg, result) | 
					
						
							| 
									
										
										
										
											2015-10-15 16:07:19 +02:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2016-03-14 09:38:54 +01:00
										 |  |  | 	} else { | 
					
						
							|  |  |  | 		t.Fatalf("invalid response: expected *Result - got: %T", response.Result) | 
					
						
							| 
									
										
										
										
											2015-10-15 16:07:19 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func TestServerMethodExecution(t *testing.T) { | 
					
						
							| 
									
										
										
										
											2016-03-14 09:38:54 +01:00
										 |  |  | 	testServerMethodExecution(t, "echo") | 
					
						
							| 
									
										
										
										
											2015-10-15 16:07:19 +02:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2015-12-09 18:28:07 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | func TestServerMethodWithCtx(t *testing.T) { | 
					
						
							| 
									
										
										
										
											2016-03-14 09:38:54 +01:00
										 |  |  | 	testServerMethodExecution(t, "echoWithCtx") | 
					
						
							| 
									
										
										
										
											2015-12-09 18:28:07 +01:00
										 |  |  | } |