github.com/wallyworld/juju@v0.0.0-20161013125918-6cf1bc9d917a/featuretests/api_undertaker_test.go (about)

     1  // Copyright 2015 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package featuretests
     5  
     6  import (
     7  	"github.com/juju/errors"
     8  	jc "github.com/juju/testing/checkers"
     9  	"github.com/juju/utils"
    10  	gc "gopkg.in/check.v1"
    11  
    12  	"github.com/juju/juju/api"
    13  	"github.com/juju/juju/api/undertaker"
    14  	apiwatcher "github.com/juju/juju/api/watcher"
    15  	"github.com/juju/juju/apiserver/params"
    16  	jujutesting "github.com/juju/juju/juju/testing"
    17  	"github.com/juju/juju/rpc"
    18  	"github.com/juju/juju/state"
    19  	coretesting "github.com/juju/juju/testing"
    20  	"github.com/juju/juju/testing/factory"
    21  	"github.com/juju/juju/watcher/watchertest"
    22  )
    23  
    24  // TODO(fwereade) 2016-03-17 lp:1558668
    25  // this is not a feature test; much of it is redundant, and other
    26  // bits should be tested elsewhere.
    27  type undertakerSuite struct {
    28  	jujutesting.JujuConnSuite
    29  }
    30  
    31  func (s *undertakerSuite) TestPermDenied(c *gc.C) {
    32  	nonManagerMachine, _ := s.OpenAPIAsNewMachine(c, state.JobHostUnits)
    33  	for _, conn := range []api.Connection{
    34  		nonManagerMachine,
    35  		s.APIState,
    36  	} {
    37  		undertakerClient, err := undertaker.NewClient(conn, apiwatcher.NewNotifyWatcher)
    38  		c.Assert(err, jc.ErrorIsNil)
    39  		c.Assert(undertakerClient, gc.NotNil)
    40  
    41  		_, err = undertakerClient.ModelInfo()
    42  		c.Assert(errors.Cause(err), gc.DeepEquals, &rpc.RequestError{
    43  			Message: "permission denied",
    44  			Code:    "unauthorized access",
    45  		})
    46  	}
    47  }
    48  
    49  func (s *undertakerSuite) TestStateEnvironInfo(c *gc.C) {
    50  	st, _ := s.OpenAPIAsNewMachine(c, state.JobManageModel)
    51  	undertakerClient, err := undertaker.NewClient(st, apiwatcher.NewNotifyWatcher)
    52  	c.Assert(err, jc.ErrorIsNil)
    53  	c.Assert(undertakerClient, gc.NotNil)
    54  
    55  	result, err := undertakerClient.ModelInfo()
    56  	c.Assert(err, jc.ErrorIsNil)
    57  	c.Assert(result, gc.NotNil)
    58  	c.Assert(result.Error, gc.IsNil)
    59  	info := result.Result
    60  	c.Assert(info.UUID, gc.Equals, coretesting.ModelTag.Id())
    61  	c.Assert(info.Name, gc.Equals, "controller")
    62  	c.Assert(info.GlobalName, gc.Equals, "user-admin/controller")
    63  	c.Assert(info.IsSystem, jc.IsTrue)
    64  	c.Assert(info.Life, gc.Equals, params.Alive)
    65  }
    66  
    67  func (s *undertakerSuite) TestStateProcessDyingEnviron(c *gc.C) {
    68  	st, _ := s.OpenAPIAsNewMachine(c, state.JobManageModel)
    69  	undertakerClient, err := undertaker.NewClient(st, apiwatcher.NewNotifyWatcher)
    70  	c.Assert(err, jc.ErrorIsNil)
    71  	c.Assert(undertakerClient, gc.NotNil)
    72  
    73  	err = undertakerClient.ProcessDyingModel()
    74  	c.Assert(err, gc.ErrorMatches, "model is not dying")
    75  
    76  	env, err := s.State.Model()
    77  	c.Assert(err, jc.ErrorIsNil)
    78  	c.Assert(env.Destroy(), jc.ErrorIsNil)
    79  	c.Assert(env.Refresh(), jc.ErrorIsNil)
    80  	c.Assert(env.Life(), gc.Equals, state.Dying)
    81  
    82  	err = undertakerClient.ProcessDyingModel()
    83  	c.Assert(err, gc.ErrorMatches, `model not empty, found 1 machine\(s\)`)
    84  }
    85  
    86  func (s *undertakerSuite) TestStateRemoveEnvironFails(c *gc.C) {
    87  	st, _ := s.OpenAPIAsNewMachine(c, state.JobManageModel)
    88  	undertakerClient, err := undertaker.NewClient(st, apiwatcher.NewNotifyWatcher)
    89  	c.Assert(err, jc.ErrorIsNil)
    90  	c.Assert(undertakerClient, gc.NotNil)
    91  	c.Assert(undertakerClient.RemoveModel(), gc.ErrorMatches, "can't remove model: model not dead")
    92  }
    93  
    94  func (s *undertakerSuite) TestHostedEnvironInfo(c *gc.C) {
    95  	undertakerClient, otherSt := s.hostedAPI(c)
    96  	defer otherSt.Close()
    97  
    98  	result, err := undertakerClient.ModelInfo()
    99  	c.Assert(err, jc.ErrorIsNil)
   100  	c.Assert(result, gc.NotNil)
   101  	c.Assert(result.Error, gc.IsNil)
   102  	envInfo := result.Result
   103  	c.Assert(envInfo.UUID, gc.Equals, otherSt.ModelUUID())
   104  	c.Assert(envInfo.Name, gc.Equals, "hosted-env")
   105  	c.Assert(envInfo.GlobalName, gc.Equals, "user-admin/hosted-env")
   106  	c.Assert(envInfo.IsSystem, jc.IsFalse)
   107  	c.Assert(envInfo.Life, gc.Equals, params.Alive)
   108  }
   109  
   110  func (s *undertakerSuite) TestHostedProcessDyingEnviron(c *gc.C) {
   111  	undertakerClient, otherSt := s.hostedAPI(c)
   112  	defer otherSt.Close()
   113  
   114  	err := undertakerClient.ProcessDyingModel()
   115  	c.Assert(err, gc.ErrorMatches, "model is not dying")
   116  
   117  	factory.NewFactory(otherSt).MakeApplication(c, nil)
   118  	env, err := otherSt.Model()
   119  	c.Assert(err, jc.ErrorIsNil)
   120  	c.Assert(env.Destroy(), jc.ErrorIsNil)
   121  	c.Assert(env.Refresh(), jc.ErrorIsNil)
   122  	c.Assert(env.Life(), gc.Equals, state.Dying)
   123  
   124  	err = otherSt.Cleanup()
   125  	c.Assert(err, jc.ErrorIsNil)
   126  	c.Assert(undertakerClient.ProcessDyingModel(), jc.ErrorIsNil)
   127  
   128  	c.Assert(env.Refresh(), jc.ErrorIsNil)
   129  	c.Assert(env.Life(), gc.Equals, state.Dead)
   130  }
   131  
   132  func (s *undertakerSuite) TestWatchModelResources(c *gc.C) {
   133  	undertakerClient, otherSt := s.hostedAPI(c)
   134  	defer otherSt.Close()
   135  
   136  	w, err := undertakerClient.WatchModelResources()
   137  	c.Assert(err, jc.ErrorIsNil)
   138  	defer w.Kill()
   139  	wc := watchertest.NewNotifyWatcherC(c, w, nil)
   140  	wc.AssertOneChange()
   141  	wc.AssertStops()
   142  }
   143  
   144  func (s *undertakerSuite) TestHostedRemoveEnviron(c *gc.C) {
   145  	undertakerClient, otherSt := s.hostedAPI(c)
   146  	defer otherSt.Close()
   147  
   148  	// Aborts on alive environ.
   149  	err := undertakerClient.RemoveModel()
   150  	c.Assert(err, gc.ErrorMatches, "can't remove model: model not dead")
   151  
   152  	factory.NewFactory(otherSt).MakeApplication(c, nil)
   153  	env, err := otherSt.Model()
   154  	c.Assert(err, jc.ErrorIsNil)
   155  	c.Assert(env.Destroy(), jc.ErrorIsNil)
   156  
   157  	// Aborts on dying environ.
   158  	err = undertakerClient.RemoveModel()
   159  	c.Assert(err, gc.ErrorMatches, "can't remove model: model not dead")
   160  
   161  	err = otherSt.Cleanup()
   162  	c.Assert(err, jc.ErrorIsNil)
   163  	c.Assert(undertakerClient.ProcessDyingModel(), jc.ErrorIsNil)
   164  
   165  	c.Assert(undertakerClient.RemoveModel(), jc.ErrorIsNil)
   166  	c.Assert(otherSt.EnsureModelRemoved(), jc.ErrorIsNil)
   167  }
   168  
   169  func (s *undertakerSuite) hostedAPI(c *gc.C) (*undertaker.Client, *state.State) {
   170  	otherState := s.Factory.MakeModel(c, &factory.ModelParams{Name: "hosted-env"})
   171  
   172  	password, err := utils.RandomPassword()
   173  	c.Assert(err, jc.ErrorIsNil)
   174  
   175  	machine := s.Factory.MakeMachine(c, &factory.MachineParams{
   176  		Jobs:     []state.MachineJob{state.JobManageModel},
   177  		Password: password,
   178  		Nonce:    "fake_nonce",
   179  	})
   180  
   181  	// Connect to hosted environ from controller.
   182  	info := s.APIInfo(c)
   183  	info.Tag = machine.Tag()
   184  	info.Password = password
   185  	info.Nonce = "fake_nonce"
   186  	info.ModelTag = otherState.ModelTag()
   187  
   188  	otherAPIState, err := api.Open(info, api.DefaultDialOpts())
   189  	c.Assert(err, jc.ErrorIsNil)
   190  
   191  	undertakerClient, err := undertaker.NewClient(otherAPIState, apiwatcher.NewNotifyWatcher)
   192  	c.Assert(err, jc.ErrorIsNil)
   193  	c.Assert(undertakerClient, gc.NotNil)
   194  
   195  	return undertakerClient, otherState
   196  }