github.com/axw/juju@v0.0.0-20161005053422-4bd6544d08d4/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 fakeBootResource struct {
   188  	gomaasapi.BootResource
   189  	name         string
   190  	architecture string
   191  }
   192  
   193  func (r *fakeBootResource) Name() string {
   194  	return r.name
   195  }
   196  
   197  func (r *fakeBootResource) Architecture() string {
   198  	return r.architecture
   199  }
   200  
   201  type fakeMachine struct {
   202  	gomaasapi.Machine
   203  	*testing.Stub
   204  
   205  	zoneName      string
   206  	hostname      string
   207  	systemID      string
   208  	ipAddresses   []string
   209  	statusName    string
   210  	statusMessage string
   211  	cpuCount      int
   212  	memory        int
   213  	architecture  string
   214  	interfaceSet  []gomaasapi.Interface
   215  	tags          []string
   216  	createDevice  gomaasapi.Device
   217  }
   218  
   219  func newFakeMachine(systemID, architecture, statusName string) *fakeMachine {
   220  	return &fakeMachine{
   221  		Stub:         &testing.Stub{},
   222  		systemID:     systemID,
   223  		architecture: architecture,
   224  		statusName:   statusName,
   225  	}
   226  }
   227  
   228  func (m *fakeMachine) Tags() []string {
   229  	return m.tags
   230  }
   231  
   232  func (m *fakeMachine) SetOwnerData(data map[string]string) error {
   233  	m.MethodCall(m, "SetOwnerData", data)
   234  	return m.NextErr()
   235  }
   236  
   237  func (m *fakeMachine) CPUCount() int {
   238  	return m.cpuCount
   239  }
   240  
   241  func (m *fakeMachine) Memory() int {
   242  	return m.memory
   243  }
   244  
   245  func (m *fakeMachine) Architecture() string {
   246  	return m.architecture
   247  }
   248  
   249  func (m *fakeMachine) SystemID() string {
   250  	return m.systemID
   251  }
   252  
   253  func (m *fakeMachine) Hostname() string {
   254  	return m.hostname
   255  }
   256  
   257  func (m *fakeMachine) IPAddresses() []string {
   258  	return m.ipAddresses
   259  }
   260  
   261  func (m *fakeMachine) StatusName() string {
   262  	return m.statusName
   263  }
   264  
   265  func (m *fakeMachine) StatusMessage() string {
   266  	return m.statusMessage
   267  }
   268  
   269  func (m *fakeMachine) Zone() gomaasapi.Zone {
   270  	return fakeZone{name: m.zoneName}
   271  }
   272  
   273  func (m *fakeMachine) InterfaceSet() []gomaasapi.Interface {
   274  	return m.interfaceSet
   275  }
   276  
   277  func (m *fakeMachine) Start(args gomaasapi.StartArgs) error {
   278  	m.MethodCall(m, "Start", args)
   279  	return m.NextErr()
   280  }
   281  
   282  func (m *fakeMachine) CreateDevice(args gomaasapi.CreateMachineDeviceArgs) (gomaasapi.Device, error) {
   283  	m.MethodCall(m, "CreateDevice", args)
   284  	return m.createDevice, m.NextErr()
   285  }
   286  
   287  type fakeZone struct {
   288  	gomaasapi.Zone
   289  	name string
   290  }
   291  
   292  func (z fakeZone) Name() string {
   293  	return z.name
   294  }
   295  
   296  type fakeSpace struct {
   297  	gomaasapi.Space
   298  	name    string
   299  	id      int
   300  	subnets []gomaasapi.Subnet
   301  }
   302  
   303  func (s fakeSpace) Name() string {
   304  	return s.name
   305  }
   306  
   307  func (s fakeSpace) ID() int {
   308  	return s.id
   309  }
   310  
   311  func (s fakeSpace) Subnets() []gomaasapi.Subnet {
   312  	return s.subnets
   313  }
   314  
   315  type fakeSubnet struct {
   316  	gomaasapi.Subnet
   317  	id         int
   318  	space      string
   319  	vlan       gomaasapi.VLAN
   320  	gateway    string
   321  	cidr       string
   322  	dnsServers []string
   323  }
   324  
   325  func (s fakeSubnet) ID() int {
   326  	return s.id
   327  }
   328  
   329  func (s fakeSubnet) Space() string {
   330  	return s.space
   331  }
   332  
   333  func (s fakeSubnet) VLAN() gomaasapi.VLAN {
   334  	return s.vlan
   335  }
   336  
   337  func (s fakeSubnet) Gateway() string {
   338  	return s.gateway
   339  }
   340  
   341  func (s fakeSubnet) CIDR() string {
   342  	return s.cidr
   343  }
   344  
   345  func (s fakeSubnet) DNSServers() []string {
   346  	return s.dnsServers
   347  }
   348  
   349  type fakeVLAN struct {
   350  	gomaasapi.VLAN
   351  	id  int
   352  	vid int
   353  	mtu int
   354  }
   355  
   356  func (v fakeVLAN) ID() int {
   357  	return v.id
   358  }
   359  
   360  func (v fakeVLAN) VID() int {
   361  	return v.vid
   362  }
   363  
   364  func (v fakeVLAN) MTU() int {
   365  	return v.mtu
   366  }
   367  
   368  type fakeInterface struct {
   369  	gomaasapi.Interface
   370  	*testing.Stub
   371  
   372  	id         int
   373  	name       string
   374  	parents    []string
   375  	children   []string
   376  	type_      string
   377  	enabled    bool
   378  	vlan       gomaasapi.VLAN
   379  	links      []gomaasapi.Link
   380  	macAddress string
   381  }
   382  
   383  func (v *fakeInterface) ID() int {
   384  	return v.id
   385  }
   386  
   387  func (v *fakeInterface) Name() string {
   388  	return v.name
   389  }
   390  
   391  func (v *fakeInterface) Parents() []string {
   392  	return v.parents
   393  }
   394  
   395  func (v *fakeInterface) Children() []string {
   396  	return v.children
   397  }
   398  
   399  func (v *fakeInterface) Type() string {
   400  	return v.type_
   401  }
   402  
   403  func (v *fakeInterface) EffectiveMTU() int {
   404  	return 1500
   405  }
   406  
   407  func (v *fakeInterface) Enabled() bool {
   408  	return v.enabled
   409  }
   410  
   411  func (v *fakeInterface) VLAN() gomaasapi.VLAN {
   412  	return v.vlan
   413  }
   414  
   415  func (v *fakeInterface) Links() []gomaasapi.Link {
   416  	return v.links
   417  }
   418  
   419  func (v *fakeInterface) MACAddress() string {
   420  	return v.macAddress
   421  }
   422  
   423  func (v *fakeInterface) LinkSubnet(args gomaasapi.LinkSubnetArgs) error {
   424  	v.MethodCall(v, "LinkSubnet", args)
   425  	return v.NextErr()
   426  }
   427  
   428  type fakeLink struct {
   429  	gomaasapi.Link
   430  	id        int
   431  	mode      string
   432  	subnet    gomaasapi.Subnet
   433  	ipAddress string
   434  }
   435  
   436  func (l *fakeLink) ID() int {
   437  	return l.id
   438  }
   439  
   440  func (l *fakeLink) Mode() string {
   441  	return l.mode
   442  }
   443  
   444  func (l *fakeLink) Subnet() gomaasapi.Subnet {
   445  	return l.subnet
   446  }
   447  
   448  func (l *fakeLink) IPAddress() string {
   449  	return l.ipAddress
   450  }
   451  
   452  type fakeFile struct {
   453  	gomaasapi.File
   454  	name     string
   455  	url      string
   456  	contents []byte
   457  	deleted  bool
   458  	error    error
   459  }
   460  
   461  func (f *fakeFile) Filename() string {
   462  	return f.name
   463  }
   464  
   465  func (f *fakeFile) AnonymousURL() string {
   466  	return f.url
   467  }
   468  
   469  func (f *fakeFile) Delete() error {
   470  	f.deleted = true
   471  	return f.error
   472  }
   473  
   474  func (f *fakeFile) ReadAll() ([]byte, error) {
   475  	if f.error != nil {
   476  		return nil, f.error
   477  	}
   478  	return f.contents, nil
   479  }
   480  
   481  type fakeBlockDevice struct {
   482  	gomaasapi.BlockDevice
   483  	name string
   484  	path string
   485  	size uint64
   486  }
   487  
   488  func (bd fakeBlockDevice) Name() string {
   489  	return bd.name
   490  }
   491  
   492  func (bd fakeBlockDevice) Path() string {
   493  	return bd.path
   494  }
   495  
   496  func (bd fakeBlockDevice) Size() uint64 {
   497  	return bd.size
   498  }
   499  
   500  type fakeDevice struct {
   501  	gomaasapi.Device
   502  	*testing.Stub
   503  
   504  	interfaceSet []gomaasapi.Interface
   505  	systemID     string
   506  	interface_   gomaasapi.Interface
   507  }
   508  
   509  func (d *fakeDevice) InterfaceSet() []gomaasapi.Interface {
   510  	return d.interfaceSet
   511  }
   512  
   513  func (d *fakeDevice) SystemID() string {
   514  	return d.systemID
   515  }
   516  
   517  func (d *fakeDevice) CreateInterface(args gomaasapi.CreateInterfaceArgs) (gomaasapi.Interface, error) {
   518  	d.MethodCall(d, "CreateInterface", args)
   519  	d.interfaceSet = append(d.interfaceSet, d.interface_)
   520  	return d.interface_, d.NextErr()
   521  }
   522  
   523  func (d *fakeDevice) Delete() error {
   524  	d.MethodCall(d, "Delete")
   525  	return d.NextErr()
   526  }