github.com/blixtra/nomad@v0.7.2-0.20171221000451-da9a1d7bb050/nomad/rpc_test.go (about)

     1  package nomad
     2  
     3  import (
     4  	"net"
     5  	"net/rpc"
     6  	"os"
     7  	"path"
     8  	"testing"
     9  	"time"
    10  
    11  	msgpackrpc "github.com/hashicorp/net-rpc-msgpackrpc"
    12  	"github.com/hashicorp/nomad/nomad/mock"
    13  	"github.com/hashicorp/nomad/nomad/structs"
    14  	"github.com/hashicorp/nomad/nomad/structs/config"
    15  	"github.com/hashicorp/nomad/testutil"
    16  	"github.com/stretchr/testify/assert"
    17  )
    18  
    19  // rpcClient is a test helper method to return a ClientCodec to use to make rpc
    20  // calls to the passed server.
    21  func rpcClient(t *testing.T, s *Server) rpc.ClientCodec {
    22  	addr := s.config.RPCAddr
    23  	conn, err := net.DialTimeout("tcp", addr.String(), time.Second)
    24  	if err != nil {
    25  		t.Fatalf("err: %v", err)
    26  	}
    27  	// Write the Consul RPC byte to set the mode
    28  	conn.Write([]byte{byte(rpcNomad)})
    29  	return NewClientCodec(conn)
    30  }
    31  
    32  func TestRPC_forwardLeader(t *testing.T) {
    33  	t.Parallel()
    34  	s1 := testServer(t, nil)
    35  	defer s1.Shutdown()
    36  	s2 := testServer(t, func(c *Config) {
    37  		c.DevDisableBootstrap = true
    38  	})
    39  	defer s2.Shutdown()
    40  	testJoin(t, s1, s2)
    41  	testutil.WaitForLeader(t, s1.RPC)
    42  	testutil.WaitForLeader(t, s2.RPC)
    43  
    44  	isLeader, remote := s1.getLeader()
    45  	if !isLeader && remote == nil {
    46  		t.Fatalf("missing leader")
    47  	}
    48  
    49  	if remote != nil {
    50  		var out struct{}
    51  		err := s1.forwardLeader(remote, "Status.Ping", struct{}{}, &out)
    52  		if err != nil {
    53  			t.Fatalf("err: %v", err)
    54  		}
    55  	}
    56  
    57  	isLeader, remote = s2.getLeader()
    58  	if !isLeader && remote == nil {
    59  		t.Fatalf("missing leader")
    60  	}
    61  
    62  	if remote != nil {
    63  		var out struct{}
    64  		err := s2.forwardLeader(remote, "Status.Ping", struct{}{}, &out)
    65  		if err != nil {
    66  			t.Fatalf("err: %v", err)
    67  		}
    68  	}
    69  }
    70  
    71  func TestRPC_forwardRegion(t *testing.T) {
    72  	t.Parallel()
    73  	s1 := testServer(t, nil)
    74  	defer s1.Shutdown()
    75  	s2 := testServer(t, func(c *Config) {
    76  		c.Region = "region2"
    77  	})
    78  	defer s2.Shutdown()
    79  	testJoin(t, s1, s2)
    80  	testutil.WaitForLeader(t, s1.RPC)
    81  	testutil.WaitForLeader(t, s2.RPC)
    82  
    83  	var out struct{}
    84  	err := s1.forwardRegion("region2", "Status.Ping", struct{}{}, &out)
    85  	if err != nil {
    86  		t.Fatalf("err: %v", err)
    87  	}
    88  
    89  	err = s2.forwardRegion("global", "Status.Ping", struct{}{}, &out)
    90  	if err != nil {
    91  		t.Fatalf("err: %v", err)
    92  	}
    93  }
    94  
    95  func TestRPC_PlaintextRPCSucceedsWhenInUpgradeMode(t *testing.T) {
    96  	t.Parallel()
    97  	assert := assert.New(t)
    98  
    99  	const (
   100  		cafile  = "../helper/tlsutil/testdata/ca.pem"
   101  		foocert = "../helper/tlsutil/testdata/nomad-foo.pem"
   102  		fookey  = "../helper/tlsutil/testdata/nomad-foo-key.pem"
   103  	)
   104  	dir := tmpDir(t)
   105  	defer os.RemoveAll(dir)
   106  
   107  	s1 := testServer(t, func(c *Config) {
   108  		c.DataDir = path.Join(dir, "node1")
   109  		c.TLSConfig = &config.TLSConfig{
   110  			EnableRPC:            true,
   111  			VerifyServerHostname: true,
   112  			CAFile:               cafile,
   113  			CertFile:             foocert,
   114  			KeyFile:              fookey,
   115  			RPCUpgradeMode:       true,
   116  		}
   117  	})
   118  	defer s1.Shutdown()
   119  
   120  	codec := rpcClient(t, s1)
   121  
   122  	// Create the register request
   123  	node := mock.Node()
   124  	req := &structs.NodeRegisterRequest{
   125  		Node:         node,
   126  		WriteRequest: structs.WriteRequest{Region: "global"},
   127  	}
   128  
   129  	var resp structs.GenericResponse
   130  	err := msgpackrpc.CallWithCodec(codec, "Node.Register", req, &resp)
   131  	assert.Nil(err)
   132  
   133  	// Check that heartbeatTimers has the heartbeat ID
   134  	_, ok := s1.heartbeatTimers[node.ID]
   135  	assert.True(ok)
   136  }
   137  
   138  func TestRPC_PlaintextRPCFailsWhenNotInUpgradeMode(t *testing.T) {
   139  	t.Parallel()
   140  	assert := assert.New(t)
   141  
   142  	const (
   143  		cafile  = "../helper/tlsutil/testdata/ca.pem"
   144  		foocert = "../helper/tlsutil/testdata/nomad-foo.pem"
   145  		fookey  = "../helper/tlsutil/testdata/nomad-foo-key.pem"
   146  	)
   147  	dir := tmpDir(t)
   148  	defer os.RemoveAll(dir)
   149  
   150  	s1 := testServer(t, func(c *Config) {
   151  		c.DataDir = path.Join(dir, "node1")
   152  		c.TLSConfig = &config.TLSConfig{
   153  			EnableRPC:            true,
   154  			VerifyServerHostname: true,
   155  			CAFile:               cafile,
   156  			CertFile:             foocert,
   157  			KeyFile:              fookey,
   158  		}
   159  	})
   160  	defer s1.Shutdown()
   161  
   162  	codec := rpcClient(t, s1)
   163  
   164  	node := mock.Node()
   165  	req := &structs.NodeRegisterRequest{
   166  		Node:         node,
   167  		WriteRequest: structs.WriteRequest{Region: "global"},
   168  	}
   169  
   170  	var resp structs.GenericResponse
   171  	err := msgpackrpc.CallWithCodec(codec, "Node.Register", req, &resp)
   172  	assert.NotNil(err)
   173  }