github.com/juju/juju@v0.0.0-20240430160146-1752b71fcf00/worker/uniter/runner/jujuc/state-set_test.go (about)

     1  // Copyright 2020 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package jujuc_test
     5  
     6  import (
     7  	"bytes"
     8  
     9  	"github.com/juju/cmd/v3"
    10  	"github.com/juju/cmd/v3/cmdtesting"
    11  	jc "github.com/juju/testing/checkers"
    12  	gc "gopkg.in/check.v1"
    13  
    14  	"github.com/juju/juju/worker/uniter/runner/jujuc"
    15  )
    16  
    17  type stateSetSuite struct {
    18  	stateSuite
    19  }
    20  
    21  var _ = gc.Suite(&stateSetSuite{})
    22  
    23  func (s *stateSetSuite) TestHelp(c *gc.C) {
    24  	toolCmd, err := jujuc.NewCommand(nil, "state-set")
    25  	c.Assert(err, jc.ErrorIsNil)
    26  
    27  	ctx := cmdtesting.Context(c)
    28  	code := cmd.Main(jujuc.NewJujucCommandWrappedForTest(toolCmd), ctx, []string{"--help"})
    29  	c.Check(code, gc.Equals, 0)
    30  	c.Assert(bufferString(ctx.Stderr), gc.Equals, "")
    31  
    32  	var expectedHelp = `
    33  Usage: state-set [options] key=value [key=value ...]
    34  
    35  Summary:
    36  set server-side-state values
    37  
    38  Options:
    39  --file  (= )
    40      file containing key-value pairs
    41  
    42  Details:
    43  state-set sets the value of the server side state specified by key.
    44  
    45  The --file option should be used when one or more key-value pairs
    46  are too long to fit within the command length limit of the shell
    47  or operating system. The file will contain a YAML map containing
    48  the settings as strings.  Settings in the file will be overridden
    49  by any duplicate key-value arguments. A value of "-" for the filename
    50  means <stdin>.
    51  
    52  The following fixed size limits apply:
    53  - Length of stored keys cannot exceed 256 bytes.
    54  - Length of stored values cannot exceed 65536 bytes.
    55  
    56  See also:
    57      state-delete
    58      state-get
    59  `[1:]
    60  
    61  	c.Assert(bufferString(ctx.Stdout), gc.Equals, expectedHelp)
    62  }
    63  
    64  type runStateSetCmd struct {
    65  	description string
    66  	args        []string
    67  	content     string
    68  	code        int
    69  	err         string
    70  	expect      func()
    71  }
    72  
    73  func (s *stateSetSuite) TestStateSet(c *gc.C) {
    74  	runStateSetCmdTests := []runStateSetCmd{
    75  		{
    76  			description: "no input",
    77  			args:        nil,
    78  		},
    79  		{
    80  			description: "set 1 values",
    81  			args:        []string{"one=two"},
    82  			expect:      s.expectStateSetOne,
    83  		},
    84  		{
    85  			description: "set 2 values",
    86  			args:        []string{"one=two", "three=four"},
    87  			expect:      s.expectStateSetTwo,
    88  		},
    89  		{
    90  			description: "key value pairs from file, yaml",
    91  			args:        []string{"--file", "-"},
    92  			content:     "{one: two, three: four}",
    93  			expect:      s.expectStateSetTwo,
    94  		},
    95  		{
    96  			description: "key value pairs from file, not yaml",
    97  			args:        []string{"--file", "-"},
    98  			content:     "one = two",
    99  			code:        1,
   100  			err:         "ERROR yaml: unmarshal errors:\n  line 1: cannot unmarshal !!str `one = two` into map[string]string\n",
   101  		},
   102  		{
   103  			description: "single work, not equal sign",
   104  			args:        []string{"five"},
   105  			code:        2,
   106  			err:         "ERROR expected \"key=value\", got \"five\"\n",
   107  		},
   108  		{
   109  			description: "set key with empty value",
   110  			args:        []string{"one="},
   111  			expect:      s.expectStateSetOneEmpty,
   112  		},
   113  	}
   114  	for i, test := range runStateSetCmdTests {
   115  		c.Logf("test %d of %d: %s", i+1, len(runStateSetCmdTests), test.description)
   116  		defer s.setupMocks(c).Finish()
   117  		if test.expect != nil {
   118  			test.expect()
   119  		}
   120  
   121  		toolCmd, err := jujuc.NewCommand(s.mockContext, "state-set")
   122  		c.Assert(err, jc.ErrorIsNil)
   123  
   124  		ctx := cmdtesting.Context(c)
   125  		if test.content != "" {
   126  			ctx.Stdin = bytes.NewBufferString(test.content)
   127  		}
   128  		code := cmd.Main(jujuc.NewJujucCommandWrappedForTest(toolCmd), ctx, test.args)
   129  		c.Check(code, gc.Equals, test.code)
   130  		c.Assert(bufferString(ctx.Stderr), gc.Equals, test.err)
   131  		c.Assert(bufferString(ctx.Stdout), gc.Equals, "")
   132  	}
   133  }
   134  
   135  func (s *stateSetSuite) TestStateSetExistingEmpty(c *gc.C) {
   136  	defer s.setupMocks(c).Finish()
   137  	s.expectStateSetOne()
   138  	s.expectStateSetOneEmpty()
   139  
   140  	toolCmd, err := jujuc.NewCommand(s.mockContext, "state-set")
   141  	c.Assert(err, jc.ErrorIsNil)
   142  
   143  	ctx := cmdtesting.Context(c)
   144  
   145  	for _, arg := range []string{"one=two", "one="} {
   146  		code := cmd.Main(jujuc.NewJujucCommandWrappedForTest(toolCmd), ctx, []string{arg})
   147  		c.Check(code, gc.Equals, 0)
   148  		c.Assert(bufferString(ctx.Stderr), gc.Equals, "")
   149  		c.Assert(bufferString(ctx.Stdout), gc.Equals, "")
   150  	}
   151  }