github.com/wallyworld/juju@v0.0.0-20161013125918-6cf1bc9d917a/worker/uniter/runner/jujuc/action-set_test.go (about)

     1  // Copyright 2014 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package jujuc_test
     5  
     6  import (
     7  	"fmt"
     8  
     9  	"github.com/juju/cmd"
    10  	jc "github.com/juju/testing/checkers"
    11  	gc "gopkg.in/check.v1"
    12  
    13  	"github.com/juju/juju/testing"
    14  	"github.com/juju/juju/worker/uniter/runner/jujuc"
    15  )
    16  
    17  var _ = gc.Suite(&ActionSetSuite{})
    18  
    19  type ActionSetSuite struct {
    20  	ContextSuite
    21  }
    22  
    23  type actionSettingContext struct {
    24  	Context
    25  	commands [][]string
    26  }
    27  
    28  func (a *actionSettingContext) UpdateActionResults(keys []string, value string) error {
    29  	if a.commands == nil {
    30  		a.commands = make([][]string, 0)
    31  	}
    32  
    33  	a.commands = append(a.commands, append(keys, value))
    34  	return nil
    35  }
    36  
    37  type nonActionSettingContext struct {
    38  	Context
    39  }
    40  
    41  func (a *nonActionSettingContext) UpdateActionResults(keys []string, value string) error {
    42  	return fmt.Errorf("not running an action")
    43  }
    44  
    45  func (s *ActionSetSuite) TestActionSetOnNonActionContextFails(c *gc.C) {
    46  	hctx := &nonActionSettingContext{}
    47  	com, err := jujuc.NewCommand(hctx, cmdString("action-set"))
    48  	c.Assert(err, jc.ErrorIsNil)
    49  	ctx := testing.Context(c)
    50  	code := cmd.Main(com, ctx, []string{"oops=nope"})
    51  	c.Check(code, gc.Equals, 1)
    52  	c.Check(bufferString(ctx.Stdout), gc.Equals, "")
    53  	expect := fmt.Sprintf(`(\n)*error: %s\n`, "not running an action")
    54  	c.Check(bufferString(ctx.Stderr), gc.Matches, expect)
    55  }
    56  
    57  func (s *ActionSetSuite) TestActionSet(c *gc.C) {
    58  	var actionSetTests = []struct {
    59  		summary  string
    60  		command  []string
    61  		expected [][]string
    62  		errMsg   string
    63  		code     int
    64  	}{{
    65  		summary: "bare value(s) are an Init error",
    66  		command: []string{"result"},
    67  		errMsg:  "error: argument \"result\" must be of the form key...=value\n",
    68  		code:    2,
    69  	}, {
    70  		summary: "invalid keys are an error",
    71  		command: []string{"result-Value=5"},
    72  		errMsg:  "error: key \"result-Value\" must start and end with lowercase alphanumeric, and contain only lowercase alphanumeric, hyphens and periods\n",
    73  		code:    2,
    74  	}, {
    75  		summary: "empty values are not an error",
    76  		command: []string{"result="},
    77  		expected: [][]string{
    78  			{"result", ""},
    79  		},
    80  	}, {
    81  		summary: "a response of one key to one value",
    82  		command: []string{"outfile=foo.bz2"},
    83  		expected: [][]string{
    84  			{"outfile", "foo.bz2"},
    85  		},
    86  	}, {
    87  		summary: "two keys, two values",
    88  		command: []string{"outfile=foo.bz2", "size=10G"},
    89  		expected: [][]string{
    90  			{"outfile", "foo.bz2"},
    91  			{"size", "10G"},
    92  		},
    93  	}, {
    94  		summary: "multiple = are ok",
    95  		command: []string{"outfile=foo=bz2"},
    96  		expected: [][]string{
    97  			{"outfile", "foo=bz2"},
    98  		},
    99  	}, {
   100  		summary: "several interleaved values",
   101  		command: []string{"outfile.name=foo.bz2",
   102  			"outfile.kind.util=bzip2",
   103  			"outfile.kind.ratio=high"},
   104  		expected: [][]string{
   105  			{"outfile", "name", "foo.bz2"},
   106  			{"outfile", "kind", "util", "bzip2"},
   107  			{"outfile", "kind", "ratio", "high"},
   108  		},
   109  	}, {
   110  		summary: "conflicting simple values",
   111  		command: []string{"util=bzip2", "util=5"},
   112  		expected: [][]string{
   113  			{"util", "bzip2"},
   114  			{"util", "5"},
   115  		},
   116  	}, {
   117  		summary: "conflicted map spec: {map1:{key:val}} vs {map1:val2}",
   118  		command: []string{"map1.key=val", "map1=val"},
   119  		expected: [][]string{
   120  			{"map1", "key", "val"},
   121  			{"map1", "val"},
   122  		},
   123  	}}
   124  
   125  	for i, t := range actionSetTests {
   126  		c.Logf("test %d: %s", i, t.summary)
   127  		hctx := &actionSettingContext{}
   128  		com, err := jujuc.NewCommand(hctx, cmdString("action-set"))
   129  		c.Assert(err, jc.ErrorIsNil)
   130  		ctx := testing.Context(c)
   131  		c.Logf("  command list: %#v", t.command)
   132  		code := cmd.Main(com, ctx, t.command)
   133  		c.Check(code, gc.Equals, t.code)
   134  		c.Check(bufferString(ctx.Stderr), gc.Equals, t.errMsg)
   135  		c.Check(hctx.commands, jc.DeepEquals, t.expected)
   136  	}
   137  }
   138  
   139  func (s *ActionSetSuite) TestHelp(c *gc.C) {
   140  	hctx := &actionSettingContext{}
   141  	com, err := jujuc.NewCommand(hctx, cmdString("action-set"))
   142  	c.Assert(err, jc.ErrorIsNil)
   143  	ctx := testing.Context(c)
   144  	code := cmd.Main(com, ctx, []string{"--help"})
   145  	c.Assert(code, gc.Equals, 0)
   146  	c.Assert(bufferString(ctx.Stdout), gc.Equals, `Usage: action-set <key>=<value> [<key>=<value> ...]
   147  
   148  Summary:
   149  set action results
   150  
   151  Details:
   152  action-set adds the given values to the results map of the Action.  This map
   153  is returned to the user after the completion of the Action.  Keys must start
   154  and end with lowercase alphanumeric, and contain only lowercase alphanumeric,
   155  hyphens and periods.
   156  
   157  Example usage:
   158   action-set outfile.size=10G
   159   action-set foo.bar=2
   160   action-set foo.baz.val=3
   161   action-set foo.bar.zab=4
   162   action-set foo.baz=1
   163  
   164   will yield:
   165  
   166   outfile:
   167     size: "10G"
   168   foo:
   169     bar:
   170       zab: "4"
   171     baz: "1"
   172  `)
   173  	c.Assert(bufferString(ctx.Stderr), gc.Equals, "")
   174  }