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 }