github.com/niedbalski/juju@v0.0.0-20190215020005-8ff100488e47/cmd/juju/space/package_test.go (about)

     1  // Copyright 2015 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package space_test
     5  
     6  import (
     7  	"strings"
     8  	stdtesting "testing"
     9  
    10  	"github.com/juju/cmd"
    11  	"github.com/juju/cmd/cmdtesting"
    12  	"github.com/juju/testing"
    13  	jc "github.com/juju/testing/checkers"
    14  	"github.com/juju/utils/featureflag"
    15  	gc "gopkg.in/check.v1"
    16  
    17  	"github.com/juju/juju/apiserver/params"
    18  	"github.com/juju/juju/cmd/juju/space"
    19  	"github.com/juju/juju/cmd/modelcmd"
    20  	"github.com/juju/juju/feature"
    21  	"github.com/juju/juju/jujuclient/jujuclienttesting"
    22  	coretesting "github.com/juju/juju/testing"
    23  )
    24  
    25  func TestPackage(t *stdtesting.T) {
    26  	gc.TestingT(t)
    27  }
    28  
    29  // BaseSpaceSuite is used for embedding in other suites.
    30  type BaseSpaceSuite struct {
    31  	coretesting.FakeJujuXDGDataHomeSuite
    32  	coretesting.BaseSuite
    33  
    34  	newCommand func() modelcmd.ModelCommand
    35  	api        *StubAPI
    36  }
    37  
    38  var _ = gc.Suite(&BaseSpaceSuite{})
    39  
    40  func (s *BaseSpaceSuite) SetUpSuite(c *gc.C) {
    41  	s.FakeJujuXDGDataHomeSuite.SetUpSuite(c)
    42  	s.BaseSuite.SetUpSuite(c)
    43  }
    44  
    45  func (s *BaseSpaceSuite) TearDownSuite(c *gc.C) {
    46  	s.BaseSuite.TearDownSuite(c)
    47  	s.FakeJujuXDGDataHomeSuite.TearDownSuite(c)
    48  }
    49  
    50  func (s *BaseSpaceSuite) SetUpTest(c *gc.C) {
    51  	// If any post-MVP command suite enabled the flag, keep it.
    52  	hasFeatureFlag := featureflag.Enabled(feature.PostNetCLIMVP)
    53  
    54  	s.BaseSuite.SetUpTest(c)
    55  	s.FakeJujuXDGDataHomeSuite.SetUpTest(c)
    56  
    57  	if hasFeatureFlag {
    58  		s.BaseSuite.SetFeatureFlags(feature.PostNetCLIMVP)
    59  	}
    60  
    61  	s.api = NewStubAPI()
    62  	c.Assert(s.api, gc.NotNil)
    63  
    64  	// All subcommand suites embedding this one should initialize
    65  	// s.newCommand immediately after calling this method!
    66  }
    67  
    68  func (s *BaseSpaceSuite) TearDownTest(c *gc.C) {
    69  	s.FakeJujuXDGDataHomeSuite.TearDownTest(c)
    70  	s.BaseSuite.TearDownTest(c)
    71  }
    72  
    73  // InitCommand creates a command with s.newCommand and runs its
    74  // Init method only. It returns the inner command and any error.
    75  func (s *BaseSpaceSuite) InitCommand(c *gc.C, args ...string) (cmd.Command, error) {
    76  	cmd := s.newCommandForTest()
    77  	err := cmdtesting.InitCommand(cmd, args)
    78  	return modelcmd.InnerCommand(cmd), err
    79  }
    80  
    81  // RunCommand creates a command with s.newCommand and executes it,
    82  // passing any args and returning the stdout and stderr output as
    83  // strings, as well as any error.
    84  func (s *BaseSpaceSuite) RunCommand(c *gc.C, args ...string) (string, string, error) {
    85  	cmd := s.newCommandForTest()
    86  	ctx, err := cmdtesting.RunCommand(c, cmd, args...)
    87  	return cmdtesting.Stdout(ctx), cmdtesting.Stderr(ctx), err
    88  }
    89  
    90  func (s *BaseSpaceSuite) newCommandForTest() modelcmd.ModelCommand {
    91  	cmd := s.newCommand()
    92  	// The client store shouldn't be used, but mock it
    93  	// out to make sure.
    94  	cmd.SetClientStore(jujuclienttesting.MinimalStore())
    95  	cmd1 := modelcmd.InnerCommand(cmd).(interface {
    96  		SetAPI(space.SpaceAPI)
    97  	})
    98  	cmd1.SetAPI(s.api)
    99  	return cmd
   100  }
   101  
   102  // AssertRunSpacesNotSupported is a shortcut for calling RunCommand with the
   103  // passed args then asserting the output is empty and the error is the
   104  // spaces not supported, finally returning the error.
   105  func (s *BaseSpaceSuite) AssertRunSpacesNotSupported(c *gc.C, expectErr string, args ...string) error {
   106  	stdout, stderr, err := s.RunCommand(c, args...)
   107  	c.Assert(err, gc.ErrorMatches, expectErr)
   108  	c.Assert(stdout, gc.Equals, "")
   109  	c.Assert(stderr, gc.Equals, expectErr+"\n")
   110  	return err
   111  }
   112  
   113  // AssertRunFailsUnauthoirzed is a shortcut for calling RunCommand with the
   114  // passed args then asserting the error is as expected, finally returning the
   115  // error.
   116  func (s *BaseSpaceSuite) AssertRunFailsUnauthorized(c *gc.C, expectErr string, args ...string) error {
   117  	_, stderr, err := s.RunCommand(c, args...)
   118  	c.Assert(strings.Replace(stderr, "\n", " ", -1), gc.Matches, `.*juju grant.*`)
   119  	return err
   120  }
   121  
   122  // AssertRunFails is a shortcut for calling RunCommand with the
   123  // passed args then asserting the output is empty and the error is as
   124  // expected, finally returning the error.
   125  func (s *BaseSpaceSuite) AssertRunFails(c *gc.C, expectErr string, args ...string) error {
   126  	stdout, stderr, err := s.RunCommand(c, args...)
   127  	c.Assert(err, gc.ErrorMatches, expectErr)
   128  	c.Assert(stdout, gc.Equals, "")
   129  	c.Assert(stderr, gc.Equals, "")
   130  	return err
   131  }
   132  
   133  // AssertRunSucceeds is a shortcut for calling RunSuperCommand with
   134  // the passed args then asserting the stderr output matches
   135  // expectStderr, stdout is equal to expectStdout, and the error is
   136  // nil.
   137  func (s *BaseSpaceSuite) AssertRunSucceeds(c *gc.C, expectStderr, expectStdout string, args ...string) {
   138  	stdout, stderr, err := s.RunCommand(c, args...)
   139  	c.Assert(err, jc.ErrorIsNil)
   140  	c.Assert(stdout, gc.Equals, expectStdout)
   141  	c.Assert(stderr, gc.Matches, expectStderr)
   142  }
   143  
   144  // Strings is makes tests taking a slice of strings slightly easier to
   145  // write: e.g. s.Strings("foo", "bar") vs. []string{"foo", "bar"}.
   146  func (s *BaseSpaceSuite) Strings(values ...string) []string {
   147  	return values
   148  }
   149  
   150  // StubAPI defines a testing stub for the SpaceAPI interface.
   151  type StubAPI struct {
   152  	*testing.Stub
   153  
   154  	Spaces  []params.Space
   155  	Subnets []params.Subnet
   156  }
   157  
   158  var _ space.SpaceAPI = (*StubAPI)(nil)
   159  
   160  // NewStubAPI creates a StubAPI suitable for passing to
   161  // space.New*Command().
   162  func NewStubAPI() *StubAPI {
   163  	subnets := []params.Subnet{{
   164  		// IPv6 subnet.
   165  		CIDR:       "2001:db8::/32",
   166  		ProviderId: "subnet-public",
   167  		Life:       params.Dying,
   168  		SpaceTag:   "space-space1",
   169  		Zones:      []string{"zone2"},
   170  	}, {
   171  		// Invalid subnet (just for 100% coverage, otherwise it can't happen).
   172  		CIDR:       "invalid",
   173  		ProviderId: "no-such",
   174  		SpaceTag:   "space-space1",
   175  		Zones:      []string{"zone1"},
   176  	}, {
   177  		// IPv4 subnet.
   178  		CIDR:       "10.1.2.0/24",
   179  		ProviderId: "subnet-private",
   180  		Life:       params.Alive,
   181  		SpaceTag:   "space-space2",
   182  		Zones:      []string{"zone1", "zone2"},
   183  	}, {
   184  		// IPv4 VLAN subnet.
   185  		CIDR:       "4.3.2.0/28",
   186  		Life:       params.Dead,
   187  		ProviderId: "vlan-42",
   188  		SpaceTag:   "space-space2",
   189  		Zones:      []string{"zone1"},
   190  		VLANTag:    42,
   191  	}}
   192  	spaces := []params.Space{{
   193  		Name:    "space1",
   194  		Subnets: append([]params.Subnet{}, subnets[:2]...),
   195  	}, {
   196  		Name:    "space2",
   197  		Subnets: append([]params.Subnet{}, subnets[2:]...),
   198  	}}
   199  	return &StubAPI{
   200  		Stub:    &testing.Stub{},
   201  		Spaces:  spaces,
   202  		Subnets: subnets,
   203  	}
   204  }
   205  
   206  func (sa *StubAPI) Close() error {
   207  	sa.MethodCall(sa, "Close")
   208  	return sa.NextErr()
   209  }
   210  
   211  func (sa *StubAPI) ListSpaces() ([]params.Space, error) {
   212  	sa.MethodCall(sa, "ListSpaces")
   213  	if err := sa.NextErr(); err != nil {
   214  		return nil, err
   215  	}
   216  	return sa.Spaces, nil
   217  }
   218  
   219  func (sa *StubAPI) AddSpace(name string, subnetIds []string, public bool) error {
   220  	sa.MethodCall(sa, "AddSpace", name, subnetIds, public)
   221  	return sa.NextErr()
   222  }
   223  
   224  func (sa *StubAPI) RemoveSpace(name string) error {
   225  	sa.MethodCall(sa, "RemoveSpace", name)
   226  	return sa.NextErr()
   227  }
   228  
   229  func (sa *StubAPI) UpdateSpace(name string, subnetIds []string) error {
   230  	sa.MethodCall(sa, "UpdateSpace", name, subnetIds)
   231  	return sa.NextErr()
   232  }
   233  
   234  func (sa *StubAPI) RenameSpace(name, newName string) error {
   235  	sa.MethodCall(sa, "RenameSpace", name, newName)
   236  	return sa.NextErr()
   237  }
   238  
   239  func (sa *StubAPI) ReloadSpaces() error {
   240  	sa.MethodCall(sa, "ReloadSpaces")
   241  	return sa.NextErr()
   242  }