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 := migrationminion.NewClient(apiCaller) _, err := client.Watch() c.Assert(err, gc.ErrorMatches, "boom") }
func (s *ClientSuite) TestReportError(c *gc.C) { apiCaller := apitesting.APICallerFunc(func(string, int, string, string, interface{}, interface{}) error { return errors.New("boom") }) client := migrationminion.NewClient(apiCaller) err := client.Report("id", migration.IMPORT, true) c.Assert(err, gc.ErrorMatches, "boom") }
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 := migrationminion.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{ {"Migrationminion.Watch", []interface{}{"", nil}}, {"MigrationStatusWatcher.Next", []interface{}{"abc", nil}}, {"MigrationStatusWatcher.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) TestReport(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, arg) return nil }) client := migrationminion.NewClient(apiCaller) err := client.Report("id", migration.IMPORT, true) c.Assert(err, jc.ErrorIsNil) stub.CheckCalls(c, []jujutesting.StubCall{ {"MigrationMinion.Report", []interface{}{params.MinionReport{ MigrationId: "id", Phase: "IMPORT", Success: true, }}}, }) }
func (s *migrationSuite) TestMigrationStatusWatcher(c *gc.C) { const nonce = "noncey" // Create a model to migrate. hostedState := s.Factory.MakeModel(c, &factory.ModelParams{Prepare: true}) defer hostedState.Close() hostedFactory := factory.NewFactory(hostedState) // Create a machine in the hosted model to connect as. m, password := hostedFactory.MakeMachineReturningPassword(c, &factory.MachineParams{ Nonce: nonce, }) // Connect as the machine to watch for migration status. apiInfo := s.APIInfo(c) apiInfo.Tag = m.Tag() apiInfo.Password = password apiInfo.ModelTag = hostedState.ModelTag() apiInfo.Nonce = nonce apiConn, err := api.Open(apiInfo, api.DialOpts{}) c.Assert(err, jc.ErrorIsNil) defer apiConn.Close() // Start watching for a migration. client := migrationminion.NewClient(apiConn) w, err := client.Watch() c.Assert(err, jc.ErrorIsNil) defer func() { c.Assert(worker.Stop(w), jc.ErrorIsNil) }() assertNoChange := func() { s.startSync(c, hostedState) select { case _, ok := <-w.Changes(): c.Fatalf("watcher sent unexpected change: (_, %v)", ok) case <-time.After(coretesting.ShortWait): } } assertChange := func(phase migration.Phase) { s.startSync(c, hostedState) select { case status, ok := <-w.Changes(): c.Assert(ok, jc.IsTrue) c.Assert(status.Phase, gc.Equals, phase) case <-time.After(coretesting.LongWait): c.Fatalf("watcher didn't emit an event") } assertNoChange() } // Initial event with no migration in progress. assertChange(migration.NONE) // Now create a migration, should trigger watcher. spec := state.ModelMigrationSpec{ InitiatedBy: names.NewUserTag("someone"), TargetInfo: migration.TargetInfo{ ControllerTag: names.NewModelTag(utils.MustNewUUID().String()), Addrs: []string{"1.2.3.4:5"}, CACert: "cert", AuthTag: names.NewUserTag("dog"), Password: "******", }, } mig, err := hostedState.CreateModelMigration(spec) c.Assert(err, jc.ErrorIsNil) assertChange(migration.QUIESCE) // Now abort the migration, this should be reported too. c.Assert(mig.SetPhase(migration.ABORT), jc.ErrorIsNil) assertChange(migration.ABORT) c.Assert(mig.SetPhase(migration.ABORTDONE), jc.ErrorIsNil) assertChange(migration.ABORTDONE) // Start a new migration, this should also trigger. _, err = hostedState.CreateModelMigration(spec) c.Assert(err, jc.ErrorIsNil) assertChange(migration.QUIESCE) }
func NewFacade(apiCaller base.APICaller) (Facade, error) { facade := migrationminion.NewClient(apiCaller) return facade, nil }