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

     1  // Copyright 2015 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package subnet_test
     5  
     6  import (
     7  	"net"
     8  	"regexp"
     9  	stdtesting "testing"
    10  
    11  	"github.com/juju/cmd"
    12  	"github.com/juju/names"
    13  	"github.com/juju/testing"
    14  	jc "github.com/juju/testing/checkers"
    15  	"github.com/juju/utils/featureflag"
    16  	gc "gopkg.in/check.v1"
    17  
    18  	"github.com/juju/juju/apiserver/params"
    19  	"github.com/juju/juju/cmd/juju/subnet"
    20  	"github.com/juju/juju/feature"
    21  	"github.com/juju/juju/network"
    22  	coretesting "github.com/juju/juju/testing"
    23  )
    24  
    25  func TestPackage(t *stdtesting.T) {
    26  	gc.TestingT(t)
    27  }
    28  
    29  // BaseSubnetSuite is used for embedding in other suites.
    30  type BaseSubnetSuite struct {
    31  	coretesting.FakeJujuHomeSuite
    32  	coretesting.BaseSuite
    33  
    34  	superCmd cmd.Command
    35  	command  cmd.Command
    36  	api      *StubAPI
    37  }
    38  
    39  var _ = gc.Suite(&BaseSubnetSuite{})
    40  
    41  func (s *BaseSubnetSuite) SetUpTest(c *gc.C) {
    42  	// If any post-MVP command suite enabled the flag, keep it.
    43  	hasFeatureFlag := featureflag.Enabled(feature.PostNetCLIMVP)
    44  
    45  	s.BaseSuite.SetUpTest(c)
    46  	s.FakeJujuHomeSuite.SetUpTest(c)
    47  
    48  	if hasFeatureFlag {
    49  		s.BaseSuite.SetFeatureFlags(feature.PostNetCLIMVP)
    50  	}
    51  
    52  	s.superCmd = subnet.NewSuperCommand()
    53  	c.Assert(s.superCmd, gc.NotNil)
    54  
    55  	s.api = NewStubAPI()
    56  	c.Assert(s.api, gc.NotNil)
    57  
    58  	// All subcommand suites embedding this one should initialize
    59  	// s.command immediately after calling this method!
    60  }
    61  
    62  // RunSuperCommand executes the super command passing any args and
    63  // returning the stdout and stderr output as strings, as well as any
    64  // error. If s.command is set, the subcommand's name will be passed as
    65  // first argument.
    66  func (s *BaseSubnetSuite) RunSuperCommand(c *gc.C, args ...string) (string, string, error) {
    67  	if s.command != nil {
    68  		args = append([]string{s.command.Info().Name}, args...)
    69  	}
    70  	ctx, err := coretesting.RunCommand(c, s.superCmd, args...)
    71  	if ctx != nil {
    72  		return coretesting.Stdout(ctx), coretesting.Stderr(ctx), err
    73  	}
    74  	return "", "", err
    75  }
    76  
    77  // RunSubCommand executes the s.command subcommand passing any args
    78  // and returning the stdout and stderr output as strings, as well as
    79  // any error.
    80  func (s *BaseSubnetSuite) RunSubCommand(c *gc.C, args ...string) (string, string, error) {
    81  	if s.command == nil {
    82  		panic("subcommand is nil")
    83  	}
    84  	ctx, err := coretesting.RunCommand(c, s.command, args...)
    85  	if ctx != nil {
    86  		return coretesting.Stdout(ctx), coretesting.Stderr(ctx), err
    87  	}
    88  	return "", "", err
    89  }
    90  
    91  // AssertRunFails is a shortcut for calling RunSubCommand with the
    92  // passed args then asserting the output is empty and the error is as
    93  // expected, finally returning the error.
    94  func (s *BaseSubnetSuite) AssertRunFails(c *gc.C, expectErr string, args ...string) error {
    95  	stdout, stderr, err := s.RunSubCommand(c, args...)
    96  	c.Assert(err, gc.ErrorMatches, expectErr)
    97  	c.Assert(stdout, gc.Equals, "")
    98  	c.Assert(stderr, gc.Equals, "")
    99  	return err
   100  }
   101  
   102  // AssertRunSucceeds is a shortcut for calling RunSuperCommand with
   103  // the passed args then asserting the stderr output matches
   104  // expectStderr, stdout is equal to expectStdout, and the error is
   105  // nil.
   106  func (s *BaseSubnetSuite) AssertRunSucceeds(c *gc.C, expectStderr, expectStdout string, args ...string) {
   107  	stdout, stderr, err := s.RunSubCommand(c, args...)
   108  	c.Assert(err, jc.ErrorIsNil)
   109  	c.Assert(stdout, gc.Equals, expectStdout)
   110  	c.Assert(stderr, gc.Matches, expectStderr)
   111  }
   112  
   113  // TestHelp runs the command with --help as argument and verifies the
   114  // output.
   115  func (s *BaseSubnetSuite) TestHelp(c *gc.C) {
   116  	stderr, stdout, err := s.RunSuperCommand(c, "--help")
   117  	c.Assert(err, jc.ErrorIsNil)
   118  	c.Check(stdout, gc.Equals, "")
   119  	c.Check(stderr, gc.Not(gc.Equals), "")
   120  
   121  	// If s.command is set, use it instead of s.superCmd.
   122  	cmdInfo := s.superCmd.Info()
   123  	var expected string
   124  	if s.command != nil {
   125  		// Subcommands embed EnvCommandBase and have an extra
   126  		// "[options]" prepended before the args.
   127  		cmdInfo = s.command.Info()
   128  		expected = "(?sm).*^usage: juju subnet " +
   129  			regexp.QuoteMeta(cmdInfo.Name) +
   130  			`( \[options\])? ` + regexp.QuoteMeta(cmdInfo.Args) + ".+"
   131  	} else {
   132  		expected = "(?sm).*^usage: juju subnet" +
   133  			`( \[options\])? ` + regexp.QuoteMeta(cmdInfo.Args) + ".+"
   134  	}
   135  	c.Check(cmdInfo, gc.NotNil)
   136  	c.Check(stderr, gc.Matches, expected)
   137  
   138  	expected = "(?sm).*^purpose: " + regexp.QuoteMeta(cmdInfo.Purpose) + "$.*"
   139  	c.Check(stderr, gc.Matches, expected)
   140  
   141  	expected = "(?sm).*^" + regexp.QuoteMeta(cmdInfo.Doc) + "$.*"
   142  	c.Check(stderr, gc.Matches, expected)
   143  }
   144  
   145  // Strings makes tests taking a slice of strings slightly easier to
   146  // write: e.g. s.Strings("foo", "bar") vs. []string{"foo", "bar"}.
   147  func (s *BaseSubnetSuite) Strings(values ...string) []string {
   148  	return values
   149  }
   150  
   151  // StubAPI defines a testing stub for the SubnetAPI interface.
   152  type StubAPI struct {
   153  	*testing.Stub
   154  
   155  	Subnets []params.Subnet
   156  	Spaces  []names.Tag
   157  	Zones   []string
   158  }
   159  
   160  var _ subnet.SubnetAPI = (*StubAPI)(nil)
   161  
   162  // NewStubAPI creates a StubAPI suitable for passing to
   163  // subnet.New*Command().
   164  func NewStubAPI() *StubAPI {
   165  	subnets := []params.Subnet{{
   166  		// IPv4 subnet.
   167  		CIDR:              "10.20.0.0/24",
   168  		ProviderId:        "subnet-foo",
   169  		Life:              params.Alive,
   170  		SpaceTag:          "space-public",
   171  		Zones:             []string{"zone1", "zone2"},
   172  		StaticRangeLowIP:  net.ParseIP("10.20.0.10"),
   173  		StaticRangeHighIP: net.ParseIP("10.20.0.100"),
   174  	}, {
   175  		// IPv6 subnet.
   176  		CIDR:       "2001:db8::/32",
   177  		ProviderId: "subnet-bar",
   178  		Life:       params.Dying,
   179  		SpaceTag:   "space-dmz",
   180  		Zones:      []string{"zone2"},
   181  	}, {
   182  		// IPv4 VLAN subnet.
   183  		CIDR:     "10.10.0.0/16",
   184  		Life:     params.Dead,
   185  		SpaceTag: "space-vlan-42",
   186  		Zones:    []string{"zone1"},
   187  		VLANTag:  42,
   188  	}}
   189  	return &StubAPI{
   190  		Stub:    &testing.Stub{},
   191  		Zones:   []string{"zone1", "zone2"},
   192  		Subnets: subnets,
   193  		Spaces: []names.Tag{
   194  			names.NewSpaceTag("default"),
   195  			names.NewSpaceTag("public"),
   196  			names.NewSpaceTag("dmz"),
   197  			names.NewSpaceTag("vlan-42"),
   198  		},
   199  	}
   200  }
   201  
   202  func (sa *StubAPI) Close() error {
   203  	sa.MethodCall(sa, "Close")
   204  	return sa.NextErr()
   205  }
   206  
   207  func (sa *StubAPI) AllZones() ([]string, error) {
   208  	sa.MethodCall(sa, "AllZones")
   209  	if err := sa.NextErr(); err != nil {
   210  		return nil, err
   211  	}
   212  	return sa.Zones, nil
   213  }
   214  
   215  func (sa *StubAPI) AllSpaces() ([]names.Tag, error) {
   216  	sa.MethodCall(sa, "AllSpaces")
   217  	if err := sa.NextErr(); err != nil {
   218  		return nil, err
   219  	}
   220  	return sa.Spaces, nil
   221  }
   222  
   223  func (sa *StubAPI) CreateSubnet(subnetCIDR names.SubnetTag, spaceTag names.SpaceTag, zones []string, isPublic bool) error {
   224  	sa.MethodCall(sa, "CreateSubnet", subnetCIDR, spaceTag, zones, isPublic)
   225  	return sa.NextErr()
   226  }
   227  
   228  func (sa *StubAPI) AddSubnet(cidr names.SubnetTag, id network.Id, spaceTag names.SpaceTag, zones []string) error {
   229  	sa.MethodCall(sa, "AddSubnet", cidr, id, spaceTag, zones)
   230  	return sa.NextErr()
   231  }
   232  
   233  func (sa *StubAPI) RemoveSubnet(subnetCIDR names.SubnetTag) error {
   234  	sa.MethodCall(sa, "RemoveSubnet", subnetCIDR)
   235  	return sa.NextErr()
   236  }
   237  
   238  func (sa *StubAPI) ListSubnets(withSpace *names.SpaceTag, withZone string) ([]params.Subnet, error) {
   239  	if withSpace == nil {
   240  		// Due to the way CheckCall works (using jc.DeepEquals
   241  		// internally), we need to pass an explicit nil here, rather
   242  		// than a pointer to a names.SpaceTag pointing to nil.
   243  		sa.MethodCall(sa, "ListSubnets", nil, withZone)
   244  	} else {
   245  		sa.MethodCall(sa, "ListSubnets", withSpace, withZone)
   246  	}
   247  	if err := sa.NextErr(); err != nil {
   248  		return nil, err
   249  	}
   250  	return sa.Subnets, nil
   251  }