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

     1  // Copyright 2015 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package storage_test
     5  
     6  import (
     7  	"fmt"
     8  	"strings"
     9  
    10  	"github.com/juju/cmd"
    11  	"github.com/juju/errors"
    12  	jc "github.com/juju/testing/checkers"
    13  	gc "gopkg.in/check.v1"
    14  
    15  	"github.com/juju/juju/apiserver/common"
    16  	"github.com/juju/juju/apiserver/params"
    17  	"github.com/juju/juju/cmd/envcmd"
    18  	"github.com/juju/juju/cmd/juju/storage"
    19  	_ "github.com/juju/juju/provider/dummy"
    20  	"github.com/juju/juju/testing"
    21  )
    22  
    23  type addSuite struct {
    24  	SubStorageSuite
    25  	mockAPI *mockAddAPI
    26  	args    []string
    27  }
    28  
    29  var _ = gc.Suite(&addSuite{})
    30  
    31  func (s *addSuite) SetUpTest(c *gc.C) {
    32  	s.SubStorageSuite.SetUpTest(c)
    33  
    34  	s.mockAPI = &mockAddAPI{}
    35  	s.PatchValue(storage.GetStorageAddAPI, func(c *storage.AddCommand) (storage.StorageAddAPI, error) {
    36  		return s.mockAPI, nil
    37  	})
    38  	s.args = nil
    39  }
    40  
    41  type tstData struct {
    42  	args        []string
    43  	expectedErr string
    44  }
    45  
    46  var errorTsts = []tstData{
    47  	{nil, ".*storage add requires a unit and a storage directive.*"},
    48  	{[]string{"tst/123"}, ".*storage add requires a unit and a storage directive.*"},
    49  	{[]string{"tst/123", "data="}, `.*storage constraints require at least one.*`},
    50  	{[]string{"tst/123", "data=-676"}, `.*count must be greater than zero, got "-676".*`},
    51  	{[]string{"tst/123", "data=676", "data=676"}, `.*storage "data" specified more than once.*`},
    52  }
    53  
    54  func (s *addSuite) TestAddArgs(c *gc.C) {
    55  	for i, t := range errorTsts {
    56  		c.Logf("test %d for %q", i, t.args)
    57  		s.args = t.args
    58  		s.assertAddErrorOutput(c, t.expectedErr)
    59  	}
    60  }
    61  
    62  func (s *addSuite) assertAddErrorOutput(c *gc.C, expected string) {
    63  	_, err := runAdd(c, s.args...)
    64  	c.Assert(errors.Cause(err), gc.ErrorMatches, expected)
    65  }
    66  
    67  func runAdd(c *gc.C, args ...string) (*cmd.Context, error) {
    68  	return testing.RunCommand(c, envcmd.Wrap(&storage.AddCommand{}), args...)
    69  }
    70  
    71  func (s *addSuite) TestAddInvalidUnit(c *gc.C) {
    72  	s.args = []string{"tst-123", "data=676"}
    73  	s.assertAddErrorOutput(c, `.*unit name "tst-123" not valid.*`)
    74  }
    75  
    76  var successTsts = []tstData{
    77  	{[]string{"tst/123", "data=676"}, ""},
    78  	{[]string{"tst/123", "data"}, ``},
    79  }
    80  
    81  func (s *addSuite) TestAddSuccess(c *gc.C) {
    82  	for i, t := range successTsts {
    83  		c.Logf("test %d for %q", i, t.args)
    84  		s.args = t.args
    85  		s.assertAddOutput(c, "", "")
    86  	}
    87  }
    88  
    89  func (s *addSuite) TestAddOperationAborted(c *gc.C) {
    90  	s.args = []string{"tst/123", "data=676"}
    91  	s.mockAPI.abort = true
    92  	s.assertAddErrorOutput(c, ".*aborted.*")
    93  }
    94  
    95  func (s *addSuite) TestAddFailure(c *gc.C) {
    96  	s.args = []string{"tst/123", "err=676"}
    97  	s.assertAddOutput(c, "", "fail: storage \"err\": test failure\n")
    98  }
    99  
   100  func (s *addSuite) TestAddMixOrderPreserved(c *gc.C) {
   101  	expectedErr := `
   102  fail: storage "err": test failure
   103  success: storage "a"`[1:]
   104  
   105  	s.args = []string{"tst/123", "a=676", "err=676"}
   106  	s.assertAddOutput(c, "", expectedErr)
   107  
   108  	s.args = []string{"tst/123", "err=676", "a=676"}
   109  	s.assertAddOutput(c, "", expectedErr)
   110  }
   111  
   112  func (s *addSuite) assertAddOutput(c *gc.C, expectedValid, expectedErr string) {
   113  	context, err := runAdd(c, s.args...)
   114  	c.Assert(err, jc.ErrorIsNil)
   115  
   116  	obtainedErr := testing.Stderr(context)
   117  	c.Assert(obtainedErr, gc.Equals, expectedErr)
   118  
   119  	obtainedValid := testing.Stdout(context)
   120  	c.Assert(obtainedValid, gc.Equals, expectedValid)
   121  }
   122  
   123  type mockAddAPI struct {
   124  	abort bool
   125  }
   126  
   127  func (s mockAddAPI) Close() error {
   128  	return nil
   129  }
   130  
   131  func (s mockAddAPI) AddToUnit(storages []params.StorageAddParams) ([]params.ErrorResult, error) {
   132  	if s.abort {
   133  		return nil, errors.New("aborted")
   134  	}
   135  	result := make([]params.ErrorResult, len(storages))
   136  	for i, one := range storages {
   137  		if strings.HasPrefix(one.StorageName, "err") {
   138  			result[i].Error = common.ServerError(fmt.Errorf("test failure"))
   139  		}
   140  	}
   141  	return result, nil
   142  }