Example #1
0
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: .*`,
	}})
}
Example #2
0
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")
}
Example #3
0
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)
}
Example #4
0
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)
}
Example #5
0
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)
}
Example #6
0
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)
}
Example #7
0
func (*diskStoreSuite) TestConcurrentAccess(c *gc.C) {
	var tw loggo.TestWriter
	c.Assert(loggo.RegisterWriter("test-log", &tw, loggo.DEBUG), gc.IsNil)

	dir := c.MkDir()
	store, err := configstore.NewDisk(dir)
	c.Assert(err, jc.ErrorIsNil)

	envDir := storePath(dir, "")
	lock, err := configstore.AcquireEnvironmentLock(envDir, "blocking-op")
	c.Assert(err, jc.ErrorIsNil)
	defer lock.Unlock()

	_, err = store.ReadInfo("someenv")
	c.Assert(errors.Cause(err), gc.Equals, fslock.ErrTimeout)

	// Using . between environments and env.lock so we don't have to care
	// about forward vs. backwards slash separator.
	messages := []jc.SimpleMessage{
		{loggo.WARNING, `configstore lock held, lock dir: .*environments.env\.lock`},
		{loggo.WARNING, `lock holder message: pid: \d+, operation: blocking-op`},
	}

	c.Check(tw.Log(), jc.LogMatches, messages)
}
Example #8
0
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)
}
Example #9
0
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()
}
Example #10
0
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()
}
Example #11
0
func (*auditSuite) TestAuditEventWrittenToAuditLogger(c *gc.C) {
	var tw loggo.TestWriter
	c.Assert(loggo.RegisterWriter("audit-log", &tw, loggo.DEBUG), gc.IsNil)

	u := &mockUser{tag: "user-agnus"}
	Audit(u, "donut eaten, %v donut(s) remain", 7)

	// Add deprecated message to be checked.
	messages := []jc.SimpleMessage{
		{loggo.INFO, `user-agnus: donut eaten, 7 donut\(s\) remain`},
	}

	c.Check(tw.Log(), jc.LogMatches, messages)
}
Example #12
0
func (s *BootstrapSuite) TestBootstrapJenvWarning(c *gc.C) {
	const envName = "devenv"
	s.patchVersionAndSeries(c, envName)

	store, err := configstore.Default()
	c.Assert(err, jc.ErrorIsNil)
	ctx := coretesting.Context(c)
	environs.PrepareFromName(envName, envcmd.BootstrapContext(ctx), store)

	logger := "jenv.warning.test"
	var testWriter loggo.TestWriter
	loggo.RegisterWriter(logger, &testWriter, loggo.WARNING)
	defer loggo.RemoveWriter(logger)

	_, errc := cmdtesting.RunCommand(ctx, newBootstrapCommand(), "-e", envName, "--auto-upgrade")
	c.Assert(<-errc, gc.IsNil)
	c.Assert(testWriter.Log(), jc.LogMatches, []string{"ignoring environments.yaml: using bootstrap config in .*"})
}
Example #13
0
func (s *ServiceSuite) TestSetUnsupportedConstraintsWarning(c *gc.C) {
	defer loggo.ResetWriters()
	logger := loggo.GetLogger("test")
	logger.SetLogLevel(loggo.DEBUG)
	var tw loggo.TestWriter
	c.Assert(loggo.RegisterWriter("constraints-tester", &tw, loggo.DEBUG), gc.IsNil)

	cons := constraints.MustParse("mem=4G cpu-power=10")
	err := s.mysql.SetConstraints(cons)
	c.Assert(err, gc.IsNil)
	c.Assert(tw.Log(), jc.LogMatches, jc.SimpleMessages{{
		loggo.WARNING,
		`setting constraints on service "mysql": unsupported constraints: cpu-power`},
	})
	scons, err := s.mysql.Constraints()
	c.Assert(err, gc.IsNil)
	c.Assert(scons, gc.DeepEquals, cons)
}
Example #14
0
func (s *BootstrapSuite) TestGUIArchiveSuccess(c *gc.C) {
	_, 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.DEBUG,
		`Juju GUI successfully set up`,
	}})

	// Retrieve the state so that it is possible to access the GUI storage.
	st, err := state.Open(testing.ModelTag, &mongo.MongoInfo{
		Info: mongo.Info{
			Addrs:  []string{gitjujutesting.MgoServer.Addr()},
			CACert: testing.CACert,
		},
		Password: testPassword,
	}, mongotest.DialOpts(), environs.NewStatePolicy())
	c.Assert(err, jc.ErrorIsNil)
	defer st.Close()

	// The GUI archive has been uploaded to the GUI storage.
	storage, err := st.GUIStorage()
	c.Assert(err, jc.ErrorIsNil)
	defer storage.Close()
	allMeta, err := storage.AllMetadata()
	c.Assert(err, jc.ErrorIsNil)
	c.Assert(allMeta, gc.HasLen, 1)
	c.Assert(allMeta[0].Version, gc.Equals, "2.0.42")

	// The current GUI version has been set.
	vers, err := st.GUIVersion()
	c.Assert(err, jc.ErrorIsNil)
	c.Assert(vers.String(), gc.Equals, "2.0.42")
}
Example #15
0
func (s *loginSuite) TestLoginSetsLogIdentifier(c *gc.C) {
	info, cleanup := s.setupServer(c)
	defer cleanup()

	machineInState, err := s.State.AddMachine("quantal", state.JobHostUnits)
	c.Assert(err, gc.IsNil)
	err = machineInState.SetProvisioned("foo", "fake_nonce", nil)
	c.Assert(err, gc.IsNil)
	password, err := utils.RandomPassword()
	c.Assert(err, gc.IsNil)
	err = machineInState.SetPassword(password)
	c.Assert(err, gc.IsNil)
	c.Assert(machineInState.Tag(), gc.Equals, names.NewMachineTag("0"))

	var tw loggo.TestWriter
	c.Assert(loggo.RegisterWriter("login-tester", &tw, loggo.DEBUG), gc.IsNil)
	defer loggo.RemoveWriter("login-tester")

	// TODO(dfc) this should be a Tag
	info.Tag = machineInState.Tag().String()
	info.Password = password
	info.Nonce = "fake_nonce"

	apiConn, err := api.Open(info, fastDialOpts)
	c.Assert(err, gc.IsNil)
	defer apiConn.Close()
	// TODO(dfc) why does this return a string
	apiMachine, err := apiConn.Machiner().Machine(machineInState.Tag().(names.MachineTag))
	c.Assert(err, gc.IsNil)
	c.Assert(apiMachine.Tag(), gc.Equals, machineInState.Tag().String())

	c.Assert(tw.Log(), jc.LogMatches, []string{
		`<- \[[0-9A-F]+\] <unknown> {"RequestId":1,"Type":"Admin","Request":"Login",` +
			`"Params":{"AuthTag":"machine-0","Password":"******"]*","Nonce":"fake_nonce"}` +
			`}`,
		// Now that we are logged in, we see the entity's tag
		// [0-9.umns] is to handle timestamps that are ns, us, ms, or s
		// long, though we expect it to be in the 'ms' range.
		`-> \[[0-9A-F]+\] machine-0 [0-9.]+[umn]?s {"RequestId":1,"Response":.*} Admin\[""\].Login`,
		`<- \[[0-9A-F]+\] machine-0 {"RequestId":2,"Type":"Machiner","Request":"Life","Params":{"Entities":\[{"Tag":"machine-0"}\]}}`,
		`-> \[[0-9A-F]+\] machine-0 [0-9.umns]+ {"RequestId":2,"Response":{"Results":\[{"Life":"alive","Error":null}\]}} Machiner\[""\]\.Life`,
	})
}
Example #16
0
func assertLogs(c *gc.C, ctx jujuc.Context, writer *loggo.TestWriter, unitname, badge string) {
	msg1 := "the chickens"
	msg2 := "are 110% AWESOME"
	com, err := jujuc.NewCommand(ctx, cmdString("juju-log"))
	c.Assert(err, jc.ErrorIsNil)
	for _, t := range []struct {
		args  []string
		level loggo.Level
	}{
		{
			level: loggo.INFO,
		}, {
			args:  []string{"--debug"},
			level: loggo.DEBUG,
		}, {
			args:  []string{"--log-level", "TRACE"},
			level: loggo.TRACE,
		}, {
			args:  []string{"--log-level", "info"},
			level: loggo.INFO,
		}, {
			args:  []string{"--log-level", "WaRnInG"},
			level: loggo.WARNING,
		}, {
			args:  []string{"--log-level", "error"},
			level: loggo.ERROR,
		},
	} {
		writer.Clear()
		c.Assert(err, jc.ErrorIsNil)

		args := append(t.args, msg1, msg2)
		code := cmd.Main(com, &cmd.Context{}, args)
		c.Assert(code, gc.Equals, 0)
		log := writer.Log()
		c.Assert(log, gc.HasLen, 1)
		c.Assert(log[0].Level, gc.Equals, t.level)
		c.Assert(log[0].Module, gc.Equals, fmt.Sprintf("unit.%s.juju-log", unitname))
		c.Assert(log[0].Message, gc.Equals, fmt.Sprintf("%s%s %s", badge, msg1, msg2))
	}
}
Example #17
0
func (s *BootstrapSuite) TestCannotRecordThenCannotStop(c *gc.C) {
	innerStorage := newStorage(s, c)
	stor := &mockStorage{Storage: innerStorage}

	startInstance := func(
		_ string, _ constraints.Value, _ []string, _ tools.List, _ *cloudinit.MachineConfig,
	) (
		instance.Instance, *instance.HardwareCharacteristics, []network.Info, error,
	) {
		stor.putErr = fmt.Errorf("suddenly a wild blah")
		return &mockInstance{id: "i-blah"}, nil, nil, nil
	}

	var stopped []instance.Id
	stopInstances := func(instances []instance.Id) error {
		stopped = append(stopped, instances...)
		return fmt.Errorf("bork bork borken")
	}

	var tw loggo.TestWriter
	c.Assert(loggo.RegisterWriter("bootstrap-tester", &tw, loggo.DEBUG), gc.IsNil)
	defer loggo.RemoveWriter("bootstrap-tester")

	env := &mockEnviron{
		storage:       stor,
		startInstance: startInstance,
		stopInstances: stopInstances,
		config:        configGetter(c),
	}

	ctx := coretesting.Context(c)
	_, _, _, err := common.Bootstrap(ctx, env, environs.BootstrapParams{
		AvailableTools: tools.List{&tools.Tools{Version: version.Current}},
	})
	c.Assert(err, gc.ErrorMatches, "cannot save state: suddenly a wild blah")
	c.Assert(stopped, gc.HasLen, 1)
	c.Assert(stopped[0], gc.Equals, instance.Id("i-blah"))
	c.Assert(tw.Log(), jc.LogMatches, []jc.SimpleMessage{{
		loggo.ERROR, `cannot stop failed bootstrap instance "i-blah": bork bork borken`,
	}})
}
Example #18
0
func (s *BootstrapSuite) TestGUIArchiveError(c *gc.C) {
	dir := filepath.FromSlash(agenttools.SharedGUIDir(s.dataDir))
	archive := filepath.Join(dir, "gui.tar.bz2")
	err := os.Remove(archive)
	c.Assert(err, jc.ErrorIsNil)
	_, 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(tw.Log(), jc.LogMatches, jc.SimpleMessages{{
		loggo.WARNING,
		`cannot set up Juju GUI: cannot read GUI archive: .*`,
	}})
}
Example #19
0
func (s *BootstrapSuite) TestBootstrapJenvWarning(c *gc.C) {
	env := resetJujuHome(c, "devenv")
	defaultSeriesVersion := version.Current
	defaultSeriesVersion.Series = config.PreferredSeries(env.Config())
	// 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)

	store, err := configstore.Default()
	c.Assert(err, jc.ErrorIsNil)
	ctx := coretesting.Context(c)
	environs.PrepareFromName("devenv", envcmd.BootstrapContext(ctx), store)

	logger := "jenv.warning.test"
	var testWriter loggo.TestWriter
	loggo.RegisterWriter(logger, &testWriter, loggo.WARNING)
	defer loggo.RemoveWriter(logger)

	_, errc := cmdtesting.RunCommand(ctx, envcmd.Wrap(new(BootstrapCommand)), "-e", "devenv")
	c.Assert(<-errc, gc.IsNil)
	c.Assert(testWriter.Log(), jc.LogMatches, []string{"ignoring environments.yaml: using bootstrap config in .*"})
}
Example #20
0
func (*diskStoreSuite) TestConcurrentAccessBreaksIfTimeExceeded(c *gc.C) {
	var tw loggo.TestWriter
	c.Assert(loggo.RegisterWriter("test-log", &tw, loggo.DEBUG), gc.IsNil)

	dir := c.MkDir()
	store, err := configstore.NewDisk(dir)
	c.Assert(err, jc.ErrorIsNil)

	envDir := storePath(dir, "")
	_, err = configstore.AcquireEnvironmentLock(envDir, "blocking-op")
	c.Assert(err, jc.ErrorIsNil)

	_, err = store.ReadInfo("somemodel")
	c.Check(err, jc.Satisfies, errors.IsNotFound)

	// Using . between environments and env.lock so we don't have to care
	// about forward vs. backwards slash separator.
	messages := []jc.SimpleMessage{
		{loggo.WARNING, `breaking configstore lock, lock dir: .*models.env\.lock`},
		{loggo.WARNING, `lock holder message: pid: \d+, operation: blocking-op`},
	}

	c.Check(tw.Log(), jc.LogMatches, messages)
}
Example #21
0
func (*suite) TestNoWarningForDeprecatedButUnusedEnv(c *gc.C) {
	// This tests that a config that has a deprecated field doesn't
	// generate a Warning if we don't actually ask for that environment.
	// However, we can only really trigger that when we have a deprecated
	// field. If support for the field is removed entirely, another
	// mechanism will need to be used
	content := `
environments:
    valid:
        type: dummy
        state-server: false
    deprecated:
        type: dummy
        state-server: false
        tools-metadata-url: aknowndeprecatedfield
        lxc-use-clone: true
`
	var tw loggo.TestWriter
	// we only capture Warning or above
	c.Assert(loggo.RegisterWriter("invalid-env-tester", &tw, loggo.WARNING), gc.IsNil)
	defer loggo.RemoveWriter("invalid-env-tester")

	envs, err := environs.ReadEnvironsBytes([]byte(content))
	c.Check(err, jc.ErrorIsNil)
	names := envs.Names()
	sort.Strings(names)
	c.Check(names, gc.DeepEquals, []string{"deprecated", "valid"})
	// There should be no warning in the log
	c.Check(tw.Log(), gc.HasLen, 0)
	// Now we actually grab the 'valid' entry
	_, err = envs.Config("valid")
	c.Check(err, jc.ErrorIsNil)
	// And still we have no warnings
	c.Check(tw.Log(), gc.HasLen, 0)
	// Only once we grab the deprecated one do we see any warnings
	_, err = envs.Config("deprecated")
	c.Check(err, jc.ErrorIsNil)
	c.Check(tw.Log(), gc.HasLen, 2)
}
Example #22
0
func checkLastMessage(c *gc.C, writer *loggo.TestWriter, expected string) {
	log := writer.Log()
	writer.Clear()
	obtained := log[len(log)-1].Message
	c.Check(obtained, gc.Equals, expected)
}
Example #23
0
func (s *ConstraintsSuite) TestDefaults(c *gc.C) {

	for _, test := range []struct {
		cons     string
		expected kvm.StartParams
		infoLog  []string
	}{{
		expected: kvm.StartParams{
			Memory:   kvm.DefaultMemory,
			CpuCores: kvm.DefaultCpu,
			RootDisk: kvm.DefaultDisk,
		},
	}, {
		cons: "mem=256M",
		expected: kvm.StartParams{
			Memory:   kvm.MinMemory,
			CpuCores: kvm.DefaultCpu,
			RootDisk: kvm.DefaultDisk,
		},
	}, {
		cons: "mem=4G",
		expected: kvm.StartParams{
			Memory:   4 * 1024,
			CpuCores: kvm.DefaultCpu,
			RootDisk: kvm.DefaultDisk,
		},
	}, {
		cons: "cpu-cores=4",
		expected: kvm.StartParams{
			Memory:   kvm.DefaultMemory,
			CpuCores: 4,
			RootDisk: kvm.DefaultDisk,
		},
	}, {
		cons: "cpu-cores=0",
		expected: kvm.StartParams{
			Memory:   kvm.DefaultMemory,
			CpuCores: kvm.MinCpu,
			RootDisk: kvm.DefaultDisk,
		},
	}, {
		cons: "root-disk=512M",
		expected: kvm.StartParams{
			Memory:   kvm.DefaultMemory,
			CpuCores: kvm.DefaultCpu,
			RootDisk: kvm.MinDisk,
		},
	}, {
		cons: "root-disk=4G",
		expected: kvm.StartParams{
			Memory:   kvm.DefaultMemory,
			CpuCores: kvm.DefaultCpu,
			RootDisk: 4,
		},
	}, {
		cons: "arch=armhf",
		expected: kvm.StartParams{
			Memory:   kvm.DefaultMemory,
			CpuCores: kvm.DefaultCpu,
			RootDisk: kvm.DefaultDisk,
		},
		infoLog: []string{
			`arch constraint of "armhf" being ignored as not supported`,
		},
	}, {
		cons: "container=lxc",
		expected: kvm.StartParams{
			Memory:   kvm.DefaultMemory,
			CpuCores: kvm.DefaultCpu,
			RootDisk: kvm.DefaultDisk,
		},
		infoLog: []string{
			`container constraint of "lxc" being ignored as not supported`,
		},
	}, {
		cons: "cpu-power=100",
		expected: kvm.StartParams{
			Memory:   kvm.DefaultMemory,
			CpuCores: kvm.DefaultCpu,
			RootDisk: kvm.DefaultDisk,
		},
		infoLog: []string{
			`cpu-power constraint of 100 being ignored as not supported`,
		},
	}, {
		cons: "tags=foo,bar",
		expected: kvm.StartParams{
			Memory:   kvm.DefaultMemory,
			CpuCores: kvm.DefaultCpu,
			RootDisk: kvm.DefaultDisk,
		},
		infoLog: []string{
			`tags constraint of "foo,bar" being ignored as not supported`,
		},
	}, {
		cons: "mem=4G cpu-cores=4 root-disk=20G arch=armhf cpu-power=100 container=lxc tags=foo,bar",
		expected: kvm.StartParams{
			Memory:   4 * 1024,
			CpuCores: 4,
			RootDisk: 20,
		},
		infoLog: []string{
			`arch constraint of "armhf" being ignored as not supported`,
			`container constraint of "lxc" being ignored as not supported`,
			`cpu-power constraint of 100 being ignored as not supported`,
			`tags constraint of "foo,bar" being ignored as not supported`,
		},
	}} {
		var tw loggo.TestWriter
		c.Assert(loggo.RegisterWriter("constraint-tester", &tw, loggo.DEBUG), gc.IsNil)
		cons := constraints.MustParse(test.cons)
		params := kvm.ParseConstraintsToStartParams(cons)
		c.Check(params, gc.DeepEquals, test.expected)
		c.Check(tw.Log(), jc.LogMatches, test.infoLog)
		loggo.RemoveWriter("constraint-tester")
	}
}