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