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  }