func (s *destroyEnvSuite) TestDestroyEnvironmentCommandBroken(c *gc.C) { oldinfo, err := s.ConfigStore.ReadInfo("dummyenv") c.Assert(err, gc.IsNil) bootstrapConfig := oldinfo.BootstrapConfig() apiEndpoint := oldinfo.APIEndpoint() apiCredentials := oldinfo.APICredentials() err = oldinfo.Destroy() c.Assert(err, gc.IsNil) newinfo := s.ConfigStore.CreateInfo("dummyenv") bootstrapConfig["broken"] = "Destroy" newinfo.SetBootstrapConfig(bootstrapConfig) newinfo.SetAPIEndpoint(apiEndpoint) newinfo.SetAPICredentials(apiCredentials) err = newinfo.Write() c.Assert(err, gc.IsNil) // Prepare the environment so we can destroy it. _, err = environs.PrepareFromName("dummyenv", cmdtesting.NullContext(c), s.ConfigStore) c.Assert(err, gc.IsNil) // destroy with broken environment opc, errc := cmdtesting.RunCommand(cmdtesting.NullContext(c), new(DestroyEnvironmentCommand), "dummyenv", "--yes") op, ok := (<-opc).(dummy.OpDestroy) c.Assert(ok, jc.IsTrue) c.Assert(op.Error, gc.ErrorMatches, "dummy.Destroy is broken") c.Check(<-errc, gc.Equals, op.Error) c.Check(<-opc, gc.IsNil) }
func (s *destroyEnvSuite) TestDestroyEnvironmentCommandEFlag(c *gc.C) { // Prepare the environment so we can destroy it. _, err := environs.PrepareFromName("dummyenv", cmdtesting.NullContext(c), s.ConfigStore) c.Assert(err, gc.IsNil) // check that either environment or the flag is mandatory opc, errc := cmdtesting.RunCommand(cmdtesting.NullContext(c), new(DestroyEnvironmentCommand)) c.Check(<-errc, gc.Equals, NoEnvironmentError) // We don't allow them to supply both entries at the same time opc, errc = cmdtesting.RunCommand(cmdtesting.NullContext(c), new(DestroyEnvironmentCommand), "-e", "dummyenv", "dummyenv", "--yes") c.Check(<-errc, gc.Equals, DoubleEnvironmentError) // We treat --environment the same way opc, errc = cmdtesting.RunCommand(cmdtesting.NullContext(c), new(DestroyEnvironmentCommand), "--environment", "dummyenv", "dummyenv", "--yes") c.Check(<-errc, gc.Equals, DoubleEnvironmentError) // destroy using the -e flag opc, errc = cmdtesting.RunCommand(cmdtesting.NullContext(c), new(DestroyEnvironmentCommand), "-e", "dummyenv", "--yes") c.Check(<-errc, gc.IsNil) c.Check((<-opc).(dummy.OpDestroy).Env, gc.Equals, "dummyenv") // Verify that the environment information has been removed. _, err = s.ConfigStore.ReadInfo("dummyenv") c.Assert(err, jc.Satisfies, errors.IsNotFound) }
func (s *destroyEnvSuite) checkDestroyEnvironment(c *gc.C, blocked, force bool) { //Setup environment envName := "dummyenv" s.startEnvironment(c, envName) if blocked { s.BlockDestroyEnvironment(c, "checkDestroyEnvironment") } opc := make(chan dummy.Operation) errc := make(chan error) if force { opc, errc = cmdtesting.RunCommand(cmdtesting.NullContext(c), newDestroyEnvironmentCommand(), envName, "--yes", "--force") } else { opc, errc = cmdtesting.RunCommand(cmdtesting.NullContext(c), newDestroyEnvironmentCommand(), envName, "--yes") } if force || !blocked { c.Check(<-errc, gc.IsNil) c.Check((<-opc).(dummy.OpDestroy).Env, gc.Equals, envName) // Verify that the environment information has been removed. _, err := s.ConfigStore.ReadInfo(envName) c.Assert(err, jc.Satisfies, errors.IsNotFound) } else { c.Check(<-errc, gc.Not(gc.IsNil)) c.Check((<-opc), gc.IsNil) // Verify that the environment information has not been removed. _, err := s.ConfigStore.ReadInfo(envName) c.Assert(err, jc.ErrorIsNil) } }
func (s *destroyEnvSuite) TestDestroyEnvironmentCommandConfirmation(c *gc.C) { var stdin, stdout bytes.Buffer ctx, err := cmd.DefaultContext() c.Assert(err, gc.IsNil) ctx.Stdout = &stdout ctx.Stdin = &stdin // Prepare the environment so we can destroy it. env, err := environs.PrepareFromName("dummyenv", cmdtesting.NullContext(c), s.ConfigStore) c.Assert(err, gc.IsNil) assertEnvironNotDestroyed(c, env, s.ConfigStore) // Ensure confirmation is requested if "-y" is not specified. stdin.WriteString("n") opc, errc := cmdtesting.RunCommand(ctx, new(DestroyEnvironmentCommand), "dummyenv") c.Check(<-errc, gc.ErrorMatches, "environment destruction aborted") c.Check(<-opc, gc.IsNil) c.Check(stdout.String(), gc.Matches, "WARNING!.*dummyenv.*\\(type: dummy\\)(.|\n)*") assertEnvironNotDestroyed(c, env, s.ConfigStore) // EOF on stdin: equivalent to answering no. stdin.Reset() stdout.Reset() opc, errc = cmdtesting.RunCommand(ctx, new(DestroyEnvironmentCommand), "dummyenv") c.Check(<-opc, gc.IsNil) c.Check(<-errc, gc.ErrorMatches, "environment destruction aborted") assertEnvironNotDestroyed(c, env, s.ConfigStore) // "--yes" passed: no confirmation request. stdin.Reset() stdout.Reset() opc, errc = cmdtesting.RunCommand(ctx, new(DestroyEnvironmentCommand), "dummyenv", "--yes") c.Check(<-errc, gc.IsNil) c.Check((<-opc).(dummy.OpDestroy).Env, gc.Equals, "dummyenv") c.Check(stdout.String(), gc.Equals, "") assertEnvironDestroyed(c, env, s.ConfigStore) // Any of casing of "y" and "yes" will confirm. for _, answer := range []string{"y", "Y", "yes", "YES"} { // Prepare the environment so we can destroy it. s.Reset(c) env, err := environs.PrepareFromName("dummyenv", cmdtesting.NullContext(c), s.ConfigStore) c.Assert(err, gc.IsNil) stdin.Reset() stdout.Reset() stdin.WriteString(answer) opc, errc = cmdtesting.RunCommand(ctx, new(DestroyEnvironmentCommand), "dummyenv") c.Check(<-errc, gc.IsNil) c.Check((<-opc).(dummy.OpDestroy).Env, gc.Equals, "dummyenv") c.Check(stdout.String(), gc.Matches, "WARNING!.*dummyenv.*\\(type: dummy\\)(.|\n)*") assertEnvironDestroyed(c, env, s.ConfigStore) } }
func (s *BootstrapSuite) TestBootstrapDestroy(c *gc.C) { resetJujuXDGDataHome(c) s.patchVersion(c) opc, errc := cmdtesting.RunCommand( cmdtesting.NullContext(c), s.newBootstrapCommand(), "devcontroller", "dummy-cloud/region-1", "--config", "broken=Bootstrap Destroy", "--auto-upgrade", ) err := <-errc c.Assert(err, gc.ErrorMatches, "failed to bootstrap model: dummy.Bootstrap is broken") var opDestroy *dummy.OpDestroy for opDestroy == nil { select { case op := <-opc: switch op := op.(type) { case dummy.OpDestroy: opDestroy = &op } default: c.Error("expected call to env.Destroy") return } } c.Assert(opDestroy.Error, gc.ErrorMatches, "dummy.Destroy is broken") }
func (s *BootstrapSuite) TestAutoUploadOnlyForDev(c *gc.C) { s.setupAutoUploadTest(c, "1.8.3", "precise") _, errc := cmdtesting.RunCommand(cmdtesting.NullContext(c), envcmd.Wrap(new(BootstrapCommand))) err := <-errc c.Assert(err, gc.ErrorMatches, "failed to bootstrap environment: Juju cannot bootstrap because no tools are available for your environment(.|\n)*") }
func (s *destroyEnvSuite) TestDestroyEnvironmentCommandTwiceOnNonStateServer(c *gc.C) { s.setupHostedEnviron(c, "dummy-non-state-server") oldInfo, err := s.ConfigStore.ReadInfo("dummy-non-state-server") c.Assert(err, jc.ErrorIsNil) opc, errc := cmdtesting.RunCommand(cmdtesting.NullContext(c), newDestroyEnvironmentCommand(), "dummy-non-state-server", "--yes") c.Check(<-errc, gc.IsNil) c.Check(<-opc, gc.IsNil) _, err = s.ConfigStore.ReadInfo("dummy-non-state-server") c.Assert(err, jc.Satisfies, errors.IsNotFound) // Simluate another client calling destroy on the same environment. This // client will have a local cache of the environ info, so write it back out. info := s.ConfigStore.CreateInfo("dummy-non-state-server") info.SetAPIEndpoint(oldInfo.APIEndpoint()) info.SetAPICredentials(oldInfo.APICredentials()) err = info.Write() c.Assert(err, jc.ErrorIsNil) // Call destroy again. context, err := coretesting.RunCommand(c, newDestroyEnvironmentCommand(), "dummy-non-state-server", "--yes") c.Assert(err, jc.ErrorIsNil) c.Assert(coretesting.Stderr(context), gc.Equals, "environment not found, removing config file\n") // Check that the client's cached info has been removed. _, err = s.ConfigStore.ReadInfo("dummy-non-state-server") c.Assert(err, jc.Satisfies, errors.IsNotFound) }
func (s *BootstrapSuite) TestBootstrapKeepBroken(c *gc.C) { resetJujuHome(c, "devenv") s.patchVersion(c) opc, errc := cmdtesting.RunCommand(cmdtesting.NullContext(c), newBootstrapCommand(), "-e", "brokenenv", "--keep-broken", "--auto-upgrade") err := <-errc c.Assert(err, gc.ErrorMatches, "failed to bootstrap environment: dummy.Bootstrap is broken") done := false for !done { select { case op, ok := <-opc: if !ok { done = true break } switch op.(type) { case dummy.OpDestroy: c.Error("unexpected call to env.Destroy") break } default: break } } }
func (s *BootstrapSuite) TestBootstrapKeepBroken(c *gc.C) { resetJujuXDGDataHome(c) s.patchVersion(c) opc, errc := cmdtesting.RunCommand(cmdtesting.NullContext(c), s.newBootstrapCommand(), "--keep-broken", "devcontroller", "dummy-cloud/region-1", "--config", "broken=Bootstrap Destroy", "--auto-upgrade", ) err := <-errc c.Assert(err, gc.ErrorMatches, "failed to bootstrap model: dummy.Bootstrap is broken") done := false for !done { select { case op, ok := <-opc: if !ok { done = true break } switch op.(type) { case dummy.OpDestroy: c.Error("unexpected call to env.Destroy") break } default: break } } }
func (s *BootstrapSuite) TestBootstrapKeepBroken(c *gc.C) { resetJujuHome(c, "devenv") devVersion := version.Current // Force a dev version by having a non zero build number. // This is because we have not uploaded any tools and auto // upload is only enabled for dev versions. devVersion.Build = 1234 s.PatchValue(&version.Current, devVersion) opc, errc := cmdtesting.RunCommand(cmdtesting.NullContext(c), envcmd.Wrap(new(BootstrapCommand)), "-e", "brokenenv", "--keep-broken") err := <-errc c.Assert(err, gc.ErrorMatches, "failed to bootstrap environment: dummy.Bootstrap is broken") done := false for !done { select { case op, ok := <-opc: if !ok { done = true break } switch op.(type) { case dummy.OpDestroy: c.Error("unexpected call to env.Destroy") break } default: break } } }
func (s *BootstrapSuite) TestBootstrapDestroy(c *gc.C) { resetJujuHome(c, "devenv") devVersion := version.Current // Force a dev version by having a non zero build number. // This is because we have not uploaded any tools and auto // upload is only enabled for dev versions. devVersion.Build = 1234 s.PatchValue(&version.Current, devVersion) opc, errc := cmdtesting.RunCommand(cmdtesting.NullContext(c), envcmd.Wrap(new(BootstrapCommand)), "-e", "brokenenv") err := <-errc c.Assert(err, gc.ErrorMatches, "failed to bootstrap environment: dummy.Bootstrap is broken") var opDestroy *dummy.OpDestroy for opDestroy == nil { select { case op := <-opc: switch op := op.(type) { case dummy.OpDestroy: opDestroy = &op } default: c.Error("expected call to env.Destroy") return } } c.Assert(opDestroy.Error, gc.ErrorMatches, "dummy.Destroy is broken") }
func (s *controllerSuite) TestWaitForAgentAPIReadyWaitsForSpaceDiscovery(c *gc.C) { s.mockBlockClient.discoveringSpacesError = 2 cmd := &modelcmd.ModelCommandBase{} cmd.SetClientStore(jujuclienttesting.NewMemStore()) err := WaitForAgentInitialisation(cmdtesting.NullContext(c), cmd, "controller", "default") c.Assert(err, jc.ErrorIsNil) c.Assert(s.mockBlockClient.discoveringSpacesError, gc.Equals, 0) }
func (s *destroyEnvSuite) TestDestroyEnvironmentCommand(c *gc.C) { // Prepare the environment so we can destroy it. _, err := environs.PrepareFromName("dummyenv", cmdtesting.NullContext(c), s.ConfigStore) c.Assert(err, gc.IsNil) // check environment is mandatory opc, errc := cmdtesting.RunCommand(cmdtesting.NullContext(c), new(DestroyEnvironmentCommand)) c.Check(<-errc, gc.Equals, NoEnvironmentError) // normal destroy opc, errc = cmdtesting.RunCommand(cmdtesting.NullContext(c), new(DestroyEnvironmentCommand), "dummyenv", "--yes") c.Check(<-errc, gc.IsNil) c.Check((<-opc).(dummy.OpDestroy).Env, gc.Equals, "dummyenv") // Verify that the environment information has been removed. _, err = s.ConfigStore.ReadInfo("dummyenv") c.Assert(err, jc.Satisfies, errors.IsNotFound) }
func (s *controllerSuite) TestWaitForAgentAPIReadyRetriesWithOpenEOFErr(c *gc.C) { s.mockBlockClient.numRetries = 0 s.mockBlockClient.retryCount = 0 s.mockBlockClient.loginError = io.EOF err := WaitForAgentInitialisation(cmdtesting.NullContext(c), nil, "controller") c.Check(err, jc.ErrorIsNil) c.Check(s.mockBlockClient.retryCount, gc.Equals, 1) }
func (s *controllerSuite) TestWaitForAgentAPIReadyStopsRetriesWithOpenErr(c *gc.C) { s.mockBlockClient.numRetries = 0 s.mockBlockClient.retryCount = 0 s.mockBlockClient.loginError = errors.NewUnauthorized(nil, "") err := WaitForAgentInitialisation(cmdtesting.NullContext(c), nil, "controller") c.Check(err, jc.Satisfies, errors.IsUnauthorized) c.Check(s.mockBlockClient.retryCount, gc.Equals, 0) }
func (s *BootstrapSuite) TestAutoUploadOnlyForDev(c *gc.C) { s.setupAutoUploadTest(c, "1.8.3", "precise") _, errc := cmdtesting.RunCommand( cmdtesting.NullContext(c), s.newBootstrapCommand(), "devcontroller", "dummy-cloud/region-1", ) err := <-errc c.Assert(err, gc.ErrorMatches, "failed to bootstrap model: Juju cannot bootstrap because no tools are available for your model(.|\n)*") }
func (s *destroyEnvSuite) TestForceDestroyEnvironmentCommandOnNonStateServerNoConfimFails(c *gc.C) { s.setupHostedEnviron(c, "dummy-non-state-server") opc, errc := cmdtesting.RunCommand(cmdtesting.NullContext(c), newDestroyEnvironmentCommand(), "dummy-non-state-server", "--force") c.Check(<-errc, gc.ErrorMatches, "cannot force destroy environment without bootstrap information") c.Check(<-opc, gc.IsNil) serverInfo, err := s.ConfigStore.ReadInfo("dummy-non-state-server") c.Assert(err, jc.ErrorIsNil) c.Assert(serverInfo, gc.Not(gc.IsNil)) }
func (s *destroyEnvSuite) TestDestroyEnvironmentCommandNonStateServer(c *gc.C) { s.setupHostedEnviron(c, "dummy-non-state-server") opc, errc := cmdtesting.RunCommand(cmdtesting.NullContext(c), newDestroyEnvironmentCommand(), "dummy-non-state-server", "--yes") c.Check(<-errc, gc.IsNil) // Check that there are no operations on the provider, we do not want to call // Destroy on it. c.Check(<-opc, gc.IsNil) _, err := s.ConfigStore.ReadInfo("dummy-non-state-server") c.Assert(err, jc.Satisfies, errors.IsNotFound) }
func (s *controllerSuite) TestWaitForAgentAPIReadyRetriesWithOpenEOFErr(c *gc.C) { s.mockBlockClient.numRetries = 0 s.mockBlockClient.retryCount = 0 s.mockBlockClient.loginError = io.EOF cmd := &modelcmd.ModelCommandBase{} cmd.SetClientStore(jujuclienttesting.NewMemStore()) err := WaitForAgentInitialisation(cmdtesting.NullContext(c), cmd, "controller", "default") c.Check(err, jc.ErrorIsNil) c.Check(s.mockBlockClient.retryCount, gc.Equals, 1) }
func (s *controllerSuite) TestWaitForAgentAPIReadyStopsRetriesWithOpenErr(c *gc.C) { s.mockBlockClient.numRetries = 0 s.mockBlockClient.retryCount = 0 s.mockBlockClient.loginError = errors.NewUnauthorized(nil, "") cmd := &modelcmd.ModelCommandBase{} cmd.SetClientStore(jujuclienttesting.NewMemStore()) err := WaitForAgentInitialisation(cmdtesting.NullContext(c), cmd, "controller", "default") c.Check(err, jc.Satisfies, errors.IsUnauthorized) c.Check(s.mockBlockClient.retryCount, gc.Equals, 0) }
// resetJujuHome restores an new, clean Juju home environment without tools. func resetJujuHome(c *gc.C, envName string) environs.Environ { jenvDir := gitjujutesting.HomePath(".juju", "environments") err := os.RemoveAll(jenvDir) c.Assert(err, jc.ErrorIsNil) coretesting.WriteEnvironments(c, envConfig) dummy.Reset() store, err := configstore.Default() c.Assert(err, jc.ErrorIsNil) env, err := environs.PrepareFromName(envName, envcmd.BootstrapContext(cmdtesting.NullContext(c)), store) c.Assert(err, jc.ErrorIsNil) return env }
func (s *BootstrapSuite) TestAutoUploadAfterFailedSync(c *gc.C) { s.PatchValue(&version.Current.Series, config.LatestLtsSeries()) s.setupAutoUploadTest(c, "1.7.3", "quantal") // Run command and check for that upload has been run for tools matching // the current juju version. opc, errc := cmdtesting.RunCommand(cmdtesting.NullContext(c), envcmd.Wrap(new(BootstrapCommand)), "-e", "devenv") c.Assert(<-errc, gc.IsNil) c.Check((<-opc).(dummy.OpBootstrap).Env, gc.Equals, "devenv") icfg := (<-opc).(dummy.OpFinalizeBootstrap).InstanceConfig c.Assert(icfg, gc.NotNil) c.Assert(icfg.Tools.Version.String(), gc.Equals, "1.7.3.1-raring-"+arch.HostArch()) }
// resetJujuHome restores an new, clean Juju home environment without tools. func resetJujuHome(c *gc.C) environs.Environ { jenvDir := gitjujutesting.HomePath(".juju", "environments") err := os.RemoveAll(jenvDir) c.Assert(err, gc.IsNil) coretesting.WriteEnvironments(c, envConfig) dummy.Reset() store, err := configstore.Default() c.Assert(err, gc.IsNil) env, err := environs.PrepareFromName("peckham", cmdtesting.NullContext(c), store) c.Assert(err, gc.IsNil) envtesting.RemoveAllTools(c, env) return env }
func (s *destroyEnvSuite) TestDestroyEnvironmentCommandEmptyJenv(c *gc.C) { oldinfo, err := s.ConfigStore.ReadInfo("dummyenv") info := s.ConfigStore.CreateInfo("dummy-no-bootstrap") info.SetAPICredentials(oldinfo.APICredentials()) info.SetAPIEndpoint(oldinfo.APIEndpoint()) err = info.Write() c.Assert(err, jc.ErrorIsNil) opc, errc := cmdtesting.RunCommand(cmdtesting.NullContext(c), newDestroyEnvironmentCommand(), "dummy-no-bootstrap", "--yes") c.Check(<-errc, gc.IsNil) c.Check((<-opc).(dummy.OpDestroy).Env, gc.Equals, "dummyenv") // Verify that the environment information has been removed. _, err = s.ConfigStore.ReadInfo("dummyenv") c.Assert(err, jc.Satisfies, errors.IsNotFound) }
func (s *BootstrapSuite) TestAutoUploadAfterFailedSync(c *gc.C) { s.PatchValue(&series.HostSeries, func() string { return series.LatestLts() }) s.setupAutoUploadTest(c, "1.7.3", "quantal") // Run command and check for that upload has been run for tools matching // the current juju version. opc, errc := cmdtesting.RunCommand( cmdtesting.NullContext(c), s.newBootstrapCommand(), "devcontroller", "dummy-cloud/region-1", "--config", "default-series=raring", "--auto-upgrade", ) c.Assert(<-errc, gc.IsNil) c.Check((<-opc).(dummy.OpBootstrap).Env, gc.Equals, "admin") icfg := (<-opc).(dummy.OpFinalizeBootstrap).InstanceConfig c.Assert(icfg, gc.NotNil) c.Assert(icfg.AgentVersion().String(), gc.Equals, "1.7.3.1-raring-"+arch.HostArch()) }
func (s *BootstrapSuite) TestBootstrapDestroy(c *gc.C) { resetJujuHome(c, "devenv") s.patchVersion(c) opc, errc := cmdtesting.RunCommand(cmdtesting.NullContext(c), newBootstrapCommand(), "-e", "brokenenv", "--auto-upgrade") err := <-errc c.Assert(err, gc.ErrorMatches, "failed to bootstrap environment: dummy.Bootstrap is broken") var opDestroy *dummy.OpDestroy for opDestroy == nil { select { case op := <-opc: switch op := op.(type) { case dummy.OpDestroy: opDestroy = &op } default: c.Error("expected call to env.Destroy") return } } c.Assert(opDestroy.Error, gc.ErrorMatches, "dummy.Destroy is broken") }
func (s *controllerSuite) TestWaitForAgentAPIReadyRetries(c *gc.C) { s.PatchValue(&bootstrapReadyPollDelay, 1*time.Millisecond) s.PatchValue(&bootstrapReadyPollCount, 5) defaultSeriesVersion := version.Current // Force a dev version by having a non zero build number. // This is because we have not uploaded any tools and auto // upload is only enabled for dev versions. defaultSeriesVersion.Build = 1234 s.PatchValue(&version.Current, defaultSeriesVersion) for _, t := range []struct { numRetries int err error }{ {0, nil}, // agent ready immediately {2, nil}, // agent ready after 2 polls {6, &rpc.RequestError{ Message: params.CodeUpgradeInProgress, Code: params.CodeUpgradeInProgress, }}, // agent ready after 6 polls but that's too long {-1, errOther}, // another error is returned } { s.mockBlockClient.numRetries = t.numRetries s.mockBlockClient.retryCount = 0 cmd := &modelcmd.ModelCommandBase{} cmd.SetClientStore(jujuclienttesting.NewMemStore()) err := WaitForAgentInitialisation(cmdtesting.NullContext(c), cmd, "controller", "default") c.Check(errors.Cause(err), gc.DeepEquals, t.err) expectedRetries := t.numRetries if t.numRetries <= 0 { expectedRetries = 1 } // Only retry maximum of bootstrapReadyPollCount times. if expectedRetries > 5 { expectedRetries = 5 } c.Check(s.mockBlockClient.retryCount, gc.Equals, expectedRetries) } }
func (test bootstrapTest) run(c *gc.C) { // Create home with dummy provider and remove all // of its envtools. env := resetJujuHome(c) if test.version != "" { useVersion := strings.Replace(test.version, "%LTS%", config.LatestLtsSeries(), 1) origVersion := version.Current version.Current = version.MustParseBinary(useVersion) defer func() { version.Current = origVersion }() } if test.hostArch != "" { origVersion := arch.HostArch arch.HostArch = func() string { return test.hostArch } defer func() { arch.HostArch = origVersion }() } if test.upload == "" { usefulVersion := version.Current usefulVersion.Series = config.PreferredSeries(env.Config()) envtesting.AssertUploadFakeToolsVersions(c, env.Storage(), usefulVersion) } // Run command and check for uploads. opc, errc := cmdtesting.RunCommand(cmdtesting.NullContext(c), envcmd.Wrap(new(BootstrapCommand)), test.args...) // Check for remaining operations/errors. if test.err != "" { err := <-errc stripped := strings.Replace(err.Error(), "\n", "", -1) c.Check(stripped, gc.Matches, test.err) return } if !c.Check(<-errc, gc.IsNil) { return } opPutBootstrapVerifyFile := (<-opc).(dummy.OpPutFile) c.Check(opPutBootstrapVerifyFile.Env, gc.Equals, "peckham") c.Check(opPutBootstrapVerifyFile.FileName, gc.Equals, environs.VerificationFilename) opBootstrap := (<-opc).(dummy.OpBootstrap) c.Check(opBootstrap.Env, gc.Equals, "peckham") c.Check(opBootstrap.Args.Constraints, gc.DeepEquals, test.constraints) c.Check(opBootstrap.Args.Placement, gc.Equals, test.placement) c.Check(opBootstrap.Args.KeepBroken, gc.Equals, test.keepBroken) opFinalizeBootstrap := (<-opc).(dummy.OpFinalizeBootstrap) c.Check(opFinalizeBootstrap.Env, gc.Equals, "peckham") c.Check(opFinalizeBootstrap.MachineConfig.Tools, gc.NotNil) if test.upload != "" { c.Check(opFinalizeBootstrap.MachineConfig.Tools.Version.String(), gc.Equals, test.upload) } store, err := configstore.Default() c.Assert(err, gc.IsNil) // Check a CA cert/key was generated by reloading the environment. env, err = environs.NewFromName("peckham", store) c.Assert(err, gc.IsNil) _, hasCert := env.Config().CACert() c.Check(hasCert, gc.Equals, true) _, hasKey := env.Config().CAPrivateKey() c.Check(hasKey, gc.Equals, true) info, err := store.ReadInfo("peckham") c.Assert(err, gc.IsNil) c.Assert(info, gc.NotNil) c.Assert(info.APIEndpoint().Addresses, gc.DeepEquals, []string{"localhost:17070"}) }
func (s *BootstrapSuite) run(c *gc.C, test bootstrapTest) (restore gitjujutesting.Restorer) { // Create home with dummy provider and remove all // of its envtools. env := resetJujuHome(c, "peckham") // Although we're testing PrepareEndpointsForCaching interactions // separately in the juju package, here we just ensure it gets // called with the right arguments. prepareCalled := false addrConnectedTo := "localhost:17070" restore = gitjujutesting.PatchValue( &prepareEndpointsForCaching, func(info configstore.EnvironInfo, hps [][]network.HostPort, addr network.HostPort) (_, _ []string, _ bool) { prepareCalled = true addrs, hosts, changed := juju.PrepareEndpointsForCaching(info, hps, addr) // Because we're bootstrapping the addresses will always // change, as there's no .jenv file saved yet. c.Assert(changed, jc.IsTrue) return addrs, hosts, changed }, ) if test.version != "" { useVersion := strings.Replace(test.version, "%LTS%", config.LatestLtsSeries(), 1) origVersion := version.Current version.Current = version.MustParseBinary(useVersion) restore = restore.Add(func() { version.Current = origVersion }) } if test.hostArch != "" { origArch := arch.HostArch arch.HostArch = func() string { return test.hostArch } restore = restore.Add(func() { arch.HostArch = origArch }) } // Run command and check for uploads. opc, errc := cmdtesting.RunCommand(cmdtesting.NullContext(c), envcmd.Wrap(new(BootstrapCommand)), test.args...) // Check for remaining operations/errors. if test.err != "" { err := <-errc c.Assert(err, gc.NotNil) stripped := strings.Replace(err.Error(), "\n", "", -1) c.Check(stripped, gc.Matches, test.err) return restore } if !c.Check(<-errc, gc.IsNil) { return restore } opBootstrap := (<-opc).(dummy.OpBootstrap) c.Check(opBootstrap.Env, gc.Equals, "peckham") c.Check(opBootstrap.Args.Constraints, gc.DeepEquals, test.constraints) c.Check(opBootstrap.Args.Placement, gc.Equals, test.placement) opFinalizeBootstrap := (<-opc).(dummy.OpFinalizeBootstrap) c.Check(opFinalizeBootstrap.Env, gc.Equals, "peckham") c.Check(opFinalizeBootstrap.InstanceConfig.Tools, gc.NotNil) if test.upload != "" { c.Check(opFinalizeBootstrap.InstanceConfig.Tools.Version.String(), gc.Equals, test.upload) } store, err := configstore.Default() c.Assert(err, jc.ErrorIsNil) // Check a CA cert/key was generated by reloading the environment. env, err = environs.NewFromName("peckham", store) c.Assert(err, jc.ErrorIsNil) _, hasCert := env.Config().CACert() c.Check(hasCert, jc.IsTrue) _, hasKey := env.Config().CAPrivateKey() c.Check(hasKey, jc.IsTrue) info, err := store.ReadInfo("peckham") c.Assert(err, jc.ErrorIsNil) c.Assert(info, gc.NotNil) c.Assert(prepareCalled, jc.IsTrue) c.Assert(info.APIEndpoint().Addresses, gc.DeepEquals, []string{addrConnectedTo}) return restore }
func (s *BootstrapSuite) run(c *gc.C, test bootstrapTest) testing.Restorer { // Create home with dummy provider and remove all // of its envtools. resetJujuXDGDataHome(c) dummy.Reset(c) var restore testing.Restorer = func() { s.store = jujuclienttesting.NewMemStore() } if test.version != "" { useVersion := strings.Replace(test.version, "%LTS%", series.LatestLts(), 1) v := version.MustParseBinary(useVersion) restore = restore.Add(testing.PatchValue(&jujuversion.Current, v.Number)) restore = restore.Add(testing.PatchValue(&arch.HostArch, func() string { return v.Arch })) restore = restore.Add(testing.PatchValue(&series.HostSeries, func() string { return v.Series })) } if test.hostArch != "" { restore = restore.Add(testing.PatchValue(&arch.HostArch, func() string { return test.hostArch })) } controllerName := "peckham-controller" cloudName := "dummy" // Run command and check for uploads. args := append([]string{ controllerName, cloudName, "--config", "default-series=raring", }, test.args...) opc, errc := cmdtesting.RunCommand(cmdtesting.NullContext(c), s.newBootstrapCommand(), args...) // Check for remaining operations/errors. if test.err != "" { err := <-errc c.Assert(err, gc.NotNil) stripped := strings.Replace(err.Error(), "\n", "", -1) c.Check(stripped, gc.Matches, test.err) return restore } if !c.Check(<-errc, gc.IsNil) { return restore } opBootstrap := (<-opc).(dummy.OpBootstrap) c.Check(opBootstrap.Env, gc.Equals, "admin") c.Check(opBootstrap.Args.ModelConstraints, gc.DeepEquals, test.constraints) if test.bootstrapConstraints == (constraints.Value{}) { test.bootstrapConstraints = test.constraints } c.Check(opBootstrap.Args.BootstrapConstraints, gc.DeepEquals, test.bootstrapConstraints) c.Check(opBootstrap.Args.Placement, gc.Equals, test.placement) opFinalizeBootstrap := (<-opc).(dummy.OpFinalizeBootstrap) c.Check(opFinalizeBootstrap.Env, gc.Equals, "admin") c.Check(opFinalizeBootstrap.InstanceConfig.ToolsList(), gc.Not(gc.HasLen), 0) if test.upload != "" { c.Check(opFinalizeBootstrap.InstanceConfig.AgentVersion().String(), gc.Equals, test.upload) } expectedBootstrappedControllerName := bootstrappedControllerName(controllerName) // Check controllers.yaml controller details. addrConnectedTo := []string{"localhost:17070"} controller, err := s.store.ControllerByName(expectedBootstrappedControllerName) c.Assert(err, jc.ErrorIsNil) c.Assert(controller.CACert, gc.Not(gc.Equals), "") c.Assert(controller.UnresolvedAPIEndpoints, gc.DeepEquals, addrConnectedTo) c.Assert(controller.APIEndpoints, gc.DeepEquals, addrConnectedTo) c.Assert(utils.IsValidUUIDString(controller.ControllerUUID), jc.IsTrue) // Controller model should be called "admin". controllerModel, err := s.store.ModelByName(expectedBootstrappedControllerName, "admin@local", "admin") c.Assert(controllerModel.ModelUUID, gc.Equals, controller.ControllerUUID) c.Assert(err, jc.ErrorIsNil) // Bootstrap config should have been saved, and should only contain // the type, name, and any user-supplied configuration. bootstrapConfig, err := s.store.BootstrapConfigForController(expectedBootstrappedControllerName) c.Assert(err, jc.ErrorIsNil) c.Assert(bootstrapConfig.Cloud, gc.Equals, "dummy") c.Assert(bootstrapConfig.Credential, gc.Equals, "") c.Assert(bootstrapConfig.Config, jc.DeepEquals, map[string]interface{}{ "name": "admin", "type": "dummy", "default-series": "raring", }) return restore }