github.com/niedbalski/juju@v0.0.0-20190215020005-8ff100488e47/worker/raft/rafttransport/manifold_test.go (about)

     1  // Copyright 2018 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package rafttransport_test
     5  
     6  import (
     7  	"context"
     8  	"crypto/tls"
     9  	"net"
    10  	"time"
    11  
    12  	"github.com/hashicorp/raft"
    13  	"github.com/juju/clock/testclock"
    14  	"github.com/juju/errors"
    15  	"github.com/juju/pubsub"
    16  	"github.com/juju/testing"
    17  	jc "github.com/juju/testing/checkers"
    18  	gc "gopkg.in/check.v1"
    19  	"gopkg.in/juju/names.v2"
    20  	"gopkg.in/juju/worker.v1"
    21  	"gopkg.in/juju/worker.v1/dependency"
    22  	dt "gopkg.in/juju/worker.v1/dependency/testing"
    23  
    24  	"github.com/juju/juju/api"
    25  	"github.com/juju/juju/apiserver/apiserverhttp"
    26  	"github.com/juju/juju/pubsub/centralhub"
    27  	coretesting "github.com/juju/juju/testing"
    28  	"github.com/juju/juju/worker/raft/rafttransport"
    29  )
    30  
    31  type ManifoldSuite struct {
    32  	testing.IsolationSuite
    33  
    34  	manifold dependency.Manifold
    35  	context  dependency.Context
    36  	agent    *mockAgent
    37  	auth     *mockAuthenticator
    38  	hub      *pubsub.StructuredHub
    39  	mux      *apiserverhttp.Mux
    40  	worker   worker.Worker
    41  	stub     testing.Stub
    42  	clock    *testclock.Clock
    43  }
    44  
    45  var _ = gc.Suite(&ManifoldSuite{})
    46  
    47  func (s *ManifoldSuite) SetUpTest(c *gc.C) {
    48  	s.IsolationSuite.SetUpTest(c)
    49  
    50  	tag := names.NewMachineTag("123")
    51  	s.agent = &mockAgent{
    52  		conf: mockAgentConfig{
    53  			tag: tag,
    54  			apiInfo: &api.Info{
    55  				Addrs:  []string{"testing.invalid:1234"},
    56  				CACert: coretesting.CACert,
    57  			},
    58  		},
    59  	}
    60  	s.auth = &mockAuthenticator{}
    61  	s.hub = centralhub.New(tag)
    62  	s.mux = &apiserverhttp.Mux{}
    63  	s.stub.ResetCalls()
    64  	s.worker = &mockTransportWorker{
    65  		Transport: &raft.InmemTransport{},
    66  	}
    67  	s.clock = testclock.NewClock(time.Time{})
    68  
    69  	s.context = s.newContext(nil)
    70  	s.manifold = rafttransport.Manifold(rafttransport.ManifoldConfig{
    71  		ClockName:         "clock",
    72  		AgentName:         "agent",
    73  		AuthenticatorName: "auth",
    74  		HubName:           "hub",
    75  		MuxName:           "mux",
    76  		DialConn:          s.dialConn,
    77  		NewWorker:         s.newWorker,
    78  		Path:              "raft/path",
    79  	})
    80  }
    81  
    82  func (s *ManifoldSuite) newContext(overlay map[string]interface{}) dependency.Context {
    83  	resources := map[string]interface{}{
    84  		"clock": s.clock,
    85  		"agent": s.agent,
    86  		"auth":  s.auth,
    87  		"hub":   s.hub,
    88  		"mux":   s.mux,
    89  	}
    90  	for k, v := range overlay {
    91  		resources[k] = v
    92  	}
    93  	return dt.StubContext(nil, resources)
    94  }
    95  
    96  func (s *ManifoldSuite) newWorker(config rafttransport.Config) (worker.Worker, error) {
    97  	s.stub.MethodCall(s, "NewWorker", config)
    98  	if err := s.stub.NextErr(); err != nil {
    99  		return nil, err
   100  	}
   101  	return s.worker, nil
   102  }
   103  
   104  func (s *ManifoldSuite) dialConn(ctx context.Context, addr string, tlsConfig *tls.Config) (net.Conn, error) {
   105  	s.stub.MethodCall(s, "DialConn")
   106  	return nil, s.stub.NextErr()
   107  }
   108  
   109  var expectedInputs = []string{"clock", "agent", "auth", "hub", "mux"}
   110  
   111  func (s *ManifoldSuite) TestInputs(c *gc.C) {
   112  	c.Assert(s.manifold.Inputs, jc.SameContents, expectedInputs)
   113  }
   114  
   115  func (s *ManifoldSuite) TestMissingInputs(c *gc.C) {
   116  	for _, input := range expectedInputs {
   117  		context := s.newContext(map[string]interface{}{
   118  			input: dependency.ErrMissing,
   119  		})
   120  		_, err := s.manifold.Start(context)
   121  		c.Assert(errors.Cause(err), gc.Equals, dependency.ErrMissing)
   122  	}
   123  }
   124  
   125  func (s *ManifoldSuite) TestStart(c *gc.C) {
   126  	s.startWorkerClean(c)
   127  
   128  	s.stub.CheckCallNames(c, "NewWorker")
   129  	args := s.stub.Calls()[0].Args
   130  	c.Assert(args, gc.HasLen, 1)
   131  	c.Assert(args[0], gc.FitsTypeOf, rafttransport.Config{})
   132  	config := args[0].(rafttransport.Config)
   133  
   134  	c.Assert(config.DialConn, gc.NotNil)
   135  	config.DialConn(context.Background(), "foo", &tls.Config{})
   136  	s.stub.CheckCallNames(c, "NewWorker", "DialConn")
   137  	config.DialConn = nil
   138  
   139  	c.Assert(config.TLSConfig, gc.NotNil)
   140  	config.TLSConfig = nil
   141  
   142  	c.Assert(config, jc.DeepEquals, rafttransport.Config{
   143  		APIInfo: &api.Info{
   144  			Addrs:  []string{"testing.invalid:1234"},
   145  			CACert: coretesting.CACert,
   146  		},
   147  		Hub:           s.hub,
   148  		Mux:           s.mux,
   149  		Authenticator: s.auth,
   150  		Path:          "raft/path",
   151  		LocalID:       "123",
   152  		Clock:         s.clock,
   153  		Timeout:       30 * time.Second,
   154  	})
   155  }
   156  
   157  func (s *ManifoldSuite) TestOutput(c *gc.C) {
   158  	w := s.startWorkerClean(c)
   159  
   160  	var t raft.Transport
   161  	err := s.manifold.Output(w, &t)
   162  	c.Assert(err, jc.ErrorIsNil)
   163  	c.Assert(t, gc.Equals, s.worker)
   164  }
   165  
   166  func (s *ManifoldSuite) startWorkerClean(c *gc.C) worker.Worker {
   167  	w, err := s.manifold.Start(s.context)
   168  	c.Assert(err, jc.ErrorIsNil)
   169  	c.Assert(w, gc.Equals, s.worker)
   170  	return w
   171  }