func (s *ClientSuite) TestExport(c *gc.C) { var stub jujutesting.Stub apiCaller := apitesting.APICallerFunc(func(objType string, version int, id, request string, arg, result interface{}) error { stub.AddCall(objType+"."+request, id, arg) out := result.(*params.SerializedModel) *out = params.SerializedModel{ Bytes: []byte("foo"), Charms: []string{"cs:foo-1"}, Tools: []params.SerializedModelTools{{ Version: "2.0.0-trusty-amd64", URI: "/tools/0", }}, } return nil }) client := migrationmaster.NewClient(apiCaller, nil) out, err := client.Export() c.Assert(err, jc.ErrorIsNil) stub.CheckCalls(c, []jujutesting.StubCall{ {"MigrationMaster.Export", []interface{}{"", nil}}, }) c.Assert(out, gc.DeepEquals, migration.SerializedModel{ Bytes: []byte("foo"), Charms: []string{"cs:foo-1"}, Tools: map[version.Binary]string{ version.MustParseBinary("2.0.0-trusty-amd64"): "/tools/0", }, }) }
func (s *ClientSuite) TestModelInfo(c *gc.C) { var stub jujutesting.Stub owner := names.NewUserTag("owner") apiCaller := apitesting.APICallerFunc(func(objType string, v int, id, request string, arg, result interface{}) error { stub.AddCall(objType+"."+request, id, arg) *(result.(*params.MigrationModelInfo)) = params.MigrationModelInfo{ UUID: "uuid", Name: "name", OwnerTag: owner.String(), AgentVersion: version.MustParse("1.2.3"), } return nil }) client := migrationmaster.NewClient(apiCaller, nil) model, err := client.ModelInfo() stub.CheckCalls(c, []jujutesting.StubCall{ {"MigrationMaster.ModelInfo", []interface{}{"", nil}}, }) c.Check(err, jc.ErrorIsNil) c.Check(model, jc.DeepEquals, migration.ModelInfo{ UUID: "uuid", Name: "name", Owner: owner, AgentVersion: version.MustParse("1.2.3"), }) }
func (s *migrationWatcherSuite) TestWatch(c *gc.C) { // Create a state server m, password := s.Factory.MakeMachineReturningPassword(c, &factory.MachineParams{ Jobs: []state.MachineJob{state.JobManageModel}, Nonce: "noncey", }) // Create a model to migrate. hostedState := s.Factory.MakeModel(c, nil) // Connect as a state server to the hosted environment. apiInfo := s.APIInfo(c) apiInfo.Tag = m.Tag() apiInfo.Password = password apiInfo.ModelTag = hostedState.ModelTag() apiInfo.Nonce = "noncey" apiConn, err := api.Open(apiInfo, api.DialOpts{}) c.Assert(err, jc.ErrorIsNil) defer apiConn.Close() // Start watching for a migration. client := migrationmaster.NewClient(apiConn) w, err := client.Watch() c.Assert(err, jc.ErrorIsNil) defer func() { c.Assert(worker.Stop(w), jc.ErrorIsNil) }() // Should be no initial events. select { case _, ok := <-w.Changes(): c.Fatalf("watcher sent unexpected change: (_, %v)", ok) case <-time.After(coretesting.ShortWait): } // Now create a migration. targetInfo := migration.TargetInfo{ ControllerTag: names.NewModelTag(utils.MustNewUUID().String()), Addrs: []string{"1.2.3.4:5"}, CACert: "trust me I'm an authority", AuthTag: names.NewUserTag("dog"), Password: "******", } _, err = hostedState.CreateModelMigration(state.ModelMigrationSpec{ InitiatedBy: names.NewUserTag("someone"), TargetInfo: targetInfo, }) c.Assert(err, jc.ErrorIsNil) // Event with correct target details should be emitted. select { case reportedTargetInfo, ok := <-w.Changes(): c.Assert(ok, jc.IsTrue) c.Assert(reportedTargetInfo, jc.DeepEquals, targetInfo) case <-time.After(coretesting.LongWait): c.Fatalf("watcher didn't emit an event") } }
func (s *ClientSuite) TestMinionReportsFailedCall(c *gc.C) { apiCaller := apitesting.APICallerFunc(func(string, int, string, string, interface{}, interface{}) error { return errors.New("blam") }) client := migrationmaster.NewClient(apiCaller, nil) _, err := client.MinionReports() c.Assert(err, gc.ErrorMatches, "blam") }
func (s *ClientSuite) TestSetPhaseError(c *gc.C) { apiCaller := apitesting.APICallerFunc(func(string, int, string, string, interface{}, interface{}) error { return errors.New("boom") }) client := migrationmaster.NewClient(apiCaller) err := client.SetPhase(migration.QUIESCE) c.Assert(err, gc.ErrorMatches, "boom") }
func (s *ClientSuite) TestExportError(c *gc.C) { apiCaller := apitesting.APICallerFunc(func(string, int, string, string, interface{}, interface{}) error { return errors.New("blam") }) client := migrationmaster.NewClient(apiCaller) _, err := client.Export() c.Assert(err, gc.ErrorMatches, "blam") }
func (s *ClientSuite) TestWatchErr(c *gc.C) { apiCaller := apitesting.APICallerFunc(func(objType string, version int, id, request string, arg, result interface{}) error { return errors.New("boom") }) client := migrationmaster.NewClient(apiCaller) _, err := client.Watch() c.Assert(err, gc.ErrorMatches, "boom") }
func (s *ClientSuite) TestSetStatusMessageError(c *gc.C) { apiCaller := apitesting.APICallerFunc(func(string, int, string, string, interface{}, interface{}) error { return errors.New("boom") }) client := migrationmaster.NewClient(apiCaller, nil) err := client.SetStatusMessage("foo") c.Assert(err, gc.ErrorMatches, "boom") }
func (s *ClientSuite) TestMinionReportsInvalidPhase(c *gc.C) { apiCaller := apitesting.APICallerFunc(func(_ string, _ int, _ string, _ string, _ interface{}, result interface{}) error { out := result.(*params.MinionReports) *out = params.MinionReports{ Phase: "BLARGH", } return nil }) client := migrationmaster.NewClient(apiCaller, nil) _, err := client.MinionReports() c.Assert(err, gc.ErrorMatches, `invalid phase: "BLARGH"`) }
func (s *ClientSuite) TestMigrationStatus(c *gc.C) { mac, err := macaroon.New([]byte("secret"), "id", "location") c.Assert(err, jc.ErrorIsNil) macs := []macaroon.Slice{{mac}} macsJSON, err := json.Marshal(macs) c.Assert(err, jc.ErrorIsNil) modelUUID := utils.MustNewUUID().String() controllerUUID := utils.MustNewUUID().String() controllerTag := names.NewControllerTag(controllerUUID) timestamp := time.Date(2016, 6, 22, 16, 42, 44, 0, time.UTC) apiCaller := apitesting.APICallerFunc(func(_ string, _ int, _, _ string, _, result interface{}) error { out := result.(*params.MasterMigrationStatus) *out = params.MasterMigrationStatus{ Spec: params.MigrationSpec{ ModelTag: names.NewModelTag(modelUUID).String(), TargetInfo: params.MigrationTargetInfo{ ControllerTag: controllerTag.String(), Addrs: []string{"2.2.2.2:2"}, CACert: "cert", AuthTag: names.NewUserTag("admin").String(), Password: "******", Macaroons: string(macsJSON), }, ExternalControl: true, }, MigrationId: "id", Phase: "IMPORT", PhaseChangedTime: timestamp, } return nil }) client := migrationmaster.NewClient(apiCaller, nil) status, err := client.MigrationStatus() c.Assert(err, jc.ErrorIsNil) c.Assert(status, gc.DeepEquals, migration.MigrationStatus{ MigrationId: "id", ModelUUID: modelUUID, Phase: migration.IMPORT, PhaseChangedTime: timestamp, ExternalControl: true, TargetInfo: migration.TargetInfo{ ControllerTag: controllerTag, Addrs: []string{"2.2.2.2:2"}, CACert: "cert", AuthTag: names.NewUserTag("admin"), Password: "******", Macaroons: macs, }, }) }
func (s *ClientSuite) TestMinionReportsBadFailedTag(c *gc.C) { apiCaller := apitesting.APICallerFunc(func(_ string, _ int, _ string, _ string, _ interface{}, result interface{}) error { out := result.(*params.MinionReports) *out = params.MinionReports{ Phase: "IMPORT", Failed: []string{"dave"}, } return nil }) client := migrationmaster.NewClient(apiCaller, nil) _, err := client.MinionReports() c.Assert(err, gc.ErrorMatches, `processing failed agents: "dave" is not a valid tag`) }
func (s *ClientSuite) TestPrechecks(c *gc.C) { var stub jujutesting.Stub apiCaller := apitesting.APICallerFunc(func(objType string, version int, id, request string, arg, result interface{}) error { stub.AddCall(objType+"."+request, id, arg) return errors.New("blam") }) client := migrationmaster.NewClient(apiCaller, nil) err := client.Prechecks() c.Check(err, gc.ErrorMatches, "blam") stub.CheckCalls(c, []jujutesting.StubCall{ {"MigrationMaster.Prechecks", []interface{}{"", nil}}, }) }
func (s *ClientSuite) TestReap(c *gc.C) { var stub jujutesting.Stub apiCaller := apitesting.APICallerFunc(func(objType string, version int, id, request string, arg, result interface{}) error { stub.AddCall(objType+"."+request, id, arg) return nil }) client := migrationmaster.NewClient(apiCaller, nil) err := client.Reap() c.Check(err, jc.ErrorIsNil) stub.CheckCalls(c, []jujutesting.StubCall{ {"MigrationMaster.Reap", []interface{}{"", nil}}, }) }
func (s *ClientSuite) TestSetPhase(c *gc.C) { var stub jujutesting.Stub apiCaller := apitesting.APICallerFunc(func(objType string, version int, id, request string, arg, result interface{}) error { stub.AddCall(objType+"."+request, id, arg) return nil }) client := migrationmaster.NewClient(apiCaller) err := client.SetPhase(migration.QUIESCE) c.Assert(err, jc.ErrorIsNil) expectedArg := params.SetMigrationPhaseArgs{Phase: "QUIESCE"} stub.CheckCalls(c, []jujutesting.StubCall{ {"MigrationMaster.SetPhase", []interface{}{"", expectedArg}}, }) }
func (s *ClientSuite) TestWatch(c *gc.C) { var stub jujutesting.Stub apiCaller := apitesting.APICallerFunc(func(objType string, version int, id, request string, arg, result interface{}) error { stub.AddCall(objType+"."+request, id, arg) switch request { case "Watch": *(result.(*params.NotifyWatchResult)) = params.NotifyWatchResult{ NotifyWatcherId: "abc", } case "Next": // The full success case is tested in api/watcher. return errors.New("boom") case "Stop": } return nil }) client := migrationmaster.NewClient(apiCaller) w, err := client.Watch() c.Assert(err, jc.ErrorIsNil) defer worker.Stop(w) errC := make(chan error) go func() { errC <- w.Wait() }() select { case err := <-errC: c.Assert(err, gc.ErrorMatches, "boom") expectedCalls := []jujutesting.StubCall{ {"MigrationMaster.Watch", []interface{}{"", nil}}, {"NotifyWatcher.Next", []interface{}{"abc", nil}}, {"NotifyWatcher.Stop", []interface{}{"abc", nil}}, } // The Stop API call happens in a separate goroutine which // might execute after the worker has exited so wait for the // expected calls to arrive. for a := coretesting.LongAttempt.Start(); a.Next(); { if len(stub.Calls()) >= len(expectedCalls) { return } } stub.CheckCalls(c, expectedCalls) case <-time.After(coretesting.LongWait): c.Fatal("timed out waiting for watcher to die") } }
func (s *ClientSuite) TestExport(c *gc.C) { var stub jujutesting.Stub apiCaller := apitesting.APICallerFunc(func(objType string, version int, id, request string, arg, result interface{}) error { stub.AddCall(objType+"."+request, id, arg) out := result.(*params.SerializedModel) *out = params.SerializedModel{Bytes: []byte("foo")} return nil }) client := migrationmaster.NewClient(apiCaller) bytes, err := client.Export() c.Assert(err, jc.ErrorIsNil) stub.CheckCalls(c, []jujutesting.StubCall{ {"MigrationMaster.Export", []interface{}{"", nil}}, }) c.Assert(string(bytes), gc.Equals, "foo") }
func (s *ClientSuite) TestMinionReports(c *gc.C) { var stub jujutesting.Stub apiCaller := apitesting.APICallerFunc(func(objType string, version int, id, request string, arg, result interface{}) error { stub.AddCall(objType+"."+request, id, arg) out := result.(*params.MinionReports) *out = params.MinionReports{ MigrationId: "id", Phase: "IMPORT", SuccessCount: 4, UnknownCount: 3, UnknownSample: []string{ names.NewMachineTag("3").String(), names.NewMachineTag("4").String(), names.NewUnitTag("foo/0").String(), }, Failed: []string{ names.NewMachineTag("5").String(), names.NewUnitTag("foo/1").String(), names.NewUnitTag("foo/2").String(), }, } return nil }) client := migrationmaster.NewClient(apiCaller, nil) out, err := client.MinionReports() c.Assert(err, jc.ErrorIsNil) stub.CheckCalls(c, []jujutesting.StubCall{ {"MigrationMaster.MinionReports", []interface{}{"", nil}}, }) c.Assert(out, gc.DeepEquals, migration.MinionReports{ MigrationId: "id", Phase: migration.IMPORT, SuccessCount: 4, UnknownCount: 3, SomeUnknownMachines: []string{"3", "4"}, SomeUnknownUnits: []string{"foo/0"}, FailedMachines: []string{"5"}, FailedUnits: []string{"foo/1", "foo/2"}, }) }
func (s *ClientSuite) TestWatch(c *gc.C) { var stub jujutesting.Stub apiCaller := apitesting.APICallerFunc(func(objType string, version int, id, request string, arg, result interface{}) error { stub.AddCall(objType+"."+request, id, arg) *(result.(*params.NotifyWatchResult)) = params.NotifyWatchResult{ NotifyWatcherId: "123", } return nil }) expectWatch := &struct{ watcher.NotifyWatcher }{} newWatcher := func(caller base.APICaller, result params.NotifyWatchResult) watcher.NotifyWatcher { c.Check(caller, gc.NotNil) c.Check(result, jc.DeepEquals, params.NotifyWatchResult{NotifyWatcherId: "123"}) return expectWatch } client := migrationmaster.NewClient(apiCaller, newWatcher) w, err := client.Watch() c.Check(err, jc.ErrorIsNil) c.Check(w, gc.Equals, expectWatch) stub.CheckCalls(c, []jujutesting.StubCall{{"MigrationMaster.Watch", []interface{}{"", nil}}}) }
func (s *ClientSuite) TestGetMigrationStatus(c *gc.C) { modelUUID := utils.MustNewUUID().String() controllerUUID := utils.MustNewUUID().String() apiCaller := apitesting.APICallerFunc(func(_ string, _ int, _, _ string, _, result interface{}) error { out := result.(*params.FullMigrationStatus) *out = params.FullMigrationStatus{ Spec: params.ModelMigrationSpec{ ModelTag: names.NewModelTag(modelUUID).String(), TargetInfo: params.ModelMigrationTargetInfo{ ControllerTag: names.NewModelTag(controllerUUID).String(), Addrs: []string{"2.2.2.2:2"}, CACert: "cert", AuthTag: names.NewUserTag("admin").String(), Password: "******", }, }, Attempt: 3, Phase: "READONLY", } return nil }) client := migrationmaster.NewClient(apiCaller) status, err := client.GetMigrationStatus() c.Assert(err, jc.ErrorIsNil) c.Assert(status, gc.DeepEquals, migrationmaster.MigrationStatus{ ModelUUID: modelUUID, Attempt: 3, Phase: migration.READONLY, TargetInfo: migration.TargetInfo{ ControllerTag: names.NewModelTag(controllerUUID), Addrs: []string{"2.2.2.2:2"}, CACert: "cert", AuthTag: names.NewUserTag("admin"), Password: "******", }, }) }
func NewFacade(apiCaller base.APICaller) (Facade, error) { facade := migrationmaster.NewClient(apiCaller) return facade, nil }
// newWorker is a shim to allow New to work with PostUpgradeManifold. func newWorker(_ agent.Agent, apiCaller base.APICaller) (worker.Worker, error) { client := masterapi.NewClient(apiCaller) return New(client), nil }