github.com/juju/juju@v0.0.0-20240430160146-1752b71fcf00/provider/gce/environ_availzones_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  	jc "github.com/juju/testing/checkers"
     8  	gc "gopkg.in/check.v1"
     9  
    10  	"github.com/juju/juju/core/instance"
    11  	"github.com/juju/juju/environs/instances"
    12  	"github.com/juju/juju/provider/gce"
    13  	"github.com/juju/juju/provider/gce/google"
    14  	"github.com/juju/juju/storage"
    15  )
    16  
    17  type environAZSuite struct {
    18  	gce.BaseSuite
    19  }
    20  
    21  var _ = gc.Suite(&environAZSuite{})
    22  
    23  func (s *environAZSuite) TestAvailabilityZonesInvalidCredentialError(c *gc.C) {
    24  	s.FakeConn.Err = gce.InvalidCredentialError
    25  	c.Assert(s.InvalidatedCredentials, jc.IsFalse)
    26  	_, err := s.Env.AvailabilityZones(s.CallCtx)
    27  	c.Check(err, gc.NotNil)
    28  	c.Assert(s.InvalidatedCredentials, jc.IsTrue)
    29  }
    30  
    31  func (s *environAZSuite) TestAvailabilityZones(c *gc.C) {
    32  	s.FakeConn.Zones = []google.AvailabilityZone{
    33  		google.NewZone("a-zone", google.StatusUp, "", ""),
    34  		google.NewZone("b-zone", google.StatusUp, "", ""),
    35  	}
    36  
    37  	zones, err := s.Env.AvailabilityZones(s.CallCtx)
    38  	c.Assert(err, jc.ErrorIsNil)
    39  
    40  	c.Check(zones, gc.HasLen, 2)
    41  	c.Check(zones[0].Name(), gc.Equals, "a-zone")
    42  	c.Check(zones[0].Available(), jc.IsTrue)
    43  	c.Check(zones[1].Name(), gc.Equals, "b-zone")
    44  	c.Check(zones[1].Available(), jc.IsTrue)
    45  }
    46  
    47  func (s *environAZSuite) TestAvailabilityZonesDeprecated(c *gc.C) {
    48  	zone := google.NewZone("a-zone", google.StatusUp, "DEPRECATED", "b-zone")
    49  
    50  	c.Check(zone.Deprecated(), jc.IsTrue)
    51  }
    52  
    53  func (s *environAZSuite) TestAvailabilityZonesAPI(c *gc.C) {
    54  	s.FakeConn.Zones = []google.AvailabilityZone{}
    55  
    56  	_, err := s.Env.AvailabilityZones(s.CallCtx)
    57  	c.Assert(err, jc.ErrorIsNil)
    58  
    59  	c.Check(s.FakeConn.Calls, gc.HasLen, 1)
    60  	c.Check(s.FakeConn.Calls[0].FuncName, gc.Equals, "AvailabilityZones")
    61  	c.Check(s.FakeConn.Calls[0].Region, gc.Equals, "us-east1")
    62  }
    63  
    64  func (s *environAZSuite) TestInstanceAvailabilityZoneNames(c *gc.C) {
    65  	s.FakeEnviron.Insts = []instances.Instance{s.Instance}
    66  
    67  	id := instance.Id("spam")
    68  	ids := []instance.Id{id}
    69  	zones, err := s.Env.InstanceAvailabilityZoneNames(s.CallCtx, ids)
    70  	c.Assert(err, jc.ErrorIsNil)
    71  
    72  	c.Check(zones, jc.DeepEquals, map[instance.Id]string{
    73  		id: "home-zone",
    74  	})
    75  }
    76  
    77  func (s *environAZSuite) TestInstanceAvailabilityZoneNamesAPIs(c *gc.C) {
    78  	s.FakeEnviron.Insts = []instances.Instance{s.Instance}
    79  
    80  	ids := []instance.Id{instance.Id("spam")}
    81  	_, err := s.Env.InstanceAvailabilityZoneNames(s.CallCtx, ids)
    82  	c.Assert(err, jc.ErrorIsNil)
    83  
    84  	s.FakeEnviron.CheckCalls(c, []gce.FakeCall{{
    85  		FuncName: "GetInstances", Args: gce.FakeCallArgs{"switch": s.Env},
    86  	}})
    87  }
    88  
    89  func (s *environAZSuite) TestDeriveAvailabilityZonesInvalidCredentialError(c *gc.C) {
    90  	s.StartInstArgs.Placement = "zone=test-available"
    91  	s.FakeConn.Err = gce.InvalidCredentialError
    92  	c.Assert(s.InvalidatedCredentials, jc.IsFalse)
    93  	_, err := s.Env.DeriveAvailabilityZones(s.CallCtx, s.StartInstArgs)
    94  	c.Check(err, gc.NotNil)
    95  	c.Assert(s.InvalidatedCredentials, jc.IsTrue)
    96  }
    97  
    98  func (s *environAZSuite) TestDeriveAvailabilityZones(c *gc.C) {
    99  	s.StartInstArgs.Placement = "zone=test-available"
   100  	s.FakeConn.Zones = []google.AvailabilityZone{
   101  		google.NewZone("test-available", google.StatusUp, "", ""),
   102  	}
   103  	zones, err := s.Env.DeriveAvailabilityZones(s.CallCtx, s.StartInstArgs)
   104  	c.Assert(err, jc.ErrorIsNil)
   105  	c.Assert(zones, gc.DeepEquals, []string{"test-available"})
   106  }
   107  
   108  func (s *environAZSuite) TestDeriveAvailabilityZonesVolumeNoPlacement(c *gc.C) {
   109  	s.FakeConn.Zones = []google.AvailabilityZone{
   110  		google.NewZone("az1", google.StatusDown, "", ""),
   111  		google.NewZone("az2", google.StatusUp, "", ""),
   112  	}
   113  	s.StartInstArgs.VolumeAttachments = []storage.VolumeAttachmentParams{{
   114  		VolumeId: "az2--c930380d-8337-4bf5-b07a-9dbb5ae771e4",
   115  	}}
   116  	zones, err := s.Env.DeriveAvailabilityZones(s.CallCtx, s.StartInstArgs)
   117  	c.Assert(err, jc.ErrorIsNil)
   118  	c.Assert(zones, gc.DeepEquals, []string{"az2"})
   119  }
   120  
   121  func (s *environAZSuite) TestDeriveAvailabilityZonesUnavailable(c *gc.C) {
   122  	s.StartInstArgs.Placement = "zone=test-unavailable"
   123  	s.FakeConn.Zones = []google.AvailabilityZone{
   124  		google.NewZone("test-unavailable", google.StatusDown, "", ""),
   125  	}
   126  	zones, err := s.Env.DeriveAvailabilityZones(s.CallCtx, s.StartInstArgs)
   127  	c.Check(err, gc.ErrorMatches, `.*availability zone "test-unavailable" is DOWN`)
   128  	c.Assert(zones, gc.HasLen, 0)
   129  }
   130  
   131  func (s *environAZSuite) TestDeriveAvailabilityZonesUnknown(c *gc.C) {
   132  	s.StartInstArgs.Placement = "zone=test-unknown"
   133  	zones, err := s.Env.DeriveAvailabilityZones(s.CallCtx, s.StartInstArgs)
   134  	c.Assert(err, gc.ErrorMatches, `invalid availability zone "test-unknown" not found`)
   135  	c.Assert(zones, gc.HasLen, 0)
   136  }
   137  
   138  func (s *environAZSuite) TestDeriveAvailabilityZonesConflictsVolume(c *gc.C) {
   139  	s.FakeConn.Zones = []google.AvailabilityZone{
   140  		google.NewZone("az1", google.StatusUp, "", ""),
   141  		google.NewZone("az2", google.StatusUp, "", ""),
   142  	}
   143  	s.StartInstArgs.Placement = "zone=az1"
   144  	s.StartInstArgs.VolumeAttachments = []storage.VolumeAttachmentParams{{
   145  		VolumeId: "az2--c930380d-8337-4bf5-b07a-9dbb5ae771e4",
   146  	}}
   147  	zones, err := s.Env.DeriveAvailabilityZones(s.CallCtx, s.StartInstArgs)
   148  	c.Assert(err, gc.ErrorMatches, `cannot create instance with placement "zone=az1": cannot create instance in zone "az1", as this will prevent attaching the requested disks in zone "az2"`)
   149  	c.Assert(zones, gc.HasLen, 0)
   150  }
   151  
   152  func (s *environAZSuite) TestDeriveAvailabilityZonesVolumeAttachments(c *gc.C) {
   153  	s.StartInstArgs.VolumeAttachments = []storage.VolumeAttachmentParams{{
   154  		VolumeId: "home-zone--c930380d-8337-4bf5-b07a-9dbb5ae771e4",
   155  	}}
   156  
   157  	zones, err := s.Env.DeriveAvailabilityZones(s.CallCtx, s.StartInstArgs)
   158  	c.Assert(err, jc.ErrorIsNil)
   159  	c.Assert(zones, gc.DeepEquals, []string{"home-zone"})
   160  }
   161  
   162  func (s *environAZSuite) TestDeriveAvailabilityZonesVolumeAttachmentsDifferentZones(c *gc.C) {
   163  	s.StartInstArgs.VolumeAttachments = []storage.VolumeAttachmentParams{{
   164  		VolumeId: "home-zone--c930380d-8337-4bf5-b07a-9dbb5ae771e4",
   165  	}, {
   166  		VolumeId: "away-zone--c930380d-8337-4bf5-b07a-9dbb5ae771e4",
   167  	}}
   168  
   169  	_, err := s.Env.DeriveAvailabilityZones(s.CallCtx, s.StartInstArgs)
   170  	c.Assert(err, gc.ErrorMatches, `cannot attach volumes from multiple availability zones: home-zone--c930380d-8337-4bf5-b07a-9dbb5ae771e4 is in home-zone, away-zone--c930380d-8337-4bf5-b07a-9dbb5ae771e4 is in away-zone`)
   171  }