github.com/wallyworld/juju@v0.0.0-20161013125918-6cf1bc9d917a/worker/provisioner/lxd-broker_test.go (about)

     1  // Copyright 2013-2016 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package provisioner_test
     5  
     6  import (
     7  	"runtime"
     8  
     9  	"github.com/juju/errors"
    10  	gitjujutesting "github.com/juju/testing"
    11  	jc "github.com/juju/testing/checkers"
    12  	"github.com/juju/utils/arch"
    13  	"github.com/juju/version"
    14  	gc "gopkg.in/check.v1"
    15  	"gopkg.in/juju/names.v2"
    16  
    17  	"github.com/juju/juju/agent"
    18  	"github.com/juju/juju/cloudconfig/instancecfg"
    19  	"github.com/juju/juju/constraints"
    20  	"github.com/juju/juju/container"
    21  	"github.com/juju/juju/environs"
    22  	"github.com/juju/juju/instance"
    23  	"github.com/juju/juju/network"
    24  	coretesting "github.com/juju/juju/testing"
    25  	coretools "github.com/juju/juju/tools"
    26  	jujuversion "github.com/juju/juju/version"
    27  	"github.com/juju/juju/worker/provisioner"
    28  )
    29  
    30  type lxdBrokerSuite struct {
    31  	coretesting.BaseSuite
    32  	broker      environs.InstanceBroker
    33  	agentConfig agent.ConfigSetterWriter
    34  	api         *fakeAPI
    35  	manager     *fakeContainerManager
    36  }
    37  
    38  var _ = gc.Suite(&lxdBrokerSuite{})
    39  
    40  func (s *lxdBrokerSuite) SetUpTest(c *gc.C) {
    41  	s.BaseSuite.SetUpTest(c)
    42  	if runtime.GOOS == "windows" {
    43  		c.Skip("Skipping lxd tests on windows")
    44  	}
    45  
    46  	// To isolate the tests from the host's architecture, we override it here.
    47  	s.PatchValue(&arch.HostArch, func() string { return arch.AMD64 })
    48  
    49  	var err error
    50  	s.agentConfig, err = agent.NewAgentConfig(
    51  		agent.AgentConfigParams{
    52  			Paths:             agent.NewPathsWithDefaults(agent.Paths{DataDir: "/not/used/here"}),
    53  			Tag:               names.NewMachineTag("1"),
    54  			UpgradedToVersion: jujuversion.Current,
    55  			Password:          "dummy-secret",
    56  			Nonce:             "nonce",
    57  			APIAddresses:      []string{"10.0.0.1:1234"},
    58  			CACert:            coretesting.CACert,
    59  			Controller:        coretesting.ControllerTag,
    60  			Model:             coretesting.ModelTag,
    61  		})
    62  	c.Assert(err, jc.ErrorIsNil)
    63  	s.api = NewFakeAPI()
    64  	s.manager = &fakeContainerManager{}
    65  	s.broker, err = provisioner.NewLxdBroker(s.api, s.manager, s.agentConfig)
    66  	c.Assert(err, jc.ErrorIsNil)
    67  }
    68  
    69  func (s *lxdBrokerSuite) startInstance(c *gc.C, machineId string) *environs.StartInstanceResult {
    70  	return callStartInstance(c, s, s.broker, machineId)
    71  }
    72  
    73  func (s *lxdBrokerSuite) TestStartInstance(c *gc.C) {
    74  	machineId := "1/lxd/0"
    75  	s.startInstance(c, machineId)
    76  	s.api.CheckCalls(c, []gitjujutesting.StubCall{{
    77  		FuncName: "ContainerConfig",
    78  	}, {
    79  		FuncName: "PrepareContainerInterfaceInfo",
    80  		Args:     []interface{}{names.NewMachineTag("1-lxd-0")},
    81  	}})
    82  	s.manager.CheckCallNames(c, "CreateContainer")
    83  	call := s.manager.Calls()[0]
    84  	c.Assert(call.Args[0], gc.FitsTypeOf, &instancecfg.InstanceConfig{})
    85  	instanceConfig := call.Args[0].(*instancecfg.InstanceConfig)
    86  	c.Assert(instanceConfig.ToolsList(), gc.HasLen, 1)
    87  	c.Assert(instanceConfig.ToolsList().Arches(), jc.DeepEquals, []string{"amd64"})
    88  }
    89  
    90  func (s *lxdBrokerSuite) TestStartInstancePopulatesNetworkInfo(c *gc.C) {
    91  	patchResolvConf(s, c)
    92  
    93  	result := s.startInstance(c, "1/lxd/0")
    94  	c.Assert(result.NetworkInfo, gc.HasLen, 1)
    95  	iface := result.NetworkInfo[0]
    96  	c.Assert(iface, jc.DeepEquals, network.InterfaceInfo{
    97  		DeviceIndex:         0,
    98  		CIDR:                "0.1.2.0/24",
    99  		InterfaceName:       "dummy0",
   100  		ParentInterfaceName: "lxdbr0",
   101  		MACAddress:          "aa:bb:cc:dd:ee:ff",
   102  		Address:             network.NewAddress("0.1.2.3"),
   103  		GatewayAddress:      network.NewAddress("0.1.2.1"),
   104  		DNSServers:          network.NewAddresses("ns1.dummy", "ns2.dummy"),
   105  		DNSSearchDomains:    []string{"dummy", "invalid"},
   106  	})
   107  }
   108  
   109  func (s *lxdBrokerSuite) TestStartInstancePopulatesFallbackNetworkInfo(c *gc.C) {
   110  	patchResolvConf(s, c)
   111  
   112  	s.api.SetErrors(
   113  		nil, // ContainerConfig succeeds
   114  		errors.NotSupportedf("container address allocation"),
   115  	)
   116  	result := s.startInstance(c, "1/lxd/0")
   117  
   118  	c.Assert(result.NetworkInfo, jc.DeepEquals, []network.InterfaceInfo{{
   119  		DeviceIndex:         0,
   120  		InterfaceName:       "eth0",
   121  		InterfaceType:       network.EthernetInterface,
   122  		ConfigType:          network.ConfigDHCP,
   123  		ParentInterfaceName: "lxdbr0",
   124  		DNSServers:          network.NewAddresses("ns1.dummy", "ns2.dummy"),
   125  		DNSSearchDomains:    []string{"dummy", "invalid"},
   126  	}})
   127  }
   128  
   129  func (s *lxdBrokerSuite) TestStartInstanceNoHostArchTools(c *gc.C) {
   130  	_, err := s.broker.StartInstance(environs.StartInstanceParams{
   131  		Tools: coretools.List{{
   132  			// non-host-arch tools should be filtered out by StartInstance
   133  			Version: version.MustParseBinary("2.3.4-quantal-arm64"),
   134  			URL:     "http://tools.testing.invalid/2.3.4-quantal-arm64.tgz",
   135  		}},
   136  		InstanceConfig: makeInstanceConfig(c, s, "1/lxd/0"),
   137  	})
   138  	c.Assert(err, gc.ErrorMatches, `need tools for arch amd64, only found \[arm64\]`)
   139  }
   140  
   141  type fakeContainerManager struct {
   142  	gitjujutesting.Stub
   143  }
   144  
   145  func (m *fakeContainerManager) CreateContainer(instanceConfig *instancecfg.InstanceConfig,
   146  	cons constraints.Value,
   147  	series string,
   148  	network *container.NetworkConfig,
   149  	storage *container.StorageConfig,
   150  	callback container.StatusCallback,
   151  ) (instance.Instance, *instance.HardwareCharacteristics, error) {
   152  	m.MethodCall(m, "CreateContainer", instanceConfig, cons, series, network, storage, callback)
   153  	return nil, nil, m.NextErr()
   154  }
   155  
   156  func (m *fakeContainerManager) DestroyContainer(id instance.Id) error {
   157  	m.MethodCall(m, "DestroyContainer", id)
   158  	return m.NextErr()
   159  }
   160  
   161  func (m *fakeContainerManager) ListContainers() ([]instance.Instance, error) {
   162  	m.MethodCall(m, "ListContainers")
   163  	return nil, m.NextErr()
   164  }
   165  
   166  func (m *fakeContainerManager) Namespace() instance.Namespace {
   167  	ns, _ := instance.NewNamespace(coretesting.ModelTag.Id())
   168  	return ns
   169  }
   170  
   171  func (m *fakeContainerManager) IsInitialized() bool {
   172  	m.MethodCall(m, "IsInitialized")
   173  	m.PopNoErr()
   174  	return true
   175  }