func (s *PublishSuite) TestPreExistingPublishedEdge(c *gc.C) { addMeta(c, s.branch, "") // If it doesn't find the right digest on the first try, it asks again for // any digest at all to keep the tip in mind. There's a small chance that // on the second request the tip has changed and matches the digest we're // looking for, in which case we have the answer already. digest, err := s.branch.RevisionId() c.Assert(err, gc.IsNil) var body string body = `{"cs:precise/wordpress": {"errors": ["entry not found"]}}` testing.Server.Response(200, nil, []byte(body)) body = `{"cs:precise/wordpress": {"kind": "published", "digest": %q, "revision": 42}}` testing.Server.Response(200, nil, []byte(fmt.Sprintf(body, digest))) ctx, err := s.runPublish(c, "cs:precise/wordpress") c.Assert(err, gc.IsNil) c.Assert(testing.Stdout(ctx), gc.Equals, "cs:precise/wordpress-42\n") req := testing.Server.WaitRequest() c.Assert(req.URL.Path, gc.Equals, "/charm-event") c.Assert(req.Form.Get("charms"), gc.Equals, "cs:precise/wordpress@"+digest) req = testing.Server.WaitRequest() c.Assert(req.URL.Path, gc.Equals, "/charm-event") c.Assert(req.Form.Get("charms"), gc.Equals, "cs:precise/wordpress") }
func (s *RunSuite) TestAllMachines(c *gc.C) { mock := s.setupMockAPI() mock.setMachinesAlive("0", "1") response0 := mockResponse{ stdout: "megatron\n", machineId: "0", } response1 := mockResponse{ error: "command timed out", machineId: "1", } mock.setResponse("0", response0) unformatted := ConvertRunResults([]params.RunResult{ makeRunResult(response0), makeRunResult(response1), }) jsonFormatted, err := cmd.FormatJson(unformatted) c.Assert(err, gc.IsNil) context, err := testing.RunCommand(c, &RunCommand{}, "--format=json", "--all", "hostname") c.Assert(err, gc.IsNil) c.Check(testing.Stdout(context), gc.Equals, string(jsonFormatted)+"\n") }
func (s *RunSuite) TestRunForMachineAndUnit(c *gc.C) { mock := s.setupMockAPI() machineResponse := mockResponse{ stdout: "megatron\n", machineId: "0", } unitResponse := mockResponse{ stdout: "bumblebee", machineId: "1", unitId: "unit/0", } mock.setResponse("0", machineResponse) mock.setResponse("unit/0", unitResponse) unformatted := ConvertRunResults([]params.RunResult{ makeRunResult(machineResponse), makeRunResult(unitResponse), }) jsonFormatted, err := cmd.FormatJson(unformatted) c.Assert(err, gc.IsNil) context, err := testing.RunCommand(c, envcmd.Wrap(&RunCommand{}), "--format=json", "--machine=0", "--unit=unit/0", "hostname", ) c.Assert(err, gc.IsNil) c.Check(testing.Stdout(context), gc.Equals, string(jsonFormatted)+"\n") }
func (s *PublishSuite) TestFullPublish(c *gc.C) { addMeta(c, s.branch, "") digest, err := s.branch.RevisionId() c.Assert(err, gc.IsNil) pushBranch := bzr.New(c.MkDir()) err = pushBranch.Init() c.Assert(err, gc.IsNil) cmd := &PublishCommand{} cmd.ChangePushLocation(func(location string) string { c.Assert(location, gc.Equals, "lp:~user/charms/precise/wordpress/trunk") return pushBranch.Location() }) cmd.SetPollDelay(testing.ShortWait) var body string // The local digest isn't found. body = `{"cs:~user/precise/wordpress": {"kind": "", "errors": ["entry not found"]}}` testing.Server.Response(200, nil, []byte(body)) // But the charm exists with an arbitrary non-matching digest. body = `{"cs:~user/precise/wordpress": {"kind": "published", "digest": "other-digest"}}` testing.Server.Response(200, nil, []byte(body)) // After the branch is pushed we fake the publishing delay. body = `{"cs:~user/precise/wordpress": {"kind": "published", "digest": "other-digest"}}` testing.Server.Response(200, nil, []byte(body)) // And finally report success. body = `{"cs:~user/precise/wordpress": {"kind": "published", "digest": %q, "revision": 42}}` testing.Server.Response(200, nil, []byte(fmt.Sprintf(body, digest))) ctx, err := testing.RunCommandInDir(c, envcmd.Wrap(cmd), []string{"cs:~user/precise/wordpress"}, s.dir) c.Assert(err, gc.IsNil) c.Assert(testing.Stdout(ctx), gc.Equals, "cs:~user/precise/wordpress-42\n") // Ensure the branch was actually pushed. pushDigest, err := pushBranch.RevisionId() c.Assert(err, gc.IsNil) c.Assert(pushDigest, gc.Equals, digest) // And that all the requests were sent with the proper data. req := testing.Server.WaitRequest() c.Assert(req.URL.Path, gc.Equals, "/charm-event") c.Assert(req.Form.Get("charms"), gc.Equals, "cs:~user/precise/wordpress@"+digest) for i := 0; i < 3; i++ { // The second request grabs tip to see the current state, and the // following requests are done after pushing to see when it changes. req = testing.Server.WaitRequest() c.Assert(req.URL.Path, gc.Equals, "/charm-event") c.Assert(req.Form.Get("charms"), gc.Equals, "cs:~user/precise/wordpress") } }
func (s *UserCommandSuite) TestHelp(c *gc.C) { // Check the help output ctx, err := coretesting.RunCommand(c, NewUserCommand(), "--help") c.Assert(err, gc.IsNil) c.Assert(coretesting.Stdout(ctx), gc.Matches, "(?s)usage: user <command> .+"+ userCommandPurpose+".+"+ userCommandDoc+".+") // Check that we have registered all the sub commands by // inspecting the help output. var namesFound []string commandHelp := strings.SplitAfter(coretesting.Stdout(ctx), "commands:")[1] commandHelp = strings.TrimSpace(commandHelp) for _, line := range strings.Split(commandHelp, "\n") { namesFound = append(namesFound, strings.TrimSpace(strings.Split(line, " - ")[0])) } c.Assert(namesFound, gc.DeepEquals, expectedUserCommmandNames) }
func (s *DeploySuite) TestUpgradeReportsDeprecated(c *gc.C) { coretesting.Charms.ClonedDirPath(s.SeriesPath, "dummy") ctx, err := coretesting.RunCommand(c, envcmd.Wrap(&DeployCommand{}), "local:dummy", "-u") c.Assert(err, gc.IsNil) c.Assert(coretesting.Stdout(ctx), gc.Equals, "") output := strings.Split(coretesting.Stderr(ctx), "\n") c.Check(output[0], gc.Matches, `Added charm ".*" to the environment.`) c.Check(output[1], gc.Equals, "--upgrade (or -u) is deprecated and ignored; charms are always deployed with a unique revision.") }
func (s *SuperCommandSuite) TestMissingCallbackErrors(c *gc.C) { callback := func(ctx *cmd.Context, subcommand string, args []string) error { return fmt.Errorf("command not found %q", subcommand) } ctx := testing.Context(c) code := cmd.Main(NewSuperWithCallback(callback), ctx, []string{"foo"}) c.Assert(code, gc.Equals, 1) c.Assert(testing.Stdout(ctx), gc.Equals, "") c.Assert(testing.Stderr(ctx), gc.Equals, "ERROR command not found \"foo\"\n") }
func (s *ListKeysSuite) TestListFullKeys(c *gc.C) { key1 := sshtesting.ValidKeyOne.Key + " user@host" key2 := sshtesting.ValidKeyTwo.Key + " another@host" s.setAuthorizedKeys(c, key1, key2) context, err := coretesting.RunCommand(c, envcmd.Wrap(&ListKeysCommand{}), "--full") c.Assert(err, gc.IsNil) output := strings.TrimSpace(coretesting.Stdout(context)) c.Assert(err, gc.IsNil) c.Assert(output, gc.Matches, "Keys for user admin:\n.*user@host\n.*another@host") }
func (s *RunSuite) TestSingleResponse(c *gc.C) { mock := s.setupMockAPI() mock.setMachinesAlive("0") mockResponse := mockResponse{ stdout: "stdout\n", stderr: "stderr\n", code: 42, machineId: "0", } mock.setResponse("0", mockResponse) unformatted := ConvertRunResults([]params.RunResult{ makeRunResult(mockResponse)}) yamlFormatted, err := cmd.FormatYaml(unformatted) c.Assert(err, gc.IsNil) jsonFormatted, err := cmd.FormatJson(unformatted) c.Assert(err, gc.IsNil) for i, test := range []struct { message string format string stdout string stderr string errorMatch string }{{ message: "smart (default)", stdout: "stdout\n", stderr: "stderr\n", errorMatch: "subprocess encountered error code 42", }, { message: "yaml output", format: "yaml", stdout: string(yamlFormatted) + "\n", }, { message: "json output", format: "json", stdout: string(jsonFormatted) + "\n", }} { c.Log(fmt.Sprintf("%v: %s", i, test.message)) args := []string{} if test.format != "" { args = append(args, "--format", test.format) } args = append(args, "--all", "ignored") context, err := testing.RunCommand(c, envcmd.Wrap(&RunCommand{}), args...) if test.errorMatch != "" { c.Check(err, gc.ErrorMatches, test.errorMatch) } else { c.Check(err, gc.IsNil) } c.Check(testing.Stdout(context), gc.Equals, test.stdout) c.Check(testing.Stderr(context), gc.Equals, test.stderr) } }
func (s *SuperCommandSuite) TestMissingCallbackContextWiredIn(c *gc.C) { callback := func(ctx *cmd.Context, subcommand string, args []string) error { fmt.Fprintf(ctx.Stdout, "this is std out") fmt.Fprintf(ctx.Stderr, "this is std err") return nil } ctx := testing.Context(c) code := cmd.Main(NewSuperWithCallback(callback), ctx, []string{"foo", "bar", "baz", "--debug"}) c.Assert(code, gc.Equals, 0) c.Assert(testing.Stdout(ctx), gc.Equals, "this is std out") c.Assert(testing.Stderr(ctx), gc.Equals, "this is std err") }
func (s *PortsSuite) TestOpenCloseDeprecation(c *gc.C) { hctx := s.GetHookContext(c, -1, "") for _, t := range portsFormatDeprectaionTests { name := t.cmd[0] com, err := jujuc.NewCommand(hctx, name) c.Assert(err, gc.IsNil) ctx := testing.Context(c) code := cmd.Main(com, ctx, t.cmd[1:]) c.Assert(code, gc.Equals, 0) c.Assert(testing.Stdout(ctx), gc.Equals, "") c.Assert(testing.Stderr(ctx), gc.Equals, "--format flag deprecated for command \""+name+"\"") } }
func (s *ListKeysSuite) TestListKeysNonDefaultUser(c *gc.C) { key1 := sshtesting.ValidKeyOne.Key + " user@host" key2 := sshtesting.ValidKeyTwo.Key + " another@host" s.setAuthorizedKeys(c, key1, key2) _, err := s.State.AddUser("fred", "password") c.Assert(err, gc.IsNil) context, err := coretesting.RunCommand(c, envcmd.Wrap(&ListKeysCommand{}), "--user", "fred") c.Assert(err, gc.IsNil) output := strings.TrimSpace(coretesting.Stdout(context)) c.Assert(err, gc.IsNil) c.Assert(output, gc.Matches, "Keys for user fred:\n.*\\(user@host\\)\n.*\\(another@host\\)") }
func (s *PublishSuite) TestPreExistingPublished(c *gc.C) { addMeta(c, s.branch, "") // Pretend the store has seen the digest before, and it has succeeded. digest, err := s.branch.RevisionId() c.Assert(err, gc.IsNil) body := `{"cs:precise/wordpress": {"kind": "published", "digest": %q, "revision": 42}}` testing.Server.Response(200, nil, []byte(fmt.Sprintf(body, digest))) ctx, err := s.runPublish(c, "cs:precise/wordpress") c.Assert(err, gc.IsNil) c.Assert(testing.Stdout(ctx), gc.Equals, "cs:precise/wordpress-42\n") req := testing.Server.WaitRequest() c.Assert(req.URL.Path, gc.Equals, "/charm-event") c.Assert(req.Form.Get("charms"), gc.Equals, "cs:precise/wordpress@"+digest) }
func (s *mainSuite) TestRunAsRootCallsSudoIfNotRoot(c *gc.C) { s.PatchValue(local.CheckIfRoot, func() bool { return false }) testing.PatchExecutableAsEchoArgs(c, s, "sudo") // the command needs to be in the path... testing.PatchExecutableAsEchoArgs(c, s, "juju-magic") magicPath, err := exec.LookPath("juju-magic") c.Assert(err, gc.IsNil) callIgnored := func(*cmd.Context) error { panic("unreachable") } args := []string{"passed"} context := coretesting.Context(c) err = local.RunAsRoot("juju-magic", args, context, callIgnored) c.Assert(err, gc.IsNil) expected := fmt.Sprintf("sudo \"--preserve-env\" %q \"passed\"\n", magicPath) c.Assert(coretesting.Stdout(context), gc.Equals, expected) }
func (*mainSuite) TestRegisteredCommands(c *gc.C) { expectedSubcommands := []string{ "help", // TODO: add some as they get registered } plugin := local.JujuLocalPlugin() ctx, err := coretesting.RunCommand(c, plugin, "help", "commands") c.Assert(err, gc.IsNil) lines := strings.Split(coretesting.Stdout(ctx), "\n") var names []string for _, line := range lines { f := strings.Fields(line) if len(f) == 0 { continue } names = append(names, f[0]) } // The names should be output in alphabetical order, so don't sort. c.Assert(names, gc.DeepEquals, expectedSubcommands) }