github.com/niedbalski/juju@v0.0.0-20190215020005-8ff100488e47/provider/gce/environ_policy_test.go (about)

     1  // Copyright 2014 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package gce_test
     5  
     6  import (
     7  	"github.com/juju/errors"
     8  	jc "github.com/juju/testing/checkers"
     9  	gc "gopkg.in/check.v1"
    10  
    11  	"github.com/juju/juju/core/constraints"
    12  	"github.com/juju/juju/environs"
    13  	"github.com/juju/juju/juju/version"
    14  	"github.com/juju/juju/provider/gce"
    15  	"github.com/juju/juju/provider/gce/google"
    16  	"github.com/juju/juju/storage"
    17  )
    18  
    19  type environPolSuite struct {
    20  	gce.BaseSuite
    21  }
    22  
    23  var _ = gc.Suite(&environPolSuite{})
    24  
    25  func (s *environPolSuite) TestPrecheckInstanceDefaults(c *gc.C) {
    26  	err := s.Env.PrecheckInstance(s.CallCtx, environs.PrecheckInstanceParams{Series: version.SupportedLTS()})
    27  	c.Assert(err, jc.ErrorIsNil)
    28  
    29  	c.Check(s.FakeConn.Calls, gc.HasLen, 0)
    30  }
    31  
    32  func (s *environPolSuite) TestPrecheckInstanceFullAPI(c *gc.C) {
    33  	s.FakeConn.Zones = []google.AvailabilityZone{
    34  		google.NewZone("home-zone", google.StatusUp, "", ""),
    35  	}
    36  
    37  	cons := constraints.MustParse("instance-type=n1-standard-1 arch=amd64 root-disk=1G")
    38  	placement := "zone=home-zone"
    39  	err := s.Env.PrecheckInstance(s.CallCtx, environs.PrecheckInstanceParams{Series: version.SupportedLTS(), Constraints: cons, Placement: placement})
    40  	c.Assert(err, jc.ErrorIsNil)
    41  
    42  	c.Check(s.FakeConn.Calls, gc.HasLen, 1)
    43  	c.Check(s.FakeConn.Calls[0].FuncName, gc.Equals, "AvailabilityZones")
    44  	c.Check(s.FakeConn.Calls[0].Region, gc.Equals, "us-east1")
    45  }
    46  
    47  func (s *environPolSuite) TestPrecheckInstanceValidInstanceType(c *gc.C) {
    48  	cons := constraints.MustParse("instance-type=n1-standard-1")
    49  	err := s.Env.PrecheckInstance(s.CallCtx, environs.PrecheckInstanceParams{Series: version.SupportedLTS(), Constraints: cons})
    50  
    51  	c.Check(err, jc.ErrorIsNil)
    52  }
    53  
    54  func (s *environPolSuite) TestPrecheckInstanceInvalidInstanceType(c *gc.C) {
    55  	cons := constraints.MustParse("instance-type=n1-standard-1.invalid")
    56  	err := s.Env.PrecheckInstance(s.CallCtx, environs.PrecheckInstanceParams{Series: version.SupportedLTS(), Constraints: cons})
    57  
    58  	c.Check(err, gc.ErrorMatches, `.*invalid GCE instance type.*`)
    59  }
    60  
    61  func (s *environPolSuite) TestPrecheckInstanceDiskSize(c *gc.C) {
    62  	cons := constraints.MustParse("instance-type=n1-standard-1 root-disk=1G")
    63  	placement := ""
    64  	err := s.Env.PrecheckInstance(s.CallCtx, environs.PrecheckInstanceParams{Series: version.SupportedLTS(), Constraints: cons, Placement: placement})
    65  
    66  	c.Check(err, jc.ErrorIsNil)
    67  }
    68  
    69  func (s *environPolSuite) TestPrecheckInstanceUnsupportedArch(c *gc.C) {
    70  	cons := constraints.MustParse("instance-type=n1-standard-1 arch=i386")
    71  	err := s.Env.PrecheckInstance(s.CallCtx, environs.PrecheckInstanceParams{Series: version.SupportedLTS(), Constraints: cons})
    72  
    73  	c.Check(err, jc.ErrorIsNil)
    74  }
    75  
    76  func (s *environPolSuite) TestPrecheckInstanceAvailZone(c *gc.C) {
    77  	s.FakeConn.Zones = []google.AvailabilityZone{
    78  		google.NewZone("a-zone", google.StatusUp, "", ""),
    79  	}
    80  
    81  	placement := "zone=a-zone"
    82  	err := s.Env.PrecheckInstance(s.CallCtx, environs.PrecheckInstanceParams{Series: version.SupportedLTS(), Placement: placement})
    83  
    84  	c.Check(err, jc.ErrorIsNil)
    85  }
    86  
    87  func (s *environPolSuite) TestPrecheckInstanceAvailZoneUnavailable(c *gc.C) {
    88  	s.FakeConn.Zones = []google.AvailabilityZone{
    89  		google.NewZone("a-zone", google.StatusDown, "", ""),
    90  	}
    91  
    92  	placement := "zone=a-zone"
    93  	err := s.Env.PrecheckInstance(s.CallCtx, environs.PrecheckInstanceParams{Series: version.SupportedLTS(), Placement: placement})
    94  
    95  	c.Check(err, gc.ErrorMatches, `.*availability zone "a-zone" is DOWN`)
    96  }
    97  
    98  func (s *environPolSuite) TestPrecheckInstanceAvailZoneUnknown(c *gc.C) {
    99  	s.FakeConn.Zones = []google.AvailabilityZone{
   100  		google.NewZone("home-zone", google.StatusUp, "", ""),
   101  	}
   102  
   103  	placement := "zone=a-zone"
   104  	err := s.Env.PrecheckInstance(s.CallCtx, environs.PrecheckInstanceParams{Series: version.SupportedLTS(), Placement: placement})
   105  
   106  	c.Check(err, jc.Satisfies, errors.IsNotFound)
   107  }
   108  
   109  func (s *environPolSuite) TestPrecheckInstanceVolumeAvailZoneNoPlacement(c *gc.C) {
   110  	s.testPrecheckInstanceVolumeAvailZone(c, "")
   111  }
   112  
   113  func (s *environPolSuite) TestPrecheckInstanceVolumeAvailZoneSameZonePlacement(c *gc.C) {
   114  	s.testPrecheckInstanceVolumeAvailZone(c, "zone=away-zone")
   115  }
   116  
   117  func (s *environPolSuite) testPrecheckInstanceVolumeAvailZone(c *gc.C, placement string) {
   118  	s.FakeConn.Zones = []google.AvailabilityZone{
   119  		google.NewZone("away-zone", google.StatusUp, "", ""),
   120  	}
   121  
   122  	err := s.Env.PrecheckInstance(s.CallCtx, environs.PrecheckInstanceParams{
   123  		Series:    version.SupportedLTS(),
   124  		Placement: placement,
   125  		VolumeAttachments: []storage.VolumeAttachmentParams{{
   126  			VolumeId: "away-zone--c930380d-8337-4bf5-b07a-9dbb5ae771e4",
   127  		}},
   128  	})
   129  	c.Check(err, jc.ErrorIsNil)
   130  }
   131  
   132  func (s *environPolSuite) TestPrecheckInstanceAvailZoneConflictsVolume(c *gc.C) {
   133  	s.FakeConn.Zones = []google.AvailabilityZone{
   134  		google.NewZone("away-zone", google.StatusUp, "", ""),
   135  	}
   136  
   137  	err := s.Env.PrecheckInstance(s.CallCtx, environs.PrecheckInstanceParams{
   138  		Series:    version.SupportedLTS(),
   139  		Placement: "zone=away-zone",
   140  		VolumeAttachments: []storage.VolumeAttachmentParams{{
   141  			VolumeId: "home-zone--c930380d-8337-4bf5-b07a-9dbb5ae771e4",
   142  		}},
   143  	})
   144  
   145  	c.Check(err, gc.ErrorMatches, `cannot create instance with placement "zone=away-zone", as this will prevent attaching the requested disks in zone "home-zone"`)
   146  }
   147  
   148  func (s *environPolSuite) TestConstraintsValidator(c *gc.C) {
   149  	validator, err := s.Env.ConstraintsValidator(s.CallCtx)
   150  	c.Assert(err, jc.ErrorIsNil)
   151  
   152  	cons := constraints.MustParse("arch=amd64")
   153  	unsupported, err := validator.Validate(cons)
   154  	c.Assert(err, jc.ErrorIsNil)
   155  	c.Check(unsupported, gc.HasLen, 0)
   156  }
   157  
   158  func (s *environPolSuite) TestConstraintsValidatorEmpty(c *gc.C) {
   159  	validator, err := s.Env.ConstraintsValidator(s.CallCtx)
   160  	c.Assert(err, jc.ErrorIsNil)
   161  
   162  	unsupported, err := validator.Validate(constraints.Value{})
   163  	c.Assert(err, jc.ErrorIsNil)
   164  
   165  	c.Check(unsupported, gc.HasLen, 0)
   166  }
   167  
   168  func (s *environPolSuite) TestConstraintsValidatorUnsupported(c *gc.C) {
   169  	validator, err := s.Env.ConstraintsValidator(s.CallCtx)
   170  	c.Assert(err, jc.ErrorIsNil)
   171  
   172  	cons := constraints.MustParse("arch=amd64 tags=foo virt-type=kvm")
   173  	unsupported, err := validator.Validate(cons)
   174  	c.Assert(err, jc.ErrorIsNil)
   175  
   176  	c.Check(unsupported, jc.SameContents, []string{"tags", "virt-type"})
   177  }
   178  
   179  func (s *environPolSuite) TestConstraintsValidatorVocabInstType(c *gc.C) {
   180  	validator, err := s.Env.ConstraintsValidator(s.CallCtx)
   181  	c.Assert(err, jc.ErrorIsNil)
   182  
   183  	cons := constraints.MustParse("instance-type=foo")
   184  	_, err = validator.Validate(cons)
   185  
   186  	c.Check(err, gc.ErrorMatches, "invalid constraint value: instance-type=foo\nvalid values are:.*")
   187  }
   188  
   189  func (s *environPolSuite) TestConstraintsValidatorVocabContainer(c *gc.C) {
   190  	validator, err := s.Env.ConstraintsValidator(s.CallCtx)
   191  	c.Assert(err, jc.ErrorIsNil)
   192  
   193  	cons := constraints.MustParse("container=lxd")
   194  	_, err = validator.Validate(cons)
   195  
   196  	c.Check(err, gc.ErrorMatches, "invalid constraint value: container=lxd\nvalid values are:.*")
   197  }
   198  
   199  func (s *environPolSuite) TestConstraintsValidatorConflicts(c *gc.C) {
   200  	validator, err := s.Env.ConstraintsValidator(s.CallCtx)
   201  	c.Assert(err, jc.ErrorIsNil)
   202  
   203  	cons := constraints.MustParse("instance-type=n1-standard-1")
   204  	// We do not check arch or container since there is only one valid
   205  	// value for each and will always match.
   206  	consFallback := constraints.MustParse("cores=2 cpu-power=1000 mem=10000 tags=bar")
   207  	merged, err := validator.Merge(consFallback, cons)
   208  	c.Assert(err, jc.ErrorIsNil)
   209  
   210  	// tags is not supported, but we're not validating here...
   211  	expected := constraints.MustParse("instance-type=n1-standard-1 tags=bar")
   212  	c.Check(merged, jc.DeepEquals, expected)
   213  }
   214  
   215  func (s *environPolSuite) TestSupportNetworks(c *gc.C) {
   216  	isSupported := s.Env.SupportNetworks(s.CallCtx)
   217  
   218  	c.Check(isSupported, jc.IsFalse)
   219  }