github.com/cloud-green/juju@v0.0.0-20151002100041-a00291338d3d/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  purpose: set action results
   148  
   149  action-set adds the given values to the results map of the Action.  This map
   150  is returned to the user after the completion of the Action.  Keys must start
   151  and end with lowercase alphanumeric, and contain only lowercase alphanumeric,
   152  hyphens and periods.
   153  
   154  Example usage:
   155   action-set outfile.size=10G
   156   action-set foo.bar=2
   157   action-set foo.baz.val=3
   158   action-set foo.bar.zab=4
   159   action-set foo.baz=1
   160  
   161   will yield:
   162  
   163   outfile:
   164     size: "10G"
   165   foo:
   166     bar:
   167       zab: "4"
   168     baz: "1"
   169  `)
   170  	c.Assert(bufferString(ctx.Stderr), gc.Equals, "")
   171  }