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 *RelationListSuite) TestRelationListHelp(c *gc.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, gc.IsNil) ctx := testing.Context(c) code := cmd.Main(com, ctx, []string{"--help"}) c.Assert(code, gc.Equals, 0) expect := fmt.Sprintf(template, t.usage, t.doc) c.Assert(bufferString(ctx.Stdout), gc.Equals, expect) c.Assert(bufferString(ctx.Stderr), gc.Equals, "") } }
func (s *RelationSetSuite) TestRun(c *gc.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, gc.IsNil) rset := com.(*jujuc.RelationSetCommand) rset.RelationId = 1 rset.Settings = t.change ctx := testing.Context(c) err = com.Run(ctx) c.Assert(err, gc.IsNil) // Check changes. c.Assert(hctx.rels[0].units["u/0"], gc.DeepEquals, pristine) c.Assert(hctx.rels[1].units["u/0"], gc.DeepEquals, t.expect) } }
func (s *RelationIdsSuite) TestHelp(c *gc.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, gc.IsNil) ctx := testing.Context(c) code := cmd.Main(com, ctx, []string{"--help"}) c.Assert(code, gc.Equals, 0) expect := fmt.Sprintf(template, t.usage, t.doc) c.Assert(bufferString(ctx.Stdout), gc.Equals, expect) c.Assert(bufferString(ctx.Stderr), gc.Equals, "") } }
func (s *RelationListSuite) TestRelationList(c *gc.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, gc.IsNil) ctx := testing.Context(c) code := cmd.Main(com, ctx, t.args) c.Logf(bufferString(ctx.Stderr)) c.Assert(code, gc.Equals, t.code) if code == 0 { c.Assert(bufferString(ctx.Stderr), gc.Equals, "") expect := t.out if expect != "" { expect = expect + "\n" } c.Assert(bufferString(ctx.Stdout), gc.Equals, expect) } else { c.Assert(bufferString(ctx.Stdout), gc.Equals, "") expect := fmt.Sprintf(`(.|\n)*error: %s\n`, t.out) c.Assert(bufferString(ctx.Stderr), gc.Matches, expect) } } }
func (s *ConfigGetSuite) TestAllPlusKey(c *gc.C) { hctx := s.GetHookContext(c, -1, "") com, err := jujuc.NewCommand(hctx, "config-get") c.Assert(err, gc.IsNil) ctx := testing.Context(c) code := cmd.Main(com, ctx, []string{"--all", "--format", "json", "monsters"}) c.Assert(code, gc.Equals, 2) c.Assert(bufferString(ctx.Stderr), gc.Equals, "error: cannot use argument --all together with key \"monsters\"\n") }
func (s *PortsSuite) TestHelp(c *gc.C) { hctx := s.GetHookContext(c, -1, "") open, err := jujuc.NewCommand(hctx, "open-port") c.Assert(err, gc.IsNil) flags := testing.NewFlagSet() c.Assert(string(open.Info().Help(flags)), gc.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, gc.IsNil) c.Assert(string(close.Info().Help(flags)), gc.Equals, ` usage: close-port <port>[/<protocol>] purpose: ensure a port is always closed `[1:]) }
func (s *RelationSetSuite) TestRunDeprecationWarning(c *gc.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, "--format", "foo", "rel=") c.Assert(err, gc.IsNil) c.Assert(testing.Stdout(ctx), gc.Equals, "") c.Assert(testing.Stderr(ctx), gc.Equals, "--format flag deprecated for command \"relation-set\"") }
func (s *PortsSuite) TestBadArgs(c *gc.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, gc.IsNil) err = testing.InitCommand(com, t.args) c.Assert(err, gc.ErrorMatches, t.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 *PortsSuite) TestOpenClose(c *gc.C) { hctx := s.GetHookContext(c, -1, "") for _, t := range portsTests { com, err := jujuc.NewCommand(hctx, t.cmd[0]) 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(bufferString(ctx.Stdout), gc.Equals, "") c.Assert(bufferString(ctx.Stderr), gc.Equals, "") c.Assert(hctx.ports, gc.DeepEquals, t.expect) } }
func (s *ConfigGetSuite) TestOutputPath(c *gc.C) { hctx := s.GetHookContext(c, -1, "") com, err := jujuc.NewCommand(hctx, "config-get") c.Assert(err, gc.IsNil) ctx := testing.Context(c) code := cmd.Main(com, ctx, []string{"--output", "some-file", "monsters"}) c.Assert(code, gc.Equals, 0) c.Assert(bufferString(ctx.Stderr), gc.Equals, "") c.Assert(bufferString(ctx.Stdout), gc.Equals, "") content, err := ioutil.ReadFile(filepath.Join(ctx.Dir, "some-file")) c.Assert(err, gc.IsNil) c.Assert(string(content), gc.Equals, "False\n") }
func (s *ConfigGetSuite) TestOutputFormatKey(c *gc.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, gc.IsNil) ctx := testing.Context(c) code := cmd.Main(com, ctx, t.args) c.Assert(code, gc.Equals, 0) c.Assert(bufferString(ctx.Stderr), gc.Equals, "") c.Assert(bufferString(ctx.Stdout), gc.Matches, t.out) } }
func (s *NewCommandSuite) TestNewCommand(c *gc.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, gc.IsNil) c.Assert(com.Info().Name, gc.Equals, t.name) } else { c.Assert(com, gc.IsNil) c.Assert(err, gc.ErrorMatches, t.err) } } }
func (s *RelationGetSuite) TestHelp(c *gc.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, gc.IsNil) ctx := testing.Context(c) code := cmd.Main(com, ctx, []string{"--help"}) c.Assert(code, gc.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), gc.Equals, expect) c.Assert(bufferString(ctx.Stderr), gc.Equals, "") } }
func (u *Uniter) startJujucServer(context *HookContext) (*jujuc.Server, string, error) { // 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 != context.id { return nil, fmt.Errorf("expected context id %q, got %q", context.id, ctxId) } return jujuc.NewCommand(context, cmdName) } socketPath := u.sockPath("agent.socket", "@") srv, err := jujuc.NewServer(getCmd, socketPath) if err != nil { return nil, "", err } go srv.Run() return srv, socketPath, nil }
func (u *Uniter) startJujucServer(context *HookContext) (*jujuc.Server, string, error) { // 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 != context.id { return nil, fmt.Errorf("expected context id %q, got %q", context.id, ctxId) } return jujuc.NewCommand(context, cmdName) } socketPath := filepath.Join(u.baseDir, "agent.socket") // Use abstract namespace so we don't get stale socket files. socketPath = "@" + socketPath srv, err := jujuc.NewServer(getCmd, socketPath) if err != nil { return nil, "", err } go srv.Run() return srv, socketPath, nil }
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, "juju-log") c.Assert(err, gc.IsNil) 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, gc.IsNil) 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)) } }
func (s *ConfigGetSuite) TestOutputFormatAll(c *gc.C) { for i, t := range configGetAllTests { c.Logf("test %d: %#v", i, t.args) hctx := s.GetHookContext(c, -1, "") com, err := jujuc.NewCommand(hctx, "config-get") c.Assert(err, gc.IsNil) ctx := testing.Context(c) code := cmd.Main(com, ctx, t.args) c.Assert(code, gc.Equals, 0) c.Assert(bufferString(ctx.Stderr), gc.Equals, "") out := map[string]interface{}{} switch t.format { case formatYaml: c.Assert(goyaml.Unmarshal(bufferBytes(ctx.Stdout), &out), gc.IsNil) case formatJson: c.Assert(json.Unmarshal(bufferBytes(ctx.Stdout), &out), gc.IsNil) } c.Assert(out, gc.DeepEquals, t.out) } }
func (s *RelationSetSuite) TestInit(c *gc.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, gc.IsNil) err = testing.InitCommand(com, t.args) if t.err == "" { c.Assert(err, gc.IsNil) rset := com.(*jujuc.RelationSetCommand) c.Assert(rset.RelationId, gc.Equals, t.relid) settings := t.settings if settings == nil { settings = map[string]string{} } c.Assert(rset.Settings, gc.DeepEquals, settings) } else { c.Assert(err, gc.ErrorMatches, t.err) } } }
func (s *RelationIdsSuite) TestRelationIds(c *gc.C) { for i, t := range relationIdsTests { c.Logf("test %d: %s", i, t.summary) hctx := s.GetHookContext(c, t.relid, "") com, err := jujuc.NewCommand(hctx, "relation-ids") c.Assert(err, gc.IsNil) ctx := testing.Context(c) code := cmd.Main(com, ctx, t.args) c.Assert(code, gc.Equals, t.code) if code == 0 { c.Assert(bufferString(ctx.Stderr), gc.Equals, "") expect := t.out if expect != "" { expect += "\n" } c.Assert(bufferString(ctx.Stdout), gc.Equals, expect) } else { c.Assert(bufferString(ctx.Stdout), gc.Equals, "") c.Assert(bufferString(ctx.Stderr), gc.Matches, t.out) } } }
func (s *RelationSetSuite) TestHelp(c *gc.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, gc.IsNil) ctx := testing.Context(c) code := cmd.Main(com, ctx, []string{"--help"}) c.Assert(code, gc.Equals, 0) c.Assert(bufferString(ctx.Stdout), gc.Equals, fmt.Sprintf(` usage: relation-set [options] key=value [key=value ...] purpose: set relation settings options: --format (= "") deprecated format flag -r (= %s) specify a relation by id `[1:], t.expect)) c.Assert(bufferString(ctx.Stderr), gc.Equals, "") } }
func (s *ActionGetSuite) TestHelp(c *gc.C) { hctx := s.GetHookContext(c, -1, "") com, err := jujuc.NewCommand(hctx, "action-get") c.Assert(err, gc.IsNil) ctx := testing.Context(c) code := cmd.Main(com, ctx, []string{"--help"}) c.Assert(code, gc.Equals, 0) c.Assert(bufferString(ctx.Stdout), gc.Equals, `usage: action-get [options] [<key>[.<key>.<key>...]] purpose: get action parameters options: --format (= smart) specify output format (json|smart|yaml) -o, --output (= "") specify an output file action-get will print the value of the parameter at the given key, serialized as YAML. If multiple keys are passed, action-get will recurse into the param map as needed. `) c.Assert(bufferString(ctx.Stderr), gc.Equals, "") }
func (s *ConfigGetSuite) TestHelp(c *gc.C) { hctx := s.GetHookContext(c, -1, "") com, err := jujuc.NewCommand(hctx, "config-get") c.Assert(err, gc.IsNil) ctx := testing.Context(c) code := cmd.Main(com, ctx, []string{"--help"}) c.Assert(code, gc.Equals, 0) c.Assert(bufferString(ctx.Stdout), gc.Equals, `usage: config-get [options] [<key>] purpose: print service configuration options: -a, --all (= false) print all keys --format (= smart) specify output format (json|smart|yaml) -o, --output (= "") specify an output file When no <key> is supplied, all keys with values or defaults are printed. If --all is set, all known keys are printed; those without defaults or values are reported as null. <key> and --all are mutually exclusive. `) c.Assert(bufferString(ctx.Stderr), gc.Equals, "") }
func newJujuLogCommand(c *gc.C) cmd.Command { ctx := &Context{} com, err := jujuc.NewCommand(ctx, "juju-log") c.Assert(err, gc.IsNil) return com }
func (s *UnitGetSuite) createCommand(c *gc.C) cmd.Command { hctx := s.GetHookContext(c, -1, "") com, err := jujuc.NewCommand(hctx, "unit-get") c.Assert(err, gc.IsNil) return com }
func (s *ActionGetSuite) TestActionGet(c *gc.C) { var actionGetTestMaps = []map[string]interface{}{ map[string]interface{}{ "outfile": "foo.bz2", }, map[string]interface{}{ "outfile": map[string]interface{}{ "filename": "foo.bz2", "format": "bzip", }, }, map[string]interface{}{ "outfile": map[string]interface{}{ "type": map[string]interface{}{ "1": "raw", "2": "gzip", "3": "bzip", }, }, }, // A map with a non-string key is not usable. map[string]interface{}{ "outfile": map[interface{}]interface{}{ 5: map[string]interface{}{ "1": "raw", "2": "gzip", "3": "bzip", }, }, }, // A map with an inner map[interface{}]interface{} is OK if // the keys are strings. map[string]interface{}{ "outfile": map[interface{}]interface{}{ "type": map[string]interface{}{ "1": "raw", "2": "gzip", "3": "bzip", }, }, }, } var actionGetTests = []struct { summary string args []string actionParams map[string]interface{} code int out string errMsg string }{{ summary: "a simple empty map with nil key", args: []string{}, out: "{}\n", }, { summary: "a simple empty map with nil key", args: []string{"--format", "yaml"}, out: "{}\n", }, { summary: "a simple empty map with nil key", args: []string{"--format", "json"}, out: "null\n", }, { summary: "a nonexistent key", args: []string{"foo"}, }, { summary: "a nonexistent key", args: []string{"--format", "yaml", "foo"}, }, { summary: "a nonexistent key", args: []string{"--format", "json", "foo"}, out: "null\n", }, { summary: "a nonexistent inner key", args: []string{"outfile.type"}, actionParams: actionGetTestMaps[1], }, { summary: "a nonexistent inner key", args: []string{"--format", "yaml", "outfile.type"}, actionParams: actionGetTestMaps[1], }, { summary: "a nonexistent inner key", args: []string{"--format", "json", "outfile.type"}, actionParams: actionGetTestMaps[1], out: "null\n", }, { summary: "a nonexistent inner key", args: []string{"outfile.type.1"}, actionParams: actionGetTestMaps[1], }, { summary: "a nonexistent inner key", args: []string{"--format", "yaml", "outfile.type.1"}, actionParams: actionGetTestMaps[1], }, { summary: "a nonexistent inner key", args: []string{"--format", "json", "outfile.type.1"}, actionParams: actionGetTestMaps[1], out: "null\n", }, { summary: "a map with a non-string key", args: []string{"outfile.type"}, actionParams: actionGetTestMaps[3], }, { summary: "a map with a non-string key", args: []string{"--format", "yaml", "outfile.type"}, actionParams: actionGetTestMaps[3], }, { summary: "a map with a non-string key", args: []string{"--format", "json", "outfile.type"}, actionParams: actionGetTestMaps[3], out: "null\n", }, { summary: "a simple map of one value to one key", args: []string{}, actionParams: actionGetTestMaps[0], out: "outfile: foo.bz2\n", }, { summary: "a simple map of one value to one key", args: []string{"--format", "yaml"}, actionParams: actionGetTestMaps[0], out: "outfile: foo.bz2\n", }, { summary: "a simple map of one value to one key", args: []string{"--format", "json"}, actionParams: actionGetTestMaps[0], out: "{\"outfile\":\"foo.bz2\"}\n", }, { summary: "an entire map", args: []string{}, actionParams: actionGetTestMaps[2], out: "outfile:\n" + " type:\n" + " \"1\": raw\n" + " \"2\": gzip\n" + " \"3\": bzip\n", }, { summary: "an entire map", args: []string{"--format", "yaml"}, actionParams: actionGetTestMaps[2], out: "outfile:\n" + " type:\n" + " \"1\": raw\n" + " \"2\": gzip\n" + " \"3\": bzip\n", }, { summary: "an entire map", args: []string{"--format", "json"}, actionParams: actionGetTestMaps[2], out: `{"outfile":{"type":{"1":"raw","2":"gzip","3":"bzip"}}}` + "\n", }, { summary: "an inner map value which is itself a map", args: []string{"outfile.type"}, actionParams: actionGetTestMaps[2], out: "\"1\": raw\n" + "\"2\": gzip\n" + "\"3\": bzip\n", }, { summary: "an inner map value which is itself a map", args: []string{"--format", "yaml", "outfile.type"}, actionParams: actionGetTestMaps[2], out: "\"1\": raw\n" + "\"2\": gzip\n" + "\"3\": bzip\n", }, { summary: "an inner map value which is itself a map", args: []string{"--format", "json", "outfile.type"}, actionParams: actionGetTestMaps[2], out: `{"1":"raw","2":"gzip","3":"bzip"}` + "\n", }, { summary: "a map with an inner map keyed by interface{}", args: []string{"outfile.type"}, actionParams: actionGetTestMaps[4], out: "\"1\": raw\n" + "\"2\": gzip\n" + "\"3\": bzip\n", }, { summary: "a map with an inner map keyed by interface{}", args: []string{"--format", "yaml", "outfile.type"}, actionParams: actionGetTestMaps[4], out: "\"1\": raw\n" + "\"2\": gzip\n" + "\"3\": bzip\n", }, { summary: "a map with an inner map keyed by interface{}", args: []string{"--format", "json", "outfile.type"}, actionParams: actionGetTestMaps[4], out: `{"1":"raw","2":"gzip","3":"bzip"}` + "\n", }, { summary: "too many arguments", args: []string{"multiple", "keys"}, code: 2, errMsg: `unrecognized args: \["keys"\]`, }} for i, t := range actionGetTests { c.Logf("test %d: %s\n args: %#v", i, t.summary, t.args) hctx := s.GetHookContext(c, -1, "") hctx.actionParams = t.actionParams com, err := jujuc.NewCommand(hctx, "action-get") c.Assert(err, gc.IsNil) ctx := testing.Context(c) code := cmd.Main(com, ctx, t.args) c.Check(code, gc.Equals, t.code) if code == 0 { c.Check(bufferString(ctx.Stderr), gc.Equals, "") c.Check(bufferString(ctx.Stdout), gc.Equals, t.out) } else { c.Check(bufferString(ctx.Stdout), gc.Equals, "") expect := fmt.Sprintf(`(.|\n)*error: %s\n`, t.errMsg) c.Check(bufferString(ctx.Stderr), gc.Matches, expect) } } }
func (s *ConfigGetSuite) TestUnknownArg(c *gc.C) { hctx := s.GetHookContext(c, -1, "") com, err := jujuc.NewCommand(hctx, "config-get") c.Assert(err, gc.IsNil) testing.TestInit(c, com, []string{"multiple", "keys"}, `unrecognized args: \["keys"\]`) }