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