github.com/juju/juju@v0.0.0-20240430160146-1752b71fcf00/worker/apiaddressupdater/apiaddressupdater_test.go (about) 1 // Copyright 2014-2015 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package apiaddressupdater_test 5 6 import ( 7 "time" 8 9 "github.com/juju/errors" 10 "github.com/juju/loggo" 11 "github.com/juju/testing" 12 jc "github.com/juju/testing/checkers" 13 "github.com/juju/worker/v3" 14 "github.com/juju/worker/v3/workertest" 15 gc "gopkg.in/check.v1" 16 17 apimachiner "github.com/juju/juju/api/agent/machiner" 18 corenetwork "github.com/juju/juju/core/network" 19 jujutesting "github.com/juju/juju/juju/testing" 20 "github.com/juju/juju/network" 21 "github.com/juju/juju/state" 22 coretesting "github.com/juju/juju/testing" 23 "github.com/juju/juju/worker/apiaddressupdater" 24 ) 25 26 type APIAddressUpdaterSuite struct { 27 jujutesting.JujuConnSuite 28 } 29 30 var _ = gc.Suite(&APIAddressUpdaterSuite{}) 31 32 func (s *APIAddressUpdaterSuite) SetUpTest(c *gc.C) { 33 s.JujuConnSuite.SetUpTest(c) 34 err := s.State.SetAPIHostPorts(nil) 35 c.Assert(err, jc.ErrorIsNil) 36 37 s.PatchValue(&network.AddressesForInterfaceName, func(string) ([]string, error) { 38 return nil, nil 39 }) 40 } 41 42 type apiAddressSetter struct { 43 servers chan []corenetwork.HostPorts 44 err error 45 } 46 47 func (s *apiAddressSetter) SetAPIHostPorts(servers []corenetwork.HostPorts) error { 48 s.servers <- servers 49 return s.err 50 } 51 52 func (s *APIAddressUpdaterSuite) TestStartStop(c *gc.C) { 53 st, _ := s.OpenAPIAsNewMachine(c, state.JobHostUnits) 54 worker, err := apiaddressupdater.NewAPIAddressUpdater( 55 apiaddressupdater.Config{ 56 Addresser: apimachiner.NewState(st), 57 Setter: &apiAddressSetter{}, 58 Logger: loggo.GetLogger("test"), 59 }) 60 c.Assert(err, jc.ErrorIsNil) 61 worker.Kill() 62 c.Assert(worker.Wait(), gc.IsNil) 63 } 64 65 func (s *APIAddressUpdaterSuite) TestAddressInitialUpdate(c *gc.C) { 66 updatedServers := []corenetwork.SpaceHostPorts{corenetwork.NewSpaceHostPorts(1234, "localhost", "127.0.0.1")} 67 err := s.State.SetAPIHostPorts(updatedServers) 68 c.Assert(err, jc.ErrorIsNil) 69 70 setter := &apiAddressSetter{servers: make(chan []corenetwork.HostPorts, 1)} 71 st, _ := s.OpenAPIAsNewMachine(c, state.JobHostUnits) 72 updater, err := apiaddressupdater.NewAPIAddressUpdater( 73 apiaddressupdater.Config{ 74 Addresser: apimachiner.NewState(st), 75 Setter: setter, 76 Logger: loggo.GetLogger("test"), 77 }) 78 c.Assert(err, jc.ErrorIsNil) 79 defer workertest.CleanKill(c, updater) 80 81 expServer := corenetwork.ProviderHostPorts{ 82 corenetwork.ProviderHostPort{ProviderAddress: corenetwork.NewMachineAddress("localhost").AsProviderAddress(), NetPort: 1234}, 83 corenetwork.ProviderHostPort{ProviderAddress: corenetwork.NewMachineAddress("127.0.0.1").AsProviderAddress(), NetPort: 1234}, 84 }.HostPorts() 85 86 // SetAPIHostPorts should be called with the initial value. 87 select { 88 case <-time.After(coretesting.LongWait): 89 c.Fatalf("timed out waiting for SetAPIHostPorts to be called") 90 case servers := <-setter.servers: 91 c.Assert(servers, gc.DeepEquals, []corenetwork.HostPorts{expServer}) 92 } 93 94 // The values are also available through the report. 95 reporter, ok := updater.(worker.Reporter) 96 c.Assert(ok, jc.IsTrue) 97 c.Assert(reporter.Report(), jc.DeepEquals, map[string]interface{}{ 98 "servers": [][]string{{"localhost:1234", "127.0.0.1:1234"}}, 99 }) 100 101 } 102 103 func (s *APIAddressUpdaterSuite) TestAddressChange(c *gc.C) { 104 setter := &apiAddressSetter{servers: make(chan []corenetwork.HostPorts, 1)} 105 st, _ := s.OpenAPIAsNewMachine(c, state.JobHostUnits) 106 worker, err := apiaddressupdater.NewAPIAddressUpdater( 107 apiaddressupdater.Config{ 108 Addresser: apimachiner.NewState(st), 109 Setter: setter, 110 Logger: loggo.GetLogger("test"), 111 }) 112 c.Assert(err, jc.ErrorIsNil) 113 defer func() { c.Assert(worker.Wait(), gc.IsNil) }() 114 defer worker.Kill() 115 updatedServers := []corenetwork.SpaceHostPorts{ 116 corenetwork.NewSpaceHostPorts(1234, "localhost", "127.0.0.1"), 117 } 118 // SetAPIHostPorts should be called with the initial value (empty), 119 // and then the updated value. 120 select { 121 case <-time.After(coretesting.LongWait): 122 c.Fatalf("timed out waiting for SetAPIHostPorts to be called initially") 123 case servers := <-setter.servers: 124 c.Assert(servers, gc.HasLen, 0) 125 } 126 err = s.State.SetAPIHostPorts(updatedServers) 127 c.Assert(err, jc.ErrorIsNil) 128 select { 129 case <-time.After(coretesting.LongWait): 130 c.Fatalf("timed out waiting for SetAPIHostPorts to be called after update") 131 case servers := <-setter.servers: 132 expServer := corenetwork.ProviderHostPorts{ 133 corenetwork.ProviderHostPort{ProviderAddress: corenetwork.NewMachineAddress("localhost").AsProviderAddress(), NetPort: 1234}, 134 corenetwork.ProviderHostPort{ProviderAddress: corenetwork.NewMachineAddress("127.0.0.1").AsProviderAddress(), NetPort: 1234}, 135 }.HostPorts() 136 c.Assert(servers, gc.DeepEquals, []corenetwork.HostPorts{expServer}) 137 } 138 } 139 140 func (s *APIAddressUpdaterSuite) TestAddressChangeEmpty(c *gc.C) { 141 setter := &apiAddressSetter{servers: make(chan []corenetwork.HostPorts, 1)} 142 st, _ := s.OpenAPIAsNewMachine(c, state.JobHostUnits) 143 worker, err := apiaddressupdater.NewAPIAddressUpdater( 144 apiaddressupdater.Config{ 145 Addresser: apimachiner.NewState(st), 146 Setter: setter, 147 Logger: loggo.GetLogger("test"), 148 }) 149 c.Assert(err, jc.ErrorIsNil) 150 defer func() { c.Assert(worker.Wait(), gc.IsNil) }() 151 defer worker.Kill() 152 153 // SetAPIHostPorts should be called with the initial value (empty), 154 // and then the updated value. 155 select { 156 case <-time.After(coretesting.LongWait): 157 c.Fatalf("timed out waiting for SetAPIHostPorts to be called initially") 158 case servers := <-setter.servers: 159 c.Assert(servers, gc.HasLen, 0) 160 } 161 162 updatedServers := []corenetwork.SpaceHostPorts{ 163 corenetwork.NewSpaceHostPorts(1234, "localhost", "127.0.0.1"), 164 } 165 166 err = s.State.SetAPIHostPorts(updatedServers) 167 c.Assert(err, jc.ErrorIsNil) 168 select { 169 case <-time.After(coretesting.LongWait): 170 c.Fatalf("timed out waiting for SetAPIHostPorts to be called after update") 171 case servers := <-setter.servers: 172 expServer := corenetwork.ProviderHostPorts{ 173 corenetwork.ProviderHostPort{ProviderAddress: corenetwork.NewMachineAddress("localhost").AsProviderAddress(), NetPort: 1234}, 174 corenetwork.ProviderHostPort{ProviderAddress: corenetwork.NewMachineAddress("127.0.0.1").AsProviderAddress(), NetPort: 1234}, 175 }.HostPorts() 176 c.Assert(servers, gc.DeepEquals, []corenetwork.HostPorts{expServer}) 177 } 178 179 updatedServers = []corenetwork.SpaceHostPorts{} 180 err = s.State.SetAPIHostPorts(updatedServers) 181 c.Assert(err, jc.ErrorIsNil) 182 select { 183 case <-time.After(coretesting.LongWait): 184 c.Fatalf("timed out waiting for SetAPIHostPorts to be called after update") 185 case servers := <-setter.servers: 186 expServer := corenetwork.ProviderHostPorts{ 187 corenetwork.ProviderHostPort{ProviderAddress: corenetwork.NewMachineAddress("localhost").AsProviderAddress(), NetPort: 1234}, 188 corenetwork.ProviderHostPort{ProviderAddress: corenetwork.NewMachineAddress("127.0.0.1").AsProviderAddress(), NetPort: 1234}, 189 }.HostPorts() 190 c.Assert(servers, gc.DeepEquals, []corenetwork.HostPorts{expServer}) 191 } 192 } 193 194 func (s *APIAddressUpdaterSuite) TestBridgeAddressesFiltering(c *gc.C) { 195 s.PatchValue(&network.AddressesForInterfaceName, func(name string) ([]string, error) { 196 if name == network.DefaultLXDBridge { 197 return []string{ 198 "10.0.4.1", 199 "10.0.4.4", 200 }, nil 201 } else if name == network.DefaultKVMBridge { 202 return []string{ 203 "192.168.122.1", 204 }, nil 205 } 206 c.Fatalf("unknown bridge in testing: %v", name) 207 return nil, nil 208 }) 209 210 initialServers := []corenetwork.SpaceHostPorts{ 211 corenetwork.NewSpaceHostPorts(1234, "localhost", "127.0.0.1"), 212 corenetwork.NewSpaceHostPorts( 213 4321, 214 "10.0.3.3", // not filtered 215 "10.0.4.1", // filtered lxd bridge address 216 "10.0.4.2", // not filtered 217 "192.168.122.1", // filtered default virbr0 218 ), 219 } 220 err := s.State.SetAPIHostPorts(initialServers) 221 c.Assert(err, jc.ErrorIsNil) 222 223 setter := &apiAddressSetter{servers: make(chan []corenetwork.HostPorts, 1)} 224 st, _ := s.OpenAPIAsNewMachine(c, state.JobHostUnits) 225 w, err := apiaddressupdater.NewAPIAddressUpdater( 226 apiaddressupdater.Config{ 227 Addresser: apimachiner.NewState(st), 228 Setter: setter, 229 Logger: loggo.GetLogger("test"), 230 }) 231 c.Assert(err, jc.ErrorIsNil) 232 defer func() { c.Assert(w.Wait(), gc.IsNil) }() 233 defer w.Kill() 234 235 updatedServers := []corenetwork.SpaceHostPorts{ 236 corenetwork.NewSpaceHostPorts(1234, "localhost", "127.0.0.1"), 237 corenetwork.NewSpaceHostPorts( 238 4001, 239 "10.0.3.3", // not filtered 240 ), 241 } 242 243 expServer1 := corenetwork.ProviderHostPorts{ 244 corenetwork.ProviderHostPort{ProviderAddress: corenetwork.NewMachineAddress("localhost").AsProviderAddress(), NetPort: 1234}, 245 corenetwork.ProviderHostPort{ProviderAddress: corenetwork.NewMachineAddress("127.0.0.1").AsProviderAddress(), NetPort: 1234}, 246 }.HostPorts() 247 248 // SetAPIHostPorts should be called with the initial value, and 249 // then the updated value, but filtering occurs in both cases. 250 select { 251 case <-time.After(coretesting.LongWait): 252 c.Fatalf("timed out waiting for SetAPIHostPorts to be called initially") 253 case servers := <-setter.servers: 254 c.Assert(servers, gc.HasLen, 2) 255 256 expServerInit := corenetwork.ProviderHostPorts{ 257 corenetwork.ProviderHostPort{ProviderAddress: corenetwork.NewMachineAddress("10.0.3.3").AsProviderAddress(), NetPort: 4321}, 258 corenetwork.ProviderHostPort{ProviderAddress: corenetwork.NewMachineAddress("10.0.4.2").AsProviderAddress(), NetPort: 4321}, 259 }.HostPorts() 260 c.Assert(servers, jc.DeepEquals, []corenetwork.HostPorts{expServer1, expServerInit}) 261 } 262 263 err = s.State.SetAPIHostPorts(updatedServers) 264 c.Assert(err, gc.IsNil) 265 select { 266 case <-time.After(coretesting.LongWait): 267 c.Fatalf("timed out waiting for SetAPIHostPorts to be called after update") 268 case servers := <-setter.servers: 269 c.Assert(servers, gc.HasLen, 2) 270 271 expServerUpd := corenetwork.ProviderHostPorts{ 272 corenetwork.ProviderHostPort{ProviderAddress: corenetwork.NewMachineAddress("10.0.3.3").AsProviderAddress(), NetPort: 4001}, 273 }.HostPorts() 274 c.Assert(servers, jc.DeepEquals, []corenetwork.HostPorts{expServer1, expServerUpd}) 275 } 276 } 277 278 type ValidateSuite struct { 279 testing.IsolationSuite 280 } 281 282 var _ = gc.Suite(&ValidateSuite{}) 283 284 func (*ValidateSuite) TestValid(c *gc.C) { 285 err := validConfig().Validate() 286 c.Check(err, jc.ErrorIsNil) 287 } 288 289 func (*ValidateSuite) TestMissingAddresser(c *gc.C) { 290 config := validConfig() 291 config.Addresser = nil 292 checkNotValid(c, config, "nil Addresser not valid") 293 } 294 295 func (*ValidateSuite) TestMissingSetter(c *gc.C) { 296 config := validConfig() 297 config.Setter = nil 298 checkNotValid(c, config, "nil Setter not valid") 299 } 300 301 func (*ValidateSuite) TestMissingLogger(c *gc.C) { 302 config := validConfig() 303 config.Logger = nil 304 checkNotValid(c, config, "nil Logger not valid") 305 } 306 307 func validConfig() apiaddressupdater.Config { 308 return apiaddressupdater.Config{ 309 Addresser: struct{ apiaddressupdater.APIAddresser }{}, 310 Setter: struct { 311 apiaddressupdater.APIAddressSetter 312 }{}, 313 Logger: loggo.GetLogger("test"), 314 } 315 } 316 317 func checkNotValid(c *gc.C, config apiaddressupdater.Config, expect string) { 318 check := func(err error) { 319 c.Check(err, gc.ErrorMatches, expect) 320 c.Check(err, jc.Satisfies, errors.IsNotValid) 321 } 322 323 err := config.Validate() 324 check(err) 325 326 worker, err := apiaddressupdater.NewAPIAddressUpdater(config) 327 c.Check(worker, gc.IsNil) 328 check(err) 329 }