github.com/niedbalski/juju@v0.0.0-20190215020005-8ff100488e47/provider/dummy/environs_test.go (about)

     1  // Copyright 2012, 2013 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package dummy_test
     5  
     6  import (
     7  	"strings"
     8  	stdtesting "testing"
     9  	"time"
    10  
    11  	"github.com/juju/errors"
    12  	gitjujutesting "github.com/juju/testing"
    13  	jc "github.com/juju/testing/checkers"
    14  	gc "gopkg.in/check.v1"
    15  
    16  	"github.com/juju/juju/cloud"
    17  	"github.com/juju/juju/core/instance"
    18  	"github.com/juju/juju/environs"
    19  	"github.com/juju/juju/environs/bootstrap"
    20  	"github.com/juju/juju/environs/context"
    21  	"github.com/juju/juju/environs/jujutest"
    22  	sstesting "github.com/juju/juju/environs/simplestreams/testing"
    23  	envtesting "github.com/juju/juju/environs/testing"
    24  	"github.com/juju/juju/juju/keys"
    25  	jujutesting "github.com/juju/juju/juju/testing"
    26  	"github.com/juju/juju/network"
    27  	"github.com/juju/juju/provider/dummy"
    28  	"github.com/juju/juju/testing"
    29  	jujuversion "github.com/juju/juju/version"
    30  )
    31  
    32  const AdminSecret = "admin-secret"
    33  
    34  func TestPackage(t *stdtesting.T) {
    35  	testing.MgoTestPackage(t)
    36  }
    37  
    38  func init() {
    39  	gc.Suite(&liveSuite{
    40  		LiveTests: jujutest.LiveTests{
    41  			TestConfig:     dummy.SampleConfig(),
    42  			CanOpenState:   true,
    43  			HasProvisioner: false,
    44  		},
    45  	})
    46  	gc.Suite(&suite{
    47  		Tests: jujutest.Tests{
    48  			TestConfig: dummy.SampleConfig(),
    49  		},
    50  	})
    51  }
    52  
    53  type liveSuite struct {
    54  	testing.BaseSuite
    55  	gitjujutesting.MgoSuite
    56  	jujutest.LiveTests
    57  }
    58  
    59  func (s *liveSuite) SetUpSuite(c *gc.C) {
    60  	s.BaseSuite.SetUpSuite(c)
    61  	s.MgoSuite.SetUpSuite(c)
    62  	s.LiveTests.SetUpSuite(c)
    63  	s.BaseSuite.PatchValue(&keys.JujuPublicKey, sstesting.SignedMetadataPublicKey)
    64  }
    65  
    66  func (s *liveSuite) TearDownSuite(c *gc.C) {
    67  	s.LiveTests.TearDownSuite(c)
    68  	s.MgoSuite.TearDownSuite(c)
    69  	s.BaseSuite.TearDownSuite(c)
    70  }
    71  
    72  func (s *liveSuite) SetUpTest(c *gc.C) {
    73  	s.BaseSuite.SetUpTest(c)
    74  	s.MgoSuite.SetUpTest(c)
    75  	s.LiveTests.SetUpTest(c)
    76  	s.BaseSuite.PatchValue(&dummy.LogDir, c.MkDir())
    77  }
    78  
    79  func (s *liveSuite) TearDownTest(c *gc.C) {
    80  	s.Destroy(c)
    81  	s.LiveTests.TearDownTest(c)
    82  	s.MgoSuite.TearDownTest(c)
    83  	s.BaseSuite.TearDownTest(c)
    84  }
    85  
    86  type suite struct {
    87  	testing.BaseSuite
    88  	gitjujutesting.MgoSuite
    89  	jujutest.Tests
    90  
    91  	callCtx context.ProviderCallContext
    92  }
    93  
    94  func (s *suite) SetUpSuite(c *gc.C) {
    95  	s.BaseSuite.SetUpSuite(c)
    96  	s.MgoSuite.SetUpSuite(c)
    97  }
    98  
    99  func (s *suite) TearDownSuite(c *gc.C) {
   100  	s.MgoSuite.TearDownSuite(c)
   101  	s.BaseSuite.TearDownSuite(c)
   102  }
   103  
   104  func (s *suite) SetUpTest(c *gc.C) {
   105  	s.BaseSuite.SetUpTest(c)
   106  	s.PatchValue(&jujuversion.Current, testing.FakeVersionNumber)
   107  	s.MgoSuite.SetUpTest(c)
   108  	s.Tests.SetUpTest(c)
   109  	s.PatchValue(&dummy.LogDir, c.MkDir())
   110  	s.callCtx = context.NewCloudCallContext()
   111  }
   112  
   113  func (s *suite) TearDownTest(c *gc.C) {
   114  	s.Tests.TearDownTest(c)
   115  	s.MgoSuite.TearDownTest(c)
   116  	dummy.Reset(c)
   117  	s.BaseSuite.TearDownTest(c)
   118  }
   119  
   120  func (s *suite) bootstrapTestEnviron(c *gc.C) environs.NetworkingEnviron {
   121  	e, err := bootstrap.PrepareController(
   122  		false,
   123  		envtesting.BootstrapContext(c),
   124  		s.ControllerStore,
   125  		bootstrap.PrepareParams{
   126  			ControllerConfig: testing.FakeControllerConfig(),
   127  			ModelConfig:      s.TestConfig,
   128  			ControllerName:   s.TestConfig["name"].(string),
   129  			Cloud:            dummy.SampleCloudSpec(),
   130  			AdminSecret:      AdminSecret,
   131  		},
   132  	)
   133  	c.Assert(err, gc.IsNil, gc.Commentf("preparing environ %#v", s.TestConfig))
   134  	c.Assert(e, gc.NotNil)
   135  	env := e.(environs.Environ)
   136  	netenv, supported := environs.SupportsNetworking(env)
   137  	c.Assert(supported, jc.IsTrue)
   138  
   139  	err = bootstrap.Bootstrap(envtesting.BootstrapContext(c), netenv,
   140  		context.NewCloudCallContext(), bootstrap.BootstrapParams{
   141  			ControllerConfig: testing.FakeControllerConfig(),
   142  			Cloud: cloud.Cloud{
   143  				Name:      "dummy",
   144  				Type:      "dummy",
   145  				AuthTypes: []cloud.AuthType{cloud.EmptyAuthType},
   146  			},
   147  			AdminSecret:  AdminSecret,
   148  			CAPrivateKey: testing.CAKey,
   149  		})
   150  	c.Assert(err, jc.ErrorIsNil)
   151  	return netenv
   152  }
   153  
   154  func (s *suite) TestAvailabilityZone(c *gc.C) {
   155  	e := s.bootstrapTestEnviron(c)
   156  	defer func() {
   157  		err := e.Destroy(s.callCtx)
   158  		c.Assert(err, jc.ErrorIsNil)
   159  	}()
   160  
   161  	inst, hwc := jujutesting.AssertStartInstance(c, e, s.callCtx, s.ControllerUUID, "0")
   162  	c.Assert(inst, gc.NotNil)
   163  	c.Check(hwc.AvailabilityZone, gc.NotNil)
   164  }
   165  
   166  func (s *suite) TestSupportsSpaces(c *gc.C) {
   167  	e := s.bootstrapTestEnviron(c)
   168  	defer func() {
   169  		err := e.Destroy(s.callCtx)
   170  		c.Assert(err, jc.ErrorIsNil)
   171  	}()
   172  
   173  	// Without change spaces are supported.
   174  	ok, err := e.SupportsSpaces(s.callCtx)
   175  	c.Assert(ok, jc.IsTrue)
   176  	c.Assert(err, jc.ErrorIsNil)
   177  
   178  	// Now turn it off.
   179  	isEnabled := dummy.SetSupportsSpaces(false)
   180  	c.Assert(isEnabled, jc.IsTrue)
   181  	ok, err = e.SupportsSpaces(s.callCtx)
   182  	c.Assert(ok, jc.IsFalse)
   183  	c.Assert(err, jc.Satisfies, errors.IsNotSupported)
   184  
   185  	// And finally turn it on again.
   186  	isEnabled = dummy.SetSupportsSpaces(true)
   187  	c.Assert(isEnabled, jc.IsFalse)
   188  	ok, err = e.SupportsSpaces(s.callCtx)
   189  	c.Assert(ok, jc.IsTrue)
   190  	c.Assert(err, jc.ErrorIsNil)
   191  }
   192  
   193  func (s *suite) TestSupportsSpaceDiscovery(c *gc.C) {
   194  	e := s.bootstrapTestEnviron(c)
   195  	defer func() {
   196  		err := e.Destroy(s.callCtx)
   197  		c.Assert(err, jc.ErrorIsNil)
   198  	}()
   199  
   200  	// Without change space discovery is not supported.
   201  	ok, err := e.SupportsSpaceDiscovery(s.callCtx)
   202  	c.Assert(ok, jc.IsFalse)
   203  	c.Assert(err, jc.ErrorIsNil)
   204  
   205  	// Now turn it on.
   206  	isEnabled := dummy.SetSupportsSpaceDiscovery(true)
   207  	c.Assert(isEnabled, jc.IsFalse)
   208  	ok, err = e.SupportsSpaceDiscovery(s.callCtx)
   209  	c.Assert(ok, jc.IsTrue)
   210  	c.Assert(err, jc.ErrorIsNil)
   211  
   212  	// And finally turn it off again.
   213  	isEnabled = dummy.SetSupportsSpaceDiscovery(false)
   214  	c.Assert(isEnabled, jc.IsTrue)
   215  	ok, err = e.SupportsSpaceDiscovery(s.callCtx)
   216  	c.Assert(ok, jc.IsFalse)
   217  	c.Assert(err, jc.ErrorIsNil)
   218  }
   219  
   220  func (s *suite) breakMethods(c *gc.C, e environs.NetworkingEnviron, names ...string) {
   221  	cfg := e.Config()
   222  	brokenCfg, err := cfg.Apply(map[string]interface{}{
   223  		"broken": strings.Join(names, " "),
   224  	})
   225  	c.Assert(err, jc.ErrorIsNil)
   226  	err = e.SetConfig(brokenCfg)
   227  	c.Assert(err, jc.ErrorIsNil)
   228  }
   229  
   230  func (s *suite) TestNetworkInterfaces(c *gc.C) {
   231  	e := s.bootstrapTestEnviron(c)
   232  	defer func() {
   233  		err := e.Destroy(s.callCtx)
   234  		c.Assert(err, jc.ErrorIsNil)
   235  	}()
   236  
   237  	opc := make(chan dummy.Operation, 200)
   238  	dummy.Listen(opc)
   239  
   240  	expectInfo := []network.InterfaceInfo{{
   241  		ProviderId:       "dummy-eth0",
   242  		ProviderSubnetId: "dummy-private",
   243  		CIDR:             "0.10.0.0/24",
   244  		DeviceIndex:      0,
   245  		InterfaceName:    "eth0",
   246  		InterfaceType:    "ethernet",
   247  		VLANTag:          0,
   248  		MACAddress:       "aa:bb:cc:dd:ee:f0",
   249  		Disabled:         false,
   250  		NoAutoStart:      false,
   251  		ConfigType:       network.ConfigDHCP,
   252  		Address:          network.NewAddress("0.10.0.2"),
   253  		DNSServers:       network.NewAddresses("ns1.dummy", "ns2.dummy"),
   254  		GatewayAddress:   network.NewAddress("0.10.0.1"),
   255  	}, {
   256  		ProviderId:       "dummy-eth1",
   257  		ProviderSubnetId: "dummy-public",
   258  		CIDR:             "0.20.0.0/24",
   259  		DeviceIndex:      1,
   260  		InterfaceName:    "eth1",
   261  		InterfaceType:    "ethernet",
   262  		VLANTag:          1,
   263  		MACAddress:       "aa:bb:cc:dd:ee:f1",
   264  		Disabled:         false,
   265  		NoAutoStart:      true,
   266  		ConfigType:       network.ConfigDHCP,
   267  		Address:          network.NewAddress("0.20.0.2"),
   268  		DNSServers:       network.NewAddresses("ns1.dummy", "ns2.dummy"),
   269  		GatewayAddress:   network.NewAddress("0.20.0.1"),
   270  	}, {
   271  		ProviderId:       "dummy-eth2",
   272  		ProviderSubnetId: "dummy-disabled",
   273  		CIDR:             "0.30.0.0/24",
   274  		DeviceIndex:      2,
   275  		InterfaceName:    "eth2",
   276  		InterfaceType:    "ethernet",
   277  		VLANTag:          2,
   278  		MACAddress:       "aa:bb:cc:dd:ee:f2",
   279  		Disabled:         true,
   280  		NoAutoStart:      false,
   281  		ConfigType:       network.ConfigDHCP,
   282  		Address:          network.NewAddress("0.30.0.2"),
   283  		DNSServers:       network.NewAddresses("ns1.dummy", "ns2.dummy"),
   284  		GatewayAddress:   network.NewAddress("0.30.0.1"),
   285  	}}
   286  	info, err := e.NetworkInterfaces(s.callCtx, "i-42")
   287  	c.Assert(err, jc.ErrorIsNil)
   288  	c.Assert(info, jc.DeepEquals, expectInfo)
   289  	assertInterfaces(c, e, opc, "i-42", expectInfo)
   290  
   291  	// Test we can induce errors.
   292  	s.breakMethods(c, e, "NetworkInterfaces")
   293  	info, err = e.NetworkInterfaces(s.callCtx, "i-any")
   294  	c.Assert(err, gc.ErrorMatches, `dummy\.NetworkInterfaces is broken`)
   295  	c.Assert(info, gc.HasLen, 0)
   296  }
   297  
   298  func (s *suite) TestSubnets(c *gc.C) {
   299  	e := s.bootstrapTestEnviron(c)
   300  	defer func() {
   301  		err := e.Destroy(s.callCtx)
   302  		c.Assert(err, jc.ErrorIsNil)
   303  	}()
   304  
   305  	opc := make(chan dummy.Operation, 200)
   306  	dummy.Listen(opc)
   307  
   308  	expectInfo := []network.SubnetInfo{{
   309  		CIDR:              "0.10.0.0/24",
   310  		ProviderId:        "dummy-private",
   311  		AvailabilityZones: []string{"zone1", "zone2"},
   312  	}, {
   313  		CIDR:       "0.20.0.0/24",
   314  		ProviderId: "dummy-public",
   315  	}}
   316  
   317  	ids := []network.Id{"dummy-private", "dummy-public", "foo-bar"}
   318  	netInfo, err := e.Subnets(s.callCtx, "i-foo", ids)
   319  	c.Assert(err, jc.ErrorIsNil)
   320  	c.Assert(netInfo, jc.DeepEquals, expectInfo)
   321  	assertSubnets(c, e, opc, "i-foo", ids, expectInfo)
   322  
   323  	// Test filtering by id(s).
   324  	netInfo, err = e.Subnets(s.callCtx, "i-foo", nil)
   325  	c.Assert(err, jc.ErrorIsNil)
   326  	c.Assert(netInfo, jc.DeepEquals, expectInfo)
   327  	assertSubnets(c, e, opc, "i-foo", nil, expectInfo)
   328  	netInfo, err = e.Subnets(s.callCtx, "i-foo", ids[0:1])
   329  	c.Assert(err, jc.ErrorIsNil)
   330  	c.Assert(netInfo, jc.DeepEquals, expectInfo[0:1])
   331  	assertSubnets(c, e, opc, "i-foo", ids[0:1], expectInfo[0:1])
   332  	netInfo, err = e.Subnets(s.callCtx, "i-foo", ids[1:])
   333  	c.Assert(err, jc.ErrorIsNil)
   334  	c.Assert(netInfo, jc.DeepEquals, expectInfo[1:])
   335  	assertSubnets(c, e, opc, "i-foo", ids[1:], expectInfo[1:])
   336  
   337  	// Test we can induce errors.
   338  	s.breakMethods(c, e, "Subnets")
   339  	netInfo, err = e.Subnets(s.callCtx, "i-any", nil)
   340  	c.Assert(err, gc.ErrorMatches, `dummy\.Subnets is broken`)
   341  	c.Assert(netInfo, gc.HasLen, 0)
   342  }
   343  
   344  func assertInterfaces(c *gc.C, e environs.Environ, opc chan dummy.Operation, expectInstId instance.Id, expectInfo []network.InterfaceInfo) {
   345  	select {
   346  	case op := <-opc:
   347  		netOp, ok := op.(dummy.OpNetworkInterfaces)
   348  		if !ok {
   349  			c.Fatalf("unexpected op: %#v", op)
   350  		}
   351  		c.Check(netOp.Env, gc.Equals, e.Config().Name())
   352  		c.Check(netOp.InstanceId, gc.Equals, expectInstId)
   353  		c.Check(netOp.Info, jc.DeepEquals, expectInfo)
   354  		return
   355  	case <-time.After(testing.ShortWait):
   356  		c.Fatalf("time out wating for operation")
   357  	}
   358  }
   359  
   360  func assertSubnets(
   361  	c *gc.C,
   362  	e environs.Environ,
   363  	opc chan dummy.Operation,
   364  	instId instance.Id,
   365  	subnetIds []network.Id,
   366  	expectInfo []network.SubnetInfo,
   367  ) {
   368  	select {
   369  	case op := <-opc:
   370  		netOp, ok := op.(dummy.OpSubnets)
   371  		if !ok {
   372  			c.Fatalf("unexpected op: %#v", op)
   373  		}
   374  		c.Check(netOp.InstanceId, gc.Equals, instId)
   375  		c.Check(netOp.SubnetIds, jc.DeepEquals, subnetIds)
   376  		c.Check(netOp.Info, jc.DeepEquals, expectInfo)
   377  		return
   378  	case <-time.After(testing.ShortWait):
   379  		c.Fatalf("time out wating for operation")
   380  	}
   381  }