github.com/cloud-green/juju@v0.0.0-20151002100041-a00291338d3d/apiserver/spaces/spaces_test.go (about)

     1  // Copyright 2015 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package spaces_test
     5  
     6  import (
     7  	"fmt"
     8  
     9  	"github.com/juju/errors"
    10  	"github.com/juju/names"
    11  	jc "github.com/juju/testing/checkers"
    12  	gc "gopkg.in/check.v1"
    13  
    14  	"github.com/juju/juju/apiserver/common"
    15  	"github.com/juju/juju/apiserver/params"
    16  	"github.com/juju/juju/apiserver/spaces"
    17  	apiservertesting "github.com/juju/juju/apiserver/testing"
    18  	coretesting "github.com/juju/juju/testing"
    19  )
    20  
    21  type SpacesSuite struct {
    22  	coretesting.BaseSuite
    23  	apiservertesting.StubNetwork
    24  
    25  	resources  *common.Resources
    26  	authorizer apiservertesting.FakeAuthorizer
    27  	facade     spaces.API
    28  }
    29  
    30  var _ = gc.Suite(&SpacesSuite{})
    31  
    32  func (s *SpacesSuite) SetUpSuite(c *gc.C) {
    33  	s.StubNetwork.SetUpSuite(c)
    34  	s.BaseSuite.SetUpSuite(c)
    35  }
    36  
    37  func (s *SpacesSuite) TearDownSuite(c *gc.C) {
    38  	s.BaseSuite.TearDownSuite(c)
    39  }
    40  
    41  func (s *SpacesSuite) SetUpTest(c *gc.C) {
    42  	s.BaseSuite.SetUpTest(c)
    43  	apiservertesting.BackingInstance.SetUp(c, apiservertesting.StubZonedNetworkingEnvironName, apiservertesting.WithZones, apiservertesting.WithSpaces, apiservertesting.WithSubnets)
    44  
    45  	s.resources = common.NewResources()
    46  	s.authorizer = apiservertesting.FakeAuthorizer{
    47  		Tag:            names.NewUserTag("admin"),
    48  		EnvironManager: false,
    49  	}
    50  
    51  	var err error
    52  	s.facade, err = spaces.NewAPIWithBacking(
    53  		apiservertesting.BackingInstance, s.resources, s.authorizer,
    54  	)
    55  	c.Assert(err, jc.ErrorIsNil)
    56  	c.Assert(s.facade, gc.NotNil)
    57  }
    58  
    59  func (s *SpacesSuite) TearDownTest(c *gc.C) {
    60  	if s.resources != nil {
    61  		s.resources.StopAll()
    62  	}
    63  	s.BaseSuite.TearDownTest(c)
    64  }
    65  
    66  func (s *SpacesSuite) TestNewAPIWithBacking(c *gc.C) {
    67  	// Clients are allowed.
    68  	facade, err := spaces.NewAPIWithBacking(
    69  		apiservertesting.BackingInstance, s.resources, s.authorizer,
    70  	)
    71  	c.Assert(err, jc.ErrorIsNil)
    72  	c.Assert(facade, gc.NotNil)
    73  	// No calls so far.
    74  	apiservertesting.CheckMethodCalls(c, apiservertesting.SharedStub)
    75  
    76  	// Agents are not allowed
    77  	agentAuthorizer := s.authorizer
    78  	agentAuthorizer.Tag = names.NewMachineTag("42")
    79  	facade, err = spaces.NewAPIWithBacking(
    80  		apiservertesting.BackingInstance, s.resources, agentAuthorizer,
    81  	)
    82  	c.Assert(err, jc.DeepEquals, common.ErrPerm)
    83  	c.Assert(facade, gc.IsNil)
    84  	// No calls so far.
    85  	apiservertesting.CheckMethodCalls(c, apiservertesting.SharedStub)
    86  }
    87  
    88  type checkAddSpacesParams struct {
    89  	Name      string
    90  	Subnets   []string
    91  	Error     string
    92  	MakesCall bool
    93  	Public    bool
    94  }
    95  
    96  func (s *SpacesSuite) checkAddSpaces(c *gc.C, p checkAddSpacesParams) {
    97  	args := params.CreateSpaceParams{}
    98  	if p.Name != "" {
    99  		args.SpaceTag = "space-" + p.Name
   100  	}
   101  	if len(p.Subnets) > 0 {
   102  		for _, cidr := range p.Subnets {
   103  			args.SubnetTags = append(args.SubnetTags, "subnet-"+cidr)
   104  		}
   105  	}
   106  	args.Public = p.Public
   107  
   108  	spaces := params.CreateSpacesParams{}
   109  	spaces.Spaces = append(spaces.Spaces, args)
   110  	results, err := s.facade.CreateSpaces(spaces)
   111  
   112  	c.Assert(len(results.Results), gc.Equals, 1)
   113  	c.Assert(err, gc.IsNil)
   114  	if p.Error == "" {
   115  		c.Assert(results.Results[0].Error, gc.IsNil)
   116  	} else {
   117  		c.Assert(results.Results[0].Error, gc.NotNil)
   118  		c.Assert(results.Results[0].Error, gc.ErrorMatches, p.Error)
   119  	}
   120  
   121  	baseCalls := []apiservertesting.StubMethodCall{
   122  		apiservertesting.BackingCall("EnvironConfig"),
   123  		apiservertesting.ProviderCall("Open", apiservertesting.BackingInstance.EnvConfig),
   124  		apiservertesting.ZonedNetworkingEnvironCall("SupportsSpaces"),
   125  	}
   126  	addSpaceCalls := append(baseCalls, apiservertesting.BackingCall("AddSpace", p.Name, p.Subnets, p.Public))
   127  
   128  	if p.Error == "" || p.MakesCall {
   129  		apiservertesting.CheckMethodCalls(c, apiservertesting.SharedStub, addSpaceCalls...)
   130  	} else {
   131  		apiservertesting.CheckMethodCalls(c, apiservertesting.SharedStub, baseCalls...)
   132  	}
   133  }
   134  
   135  func (s *SpacesSuite) TestAddSpacesOneSubnet(c *gc.C) {
   136  	p := checkAddSpacesParams{
   137  		Name:    "foo",
   138  		Subnets: []string{"10.0.0.0/24"},
   139  	}
   140  	s.checkAddSpaces(c, p)
   141  }
   142  
   143  func (s *SpacesSuite) TestAddSpacesTwoSubnets(c *gc.C) {
   144  	p := checkAddSpacesParams{
   145  		Name:    "foo",
   146  		Subnets: []string{"10.0.0.0/24", "10.0.1.0/24"},
   147  	}
   148  	s.checkAddSpaces(c, p)
   149  }
   150  
   151  func (s *SpacesSuite) TestAddSpacesManySubnets(c *gc.C) {
   152  	p := checkAddSpacesParams{
   153  		Name: "foo",
   154  		Subnets: []string{"10.0.0.0/24", "10.0.1.0/24", "10.0.2.0/24",
   155  			"10.0.3.0/24", "10.0.4.0/24", "10.0.5.0/24", "10.0.6.0/24"},
   156  	}
   157  	s.checkAddSpaces(c, p)
   158  }
   159  
   160  func (s *SpacesSuite) TestAddSpacesAPIError(c *gc.C) {
   161  	apiservertesting.SharedStub.SetErrors(
   162  		nil, // Backing.EnvironConfig()
   163  		nil, // Provider.Open()
   164  		nil, // ZonedNetworkingEnviron.SupportsSpaces()
   165  		errors.AlreadyExistsf("space-foo"), // Backing.AddSpace()
   166  	)
   167  	p := checkAddSpacesParams{
   168  		Name:      "foo",
   169  		Subnets:   []string{"10.0.0.0/24"},
   170  		MakesCall: true,
   171  		Error:     "space-foo already exists",
   172  	}
   173  	s.checkAddSpaces(c, p)
   174  }
   175  
   176  func (s *SpacesSuite) TestCreateInvalidSpace(c *gc.C) {
   177  	p := checkAddSpacesParams{
   178  		Name:    "-",
   179  		Subnets: []string{"10.0.0.0/24"},
   180  		Error:   `"space--" is not a valid space tag`,
   181  	}
   182  	s.checkAddSpaces(c, p)
   183  }
   184  
   185  func (s *SpacesSuite) TestCreateInvalidSubnet(c *gc.C) {
   186  	p := checkAddSpacesParams{
   187  		Name:    "foo",
   188  		Subnets: []string{"bar"},
   189  		Error:   `"subnet-bar" is not a valid subnet tag`,
   190  	}
   191  	s.checkAddSpaces(c, p)
   192  }
   193  
   194  func (s *SpacesSuite) TestPublic(c *gc.C) {
   195  	p := checkAddSpacesParams{
   196  		Name:    "foo",
   197  		Subnets: []string{"10.0.0.0/24"},
   198  		Public:  true,
   199  	}
   200  	s.checkAddSpaces(c, p)
   201  }
   202  
   203  func (s *SpacesSuite) TestEmptySpaceName(c *gc.C) {
   204  	p := checkAddSpacesParams{
   205  		Subnets: []string{"10.0.0.0/24"},
   206  		Error:   `"" is not a valid tag`,
   207  	}
   208  	s.checkAddSpaces(c, p)
   209  }
   210  
   211  func (s *SpacesSuite) TestNoSubnets(c *gc.C) {
   212  	p := checkAddSpacesParams{
   213  		Name:    "foo",
   214  		Subnets: nil,
   215  	}
   216  	s.checkAddSpaces(c, p)
   217  }
   218  
   219  func (s *SpacesSuite) TestListSpacesDefault(c *gc.C) {
   220  	expected := []params.Space{{
   221  		Name: "default",
   222  		Subnets: []params.Subnet{{
   223  			CIDR:       "192.168.0.0/24",
   224  			ProviderId: "provider-192.168.0.0/24",
   225  			Zones:      []string{"foo"},
   226  			Status:     "in-use",
   227  			SpaceTag:   "space-default",
   228  		}, {
   229  			CIDR:       "192.168.3.0/24",
   230  			ProviderId: "provider-192.168.3.0/24",
   231  			VLANTag:    23,
   232  			Zones:      []string{"bar", "bam"},
   233  			SpaceTag:   "space-default",
   234  		}},
   235  	}, {
   236  		Name: "dmz",
   237  		Subnets: []params.Subnet{{
   238  			CIDR:       "192.168.1.0/24",
   239  			ProviderId: "provider-192.168.1.0/24",
   240  			VLANTag:    23,
   241  			Zones:      []string{"bar", "bam"},
   242  			SpaceTag:   "space-dmz",
   243  		}},
   244  	}, {
   245  		Name: "private",
   246  		Subnets: []params.Subnet{{
   247  			CIDR:       "192.168.2.0/24",
   248  			ProviderId: "provider-192.168.2.0/24",
   249  			Zones:      []string{"foo"},
   250  			Status:     "in-use",
   251  			SpaceTag:   "space-private",
   252  		}},
   253  	}}
   254  	spaces, err := s.facade.ListSpaces()
   255  	c.Assert(err, jc.ErrorIsNil)
   256  	c.Assert(spaces.Results, jc.DeepEquals, expected)
   257  }
   258  
   259  func (s *SpacesSuite) TestListSpacesAllSpacesError(c *gc.C) {
   260  	boom := errors.New("backing boom")
   261  	apiservertesting.BackingInstance.SetErrors(boom)
   262  	_, err := s.facade.ListSpaces()
   263  	c.Assert(err, gc.ErrorMatches, "getting environment config: backing boom")
   264  }
   265  
   266  func (s *SpacesSuite) TestListSpacesSubnetsError(c *gc.C) {
   267  	apiservertesting.SharedStub.SetErrors(
   268  		nil, // Backing.EnvironConfig()
   269  		nil, // Provider.Open()
   270  		nil, // ZonedNetworkingEnviron.SupportsSpaces()
   271  		nil, // Backing.AllSpaces()
   272  		errors.New("space0 subnets failed"), // Space.Subnets()
   273  		errors.New("space1 subnets failed"), // Space.Subnets()
   274  		errors.New("space2 subnets failed"), // Space.Subnets()
   275  	)
   276  
   277  	results, err := s.facade.ListSpaces()
   278  	for i, space := range results.Results {
   279  		errmsg := fmt.Sprintf("fetching subnets: space%d subnets failed", i)
   280  		c.Assert(space.Error, gc.ErrorMatches, errmsg)
   281  	}
   282  	c.Assert(err, jc.ErrorIsNil)
   283  }
   284  
   285  func (s *SpacesSuite) TestListSpacesSubnetsSingleSubnetError(c *gc.C) {
   286  	boom := errors.New("boom")
   287  	apiservertesting.SharedStub.SetErrors(
   288  		nil,  // Backing.EnvironConfig()
   289  		nil,  // Provider.Open()
   290  		nil,  // ZonedNetworkingEnviron.SupportsSpaces()
   291  		nil,  // Backing.AllSpaces()
   292  		nil,  // Space.Subnets() (1st no error)
   293  		boom, // Space.Subnets() (2nd with error)
   294  	)
   295  
   296  	results, err := s.facade.ListSpaces()
   297  	for i, space := range results.Results {
   298  		if i == 1 {
   299  			c.Assert(space.Error, gc.ErrorMatches, "fetching subnets: boom")
   300  		} else {
   301  			c.Assert(space.Error, gc.IsNil)
   302  		}
   303  	}
   304  	c.Assert(err, jc.ErrorIsNil)
   305  }
   306  
   307  func (s *SpacesSuite) TestCreateSpacesEnvironConfigError(c *gc.C) {
   308  	apiservertesting.SharedStub.SetErrors(
   309  		errors.New("boom"), // Backing.EnvironConfig()
   310  	)
   311  
   312  	spaces := params.CreateSpacesParams{}
   313  	_, err := s.facade.CreateSpaces(spaces)
   314  	c.Assert(err, gc.ErrorMatches, "getting environment config: boom")
   315  }
   316  
   317  func (s *SpacesSuite) TestCreateSpacesProviderOpenError(c *gc.C) {
   318  	apiservertesting.SharedStub.SetErrors(
   319  		nil,                // Backing.EnvironConfig()
   320  		errors.New("boom"), // Provider.Open()
   321  	)
   322  
   323  	spaces := params.CreateSpacesParams{}
   324  	_, err := s.facade.CreateSpaces(spaces)
   325  	c.Assert(err, gc.ErrorMatches, "validating environment config: boom")
   326  }
   327  
   328  func (s *SpacesSuite) TestCreateSpacesNotSupportedError(c *gc.C) {
   329  	apiservertesting.SharedStub.SetErrors(
   330  		nil, // Backing.EnvironConfig()
   331  		nil, // Provider.Open()
   332  		errors.NotSupportedf("spaces"), // ZonedNetworkingEnviron.SupportsSpaces()
   333  	)
   334  
   335  	spaces := params.CreateSpacesParams{}
   336  	_, err := s.facade.CreateSpaces(spaces)
   337  	c.Assert(err, gc.ErrorMatches, "spaces not supported")
   338  }
   339  
   340  func (s *SpacesSuite) TestListSpacesNotSupportedError(c *gc.C) {
   341  	apiservertesting.SharedStub.SetErrors(
   342  		nil, // Backing.EnvironConfig()
   343  		nil, // Provider.Open
   344  		errors.NotSupportedf("spaces"), // ZonedNetworkingEnviron.SupportsSpaces()
   345  	)
   346  
   347  	_, err := s.facade.ListSpaces()
   348  	c.Assert(err, gc.ErrorMatches, "spaces not supported")
   349  }