Example #1
0
func (s *runcommandsSuite) SetUpTest(c *gc.C) {
	s.charmURL = charm.MustParseURL("cs:precise/mysql-2")
	s.remoteState = remotestate.Snapshot{
		CharmURL: s.charmURL,
	}
	s.mockRunner = mockRunner{runCommands: func(commands string) (*exec.ExecResponse, error) {
		return s.runCommands(commands)
	}}
	s.callbacks = &mockCallbacks{}
	s.opFactory = operation.NewFactory(operation.FactoryParams{
		Callbacks: s.callbacks,
		RunnerFactory: &mockRunnerFactory{
			newCommandRunner: func(info runnercontext.CommandInfo) (runner.Runner, error) {
				return &s.mockRunner, nil
			},
		},
	})

	s.commands = runcommands.NewCommands()
	s.commandCompleted = nil
	s.resolver = runcommands.NewCommandsResolver(
		s.commands, func(id string) {
			if s.commandCompleted != nil {
				s.commandCompleted(id)
			}
		},
	)
}
Example #2
0
func (s *RunHookSuite) testPrepareHookError(
	c *gc.C, newHook newHook, expectClearResolvedFlag, expectSkip bool,
) {
	callbacks := &PrepareHookCallbacks{
		MockPrepareHook:       &MockPrepareHook{err: errors.New("pow")},
		MockClearResolvedFlag: &MockNoArgs{},
	}
	factory := operation.NewFactory(operation.FactoryParams{
		Callbacks: callbacks,
	})
	op, err := newHook(factory, hook.Info{Kind: hooks.ConfigChanged})
	c.Assert(err, jc.ErrorIsNil)

	newState, err := op.Prepare(operation.State{})
	c.Check(newState, gc.IsNil)
	c.Check(callbacks.MockClearResolvedFlag.called, gc.Equals, expectClearResolvedFlag)
	if expectSkip {
		c.Check(err, gc.Equals, operation.ErrSkipExecute)
		c.Check(callbacks.MockPrepareHook.gotHook, gc.IsNil)
		return
	}
	c.Check(err, gc.ErrorMatches, "pow")
	c.Check(callbacks.MockPrepareHook.gotHook, gc.DeepEquals, &hook.Info{
		Kind: hooks.ConfigChanged,
	})
}
Example #3
0
func (s *MetricsOperationSuite) TestSendingFails(c *gc.C) {
	apiSender := newTestAPIMetricSender()

	factory := operation.NewFactory(operation.FactoryParams{
		MetricSender:   apiSender,
		MetricSpoolDir: s.spoolDir,
	})

	sendOperation, err := factory.NewSendMetrics()
	c.Assert(err, gc.IsNil)

	_, err = sendOperation.Prepare(operation.State{})
	c.Assert(err, jc.ErrorIsNil)

	select {
	case apiSender.sendError <- errors.New("something went wrong"):
	default:
		c.Fatalf("blocked error channel")
	}

	_, err = sendOperation.Execute(operation.State{})
	c.Assert(err, jc.ErrorIsNil)

	c.Assert(apiSender.batches, gc.HasLen, 1)

	reader, err := metrics.NewJSONMetricReader(s.spoolDir)
	c.Assert(err, gc.IsNil)
	batches, err := reader.Read()
	c.Assert(err, gc.IsNil)
	c.Assert(batches, gc.HasLen, 1)
}
Example #4
0
func (s *RunHookSuite) TestPrepareHookCtxError(c *gc.C) {
	ctx := &MockContext{}
	ctx.SetErrors(errors.New("ctx prepare error"))
	callbacks := &PrepareHookCallbacks{
		MockPrepareHook: &MockPrepareHook{},
	}
	runnerFactory := &MockRunnerFactory{
		MockNewHookRunner: &MockNewHookRunner{
			runner: &MockRunner{
				context: ctx,
			},
		},
	}
	factory := operation.NewFactory(operation.FactoryParams{
		RunnerFactory: runnerFactory,
		Callbacks:     callbacks,
	})

	op, err := factory.NewRunHook(hook.Info{Kind: hooks.ConfigChanged})
	c.Assert(err, jc.ErrorIsNil)

	newState, err := op.Prepare(operation.State{})
	c.Check(newState, gc.IsNil)
	c.Assert(err, gc.ErrorMatches, `ctx prepare error`)

	ctx.CheckCall(c, 0, "Prepare")
}
Example #5
0
func (s *MetricsOperationSuite) TestSendingGetDuplicate(c *gc.C) {
	apiSender := newTestAPIMetricSender()

	factory := operation.NewFactory(operation.FactoryParams{
		MetricSender:   apiSender,
		MetricSpoolDir: s.spoolDir,
	})

	sendOperation, err := factory.NewSendMetrics()
	c.Assert(err, gc.IsNil)

	_, err = sendOperation.Prepare(operation.State{})
	c.Assert(err, jc.ErrorIsNil)

	apiErr := &params.Error{Message: "already exists", Code: params.CodeAlreadyExists}
	select {
	case apiSender.errors <- apiErr:
	default:
		c.Fatalf("blocked error channel")
	}

	_, err = sendOperation.Execute(operation.State{})
	c.Assert(err, jc.ErrorIsNil)

	c.Assert(apiSender.batches, gc.HasLen, 1)

	reader, err := metrics.NewJSONMetricReader(s.spoolDir)
	c.Assert(err, gc.IsNil)
	batches, err := reader.Read()
	c.Assert(err, gc.IsNil)
	c.Assert(batches, gc.HasLen, 0)
}
Example #6
0
func (s *MetricsOperationSuite) TestMetricSendingSuccess(c *gc.C) {
	apiSender := newTestAPIMetricSender()

	factory := operation.NewFactory(operation.FactoryParams{
		MetricSender:   apiSender,
		MetricSpoolDir: s.spoolDir,
	})

	sendOperation, err := factory.NewSendMetrics()
	c.Assert(err, gc.IsNil)

	_, err = sendOperation.Prepare(operation.State{})
	c.Assert(err, jc.ErrorIsNil)

	_, err = sendOperation.Execute(operation.State{})
	c.Assert(err, jc.ErrorIsNil)

	c.Assert(apiSender.batches, gc.HasLen, 1)

	reader, err := metrics.NewJSONMetricReader(s.spoolDir)
	c.Assert(err, gc.IsNil)
	batches, err := reader.Read()
	c.Assert(err, gc.IsNil)
	c.Assert(batches, gc.HasLen, 0)
}
Example #7
0
func (s *DeploySuite) testNotifyDeployerError(
	c *gc.C, newDeploy newDeploy, expectNotifyRevert bool,
) {
	callbacks := &DeployCallbacks{
		MockClearResolvedFlag: &MockNoArgs{},
	}
	deployer := &MockDeployer{}
	expectCall := &MockNoArgs{err: errors.New("snh")}
	if expectNotifyRevert {
		deployer.MockNotifyRevert = expectCall
	} else {
		deployer.MockNotifyResolved = expectCall
	}
	factory := operation.NewFactory(operation.FactoryParams{
		Callbacks: callbacks,
		Deployer:  deployer,
	})
	op, err := newDeploy(factory, curl("cs:quantal/hive-23"))
	c.Assert(err, jc.ErrorIsNil)

	newState, err := op.Prepare(operation.State{})
	c.Check(newState, gc.IsNil)
	c.Check(err, gc.ErrorMatches, "snh")
	c.Check(expectCall.called, jc.IsTrue)
}
Example #8
0
func (s *resolverSuite) SetUpTest(c *gc.C) {
	s.stub = testing.Stub{}
	s.charmURL = charm.MustParseURL("cs:precise/mysql-2")
	s.remoteState = remotestate.Snapshot{
		CharmModifiedVersion: s.charmModifiedVersion,
		CharmURL:             s.charmURL,
	}
	s.opFactory = operation.NewFactory(operation.FactoryParams{})

	attachments, err := storage.NewAttachments(&dummyStorageAccessor{}, names.NewUnitTag("u/0"), c.MkDir(), nil)
	c.Assert(err, jc.ErrorIsNil)

	s.clearResolved = func() error {
		return errors.New("unexpected resolved")
	}

	s.reportHookError = func(hook.Info) error {
		return errors.New("unexpected report hook error")
	}

	s.resolverConfig = uniter.ResolverConfig{
		ClearResolved:       func() error { return s.clearResolved() },
		ReportHookError:     func(info hook.Info) error { return s.reportHookError(info) },
		StartRetryHookTimer: func() { s.stub.AddCall("StartRetryHookTimer") },
		StopRetryHookTimer:  func() { s.stub.AddCall("StopRetryHookTimer") },
		ShouldRetryHooks:    true,
		Leadership:          leadership.NewResolver(),
		Actions:             uniteractions.NewResolver(),
		Relations:           relation.NewRelationsResolver(&dummyRelations{}),
		Storage:             storage.NewResolver(attachments),
		Commands:            nopResolver{},
	}

	s.resolver = uniter.NewUniterResolver(s.resolverConfig)
}
Example #9
0
func (s *RunHookSuite) TestPrepareHookCtxCalled(c *gc.C) {
	ctx := &MockContext{}
	callbacks := &PrepareHookCallbacks{
		MockPrepareHook:       &MockPrepareHook{},
		MockClearResolvedFlag: &MockNoArgs{},
	}
	runnerFactory := &MockRunnerFactory{
		MockNewHookRunner: &MockNewHookRunner{
			runner: &MockRunner{
				context: ctx,
			},
		},
	}
	factory := operation.NewFactory(operation.FactoryParams{
		RunnerFactory: runnerFactory,
		Callbacks:     callbacks,
	})

	op, err := factory.NewRunHook(hook.Info{Kind: hooks.ConfigChanged})
	c.Assert(err, jc.ErrorIsNil)

	newState, err := op.Prepare(operation.State{})
	c.Check(newState, gc.NotNil)
	c.Assert(err, jc.ErrorIsNil)

	ctx.CheckCall(c, 0, "Prepare")
}
Example #10
0
func (s *RunCommandsSuite) TestPrepareSuccess(c *gc.C) {
	ctx := &MockContext{}
	runnerFactory := &MockRunnerFactory{
		MockNewCommandRunner: &MockNewCommandRunner{
			runner: &MockRunner{
				context: ctx,
			},
		},
	}
	factory := operation.NewFactory(operation.FactoryParams{
		RunnerFactory: runnerFactory,
	})
	sendResponse := func(*utilexec.ExecResponse, error) { panic("not expected") }
	op, err := factory.NewCommands(someCommandArgs, sendResponse)
	c.Assert(err, jc.ErrorIsNil)

	newState, err := op.Prepare(operation.State{})
	c.Assert(err, jc.ErrorIsNil)
	c.Assert(newState, gc.IsNil)
	c.Assert(*runnerFactory.MockNewCommandRunner.gotInfo, gc.Equals, runner.CommandInfo{
		RelationId:      123,
		RemoteUnitName:  "foo/456",
		ForceRemoteUnit: true,
	})
	ctx.CheckCall(c, 0, "Prepare")
}
Example #11
0
func (s *DeploySuite) testPrepareStageError(c *gc.C, newDeploy newDeploy) {
	callbacks := &DeployCallbacks{
		MockClearResolvedFlag: &MockNoArgs{},
		MockGetArchiveInfo:    &MockGetArchiveInfo{info: &MockBundleInfo{}},
	}
	deployer := &MockDeployer{
		MockNotifyRevert:   &MockNoArgs{},
		MockNotifyResolved: &MockNoArgs{},
		MockStage:          &MockStage{err: errors.New("squish")},
	}
	var abort <-chan struct{} = make(chan struct{})
	factory := operation.NewFactory(operation.FactoryParams{
		Deployer:  deployer,
		Callbacks: callbacks,
		Abort:     abort,
	})
	op, err := newDeploy(factory, curl("cs:quantal/hive-23"))
	c.Assert(err, jc.ErrorIsNil)

	newState, err := op.Prepare(operation.State{})
	c.Check(newState, gc.IsNil)
	c.Check(err, gc.ErrorMatches, "squish")
	c.Check(*deployer.MockStage.gotInfo, gc.Equals, callbacks.MockGetArchiveInfo.info)
	c.Check(*deployer.MockStage.gotAbort, gc.Equals, abort)
}
Example #12
0
func (s *RunHookSuite) testCommitSuccess_CollectMetricsTime(c *gc.C, newHook newHook) {
	callbacks := &CommitHookCallbacks{
		MockCommitHook: &MockCommitHook{},
	}
	factory := operation.NewFactory(operation.FactoryParams{
		Callbacks: callbacks,
	})
	op, err := newHook(factory, hook.Info{Kind: hooks.CollectMetrics})
	c.Assert(err, jc.ErrorIsNil)

	nowBefore := time.Now().Unix()
	newState, err := op.Commit(overwriteState)
	c.Assert(err, jc.ErrorIsNil)

	nowAfter := time.Now().Unix()
	nowWritten := newState.CollectMetricsTime
	c.Logf("%d <= %d <= %d", nowBefore, nowWritten, nowAfter)
	c.Check(nowBefore <= nowWritten, jc.IsTrue)
	c.Check(nowWritten <= nowAfter, jc.IsTrue)

	// Check the other fields match.
	newState.CollectMetricsTime = 0
	c.Check(newState, gc.DeepEquals, &operation.State{
		Started:          true,
		Kind:             operation.Continue,
		Step:             operation.Pending,
		UpdateStatusTime: 1234567,
	})
}
Example #13
0
func (s *DeploySuite) testExecuteConflictError(c *gc.C, newDeploy newDeploy) {
	callbacks := NewDeployCallbacks()
	deployer := &MockDeployer{
		MockNotifyRevert:   &MockNoArgs{},
		MockNotifyResolved: &MockNoArgs{},
		MockStage:          &MockStage{},
		MockDeploy:         &MockNoArgs{err: charm.ErrConflict},
	}
	factory := operation.NewFactory(operation.FactoryParams{
		Deployer:  deployer,
		Callbacks: callbacks,
	})
	charmURL := curl("cs:quantal/nyancat-4")
	op, err := newDeploy(factory, charmURL)
	c.Assert(err, jc.ErrorIsNil)
	_, err = op.Prepare(operation.State{})
	c.Assert(err, jc.ErrorIsNil)

	newState, err := op.Execute(operation.State{})
	c.Check(newState, gc.IsNil)
	c.Check(err, gc.ErrorMatches, "cannot deploy charm cs:quantal/nyancat-4")
	ok := operation.IsDeployConflictError(err)
	c.Check(ok, jc.IsTrue)
	c.Check(deployer.MockDeploy.called, jc.IsTrue)
}
Example #14
0
func (s *RunCommandsSuite) TestNeedsGlobalMachineLock(c *gc.C) {
	factory := operation.NewFactory(operation.FactoryParams{})
	sendResponse := &MockSendResponse{}
	op, err := factory.NewCommands(someCommandArgs, sendResponse.Call)
	c.Assert(err, jc.ErrorIsNil)
	c.Assert(op.NeedsGlobalMachineLock(), jc.IsTrue)
}
Example #15
0
func (s *UpdateRelationsSuite) TestPrepare(c *gc.C) {
	factory := operation.NewFactory(operation.FactoryParams{})
	op, err := factory.NewUpdateRelations(nil)
	c.Assert(err, jc.ErrorIsNil)
	state, err := op.Prepare(operation.State{})
	c.Check(err, jc.ErrorIsNil)
	c.Check(state, gc.IsNil)
}
Example #16
0
func (s *UpdateRelationsSuite) TestCommit(c *gc.C) {
	factory := operation.NewFactory(nil, nil, nil, nil, nil)
	op, err := factory.NewUpdateRelations(nil)
	c.Assert(err, jc.ErrorIsNil)
	state, err := op.Commit(operation.State{})
	c.Check(err, jc.ErrorIsNil)
	c.Check(state, gc.IsNil)
}
Example #17
0
func (s *UpdateStorageSuite) TestPrepare(c *gc.C) {
	factory := operation.NewFactory(nil, nil, nil, nil, nil)
	op, err := factory.NewUpdateStorage(nil)
	c.Assert(err, jc.ErrorIsNil)
	state, err := op.Prepare(operation.State{})
	c.Check(err, jc.ErrorIsNil)
	c.Check(state, gc.IsNil)
}
Example #18
0
func (s *UpdateStorageSuite) TestCommit(c *gc.C) {
	factory := operation.NewFactory(operation.FactoryParams{})
	op, err := factory.NewUpdateStorage(nil)
	c.Assert(err, jc.ErrorIsNil)
	state, err := op.Commit(operation.State{})
	c.Check(err, jc.ErrorIsNil)
	c.Check(state, gc.IsNil)
}
Example #19
0
func (s *FactorySuite) SetUpTest(c *gc.C) {
	s.IsolationSuite.SetUpTest(c)
	// Yes, this factory will produce useless ops; this suite is just for
	// verifying that inadequate args to the factory methods will produce
	// the expected errors; and that the results of same get a string
	// representation that does not depend on the factory attributes.
	s.factory = operation.NewFactory(operation.FactoryParams{})
}
Example #20
0
func (s *LeaderSuite) TestResignLeadership_Prepare_Leader(c *gc.C) {
	factory := operation.NewFactory(nil, nil, nil, nil, nil)
	op, err := factory.NewResignLeadership()
	c.Assert(err, jc.ErrorIsNil)

	newState, err := op.Prepare(operation.State{Leader: true})
	c.Check(newState, gc.IsNil)
	c.Check(err, jc.ErrorIsNil)
}
Example #21
0
func (s *RunCommandsSuite) TestCommit(c *gc.C) {
	factory := operation.NewFactory(operation.FactoryParams{})
	sendResponse := func(*utilexec.ExecResponse, error) { panic("not expected") }
	op, err := factory.NewCommands(someCommandArgs, sendResponse)
	c.Assert(err, jc.ErrorIsNil)
	newState, err := op.Commit(operation.State{})
	c.Assert(newState, gc.IsNil)
	c.Assert(err, jc.ErrorIsNil)
}
Example #22
0
func (s *LeaderSuite) TestResignLeadership_Prepare_NotLeader(c *gc.C) {
	factory := operation.NewFactory(operation.FactoryParams{})
	op, err := factory.NewResignLeadership()
	c.Assert(err, jc.ErrorIsNil)

	newState, err := op.Prepare(operation.State{})
	c.Check(newState, gc.IsNil)
	c.Check(err, gc.Equals, operation.ErrSkipExecute)
}
Example #23
0
func (s *DeploySuite) testCommitMetricsError(c *gc.C, newDeploy newDeploy) {
	callbacks := NewDeployCommitCallbacks(errors.New("glukh"))
	factory := operation.NewFactory(nil, nil, callbacks, nil, nil)
	op, err := newDeploy(factory, curl("cs:quantal/x-0"))
	c.Assert(err, jc.ErrorIsNil)
	newState, err := op.Commit(operation.State{})
	c.Check(err, gc.ErrorMatches, "glukh")
	c.Check(newState, gc.IsNil)
}
Example #24
0
func (s *LeaderSuite) TestResignLeadership_Commit_ClearLeader(c *gc.C) {
	factory := operation.NewFactory(operation.FactoryParams{})
	op, err := factory.NewResignLeadership()
	c.Assert(err, jc.ErrorIsNil)

	newState, err := op.Commit(operation.State{Leader: true})
	c.Check(newState, gc.DeepEquals, &operation.State{})
	c.Check(err, jc.ErrorIsNil)
}
Example #25
0
func (s *LeaderSuite) TestResignLeadership_Commit_PreserveOthers(c *gc.C) {
	factory := operation.NewFactory(operation.FactoryParams{})
	op, err := factory.NewResignLeadership()
	c.Assert(err, jc.ErrorIsNil)

	newState, err := op.Commit(overwriteState)
	c.Check(newState, gc.DeepEquals, &overwriteState)
	c.Check(err, jc.ErrorIsNil)
}
Example #26
0
func (s *LeaderSuite) TestAcceptLeadership_Prepare_NotLeader(c *gc.C) {
	factory := operation.NewFactory(operation.FactoryParams{})
	op, err := factory.NewAcceptLeadership()
	c.Assert(err, jc.ErrorIsNil)

	newState, err := op.Prepare(operation.State{Kind: operation.Continue})
	c.Check(newState, gc.IsNil)
	// *execute* is currently just a no-op -- all the meat happens in commit.
	c.Check(err, gc.Equals, operation.ErrSkipExecute)
}
Example #27
0
func (s *LeaderSuite) TestAcceptLeadership_Prepare_BadState(c *gc.C) {
	factory := operation.NewFactory(operation.FactoryParams{})
	op, err := factory.NewAcceptLeadership()
	c.Assert(err, jc.ErrorIsNil)

	newState, err := op.Prepare(operation.State{})
	c.Check(newState, gc.IsNil)
	// accept is only valid in Continue mode, when we're sure nothing is queued
	// or in progress.
	c.Check(err, gc.Equals, operation.ErrCannotAcceptLeadership)
}
Example #28
0
func (s *LeaderSuite) TestResignLeadership_Commit_All(c *gc.C) {
	factory := operation.NewFactory(operation.FactoryParams{})
	op, err := factory.NewResignLeadership()
	c.Assert(err, jc.ErrorIsNil)

	leaderState := overwriteState
	leaderState.Leader = true
	newState, err := op.Commit(leaderState)
	c.Check(newState, gc.DeepEquals, &overwriteState)
	c.Check(err, jc.ErrorIsNil)
}
Example #29
0
func (s *DeploySuite) testClearResolvedFlagError(c *gc.C, newDeploy newDeploy) {
	callbacks := &DeployCallbacks{
		MockClearResolvedFlag: &MockNoArgs{err: errors.New("blort")},
	}
	factory := operation.NewFactory(nil, nil, callbacks, nil, nil)
	op, err := newDeploy(factory, curl("cs:quantal/hive-23"))
	c.Assert(err, jc.ErrorIsNil)
	newState, err := op.Prepare(operation.State{})
	c.Check(newState, gc.IsNil)
	c.Check(err, gc.ErrorMatches, "blort")
	c.Check(callbacks.MockClearResolvedFlag.called, jc.IsTrue)
}
Example #30
0
func (s *RunActionSuite) TestCommit(c *gc.C) {
	var stateChangeTests = []struct {
		description string
		before      operation.State
		after       operation.State
	}{{
		description: "empty state",
		after: operation.State{
			Kind: operation.Continue,
			Step: operation.Pending,
		},
	}, {
		description: "preserves only appropriate fields, no hook",
		before: operation.State{
			Kind:     operation.Continue,
			Step:     operation.Pending,
			Started:  true,
			CharmURL: curl("cs:quantal/wordpress-2"),
			ActionId: &randomActionId,
		},
		after: operation.State{
			Kind:    operation.Continue,
			Step:    operation.Pending,
			Started: true,
		},
	}, {
		description: "preserves only appropriate fields, with hook",
		before: operation.State{
			Kind:     operation.Continue,
			Step:     operation.Pending,
			Started:  true,
			CharmURL: curl("cs:quantal/wordpress-2"),
			ActionId: &randomActionId,
			Hook:     &hook.Info{Kind: hooks.Install},
		},
		after: operation.State{
			Kind:    operation.RunHook,
			Step:    operation.Pending,
			Hook:    &hook.Info{Kind: hooks.Install},
			Started: true,
		},
	}}

	for i, test := range stateChangeTests {
		c.Logf("test %d: %s", i, test.description)
		factory := operation.NewFactory(operation.FactoryParams{})
		op, err := factory.NewAction(someActionId)
		c.Assert(err, jc.ErrorIsNil)

		newState, err := op.Commit(test.before)
		c.Assert(newState, jc.DeepEquals, &test.after)
	}
}