github.com/altoros/juju-vmware@v0.0.0-20150312064031-f19ae857ccca/cmd/juju/set_test.go (about)

     1  // Copyright 2012, 2013 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package main
     5  
     6  import (
     7  	"bytes"
     8  	"io/ioutil"
     9  	"os"
    10  	"strings"
    11  	"unicode/utf8"
    12  
    13  	"github.com/juju/cmd"
    14  	jc "github.com/juju/testing/checkers"
    15  	"github.com/juju/utils"
    16  	gc "gopkg.in/check.v1"
    17  	"gopkg.in/juju/charm.v4"
    18  
    19  	"github.com/juju/juju/cmd/envcmd"
    20  	"github.com/juju/juju/juju/testing"
    21  	"github.com/juju/juju/state"
    22  	coretesting "github.com/juju/juju/testing"
    23  )
    24  
    25  type SetSuite struct {
    26  	testing.JujuConnSuite
    27  	svc *state.Service
    28  	dir string
    29  }
    30  
    31  var _ = gc.Suite(&SetSuite{})
    32  
    33  var (
    34  	validSetTestValue   = "a value with spaces\nand newline\nand UTF-8 characters: \U0001F604 / \U0001F44D"
    35  	invalidSetTestValue = "a value with an invalid UTF-8 sequence: " + string([]byte{0xFF, 0xFF})
    36  )
    37  
    38  func (s *SetSuite) SetUpTest(c *gc.C) {
    39  	s.JujuConnSuite.SetUpTest(c)
    40  	ch := s.AddTestingCharm(c, "dummy")
    41  	svc := s.AddTestingService(c, "dummy-service", ch)
    42  	s.svc = svc
    43  	s.dir = c.MkDir()
    44  	c.Assert(utf8.ValidString(validSetTestValue), jc.IsTrue)
    45  	c.Assert(utf8.ValidString(invalidSetTestValue), jc.IsFalse)
    46  	setupValueFile(c, s.dir, "valid.txt", validSetTestValue)
    47  	setupValueFile(c, s.dir, "invalid.txt", invalidSetTestValue)
    48  	setupBigFile(c, s.dir)
    49  	setupConfigFile(c, s.dir)
    50  }
    51  
    52  func (s *SetSuite) TestSetOptionSuccess(c *gc.C) {
    53  	assertSetSuccess(c, s.dir, s.svc, []string{
    54  		"username=hello",
    55  		"outlook=hello@world.tld",
    56  	}, charm.Settings{
    57  		"username": "hello",
    58  		"outlook":  "hello@world.tld",
    59  	})
    60  	assertSetSuccess(c, s.dir, s.svc, []string{
    61  		"username=hello=foo",
    62  	}, charm.Settings{
    63  		"username": "hello=foo",
    64  		"outlook":  "hello@world.tld",
    65  	})
    66  	assertSetSuccess(c, s.dir, s.svc, []string{
    67  		"username=@valid.txt",
    68  	}, charm.Settings{
    69  		"username": validSetTestValue,
    70  		"outlook":  "hello@world.tld",
    71  	})
    72  	assertSetSuccess(c, s.dir, s.svc, []string{
    73  		"username=",
    74  	}, charm.Settings{
    75  		"username": "",
    76  		"outlook":  "hello@world.tld",
    77  	})
    78  }
    79  
    80  func (s *SetSuite) TestSetSameValue(c *gc.C) {
    81  	assertSetSuccess(c, s.dir, s.svc, []string{
    82  		"username=hello",
    83  		"outlook=hello@world.tld",
    84  	}, charm.Settings{
    85  		"username": "hello",
    86  		"outlook":  "hello@world.tld",
    87  	})
    88  	assertSetWarning(c, s.dir, []string{
    89  		"username=hello",
    90  	}, "the configuration setting \"username\" already has the value \"hello\"")
    91  	assertSetWarning(c, s.dir, []string{
    92  		"outlook=hello@world.tld",
    93  	}, "the configuration setting \"outlook\" already has the value \"hello@world.tld\"")
    94  
    95  }
    96  
    97  func (s *SetSuite) TestSetOptionFail(c *gc.C) {
    98  	assertSetFail(c, s.dir, []string{"foo", "bar"}, "error: expected \"key=value\", got \"foo\"\n")
    99  	assertSetFail(c, s.dir, []string{"=bar"}, "error: expected \"key=value\", got \"=bar\"\n")
   100  	assertSetFail(c, s.dir, []string{
   101  		"username=@missing.txt",
   102  	}, "error: cannot read option from file \"missing.txt\": .* "+utils.NoSuchFileErrRegexp+"\n")
   103  	assertSetFail(c, s.dir, []string{
   104  		"username=@big.txt",
   105  	}, "error: size of option file is larger than 5M\n")
   106  	assertSetFail(c, s.dir, []string{
   107  		"username=@invalid.txt",
   108  	}, "error: value for option \"username\" contains non-UTF-8 sequences\n")
   109  }
   110  
   111  func (s *SetSuite) TestSetConfig(c *gc.C) {
   112  	assertSetFail(c, s.dir, []string{
   113  		"--config",
   114  		"missing.yaml",
   115  	}, "error.* "+utils.NoSuchFileErrRegexp+"\n")
   116  
   117  	assertSetSuccess(c, s.dir, s.svc, []string{
   118  		"--config",
   119  		"testconfig.yaml",
   120  	}, charm.Settings{
   121  		"username":    "admin001",
   122  		"skill-level": int64(9000),
   123  	})
   124  }
   125  
   126  func (s *SetSuite) TestBlockSetConfig(c *gc.C) {
   127  	// Block operation
   128  	s.AssertConfigParameterUpdated(c, "block-all-changes", true)
   129  	ctx := coretesting.ContextForDir(c, s.dir)
   130  	code := cmd.Main(envcmd.Wrap(&SetCommand{}), ctx, append([]string{"dummy-service"}, []string{
   131  		"--config",
   132  		"testconfig.yaml",
   133  	}...))
   134  	c.Check(code, gc.Equals, 1)
   135  	// msg is logged
   136  	stripped := strings.Replace(c.GetTestLog(), "\n", "", -1)
   137  	c.Check(stripped, gc.Matches, ".*To unblock changes.*")
   138  }
   139  
   140  // assertSetSuccess sets configuration options and checks the expected settings.
   141  func assertSetSuccess(c *gc.C, dir string, svc *state.Service, args []string, expect charm.Settings) {
   142  	ctx := coretesting.ContextForDir(c, dir)
   143  	code := cmd.Main(envcmd.Wrap(&SetCommand{}), ctx, append([]string{"dummy-service"}, args...))
   144  	c.Check(code, gc.Equals, 0)
   145  	settings, err := svc.ConfigSettings()
   146  	c.Assert(err, jc.ErrorIsNil)
   147  	c.Assert(settings, gc.DeepEquals, expect)
   148  }
   149  
   150  // assertSetFail sets configuration options and checks the expected error.
   151  func assertSetFail(c *gc.C, dir string, args []string, err string) {
   152  	ctx := coretesting.ContextForDir(c, dir)
   153  	code := cmd.Main(envcmd.Wrap(&SetCommand{}), ctx, append([]string{"dummy-service"}, args...))
   154  	c.Check(code, gc.Not(gc.Equals), 0)
   155  	c.Assert(ctx.Stderr.(*bytes.Buffer).String(), gc.Matches, err)
   156  }
   157  
   158  func assertSetWarning(c *gc.C, dir string, args []string, w string) {
   159  	ctx := coretesting.ContextForDir(c, dir)
   160  	code := cmd.Main(envcmd.Wrap(&SetCommand{}), ctx, append([]string{"dummy-service"}, args...))
   161  	c.Check(code, gc.Equals, 0)
   162  
   163  	c.Assert(strings.Replace(c.GetTestLog(), "\n", " ", -1), gc.Matches, ".*WARNING.*"+w+".*")
   164  }
   165  
   166  // setupValueFile creates a file containing one value for testing
   167  // set with name=@filename.
   168  func setupValueFile(c *gc.C, dir, filename, value string) string {
   169  	ctx := coretesting.ContextForDir(c, dir)
   170  	path := ctx.AbsPath(filename)
   171  	content := []byte(value)
   172  	err := ioutil.WriteFile(path, content, 0666)
   173  	c.Assert(err, jc.ErrorIsNil)
   174  	return path
   175  }
   176  
   177  // setupBigFile creates a too big file for testing
   178  // set with name=@filename.
   179  func setupBigFile(c *gc.C, dir string) string {
   180  	ctx := coretesting.ContextForDir(c, dir)
   181  	path := ctx.AbsPath("big.txt")
   182  	file, err := os.Create(path)
   183  	c.Assert(err, jc.ErrorIsNil)
   184  	defer file.Close()
   185  	chunk := make([]byte, 1024)
   186  	for i := 0; i < cap(chunk); i++ {
   187  		chunk[i] = byte(i % 256)
   188  	}
   189  	for i := 0; i < 6000; i++ {
   190  		_, err = file.Write(chunk)
   191  		c.Assert(err, jc.ErrorIsNil)
   192  	}
   193  	return path
   194  }
   195  
   196  // setupConfigFile creates a configuration file for testing set
   197  // with the --config argument specifying a configuration file.
   198  func setupConfigFile(c *gc.C, dir string) string {
   199  	ctx := coretesting.ContextForDir(c, dir)
   200  	path := ctx.AbsPath("testconfig.yaml")
   201  	content := []byte("dummy-service:\n  skill-level: 9000\n  username: admin001\n\n")
   202  	err := ioutil.WriteFile(path, content, 0666)
   203  	c.Assert(err, jc.ErrorIsNil)
   204  	return path
   205  }