github.com/wallyworld/juju@v0.0.0-20161013125918-6cf1bc9d917a/apiserver/machine/machiner_test.go (about)

     1  // Copyright 2013 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package machine_test
     5  
     6  import (
     7  	"time"
     8  
     9  	jc "github.com/juju/testing/checkers"
    10  	gc "gopkg.in/check.v1"
    11  	"gopkg.in/juju/names.v2"
    12  
    13  	"github.com/juju/juju/apiserver/common"
    14  	"github.com/juju/juju/apiserver/machine"
    15  	"github.com/juju/juju/apiserver/params"
    16  	apiservertesting "github.com/juju/juju/apiserver/testing"
    17  	"github.com/juju/juju/network"
    18  	"github.com/juju/juju/state"
    19  	"github.com/juju/juju/state/multiwatcher"
    20  	statetesting "github.com/juju/juju/state/testing"
    21  	"github.com/juju/juju/status"
    22  )
    23  
    24  type machinerSuite struct {
    25  	commonSuite
    26  
    27  	resources *common.Resources
    28  	machiner  *machine.MachinerAPI
    29  }
    30  
    31  var _ = gc.Suite(&machinerSuite{})
    32  
    33  func (s *machinerSuite) SetUpTest(c *gc.C) {
    34  	s.commonSuite.SetUpTest(c)
    35  
    36  	// Create the resource registry separately to track invocations to
    37  	// Register.
    38  	s.resources = common.NewResources()
    39  
    40  	// Create a machiner API for machine 1.
    41  	machiner, err := machine.NewMachinerAPI(
    42  		s.State,
    43  		s.resources,
    44  		s.authorizer,
    45  	)
    46  	c.Assert(err, jc.ErrorIsNil)
    47  	s.machiner = machiner
    48  }
    49  
    50  func (s *machinerSuite) TestMachinerFailsWithNonMachineAgentUser(c *gc.C) {
    51  	anAuthorizer := s.authorizer
    52  	anAuthorizer.Tag = names.NewUnitTag("ubuntu/1")
    53  	aMachiner, err := machine.NewMachinerAPI(s.State, s.resources, anAuthorizer)
    54  	c.Assert(err, gc.NotNil)
    55  	c.Assert(aMachiner, gc.IsNil)
    56  	c.Assert(err, gc.ErrorMatches, "permission denied")
    57  }
    58  
    59  func (s *machinerSuite) TestSetStatus(c *gc.C) {
    60  	now := time.Now()
    61  	sInfo := status.StatusInfo{
    62  		Status:  status.Started,
    63  		Message: "blah",
    64  		Since:   &now,
    65  	}
    66  	err := s.machine0.SetStatus(sInfo)
    67  	c.Assert(err, jc.ErrorIsNil)
    68  	sInfo = status.StatusInfo{
    69  		Status:  status.Stopped,
    70  		Message: "foo",
    71  		Since:   &now,
    72  	}
    73  	err = s.machine1.SetStatus(sInfo)
    74  	c.Assert(err, jc.ErrorIsNil)
    75  
    76  	args := params.SetStatus{
    77  		Entities: []params.EntityStatusArgs{
    78  			{Tag: "machine-1", Status: status.Error.String(), Info: "not really"},
    79  			{Tag: "machine-0", Status: status.Stopped.String(), Info: "foobar"},
    80  			{Tag: "machine-42", Status: status.Started.String(), Info: "blah"},
    81  		}}
    82  	result, err := s.machiner.SetStatus(args)
    83  	c.Assert(err, jc.ErrorIsNil)
    84  	c.Assert(result, gc.DeepEquals, params.ErrorResults{
    85  		Results: []params.ErrorResult{
    86  			{nil},
    87  			{apiservertesting.ErrUnauthorized},
    88  			{apiservertesting.ErrUnauthorized},
    89  		},
    90  	})
    91  
    92  	// Verify machine 0 - no change.
    93  	statusInfo, err := s.machine0.Status()
    94  	c.Assert(err, jc.ErrorIsNil)
    95  	c.Assert(statusInfo.Status, gc.Equals, status.Started)
    96  	c.Assert(statusInfo.Message, gc.Equals, "blah")
    97  	// ...machine 1 is fine though.
    98  	statusInfo, err = s.machine1.Status()
    99  	c.Assert(err, jc.ErrorIsNil)
   100  	c.Assert(statusInfo.Status, gc.Equals, status.Error)
   101  	c.Assert(statusInfo.Message, gc.Equals, "not really")
   102  }
   103  
   104  func (s *machinerSuite) TestLife(c *gc.C) {
   105  	err := s.machine1.EnsureDead()
   106  	c.Assert(err, jc.ErrorIsNil)
   107  	err = s.machine1.Refresh()
   108  	c.Assert(err, jc.ErrorIsNil)
   109  	c.Assert(s.machine1.Life(), gc.Equals, state.Dead)
   110  
   111  	args := params.Entities{Entities: []params.Entity{
   112  		{Tag: "machine-1"},
   113  		{Tag: "machine-0"},
   114  		{Tag: "machine-42"},
   115  	}}
   116  	result, err := s.machiner.Life(args)
   117  	c.Assert(err, jc.ErrorIsNil)
   118  	c.Assert(result, gc.DeepEquals, params.LifeResults{
   119  		Results: []params.LifeResult{
   120  			{Life: "dead"},
   121  			{Error: apiservertesting.ErrUnauthorized},
   122  			{Error: apiservertesting.ErrUnauthorized},
   123  		},
   124  	})
   125  }
   126  
   127  func (s *machinerSuite) TestEnsureDead(c *gc.C) {
   128  	c.Assert(s.machine0.Life(), gc.Equals, state.Alive)
   129  	c.Assert(s.machine1.Life(), gc.Equals, state.Alive)
   130  
   131  	args := params.Entities{Entities: []params.Entity{
   132  		{Tag: "machine-1"},
   133  		{Tag: "machine-0"},
   134  		{Tag: "machine-42"},
   135  	}}
   136  	result, err := s.machiner.EnsureDead(args)
   137  	c.Assert(err, jc.ErrorIsNil)
   138  	c.Assert(result, gc.DeepEquals, params.ErrorResults{
   139  		Results: []params.ErrorResult{
   140  			{nil},
   141  			{apiservertesting.ErrUnauthorized},
   142  			{apiservertesting.ErrUnauthorized},
   143  		},
   144  	})
   145  
   146  	err = s.machine0.Refresh()
   147  	c.Assert(err, jc.ErrorIsNil)
   148  	c.Assert(s.machine0.Life(), gc.Equals, state.Alive)
   149  	err = s.machine1.Refresh()
   150  	c.Assert(err, jc.ErrorIsNil)
   151  	c.Assert(s.machine1.Life(), gc.Equals, state.Dead)
   152  
   153  	// Try it again on a Dead machine; should work.
   154  	args = params.Entities{
   155  		Entities: []params.Entity{{Tag: "machine-1"}},
   156  	}
   157  	result, err = s.machiner.EnsureDead(args)
   158  	c.Assert(err, jc.ErrorIsNil)
   159  	c.Assert(result, gc.DeepEquals, params.ErrorResults{
   160  		Results: []params.ErrorResult{{nil}},
   161  	})
   162  
   163  	// Verify Life is unchanged.
   164  	err = s.machine1.Refresh()
   165  	c.Assert(err, jc.ErrorIsNil)
   166  	c.Assert(s.machine1.Life(), gc.Equals, state.Dead)
   167  }
   168  
   169  func (s *machinerSuite) TestSetMachineAddresses(c *gc.C) {
   170  	c.Assert(s.machine0.Addresses(), gc.HasLen, 0)
   171  	c.Assert(s.machine1.Addresses(), gc.HasLen, 0)
   172  
   173  	addresses := network.NewAddresses("127.0.0.1", "8.8.8.8")
   174  
   175  	args := params.SetMachinesAddresses{MachineAddresses: []params.MachineAddresses{
   176  		{Tag: "machine-1", Addresses: params.FromNetworkAddresses(addresses...)},
   177  		{Tag: "machine-0", Addresses: params.FromNetworkAddresses(addresses...)},
   178  		{Tag: "machine-42", Addresses: params.FromNetworkAddresses(addresses...)},
   179  	}}
   180  
   181  	result, err := s.machiner.SetMachineAddresses(args)
   182  	c.Assert(err, jc.ErrorIsNil)
   183  	c.Assert(result, gc.DeepEquals, params.ErrorResults{
   184  		Results: []params.ErrorResult{
   185  			{nil},
   186  			{apiservertesting.ErrUnauthorized},
   187  			{apiservertesting.ErrUnauthorized},
   188  		},
   189  	})
   190  
   191  	err = s.machine1.Refresh()
   192  	c.Assert(err, jc.ErrorIsNil)
   193  
   194  	expectedAddresses := network.NewAddresses("8.8.8.8", "127.0.0.1")
   195  	c.Assert(s.machine1.MachineAddresses(), gc.DeepEquals, expectedAddresses)
   196  	err = s.machine0.Refresh()
   197  	c.Assert(err, jc.ErrorIsNil)
   198  	c.Assert(s.machine0.MachineAddresses(), gc.HasLen, 0)
   199  }
   200  
   201  func (s *machinerSuite) TestSetEmptyMachineAddresses(c *gc.C) {
   202  	// Set some addresses so we can ensure they are removed.
   203  	addresses := network.NewAddresses("127.0.0.1", "8.8.8.8")
   204  	args := params.SetMachinesAddresses{MachineAddresses: []params.MachineAddresses{
   205  		{Tag: "machine-1", Addresses: params.FromNetworkAddresses(addresses...)},
   206  	}}
   207  	result, err := s.machiner.SetMachineAddresses(args)
   208  	c.Assert(err, jc.ErrorIsNil)
   209  	c.Assert(result, gc.DeepEquals, params.ErrorResults{
   210  		Results: []params.ErrorResult{
   211  			{nil},
   212  		},
   213  	})
   214  	err = s.machine1.Refresh()
   215  	c.Assert(err, jc.ErrorIsNil)
   216  	c.Assert(s.machine1.MachineAddresses(), gc.HasLen, 2)
   217  
   218  	args.MachineAddresses[0].Addresses = nil
   219  	result, err = s.machiner.SetMachineAddresses(args)
   220  	c.Assert(err, jc.ErrorIsNil)
   221  	c.Assert(result, gc.DeepEquals, params.ErrorResults{
   222  		Results: []params.ErrorResult{
   223  			{nil},
   224  		},
   225  	})
   226  
   227  	err = s.machine1.Refresh()
   228  	c.Assert(err, jc.ErrorIsNil)
   229  	c.Assert(s.machine1.MachineAddresses(), gc.HasLen, 0)
   230  }
   231  
   232  func (s *machinerSuite) TestJobs(c *gc.C) {
   233  	args := params.Entities{Entities: []params.Entity{
   234  		{Tag: "machine-1"},
   235  		{Tag: "machine-0"},
   236  		{Tag: "machine-42"},
   237  	}}
   238  
   239  	result, err := s.machiner.Jobs(args)
   240  	c.Assert(err, jc.ErrorIsNil)
   241  	c.Assert(result, gc.DeepEquals, params.JobsResults{
   242  		Results: []params.JobsResult{
   243  			{Jobs: []multiwatcher.MachineJob{multiwatcher.JobHostUnits}},
   244  			{Error: apiservertesting.ErrUnauthorized},
   245  			{Error: apiservertesting.ErrUnauthorized},
   246  		},
   247  	})
   248  }
   249  
   250  func (s *machinerSuite) TestWatch(c *gc.C) {
   251  	c.Assert(s.resources.Count(), gc.Equals, 0)
   252  
   253  	args := params.Entities{Entities: []params.Entity{
   254  		{Tag: "machine-1"},
   255  		{Tag: "machine-0"},
   256  		{Tag: "machine-42"},
   257  	}}
   258  	result, err := s.machiner.Watch(args)
   259  	c.Assert(err, jc.ErrorIsNil)
   260  	c.Assert(result, gc.DeepEquals, params.NotifyWatchResults{
   261  		Results: []params.NotifyWatchResult{
   262  			{NotifyWatcherId: "1"},
   263  			{Error: apiservertesting.ErrUnauthorized},
   264  			{Error: apiservertesting.ErrUnauthorized},
   265  		},
   266  	})
   267  
   268  	// Verify the resource was registered and stop when done
   269  	c.Assert(s.resources.Count(), gc.Equals, 1)
   270  	c.Assert(result.Results[0].NotifyWatcherId, gc.Equals, "1")
   271  	resource := s.resources.Get("1")
   272  	defer statetesting.AssertStop(c, resource)
   273  
   274  	// Check that the Watch has consumed the initial event ("returned" in
   275  	// the Watch call)
   276  	wc := statetesting.NewNotifyWatcherC(c, s.State, resource.(state.NotifyWatcher))
   277  	wc.AssertNoChange()
   278  }
   279  
   280  func (s *machinerSuite) TestSetObservedNetworkConfig(c *gc.C) {
   281  	c.Skip("dimitern: Test disabled until dummy provider is fixed properly")
   282  	devices, err := s.machine1.AllLinkLayerDevices()
   283  	c.Assert(err, jc.ErrorIsNil)
   284  	c.Assert(devices, gc.HasLen, 0)
   285  
   286  	err = s.machine1.SetInstanceInfo("i-foo", "FAKE_NONCE", nil, nil, nil, nil, nil)
   287  	c.Assert(err, jc.ErrorIsNil)
   288  
   289  	observedConfig := []params.NetworkConfig{{
   290  		InterfaceName: "lo",
   291  		InterfaceType: "loopback",
   292  		CIDR:          "127.0.0.0/8",
   293  		Address:       "127.0.0.1",
   294  	}, {
   295  		InterfaceName: "eth0",
   296  		InterfaceType: "ethernet",
   297  		MACAddress:    "aa:bb:cc:dd:ee:f0",
   298  		CIDR:          "0.10.0.0/24",
   299  		Address:       "0.10.0.2",
   300  	}, {
   301  		InterfaceName: "eth1",
   302  		InterfaceType: "ethernet",
   303  		MACAddress:    "aa:bb:cc:dd:ee:f1",
   304  		CIDR:          "0.20.0.0/24",
   305  		Address:       "0.20.0.2",
   306  	}}
   307  	args := params.SetMachineNetworkConfig{
   308  		Tag:    s.machine1.Tag().String(),
   309  		Config: observedConfig,
   310  	}
   311  
   312  	err = s.machiner.SetObservedNetworkConfig(args)
   313  	c.Assert(err, jc.ErrorIsNil)
   314  
   315  	devices, err = s.machine1.AllLinkLayerDevices()
   316  	c.Assert(err, jc.ErrorIsNil)
   317  	c.Assert(devices, gc.HasLen, 3)
   318  
   319  	for _, device := range devices {
   320  		c.Check(device.Name(), gc.Matches, `(lo|eth0|eth1)`)
   321  		c.Check(string(device.Type()), gc.Matches, `(loopback|ethernet)`)
   322  		c.Check(device.MACAddress(), gc.Matches, `(|aa:bb:cc:dd:ee:f0|aa:bb:cc:dd:ee:f1)`)
   323  	}
   324  }
   325  
   326  func (s *machinerSuite) TestSetObservedNetworkConfigPermissions(c *gc.C) {
   327  	args := params.SetMachineNetworkConfig{
   328  		Tag:    "machine-0",
   329  		Config: nil,
   330  	}
   331  
   332  	err := s.machiner.SetObservedNetworkConfig(args)
   333  	c.Assert(err, gc.ErrorMatches, "permission denied")
   334  }
   335  
   336  func (s *machinerSuite) TestSetProviderNetworkConfig(c *gc.C) {
   337  	c.Skip("dimitern: Test disabled until dummy provider is fixed properly")
   338  	devices, err := s.machine1.AllLinkLayerDevices()
   339  	c.Assert(err, jc.ErrorIsNil)
   340  	c.Assert(devices, gc.HasLen, 0)
   341  
   342  	err = s.machine1.SetInstanceInfo("i-foo", "FAKE_NONCE", nil, nil, nil, nil, nil)
   343  	c.Assert(err, jc.ErrorIsNil)
   344  
   345  	args := params.Entities{Entities: []params.Entity{
   346  		{Tag: s.machine1.Tag().String()},
   347  	}}
   348  
   349  	result, err := s.machiner.SetProviderNetworkConfig(args)
   350  	c.Assert(err, jc.ErrorIsNil)
   351  	c.Assert(result, gc.DeepEquals, params.ErrorResults{
   352  		Results: []params.ErrorResult{{nil}},
   353  	})
   354  
   355  	devices, err = s.machine1.AllLinkLayerDevices()
   356  	c.Assert(err, jc.ErrorIsNil)
   357  	c.Assert(devices, gc.HasLen, 3)
   358  
   359  	for _, device := range devices {
   360  		c.Check(device.Name(), gc.Matches, `eth[0-2]`)
   361  		c.Check(string(device.Type()), gc.Equals, "ethernet")
   362  		c.Check(device.MACAddress(), gc.Matches, `aa:bb:cc:dd:ee:f[0-2]`)
   363  		addrs, err := device.Addresses()
   364  		c.Check(err, jc.ErrorIsNil)
   365  		c.Check(addrs, gc.HasLen, 1)
   366  	}
   367  }
   368  
   369  func (s *machinerSuite) TestSetProviderNetworkConfigPermissions(c *gc.C) {
   370  	args := params.Entities{Entities: []params.Entity{
   371  		{Tag: "machine-1"},
   372  		{Tag: "machine-0"},
   373  		{Tag: "machine-42"},
   374  	}}
   375  
   376  	result, err := s.machiner.SetProviderNetworkConfig(args)
   377  	c.Assert(err, jc.ErrorIsNil)
   378  	c.Assert(result, gc.DeepEquals, params.ErrorResults{
   379  		Results: []params.ErrorResult{
   380  			{Error: apiservertesting.NotProvisionedError(s.machine1.Id())},
   381  			{Error: apiservertesting.ErrUnauthorized},
   382  			{Error: apiservertesting.ErrUnauthorized},
   383  		},
   384  	})
   385  }