func (c *HelpToolCommand) Run(ctx *cmd.Context) error { var hookctx dummyHookContext if c.tool == "" { // Ripped from SuperCommand. We could Run() a SuperCommand // with "help commands", but then the implicit "help" command // shows up. names := jujuc.CommandNames() cmds := make([]cmd.Command, 0, len(names)) longest := 0 for _, name := range names { if c, err := jujuc.NewCommand(hookctx, name); err == nil { if len(name) > longest { longest = len(name) } cmds = append(cmds, c) } } for _, c := range cmds { info := c.Info() fmt.Fprintf(ctx.Stdout, "%-*s %s\n", longest, info.Name, info.Purpose) } } else { c, err := jujuc.NewCommand(hookctx, c.tool) if err != nil { return err } info := c.Info() f := gnuflag.NewFlagSet(info.Name, gnuflag.ContinueOnError) c.SetFlags(f) ctx.Stdout.Write(info.Help(f)) } return nil }
func (s *JujuLogSuite) TestLogLevel(c *C) { ctx := &Context{} com, err := jujuc.NewCommand(ctx, "juju-log") c.Assert(err, IsNil) // missing log level argument err = com.Init(dummyFlagSet(), []string{"-l"}) c.Assert(err, ErrorMatches, "flag needs an argument.*") com, err = jujuc.NewCommand(ctx, "juju-log") c.Assert(err, IsNil) // valid log level err = com.Init(dummyFlagSet(), []string{"-l", "FATAL"}) c.Assert(err, ErrorMatches, "no message specified") }
func (s *RelationIdsSuite) TestHelp(c *C) { template := ` usage: %s purpose: list all relation ids with the given relation name options: --format (= smart) specify output format (json|smart|yaml) -o, --output (= "") specify an output file %s`[1:] for relid, t := range map[int]struct { usage, doc string }{ -1: {"relation-ids [options] <name>", ""}, 0: {"relation-ids [options] [<name>]", "\nCurrent default relation name is \"x\".\n"}, 3: {"relation-ids [options] [<name>]", "\nCurrent default relation name is \"y\".\n"}, } { c.Logf("relid %d", relid) hctx := s.GetHookContext(c, relid, "") com, err := jujuc.NewCommand(hctx, "relation-ids") c.Assert(err, IsNil) ctx := testing.Context(c) code := cmd.Main(com, ctx, []string{"--help"}) c.Assert(code, Equals, 0) expect := fmt.Sprintf(template, t.usage, t.doc) c.Assert(bufferString(ctx.Stdout), Equals, expect) c.Assert(bufferString(ctx.Stderr), Equals, "") } }
func (s *ConfigGetSuite) TestUnknownArg(c *C) { hctx := s.GetHookContext(c, -1, "") com, err := jujuc.NewCommand(hctx, "config-get") c.Assert(err, IsNil) err = com.Init(dummyFlagSet(), []string{"multiple", "keys"}) c.Assert(err, ErrorMatches, `unrecognized args: \["keys"\]`) }
func (s *RelationListSuite) TestRelationList(c *C) { for i, t := range relationListTests { c.Logf("test %d: %s", i, t.summary) hctx := s.GetHookContext(c, t.relid, "") setMembers(hctx.rels[0], t.members0) setMembers(hctx.rels[1], t.members1) com, err := jujuc.NewCommand(hctx, "relation-list") c.Assert(err, IsNil) ctx := dummyContext(c) code := cmd.Main(com, ctx, t.args) c.Logf(bufferString(ctx.Stderr)) c.Assert(code, Equals, t.code) if code == 0 { c.Assert(bufferString(ctx.Stderr), Equals, "") expect := t.out if expect != "" { expect = expect + "\n" } c.Assert(bufferString(ctx.Stdout), Equals, expect) } else { c.Assert(bufferString(ctx.Stdout), Equals, "") expect := fmt.Sprintf(`(.|\n)*error: %s\n`, t.out) c.Assert(bufferString(ctx.Stderr), Matches, expect) } } }
func (s *UnitGetSuite) TestUnknownArg(c *C) { hctx := s.GetHookContext(c, -1, "") com, err := jujuc.NewCommand(hctx, "unit-get") c.Assert(err, IsNil) err = com.Init(dummyFlagSet(), []string{"private-address", "blah"}) c.Assert(err, ErrorMatches, `unrecognized args: \["blah"\]`) }
func (s *UnitGetSuite) TestUnknownSetting(c *C) { hctx := s.GetHookContext(c, -1, "") com, err := jujuc.NewCommand(hctx, "unit-get") c.Assert(err, IsNil) err = com.Init(dummyFlagSet(), []string{"protected-address"}) c.Assert(err, ErrorMatches, `unknown setting "protected-address"`) }
func (s *RelationListSuite) TestRelationListHelp(c *C) { template := ` usage: relation-list [options] %s purpose: list relation units options: --format (= smart) specify output format (json|smart|yaml) -o, --output (= "") specify an output file %s`[1:] for relid, t := range map[int]struct { usage, doc string }{ -1: {"<id>", ""}, 0: {"[<id>]", "\nCurrent default relation id is \"peer0:0\".\n"}, } { c.Logf("test relid %d", relid) hctx := s.GetHookContext(c, relid, "") com, err := jujuc.NewCommand(hctx, "relation-list") c.Assert(err, IsNil) ctx := dummyContext(c) code := cmd.Main(com, ctx, []string{"--help"}) c.Assert(code, Equals, 0) c.Assert(bufferString(ctx.Stdout), Equals, "") expect := fmt.Sprintf(template, t.usage, t.doc) c.Assert(bufferString(ctx.Stderr), Equals, expect) } }
func (s *RelationSetSuite) TestRun(c *C) { hctx := s.GetHookContext(c, 0, "") for i, t := range relationSetRunTests { c.Logf("test %d", i) pristine := Settings{"pristine": "untouched"} hctx.rels[0].units["u/0"] = pristine basic := Settings{"base": "value"} hctx.rels[1].units["u/0"] = basic // Run the command. com, err := jujuc.NewCommand(hctx, "relation-set") c.Assert(err, IsNil) rset := com.(*jujuc.RelationSetCommand) rset.RelationId = 1 rset.Settings = t.change ctx := dummyContext(c) err = com.Run(ctx) c.Assert(err, IsNil) // Check changes. c.Assert(hctx.rels[0].units["u/0"], DeepEquals, pristine) c.Assert(hctx.rels[1].units["u/0"], DeepEquals, t.expect) } }
func (s *RelationListSuite) TestRelationListHelp(c *C) { template := ` usage: relation-list [options] purpose: list relation units options: --format (= smart) specify output format (json|smart|yaml) -o, --output (= "") specify an output file -r (= %s) specify a relation by id %s`[1:] for relid, t := range map[int]struct { usage, doc string }{ -1: {"", "\n-r must be specified when not in a relation hook\n"}, 0: {"peer0:0", ""}, } { c.Logf("test relid %d", relid) hctx := s.GetHookContext(c, relid, "") com, err := jujuc.NewCommand(hctx, "relation-list") c.Assert(err, IsNil) ctx := testing.Context(c) code := cmd.Main(com, ctx, []string{"--help"}) c.Assert(code, Equals, 0) expect := fmt.Sprintf(template, t.usage, t.doc) c.Assert(bufferString(ctx.Stdout), Equals, expect) c.Assert(bufferString(ctx.Stderr), Equals, "") } }
func assertLogs(c *C, ctx jujuc.Context, badge string) { loggo.ConfigureLoggers("juju=DEBUG") writer := &loggo.TestWriter{} old_writer, err := loggo.ReplaceDefaultWriter(writer) c.Assert(err, IsNil) defer loggo.ReplaceDefaultWriter(old_writer) msg1 := "the chickens" msg2 := "are 110% AWESOME" com, err := jujuc.NewCommand(ctx, "juju-log") c.Assert(err, IsNil) for _, t := range commonLogTests { writer.Clear() c.Assert(err, IsNil) var args []string if t.debugFlag { args = []string{"--debug", msg1, msg2} } else { args = []string{msg1, msg2} } code := cmd.Main(com, &cmd.Context{}, args) c.Assert(code, Equals, 0) c.Assert(writer.Log, HasLen, 1) c.Assert(writer.Log[0].Level, Equals, t.level) c.Assert(writer.Log[0].Message, Equals, fmt.Sprintf("%s: %s %s", badge, msg1, msg2)) } }
func (s *JujuLogSuite) TestRequiresMessage(c *C) { ctx := &Context{} com, err := jujuc.NewCommand(ctx, "juju-log") c.Assert(err, IsNil) err = com.Init(dummyFlagSet(), nil) c.Assert(err, ErrorMatches, "no message specified") }
func assertLogs(c *C, ctx jujuc.Context, badge string) { msg1 := "the chickens" msg2 := "are 110% AWESOME" com, err := jujuc.NewCommand(ctx, "juju-log") c.Assert(err, IsNil) for _, t := range commonLogTests { buf, pop := pushLog(t.debugEnabled) defer pop() var args []string if t.debugFlag { args = []string{"--debug", msg1, msg2} } else { args = []string{msg1, msg2} } code := cmd.Main(com, &cmd.Context{}, args) c.Assert(code, Equals, 0) if t.target == "" { c.Assert(buf.String(), Equals, "") } else { expect := fmt.Sprintf("%s %s: %s %s\n", t.target, badge, msg1, msg2) c.Assert(buf.String(), Equals, expect) } } }
// runHook executes the supplied hook.Info in an appropriate hook context. If // the hook itself fails to execute, it returns errHookFailed. func (u *Uniter) runHook(hi hook.Info) (err error) { // Prepare context. if err = hi.Validate(); err != nil { return err } hookName := string(hi.Kind) relationId := -1 if hi.Kind.IsRelation() { relationId = hi.RelationId if hookName, err = u.relationers[relationId].PrepareHook(hi); err != nil { return err } } hctxId := fmt.Sprintf("%s:%s:%d", u.unit.Name(), hookName, u.rand.Int63()) hctx := &HookContext{ service: u.service, unit: u.unit, id: hctxId, relationId: relationId, remoteUnitName: hi.RemoteUnit, relations: map[int]*ContextRelation{}, } for id, r := range u.relationers { hctx.relations[id] = r.Context() } // Prepare server. getCmd := func(ctxId, cmdName string) (cmd.Command, error) { // TODO: switch to long-running server with single context; // use nonce in place of context id. if ctxId != hctxId { return nil, fmt.Errorf("expected context id %q, got %q", hctxId, ctxId) } return jujuc.NewCommand(hctx, cmdName) } socketPath := filepath.Join(u.baseDir, "agent.socket") srv, err := jujuc.NewServer(getCmd, socketPath) if err != nil { return err } go srv.Run() defer srv.Close() // Run the hook. if err := u.writeState(RunHook, Pending, &hi, nil); err != nil { return err } log.Printf("worker/uniter: running %q hook", hookName) if err := hctx.RunHook(hookName, u.charm.Path(), u.toolsDir, socketPath); err != nil { log.Printf("worker/uniter: hook failed: %s", err) return errHookFailed } if err := u.writeState(RunHook, Done, &hi, nil); err != nil { return err } log.Printf("worker/uniter: ran %q hook", hookName) return u.commitHook(hi) }
func (s *PortsSuite) TestHelp(c *C) { hctx := s.GetHookContext(c, -1, "") open, err := jujuc.NewCommand(hctx, "open-port") c.Assert(err, IsNil) c.Assert(string(open.Info().Help(dummyFlagSet())), Equals, ` usage: open-port <port>[/<protocol>] purpose: register a port to open The port will only be open while the service is exposed. `[1:]) close, err := jujuc.NewCommand(hctx, "close-port") c.Assert(err, IsNil) c.Assert(string(close.Info().Help(dummyFlagSet())), Equals, ` usage: close-port <port>[/<protocol>] purpose: ensure a port is always closed `[1:]) }
func (s *ConfigGetSuite) TestAllPlusKey(c *C) { hctx := s.GetHookContext(c, -1, "") com, err := jujuc.NewCommand(hctx, "config-get") c.Assert(err, IsNil) ctx := testing.Context(c) code := cmd.Main(com, ctx, []string{"--all", "--format", "json", "monsters"}) c.Assert(code, Equals, 2) c.Assert(bufferString(ctx.Stderr), Equals, "error: cannot use argument --all together with key \"monsters\"\n") }
func (s *RelationSetSuite) TestRunDeprecationWarning(c *C) { hctx := s.GetHookContext(c, 0, "") com, _ := jujuc.NewCommand(hctx, "relation-set") // The rel= is needed to make this a valid command. ctx, err := testing.RunCommand(c, com, []string{"--format", "foo", "rel="}) c.Assert(err, IsNil) c.Assert(testing.Stdout(ctx), Equals, "") c.Assert(testing.Stderr(ctx), Equals, "--format flag deprecated for command \"relation-set\"") }
func (s *PortsSuite) TestBadArgs(c *C) { for _, name := range []string{"open-port", "close-port"} { for _, t := range badPortsTests { hctx := s.GetHookContext(c, -1, "") com, err := jujuc.NewCommand(hctx, name) c.Assert(err, IsNil) err = com.Init(dummyFlagSet(), t.args) c.Assert(err, ErrorMatches, t.err) } } }
func (s *UnitGetSuite) TestOutputFormat(c *C) { for _, t := range unitGetTests { hctx := s.GetHookContext(c, -1, "") com, err := jujuc.NewCommand(hctx, "unit-get") c.Assert(err, IsNil) ctx := dummyContext(c) code := cmd.Main(com, ctx, t.args) c.Assert(code, Equals, 0) c.Assert(bufferString(ctx.Stderr), Equals, "") c.Assert(bufferString(ctx.Stdout), Matches, t.out) } }
func (s *UnitGetSuite) TestOutputPath(c *C) { hctx := s.GetHookContext(c, -1, "") com, err := jujuc.NewCommand(hctx, "unit-get") c.Assert(err, IsNil) ctx := dummyContext(c) code := cmd.Main(com, ctx, []string{"--output", "some-file", "private-address"}) c.Assert(code, Equals, 0) c.Assert(bufferString(ctx.Stderr), Equals, "") c.Assert(bufferString(ctx.Stdout), Equals, "") content, err := ioutil.ReadFile(filepath.Join(ctx.Dir, "some-file")) c.Assert(err, IsNil) c.Assert(string(content), Equals, "192.168.0.99\n") }
func (s *PortsSuite) TestOpenCloseDeprecation(c *C) { hctx := s.GetHookContext(c, -1, "") for _, t := range portsFormatDeprectaionTests { name := t.cmd[0] com, err := jujuc.NewCommand(hctx, name) c.Assert(err, IsNil) ctx := testing.Context(c) code := cmd.Main(com, ctx, t.cmd[1:]) c.Assert(code, Equals, 0) c.Assert(testing.Stdout(ctx), Equals, "") c.Assert(testing.Stderr(ctx), Equals, "--format flag deprecated for command \""+name+"\"") } }
func (s *ConfigGetSuite) TestOutputPath(c *C) { hctx := s.GetHookContext(c, -1, "") com, err := jujuc.NewCommand(hctx, "config-get") c.Assert(err, IsNil) ctx := dummyContext(c) code := cmd.Main(com, ctx, []string{"--output", "some-file", "monsters"}) c.Assert(code, Equals, 0) c.Assert(bufferString(ctx.Stderr), Equals, "") c.Assert(bufferString(ctx.Stdout), Equals, "") content, err := ioutil.ReadFile(filepath.Join(ctx.Dir, "some-file")) c.Assert(err, IsNil) c.Assert(string(content), Equals, "false\n") }
func (s *ConfigGetSuite) TestOutputFormatKey(c *C) { for i, t := range configGetKeyTests { c.Logf("test %d: %#v", i, t.args) hctx := s.GetHookContext(c, -1, "") com, err := jujuc.NewCommand(hctx, "config-get") c.Assert(err, IsNil) ctx := testing.Context(c) code := cmd.Main(com, ctx, t.args) c.Assert(code, Equals, 0) c.Assert(bufferString(ctx.Stderr), Equals, "") c.Assert(bufferString(ctx.Stdout), Matches, t.out) } }
func (s *PortsSuite) TestOpenClose(c *C) { hctx := s.GetHookContext(c, -1, "") for _, t := range portsTests { com, err := jujuc.NewCommand(hctx, t.cmd[0]) c.Assert(err, IsNil) ctx := dummyContext(c) code := cmd.Main(com, ctx, t.cmd[1:]) c.Assert(code, Equals, 0) c.Assert(bufferString(ctx.Stdout), Equals, "") c.Assert(bufferString(ctx.Stderr), Equals, "") c.Assert(hctx.ports, DeepEquals, t.expect) } }
func (s *RelationGetSuite) TestOutputPath(c *C) { hctx := s.GetHookContext(c, 1, "m/0") com, err := jujuc.NewCommand(hctx, "relation-get") c.Assert(err, IsNil) ctx := testing.Context(c) code := cmd.Main(com, ctx, []string{"--output", "some-file", "pew"}) c.Assert(code, Equals, 0) c.Assert(bufferString(ctx.Stderr), Equals, "") c.Assert(bufferString(ctx.Stdout), Equals, "") content, err := ioutil.ReadFile(filepath.Join(ctx.Dir, "some-file")) c.Assert(err, IsNil) c.Assert(string(content), Equals, "pew\npew\n\n") }
func (s *NewCommandSuite) TestNewCommand(c *C) { ctx := s.GetHookContext(c, 0, "") for _, t := range newCommandTests { com, err := jujuc.NewCommand(ctx, t.name) if t.err == "" { // At this level, just check basic sanity; commands are tested in // more detail elsewhere. c.Assert(err, IsNil) c.Assert(com.Info().Name, Equals, t.name) } else { c.Assert(com, IsNil) c.Assert(err, ErrorMatches, t.err) } } }
func (s *RelationSetSuite) TestInit(c *C) { for i, t := range relationSetInitTests { c.Logf("test %d", i) hctx := s.GetHookContext(c, t.ctxrelid, "") com, err := jujuc.NewCommand(hctx, "relation-set") c.Assert(err, IsNil) err = com.Init(dummyFlagSet(), t.args) if t.err == "" { c.Assert(err, IsNil) rset := com.(*jujuc.RelationSetCommand) c.Assert(rset.RelationId, Equals, t.relid) c.Assert(rset.Settings, DeepEquals, t.settings) } else { c.Assert(err, ErrorMatches, t.err) } } }
func (s *UnitGetSuite) TestHelp(c *C) { hctx := s.GetHookContext(c, -1, "") com, err := jujuc.NewCommand(hctx, "unit-get") c.Assert(err, IsNil) ctx := dummyContext(c) code := cmd.Main(com, ctx, []string{"--help"}) c.Assert(code, Equals, 0) c.Assert(bufferString(ctx.Stdout), Equals, "") c.Assert(bufferString(ctx.Stderr), Equals, `usage: unit-get [options] <setting> purpose: print public-address or private-address options: --format (= smart) specify output format (json|smart|yaml) -o, --output (= "") specify an output file `) }
func (s *RelationGetSuite) TestHelp(c *C) { for i, t := range relationGetHelpTests { c.Logf("test %d", i) hctx := s.GetHookContext(c, t.relid, t.unit) com, err := jujuc.NewCommand(hctx, "relation-get") c.Assert(err, IsNil) ctx := testing.Context(c) code := cmd.Main(com, ctx, []string{"--help"}) c.Assert(code, Equals, 0) unitHelp := "" if t.unit != "" { unitHelp = fmt.Sprintf("Current default unit id is %q.\n", t.unit) } expect := fmt.Sprintf(helpTemplate, t.usage, t.rel, unitHelp) c.Assert(bufferString(ctx.Stdout), Equals, expect) c.Assert(bufferString(ctx.Stderr), Equals, "") } }
func (s *RelationSetSuite) TestHelp(c *C) { for i, t := range helpTests { c.Logf("test %d", i) hctx := s.GetHookContext(c, t.relid, "") com, err := jujuc.NewCommand(hctx, "relation-set") c.Assert(err, IsNil) ctx := dummyContext(c) code := cmd.Main(com, ctx, []string{"--help"}) c.Assert(code, Equals, 0) c.Assert(bufferString(ctx.Stdout), Equals, "") c.Assert(bufferString(ctx.Stderr), Equals, fmt.Sprintf(` usage: relation-set [options] key=value [key=value ...] purpose: set relation settings options: -r (= %s) specify a relation by id `[1:], t.expect)) } }