blob: 90ef3a0ed6aa1d40ad01ab4b8086238a934014a1 [file] [log] [blame]
Steve Bakerdd7c6ce2013-06-24 14:46:47 +12001# vim: tabstop=4 shiftwidth=4 softtabstop=4
2
3# Licensed under the Apache License, Version 2.0 (the "License"); you may
4# not use this file except in compliance with the License. You may obtain
5# a copy of the License at
6#
7# http://www.apache.org/licenses/LICENSE-2.0
8#
9# Unless required by applicable law or agreed to in writing, software
10# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12# License for the specific language governing permissions and limitations
13# under the License.
14
Steve Bakerdd9fb002013-09-30 11:35:18 +130015import heatclient.exc as heat_exceptions
Matthew Treinishf4418592013-09-09 20:59:23 +000016import time
17
Steve Bakerdd7c6ce2013-06-24 14:46:47 +120018from tempest.scenario import manager
19from tempest.test import attr
20from tempest.test import call_until_true
Matthew Treinish2153ec02013-09-09 20:57:30 +000021from tempest.test import services
Steve Bakerace4e6d2013-12-04 15:56:45 +130022from tempest.test import skip_because
Steve Bakerdd7c6ce2013-06-24 14:46:47 +120023
24
Steve Bakerdd7c6ce2013-06-24 14:46:47 +120025class AutoScalingTest(manager.OrchestrationScenarioTest):
26
27 def setUp(self):
28 super(AutoScalingTest, self).setUp()
29 if not self.config.orchestration.image_ref:
30 raise self.skipException("No image available to test")
31 self.client = self.orchestration_client
32
33 def assign_keypair(self):
34 self.stack_name = self._stack_rand_name()
35 if self.config.orchestration.keypair_name:
36 self.keypair_name = self.config.orchestration.keypair_name
37 else:
Ken'ichi Ohmichi8ca06252013-08-23 22:36:17 +090038 self.keypair = self.create_keypair()
Steve Bakerdd7c6ce2013-06-24 14:46:47 +120039 self.keypair_name = self.keypair.id
Steve Bakerdd7c6ce2013-06-24 14:46:47 +120040
41 def launch_stack(self):
Steve Baker80252da2013-09-25 13:29:10 +120042 net = self._get_default_network()
Steve Bakerdd7c6ce2013-06-24 14:46:47 +120043 self.parameters = {
44 'KeyName': self.keypair_name,
45 'InstanceType': self.config.orchestration.instance_type,
46 'ImageId': self.config.orchestration.image_ref,
Steve Baker80252da2013-09-25 13:29:10 +120047 'StackStart': str(time.time()),
48 'Subnet': net['subnets'][0]
Steve Bakerdd7c6ce2013-06-24 14:46:47 +120049 }
50
51 # create the stack
52 self.template = self._load_template(__file__, 'test_autoscaling.yaml')
53 self.client.stacks.create(
54 stack_name=self.stack_name,
55 template=self.template,
56 parameters=self.parameters)
57
58 self.stack = self.client.stacks.get(self.stack_name)
59 self.stack_identifier = '%s/%s' % (self.stack_name, self.stack.id)
60
61 # if a keypair was set, do not delete the stack on exit to allow
62 # for manual post-mortums
63 if not self.config.orchestration.keypair_name:
64 self.set_resource('stack', self.stack)
65
Steve Bakerace4e6d2013-12-04 15:56:45 +130066 @skip_because(bug="1257575")
Steve Bakerdd7c6ce2013-06-24 14:46:47 +120067 @attr(type='slow')
Matthew Treinish2153ec02013-09-09 20:57:30 +000068 @services('orchestration', 'compute')
Steve Bakerdd7c6ce2013-06-24 14:46:47 +120069 def test_scale_up_then_down(self):
70
71 self.assign_keypair()
72 self.launch_stack()
73
74 sid = self.stack_identifier
75 timeout = self.config.orchestration.build_timeout
76 interval = 10
77
78 self.assertEqual('CREATE', self.stack.action)
79 # wait for create to complete.
Steve Bakerdd9fb002013-09-30 11:35:18 +130080 self.status_timeout(self.client.stacks, sid, 'COMPLETE',
81 error_status='FAILED')
Steve Bakerdd7c6ce2013-06-24 14:46:47 +120082
83 self.stack.get()
84 self.assertEqual('CREATE_COMPLETE', self.stack.stack_status)
85
86 # the resource SmokeServerGroup is implemented as a nested
87 # stack, so servers can be counted by counting the resources
88 # inside that nested stack
89 resource = self.client.resources.get(sid, 'SmokeServerGroup')
90 nested_stack_id = resource.physical_resource_id
91
92 def server_count():
93 # the number of servers is the number of resources
Chang Bo Guocc1623c2013-09-13 20:11:27 -070094 # in the nested stack
Steve Bakerdd7c6ce2013-06-24 14:46:47 +120095 self.server_count = len(
96 self.client.resources.list(nested_stack_id))
97 return self.server_count
98
99 def assertScale(from_servers, to_servers):
100 call_until_true(lambda: server_count() == to_servers,
101 timeout, interval)
102 self.assertEqual(to_servers, self.server_count,
Steve Bakerdd9fb002013-09-30 11:35:18 +1300103 'Failed scaling from %d to %d servers. '
104 'Current server count: %s' % (
105 from_servers, to_servers,
106 self.server_count))
Steve Bakerdd7c6ce2013-06-24 14:46:47 +1200107
108 # he marched them up to the top of the hill
109 assertScale(1, 2)
110 assertScale(2, 3)
111
112 # and he marched them down again
113 assertScale(3, 2)
114 assertScale(2, 1)
Steve Bakerdd9fb002013-09-30 11:35:18 +1300115
116 # delete stack on completion
117 self.stack.delete()
118 self.status_timeout(self.client.stacks, sid, 'COMPLETE',
119 error_status='FAILED',
120 not_found_exception=heat_exceptions.NotFound)
121
122 try:
123 self.stack.get()
124 self.assertEqual('DELETE_COMPLETE', self.stack.stack_status)
125 except heat_exceptions.NotFound:
126 pass