func (*writerBasicsSuite) TestRemoveDefaultWriter(c *gc.C) { defaultWriter, level, err := loggo.RemoveWriter("default") c.Assert(err, gc.IsNil) c.Assert(level, gc.Equals, loggo.TRACE) c.Assert(defaultWriter, gc.NotNil) // Trying again fails. defaultWriter, level, err = loggo.RemoveWriter("default") c.Assert(err, gc.ErrorMatches, `Writer "default" is not registered`) c.Assert(level, gc.Equals, loggo.UNSPECIFIED) c.Assert(defaultWriter, gc.IsNil) }
func (s *SimpleStreamsToolsSuite) TestFindToolsFiltering(c *gc.C) { tw := &loggo.TestWriter{} c.Assert(loggo.RegisterWriter("filter-tester", tw, loggo.DEBUG), gc.IsNil) defer loggo.RemoveWriter("filter-tester") _, err := envtools.FindTools( s.env, 1, -1, coretools.Filter{Number: version.Number{Major: 1, Minor: 2, Patch: 3}}, envtools.DoNotAllowRetry) c.Assert(err, jc.Satisfies, errors.IsNotFound) // This is slightly overly prescriptive, but feel free to change or add // messages. This still helps to ensure that all log messages are // properly formed. messages := []jc.SimpleMessage{ {loggo.INFO, "reading tools with major version 1"}, {loggo.INFO, "filtering tools by version: \\d+\\.\\d+\\.\\d+"}, {loggo.DEBUG, "no architecture specified when finding tools, looking for any"}, {loggo.DEBUG, "no series specified when finding tools, looking for any"}, } sources, err := envtools.GetMetadataSources(s.env) c.Assert(err, gc.IsNil) for i := 0; i < 2*len(sources); i++ { messages = append(messages, jc.SimpleMessage{loggo.DEBUG, `fetchData failed for .*`}, jc.SimpleMessage{loggo.DEBUG, `cannot load index .*`}) } c.Check(tw.Log, jc.LogMatches, messages) }
func (s *syncToolsSuite) TestSyncToolsCommandDeprecatedDestination(c *gc.C) { called := false dir := c.MkDir() syncTools = func(sctx *sync.SyncContext) error { c.Assert(sctx.AllVersions, jc.IsFalse) c.Assert(sctx.DryRun, jc.IsFalse) c.Assert(sctx.Stream, gc.Equals, "released") c.Assert(sctx.Source, gc.Equals, "") c.Assert(sctx.TargetToolsUploader, gc.FitsTypeOf, sync.StorageToolsUploader{}) uploader := sctx.TargetToolsUploader.(sync.StorageToolsUploader) url, err := uploader.Storage.URL("") c.Assert(err, jc.ErrorIsNil) c.Assert(url, gc.Equals, utils.MakeFileURL(dir)) called = true return nil } // Register writer. var tw loggo.TestWriter c.Assert(loggo.RegisterWriter("deprecated-tester", &tw, loggo.DEBUG), gc.IsNil) defer loggo.RemoveWriter("deprecated-tester") // Add deprecated message to be checked. messages := []jc.SimpleMessage{ {loggo.WARNING, "Use of the --destination flag is deprecated in 1.18. Please use --local-dir instead."}, } // Run sync-tools command with --destination flag. ctx, err := runSyncToolsCommand(c, "-m", "test-target", "--destination", dir, "--stream", "released") c.Assert(err, jc.ErrorIsNil) c.Assert(ctx, gc.NotNil) c.Assert(called, jc.IsTrue) // Check deprecated message was logged. c.Check(tw.Log(), jc.LogMatches, messages) }
func (s *SimpleStreamsToolsSuite) TestFindToolsFiltering(c *gc.C) { var tw loggo.TestWriter c.Assert(loggo.RegisterWriter("filter-tester", &tw, loggo.TRACE), gc.IsNil) defer loggo.RemoveWriter("filter-tester") logger := loggo.GetLogger("juju.environs") defer logger.SetLogLevel(logger.LogLevel()) logger.SetLogLevel(loggo.TRACE) _, err := envtools.FindTools( s.env, 1, -1, "released", coretools.Filter{Number: version.Number{Major: 1, Minor: 2, Patch: 3}}) c.Assert(err, jc.Satisfies, errors.IsNotFound) // This is slightly overly prescriptive, but feel free to change or add // messages. This still helps to ensure that all log messages are // properly formed. messages := []jc.SimpleMessage{ {loggo.INFO, "reading tools with major version 1"}, {loggo.INFO, "filtering tools by version: \\d+\\.\\d+\\.\\d+"}, {loggo.TRACE, "no architecture specified when finding tools, looking for "}, {loggo.TRACE, "no series specified when finding tools, looking for \\[.*\\]"}, } sources, err := envtools.GetMetadataSources(s.env) c.Assert(err, jc.ErrorIsNil) for i := 0; i < 2*len(sources); i++ { messages = append(messages, jc.SimpleMessage{loggo.TRACE, `fetchData failed for .*`}, jc.SimpleMessage{loggo.TRACE, `cannot load index .*`}) } c.Check(tw.Log(), jc.LogMatches, messages) }
// Init is called by the cmd system to initialize the structure for // running. func (a *machineAgentCmd) Init(args []string) error { if !names.IsValidMachine(a.machineId) { return fmt.Errorf("--machine-id option must be set, and expects a non-negative integer") } if err := a.agentInitializer.CheckArgs(args); err != nil { return err } // Due to changes in the logging, and needing to care about old // models that have been upgraded, we need to explicitly remove the // file writer if one has been added, otherwise we will get duplicate // lines of all logging in the log file. loggo.RemoveWriter("logfile") if a.logToStdErr { return nil } err := a.currentConfig.ReadConfig(names.NewMachineTag(a.machineId).String()) if err != nil { return errors.Annotate(err, "cannot read agent configuration") } // the context's stderr is set as the loggo writer in github.com/juju/cmd/logging.go a.ctx.Stderr = &lumberjack.Logger{ Filename: agent.LogFilename(a.currentConfig.CurrentConfig()), MaxSize: 300, // megabytes MaxBackups: 2, } return nil }
func (s *writerSuite) SetUpTest(c *gc.C) { loggo.ResetLoggers() loggo.RemoveWriter("default") s.logger = loggo.GetLogger("test.writer") // Make it so the logger itself writes all messages. s.logger.SetLogLevel(loggo.TRACE) }
func (s *BenchmarksSuite) BenchmarkLoggingNoWriters(c *gc.C) { // No writers loggo.RemoveWriter("test") for i := 0; i < c.N; i++ { s.logger.Warningf("just a simple warning for %d", i) } }
func (s *syncToolsSuite) TestSyncToolsCommandDeprecatedDestination(c *gc.C) { called := false dir := c.MkDir() syncTools = func(sctx *sync.SyncContext) error { c.Assert(sctx.AllVersions, gc.Equals, false) c.Assert(sctx.DryRun, gc.Equals, false) c.Assert(sctx.Dev, gc.Equals, false) c.Assert(sctx.Source, gc.Equals, "") url, err := sctx.Target.URL("") c.Assert(err, gc.IsNil) c.Assert(url, gc.Equals, "file://"+dir) called = true return nil } // Register writer. var tw loggo.TestWriter c.Assert(loggo.RegisterWriter("deprecated-tester", &tw, loggo.DEBUG), gc.IsNil) defer loggo.RemoveWriter("deprecated-tester") // Add deprecated message to be checked. messages := []jc.SimpleMessage{ {loggo.WARNING, "Use of the --destination flag is deprecated in 1.18. Please use --local-dir instead."}, } // Run sync-tools command with --destination flag. ctx, err := runSyncToolsCommand(c, "-e", "test-target", "--destination", dir) c.Assert(err, gc.IsNil) c.Assert(ctx, gc.NotNil) c.Assert(called, jc.IsTrue) // Check deprecated message was logged. c.Check(tw.Log(), jc.LogMatches, messages) s.Reset(c) }
func (s *BootstrapSuite) TestGUIArchiveInfoError(c *gc.C) { if runtime.GOOS == "windows" { // TODO frankban: skipping for now due to chmod problems with mode 0000 // on Windows. We will re-enable this test after further investigation: // "jujud bootstrap" is never run on Windows anyway. c.Skip("needs chmod investigation") } dir := filepath.FromSlash(agenttools.SharedGUIDir(s.dataDir)) info := filepath.Join(dir, "downloaded-gui.txt") err := os.Chmod(info, 0000) c.Assert(err, jc.ErrorIsNil) defer os.Chmod(info, 0600) _, cmd, err := s.initBootstrapCommand( c, nil, "--model-config", s.b64yamlControllerModelConfig, "--hosted-model-config", s.b64yamlHostedModelConfig, "--instance-id", string(s.instanceId)) c.Assert(err, jc.ErrorIsNil) var tw loggo.TestWriter err = loggo.RegisterWriter("bootstrap-test", &tw, loggo.DEBUG) c.Assert(err, jc.ErrorIsNil) defer loggo.RemoveWriter("bootstrap-test") err = cmd.Run(nil) c.Assert(err, jc.ErrorIsNil) c.Assert(tw.Log(), jc.LogMatches, jc.SimpleMessages{{ loggo.WARNING, `cannot set up Juju GUI: cannot fetch GUI info: cannot read GUI metadata in tools directory: .*`, }}) }
func (s *UpgradeSuite) captureLogs(c *gc.C) { c.Assert(loggo.RegisterWriter("upgrade-tests", &s.logWriter, loggo.INFO), gc.IsNil) s.AddCleanup(func(*gc.C) { loggo.RemoveWriter("upgrade-tests") s.logWriter.Clear() }) }
func (s *logwriterSuite) BenchmarkLoggingNoWritersNoFormat(c *gc.C) { // No writers loggo.RemoveWriter("test") for i := 0; i < c.N; i++ { s.logger.Warningf("just a simple warning") } }
// Run runs a machine agent. func (a *MachineAgent) Run(_ *cmd.Context) error { // Due to changes in the logging, and needing to care about old // environments that have been upgraded, we need to explicitly remove the // file writer if one has been added, otherwise we will get duplicate // lines of all logging in the log file. loggo.RemoveWriter("logfile") defer a.tomb.Done() logger.Infof("machine agent %v start (%s [%s])", a.Tag(), version.Current, runtime.Compiler) if err := a.ReadConfig(a.Tag()); err != nil { return fmt.Errorf("cannot read agent configuration: %v", err) } a.configChangedVal.Set(struct{}{}) agentConfig := a.CurrentConfig() charm.CacheDir = filepath.Join(agentConfig.DataDir(), "charmcache") if err := a.createJujuRun(agentConfig.DataDir()); err != nil { return fmt.Errorf("cannot create juju run symlink: %v", err) } a.runner.StartWorker("api", a.APIWorker) a.runner.StartWorker("statestarter", a.newStateStarterWorker) a.runner.StartWorker("termination", func() (worker.Worker, error) { return terminationworker.NewWorker(), nil }) // At this point, all workers will have been configured to start close(a.workersStarted) err := a.runner.Wait() if err == worker.ErrTerminateAgent { err = a.uninstallAgent(agentConfig) } err = agentDone(err) a.tomb.Kill(err) return err }
func (c *SyncToolsCommand) Run(ctx *cmd.Context) (resultErr error) { // Register writer for output on screen. loggo.RegisterWriter("synctools", cmd.NewCommandLogWriter("juju.environs.sync", ctx.Stdout, ctx.Stderr), loggo.INFO) defer loggo.RemoveWriter("synctools") environ, cleanup, err := environFromName(ctx, c.EnvName, &resultErr, "Sync-tools") if err != nil { return err } defer cleanup() target := environ.Storage() if c.localDir != "" { target, err = filestorage.NewFileStorageWriter(c.localDir) if err != nil { return err } } // Prepare syncing. sctx := &sync.SyncContext{ Target: target, AllVersions: c.allVersions, MajorVersion: c.majorVersion, MinorVersion: c.minorVersion, DryRun: c.dryRun, Dev: c.dev, Public: c.public, Source: c.source, } return syncTools(sctx) }
func (s *MongoSuite) assertSuccessWithInstallStepFailCentOS(c *gc.C, exec []string, execNameFail string, returnCode int, expectedResult []jc.SimpleMessage) { type installs struct { series string pkg string } test := installs{ "centos7", "mongodb*", } for _, e := range exec { testing.PatchExecutableAsEchoArgs(c, s, e) } testing.PatchExecutableThrowError(c, s, execNameFail, returnCode) dataDir := c.MkDir() s.patchSeries(test.series) var tw loggo.TestWriter c.Assert(loggo.RegisterWriter("mongosuite", &tw, loggo.INFO), jc.ErrorIsNil) defer loggo.RemoveWriter("mongosuite") err := mongo.EnsureServer(makeEnsureServerParams(dataDir)) c.Assert(err, jc.ErrorIsNil) c.Assert(tw.Log(), jc.LogMatches, expectedResult) }
func (s *MongoSuite) assertTestMongoGetFails(c *gc.C, series string, packageManager string) { s.patchSeries(series) // Any exit code from apt-get that isn't 0 or 100 will be treated // as unexpected, skipping the normal retry loop. failCmd causes // the command to exit with 1. binDir := c.MkDir() s.PatchEnvPathPrepend(binDir) failCmd(filepath.Join(binDir, packageManager)) // Set the mongodb service as installed but not running. s.data.SetStatus(mongo.ServiceName, "installed") var tw loggo.TestWriter c.Assert(loggo.RegisterWriter("test-writer", &tw, loggo.ERROR), jc.ErrorIsNil) defer loggo.RemoveWriter("test-writer") dataDir := c.MkDir() err := mongo.EnsureServer(makeEnsureServerParams(dataDir)) // Even though apt-get failed, EnsureServer should continue and // not return the error - even though apt-get failed, the Juju // mongodb package is most likely already installed. // The error should be logged however. c.Assert(err, jc.ErrorIsNil) c.Check(tw.Log(), jc.LogMatches, []jc.SimpleMessage{ {loggo.ERROR, `packaging command failed: .+`}, {loggo.ERROR, `cannot install/upgrade mongod \(will proceed anyway\): packaging command failed`}, }) // Verify that EnsureServer continued and started the mongodb service. c.Check(s.data.Installed(), gc.HasLen, 0) s.data.CheckCallNames(c, "Installed", "Exists", "Running", "Start") }
func (s *MongoSuite) TestQuantalAptAddRepo(c *gc.C) { dir := c.MkDir() // patch manager.RunCommandWithRetry for repository addition: s.PatchValue(&manager.RunCommandWithRetry, func(string) (string, int, error) { return "", 1, fmt.Errorf("packaging command failed: exit status 1") }) s.PatchEnvPathPrepend(dir) failCmd(filepath.Join(dir, "add-apt-repository")) mockShellCommand(c, &s.CleanupSuite, "apt-get") var tw loggo.TestWriter c.Assert(loggo.RegisterWriter("test-writer", &tw, loggo.ERROR), jc.ErrorIsNil) defer loggo.RemoveWriter("test-writer") // test that we call add-apt-repository only for quantal // (and that if it fails, we log the error) s.PatchValue(&version.Current.Series, "quantal") err := mongo.EnsureServer(makeEnsureServerParams(dir, "")) c.Assert(err, jc.ErrorIsNil) c.Assert(tw.Log(), jc.LogMatches, []jc.SimpleMessage{ {loggo.ERROR, `cannot install/upgrade mongod \(will proceed anyway\): packaging command failed`}, }) s.PatchValue(&manager.RunCommandWithRetry, func(string) (string, int, error) { return "", 0, nil }) s.PatchValue(&version.Current.Series, "trusty") failCmd(filepath.Join(dir, "mongod")) err = mongo.EnsureServer(makeEnsureServerParams(dir, "")) c.Assert(err, jc.ErrorIsNil) }
func (s *BootstrapSuite) TestBootstrapJenvWarning(c *gc.C) { env, fake := makeEmptyFakeHome(c) defer fake.Restore() defaultSeriesVersion := version.Current defaultSeriesVersion.Series = config.PreferredSeries(env.Config()) // Force a dev version by having an odd minor version number. // This is because we have not uploaded any tools and auto // upload is only enabled for dev versions. defaultSeriesVersion.Minor = 11 s.PatchValue(&version.Current, defaultSeriesVersion) store, err := configstore.Default() c.Assert(err, gc.IsNil) ctx := coretesting.Context(c) environs.PrepareFromName("peckham", ctx, store) logger := "jenv.warning.test" testWriter := &loggo.TestWriter{} loggo.RegisterWriter(logger, testWriter, loggo.WARNING) defer loggo.RemoveWriter(logger) _, errc := runCommand(ctx, new(BootstrapCommand), "-e", "peckham") c.Assert(<-errc, gc.IsNil) c.Assert(testWriter.Log, jc.LogMatches, []string{"ignoring environments.yaml: using bootstrap config in .*"}) }
func (s *cmdControllerSuite) run(c *gc.C, args ...string) *cmd.Context { context := testing.Context(c) command := commands.NewJujuCommand(context) c.Assert(testing.InitCommand(command, args), jc.ErrorIsNil) c.Assert(command.Run(context), jc.ErrorIsNil) loggo.RemoveWriter("warning") return context }
func (s *environSuite) TestEnvironmentChanges(c *gc.C) { originalConfig, err := s.State.EnvironConfig() c.Assert(err, gc.IsNil) logc := make(logChan, 1009) c.Assert(loggo.RegisterWriter("testing", logc, loggo.WARNING), gc.IsNil) defer loggo.RemoveWriter("testing") obs, err := worker.NewEnvironObserver(s.State) c.Assert(err, gc.IsNil) env := obs.Environ() c.Assert(env.Config().AllAttrs(), gc.DeepEquals, originalConfig.AllAttrs()) var oldType string oldType = env.Config().AllAttrs()["type"].(string) info := s.MongoInfo(c) opts := mongo.DefaultDialOpts() st2, err := state.Open(info, opts, state.Policy(nil)) defer st2.Close() // Change to an invalid configuration and check // that the observer's environment remains the same. st2.UpdateEnvironConfig(map[string]interface{}{"type": "invalid"}, nil, nil) st2.StartSync() // Wait for the observer to register the invalid environment timeout := time.After(coretesting.LongWait) loop: for { select { case msg := <-logc: if strings.Contains(msg, "error creating Environ") { break loop } case <-timeout: c.Fatalf("timed out waiting to see broken environment") } } // Check that the returned environ is still the same. env = obs.Environ() c.Assert(env.Config().AllAttrs(), gc.DeepEquals, originalConfig.AllAttrs()) // Change the environment back to a valid configuration // with a different name and check that we see it. st2.UpdateEnvironConfig(map[string]interface{}{"type": oldType, "name": "a-new-name"}, nil, nil) st2.StartSync() for a := coretesting.LongAttempt.Start(); a.Next(); { env := obs.Environ() if !a.HasNext() { c.Fatalf("timed out waiting for new environ") } if env.Config().Name() == "a-new-name" { break } } }
func (s *BenchmarksSuite) setupTempFileWriter(c *gc.C) *os.File { loggo.RemoveWriter("test") logFile, err := ioutil.TempFile(c.MkDir(), "loggo-test") c.Assert(err, gc.IsNil) writer := loggo.NewSimpleWriter(logFile, loggo.DefaultFormatter) err = loggo.RegisterWriter("testfile", writer) c.Assert(err, gc.IsNil) return logFile }
func (s *ConfigDeprecationSuite) setupLogger(c *gc.C) func() { var err error s.writer = &loggo.TestWriter{} err = loggo.RegisterWriter("test", s.writer, loggo.WARNING) c.Assert(err, jc.ErrorIsNil) return func() { _, _, err := loggo.RemoveWriter("test") c.Assert(err, jc.ErrorIsNil) } }
func (s *wrenchSuite) SetUpTest(c *gc.C) { s.BaseSuite.SetUpTest(c) // BaseSuite turns off wrench so restore the non-testing default. wrench.SetEnabled(true) c.Assert(loggo.RegisterWriter("wrench-tests", &s.logWriter, loggo.TRACE), gc.IsNil) s.AddCleanup(func(*gc.C) { s.logWriter.Clear() loggo.RemoveWriter("wrench-tests") }) }
func (s *logwriterSuite) SetUpTest(c *gc.C) { loggo.ResetLoggers() loggo.RemoveWriter("default") s.writer = &loggo.TestWriter{} err := loggo.RegisterWriter("test", s.writer, loggo.TRACE) c.Assert(err, gc.IsNil) s.logger = loggo.GetLogger("test.writer") // Make it so the logger itself writes all messages. s.logger.SetLogLevel(loggo.TRACE) }
func (c *signMetadataCommand) Run(context *cmd.Context) error { loggo.RegisterWriter("signmetadata", cmd.NewCommandLogWriter("juju.plugins.metadata", context.Stdout, context.Stderr), loggo.INFO) defer loggo.RemoveWriter("signmetadata") keyData, err := ioutil.ReadFile(c.keyFile) if err != nil { return err } dir := context.AbsPath(c.dir) return process(dir, string(keyData), c.passphrase) }
func gatherLog(f func()) []loggo.Entry { var tw loggo.TestWriter err := loggo.RegisterWriter("test", &tw) if err != nil { panic(err) } defer loggo.RemoveWriter("test") f() return tw.Log() }
// Start starts logging using the given Context. func (log *Log) Start(ctx *Context) error { if log.Verbose && log.Quiet { return fmt.Errorf(`"verbose" and "quiet" flags clash, please use one or the other, not both`) } ctx.quiet = log.Quiet ctx.verbose = log.Verbose if log.Path != "" { path := ctx.AbsPath(log.Path) target, err := os.OpenFile(path, os.O_WRONLY|os.O_APPEND|os.O_CREATE, 0644) if err != nil { return err } writer := log.GetLogWriter(target) err = loggo.RegisterWriter("logfile", writer) if err != nil { return err } } level := loggo.WARNING if log.ShowLog { level = loggo.INFO } if log.Debug { log.ShowLog = true level = loggo.DEBUG // override quiet or verbose if set, this way all the information goes // to the log file. ctx.quiet = true ctx.verbose = false } if log.ShowLog { // We replace the default writer to use ctx.Stderr rather than os.Stderr. writer := log.GetLogWriter(ctx.Stderr) _, err := loggo.ReplaceDefaultWriter(writer) if err != nil { return err } } else { loggo.RemoveWriter("default") // Create a simple writer that doesn't show filenames, or timestamps, // and only shows warning or above. writer := NewWarningWriter(ctx.Stderr) err := loggo.RegisterWriter("warning", writer) if err != nil { return err } } // Set the level on the root logger. root := loggo.GetLogger("") root.SetLogLevel(level) // Override the logging config with specified logging config. loggo.ConfigureLoggers(log.Config) return nil }
func (s *prepareSuite) assertCall(c *gc.C, args params.Entities, expectResults *params.MachineNetworkConfigResults, expectErr string) (error, []loggo.TestLogValues) { // Capture the logs for later inspection. logger := loggo.GetLogger("juju.apiserver.provisioner") defer logger.SetLogLevel(logger.LogLevel()) logger.SetLogLevel(loggo.TRACE) var tw loggo.TestWriter c.Assert(loggo.RegisterWriter("test", &tw, loggo.TRACE), gc.IsNil) defer loggo.RemoveWriter("test") results, err := s.provAPI.PrepareContainerInterfaceInfo(args) c.Logf("PrepareContainerInterfaceInfo returned: err=%v, results=%v", err, results) c.Assert(results.Results, gc.HasLen, len(args.Entities)) if expectErr == "" { c.Assert(err, jc.ErrorIsNil) c.Assert(expectResults, gc.NotNil) c.Assert(results.Results, gc.HasLen, len(expectResults.Results)) // Check for any "regex:" prefixes first. Then replace // addresses in expected with the actual ones, so we can use // jc.DeepEquals on the whole result below. // Also check MAC addresses are valid, but as they're randomly // generated we can't test specific values. for i, expect := range expectResults.Results { cfg := results.Results[i].Config c.Assert(cfg, gc.HasLen, len(expect.Config)) for j, expCfg := range expect.Config { if strings.HasPrefix(expCfg.Address, "regex:") { rex := strings.TrimPrefix(expCfg.Address, "regex:") c.Assert(cfg[j].Address, gc.Matches, rex) expectResults.Results[i].Config[j].Address = cfg[j].Address } macAddress := cfg[j].MACAddress c.Assert(macAddress[:8], gc.Equals, provisioner.MACAddressTemplate[:8]) remainder := strings.Replace(macAddress[8:], ":", "", 3) c.Assert(remainder, gc.HasLen, 6) _, err = hex.DecodeString(remainder) c.Assert(err, jc.ErrorIsNil) expectResults.Results[i].Config[j].MACAddress = macAddress } } c.Assert(results, jc.DeepEquals, *expectResults) } else { c.Assert(err, gc.ErrorMatches, expectErr) if len(args.Entities) > 0 { result := results.Results[0] // Not using jc.ErrorIsNil below because // (*params.Error)(nil) does not satisfy the error // interface. c.Assert(result.Error, gc.IsNil) c.Assert(result.Config, gc.IsNil) } } return err, tw.Log() }
func (s *environSuite) TestEnvironmentChanges(c *gc.C) { s.st.SetConfig(c, nil) logc := make(logChan, 1009) c.Assert(loggo.RegisterWriter("testing", logc, loggo.WARNING), gc.IsNil) defer loggo.RemoveWriter("testing") obs, err := worker.NewEnvironObserver(s.st) c.Assert(err, jc.ErrorIsNil) env := obs.Environ() s.st.AssertConfig(c, env.Config()) // Change to an invalid configuration and check // that the observer's environment remains the same. originalConfig, err := s.st.EnvironConfig() c.Assert(err, jc.ErrorIsNil) s.st.SetConfig(c, coretesting.Attrs{ "type": "invalid", }) // Wait for the observer to register the invalid environment loop: for { select { case msg := <-logc: if strings.Contains(msg, "error creating an environment") { break loop } case <-time.After(coretesting.LongWait): c.Fatalf("timed out waiting to see broken environment") } } // Check that the returned environ is still the same. env = obs.Environ() c.Assert(env.Config().AllAttrs(), jc.DeepEquals, originalConfig.AllAttrs()) // Change the environment back to a valid configuration // with a different name and check that we see it. s.st.SetConfig(c, coretesting.Attrs{ "name": "a-new-name", }) for a := coretesting.LongAttempt.Start(); a.Next(); { env := obs.Environ() if !a.HasNext() { c.Fatalf("timed out waiting for new environ") } if env.Config().Name() == "a-new-name" { break } } }
func runJujuCommand(c *gc.C, args ...string) (*cmd.Context, error) { // NOTE (alesstimec): Writers need to be reset, because // they are set globally in the juju/cmd package and will // return an error if we attempt to run two commands in the // same test. loggo.RemoveWriter("warning") ctx, err := cmd.DefaultContext() c.Assert(err, jc.ErrorIsNil) command := jujucmd.NewJujuCommand(ctx) return testing.RunCommand(c, command, args...) }
func (s *cmdLoginSuite) run(c *gc.C, stdin io.Reader, args ...string) *cmd.Context { context := testing.Context(c) if stdin != nil { context.Stdin = stdin } command := commands.NewJujuCommand(context) c.Assert(testing.InitCommand(command, args), jc.ErrorIsNil) c.Assert(command.Run(context), jc.ErrorIsNil) loggo.RemoveWriter("warning") // remove logger added by main command return context }