| # vim: tabstop=4 shiftwidth=4 softtabstop=4 |
| |
| # Licensed under the Apache License, Version 2.0 (the "License"); |
| # you may not use this file except in compliance with the License. |
| # You may obtain a copy of the License at |
| # |
| # http://www.apache.org/licenses/LICENSE-2.0 |
| # |
| # Unless required by applicable law or agreed to in writing, software |
| # distributed under the License is distributed on an "AS IS" BASIS, |
| # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| # See the License for the specific language governing permissions and |
| # limitations under the License. |
| |
| import socket |
| import subprocess |
| |
| from tempest.common.utils.data_utils import rand_name |
| import tempest.stress.stressaction as stressaction |
| import tempest.test |
| |
| |
| class FloatingStress(stressaction.StressAction): |
| |
| # from the scenario manager |
| def ping_ip_address(self, ip_address): |
| cmd = ['ping', '-c1', '-w1', ip_address] |
| |
| proc = subprocess.Popen(cmd, |
| stdout=subprocess.PIPE, |
| stderr=subprocess.PIPE) |
| proc.wait() |
| success = proc.returncode == 0 |
| self.logger.info("%s(%s): %s", self.server_id, self.floating['ip'], |
| "pong!" if success else "no pong :(") |
| return success |
| |
| def tcp_connect_scan(self, addr, port): |
| # like tcp |
| s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) |
| try: |
| s.connect((addr, port)) |
| except socket.error as exc: |
| self.logger.info("%s(%s): %s", self.server_id, self.floating['ip'], |
| str(exc)) |
| return False |
| self.logger.info("%s(%s): Connected :)", self.server_id, |
| self.floating['ip']) |
| s.close() |
| return True |
| |
| def check_port_ssh(self): |
| def func(): |
| return self.tcp_connect_scan(self.floating['ip'], 22) |
| if not tempest.test.call_until_true(func, self.check_timeout, |
| self.check_interval): |
| raise RuntimeError("Cannot connect to the ssh port.") |
| |
| def check_icmp_echo(self): |
| def func(): |
| return self.ping_ip_address(self.floating['ip']) |
| if not tempest.test.call_until_true(func, self.check_timeout, |
| self.check_interval): |
| raise RuntimeError("Cannot ping the machine.") |
| |
| def _create_vm(self): |
| self.name = name = rand_name("instance") |
| servers_client = self.manager.servers_client |
| self.logger.info("creating %s" % name) |
| vm_args = self.vm_extra_args.copy() |
| vm_args['security_groups'] = [{'name': self.sec_grp}] |
| resp, server = servers_client.create_server(name, self.image, |
| self.flavor, |
| **vm_args) |
| self.server_id = server['id'] |
| assert(resp.status == 202) |
| if self.wait_after_vm_create: |
| self.manager.servers_client.wait_for_server_status(self.server_id, |
| 'ACTIVE') |
| |
| def _destroy_vm(self): |
| self.logger.info("deleting %s" % self.server_id) |
| resp, _ = self.manager.servers_client.delete_server(self.server_id) |
| assert(resp.status == 204) # It cannot be 204 if I had to wait.. |
| self.manager.servers_client.wait_for_server_termination(self.server_id) |
| self.logger.info("deleted %s" % self.server_id) |
| |
| def _create_sec_group(self): |
| sec_grp_cli = self.manager.security_groups_client |
| s_name = rand_name('sec_grp-') |
| s_description = rand_name('desc-') |
| _, _sec_grp = sec_grp_cli.create_security_group(s_name, |
| s_description) |
| self.sec_grp = _sec_grp['id'] |
| create_rule = sec_grp_cli.create_security_group_rule |
| create_rule(self.sec_grp, 'tcp', 22, 22) |
| create_rule(self.sec_grp, 'icmp', -1, -1) |
| |
| def _destroy_sec_grp(self): |
| sec_grp_cli = self.manager.security_groups_client |
| sec_grp_cli.delete_security_group(self.sec_grp) |
| |
| def _create_floating_ip(self): |
| floating_cli = self.manager.floating_ips_client |
| _, self.floating = floating_cli.create_floating_ip(self.floating_pool) |
| |
| def _destroy_floating_ip(self): |
| cli = self.manager.floating_ips_client |
| cli.delete_floating_ip(self.floating['id']) |
| cli.wait_for_resource_deletion(self.floating['id']) |
| self.logger.info("Deleted Floating IP %s", str(self.floating['ip'])) |
| |
| def setUp(self, **kwargs): |
| self.image = self.manager.config.compute.image_ref |
| self.flavor = self.manager.config.compute.flavor_ref |
| self.vm_extra_args = kwargs.get('vm_extra_args', {}) |
| self.wait_after_vm_create = kwargs.get('wait_after_vm_create', |
| True) |
| self.new_vm = kwargs.get('new_vm', False) |
| self.new_sec_grp = kwargs.get('new_sec_group', False) |
| self.new_floating = kwargs.get('new_floating', False) |
| self.reboot = kwargs.get('reboot', False) |
| self.floating_pool = kwargs.get('floating_pool', None) |
| self.verify = kwargs.get('verify', ('check_port_ssh', |
| 'check_icmp_echo')) |
| self.check_timeout = kwargs.get('check_timeout', 120) |
| self.check_interval = kwargs.get('check_interval', 1) |
| self.wait_for_disassociate = kwargs.get('wait_for_disassociate', |
| True) |
| |
| # allocate floating |
| if not self.new_floating: |
| self._create_floating_ip() |
| # add security group |
| if not self.new_sec_grp: |
| self._create_sec_group() |
| # create vm |
| if not self.new_vm: |
| self._create_vm() |
| |
| def wait_disassociate(self): |
| cli = self.manager.floating_ips_client |
| |
| def func(): |
| _, floating = cli.get_floating_ip_details(self.floating['id']) |
| return floating['instance_id'] is None |
| |
| if not tempest.test.call_until_true(func, self.check_timeout, |
| self.check_interval): |
| raise RuntimeError("IP disassociate timeout!") |
| |
| def run_core(self): |
| cli = self.manager.floating_ips_client |
| cli.associate_floating_ip_to_server(self.floating['ip'], |
| self.server_id) |
| for method in self.verify: |
| m = getattr(self, method) |
| m() |
| cli.disassociate_floating_ip_from_server(self.floating['ip'], |
| self.server_id) |
| if self.wait_for_disassociate: |
| self.wait_disassociate() |
| |
| def run(self): |
| if self.new_sec_grp: |
| self._create_sec_group() |
| if self.new_floating: |
| self._create_floating_ip() |
| if self.new_vm: |
| self._create_vm() |
| if self.reboot: |
| self.manager.servers_client.reboot(self.server_id, 'HARD') |
| |
| self.run_core() |
| |
| if self.new_vm: |
| self._destroy_vm() |
| if self.new_floating: |
| self._destroy_floating_ip() |
| if self.new_sec_grp: |
| self._destroy_sec_grp() |
| |
| def tearDown(self): |
| if not self.new_vm: |
| self._destroy_vm() |
| if not self.new_floating: |
| self._destroy_floating_ip() |
| if not self.new_sec_grp: |
| self._destroy_sec_grp() |