예제 #1
0
func (s *LoopSuite) TestLoop(c *gc.C) {
	var resolverCalls int
	theOp := &mockOp{}
	s.resolver = resolver.ResolverFunc(func(
		_ resolver.LocalState,
		_ remotestate.Snapshot,
		_ operation.Factory,
	) (operation.Operation, error) {
		resolverCalls++
		switch resolverCalls {
		// On the first call, return an operation.
		case 1:
			return theOp, nil
		// On the second call, simulate having
		// no operations to perform, at which
		// point we'll wait for a remote state
		// change.
		case 2:
			s.watcher.changes <- struct{}{}
			break
		// On the third call, kill the loop.
		case 3:
			close(s.dying)
			break
		}
		return nil, resolver.ErrNoOperation
	})

	_, err := s.loop()
	c.Assert(err, gc.Equals, tomb.ErrDying)
	c.Assert(resolverCalls, gc.Equals, 3)
	s.executor.CheckCallNames(c, "State", "State", "Run", "State", "State")
	c.Assert(s.executor.Calls()[2].Args, jc.SameContents, []interface{}{theOp})
}
예제 #2
0
func (s *LoopSuite) TestNextOpFails(c *gc.C) {
	s.resolver = resolver.ResolverFunc(func(
		_ resolver.LocalState,
		_ remotestate.Snapshot,
		_ operation.Factory,
	) (operation.Operation, error) {
		return nil, errors.New("NextOp fails")
	})
	_, err := s.loop()
	c.Assert(err, gc.ErrorMatches, "NextOp fails")
}
예제 #3
0
func (s *LoopSuite) TestRunFails(c *gc.C) {
	s.executor.SetErrors(errors.New("Run fails"))
	s.resolver = resolver.ResolverFunc(func(
		_ resolver.LocalState,
		_ remotestate.Snapshot,
		_ operation.Factory,
	) (operation.Operation, error) {
		return mockOp{}, nil
	})
	_, err := s.loop()
	c.Assert(err, gc.ErrorMatches, "Run fails")
}
예제 #4
0
func (s *LoopSuite) SetUpTest(c *gc.C) {
	s.BaseSuite.SetUpTest(c)
	s.resolver = resolver.ResolverFunc(func(resolver.LocalState, remotestate.Snapshot, operation.Factory) (operation.Operation, error) {
		return nil, resolver.ErrNoOperation
	})
	s.watcher = &mockRemoteStateWatcher{
		changes: make(chan struct{}, 1),
	}
	s.opFactory = &mockOpFactory{}
	s.executor = &mockOpExecutor{}
	s.charmURL = charm.MustParseURL("cs:trusty/mysql")
	s.dying = make(chan struct{})
}
예제 #5
0
func (s *LoopSuite) TestErrWaitingNoOnIdle(c *gc.C) {
	var onIdleCalled bool
	s.onIdle = func() error {
		onIdleCalled = true
		return nil
	}
	s.resolver = resolver.ResolverFunc(func(
		_ resolver.LocalState,
		_ remotestate.Snapshot,
		_ operation.Factory,
	) (operation.Operation, error) {
		return nil, resolver.ErrWaiting
	})
	close(s.dying)
	_, err := s.loop()
	c.Assert(err, gc.Equals, tomb.ErrDying)
	c.Assert(onIdleCalled, jc.IsFalse)
}
예제 #6
0
func (s *LoopSuite) TestInitialFinalLocalState(c *gc.C) {
	var local resolver.LocalState
	s.resolver = resolver.ResolverFunc(func(
		l resolver.LocalState,
		_ remotestate.Snapshot,
		_ operation.Factory,
	) (operation.Operation, error) {
		local = l
		return nil, resolver.ErrNoOperation
	})

	close(s.abort)
	lastLocal, err := s.loop()
	c.Assert(err, gc.Equals, resolver.ErrLoopAborted)
	c.Assert(local, jc.DeepEquals, resolver.LocalState{
		CharmURL: s.charmURL,
	})
	c.Assert(lastLocal, jc.DeepEquals, local)
}
예제 #7
0
func (s *LoopSuite) TestInitialFinalLocalState(c *gc.C) {
	var local resolver.LocalState
	s.resolver = resolver.ResolverFunc(func(
		l resolver.LocalState,
		_ remotestate.Snapshot,
		_ operation.Factory,
	) (operation.Operation, error) {
		local = l
		return nil, resolver.ErrNoOperation
	})

	close(s.dying)
	lastLocal, err := s.loop()
	c.Assert(err, gc.Equals, tomb.ErrDying)
	c.Assert(local, jc.DeepEquals, resolver.LocalState{
		CharmURL:         s.charmURL,
		CompletedActions: map[string]struct{}{},
	})
	c.Assert(lastLocal, jc.DeepEquals, local)
}