github.com/cloud-green/juju@v0.0.0-20151002100041-a00291338d3d/cmd/juju/common/constraints_test.go (about)

     1  // Copyright 2013 - 2015 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package common_test
     5  
     6  import (
     7  	"bytes"
     8  	"strings"
     9  
    10  	"github.com/juju/cmd"
    11  	"github.com/juju/errors"
    12  	"github.com/juju/names"
    13  	jc "github.com/juju/testing/checkers"
    14  	gc "gopkg.in/check.v1"
    15  
    16  	"github.com/juju/juju/apiserver/common"
    17  	"github.com/juju/juju/cmd/envcmd"
    18  	// TODO(dimitern): Don't ever import "." unless there's a GOOD
    19  	// reason to do it.
    20  	. "github.com/juju/juju/cmd/juju/common"
    21  	"github.com/juju/juju/constraints"
    22  	"github.com/juju/juju/testing"
    23  )
    24  
    25  type ConstraintsCommandsSuite struct {
    26  	testing.FakeJujuHomeSuite
    27  	fake *fakeConstraintsClient
    28  }
    29  
    30  var _ = gc.Suite(&ConstraintsCommandsSuite{})
    31  
    32  type fakeConstraintsClient struct {
    33  	err      error
    34  	envCons  constraints.Value
    35  	servCons map[string]constraints.Value
    36  }
    37  
    38  func (f *fakeConstraintsClient) addTestingService(name string) {
    39  	f.servCons[name] = constraints.Value{}
    40  }
    41  
    42  func (f *fakeConstraintsClient) Close() error {
    43  	return nil
    44  }
    45  
    46  func (f *fakeConstraintsClient) GetEnvironmentConstraints() (constraints.Value, error) {
    47  	return f.envCons, nil
    48  }
    49  
    50  func (f *fakeConstraintsClient) GetServiceConstraints(name string) (constraints.Value, error) {
    51  	if !names.IsValidService(name) {
    52  		return constraints.Value{}, errors.Errorf("%q is not a valid service name", name)
    53  	}
    54  
    55  	cons, ok := f.servCons[name]
    56  	if !ok {
    57  		return constraints.Value{}, errors.NotFoundf("service %q", name)
    58  	}
    59  
    60  	return cons, nil
    61  }
    62  
    63  func (f *fakeConstraintsClient) SetEnvironmentConstraints(cons constraints.Value) error {
    64  	if f.err != nil {
    65  		return f.err
    66  	}
    67  
    68  	f.envCons = cons
    69  	return nil
    70  }
    71  
    72  func (f *fakeConstraintsClient) SetServiceConstraints(name string, cons constraints.Value) error {
    73  	if f.err != nil {
    74  		return f.err
    75  	}
    76  
    77  	if !names.IsValidService(name) {
    78  		return errors.Errorf("%q is not a valid service name", name)
    79  	}
    80  
    81  	_, ok := f.servCons[name]
    82  	if !ok {
    83  		return errors.NotFoundf("service %q", name)
    84  	}
    85  
    86  	f.servCons[name] = cons
    87  	return nil
    88  }
    89  
    90  func runCmdLine(c *gc.C, com cmd.Command, args ...string) (code int, stdout, stderr string) {
    91  	ctx := testing.Context(c)
    92  	code = cmd.Main(com, ctx, args)
    93  	stdout = ctx.Stdout.(*bytes.Buffer).String()
    94  	stderr = ctx.Stderr.(*bytes.Buffer).String()
    95  	c.Logf("args:   %#v\ncode:   %d\nstdout: %q\nstderr: %q", args, code, stdout, stderr)
    96  	return
    97  }
    98  
    99  func uint64p(val uint64) *uint64 {
   100  	return &val
   101  }
   102  
   103  func (s *ConstraintsCommandsSuite) assertSet(c *gc.C, args ...string) {
   104  	command := NewSetConstraintsCommand(s.fake)
   105  	rcode, rstdout, rstderr := runCmdLine(c, envcmd.Wrap(command), args...)
   106  
   107  	c.Assert(rcode, gc.Equals, 0)
   108  	c.Assert(rstdout, gc.Equals, "")
   109  	c.Assert(rstderr, gc.Equals, "")
   110  }
   111  
   112  func (s *ConstraintsCommandsSuite) assertSetBlocked(c *gc.C, args ...string) {
   113  	command := NewSetConstraintsCommand(s.fake)
   114  	rcode, _, _ := runCmdLine(c, envcmd.Wrap(command), args...)
   115  
   116  	c.Assert(rcode, gc.Equals, 1)
   117  
   118  	// msg is logged
   119  	stripped := strings.Replace(c.GetTestLog(), "\n", "", -1)
   120  	c.Check(stripped, gc.Matches, ".*To unblock changes.*")
   121  }
   122  
   123  func (s *ConstraintsCommandsSuite) SetUpTest(c *gc.C) {
   124  	s.FakeJujuHomeSuite.SetUpTest(c)
   125  	s.fake = &fakeConstraintsClient{servCons: make(map[string]constraints.Value)}
   126  }
   127  
   128  func (s *ConstraintsCommandsSuite) TestSetEnviron(c *gc.C) {
   129  	// Set constraints.
   130  	s.assertSet(c, "mem=4G", "cpu-power=250")
   131  	cons, err := s.fake.GetEnvironmentConstraints()
   132  	c.Assert(err, jc.ErrorIsNil)
   133  	c.Assert(cons, gc.DeepEquals, constraints.Value{
   134  		CpuPower: uint64p(250),
   135  		Mem:      uint64p(4096),
   136  	})
   137  
   138  	// Clear constraints.
   139  	s.assertSet(c)
   140  	cons, err = s.fake.GetEnvironmentConstraints()
   141  	c.Assert(err, jc.ErrorIsNil)
   142  	c.Assert(&cons, jc.Satisfies, constraints.IsEmpty)
   143  }
   144  
   145  func (s *ConstraintsCommandsSuite) TestBlockSetEnviron(c *gc.C) {
   146  	// Block operation
   147  	s.fake.err = common.ErrOperationBlocked("TestBlockSetEnviron")
   148  	// Set constraints.
   149  	s.assertSetBlocked(c, "mem=4G", "cpu-power=250")
   150  }
   151  
   152  func (s *ConstraintsCommandsSuite) TestSetService(c *gc.C) {
   153  	s.fake.addTestingService("svc")
   154  
   155  	// Set constraints.
   156  	s.assertSet(c, "-s", "svc", "mem=4G", "cpu-power=250")
   157  	cons := s.fake.servCons["svc"]
   158  	c.Assert(cons, gc.DeepEquals, constraints.Value{
   159  		CpuPower: uint64p(250),
   160  		Mem:      uint64p(4096),
   161  	})
   162  
   163  	// Clear constraints.
   164  	s.assertSet(c, "-s", "svc")
   165  	cons = s.fake.servCons["svc"]
   166  	c.Assert(&cons, jc.Satisfies, constraints.IsEmpty)
   167  }
   168  
   169  func (s *ConstraintsCommandsSuite) TestBlockSetService(c *gc.C) {
   170  	s.fake.addTestingService("svc")
   171  
   172  	// Block operation
   173  	s.fake.err = common.ErrOperationBlocked("TestBlockSetService")
   174  	// Set constraints.
   175  	s.assertSetBlocked(c, "-s", "svc", "mem=4G", "cpu-power=250")
   176  }
   177  
   178  func (s *ConstraintsCommandsSuite) assertSetError(c *gc.C, code int, stderr string, args ...string) {
   179  	command := NewSetConstraintsCommand(s.fake)
   180  	rcode, rstdout, rstderr := runCmdLine(c, envcmd.Wrap(command), args...)
   181  	c.Assert(rcode, gc.Equals, code)
   182  	c.Assert(rstdout, gc.Equals, "")
   183  	c.Assert(rstderr, gc.Matches, "error: "+stderr+"\n")
   184  }
   185  
   186  func (s *ConstraintsCommandsSuite) TestSetErrors(c *gc.C) {
   187  	s.assertSetError(c, 2, `invalid service name "badname-0"`, "-s", "badname-0")
   188  	s.assertSetError(c, 2, `malformed constraint "="`, "=")
   189  	s.assertSetError(c, 2, `malformed constraint "="`, "-s", "s", "=")
   190  	s.assertSetError(c, 1, `service "missing" not found`, "-s", "missing")
   191  }
   192  
   193  func (s *ConstraintsCommandsSuite) assertGet(c *gc.C, stdout string, args ...string) {
   194  	command := NewGetConstraintsCommand(s.fake)
   195  	rcode, rstdout, rstderr := runCmdLine(c, envcmd.Wrap(command), args...)
   196  	c.Assert(rcode, gc.Equals, 0)
   197  	c.Assert(rstdout, gc.Equals, stdout)
   198  	c.Assert(rstderr, gc.Equals, "")
   199  }
   200  
   201  func (s *ConstraintsCommandsSuite) TestGetEnvironEmpty(c *gc.C) {
   202  	s.assertGet(c, "")
   203  }
   204  
   205  func (s *ConstraintsCommandsSuite) TestGetEnvironValues(c *gc.C) {
   206  	cons := constraints.Value{CpuCores: uint64p(64)}
   207  	s.fake.SetEnvironmentConstraints(cons)
   208  	s.assertGet(c, "cpu-cores=64\n")
   209  }
   210  
   211  func (s *ConstraintsCommandsSuite) TestGetServiceEmpty(c *gc.C) {
   212  	s.fake.addTestingService("svc")
   213  	s.assertGet(c, "", "svc")
   214  }
   215  
   216  func (s *ConstraintsCommandsSuite) TestGetServiceValues(c *gc.C) {
   217  	s.fake.addTestingService("svc")
   218  	s.fake.SetServiceConstraints("svc", constraints.Value{CpuCores: uint64p(64)})
   219  	s.assertGet(c, "cpu-cores=64\n", "svc")
   220  }
   221  
   222  func (s *ConstraintsCommandsSuite) TestGetFormats(c *gc.C) {
   223  	cons := constraints.Value{CpuCores: uint64p(64), CpuPower: uint64p(0)}
   224  	s.fake.SetEnvironmentConstraints(cons)
   225  	s.assertGet(c, "cpu-cores=64 cpu-power=\n", "--format", "constraints")
   226  	s.assertGet(c, "cpu-cores: 64\ncpu-power: 0\n", "--format", "yaml")
   227  	s.assertGet(c, `{"cpu-cores":64,"cpu-power":0}`+"\n", "--format", "json")
   228  }
   229  
   230  func (s *ConstraintsCommandsSuite) assertGetError(c *gc.C, code int, stderr string, args ...string) {
   231  	command := NewGetConstraintsCommand(s.fake)
   232  	rcode, rstdout, rstderr := runCmdLine(c, envcmd.Wrap(command), args...)
   233  	c.Assert(rcode, gc.Equals, code)
   234  	c.Assert(rstdout, gc.Equals, "")
   235  	c.Assert(rstderr, gc.Matches, "error: "+stderr+"\n")
   236  }
   237  
   238  func (s *ConstraintsCommandsSuite) TestGetErrors(c *gc.C) {
   239  	s.assertGetError(c, 2, `invalid service name "badname-0"`, "badname-0")
   240  	s.assertGetError(c, 2, `unrecognized args: \["blether"\]`, "goodname", "blether")
   241  	s.assertGetError(c, 1, `service "missing" not found`, "missing")
   242  }