github.com/axw/juju@v0.0.0-20161005053422-4bd6544d08d4/api/migrationmaster/client_test.go (about)

     1  // Copyright 2016 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package migrationmaster_test
     5  
     6  import (
     7  	"encoding/json"
     8  	"time"
     9  
    10  	"github.com/juju/errors"
    11  	jujutesting "github.com/juju/testing"
    12  	jc "github.com/juju/testing/checkers"
    13  	"github.com/juju/utils"
    14  	"github.com/juju/version"
    15  	gc "gopkg.in/check.v1"
    16  	"gopkg.in/juju/names.v2"
    17  	"gopkg.in/macaroon.v1"
    18  
    19  	"github.com/juju/juju/api/base"
    20  	apitesting "github.com/juju/juju/api/base/testing"
    21  	"github.com/juju/juju/api/migrationmaster"
    22  	"github.com/juju/juju/apiserver/params"
    23  	"github.com/juju/juju/core/migration"
    24  	"github.com/juju/juju/watcher"
    25  )
    26  
    27  type ClientSuite struct {
    28  	jujutesting.IsolationSuite
    29  }
    30  
    31  var _ = gc.Suite(&ClientSuite{})
    32  
    33  func (s *ClientSuite) TestWatch(c *gc.C) {
    34  	var stub jujutesting.Stub
    35  	apiCaller := apitesting.APICallerFunc(func(objType string, version int, id, request string, arg, result interface{}) error {
    36  		stub.AddCall(objType+"."+request, id, arg)
    37  		*(result.(*params.NotifyWatchResult)) = params.NotifyWatchResult{
    38  			NotifyWatcherId: "123",
    39  		}
    40  		return nil
    41  	})
    42  	expectWatch := &struct{ watcher.NotifyWatcher }{}
    43  	newWatcher := func(caller base.APICaller, result params.NotifyWatchResult) watcher.NotifyWatcher {
    44  		c.Check(caller, gc.NotNil)
    45  		c.Check(result, jc.DeepEquals, params.NotifyWatchResult{NotifyWatcherId: "123"})
    46  		return expectWatch
    47  	}
    48  	client := migrationmaster.NewClient(apiCaller, newWatcher)
    49  
    50  	w, err := client.Watch()
    51  	c.Check(err, jc.ErrorIsNil)
    52  	c.Check(w, gc.Equals, expectWatch)
    53  	stub.CheckCalls(c, []jujutesting.StubCall{{"MigrationMaster.Watch", []interface{}{"", nil}}})
    54  }
    55  
    56  func (s *ClientSuite) TestWatchCallError(c *gc.C) {
    57  	apiCaller := apitesting.APICallerFunc(func(objType string, version int, id, request string, arg, result interface{}) error {
    58  		return errors.New("boom")
    59  	})
    60  	client := migrationmaster.NewClient(apiCaller, nil)
    61  	_, err := client.Watch()
    62  	c.Assert(err, gc.ErrorMatches, "boom")
    63  }
    64  
    65  func (s *ClientSuite) TestMigrationStatus(c *gc.C) {
    66  	mac, err := macaroon.New([]byte("secret"), "id", "location")
    67  	c.Assert(err, jc.ErrorIsNil)
    68  	macs := []macaroon.Slice{{mac}}
    69  	macsJSON, err := json.Marshal(macs)
    70  	c.Assert(err, jc.ErrorIsNil)
    71  
    72  	modelUUID := utils.MustNewUUID().String()
    73  	controllerUUID := utils.MustNewUUID().String()
    74  	controllerTag := names.NewControllerTag(controllerUUID)
    75  	timestamp := time.Date(2016, 6, 22, 16, 42, 44, 0, time.UTC)
    76  	apiCaller := apitesting.APICallerFunc(func(_ string, _ int, _, _ string, _, result interface{}) error {
    77  		out := result.(*params.MasterMigrationStatus)
    78  		*out = params.MasterMigrationStatus{
    79  			Spec: params.MigrationSpec{
    80  				ModelTag: names.NewModelTag(modelUUID).String(),
    81  				TargetInfo: params.MigrationTargetInfo{
    82  					ControllerTag: controllerTag.String(),
    83  					Addrs:         []string{"2.2.2.2:2"},
    84  					CACert:        "cert",
    85  					AuthTag:       names.NewUserTag("admin").String(),
    86  					Password:      "secret",
    87  					Macaroons:     string(macsJSON),
    88  				},
    89  				ExternalControl: true,
    90  			},
    91  			MigrationId:      "id",
    92  			Phase:            "IMPORT",
    93  			PhaseChangedTime: timestamp,
    94  		}
    95  		return nil
    96  	})
    97  	client := migrationmaster.NewClient(apiCaller, nil)
    98  
    99  	status, err := client.MigrationStatus()
   100  	c.Assert(err, jc.ErrorIsNil)
   101  	c.Assert(status, gc.DeepEquals, migration.MigrationStatus{
   102  		MigrationId:      "id",
   103  		ModelUUID:        modelUUID,
   104  		Phase:            migration.IMPORT,
   105  		PhaseChangedTime: timestamp,
   106  		ExternalControl:  true,
   107  		TargetInfo: migration.TargetInfo{
   108  			ControllerTag: controllerTag,
   109  			Addrs:         []string{"2.2.2.2:2"},
   110  			CACert:        "cert",
   111  			AuthTag:       names.NewUserTag("admin"),
   112  			Password:      "secret",
   113  			Macaroons:     macs,
   114  		},
   115  	})
   116  }
   117  
   118  func (s *ClientSuite) TestSetPhase(c *gc.C) {
   119  	var stub jujutesting.Stub
   120  	apiCaller := apitesting.APICallerFunc(func(objType string, version int, id, request string, arg, result interface{}) error {
   121  		stub.AddCall(objType+"."+request, id, arg)
   122  		return nil
   123  	})
   124  	client := migrationmaster.NewClient(apiCaller, nil)
   125  	err := client.SetPhase(migration.QUIESCE)
   126  	c.Assert(err, jc.ErrorIsNil)
   127  	expectedArg := params.SetMigrationPhaseArgs{Phase: "QUIESCE"}
   128  	stub.CheckCalls(c, []jujutesting.StubCall{
   129  		{"MigrationMaster.SetPhase", []interface{}{"", expectedArg}},
   130  	})
   131  }
   132  
   133  func (s *ClientSuite) TestSetPhaseError(c *gc.C) {
   134  	apiCaller := apitesting.APICallerFunc(func(string, int, string, string, interface{}, interface{}) error {
   135  		return errors.New("boom")
   136  	})
   137  	client := migrationmaster.NewClient(apiCaller, nil)
   138  	err := client.SetPhase(migration.QUIESCE)
   139  	c.Assert(err, gc.ErrorMatches, "boom")
   140  }
   141  
   142  func (s *ClientSuite) TestSetStatusMessage(c *gc.C) {
   143  	var stub jujutesting.Stub
   144  	apiCaller := apitesting.APICallerFunc(func(objType string, version int, id, request string, arg, result interface{}) error {
   145  		stub.AddCall(objType+"."+request, id, arg)
   146  		return nil
   147  	})
   148  	client := migrationmaster.NewClient(apiCaller, nil)
   149  	err := client.SetStatusMessage("foo")
   150  	c.Assert(err, jc.ErrorIsNil)
   151  	expectedArg := params.SetMigrationStatusMessageArgs{Message: "foo"}
   152  	stub.CheckCalls(c, []jujutesting.StubCall{
   153  		{"MigrationMaster.SetStatusMessage", []interface{}{"", expectedArg}},
   154  	})
   155  }
   156  
   157  func (s *ClientSuite) TestSetStatusMessageError(c *gc.C) {
   158  	apiCaller := apitesting.APICallerFunc(func(string, int, string, string, interface{}, interface{}) error {
   159  		return errors.New("boom")
   160  	})
   161  	client := migrationmaster.NewClient(apiCaller, nil)
   162  	err := client.SetStatusMessage("foo")
   163  	c.Assert(err, gc.ErrorMatches, "boom")
   164  }
   165  
   166  func (s *ClientSuite) TestModelInfo(c *gc.C) {
   167  	var stub jujutesting.Stub
   168  	owner := names.NewUserTag("owner")
   169  	apiCaller := apitesting.APICallerFunc(func(objType string, v int, id, request string, arg, result interface{}) error {
   170  		stub.AddCall(objType+"."+request, id, arg)
   171  		*(result.(*params.MigrationModelInfo)) = params.MigrationModelInfo{
   172  			UUID:         "uuid",
   173  			Name:         "name",
   174  			OwnerTag:     owner.String(),
   175  			AgentVersion: version.MustParse("1.2.3"),
   176  		}
   177  		return nil
   178  	})
   179  	client := migrationmaster.NewClient(apiCaller, nil)
   180  	model, err := client.ModelInfo()
   181  	stub.CheckCalls(c, []jujutesting.StubCall{
   182  		{"MigrationMaster.ModelInfo", []interface{}{"", nil}},
   183  	})
   184  	c.Check(err, jc.ErrorIsNil)
   185  	c.Check(model, jc.DeepEquals, migration.ModelInfo{
   186  		UUID:         "uuid",
   187  		Name:         "name",
   188  		Owner:        owner,
   189  		AgentVersion: version.MustParse("1.2.3"),
   190  	})
   191  }
   192  
   193  func (s *ClientSuite) TestPrechecks(c *gc.C) {
   194  	var stub jujutesting.Stub
   195  	apiCaller := apitesting.APICallerFunc(func(objType string, version int, id, request string, arg, result interface{}) error {
   196  		stub.AddCall(objType+"."+request, id, arg)
   197  		return errors.New("blam")
   198  	})
   199  	client := migrationmaster.NewClient(apiCaller, nil)
   200  	err := client.Prechecks()
   201  	c.Check(err, gc.ErrorMatches, "blam")
   202  	stub.CheckCalls(c, []jujutesting.StubCall{
   203  		{"MigrationMaster.Prechecks", []interface{}{"", nil}},
   204  	})
   205  }
   206  
   207  func (s *ClientSuite) TestExport(c *gc.C) {
   208  	var stub jujutesting.Stub
   209  	apiCaller := apitesting.APICallerFunc(func(objType string, version int, id, request string, arg, result interface{}) error {
   210  		stub.AddCall(objType+"."+request, id, arg)
   211  		out := result.(*params.SerializedModel)
   212  		*out = params.SerializedModel{
   213  			Bytes:  []byte("foo"),
   214  			Charms: []string{"cs:foo-1"},
   215  			Tools: []params.SerializedModelTools{{
   216  				Version: "2.0.0-trusty-amd64",
   217  				URI:     "/tools/0",
   218  			}},
   219  		}
   220  		return nil
   221  	})
   222  	client := migrationmaster.NewClient(apiCaller, nil)
   223  	out, err := client.Export()
   224  	c.Assert(err, jc.ErrorIsNil)
   225  	stub.CheckCalls(c, []jujutesting.StubCall{
   226  		{"MigrationMaster.Export", []interface{}{"", nil}},
   227  	})
   228  	c.Assert(out, gc.DeepEquals, migration.SerializedModel{
   229  		Bytes:  []byte("foo"),
   230  		Charms: []string{"cs:foo-1"},
   231  		Tools: map[version.Binary]string{
   232  			version.MustParseBinary("2.0.0-trusty-amd64"): "/tools/0",
   233  		},
   234  	})
   235  }
   236  
   237  func (s *ClientSuite) TestExportError(c *gc.C) {
   238  	apiCaller := apitesting.APICallerFunc(func(string, int, string, string, interface{}, interface{}) error {
   239  		return errors.New("blam")
   240  	})
   241  	client := migrationmaster.NewClient(apiCaller, nil)
   242  	_, err := client.Export()
   243  	c.Assert(err, gc.ErrorMatches, "blam")
   244  }
   245  
   246  func (s *ClientSuite) TestReap(c *gc.C) {
   247  	var stub jujutesting.Stub
   248  	apiCaller := apitesting.APICallerFunc(func(objType string, version int, id, request string, arg, result interface{}) error {
   249  		stub.AddCall(objType+"."+request, id, arg)
   250  		return nil
   251  	})
   252  	client := migrationmaster.NewClient(apiCaller, nil)
   253  	err := client.Reap()
   254  	c.Check(err, jc.ErrorIsNil)
   255  	stub.CheckCalls(c, []jujutesting.StubCall{
   256  		{"MigrationMaster.Reap", []interface{}{"", nil}},
   257  	})
   258  }
   259  
   260  func (s *ClientSuite) TestReapError(c *gc.C) {
   261  	apiCaller := apitesting.APICallerFunc(func(string, int, string, string, interface{}, interface{}) error {
   262  		return errors.New("blam")
   263  	})
   264  	client := migrationmaster.NewClient(apiCaller, nil)
   265  	err := client.Reap()
   266  	c.Assert(err, gc.ErrorMatches, "blam")
   267  }
   268  
   269  func (s *ClientSuite) TestWatchMinionReports(c *gc.C) {
   270  	var stub jujutesting.Stub
   271  	apiCaller := apitesting.APICallerFunc(func(objType string, version int, id, request string, arg, result interface{}) error {
   272  		stub.AddCall(objType+"."+request, id, arg)
   273  		*(result.(*params.NotifyWatchResult)) = params.NotifyWatchResult{
   274  			NotifyWatcherId: "123",
   275  		}
   276  		return nil
   277  	})
   278  
   279  	expectWatch := &struct{ watcher.NotifyWatcher }{}
   280  	newWatcher := func(caller base.APICaller, result params.NotifyWatchResult) watcher.NotifyWatcher {
   281  		c.Check(caller, gc.NotNil)
   282  		c.Check(result, jc.DeepEquals, params.NotifyWatchResult{NotifyWatcherId: "123"})
   283  		return expectWatch
   284  	}
   285  	client := migrationmaster.NewClient(apiCaller, newWatcher)
   286  
   287  	w, err := client.WatchMinionReports()
   288  	c.Check(err, jc.ErrorIsNil)
   289  	c.Check(w, gc.Equals, expectWatch)
   290  	stub.CheckCalls(c, []jujutesting.StubCall{{"MigrationMaster.WatchMinionReports", []interface{}{"", nil}}})
   291  }
   292  
   293  func (s *ClientSuite) TestWatchMinionReportsError(c *gc.C) {
   294  	apiCaller := apitesting.APICallerFunc(func(objType string, version int, id, request string, arg, result interface{}) error {
   295  		return errors.New("boom")
   296  	})
   297  	client := migrationmaster.NewClient(apiCaller, nil)
   298  	_, err := client.WatchMinionReports()
   299  	c.Assert(err, gc.ErrorMatches, "boom")
   300  }
   301  
   302  func (s *ClientSuite) TestMinionReports(c *gc.C) {
   303  	var stub jujutesting.Stub
   304  	apiCaller := apitesting.APICallerFunc(func(objType string, version int, id, request string, arg, result interface{}) error {
   305  		stub.AddCall(objType+"."+request, id, arg)
   306  		out := result.(*params.MinionReports)
   307  		*out = params.MinionReports{
   308  			MigrationId:  "id",
   309  			Phase:        "IMPORT",
   310  			SuccessCount: 4,
   311  			UnknownCount: 3,
   312  			UnknownSample: []string{
   313  				names.NewMachineTag("3").String(),
   314  				names.NewMachineTag("4").String(),
   315  				names.NewUnitTag("foo/0").String(),
   316  			},
   317  			Failed: []string{
   318  				names.NewMachineTag("5").String(),
   319  				names.NewUnitTag("foo/1").String(),
   320  				names.NewUnitTag("foo/2").String(),
   321  			},
   322  		}
   323  		return nil
   324  	})
   325  	client := migrationmaster.NewClient(apiCaller, nil)
   326  	out, err := client.MinionReports()
   327  	c.Assert(err, jc.ErrorIsNil)
   328  	stub.CheckCalls(c, []jujutesting.StubCall{
   329  		{"MigrationMaster.MinionReports", []interface{}{"", nil}},
   330  	})
   331  	c.Assert(out, gc.DeepEquals, migration.MinionReports{
   332  		MigrationId:         "id",
   333  		Phase:               migration.IMPORT,
   334  		SuccessCount:        4,
   335  		UnknownCount:        3,
   336  		SomeUnknownMachines: []string{"3", "4"},
   337  		SomeUnknownUnits:    []string{"foo/0"},
   338  		FailedMachines:      []string{"5"},
   339  		FailedUnits:         []string{"foo/1", "foo/2"},
   340  	})
   341  }
   342  
   343  func (s *ClientSuite) TestMinionReportsFailedCall(c *gc.C) {
   344  	apiCaller := apitesting.APICallerFunc(func(string, int, string, string, interface{}, interface{}) error {
   345  		return errors.New("blam")
   346  	})
   347  	client := migrationmaster.NewClient(apiCaller, nil)
   348  	_, err := client.MinionReports()
   349  	c.Assert(err, gc.ErrorMatches, "blam")
   350  }
   351  
   352  func (s *ClientSuite) TestMinionReportsInvalidPhase(c *gc.C) {
   353  	apiCaller := apitesting.APICallerFunc(func(_ string, _ int, _ string, _ string, _ interface{}, result interface{}) error {
   354  		out := result.(*params.MinionReports)
   355  		*out = params.MinionReports{
   356  			Phase: "BLARGH",
   357  		}
   358  		return nil
   359  	})
   360  	client := migrationmaster.NewClient(apiCaller, nil)
   361  	_, err := client.MinionReports()
   362  	c.Assert(err, gc.ErrorMatches, `invalid phase: "BLARGH"`)
   363  }
   364  
   365  func (s *ClientSuite) TestMinionReportsBadUnknownTag(c *gc.C) {
   366  	apiCaller := apitesting.APICallerFunc(func(_ string, _ int, _ string, _ string, _ interface{}, result interface{}) error {
   367  		out := result.(*params.MinionReports)
   368  		*out = params.MinionReports{
   369  			Phase:         "IMPORT",
   370  			UnknownSample: []string{"carl"},
   371  		}
   372  		return nil
   373  	})
   374  	client := migrationmaster.NewClient(apiCaller, nil)
   375  	_, err := client.MinionReports()
   376  	c.Assert(err, gc.ErrorMatches, `processing unknown agents: "carl" is not a valid tag`)
   377  }
   378  
   379  func (s *ClientSuite) TestMinionReportsBadFailedTag(c *gc.C) {
   380  	apiCaller := apitesting.APICallerFunc(func(_ string, _ int, _ string, _ string, _ interface{}, result interface{}) error {
   381  		out := result.(*params.MinionReports)
   382  		*out = params.MinionReports{
   383  			Phase:  "IMPORT",
   384  			Failed: []string{"dave"},
   385  		}
   386  		return nil
   387  	})
   388  	client := migrationmaster.NewClient(apiCaller, nil)
   389  	_, err := client.MinionReports()
   390  	c.Assert(err, gc.ErrorMatches, `processing failed agents: "dave" is not a valid tag`)
   391  }