Example #1
0
func (*APIOpenerSuite) TestTimoutClosesAPIOnTimeout(c *gc.C) {
	var controllerName, accountName, modelName string
	finished := make(chan struct{})
	mockConn := &mockConnection{closed: make(chan struct{})}
	open := func(_ jujuclient.ClientStore, controllerNameArg, accountNameArg, modelNameArg string) (api.Connection, error) {
		<-finished
		controllerName = controllerNameArg
		accountName = accountNameArg
		modelName = modelNameArg
		return mockConn, nil
	}
	// have the mock clock only wait a microsecond
	clock := &mockClock{wait: time.Microsecond}
	// but tell it to wait five seconds
	opener := modelcmd.NewTimeoutOpener(modelcmd.OpenFunc(open), clock, 5*time.Second)
	conn, err := opener.Open(nil, "a-name", "b-name", "c-name")
	c.Assert(errors.Cause(err), gc.Equals, modelcmd.ErrConnTimedOut)
	c.Assert(conn, gc.IsNil)
	// check it was told to wait for 5 seconds
	c.Assert(clock.duration, gc.Equals, 5*time.Second)
	// tell the open func to continue now we have timed out
	close(finished)
	// wait until the connection has been closed
	select {
	case <-mockConn.closed:
		// continue
	case <-time.After(5 * time.Second):
		c.Error("API connection was not closed.")
	}
	c.Assert(controllerName, gc.Equals, "a-name")
	c.Assert(accountName, gc.Equals, "b-name")
	c.Assert(modelName, gc.Equals, "c-name")
}
Example #2
0
func (s *KillSuite) TestKillAPIPermErrFails(c *gc.C) {
	testDialer := func(_ jujuclient.ClientStore, controllerName, accountName, modelName string) (api.Connection, error) {
		return nil, common.ErrPerm
	}
	cmd := controller.NewKillCommandForTest(nil, nil, s.store, nil, clock.WallClock, modelcmd.OpenFunc(testDialer))
	_, err := testing.RunCommand(c, cmd, "local.test1", "-y")
	c.Assert(err, gc.ErrorMatches, "cannot destroy controller: permission denied")
	checkControllerExistsInStore(c, "local.test1", s.store)
}
Example #3
0
File: kill.go Project: kat-co/juju
// wrapKillCommand provides the common wrapping used by tests and
// the default NewKillCommand above.
func wrapKillCommand(kill *killCommand, apiOpen modelcmd.APIOpener, clock clock.Clock) cmd.Command {
	if apiOpen == nil {
		apiOpen = modelcmd.OpenFunc(kill.JujuCommandBase.NewAPIRoot)
	}
	openStrategy := modelcmd.NewTimeoutOpener(apiOpen, clock, 10*time.Second)
	return modelcmd.WrapController(
		kill,
		modelcmd.WrapControllerSkipControllerFlags,
		modelcmd.WrapControllerSkipDefaultController,
		modelcmd.WrapControllerAPIOpener(openStrategy),
	)
}
Example #4
0
func (*APIOpenerSuite) TestTimoutErrors(c *gc.C) {
	var controllerName, modelName string
	open := func(_ jujuclient.ClientStore, controllerNameArg, modelNameArg string) (api.Connection, error) {
		controllerName = controllerNameArg
		modelName = modelNameArg
		return nil, errors.New("boom")
	}
	opener := modelcmd.NewTimeoutOpener(modelcmd.OpenFunc(open), clock.WallClock, 10*time.Second)
	conn, err := opener.Open(nil, "a-name", "b-name")
	c.Assert(err, gc.ErrorMatches, "boom")
	c.Assert(conn, gc.IsNil)
	c.Assert(controllerName, gc.Equals, "a-name")
	c.Assert(modelName, gc.Equals, "b-name")
}
Example #5
0
func (*APIOpenerSuite) TestTimoutSuccess(c *gc.C) {
	var controllerName, accountName, modelName string
	open := func(_ jujuclient.ClientStore, controllerNameArg, accountNameArg, modelNameArg string) (api.Connection, error) {
		controllerName = controllerNameArg
		accountName = accountNameArg
		modelName = modelNameArg
		return &mockConnection{}, nil
	}
	opener := modelcmd.NewTimeoutOpener(modelcmd.OpenFunc(open), clock.WallClock, 10*time.Second)
	conn, err := opener.Open(nil, "a-name", "b-name", "c-name")
	c.Assert(err, jc.ErrorIsNil)
	c.Assert(conn, gc.NotNil)
	c.Assert(controllerName, gc.Equals, "a-name")
	c.Assert(accountName, gc.Equals, "b-name")
	c.Assert(modelName, gc.Equals, "c-name")
}
Example #6
0
func (*APIOpenerSuite) TestPassthrough(c *gc.C) {
	var controllerName, modelName string
	open := func(_ jujuclient.ClientStore, controllerNameArg, modelNameArg string) (api.Connection, error) {
		controllerName = controllerNameArg
		modelName = modelNameArg
		// Lets do the bad thing and return both a connection instance
		// and an error to check they both come through.
		return &mockConnection{}, errors.New("boom")
	}
	opener := modelcmd.OpenFunc(open)
	conn, err := opener.Open(nil, "a-name", "b-name")
	c.Assert(err, gc.ErrorMatches, "boom")
	c.Assert(conn, gc.NotNil)
	c.Assert(controllerName, gc.Equals, "a-name")
	c.Assert(modelName, gc.Equals, "b-name")
}
Example #7
0
func (s *KillSuite) TestKillEarlyAPIConnectionTimeout(c *gc.C) {
	clock := &mockClock{}

	stop := make(chan struct{})
	defer close(stop)
	testDialer := func(_ jujuclient.ClientStore, controllerName, accountName, modelName string) (api.Connection, error) {
		<-stop
		return nil, errors.New("kill command waited too long")
	}

	cmd := controller.NewKillCommandForTest(nil, nil, s.store, nil, clock, modelcmd.OpenFunc(testDialer))
	ctx, err := testing.RunCommand(c, cmd, "local.test1", "-y")
	c.Check(err, jc.ErrorIsNil)
	c.Check(testing.Stderr(ctx), jc.Contains, "Unable to open API: open connection timed out")
	checkControllerRemovedFromStore(c, "local.test1", s.store)
	// Check that we were actually told to wait for 10s.
	c.Assert(clock.wait, gc.Equals, 10*time.Second)
}
Example #8
0
func (s *UpgradeCharmSuite) SetUpTest(c *gc.C) {
	s.IsolationSuite.SetUpTest(c)
	s.Stub.ResetCalls()

	// Create persistent cookies in a temporary location.
	cookieFile := filepath.Join(c.MkDir(), "cookies")
	s.PatchEnvironment("JUJU_COOKIEFILE", cookieFile)

	s.deployResources = func(
		applicationID string,
		chID jujucharmstore.CharmID,
		csMac *macaroon.Macaroon,
		filesAndRevisions map[string]string,
		resources map[string]charmresource.Meta,
		conn base.APICallCloser,
	) (ids map[string]string, err error) {
		s.AddCall("DeployResources", applicationID, chID, csMac, filesAndRevisions, resources, conn)
		return nil, s.NextErr()
	}

	s.resolveCharm = func(
		resolveWithChannel func(*charm.URL) (*charm.URL, csclientparams.Channel, []string, error),
		conf *config.Config,
		url *charm.URL,
	) (*charm.URL, csclientparams.Channel, []string, error) {
		s.AddCall("ResolveCharm", resolveWithChannel, conf, url)
		if err := s.NextErr(); err != nil {
			return nil, csclientparams.NoChannel, nil, err
		}
		return s.resolvedCharmURL, csclientparams.StableChannel, []string{"quantal"}, nil
	}

	currentCharmURL := charm.MustParseURL("cs:quantal/foo-1")
	latestCharmURL := charm.MustParseURL("cs:quantal/foo-2")
	s.resolvedCharmURL = latestCharmURL

	s.apiConnection = mockAPIConnection{
		bestFacadeVersion: 2,
		serverVersion: &version.Number{
			Major: 1,
			Minor: 2,
			Patch: 3,
		},
	}
	s.charmAdder = mockCharmAdder{}
	s.charmClient = mockCharmClient{
		charmInfo: &charms.CharmInfo{
			Meta: &charm.Meta{},
		},
	}
	s.charmUpgradeClient = mockCharmUpgradeClient{charmURL: currentCharmURL}
	s.modelConfigGetter = mockModelConfigGetter{}
	s.resourceLister = mockResourceLister{}

	store := jujuclienttesting.NewMemStore()
	store.CurrentControllerName = "foo"
	store.Controllers["foo"] = jujuclient.ControllerDetails{}
	store.Models["foo"] = &jujuclient.ControllerModels{
		CurrentModel: "admin@local/bar",
		Models:       map[string]jujuclient.ModelDetails{"admin@local/bar": {}},
	}
	apiOpener := modelcmd.OpenFunc(func(store jujuclient.ClientStore, controller, model string) (api.Connection, error) {
		s.AddCall("OpenAPI", store, controller, model)
		return &s.apiConnection, nil
	})

	s.cmd = NewUpgradeCharmCommandForTest(
		store,
		apiOpener,
		s.deployResources,
		s.resolveCharm,
		func(conn api.Connection, bakeryClient *httpbakery.Client, channel csclientparams.Channel) CharmAdder {
			s.AddCall("NewCharmAdder", conn, bakeryClient, channel)
			s.PopNoErr()
			return &s.charmAdder
		},
		func(conn api.Connection) CharmClient {
			s.AddCall("NewCharmClient", conn)
			s.PopNoErr()
			return &s.charmClient
		},
		func(conn api.Connection) CharmUpgradeClient {
			s.AddCall("NewCharmUpgradeClient", conn)
			s.PopNoErr()
			return &s.charmUpgradeClient
		},
		func(conn api.Connection) ModelConfigGetter {
			s.AddCall("NewModelConfigGetter", conn)
			return &s.modelConfigGetter
		},
		func(conn api.Connection) (ResourceLister, error) {
			s.AddCall("NewResourceLister", conn)
			return &s.resourceLister, s.NextErr()
		},
	)
}