aboutsummaryrefslogtreecommitdiffstats
path: root/node/node_test.go
diff options
context:
space:
mode:
authorPéter Szilágyi <peterke@gmail.com>2016-02-03 01:06:43 +0800
committerPéter Szilágyi <peterke@gmail.com>2016-02-04 17:23:15 +0800
commit188ab928c3f2a2eac5ee0f7ac42cbf2f35568bcd (patch)
treeeaeebfbe371a9ae8e801bd934d7dd850c7354765 /node/node_test.go
parent3274db19c7563e31f79418b63f6c10233cbaa32a (diff)
downloaddexon-188ab928c3f2a2eac5ee0f7ac42cbf2f35568bcd.tar.gz
dexon-188ab928c3f2a2eac5ee0f7ac42cbf2f35568bcd.tar.zst
dexon-188ab928c3f2a2eac5ee0f7ac42cbf2f35568bcd.zip
cmd, common, node, rpc: move IPC into the node itself
Diffstat (limited to 'node/node_test.go')
-rw-r--r--node/node_test.go101
1 files changed, 90 insertions, 11 deletions
diff --git a/node/node_test.go b/node/node_test.go
index ef096fc91..53dcbcf74 100644
--- a/node/node_test.go
+++ b/node/node_test.go
@@ -18,27 +18,34 @@ package node
import (
"errors"
+ "fmt"
"io/ioutil"
+ "math/rand"
"os"
"reflect"
"testing"
+ "time"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/p2p"
+ "github.com/ethereum/go-ethereum/rpc"
)
var (
testNodeKey, _ = crypto.GenerateKey()
+)
- testNodeConfig = &Config{
+func testNodeConfig() *Config {
+ return &Config{
+ IpcPath: fmt.Sprintf("test-%d.ipc", rand.Int63()),
PrivateKey: testNodeKey,
Name: "test node",
}
-)
+}
// Tests that an empty protocol stack can be started, restarted and stopped.
func TestNodeLifeCycle(t *testing.T) {
- stack, err := New(testNodeConfig)
+ stack, err := New(testNodeConfig())
if err != nil {
t.Fatalf("failed to create protocol stack: %v", err)
}
@@ -101,7 +108,7 @@ func TestNodeUsedDataDir(t *testing.T) {
// Tests whether services can be registered and duplicates caught.
func TestServiceRegistry(t *testing.T) {
- stack, err := New(testNodeConfig)
+ stack, err := New(testNodeConfig())
if err != nil {
t.Fatalf("failed to create protocol stack: %v", err)
}
@@ -133,7 +140,7 @@ func TestServiceRegistry(t *testing.T) {
// Tests that registered services get started and stopped correctly.
func TestServiceLifeCycle(t *testing.T) {
- stack, err := New(testNodeConfig)
+ stack, err := New(testNodeConfig())
if err != nil {
t.Fatalf("failed to create protocol stack: %v", err)
}
@@ -183,7 +190,7 @@ func TestServiceLifeCycle(t *testing.T) {
// Tests that services are restarted cleanly as new instances.
func TestServiceRestarts(t *testing.T) {
- stack, err := New(testNodeConfig)
+ stack, err := New(testNodeConfig())
if err != nil {
t.Fatalf("failed to create protocol stack: %v", err)
}
@@ -231,7 +238,7 @@ func TestServiceRestarts(t *testing.T) {
// Tests that if a service fails to initialize itself, none of the other services
// will be allowed to even start.
func TestServiceConstructionAbortion(t *testing.T) {
- stack, err := New(testNodeConfig)
+ stack, err := New(testNodeConfig())
if err != nil {
t.Fatalf("failed to create protocol stack: %v", err)
}
@@ -278,7 +285,7 @@ func TestServiceConstructionAbortion(t *testing.T) {
// Tests that if a service fails to start, all others started before it will be
// shut down.
func TestServiceStartupAbortion(t *testing.T) {
- stack, err := New(testNodeConfig)
+ stack, err := New(testNodeConfig())
if err != nil {
t.Fatalf("failed to create protocol stack: %v", err)
}
@@ -331,7 +338,7 @@ func TestServiceStartupAbortion(t *testing.T) {
// Tests that even if a registered service fails to shut down cleanly, it does
// not influece the rest of the shutdown invocations.
func TestServiceTerminationGuarantee(t *testing.T) {
- stack, err := New(testNodeConfig)
+ stack, err := New(testNodeConfig())
if err != nil {
t.Fatalf("failed to create protocol stack: %v", err)
}
@@ -406,7 +413,7 @@ func TestServiceTerminationGuarantee(t *testing.T) {
// TestServiceRetrieval tests that individual services can be retrieved.
func TestServiceRetrieval(t *testing.T) {
// Create a simple stack and register two service types
- stack, err := New(testNodeConfig)
+ stack, err := New(testNodeConfig())
if err != nil {
t.Fatalf("failed to create protocol stack: %v", err)
}
@@ -441,7 +448,7 @@ func TestServiceRetrieval(t *testing.T) {
// Tests that all protocols defined by individual services get launched.
func TestProtocolGather(t *testing.T) {
- stack, err := New(testNodeConfig)
+ stack, err := New(testNodeConfig())
if err != nil {
t.Fatalf("failed to create protocol stack: %v", err)
}
@@ -494,3 +501,75 @@ func TestProtocolGather(t *testing.T) {
}
}
}
+
+// Tests that all APIs defined by individual services get exposed.
+func TestAPIGather(t *testing.T) {
+ stack, err := New(testNodeConfig())
+ if err != nil {
+ t.Fatalf("failed to create protocol stack: %v", err)
+ }
+ // Register a batch of services with some configured APIs
+ calls := make(chan string, 1)
+
+ services := map[string]struct {
+ APIs []rpc.API
+ Maker InstrumentingWrapper
+ }{
+ "Zero APIs": {[]rpc.API{}, InstrumentedServiceMakerA},
+ "Single API": {[]rpc.API{
+ {"single", "1", &OneMethodApi{fun: func() { calls <- "single.v1" }}, true},
+ }, InstrumentedServiceMakerB},
+ "Many APIs": {[]rpc.API{
+ {"multi", "1", &OneMethodApi{fun: func() { calls <- "multi.v1" }}, true},
+ {"multi.v2", "2", &OneMethodApi{fun: func() { calls <- "multi.v2" }}, true},
+ {"multi.v2.nested", "2", &OneMethodApi{fun: func() { calls <- "multi.v2.nested" }}, true},
+ }, InstrumentedServiceMakerC},
+ }
+ for id, config := range services {
+ config := config
+ constructor := func(*ServiceContext) (Service, error) {
+ return &InstrumentedService{apis: config.APIs}, nil
+ }
+ if err := stack.Register(config.Maker(constructor)); err != nil {
+ t.Fatalf("service %s: registration failed: %v", id, err)
+ }
+ }
+ // Start the services and ensure all API start successfully
+ if err := stack.Start(); err != nil {
+ t.Fatalf("failed to start protocol stack: %v", err)
+ }
+ defer stack.Stop()
+
+ // Connect to the RPC server and verify the various registered endpoints
+ ipcClient, err := rpc.NewIPCClient(stack.IpcEndpoint())
+ if err != nil {
+ t.Fatalf("failed to connect to the IPC API server: %v", err)
+ }
+
+ tests := []struct {
+ Method string
+ Result string
+ }{
+ {"single_theOneMethod", "single.v1"},
+ {"multi_theOneMethod", "multi.v1"},
+ {"multi.v2_theOneMethod", "multi.v2"},
+ {"multi.v2.nested_theOneMethod", "multi.v2.nested"},
+ }
+ for i, test := range tests {
+ if err := ipcClient.Send(rpc.JSONRequest{Id: new(int64), Version: "2.0", Method: test.Method}); err != nil {
+ t.Fatalf("test %d: failed to send API request: %v", i, err)
+ }
+ reply := new(rpc.JSONSuccessResponse)
+ if err := ipcClient.Recv(reply); err != nil {
+ t.Fatalf("test %d: failed to read API reply: %v", i, err)
+ }
+ select {
+ case result := <-calls:
+ if result != test.Result {
+ t.Errorf("test %d: result mismatch: have %s, want %s", i, result, test.Result)
+ }
+ case <-time.After(time.Second):
+ t.Fatalf("test %d: rpc execution timeout", i)
+ }
+ }
+}