github.com/makyo/juju@v0.0.0-20160425123129-2608902037e9/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  	stdtesting "testing"
     9  
    10  	"github.com/juju/cmd"
    11  	"github.com/juju/names"
    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/subnet"
    19  	"github.com/juju/juju/feature"
    20  	"github.com/juju/juju/network"
    21  	coretesting "github.com/juju/juju/testing"
    22  )
    23  
    24  func TestPackage(t *stdtesting.T) {
    25  	gc.TestingT(t)
    26  }
    27  
    28  // BaseSubnetSuite is used for embedding in other suites.
    29  type BaseSubnetSuite struct {
    30  	coretesting.FakeJujuXDGDataHomeSuite
    31  	coretesting.BaseSuite
    32  
    33  	command cmd.Command
    34  	api     *StubAPI
    35  }
    36  
    37  var _ = gc.Suite(&BaseSubnetSuite{})
    38  
    39  func (s *BaseSubnetSuite) SetUpSuite(c *gc.C) {
    40  	s.FakeJujuXDGDataHomeSuite.SetUpSuite(c)
    41  	s.BaseSuite.SetUpSuite(c)
    42  }
    43  
    44  func (s *BaseSubnetSuite) TearDownSuite(c *gc.C) {
    45  	s.BaseSuite.TearDownSuite(c)
    46  	s.FakeJujuXDGDataHomeSuite.TearDownSuite(c)
    47  }
    48  
    49  func (s *BaseSubnetSuite) SetUpTest(c *gc.C) {
    50  	// If any post-MVP command suite enabled the flag, keep it.
    51  	hasFeatureFlag := featureflag.Enabled(feature.PostNetCLIMVP)
    52  
    53  	s.BaseSuite.SetUpTest(c)
    54  	s.FakeJujuXDGDataHomeSuite.SetUpTest(c)
    55  
    56  	if hasFeatureFlag {
    57  		s.BaseSuite.SetFeatureFlags(feature.PostNetCLIMVP)
    58  	}
    59  
    60  	s.api = NewStubAPI()
    61  	c.Assert(s.api, gc.NotNil)
    62  
    63  	// All subcommand suites embedding this one should initialize
    64  	// s.command immediately after calling this method!
    65  }
    66  
    67  func (s *BaseSubnetSuite) TearDownTest(c *gc.C) {
    68  	s.BaseSuite.TearDownTest(c)
    69  	s.FakeJujuXDGDataHomeSuite.TearDownTest(c)
    70  }
    71  
    72  // RunCommand executes the s.command passing any args
    73  // and returning the stdout and stderr output as strings, as well as
    74  // any error.
    75  func (s *BaseSubnetSuite) RunCommand(c *gc.C, args ...string) (string, string, error) {
    76  	if s.command == nil {
    77  		panic("command is nil")
    78  	}
    79  	ctx, err := coretesting.RunCommand(c, s.command, args...)
    80  	if ctx != nil {
    81  		return coretesting.Stdout(ctx), coretesting.Stderr(ctx), err
    82  	}
    83  	return "", "", err
    84  }
    85  
    86  // AssertRunFails is a shortcut for calling RunCommand with the
    87  // passed args then asserting the output is empty and the error is as
    88  // expected, finally returning the error.
    89  func (s *BaseSubnetSuite) AssertRunFails(c *gc.C, expectErr string, args ...string) error {
    90  	stdout, stderr, err := s.RunCommand(c, args...)
    91  	c.Assert(err, gc.ErrorMatches, expectErr)
    92  	c.Assert(stdout, gc.Equals, "")
    93  	c.Assert(stderr, gc.Equals, "")
    94  	return err
    95  }
    96  
    97  // AssertRunSucceeds is a shortcut for calling RunCommand with
    98  // the passed args then asserting the stderr output matches
    99  // expectStderr, stdout is equal to expectStdout, and the error is
   100  // nil.
   101  func (s *BaseSubnetSuite) AssertRunSucceeds(c *gc.C, expectStderr, expectStdout string, args ...string) {
   102  	stdout, stderr, err := s.RunCommand(c, args...)
   103  	c.Assert(err, jc.ErrorIsNil)
   104  	c.Assert(stdout, gc.Equals, expectStdout)
   105  	c.Assert(stderr, gc.Matches, expectStderr)
   106  }
   107  
   108  // Strings makes tests taking a slice of strings slightly easier to
   109  // write: e.g. s.Strings("foo", "bar") vs. []string{"foo", "bar"}.
   110  func (s *BaseSubnetSuite) Strings(values ...string) []string {
   111  	return values
   112  }
   113  
   114  // StubAPI defines a testing stub for the SubnetAPI interface.
   115  type StubAPI struct {
   116  	*testing.Stub
   117  
   118  	Subnets []params.Subnet
   119  	Spaces  []names.Tag
   120  	Zones   []string
   121  }
   122  
   123  var _ subnet.SubnetAPI = (*StubAPI)(nil)
   124  
   125  // NewStubAPI creates a StubAPI suitable for passing to
   126  // subnet.New*Command().
   127  func NewStubAPI() *StubAPI {
   128  	subnets := []params.Subnet{{
   129  		// IPv4 subnet.
   130  		CIDR:              "10.20.0.0/24",
   131  		ProviderId:        "subnet-foo",
   132  		Life:              params.Alive,
   133  		SpaceTag:          "space-public",
   134  		Zones:             []string{"zone1", "zone2"},
   135  		StaticRangeLowIP:  net.ParseIP("10.20.0.10"),
   136  		StaticRangeHighIP: net.ParseIP("10.20.0.100"),
   137  	}, {
   138  		// IPv6 subnet.
   139  		CIDR:       "2001:db8::/32",
   140  		ProviderId: "subnet-bar",
   141  		Life:       params.Dying,
   142  		SpaceTag:   "space-dmz",
   143  		Zones:      []string{"zone2"},
   144  	}, {
   145  		// IPv4 VLAN subnet.
   146  		CIDR:     "10.10.0.0/16",
   147  		Life:     params.Dead,
   148  		SpaceTag: "space-vlan-42",
   149  		Zones:    []string{"zone1"},
   150  		VLANTag:  42,
   151  	}}
   152  	return &StubAPI{
   153  		Stub:    &testing.Stub{},
   154  		Zones:   []string{"zone1", "zone2"},
   155  		Subnets: subnets,
   156  		Spaces: []names.Tag{
   157  			names.NewSpaceTag("default"),
   158  			names.NewSpaceTag("public"),
   159  			names.NewSpaceTag("dmz"),
   160  			names.NewSpaceTag("vlan-42"),
   161  		},
   162  	}
   163  }
   164  
   165  func (sa *StubAPI) Close() error {
   166  	sa.MethodCall(sa, "Close")
   167  	return sa.NextErr()
   168  }
   169  
   170  func (sa *StubAPI) AllZones() ([]string, error) {
   171  	sa.MethodCall(sa, "AllZones")
   172  	if err := sa.NextErr(); err != nil {
   173  		return nil, err
   174  	}
   175  	return sa.Zones, nil
   176  }
   177  
   178  func (sa *StubAPI) AllSpaces() ([]names.Tag, error) {
   179  	sa.MethodCall(sa, "AllSpaces")
   180  	if err := sa.NextErr(); err != nil {
   181  		return nil, err
   182  	}
   183  	return sa.Spaces, nil
   184  }
   185  
   186  func (sa *StubAPI) CreateSubnet(subnetCIDR names.SubnetTag, spaceTag names.SpaceTag, zones []string, isPublic bool) error {
   187  	sa.MethodCall(sa, "CreateSubnet", subnetCIDR, spaceTag, zones, isPublic)
   188  	return sa.NextErr()
   189  }
   190  
   191  func (sa *StubAPI) AddSubnet(cidr names.SubnetTag, id network.Id, spaceTag names.SpaceTag, zones []string) error {
   192  	sa.MethodCall(sa, "AddSubnet", cidr, id, spaceTag, zones)
   193  	return sa.NextErr()
   194  }
   195  
   196  func (sa *StubAPI) RemoveSubnet(subnetCIDR names.SubnetTag) error {
   197  	sa.MethodCall(sa, "RemoveSubnet", subnetCIDR)
   198  	return sa.NextErr()
   199  }
   200  
   201  func (sa *StubAPI) ListSubnets(withSpace *names.SpaceTag, withZone string) ([]params.Subnet, error) {
   202  	if withSpace == nil {
   203  		// Due to the way CheckCall works (using jc.DeepEquals
   204  		// internally), we need to pass an explicit nil here, rather
   205  		// than a pointer to a names.SpaceTag pointing to nil.
   206  		sa.MethodCall(sa, "ListSubnets", nil, withZone)
   207  	} else {
   208  		sa.MethodCall(sa, "ListSubnets", withSpace, withZone)
   209  	}
   210  	if err := sa.NextErr(); err != nil {
   211  		return nil, err
   212  	}
   213  	return sa.Subnets, nil
   214  }