github.com/cloud-green/juju@v0.0.0-20151002100041-a00291338d3d/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  	"net"
     8  	"regexp"
     9  	stdtesting "testing"
    10  
    11  	"github.com/juju/cmd"
    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/feature"
    20  	coretesting "github.com/juju/juju/testing"
    21  )
    22  
    23  func TestPackage(t *stdtesting.T) {
    24  	gc.TestingT(t)
    25  }
    26  
    27  // BaseSpaceSuite is used for embedding in other suites.
    28  type BaseSpaceSuite struct {
    29  	coretesting.FakeJujuHomeSuite
    30  	coretesting.BaseSuite
    31  
    32  	superCmd cmd.Command
    33  	command  cmd.Command
    34  	api      *StubAPI
    35  }
    36  
    37  var _ = gc.Suite(&BaseSpaceSuite{})
    38  
    39  func (s *BaseSpaceSuite) SetUpTest(c *gc.C) {
    40  	// If any post-MVP command suite enabled the flag, keep it.
    41  	hasFeatureFlag := featureflag.Enabled(feature.PostNetCLIMVP)
    42  
    43  	s.BaseSuite.SetUpTest(c)
    44  	s.FakeJujuHomeSuite.SetUpTest(c)
    45  
    46  	if hasFeatureFlag {
    47  		s.BaseSuite.SetFeatureFlags(feature.PostNetCLIMVP)
    48  	}
    49  
    50  	s.superCmd = space.NewSuperCommand()
    51  	c.Assert(s.superCmd, gc.NotNil)
    52  
    53  	s.api = NewStubAPI()
    54  	c.Assert(s.api, gc.NotNil)
    55  
    56  	// All subcommand suites embedding this one should initialize
    57  	// s.command immediately after calling this method!
    58  }
    59  
    60  // RunSuperCommand executes the super command passing any args and
    61  // returning the stdout and stderr output as strings, as well as any
    62  // error. If s.command is set, the subcommand's name will be passed as
    63  // first argument.
    64  func (s *BaseSpaceSuite) RunSuperCommand(c *gc.C, args ...string) (string, string, error) {
    65  	if s.command != nil {
    66  		args = append([]string{s.command.Info().Name}, args...)
    67  	}
    68  	ctx, err := coretesting.RunCommand(c, s.superCmd, args...)
    69  	if ctx != nil {
    70  		return coretesting.Stdout(ctx), coretesting.Stderr(ctx), err
    71  	}
    72  	return "", "", err
    73  }
    74  
    75  // RunSubCommand executes the s.command subcommand passing any args
    76  // and returning the stdout and stderr output as strings, as well as
    77  // any error.
    78  func (s *BaseSpaceSuite) RunSubCommand(c *gc.C, args ...string) (string, string, error) {
    79  	if s.command == nil {
    80  		panic("subcommand is nil")
    81  	}
    82  	ctx, err := coretesting.RunCommand(c, s.command, args...)
    83  	if ctx != nil {
    84  		return coretesting.Stdout(ctx), coretesting.Stderr(ctx), err
    85  	}
    86  	return "", "", err
    87  }
    88  
    89  // AssertRunSpacesNotSupported is a shortcut for calling RunSubCommand with the
    90  // passed args then asserting the output is empty and the error is the
    91  // spaces not supported, finally returning the error.
    92  func (s *BaseSpaceSuite) AssertRunSpacesNotSupported(c *gc.C, expectErr string, args ...string) error {
    93  	stdout, stderr, err := s.RunSubCommand(c, args...)
    94  	c.Assert(err, gc.ErrorMatches, expectErr)
    95  	c.Assert(stdout, gc.Equals, "")
    96  	c.Assert(stderr, gc.Equals, expectErr+"\n")
    97  	return err
    98  }
    99  
   100  // AssertRunFails is a shortcut for calling RunSubCommand with the
   101  // passed args then asserting the output is empty and the error is as
   102  // expected, finally returning the error.
   103  func (s *BaseSpaceSuite) AssertRunFails(c *gc.C, expectErr string, args ...string) error {
   104  	stdout, stderr, err := s.RunSubCommand(c, args...)
   105  	c.Assert(err, gc.ErrorMatches, expectErr)
   106  	c.Assert(stdout, gc.Equals, "")
   107  	c.Assert(stderr, gc.Equals, "")
   108  	return err
   109  }
   110  
   111  // AssertRunSucceeds is a shortcut for calling RunSuperCommand with
   112  // the passed args then asserting the stderr output matches
   113  // expectStderr, stdout is equal to expectStdout, and the error is
   114  // nil.
   115  func (s *BaseSpaceSuite) AssertRunSucceeds(c *gc.C, expectStderr, expectStdout string, args ...string) {
   116  	stdout, stderr, err := s.RunSubCommand(c, args...)
   117  	c.Assert(err, jc.ErrorIsNil)
   118  	c.Assert(stdout, gc.Equals, expectStdout)
   119  	c.Assert(stderr, gc.Matches, expectStderr)
   120  }
   121  
   122  // TestHelp runs the command with --help as argument and verifies the
   123  // output.
   124  func (s *BaseSpaceSuite) TestHelp(c *gc.C) {
   125  	stderr, stdout, err := s.RunSuperCommand(c, "--help")
   126  	c.Assert(err, jc.ErrorIsNil)
   127  	c.Check(stdout, gc.Equals, "")
   128  	c.Check(stderr, gc.Not(gc.Equals), "")
   129  
   130  	// If s.command is set, use it instead of s.superCmd.
   131  	cmdInfo := s.superCmd.Info()
   132  	var expected string
   133  	if s.command != nil {
   134  		// Subcommands embed EnvCommandBase
   135  		cmdInfo = s.command.Info()
   136  		expected = "(?sm).*^usage: juju space " +
   137  			regexp.QuoteMeta(cmdInfo.Name) +
   138  			`( \[options\])? ` + regexp.QuoteMeta(cmdInfo.Args) + ".+"
   139  	} else {
   140  		expected = "(?sm).*^usage: juju space" +
   141  			`( \[options\])? ` + regexp.QuoteMeta(cmdInfo.Args) + ".+"
   142  	}
   143  	c.Check(cmdInfo, gc.NotNil)
   144  	c.Check(stderr, gc.Matches, expected)
   145  
   146  	expected = "(?sm).*^purpose: " + regexp.QuoteMeta(cmdInfo.Purpose) + "$.*"
   147  	c.Check(stderr, gc.Matches, expected)
   148  
   149  	expected = "(?sm).*^" + regexp.QuoteMeta(cmdInfo.Doc) + "$.*"
   150  	c.Check(stderr, gc.Matches, expected)
   151  }
   152  
   153  // Strings is makes tests taking a slice of strings slightly easier to
   154  // write: e.g. s.Strings("foo", "bar") vs. []string{"foo", "bar"}.
   155  func (s *BaseSpaceSuite) Strings(values ...string) []string {
   156  	return values
   157  }
   158  
   159  // StubAPI defines a testing stub for the SpaceAPI interface.
   160  type StubAPI struct {
   161  	*testing.Stub
   162  
   163  	Spaces  []params.Space
   164  	Subnets []params.Subnet
   165  }
   166  
   167  var _ space.SpaceAPI = (*StubAPI)(nil)
   168  
   169  // NewStubAPI creates a StubAPI suitable for passing to
   170  // space.New*Command().
   171  func NewStubAPI() *StubAPI {
   172  	subnets := []params.Subnet{{
   173  		// IPv6 subnet.
   174  		CIDR:       "2001:db8::/32",
   175  		ProviderId: "subnet-public",
   176  		Life:       params.Dying,
   177  		SpaceTag:   "space-space1",
   178  		Zones:      []string{"zone2"},
   179  	}, {
   180  		// Invalid subnet (just for 100% coverage, otherwise it can't happen).
   181  		CIDR:       "invalid",
   182  		ProviderId: "no-such",
   183  		SpaceTag:   "space-space1",
   184  		Zones:      []string{"zone1"},
   185  	}, {
   186  		// IPv4 subnet.
   187  		CIDR:              "10.1.2.0/24",
   188  		ProviderId:        "subnet-private",
   189  		Life:              params.Alive,
   190  		SpaceTag:          "space-space2",
   191  		Zones:             []string{"zone1", "zone2"},
   192  		StaticRangeLowIP:  net.ParseIP("10.1.2.10"),
   193  		StaticRangeHighIP: net.ParseIP("10.1.2.200"),
   194  	}, {
   195  		// IPv4 VLAN subnet.
   196  		CIDR:              "4.3.2.0/28",
   197  		Life:              params.Dead,
   198  		ProviderId:        "vlan-42",
   199  		SpaceTag:          "space-space2",
   200  		Zones:             []string{"zone1"},
   201  		VLANTag:           42,
   202  		StaticRangeLowIP:  net.ParseIP("4.3.2.2"),
   203  		StaticRangeHighIP: net.ParseIP("4.3.2.4"),
   204  	}}
   205  	spaces := []params.Space{{
   206  		Name:    "space1",
   207  		Subnets: append([]params.Subnet{}, subnets[:2]...),
   208  	}, {
   209  		Name:    "space2",
   210  		Subnets: append([]params.Subnet{}, subnets[2:]...),
   211  	}}
   212  	return &StubAPI{
   213  		Stub:    &testing.Stub{},
   214  		Spaces:  spaces,
   215  		Subnets: subnets,
   216  	}
   217  }
   218  
   219  func (sa *StubAPI) Close() error {
   220  	sa.MethodCall(sa, "Close")
   221  	return sa.NextErr()
   222  }
   223  
   224  func (sa *StubAPI) ListSpaces() ([]params.Space, error) {
   225  	sa.MethodCall(sa, "ListSpaces")
   226  	if err := sa.NextErr(); err != nil {
   227  		return nil, err
   228  	}
   229  	return sa.Spaces, nil
   230  }
   231  
   232  func (sa *StubAPI) CreateSpace(name string, subnetIds []string, public bool) error {
   233  	sa.MethodCall(sa, "CreateSpace", name, subnetIds, public)
   234  	return sa.NextErr()
   235  }
   236  
   237  func (sa *StubAPI) RemoveSpace(name string) error {
   238  	sa.MethodCall(sa, "RemoveSpace", name)
   239  	return sa.NextErr()
   240  }
   241  
   242  func (sa *StubAPI) UpdateSpace(name string, subnetIds []string) error {
   243  	sa.MethodCall(sa, "UpdateSpace", name, subnetIds)
   244  	return sa.NextErr()
   245  }
   246  
   247  func (sa *StubAPI) RenameSpace(name, newName string) error {
   248  	sa.MethodCall(sa, "RenameSpace", name, newName)
   249  	return sa.NextErr()
   250  }