blob: cd7a2b203e9e5007c085693ae21abb50d9340781 [file] [log] [blame]
Steve Bakerdd7c6ce2013-06-24 14:46:47 +12001# Licensed under the Apache License, Version 2.0 (the "License"); you may
2# not use this file except in compliance with the License. You may obtain
3# a copy of the License at
4#
5# http://www.apache.org/licenses/LICENSE-2.0
6#
7# Unless required by applicable law or agreed to in writing, software
8# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
9# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
10# License for the specific language governing permissions and limitations
11# under the License.
12
Steve Bakerdd9fb002013-09-30 11:35:18 +130013import heatclient.exc as heat_exceptions
Matthew Treinishf4418592013-09-09 20:59:23 +000014import time
15
Matthew Treinish6c072292014-01-29 19:15:52 +000016from tempest import config
Steve Bakerdd7c6ce2013-06-24 14:46:47 +120017from tempest.scenario import manager
18from tempest.test import attr
19from tempest.test import call_until_true
Matthew Treinish2153ec02013-09-09 20:57:30 +000020from tempest.test import services
Steve Bakerace4e6d2013-12-04 15:56:45 +130021from tempest.test import skip_because
Steve Bakerdd7c6ce2013-06-24 14:46:47 +120022
Matthew Treinish6c072292014-01-29 19:15:52 +000023CONF = config.CONF
24
Steve Bakerdd7c6ce2013-06-24 14:46:47 +120025
Steve Bakerdd7c6ce2013-06-24 14:46:47 +120026class AutoScalingTest(manager.OrchestrationScenarioTest):
27
28 def setUp(self):
29 super(AutoScalingTest, self).setUp()
Matthew Treinish6c072292014-01-29 19:15:52 +000030 if not CONF.orchestration.image_ref:
Steve Bakerdd7c6ce2013-06-24 14:46:47 +120031 raise self.skipException("No image available to test")
32 self.client = self.orchestration_client
33
34 def assign_keypair(self):
35 self.stack_name = self._stack_rand_name()
Matthew Treinish6c072292014-01-29 19:15:52 +000036 if CONF.orchestration.keypair_name:
37 self.keypair_name = CONF.orchestration.keypair_name
Steve Bakerdd7c6ce2013-06-24 14:46:47 +120038 else:
Ken'ichi Ohmichi8ca06252013-08-23 22:36:17 +090039 self.keypair = self.create_keypair()
Steve Bakerdd7c6ce2013-06-24 14:46:47 +120040 self.keypair_name = self.keypair.id
Steve Bakerdd7c6ce2013-06-24 14:46:47 +120041
42 def launch_stack(self):
Steve Baker80252da2013-09-25 13:29:10 +120043 net = self._get_default_network()
Steve Bakerdd7c6ce2013-06-24 14:46:47 +120044 self.parameters = {
45 'KeyName': self.keypair_name,
Matthew Treinish6c072292014-01-29 19:15:52 +000046 'InstanceType': CONF.orchestration.instance_type,
47 'ImageId': CONF.orchestration.image_ref,
Steve Baker80252da2013-09-25 13:29:10 +120048 'StackStart': str(time.time()),
49 'Subnet': net['subnets'][0]
Steve Bakerdd7c6ce2013-06-24 14:46:47 +120050 }
51
52 # create the stack
53 self.template = self._load_template(__file__, 'test_autoscaling.yaml')
54 self.client.stacks.create(
55 stack_name=self.stack_name,
56 template=self.template,
57 parameters=self.parameters)
58
59 self.stack = self.client.stacks.get(self.stack_name)
60 self.stack_identifier = '%s/%s' % (self.stack_name, self.stack.id)
61
62 # if a keypair was set, do not delete the stack on exit to allow
63 # for manual post-mortums
Matthew Treinish6c072292014-01-29 19:15:52 +000064 if not CONF.orchestration.keypair_name:
Steve Bakerdd7c6ce2013-06-24 14:46:47 +120065 self.set_resource('stack', self.stack)
66
Steve Bakerace4e6d2013-12-04 15:56:45 +130067 @skip_because(bug="1257575")
Steve Bakerdd7c6ce2013-06-24 14:46:47 +120068 @attr(type='slow')
Matthew Treinish2153ec02013-09-09 20:57:30 +000069 @services('orchestration', 'compute')
Steve Bakerdd7c6ce2013-06-24 14:46:47 +120070 def test_scale_up_then_down(self):
71
72 self.assign_keypair()
73 self.launch_stack()
74
75 sid = self.stack_identifier
Matthew Treinish6c072292014-01-29 19:15:52 +000076 timeout = CONF.orchestration.build_timeout
Steve Bakerdd7c6ce2013-06-24 14:46:47 +120077 interval = 10
78
79 self.assertEqual('CREATE', self.stack.action)
80 # wait for create to complete.
Steve Bakerdd9fb002013-09-30 11:35:18 +130081 self.status_timeout(self.client.stacks, sid, 'COMPLETE',
82 error_status='FAILED')
Steve Bakerdd7c6ce2013-06-24 14:46:47 +120083
84 self.stack.get()
85 self.assertEqual('CREATE_COMPLETE', self.stack.stack_status)
86
87 # the resource SmokeServerGroup is implemented as a nested
88 # stack, so servers can be counted by counting the resources
89 # inside that nested stack
90 resource = self.client.resources.get(sid, 'SmokeServerGroup')
91 nested_stack_id = resource.physical_resource_id
92
93 def server_count():
94 # the number of servers is the number of resources
Chang Bo Guocc1623c2013-09-13 20:11:27 -070095 # in the nested stack
Steve Bakerdd7c6ce2013-06-24 14:46:47 +120096 self.server_count = len(
97 self.client.resources.list(nested_stack_id))
98 return self.server_count
99
100 def assertScale(from_servers, to_servers):
101 call_until_true(lambda: server_count() == to_servers,
102 timeout, interval)
103 self.assertEqual(to_servers, self.server_count,
Steve Bakerdd9fb002013-09-30 11:35:18 +1300104 'Failed scaling from %d to %d servers. '
105 'Current server count: %s' % (
106 from_servers, to_servers,
107 self.server_count))
Steve Bakerdd7c6ce2013-06-24 14:46:47 +1200108
109 # he marched them up to the top of the hill
110 assertScale(1, 2)
111 assertScale(2, 3)
112
113 # and he marched them down again
114 assertScale(3, 2)
115 assertScale(2, 1)
Steve Bakerdd9fb002013-09-30 11:35:18 +1300116
117 # delete stack on completion
118 self.stack.delete()
119 self.status_timeout(self.client.stacks, sid, 'COMPLETE',
120 error_status='FAILED',
121 not_found_exception=heat_exceptions.NotFound)
122
123 try:
124 self.stack.get()
125 self.assertEqual('DELETE_COMPLETE', self.stack.stack_status)
126 except heat_exceptions.NotFound:
127 pass