1
// Copyright 2015 Canonical Ltd.
2
// Licensed under the AGPLv3, see LICENCE file for details.
11
"github.com/juju/errors"
12
jc "github.com/juju/testing/checkers"
13
gc "gopkg.in/check.v1"
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"
23
type addSuite struct {
29
var _ = gc.Suite(&addSuite{})
31
func (s *addSuite) SetUpTest(c *gc.C) {
32
s.SubStorageSuite.SetUpTest(c)
34
s.mockAPI = &mockAddAPI{}
35
s.PatchValue(storage.GetStorageAddAPI, func(c *storage.AddCommand) (storage.StorageAddAPI, error) {
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.*`},
54
func (s *addSuite) TestAddArgs(c *gc.C) {
55
for i, t := range errorTsts {
56
c.Logf("test %d for %q", i, t.args)
58
s.assertAddErrorOutput(c, t.expectedErr)
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)
67
func runAdd(c *gc.C, args ...string) (*cmd.Context, error) {
68
return testing.RunCommand(c, envcmd.Wrap(&storage.AddCommand{}), args...)
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.*`)
76
var successTsts = []tstData{
77
{[]string{"tst/123", "data=676"}, ""},
78
{[]string{"tst/123", "data"}, ``},
81
func (s *addSuite) TestAddSuccess(c *gc.C) {
82
for i, t := range successTsts {
83
c.Logf("test %d for %q", i, t.args)
85
s.assertAddOutput(c, "", "")
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.*")
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")
100
func (s *addSuite) TestAddMixOrderPreserved(c *gc.C) {
102
fail: storage "err": test failure
103
success: storage "a"`[1:]
105
s.args = []string{"tst/123", "a=676", "err=676"}
106
s.assertAddOutput(c, "", expectedErr)
108
s.args = []string{"tst/123", "err=676", "a=676"}
109
s.assertAddOutput(c, "", expectedErr)
112
func (s *addSuite) assertAddOutput(c *gc.C, expectedValid, expectedErr string) {
113
context, err := runAdd(c, s.args...)
114
c.Assert(err, jc.ErrorIsNil)
116
obtainedErr := testing.Stderr(context)
117
c.Assert(obtainedErr, gc.Equals, expectedErr)
119
obtainedValid := testing.Stdout(context)
120
c.Assert(obtainedValid, gc.Equals, expectedValid)
123
type mockAddAPI struct {
127
func (s mockAddAPI) Close() error {
131
func (s mockAddAPI) AddToUnit(storages []params.StorageAddParams) ([]params.ErrorResult, error) {
133
return nil, errors.New("aborted")
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"))