github.com/wallyworld/juju@v0.0.0-20161013125918-6cf1bc9d917a/provider/maas/maas2_test.go (about)

     1  // Copyright 2016 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package maas
     5  
     6  import (
     7  	"github.com/juju/errors"
     8  	"github.com/juju/gomaasapi"
     9  	"github.com/juju/testing"
    10  	jc "github.com/juju/testing/checkers"
    11  	"github.com/juju/utils/set"
    12  	gc "gopkg.in/check.v1"
    13  
    14  	"github.com/juju/juju/cloud"
    15  	"github.com/juju/juju/environs"
    16  	"github.com/juju/juju/environs/config"
    17  	coretesting "github.com/juju/juju/testing"
    18  	"github.com/juju/juju/version"
    19  )
    20  
    21  type maas2Suite struct {
    22  	baseProviderSuite
    23  }
    24  
    25  func (suite *maas2Suite) injectController(controller gomaasapi.Controller) {
    26  	mockGetController := func(maasServer, apiKey string) (gomaasapi.Controller, error) {
    27  		return controller, nil
    28  	}
    29  	suite.PatchValue(&GetMAAS2Controller, mockGetController)
    30  }
    31  
    32  func (suite *maas2Suite) makeEnviron(c *gc.C, controller gomaasapi.Controller) *maasEnviron {
    33  	if controller != nil {
    34  		suite.injectController(controller)
    35  	}
    36  	testAttrs := coretesting.Attrs{}
    37  	for k, v := range maasEnvAttrs {
    38  		testAttrs[k] = v
    39  	}
    40  	testAttrs["agent-version"] = version.Current.String()
    41  
    42  	cred := cloud.NewCredential(cloud.OAuth1AuthType, map[string]string{
    43  		"maas-oauth": "a:b:c",
    44  	})
    45  	cloud := environs.CloudSpec{
    46  		Type:       "maas",
    47  		Name:       "maas",
    48  		Endpoint:   "http://any-old-junk.invalid/",
    49  		Credential: &cred,
    50  	}
    51  
    52  	attrs := coretesting.FakeConfig().Merge(testAttrs)
    53  	suite.controllerUUID = coretesting.FakeControllerConfig().ControllerUUID()
    54  	cfg, err := config.New(config.NoDefaults, attrs)
    55  	c.Assert(err, jc.ErrorIsNil)
    56  	env, err := NewEnviron(cloud, cfg)
    57  	c.Assert(err, jc.ErrorIsNil)
    58  	c.Assert(env, gc.NotNil)
    59  	return env
    60  }
    61  
    62  type fakeController struct {
    63  	gomaasapi.Controller
    64  	*testing.Stub
    65  
    66  	bootResources      []gomaasapi.BootResource
    67  	bootResourcesError error
    68  	machines           []gomaasapi.Machine
    69  	machinesError      error
    70  	machinesArgsCheck  func(gomaasapi.MachinesArgs)
    71  	zones              []gomaasapi.Zone
    72  	zonesError         error
    73  	spaces             []gomaasapi.Space
    74  	spacesError        error
    75  
    76  	allocateMachine          gomaasapi.Machine
    77  	allocateMachineMatches   gomaasapi.ConstraintMatches
    78  	allocateMachineError     error
    79  	allocateMachineArgsCheck func(gomaasapi.AllocateMachineArgs)
    80  
    81  	files []gomaasapi.File
    82  
    83  	devices []gomaasapi.Device
    84  }
    85  
    86  func newFakeController() *fakeController {
    87  	return &fakeController{Stub: &testing.Stub{}}
    88  }
    89  
    90  func newFakeControllerWithErrors(errors ...error) *fakeController {
    91  	controller := newFakeController()
    92  	controller.SetErrors(errors...)
    93  	return controller
    94  }
    95  
    96  func newFakeControllerWithFiles(files ...gomaasapi.File) *fakeController {
    97  	return &fakeController{Stub: &testing.Stub{}, files: files}
    98  }
    99  
   100  func (c *fakeController) Devices(args gomaasapi.DevicesArgs) ([]gomaasapi.Device, error) {
   101  	c.MethodCall(c, "Devices", args)
   102  	return c.devices, c.NextErr()
   103  }
   104  
   105  func (c *fakeController) Machines(args gomaasapi.MachinesArgs) ([]gomaasapi.Machine, error) {
   106  	if c.machinesArgsCheck != nil {
   107  		c.machinesArgsCheck(args)
   108  	}
   109  	if c.machinesError != nil {
   110  		return nil, c.machinesError
   111  	}
   112  	if len(args.SystemIDs) > 0 {
   113  		result := []gomaasapi.Machine{}
   114  		systemIds := set.NewStrings(args.SystemIDs...)
   115  		for _, machine := range c.machines {
   116  			if systemIds.Contains(machine.SystemID()) {
   117  				result = append(result, machine)
   118  			}
   119  		}
   120  		return result, nil
   121  	}
   122  	return c.machines, nil
   123  }
   124  
   125  func (c *fakeController) AllocateMachine(args gomaasapi.AllocateMachineArgs) (gomaasapi.Machine, gomaasapi.ConstraintMatches, error) {
   126  	if c.allocateMachineArgsCheck != nil {
   127  		c.allocateMachineArgsCheck(args)
   128  	}
   129  	if c.allocateMachineError != nil {
   130  		return nil, c.allocateMachineMatches, c.allocateMachineError
   131  	}
   132  	return c.allocateMachine, c.allocateMachineMatches, nil
   133  }
   134  
   135  func (c *fakeController) BootResources() ([]gomaasapi.BootResource, error) {
   136  	if c.bootResourcesError != nil {
   137  		return nil, c.bootResourcesError
   138  	}
   139  	return c.bootResources, nil
   140  }
   141  
   142  func (c *fakeController) Zones() ([]gomaasapi.Zone, error) {
   143  	if c.zonesError != nil {
   144  		return nil, c.zonesError
   145  	}
   146  	return c.zones, nil
   147  }
   148  
   149  func (c *fakeController) Spaces() ([]gomaasapi.Space, error) {
   150  	if c.spacesError != nil {
   151  		return nil, c.spacesError
   152  	}
   153  	return c.spaces, nil
   154  }
   155  
   156  func (c *fakeController) Files(prefix string) ([]gomaasapi.File, error) {
   157  	c.MethodCall(c, "Files", prefix)
   158  	return c.files, c.NextErr()
   159  }
   160  
   161  func (c *fakeController) GetFile(filename string) (gomaasapi.File, error) {
   162  	c.MethodCall(c, "GetFile", filename)
   163  	err := c.NextErr()
   164  	if err != nil {
   165  		return nil, err
   166  	}
   167  	// Try to find the file by name (needed for testing RemoveAll)
   168  	for _, file := range c.files {
   169  		if file.Filename() == filename {
   170  			return file, nil
   171  		}
   172  	}
   173  	// The test forgot to set up matching files!
   174  	return nil, errors.Errorf("no file named %v found - did you set up your test correctly?", filename)
   175  }
   176  
   177  func (c *fakeController) AddFile(args gomaasapi.AddFileArgs) error {
   178  	c.MethodCall(c, "AddFile", args)
   179  	return c.NextErr()
   180  }
   181  
   182  func (c *fakeController) ReleaseMachines(args gomaasapi.ReleaseMachinesArgs) error {
   183  	c.MethodCall(c, "ReleaseMachines", args)
   184  	return c.NextErr()
   185  }
   186  
   187  type fakeMachineOnlyController struct {
   188  	machines []gomaasapi.Machine
   189  }
   190  
   191  func (f *fakeMachineOnlyController) Machines(gomaasapi.MachinesArgs) ([]gomaasapi.Machine, error) {
   192  	return f.machines, nil
   193  }
   194  
   195  type fakeBootResource struct {
   196  	gomaasapi.BootResource
   197  	name         string
   198  	architecture string
   199  }
   200  
   201  func (r *fakeBootResource) Name() string {
   202  	return r.name
   203  }
   204  
   205  func (r *fakeBootResource) Architecture() string {
   206  	return r.architecture
   207  }
   208  
   209  type fakeMachine struct {
   210  	gomaasapi.Machine
   211  	*testing.Stub
   212  
   213  	zoneName      string
   214  	hostname      string
   215  	systemID      string
   216  	ipAddresses   []string
   217  	statusName    string
   218  	statusMessage string
   219  	cpuCount      int
   220  	memory        int
   221  	architecture  string
   222  	interfaceSet  []gomaasapi.Interface
   223  	tags          []string
   224  	createDevice  gomaasapi.Device
   225  }
   226  
   227  func newFakeMachine(systemID, architecture, statusName string) *fakeMachine {
   228  	return &fakeMachine{
   229  		Stub:         &testing.Stub{},
   230  		systemID:     systemID,
   231  		architecture: architecture,
   232  		statusName:   statusName,
   233  	}
   234  }
   235  
   236  func (m *fakeMachine) Tags() []string {
   237  	return m.tags
   238  }
   239  
   240  func (m *fakeMachine) SetOwnerData(data map[string]string) error {
   241  	m.MethodCall(m, "SetOwnerData", data)
   242  	return m.NextErr()
   243  }
   244  
   245  func (m *fakeMachine) CPUCount() int {
   246  	return m.cpuCount
   247  }
   248  
   249  func (m *fakeMachine) Memory() int {
   250  	return m.memory
   251  }
   252  
   253  func (m *fakeMachine) Architecture() string {
   254  	return m.architecture
   255  }
   256  
   257  func (m *fakeMachine) SystemID() string {
   258  	return m.systemID
   259  }
   260  
   261  func (m *fakeMachine) Hostname() string {
   262  	return m.hostname
   263  }
   264  
   265  func (m *fakeMachine) IPAddresses() []string {
   266  	return m.ipAddresses
   267  }
   268  
   269  func (m *fakeMachine) StatusName() string {
   270  	return m.statusName
   271  }
   272  
   273  func (m *fakeMachine) StatusMessage() string {
   274  	return m.statusMessage
   275  }
   276  
   277  func (m *fakeMachine) Zone() gomaasapi.Zone {
   278  	return fakeZone{name: m.zoneName}
   279  }
   280  
   281  func (m *fakeMachine) InterfaceSet() []gomaasapi.Interface {
   282  	return m.interfaceSet
   283  }
   284  
   285  func (m *fakeMachine) Start(args gomaasapi.StartArgs) error {
   286  	m.MethodCall(m, "Start", args)
   287  	return m.NextErr()
   288  }
   289  
   290  func (m *fakeMachine) CreateDevice(args gomaasapi.CreateMachineDeviceArgs) (gomaasapi.Device, error) {
   291  	m.MethodCall(m, "CreateDevice", args)
   292  	return m.createDevice, m.NextErr()
   293  }
   294  
   295  type fakeZone struct {
   296  	gomaasapi.Zone
   297  	name string
   298  }
   299  
   300  func (z fakeZone) Name() string {
   301  	return z.name
   302  }
   303  
   304  type fakeSpace struct {
   305  	gomaasapi.Space
   306  	name    string
   307  	id      int
   308  	subnets []gomaasapi.Subnet
   309  }
   310  
   311  func (s fakeSpace) Name() string {
   312  	return s.name
   313  }
   314  
   315  func (s fakeSpace) ID() int {
   316  	return s.id
   317  }
   318  
   319  func (s fakeSpace) Subnets() []gomaasapi.Subnet {
   320  	return s.subnets
   321  }
   322  
   323  type fakeSubnet struct {
   324  	gomaasapi.Subnet
   325  	id         int
   326  	space      string
   327  	vlan       gomaasapi.VLAN
   328  	gateway    string
   329  	cidr       string
   330  	dnsServers []string
   331  }
   332  
   333  func (s fakeSubnet) ID() int {
   334  	return s.id
   335  }
   336  
   337  func (s fakeSubnet) Space() string {
   338  	return s.space
   339  }
   340  
   341  func (s fakeSubnet) VLAN() gomaasapi.VLAN {
   342  	return s.vlan
   343  }
   344  
   345  func (s fakeSubnet) Gateway() string {
   346  	return s.gateway
   347  }
   348  
   349  func (s fakeSubnet) CIDR() string {
   350  	return s.cidr
   351  }
   352  
   353  func (s fakeSubnet) DNSServers() []string {
   354  	return s.dnsServers
   355  }
   356  
   357  type fakeVLAN struct {
   358  	gomaasapi.VLAN
   359  	id  int
   360  	vid int
   361  	mtu int
   362  }
   363  
   364  func (v fakeVLAN) ID() int {
   365  	return v.id
   366  }
   367  
   368  func (v fakeVLAN) VID() int {
   369  	return v.vid
   370  }
   371  
   372  func (v fakeVLAN) MTU() int {
   373  	return v.mtu
   374  }
   375  
   376  type fakeInterface struct {
   377  	gomaasapi.Interface
   378  	*testing.Stub
   379  
   380  	id         int
   381  	name       string
   382  	parents    []string
   383  	children   []string
   384  	type_      string
   385  	enabled    bool
   386  	vlan       gomaasapi.VLAN
   387  	links      []gomaasapi.Link
   388  	macAddress string
   389  }
   390  
   391  func (v *fakeInterface) ID() int {
   392  	return v.id
   393  }
   394  
   395  func (v *fakeInterface) Name() string {
   396  	return v.name
   397  }
   398  
   399  func (v *fakeInterface) Parents() []string {
   400  	return v.parents
   401  }
   402  
   403  func (v *fakeInterface) Children() []string {
   404  	return v.children
   405  }
   406  
   407  func (v *fakeInterface) Type() string {
   408  	return v.type_
   409  }
   410  
   411  func (v *fakeInterface) EffectiveMTU() int {
   412  	return 1500
   413  }
   414  
   415  func (v *fakeInterface) Enabled() bool {
   416  	return v.enabled
   417  }
   418  
   419  func (v *fakeInterface) VLAN() gomaasapi.VLAN {
   420  	return v.vlan
   421  }
   422  
   423  func (v *fakeInterface) Links() []gomaasapi.Link {
   424  	return v.links
   425  }
   426  
   427  func (v *fakeInterface) MACAddress() string {
   428  	return v.macAddress
   429  }
   430  
   431  func (v *fakeInterface) LinkSubnet(args gomaasapi.LinkSubnetArgs) error {
   432  	v.MethodCall(v, "LinkSubnet", args)
   433  	return v.NextErr()
   434  }
   435  
   436  type fakeLink struct {
   437  	gomaasapi.Link
   438  	id        int
   439  	mode      string
   440  	subnet    gomaasapi.Subnet
   441  	ipAddress string
   442  }
   443  
   444  func (l *fakeLink) ID() int {
   445  	return l.id
   446  }
   447  
   448  func (l *fakeLink) Mode() string {
   449  	return l.mode
   450  }
   451  
   452  func (l *fakeLink) Subnet() gomaasapi.Subnet {
   453  	return l.subnet
   454  }
   455  
   456  func (l *fakeLink) IPAddress() string {
   457  	return l.ipAddress
   458  }
   459  
   460  type fakeFile struct {
   461  	gomaasapi.File
   462  	name     string
   463  	url      string
   464  	contents []byte
   465  	deleted  bool
   466  	error    error
   467  }
   468  
   469  func (f *fakeFile) Filename() string {
   470  	return f.name
   471  }
   472  
   473  func (f *fakeFile) AnonymousURL() string {
   474  	return f.url
   475  }
   476  
   477  func (f *fakeFile) Delete() error {
   478  	f.deleted = true
   479  	return f.error
   480  }
   481  
   482  func (f *fakeFile) ReadAll() ([]byte, error) {
   483  	if f.error != nil {
   484  		return nil, f.error
   485  	}
   486  	return f.contents, nil
   487  }
   488  
   489  type fakeBlockDevice struct {
   490  	gomaasapi.BlockDevice
   491  	name string
   492  	path string
   493  	size uint64
   494  }
   495  
   496  func (bd fakeBlockDevice) Name() string {
   497  	return bd.name
   498  }
   499  
   500  func (bd fakeBlockDevice) Path() string {
   501  	return bd.path
   502  }
   503  
   504  func (bd fakeBlockDevice) Size() uint64 {
   505  	return bd.size
   506  }
   507  
   508  type fakeDevice struct {
   509  	gomaasapi.Device
   510  	*testing.Stub
   511  
   512  	interfaceSet []gomaasapi.Interface
   513  	systemID     string
   514  	interface_   gomaasapi.Interface
   515  }
   516  
   517  func (d *fakeDevice) InterfaceSet() []gomaasapi.Interface {
   518  	return d.interfaceSet
   519  }
   520  
   521  func (d *fakeDevice) SystemID() string {
   522  	return d.systemID
   523  }
   524  
   525  func (d *fakeDevice) CreateInterface(args gomaasapi.CreateInterfaceArgs) (gomaasapi.Interface, error) {
   526  	d.MethodCall(d, "CreateInterface", args)
   527  	d.interfaceSet = append(d.interfaceSet, d.interface_)
   528  	return d.interface_, d.NextErr()
   529  }
   530  
   531  func (d *fakeDevice) Delete() error {
   532  	d.MethodCall(d, "Delete")
   533  	return d.NextErr()
   534  }