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