| 
									
										
										
										
											2018-06-06 16:51:56 +08:00
										 |  |  | /* | 
					
						
							| 
									
										
										
										
											2019-04-10 02:39:42 +08:00
										 |  |  |  * MinIO Cloud Storage, (C) 2018 MinIO, Inc. | 
					
						
							| 
									
										
										
										
											2018-06-06 16:51:56 +08:00
										 |  |  |  * | 
					
						
							|  |  |  |  * Licensed under the Apache License, Version 2.0 (the "License"); | 
					
						
							|  |  |  |  * you may not use this file except in compliance with the License. | 
					
						
							|  |  |  |  * You may obtain a copy of the License at | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  *     http://www.apache.org/licenses/LICENSE-2.0
 | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Unless required by applicable law or agreed to in writing, software | 
					
						
							|  |  |  |  * distributed under the License is distributed on an "AS IS" BASIS, | 
					
						
							|  |  |  |  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | 
					
						
							|  |  |  |  * See the License for the specific language governing permissions and | 
					
						
							|  |  |  |  * limitations under the License. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | package cmd | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import ( | 
					
						
							|  |  |  | 	"crypto/tls" | 
					
						
							|  |  |  | 	"errors" | 
					
						
							|  |  |  | 	"net/http" | 
					
						
							|  |  |  | 	"net/http/httptest" | 
					
						
							|  |  |  | 	"reflect" | 
					
						
							|  |  |  | 	"testing" | 
					
						
							|  |  |  | 	"time" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	xrpc "github.com/minio/minio/cmd/rpc" | 
					
						
							|  |  |  | 	xnet "github.com/minio/minio/pkg/net" | 
					
						
							|  |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func TestAuthArgsAuthenticate(t *testing.T) { | 
					
						
							|  |  |  | 	tmpGlobalServerConfig := globalServerConfig | 
					
						
							|  |  |  | 	defer func() { | 
					
						
							|  |  |  | 		globalServerConfig = tmpGlobalServerConfig | 
					
						
							|  |  |  | 	}() | 
					
						
							|  |  |  | 	globalServerConfig = newServerConfig() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	case1Args := AuthArgs{ | 
					
						
							|  |  |  | 		Token:       newAuthToken(), | 
					
						
							|  |  |  | 		RPCVersion:  globalRPCAPIVersion, | 
					
						
							|  |  |  | 		RequestTime: UTCNow(), | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	case2Args := AuthArgs{ | 
					
						
							|  |  |  | 		Token:       newAuthToken(), | 
					
						
							|  |  |  | 		RPCVersion:  globalRPCAPIVersion, | 
					
						
							|  |  |  | 		RequestTime: UTCNow().Add(15 * time.Minute), | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	case3Args := AuthArgs{ | 
					
						
							|  |  |  | 		Token:       newAuthToken(), | 
					
						
							|  |  |  | 		RPCVersion:  globalRPCAPIVersion, | 
					
						
							|  |  |  | 		RequestTime: UTCNow().Add(-16 * time.Minute), | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	case4Args := AuthArgs{ | 
					
						
							|  |  |  | 		Token:       newAuthToken(), | 
					
						
							|  |  |  | 		RPCVersion:  RPCVersion{99, 99, 99}, | 
					
						
							|  |  |  | 		RequestTime: UTCNow(), | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	case5Args := AuthArgs{ | 
					
						
							|  |  |  | 		Token:       "invalid-token", | 
					
						
							|  |  |  | 		RPCVersion:  globalRPCAPIVersion, | 
					
						
							|  |  |  | 		RequestTime: UTCNow(), | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	testCases := []struct { | 
					
						
							|  |  |  | 		args      AuthArgs | 
					
						
							|  |  |  | 		expectErr bool | 
					
						
							|  |  |  | 	}{ | 
					
						
							|  |  |  | 		{case1Args, false}, | 
					
						
							|  |  |  | 		{case2Args, false}, | 
					
						
							|  |  |  | 		{case3Args, true}, | 
					
						
							|  |  |  | 		{case4Args, true}, | 
					
						
							|  |  |  | 		{case5Args, true}, | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	for i, testCase := range testCases { | 
					
						
							|  |  |  | 		err := testCase.args.Authenticate() | 
					
						
							|  |  |  | 		expectErr := (err != nil) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if expectErr != testCase.expectErr { | 
					
						
							|  |  |  | 			t.Fatalf("case %v: expected: %v, got: %v", i+1, testCase.expectErr, expectErr) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func TestAuthArgsSetAuthArgs(t *testing.T) { | 
					
						
							|  |  |  | 	tmpGlobalServerConfig := globalServerConfig | 
					
						
							|  |  |  | 	defer func() { | 
					
						
							|  |  |  | 		globalServerConfig = tmpGlobalServerConfig | 
					
						
							|  |  |  | 	}() | 
					
						
							|  |  |  | 	globalServerConfig = newServerConfig() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	case1Args := AuthArgs{ | 
					
						
							|  |  |  | 		Token:       newAuthToken(), | 
					
						
							|  |  |  | 		RPCVersion:  globalRPCAPIVersion, | 
					
						
							|  |  |  | 		RequestTime: UTCNow(), | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	case2Args := AuthArgs{ | 
					
						
							|  |  |  | 		Token:       newAuthToken(), | 
					
						
							|  |  |  | 		RPCVersion:  globalRPCAPIVersion, | 
					
						
							|  |  |  | 		RequestTime: UTCNow().Add(15 * time.Minute), | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	testCases := []struct { | 
					
						
							|  |  |  | 		args           *AuthArgs | 
					
						
							|  |  |  | 		authArgs       AuthArgs | 
					
						
							|  |  |  | 		expectedResult *AuthArgs | 
					
						
							|  |  |  | 	}{ | 
					
						
							|  |  |  | 		{&AuthArgs{}, case1Args, &case1Args}, | 
					
						
							|  |  |  | 		{&case2Args, case1Args, &case1Args}, | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	for i, testCase := range testCases { | 
					
						
							|  |  |  | 		testCase.args.SetAuthArgs(testCase.authArgs) | 
					
						
							|  |  |  | 		result := testCase.args | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if !reflect.DeepEqual(result, testCase.expectedResult) { | 
					
						
							|  |  |  | 			t.Fatalf("case %v: expected: %v, got: %v", i+1, testCase.expectedResult, result) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func TestRPCClientArgsValidate(t *testing.T) { | 
					
						
							|  |  |  | 	case1URL, err := xnet.ParseURL("http://localhost:12345/rpc") | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		t.Fatalf("unexpected error %v", err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	case1Args := RPCClientArgs{ | 
					
						
							|  |  |  | 		NewAuthTokenFunc: newAuthToken, | 
					
						
							|  |  |  | 		RPCVersion:       globalRPCAPIVersion, | 
					
						
							|  |  |  | 		ServiceName:      "Arith", | 
					
						
							|  |  |  | 		ServiceURL:       case1URL, | 
					
						
							|  |  |  | 		TLSConfig:        nil, | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	case2URL, err := xnet.ParseURL("https://localhost:12345/rpc") | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		t.Fatalf("unexpected error %v", err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	case2Args := RPCClientArgs{ | 
					
						
							|  |  |  | 		NewAuthTokenFunc: newAuthToken, | 
					
						
							|  |  |  | 		RPCVersion:       globalRPCAPIVersion, | 
					
						
							|  |  |  | 		ServiceName:      "Arith", | 
					
						
							|  |  |  | 		ServiceURL:       case1URL, | 
					
						
							|  |  |  | 		TLSConfig:        &tls.Config{}, | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	case3Args := RPCClientArgs{ | 
					
						
							|  |  |  | 		NewAuthTokenFunc: nil, | 
					
						
							|  |  |  | 		RPCVersion:       globalRPCAPIVersion, | 
					
						
							|  |  |  | 		ServiceName:      "Arith", | 
					
						
							|  |  |  | 		ServiceURL:       case1URL, | 
					
						
							|  |  |  | 		TLSConfig:        &tls.Config{}, | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	case4Args := RPCClientArgs{ | 
					
						
							|  |  |  | 		NewAuthTokenFunc: newAuthToken, | 
					
						
							|  |  |  | 		RPCVersion:       globalRPCAPIVersion, | 
					
						
							|  |  |  | 		ServiceURL:       case1URL, | 
					
						
							|  |  |  | 		TLSConfig:        &tls.Config{}, | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	case5URL, err := xnet.ParseURL("ftp://localhost:12345/rpc") | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		t.Fatalf("unexpected error %v", err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	case5Args := RPCClientArgs{ | 
					
						
							|  |  |  | 		NewAuthTokenFunc: newAuthToken, | 
					
						
							|  |  |  | 		RPCVersion:       globalRPCAPIVersion, | 
					
						
							|  |  |  | 		ServiceName:      "Arith", | 
					
						
							|  |  |  | 		ServiceURL:       case5URL, | 
					
						
							|  |  |  | 		TLSConfig:        &tls.Config{}, | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	case6URL, err := xnet.ParseURL("http://localhost:12345/rpc?location") | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		t.Fatalf("unexpected error %v", err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	case6Args := RPCClientArgs{ | 
					
						
							|  |  |  | 		NewAuthTokenFunc: newAuthToken, | 
					
						
							|  |  |  | 		RPCVersion:       globalRPCAPIVersion, | 
					
						
							|  |  |  | 		ServiceName:      "Arith", | 
					
						
							|  |  |  | 		ServiceURL:       case6URL, | 
					
						
							|  |  |  | 		TLSConfig:        &tls.Config{}, | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	case7Args := RPCClientArgs{ | 
					
						
							|  |  |  | 		NewAuthTokenFunc: newAuthToken, | 
					
						
							|  |  |  | 		RPCVersion:       globalRPCAPIVersion, | 
					
						
							|  |  |  | 		ServiceName:      "Arith", | 
					
						
							|  |  |  | 		ServiceURL:       case2URL, | 
					
						
							|  |  |  | 		TLSConfig:        nil, | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	testCases := []struct { | 
					
						
							|  |  |  | 		args      RPCClientArgs | 
					
						
							|  |  |  | 		expectErr bool | 
					
						
							|  |  |  | 	}{ | 
					
						
							|  |  |  | 		{case1Args, false}, | 
					
						
							|  |  |  | 		{case2Args, false}, | 
					
						
							|  |  |  | 		// NewAuthTokenFunc must not be empty error.
 | 
					
						
							|  |  |  | 		{case3Args, true}, | 
					
						
							|  |  |  | 		// ServiceName must not be empty.
 | 
					
						
							|  |  |  | 		{case4Args, true}, | 
					
						
							|  |  |  | 		// unknown RPC URL error.
 | 
					
						
							|  |  |  | 		{case5Args, true}, | 
					
						
							|  |  |  | 		// unknown RPC URL error.
 | 
					
						
							|  |  |  | 		{case6Args, true}, | 
					
						
							|  |  |  | 		// tls configuration must not be empty for https url error.
 | 
					
						
							|  |  |  | 		{case7Args, true}, | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	for i, testCase := range testCases { | 
					
						
							|  |  |  | 		err := testCase.args.validate() | 
					
						
							|  |  |  | 		expectErr := (err != nil) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if expectErr != testCase.expectErr { | 
					
						
							|  |  |  | 			t.Fatalf("case %v: expected: %v, got: %v", i+1, testCase.expectErr, expectErr) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | type Args struct { | 
					
						
							|  |  |  | 	AuthArgs | 
					
						
							|  |  |  | 	A, B int | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | type Quotient struct { | 
					
						
							|  |  |  | 	Quo, Rem int | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | type Arith struct{} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (t *Arith) Multiply(args *Args, reply *int) error { | 
					
						
							|  |  |  | 	*reply = args.A * args.B | 
					
						
							|  |  |  | 	return nil | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (t *Arith) Divide(args *Args, quo *Quotient) error { | 
					
						
							|  |  |  | 	if args.B == 0 { | 
					
						
							|  |  |  | 		return errors.New("divide by zero") | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	quo.Quo = args.A / args.B | 
					
						
							|  |  |  | 	quo.Rem = args.A % args.B | 
					
						
							|  |  |  | 	return nil | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func TestRPCClientCall(t *testing.T) { | 
					
						
							|  |  |  | 	tmpGlobalServerConfig := globalServerConfig | 
					
						
							|  |  |  | 	defer func() { | 
					
						
							|  |  |  | 		globalServerConfig = tmpGlobalServerConfig | 
					
						
							|  |  |  | 	}() | 
					
						
							|  |  |  | 	globalServerConfig = newServerConfig() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	rpcServer := xrpc.NewServer() | 
					
						
							|  |  |  | 	if err := rpcServer.RegisterName("Arith", &Arith{}); err != nil { | 
					
						
							|  |  |  | 		t.Fatalf("unexpected error %v", err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	httpServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { | 
					
						
							|  |  |  | 		rpcServer.ServeHTTP(w, r) | 
					
						
							|  |  |  | 	})) | 
					
						
							|  |  |  | 	defer httpServer.Close() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	url, err := xnet.ParseURL(httpServer.URL) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		t.Fatalf("unexpected error %v", err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	rpcClient, err := NewRPCClient(RPCClientArgs{ | 
					
						
							|  |  |  | 		NewAuthTokenFunc: newAuthToken, | 
					
						
							|  |  |  | 		RPCVersion:       globalRPCAPIVersion, | 
					
						
							|  |  |  | 		ServiceName:      "Arith", | 
					
						
							|  |  |  | 		ServiceURL:       url, | 
					
						
							|  |  |  | 	}) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		t.Fatalf("unexpected error %v", err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	var case1Result int | 
					
						
							|  |  |  | 	case1ExpectedResult := 19 * 8 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	testCases := []struct { | 
					
						
							| 
									
										
										
										
											2019-02-13 20:59:36 +08:00
										 |  |  | 		serviceMethod  string | 
					
						
							|  |  |  | 		args           *Args | 
					
						
							| 
									
										
										
										
											2018-06-06 16:51:56 +08:00
										 |  |  | 		result         interface{} | 
					
						
							|  |  |  | 		changeConfig   bool | 
					
						
							|  |  |  | 		expectedResult interface{} | 
					
						
							|  |  |  | 		expectErr      bool | 
					
						
							|  |  |  | 	}{ | 
					
						
							|  |  |  | 		{"Arith.Multiply", &Args{A: 19, B: 8}, &case1Result, false, &case1ExpectedResult, false}, | 
					
						
							|  |  |  | 		{"Arith.Divide", &Args{A: 19, B: 8}, &Quotient{}, false, &Quotient{2, 3}, false}, | 
					
						
							|  |  |  | 		{"Arith.Multiply", &Args{A: 19, B: 8}, &case1Result, true, &case1ExpectedResult, false}, | 
					
						
							|  |  |  | 		{"Arith.Divide", &Args{A: 19, B: 8}, &Quotient{}, true, &Quotient{2, 3}, false}, | 
					
						
							|  |  |  | 		{"Arith.Divide", &Args{A: 19, B: 0}, &Quotient{}, false, nil, true}, | 
					
						
							|  |  |  | 		{"Arith.Divide", &Args{A: 19, B: 8}, &case1Result, false, nil, true}, | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	for i, testCase := range testCases { | 
					
						
							|  |  |  | 		if testCase.changeConfig { | 
					
						
							|  |  |  | 			globalServerConfig = newServerConfig() | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		err := rpcClient.Call(testCase.serviceMethod, testCase.args, testCase.result) | 
					
						
							|  |  |  | 		expectErr := (err != nil) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if expectErr != testCase.expectErr { | 
					
						
							|  |  |  | 			t.Fatalf("case %v: expected: %v, got: %v", i+1, testCase.expectErr, expectErr) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if !testCase.expectErr { | 
					
						
							|  |  |  | 			if !reflect.DeepEqual(testCase.result, testCase.expectedResult) { | 
					
						
							|  |  |  | 				t.Fatalf("case %v: expected: %v, got: %v", i+1, testCase.expectedResult, testCase.result) | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func TestRPCClientClose(t *testing.T) { | 
					
						
							|  |  |  | 	tmpGlobalServerConfig := globalServerConfig | 
					
						
							|  |  |  | 	defer func() { | 
					
						
							|  |  |  | 		globalServerConfig = tmpGlobalServerConfig | 
					
						
							|  |  |  | 	}() | 
					
						
							|  |  |  | 	globalServerConfig = newServerConfig() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	url, err := xnet.ParseURL("http://localhost:12345") | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		t.Fatalf("unexpected error %v", err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	rpcClient, err := NewRPCClient(RPCClientArgs{ | 
					
						
							|  |  |  | 		NewAuthTokenFunc: newAuthToken, | 
					
						
							|  |  |  | 		RPCVersion:       globalRPCAPIVersion, | 
					
						
							|  |  |  | 		ServiceName:      "Arith", | 
					
						
							|  |  |  | 		ServiceURL:       url, | 
					
						
							|  |  |  | 	}) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		t.Fatalf("unexpected error %v", err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	testCases := []struct { | 
					
						
							|  |  |  | 		rpcClient *RPCClient | 
					
						
							|  |  |  | 		expectErr bool | 
					
						
							|  |  |  | 	}{ | 
					
						
							|  |  |  | 		{rpcClient, false}, | 
					
						
							|  |  |  | 		// Double close.
 | 
					
						
							|  |  |  | 		{rpcClient, false}, | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	for i, testCase := range testCases { | 
					
						
							|  |  |  | 		err := testCase.rpcClient.Close() | 
					
						
							|  |  |  | 		expectErr := (err != nil) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if expectErr != testCase.expectErr { | 
					
						
							|  |  |  | 			t.Fatalf("case %v: expected: %v, got: %v", i+1, testCase.expectErr, expectErr) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func TestRPCClientServiceURL(t *testing.T) { | 
					
						
							|  |  |  | 	tmpGlobalServerConfig := globalServerConfig | 
					
						
							|  |  |  | 	defer func() { | 
					
						
							|  |  |  | 		globalServerConfig = tmpGlobalServerConfig | 
					
						
							|  |  |  | 	}() | 
					
						
							|  |  |  | 	globalServerConfig = newServerConfig() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	url, err := xnet.ParseURL("http://localhost:12345") | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		t.Fatalf("unexpected error %v", err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	rpcClient, err := NewRPCClient(RPCClientArgs{ | 
					
						
							|  |  |  | 		NewAuthTokenFunc: newAuthToken, | 
					
						
							|  |  |  | 		RPCVersion:       globalRPCAPIVersion, | 
					
						
							|  |  |  | 		ServiceName:      "Arith", | 
					
						
							|  |  |  | 		ServiceURL:       url, | 
					
						
							|  |  |  | 	}) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		t.Fatalf("unexpected error %v", err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	case1Result, err := xnet.ParseURL("http://localhost:12345") | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		t.Fatalf("unexpected error %v", err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	testCases := []struct { | 
					
						
							|  |  |  | 		rpcClient      *RPCClient | 
					
						
							|  |  |  | 		expectedResult *xnet.URL | 
					
						
							|  |  |  | 	}{ | 
					
						
							|  |  |  | 		{rpcClient, case1Result}, | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	for i, testCase := range testCases { | 
					
						
							|  |  |  | 		result := testCase.rpcClient.ServiceURL() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if !reflect.DeepEqual(result, testCase.expectedResult) { | 
					
						
							|  |  |  | 			t.Fatalf("case %v: expected: %v, got: %v", i+1, testCase.expectedResult, result) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } |