github.com/axw/juju@v0.0.0-20161005053422-4bd6544d08d4/worker/apiconfigwatcher/manifold_test.go (about)

     1  // Copyright 2016 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package apiconfigwatcher_test
     5  
     6  import (
     7  	"sync"
     8  
     9  	"github.com/juju/testing"
    10  	jc "github.com/juju/testing/checkers"
    11  	"github.com/juju/utils/voyeur"
    12  	gc "gopkg.in/check.v1"
    13  
    14  	"github.com/juju/juju/agent"
    15  	"github.com/juju/juju/worker"
    16  	"github.com/juju/juju/worker/apiconfigwatcher"
    17  	"github.com/juju/juju/worker/dependency"
    18  	dt "github.com/juju/juju/worker/dependency/testing"
    19  	"github.com/juju/juju/worker/workertest"
    20  )
    21  
    22  type ManifoldSuite struct {
    23  	testing.IsolationSuite
    24  
    25  	manifold           dependency.Manifold
    26  	context            dependency.Context
    27  	agent              *mockAgent
    28  	agentConfigChanged *voyeur.Value
    29  }
    30  
    31  var _ = gc.Suite(&ManifoldSuite{})
    32  
    33  func (s *ManifoldSuite) SetUpTest(c *gc.C) {
    34  	s.IsolationSuite.SetUpTest(c)
    35  
    36  	s.agent = new(mockAgent)
    37  	s.context = dt.StubContext(nil, map[string]interface{}{
    38  		"agent": s.agent,
    39  	})
    40  	s.agentConfigChanged = voyeur.NewValue(0)
    41  	s.manifold = apiconfigwatcher.Manifold(apiconfigwatcher.ManifoldConfig{
    42  		AgentName:          "agent",
    43  		AgentConfigChanged: s.agentConfigChanged,
    44  	})
    45  }
    46  
    47  func (s *ManifoldSuite) TestInputs(c *gc.C) {
    48  	c.Assert(s.manifold.Inputs, jc.SameContents, []string{"agent"})
    49  }
    50  
    51  func (s *ManifoldSuite) TestNilAgentConfigChanged(c *gc.C) {
    52  	manifold := apiconfigwatcher.Manifold(apiconfigwatcher.ManifoldConfig{
    53  		AgentName: "agent",
    54  	})
    55  	_, err := manifold.Start(s.context)
    56  	c.Assert(err, gc.ErrorMatches, "nil AgentConfigChanged .+")
    57  }
    58  
    59  func (s *ManifoldSuite) TestNoAgent(c *gc.C) {
    60  	context := dt.StubContext(nil, map[string]interface{}{
    61  		"agent": dependency.ErrMissing,
    62  	})
    63  	_, err := s.manifold.Start(context)
    64  	c.Assert(err, gc.Equals, dependency.ErrMissing)
    65  }
    66  
    67  func (s *ManifoldSuite) TestStart(c *gc.C) {
    68  	w := s.startWorkerClean(c)
    69  	workertest.CleanKill(c, w)
    70  }
    71  
    72  func (s *ManifoldSuite) TestBounceOnChange(c *gc.C) {
    73  	s.agent.conf.setAddresses("1.1.1.1:1")
    74  	w := s.startWorkerClean(c)
    75  
    76  	// Change API addresses - worker should bounce.
    77  	s.agent.conf.setAddresses("2.2.2.2:2")
    78  	s.agentConfigChanged.Set(0)
    79  	err := workertest.CheckKilled(c, w)
    80  	c.Assert(err, gc.Equals, dependency.ErrBounce)
    81  
    82  	// Restart the worker - worker should stay up.
    83  	w = s.startWorkerClean(c)
    84  
    85  	// Change API addresses again - worker should bounce again.
    86  	s.agent.conf.setAddresses("2.2.2.2:2", "3.3.3.3:3")
    87  	s.agentConfigChanged.Set(0)
    88  	err = workertest.CheckKilled(c, w)
    89  	c.Assert(err, gc.Equals, dependency.ErrBounce)
    90  }
    91  
    92  func (s *ManifoldSuite) TestConfigChangeWithNoAddrChange(c *gc.C) {
    93  	s.agent.conf.setAddresses("1.1.1.1:1")
    94  	w := s.startWorkerClean(c)
    95  
    96  	// Signal config change without changing API addresses - worker
    97  	// should continue running.
    98  	s.agentConfigChanged.Set(0)
    99  	workertest.CheckAlive(c, w)
   100  }
   101  
   102  func (s *ManifoldSuite) TestConfigChangeWithAddrReordering(c *gc.C) {
   103  	s.agent.conf.setAddresses("1.1.1.1:1", "2.2.2.2:2")
   104  	w := s.startWorkerClean(c)
   105  
   106  	// Change API address ordering - worker should stay up.
   107  	s.agent.conf.setAddresses("2.2.2.2:2", "1.1.1.1:1")
   108  	s.agentConfigChanged.Set(0)
   109  	workertest.CheckAlive(c, w)
   110  }
   111  
   112  func (s *ManifoldSuite) TestClosedVoyeur(c *gc.C) {
   113  	w := s.startWorkerClean(c)
   114  	s.agentConfigChanged.Close()
   115  	err := workertest.CheckKilled(c, w)
   116  	c.Assert(err, gc.ErrorMatches, "config changed value closed")
   117  }
   118  
   119  func (s *ManifoldSuite) startWorkerClean(c *gc.C) worker.Worker {
   120  	w, err := s.manifold.Start(s.context)
   121  	c.Assert(err, jc.ErrorIsNil)
   122  	workertest.CheckAlive(c, w)
   123  	return w
   124  }
   125  
   126  type mockAgent struct {
   127  	agent.Agent
   128  	conf mockConfig
   129  }
   130  
   131  func (ma *mockAgent) CurrentConfig() agent.Config {
   132  	return &ma.conf
   133  }
   134  
   135  type mockConfig struct {
   136  	agent.Config
   137  
   138  	mu    sync.Mutex
   139  	addrs []string
   140  }
   141  
   142  func (mc *mockConfig) setAddresses(addrs ...string) {
   143  	mc.mu.Lock()
   144  	defer mc.mu.Unlock()
   145  	mc.addrs = append([]string(nil), addrs...)
   146  }
   147  
   148  func (mc *mockConfig) APIAddresses() ([]string, error) {
   149  	mc.mu.Lock()
   150  	defer mc.mu.Unlock()
   151  	return mc.addrs, nil
   152  }