func (s *suite) TestClosedChangesChannel(c *gc.C) {
	s.runDirtyTest(c, func(w worker.Worker, backend *mockBackend) {
		backend.sendModelChange("uuid1", "uuid2")
		workers := s.waitWorkers(c, 2)

		close(backend.envWatcher.changes)
		err := workertest.CheckKilled(c, w)
		c.Check(err, gc.ErrorMatches, "changes stopped")
		for _, worker := range workers {
			workertest.CheckKilled(c, worker)
		}
		s.assertNoWorkers(c)
	})
}
Esempio n. 2
0
func (*WorkerSuite) TestStopKills(c *gc.C) {
	w := workertest.NewErrorWorker(nil)
	defer workertest.CleanKill(c, w)

	worker.Stop(w)
	workertest.CheckKilled(c, w)
}
Esempio 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}},
		},
	))
}
Esempio n. 4
0
func (s *Suite) TestClosedWatcherChannel(c *gc.C) {
	close(s.client.watcher.changes)
	w, err := migrationminion.New(s.config)
	c.Assert(err, jc.ErrorIsNil)
	err = workertest.CheckKilled(c, w)
	c.Check(err, gc.ErrorMatches, "watcher channel closed")
}
Esempio n. 5
0
func (*WorkerSuite) TestStopWaits(c *gc.C) {
	w := workertest.NewForeverWorker(nil)
	defer workertest.CheckKilled(c, w)
	defer w.ReallyKill()

	done := make(chan struct{})
	go func() {
		defer close(done)
		worker.Stop(w)
	}()

	select {
	case <-time.After(coretesting.ShortWait):
	case <-done:
		c.Fatalf("Stop returned early")
	}

	w.ReallyKill()

	select {
	case <-done:
	case <-time.After(coretesting.LongWait):
		c.Fatalf("Stop never returned")
	}
}
Esempio n. 6
0
// TestWorstError starts an engine with two manifolds that always error
// with fatal errors. We test that the most important error is the one
// returned by the engine.
//
// This test uses manifolds whose workers ignore kill requests. We want
// this (dangerous!) behaviour so that we don't race over which fatal
// error is seen by the engine first.
func (s *EngineSuite) TestWorstError(c *gc.C) {
	worstErr := errors.New("awful error")
	callCount := 0
	s.fix.worstError = func(err1, err2 error) error {
		callCount++
		return worstErr
	}
	s.fix.isFatal = alwaysFatal
	s.fix.dirty = true
	s.fix.run(c, func(engine dependency.Engine) {

		mh1 := newErrorIgnoringManifoldHarness()
		err := engine.Install("task", mh1.Manifold())
		c.Assert(err, jc.ErrorIsNil)
		mh1.AssertOneStart(c)

		mh2 := newErrorIgnoringManifoldHarness()
		err = engine.Install("another task", mh2.Manifold())
		c.Assert(err, jc.ErrorIsNil)
		mh2.AssertOneStart(c)

		mh1.InjectError(c, errors.New("ping"))
		mh2.InjectError(c, errors.New("pong"))

		err = workertest.CheckKilled(c, engine)
		c.Check(errors.Cause(err), gc.Equals, worstErr)
		c.Check(callCount, gc.Equals, 2)
	})
}
Esempio n. 7
0
// cleanup checks that every expected worker has already been stopped by
// the SUT. (i.e.: don't set up more workers than your fixture needs).
func (wl *workerList) cleanup(c *gc.C) {
	for _, w := range wl.workers {
		if w != nil {
			workertest.CheckKilled(c, w)
		}
	}
}
Esempio n. 8
0
func (s *UndertakerSuite) TestProcessDyingModelErrorRetried(c *gc.C) {
	s.fix.errors = []error{
		nil, // ModelInfo
		nil, // SetStatus
		nil, // WatchModelResources,
		errors.New("meh, will retry"),  // ProcessDyingModel,
		errors.New("will retry again"), // ProcessDyingModel,
		nil, // ProcessDyingModel,
		nil, // SetStatus
		nil, // Destroy,
		nil, // RemoveModel
	}
	stub := s.fix.run(c, func(w worker.Worker) {
		workertest.CheckKilled(c, w)
	})
	stub.CheckCallNames(c,
		"ModelInfo",
		"SetStatus",
		"WatchModelResources",
		"ProcessDyingModel",
		"ProcessDyingModel",
		"ProcessDyingModel",
		"SetStatus",
		"Destroy",
		"RemoveModel",
	)
}
Esempio n. 9
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}},
	})
}
Esempio n. 10
0
func (s *UndertakerSuite) TestAlreadyDeadRemoves(c *gc.C) {
	s.fix.info.Result.Life = "dead"
	stub := s.fix.run(c, func(w worker.Worker) {
		workertest.CheckKilled(c, w)
	})
	stub.CheckCallNames(c, "ModelInfo", "SetStatus", "Destroy", "RemoveModel")
}
Esempio n. 11
0
func (s *Suite) TestWatchFailure(c *gc.C) {
	s.client.watchErr = errors.New("boom")
	w, err := migrationminion.New(s.config)
	c.Assert(err, jc.ErrorIsNil)
	err = workertest.CheckKilled(c, w)
	c.Check(err, gc.ErrorMatches, "setting up watcher: boom")
}
Esempio n. 12
0
func (s *EngineSuite) TestIsFatal(c *gc.C) {
	fatalErr := errors.New("KABOOM")
	s.fix.isFatal = isFatalIf(fatalErr)
	s.fix.dirty = true
	s.fix.run(c, func(engine dependency.Engine) {

		// Start two independent workers.
		mh1 := newManifoldHarness()
		err := engine.Install("some-task", mh1.Manifold())
		c.Assert(err, jc.ErrorIsNil)
		mh1.AssertOneStart(c)
		mh2 := newManifoldHarness()
		err = engine.Install("other-task", mh2.Manifold())
		c.Assert(err, jc.ErrorIsNil)
		mh2.AssertOneStart(c)

		// Bounce one worker with Just Some Error; check that worker bounces.
		mh1.InjectError(c, errors.New("splort"))
		mh1.AssertOneStart(c)
		mh2.AssertNoStart(c)

		// Bounce another worker with the fatal error; check the engine exits with
		// the right error.
		mh2.InjectError(c, fatalErr)
		mh1.AssertNoStart(c)
		mh2.AssertNoStart(c)
		err = workertest.CheckKilled(c, engine)
		c.Assert(err, gc.Equals, fatalErr)
	})
}
Esempio n. 13
0
func (*WorkerSuite) TestWatchErrorNonEmptyRunningActions(c *gc.C) {
	stub := &testing.Stub{}
	stub.SetErrors(nil, errors.New("ignored"), errors.New("kuso"))
	facade := &mockFacade{
		stub:           stub,
		runningActions: fakeRunningActions,
	}
	config := machineactions.WorkerConfig{
		Facade:       facade,
		MachineTag:   fakeTag,
		HandleAction: mockHandleAction(stub),
	}
	worker, err := machineactions.NewMachineActionsWorker(config)
	c.Assert(err, jc.ErrorIsNil)
	err = workertest.CheckKilled(c, worker)
	c.Check(err, gc.ErrorMatches, "kuso")

	stub.CheckCalls(c, []testing.StubCall{{
		FuncName: "RunningActions",
		Args:     []interface{}{fakeTag},
	}, {
		FuncName: "ActionFinish",
		Args:     []interface{}{thirdActionTag, params.ActionFailed, "action cancelled"},
	}, {
		FuncName: "WatchActionNotifications",
		Args:     []interface{}{fakeTag},
	}})
}
Esempio n. 14
0
func (s *Suite) TestReportKeysError(c *gc.C) {
	s.facade.reportErr = errors.New("blam")
	w, err := hostkeyreporter.New(s.config)
	c.Assert(err, jc.ErrorIsNil)
	err = workertest.CheckKilled(c, w)
	c.Check(err, gc.ErrorMatches, "blam")
}
Esempio n. 15
0
func (*ResumerSuite) TestImmediateFailure(c *gc.C) {
	fix := newFixture(errors.New("zap"))
	stub := fix.Run(c, func(_ *testing.Clock, worker *resumer.Resumer) {
		err := workertest.CheckKilled(c, worker)
		c.Check(err, gc.ErrorMatches, "cannot resume transactions: zap")
	})
	stub.CheckCallNames(c, "ResumeTransactions")
}
Esempio n. 16
0
func (s *Suite) TestCheckKilledTimeout(c *gc.C) {
	w := workertest.NewErrorWorker(nil)
	defer workertest.CleanKill(c, w)

	err := workertest.CheckKilled(c, w)
	s.CheckFailed(c)
	c.Check(err, gc.ErrorMatches, "workertest: worker not stopping")
}
Esempio n. 17
0
func (context *context) checkCleanedUp() {
	context.c.Logf("checking no active current pinger")
	context.mu.Lock()
	defer context.mu.Unlock()
	if context.current != nil {
		workertest.CheckKilled(context.c, context.current)
	}
}
Esempio n. 18
0
func (s *Suite) TestCheckKilledSuccess(c *gc.C) {
	expect := errors.New("snifplog")
	w := workertest.NewErrorWorker(expect)
	defer workertest.DirtyKill(c, w)

	w.Kill()
	err := workertest.CheckKilled(c, w)
	c.Check(err, gc.Equals, expect)
}
Esempio n. 19
0
func (s *UndertakerSuite) TestAlreadyDeadTimeMissingFinishes(c *gc.C) {
	s.fix.info.Result.Life = "dead"
	stub := s.fix.run(c, func(w worker.Worker, clock *coretesting.Clock) {
		waitAlarm(c, clock)
		clock.Advance(RIPTime)
		workertest.CheckKilled(c, w)
	})
	stub.CheckCallNames(c, "ModelInfo", "Destroy", "RemoveModel")
}
Esempio n. 20
0
func (s *undertakerSuite) TestErrorGettingRemovals(c *gc.C) {
	api := s.makeAPIWithWatcher()
	api.SetErrors(nil, errors.New("explodo"))
	w, err := machineundertaker.NewWorker(api, &fakeEnviron{})
	c.Assert(err, jc.ErrorIsNil)
	err = workertest.CheckKilled(c, w)
	c.Check(err, gc.ErrorMatches, "explodo")
	api.CheckCallNames(c, "WatchMachineRemovals", "AllMachineRemovals")
}
Esempio n. 21
0
func (s *Suite) TestSuccess(c *gc.C) {
	w, err := hostkeyreporter.New(s.config)
	c.Assert(err, jc.ErrorIsNil)
	err = workertest.CheckKilled(c, w)
	c.Check(err, gc.Equals, dependency.ErrUninstall)
	s.stub.CheckCalls(c, []jujutesting.StubCall{{
		"ReportKeys", []interface{}{"42", []string{"dsa", "ecdsa", "rsa"}},
	}})
}
Esempio n. 22
0
func (s *Suite) TestNoSSHDir(c *gc.C) {
	// No /etc/ssh at all
	s.config.RootDir = c.MkDir()

	w, err := hostkeyreporter.New(s.config)
	c.Assert(err, jc.ErrorIsNil)
	err = workertest.CheckKilled(c, w)
	c.Check(errors.Cause(err), gc.Equals, dependency.ErrUninstall)
}
Esempio n. 23
0
func (s *UndertakerSuite) TestModelInfoErrorFatal(c *gc.C) {
	s.fix.errors = []error{errors.New("pow")}
	s.fix.dirty = true
	stub := s.fix.run(c, func(w worker.Worker) {
		err := workertest.CheckKilled(c, w)
		c.Check(err, gc.ErrorMatches, "pow")
	})
	stub.CheckCallNames(c, "ModelInfo")
}
Esempio n. 24
0
func (s *UndertakerSuite) TestAliveError(c *gc.C) {
	s.fix.info.Result.Life = "alive"
	s.fix.dirty = true
	stub := s.fix.run(c, func(w worker.Worker) {
		err := workertest.CheckKilled(c, w)
		c.Check(err, gc.ErrorMatches, "model still alive")
	})
	stub.CheckCallNames(c, "ModelInfo")
}
Esempio n. 25
0
func (s *UndertakerSuite) TestWatchModelResourcesErrorFatal(c *gc.C) {
	s.fix.errors = []error{nil, nil, errors.New("pow")}
	s.fix.dirty = true
	stub := s.fix.run(c, func(w worker.Worker) {
		err := workertest.CheckKilled(c, w)
		c.Check(err, gc.ErrorMatches, "pow")
	})
	stub.CheckCallNames(c, "ModelInfo", "SetStatus", "WatchModelResources")
}
Esempio n. 26
0
func (s *FlagSuite) TestClaimFailureWaitSuccess(c *gc.C) {
	fix := newFixture(c, errClaimDenied, nil)
	fix.Run(c, func(flag *singular.FlagWorker, _ *coretesting.Clock, unblock func()) {
		c.Check(flag.Check(), jc.IsFalse)
		unblock()
		err := workertest.CheckKilled(c, flag)
		c.Check(errors.Cause(err), gc.Equals, singular.ErrRefresh)
	})
	fix.CheckClaimWait(c)
}
Esempio n. 27
0
func (s *FlagSuite) TestClaimFailureWaitError(c *gc.C) {
	fix := newFixture(c, errClaimDenied, errors.New("glug"))
	fix.Run(c, func(flag *singular.FlagWorker, _ *coretesting.Clock, unblock func()) {
		c.Check(flag.Check(), jc.IsFalse)
		unblock()
		err := workertest.CheckKilled(c, flag)
		c.Check(err, gc.ErrorMatches, "glug")
	})
	fix.CheckClaimWait(c)
}
Esempio n. 28
0
func (s *UndertakerSuite) TestRemoveModelErrorFatal(c *gc.C) {
	s.fix.errors = []error{nil, nil, nil, errors.New("pow")}
	s.fix.info.Result.Life = "dead"
	s.fix.dirty = true
	stub := s.fix.run(c, func(w worker.Worker) {
		err := workertest.CheckKilled(c, w)
		c.Check(err, gc.ErrorMatches, "cannot remove model: pow")
	})
	stub.CheckCallNames(c, "ModelInfo", "SetStatus", "Destroy", "RemoveModel")
}
Esempio n. 29
0
func (s *FlagSuite) TestClaimSuccessThenFailure(c *gc.C) {
	fix := newFixture(c, nil, errClaimDenied)
	fix.Run(c, func(flag *singular.FlagWorker, clock *coretesting.Clock, unblock func()) {
		<-clock.Alarms()
		clock.Advance(30 * time.Second)
		err := workertest.CheckKilled(c, flag)
		c.Check(errors.Cause(err), gc.Equals, singular.ErrRefresh)
	})
	fix.CheckClaims(c, 2)
}
Esempio n. 30
0
func (s *UndertakerSuite) TestDestroyErrorFatal(c *gc.C) {
	s.fix.errors = []error{nil, errors.New("pow")}
	s.fix.info.Result.Life = "dead"
	s.fix.dirty = true
	stub := s.fix.run(c, func(w worker.Worker, clock *coretesting.Clock) {
		err := workertest.CheckKilled(c, w)
		c.Check(err, gc.ErrorMatches, "pow")
	})
	stub.CheckCallNames(c, "ModelInfo", "Destroy")
}