@@ -4563,21 +4563,144 @@ def test_create_instance_name_all_blank_spaces(self):
45634563 self .assertRaises (exception .ValidationError ,
45644564 self .controller .create , req , body = body )
45654565
4566- def test_create_az_with_leading_trailing_spaces (self ):
4566+ def test_create_instance_az_with_leading_trailing_spaces (self ):
45674567 self .body ['server' ]['availability_zone' ] = ' zone1 '
45684568 self .req .body = jsonutils .dump_as_bytes (self .body )
45694569 self .assertRaises (exception .ValidationError ,
45704570 self .controller .create , self .req , body = self .body )
45714571
4572- def test_create_az_with_leading_trailing_spaces_in_compat_mode (
4573- self ):
4572+ def test_create_instance_az_with_leading_trailing_spaces_compat_mode (self ):
45744573 self .body ['server' ]['name' ] = ' abc def '
4575- self .body ['server' ]['availability_zones ' ] = ' zone1 '
4574+ self .body ['server' ]['availability_zone ' ] = ' zone1 '
45764575 self .req .body = jsonutils .dump_as_bytes (self .body )
45774576 self .req .set_legacy_v2 ()
4578- with mock .patch .object (availability_zones , 'get_availability_zones' ,
4579- return_value = [' zone1 ' ]):
4577+ with mock .patch .object (
4578+ availability_zones , 'get_availability_zones' ,
4579+ return_value = [' zone1 ' ],
4580+ ) as mock_get_azs :
45804581 self .controller .create (self .req , body = self .body )
4582+ mock_get_azs .assert_called_once ()
4583+
4584+ def test_create_instance_invalid_az (self ):
4585+ self .body ['server' ]['availability_zone' ] = 'zone1'
4586+ self .req .body = jsonutils .dump_as_bytes (self .body )
4587+ with mock .patch .object (
4588+ availability_zones , 'get_availability_zones' ,
4589+ return_value = ['zone2' ],
4590+ ) as mock_get_azs :
4591+ self .assertRaises (
4592+ webob .exc .HTTPBadRequest ,
4593+ self .controller .create ,
4594+ self .req , body = self .body )
4595+ mock_get_azs .assert_called_once ()
4596+
4597+ @mock .patch .object (objects .AggregateList , 'get_by_host' )
4598+ @mock .patch .object (servers , 'LOG' )
4599+ def test_create_instance_az_host (self , mock_log , mock_get_host_aggs ):
4600+ """Ensure we handle az:host format for 'availability_zone'."""
4601+ mock_get_host_aggs .return_value = objects .AggregateList (
4602+ objects = [
4603+ objects .Aggregate (metadata = {'availability_zone' : 'zone1' }),
4604+ ],
4605+ )
4606+
4607+ self .body ['server' ]['availability_zone' ] = 'zone1:host1'
4608+ self .req .body = jsonutils .dump_as_bytes (self .body )
4609+
4610+ self .controller .create (self .req , body = self .body )
4611+
4612+ mock_get_host_aggs .assert_called_once ()
4613+ mock_log .warning .assert_not_called ()
4614+
4615+ @mock .patch .object (objects .AggregateList , 'get_by_host' )
4616+ @mock .patch .object (servers , 'LOG' )
4617+ def test_create_instance_az_host_mismatch_without_aggs (
4618+ self , mock_log , mock_get_host_aggs ,
4619+ ):
4620+ """User requests an AZ but the host doesn't have one"""
4621+ mock_get_host_aggs .return_value = objects .AggregateList (objects = [])
4622+
4623+ self .body ['server' ]['availability_zone' ] = 'zone1:host1'
4624+ self .req .body = jsonutils .dump_as_bytes (self .body )
4625+
4626+ self .controller .create (self .req , body = self .body )
4627+
4628+ mock_get_host_aggs .assert_called_once ()
4629+ # we should see a log since the host doesn't belong to the requested AZ
4630+ self .assertIn ('bug #1934770' , mock_log .warning .call_args [0 ][0 ])
4631+
4632+ @mock .patch .object (objects .AggregateList , 'get_by_host' )
4633+ @mock .patch .object (servers , 'LOG' )
4634+ def test_create_instance_az_host_mismatch_without_aggs_in_default_az (
4635+ self , mock_log , mock_get_host_aggs ,
4636+ ):
4637+ """User requests the default AZ and host isn't in any explicit AZ"""
4638+ self .flags (default_availability_zone = 'zone1' )
4639+ mock_get_host_aggs .return_value = objects .AggregateList (objects = [])
4640+
4641+ self .body ['server' ]['availability_zone' ] = 'zone1:host1'
4642+ self .req .body = jsonutils .dump_as_bytes (self .body )
4643+
4644+ self .controller .create (self .req , body = self .body )
4645+
4646+ mock_get_host_aggs .assert_called_once ()
4647+ # we shouldn't see a log since the host is not in any aggregate and
4648+ # therefore is in the default AZ
4649+ mock_log .warning .assert_not_called ()
4650+
4651+ @mock .patch .object (objects .AggregateList , 'get_by_host' )
4652+ @mock .patch .object (servers , 'LOG' )
4653+ def test_create_instance_az_host_mismatch_with_aggs (
4654+ self , mock_log , mock_get_host_aggs ,
4655+ ):
4656+ """User requests an AZ but the host has a different one."""
4657+ mock_get_host_aggs .return_value = objects .AggregateList (
4658+ objects = [
4659+ objects .Aggregate (metadata = {'availability_zone' : 'zone2' }),
4660+ ],
4661+ )
4662+
4663+ self .body ['server' ]['availability_zone' ] = 'zone1:host1'
4664+ self .req .body = jsonutils .dump_as_bytes (self .body )
4665+
4666+ self .controller .create (self .req , body = self .body )
4667+
4668+ mock_get_host_aggs .assert_called_once ()
4669+ # we should see a log since the host belongs to a different AZ
4670+ self .assertIn ('bug #1934770' , mock_log .warning .call_args [0 ][0 ])
4671+
4672+ @mock .patch .object (objects .AggregateList , 'get_by_host' )
4673+ @mock .patch .object (servers , 'LOG' )
4674+ def test_create_instance_az_host_mismatch_with_aggs_in_default_az (
4675+ self , mock_log , mock_get_host_aggs ,
4676+ ):
4677+ """User requests the default AZ and host is in aggregates without AZ"""
4678+ self .flags (default_availability_zone = 'zone1' )
4679+ mock_get_host_aggs .return_value = objects .AggregateList (
4680+ objects = [objects .Aggregate (metadata = {})],
4681+ )
4682+
4683+ self .body ['server' ]['availability_zone' ] = 'zone1:host1'
4684+ self .req .body = jsonutils .dump_as_bytes (self .body )
4685+
4686+ self .controller .create (self .req , body = self .body )
4687+
4688+ mock_get_host_aggs .assert_called_once ()
4689+ # we shouldn't see a log since none of the host aggregates have an
4690+ # explicit AZ set and the host is therefore in the default AZ
4691+ mock_log .warning .assert_not_called ()
4692+
4693+ def test_create_instance_invalid_az_format (self ):
4694+ self .body ['server' ]['availability_zone' ] = 'invalid::::zone'
4695+ self .assertRaises (webob .exc .HTTPBadRequest ,
4696+ self .controller .create ,
4697+ self .req , body = self .body )
4698+
4699+ def test_create_instance_invalid_az_as_int (self ):
4700+ self .body ['server' ]['availability_zone' ] = 123
4701+ self .assertRaises (exception .ValidationError ,
4702+ self .controller .create ,
4703+ self .req , body = self .body )
45814704
45824705 def test_create_instance (self ):
45834706 self .stub_out ('uuid.uuid4' , lambda : FAKE_UUID )
@@ -6181,18 +6304,6 @@ def test_create_instance_raise_image_bad_request(self, mock_create):
61816304 self .controller .create ,
61826305 self .req , body = self .body )
61836306
6184- def test_create_instance_invalid_availability_zone (self ):
6185- self .body ['server' ]['availability_zone' ] = 'invalid::::zone'
6186- self .assertRaises (webob .exc .HTTPBadRequest ,
6187- self .controller .create ,
6188- self .req , body = self .body )
6189-
6190- def test_create_instance_invalid_availability_zone_as_int (self ):
6191- self .body ['server' ]['availability_zone' ] = 123
6192- self .assertRaises (exception .ValidationError ,
6193- self .controller .create ,
6194- self .req , body = self .body )
6195-
61966307 @mock .patch .object (compute_api .API , 'create' ,
61976308 side_effect = exception .FixedIpNotFoundForAddress (
61986309 address = 'dummy' ))
0 commit comments