Ejemplo n.º 1
0
func (s *Suite) TestMigration(c *gc.C) {
	masterClient := newStubMasterClient(s.stub)
	w := migrationmaster.New(masterClient)

	// Trigger migration.
	masterClient.watcher.changes <- migration.TargetInfo{
		ControllerTag: names.NewModelTag("uuid"),
		Addrs:         []string{"1.2.3.4:5"},
		CACert:        "cert",
		AuthTag:       names.NewUserTag("admin"),
		Password:      "******",
	}

	// This error is temporary while migrationmaster is a WIP.
	runWorkerAndWait(c, w, "migration seen and aborted")

	// Observe that the migration was seen, the model exported, an API
	// connection to the target controller was made, the model was
	// imported and then the migration aborted.
	s.stub.CheckCalls(c, []jujutesting.StubCall{
		{"masterClient.Watch", nil},
		{"masterClient.Export", nil},
		{"apiOpen", []interface{}{&api.Info{
			Addrs:    []string{"1.2.3.4:5"},
			CACert:   "cert",
			Tag:      names.NewUserTag("admin"),
			Password: "******",
		}, api.DefaultDialOpts()}},
		{"APICall:MigrationTarget.Import",
			[]interface{}{params.SerializedModel{Bytes: fakeSerializedModel}}},
		{"masterClient.SetPhase", []interface{}{migration.ABORT}},
		{"Connection.Close", nil},
	})
}
Ejemplo n.º 2
0
func (s *Suite) TestImportFailure(c *gc.C) {
	masterClient := newStubMasterClient(s.stub)
	worker, err := migrationmaster.New(migrationmaster.Config{
		Facade: masterClient,
		Guard:  newStubGuard(s.stub),
	})
	c.Assert(err, jc.ErrorIsNil)
	s.connection.importErr = errors.New("boom")
	s.triggerMigration(masterClient)

	err = workertest.CheckKilled(c, worker)
	c.Assert(err, gc.Equals, migrationmaster.ErrDoneForNow)

	s.stub.CheckCalls(c, []jujutesting.StubCall{
		{"masterClient.Watch", nil},
		{"masterClient.GetMigrationStatus", nil},
		{"guard.Lockdown", nil},
		{"masterClient.SetPhase", []interface{}{migration.READONLY}},
		{"masterClient.SetPhase", []interface{}{migration.PRECHECK}},
		{"masterClient.SetPhase", []interface{}{migration.IMPORT}},
		{"masterClient.Export", nil},
		apiOpenCall,
		importCall,
		connCloseCall,
		{"masterClient.SetPhase", []interface{}{migration.ABORT}},
		apiOpenCall,
		abortCall,
		connCloseCall,
		{"masterClient.SetPhase", []interface{}{migration.ABORTDONE}},
	})
}
Ejemplo n.º 3
0
func (s *Suite) TestSUCCESSMinionWaitTimeout(c *gc.C) {
	// The SUCCESS phase is special in that even if some minions fail
	// to report the migration should continue. There's no turning
	// back from SUCCESS.
	s.facade.queueStatus(s.makeStatus(coremigration.SUCCESS))

	worker, err := migrationmaster.New(s.config)
	c.Assert(err, jc.ErrorIsNil)
	defer workertest.DirtyKill(c, worker)

	select {
	case <-s.clock.Alarms():
	case <-time.After(coretesting.LongWait):
		c.Fatal("timed out waiting for clock.After call")
	}

	// Move time ahead in order to trigger timeout.
	s.clock.Advance(15 * time.Minute)

	err = workertest.CheckKilled(c, worker)
	c.Assert(err, gc.Equals, migrationmaster.ErrMigrated)

	s.stub.CheckCalls(c, joinCalls(
		watchStatusLockdownCalls,
		[]jujutesting.StubCall{
			{"facade.WatchMinionReports", nil},
			{"facade.SetPhase", []interface{}{coremigration.LOGTRANSFER}},
			{"facade.SetPhase", []interface{}{coremigration.REAP}},
			{"facade.Reap", nil},
			{"facade.SetPhase", []interface{}{coremigration.DONE}},
		},
	))
}
Ejemplo n.º 4
0
func (s *Suite) TestWatchFailure(c *gc.C) {
	masterClient := newStubMasterClient(s.stub)
	masterClient.watchErr = errors.New("boom")
	worker, err := migrationmaster.New(migrationmaster.Config{
		Facade: masterClient,
		Guard:  newStubGuard(s.stub),
	})
	c.Assert(err, jc.ErrorIsNil)
	err = workertest.CheckKilled(c, worker)
	c.Assert(err, gc.ErrorMatches, "watching for migration: boom")
}
Ejemplo n.º 5
0
func checkNotValid(c *gc.C, config migrationmaster.Config, expect string) {
	check := func(err error) {
		c.Check(err, gc.ErrorMatches, expect)
		c.Check(err, jc.Satisfies, errors.IsNotValid)
	}

	err := config.Validate()
	check(err)

	worker, err := migrationmaster.New(config)
	c.Check(worker, gc.IsNil)
	check(err)
}
Ejemplo n.º 6
0
func (s *Suite) TestPreviouslyAbortedMigration(c *gc.C) {
	s.facade.queueStatus(s.makeStatus(coremigration.ABORTDONE))

	worker, err := migrationmaster.New(s.config)
	c.Assert(err, jc.ErrorIsNil)
	defer workertest.CleanKill(c, worker)

	s.waitForStubCalls(c, []string{
		"facade.Watch",
		"facade.MigrationStatus",
		"guard.Unlock",
	})
}
Ejemplo n.º 7
0
func (s *Suite) TestPreviouslyAbortedMigration(c *gc.C) {
	masterClient := newStubMasterClient(s.stub)
	masterClient.status.Phase = migration.ABORTDONE
	s.triggerMigration(masterClient)
	worker, err := migrationmaster.New(migrationmaster.Config{
		Facade: masterClient,
		Guard:  newStubGuard(s.stub),
	})
	c.Assert(err, jc.ErrorIsNil)
	workertest.CheckAlive(c, worker)
	workertest.CleanKill(c, worker)

	// No reliable way to test stub calls in this case unfortunately.
}
Ejemplo n.º 8
0
func (s *Suite) TestStatusNotFound(c *gc.C) {
	s.facade.statusErr = &params.Error{Code: params.CodeNotFound}
	s.facade.triggerWatcher()

	worker, err := migrationmaster.New(s.config)
	c.Assert(err, jc.ErrorIsNil)
	defer workertest.CleanKill(c, worker)

	s.waitForStubCalls(c, []string{
		"facade.Watch",
		"facade.MigrationStatus",
		"guard.Unlock",
	})
}
Ejemplo n.º 9
0
func (s *Suite) TestStatusError(c *gc.C) {
	masterClient := newStubMasterClient(s.stub)
	masterClient.statusErr = errors.New("splat")
	worker, err := migrationmaster.New(migrationmaster.Config{
		Facade: masterClient,
		Guard:  newStubGuard(s.stub),
	})
	c.Assert(err, jc.ErrorIsNil)
	s.triggerMigration(masterClient)

	err = workertest.CheckKilled(c, worker)

	s.stub.CheckCalls(c, []jujutesting.StubCall{
		{"masterClient.Watch", nil},
		{"masterClient.GetMigrationStatus", nil},
	})
}
Ejemplo n.º 10
0
func (s *Suite) TestPreviouslyCompletedMigration(c *gc.C) {
	masterClient := newStubMasterClient(s.stub)
	masterClient.status.Phase = migration.DONE
	s.triggerMigration(masterClient)
	worker, err := migrationmaster.New(migrationmaster.Config{
		Facade: masterClient,
		Guard:  newStubGuard(s.stub),
	})
	c.Assert(err, jc.ErrorIsNil)

	err = workertest.CheckKilled(c, worker)
	c.Assert(errors.Cause(err), gc.Equals, dependency.ErrUninstall)

	s.stub.CheckCalls(c, []jujutesting.StubCall{
		{"masterClient.Watch", nil},
		{"masterClient.GetMigrationStatus", nil},
	})
}
Ejemplo n.º 11
0
func (s *Suite) TestStatusNotFound(c *gc.C) {
	masterClient := newStubMasterClient(s.stub)
	masterClient.statusErr = &params.Error{Code: params.CodeNotFound}
	worker, err := migrationmaster.New(migrationmaster.Config{
		Facade: masterClient,
		Guard:  newStubGuard(s.stub),
	})
	c.Assert(err, jc.ErrorIsNil)
	s.triggerMigration(masterClient)

	workertest.CheckAlive(c, worker)
	workertest.CleanKill(c, worker)

	s.stub.CheckCalls(c, []jujutesting.StubCall{
		{"masterClient.Watch", nil},
		{"masterClient.GetMigrationStatus", nil},
		{"guard.Unlock", nil},
	})
}
Ejemplo n.º 12
0
func (s *Suite) TestLockdownError(c *gc.C) {
	masterClient := newStubMasterClient(s.stub)
	guard := newStubGuard(s.stub)
	guard.lockdownErr = errors.New("biff")
	worker, err := migrationmaster.New(migrationmaster.Config{
		Facade: masterClient,
		Guard:  guard,
	})
	c.Assert(err, jc.ErrorIsNil)
	s.triggerMigration(masterClient)

	err = workertest.CheckKilled(c, worker)
	c.Check(err, gc.ErrorMatches, "biff")

	s.stub.CheckCalls(c, []jujutesting.StubCall{
		{"masterClient.Watch", nil},
		{"masterClient.GetMigrationStatus", nil},
		{"guard.Lockdown", nil},
	})
}
Ejemplo n.º 13
0
func (s *Suite) TestUnlockError(c *gc.C) {
	masterClient := newStubMasterClient(s.stub)
	masterClient.statusErr = &params.Error{Code: params.CodeNotFound}
	guard := newStubGuard(s.stub)
	guard.unlockErr = errors.New("pow")
	worker, err := migrationmaster.New(migrationmaster.Config{
		Facade: masterClient,
		Guard:  guard,
	})
	c.Assert(err, jc.ErrorIsNil)
	s.triggerMigration(masterClient)

	err = workertest.CheckKilled(c, worker)
	c.Check(err, gc.ErrorMatches, "pow")

	s.stub.CheckCalls(c, []jujutesting.StubCall{
		{"masterClient.Watch", nil},
		{"masterClient.GetMigrationStatus", nil},
		{"guard.Unlock", nil},
	})
}
Ejemplo n.º 14
0
func (s *Suite) TestSuccessfulMigration(c *gc.C) {
	masterClient := newStubMasterClient(s.stub)
	worker, err := migrationmaster.New(migrationmaster.Config{
		Facade: masterClient,
		Guard:  newStubGuard(s.stub),
	})
	c.Assert(err, jc.ErrorIsNil)
	s.triggerMigration(masterClient)

	err = workertest.CheckKilled(c, worker)
	c.Assert(errors.Cause(err), gc.Equals, dependency.ErrUninstall)

	// Observe that the migration was seen, the model exported, an API
	// connection to the target controller was made, the model was
	// imported and then the migration completed.
	s.stub.CheckCalls(c, []jujutesting.StubCall{
		{"masterClient.Watch", nil},
		{"masterClient.GetMigrationStatus", nil},
		{"guard.Lockdown", nil},
		{"masterClient.SetPhase", []interface{}{migration.READONLY}},
		{"masterClient.SetPhase", []interface{}{migration.PRECHECK}},
		{"masterClient.SetPhase", []interface{}{migration.IMPORT}},
		{"masterClient.Export", nil},
		apiOpenCall,
		importCall,
		connCloseCall,
		{"masterClient.SetPhase", []interface{}{migration.VALIDATION}},
		apiOpenCall,
		activateCall,
		connCloseCall,
		{"masterClient.SetPhase", []interface{}{migration.SUCCESS}},
		{"masterClient.SetPhase", []interface{}{migration.LOGTRANSFER}},
		{"masterClient.SetPhase", []interface{}{migration.REAP}},
		{"masterClient.SetPhase", []interface{}{migration.DONE}},
	})
}
Ejemplo n.º 15
0
func (s *Suite) TestMigrationResume(c *gc.C) {
	// Test that a partially complete migration can be resumed.

	masterClient := newStubMasterClient(s.stub)
	worker, err := migrationmaster.New(migrationmaster.Config{
		Facade: masterClient,
		Guard:  newStubGuard(s.stub),
	})
	c.Assert(err, jc.ErrorIsNil)
	masterClient.status.Phase = migration.SUCCESS
	s.triggerMigration(masterClient)

	err = workertest.CheckKilled(c, worker)
	c.Assert(errors.Cause(err), gc.Equals, dependency.ErrUninstall)

	s.stub.CheckCalls(c, []jujutesting.StubCall{
		{"masterClient.Watch", nil},
		{"masterClient.GetMigrationStatus", nil},
		{"guard.Lockdown", nil},
		{"masterClient.SetPhase", []interface{}{migration.LOGTRANSFER}},
		{"masterClient.SetPhase", []interface{}{migration.REAP}},
		{"masterClient.SetPhase", []interface{}{migration.DONE}},
	})
}
Ejemplo n.º 16
0
func (s *Suite) runWorker(c *gc.C) error {
	w, err := migrationmaster.New(s.config)
	c.Assert(err, jc.ErrorIsNil)
	defer workertest.DirtyKill(c, w)
	return workertest.CheckKilled(c, w)
}
Ejemplo n.º 17
0
func (s *Suite) TestWatchFailure(c *gc.C) {
	client := newStubMasterClient(s.stub)
	client.watchErr = errors.New("boom")
	w := migrationmaster.New(client)
	runWorkerAndWait(c, w, "watching for migration: boom")
}