From c17ed78948a2b08384ba82f084f5b1366eca4e24 Mon Sep 17 00:00:00 2001 From: Bartek Grzybowski Date: Wed, 3 Jun 2020 11:46:51 +0200 Subject: [PATCH] Drop shell wrapper for stopping simulator instances Instance method is added to manage stopping simulator instances and ROP scripts directly in MassPnfSim class. Change-Id: Ic551f99c0f5f2a177b9c72daac02690b0bbded04 Issue-ID: INT-1610 Signed-off-by: Bartek Grzybowski --- test/mocks/mass-pnf-sim/MassPnfSim.py | 40 ++++++++++++++++++++++++------- test/mocks/mass-pnf-sim/test_lifecycle.py | 22 +++++++++++------ 2 files changed, 47 insertions(+), 15 deletions(-) diff --git a/test/mocks/mass-pnf-sim/MassPnfSim.py b/test/mocks/mass-pnf-sim/MassPnfSim.py index b6a32fe2f..42424e602 100755 --- a/test/mocks/mass-pnf-sim/MassPnfSim.py +++ b/test/mocks/mass-pnf-sim/MassPnfSim.py @@ -4,7 +4,7 @@ from subprocess import run, CalledProcessError import argparse import ipaddress from sys import exit -from os import chdir, getcwd, path +from os import chdir, getcwd, path, popen, kill from shutil import copytree, rmtree from json import dumps from yaml import load, SafeLoader @@ -84,10 +84,6 @@ class MassPnfSim: def do_action(action_string, cmd): def action_decorator(method): def action_wrap(self): - cmd_local = cmd - # Append instance # if action is 'stop' - if method.__name__ == 'stop': - cmd_local += " {}" # Alter looping range if action is 'tigger_custom' if method.__name__ == 'trigger_custom': iter_range = [self.args.triggerstart, self.args.triggerend+1] @@ -101,7 +97,7 @@ class MassPnfSim: method(self) for i in range(*iter_range): self.logger.info(f'{action_string} {self.sim_dirname_pattern}{i} instance:') - self._run_cmd(cmd_local.format(i), f"{self.sim_dirname_pattern}{i}") + self._run_cmd(cmd, f"{self.sim_dirname_pattern}{i}") return action_wrap return action_decorator @@ -110,6 +106,7 @@ class MassPnfSim: sim_port = 5000 sim_base_url = 'http://{}:' + str(sim_port) + '/simulator' sim_container_name = 'pnf-simulator' + rop_script_name = 'ROP_file_creator.sh' def __init__(self, args): self.args = args @@ -280,9 +277,36 @@ class MassPnfSim: else: self.logger.info(' Simulator containers are down') - @_MassPnfSim_Decorators.do_action('Stopping', './simulator.sh stop') def stop(self): - pass + for i in range(*self._get_iter_range()): + self.logger.info(f'Stopping {self.sim_dirname_pattern}{i} instance:') + self.logger.info(f' PNF-Sim IP: {self._get_sim_instance_data(i)}') + # attempt killing ROP script + rop_pid = [] + for ps_line in iter(popen(f'ps --no-headers -C {self.rop_script_name} -o pid,cmd').readline, ''): + # try getting ROP script pid + try: + ps_line_arr = ps_line.split() + assert self.rop_script_name in ps_line_arr[2] + assert ps_line_arr[3] == str(i) + rop_pid = ps_line_arr[0] + except AssertionError: + pass + else: + # get rop script childs, kill ROP script and all childs + childs = popen(f'pgrep -P {rop_pid}').read().split() + for pid in [rop_pid] + childs: + kill(int(pid), 15) + self.logger.info(f' ROP_file_creator.sh {i} successfully killed') + if not rop_pid: + # no process found + self.logger.warning(f' ROP_file_creator.sh {i} already not running') + # try tearing down docker-compose application + if f"{self.sim_container_name}-{i}" in self._get_docker_containers(): + self._run_cmd('docker-compose down', self.sim_dirname_pattern + str(i)) + self._run_cmd('docker-compose rm', self.sim_dirname_pattern + str(i)) + else: + self.logger.warning(" Simulator containers are already down") @_MassPnfSim_Decorators.do_action('Triggering', './simulator.sh trigger-simulator') def trigger(self): diff --git a/test/mocks/mass-pnf-sim/test_lifecycle.py b/test/mocks/mass-pnf-sim/test_lifecycle.py index c61b72dd1..beaa084a8 100644 --- a/test/mocks/mass-pnf-sim/test_lifecycle.py +++ b/test/mocks/mass-pnf-sim/test_lifecycle.py @@ -133,24 +133,32 @@ def test_trigger_custom(args_trigger_custom, caplog, capfd): assert "Cannot start simulator since it's already running" in msg.out caplog.clear() -def test_stop(args_stop, caplog, capfd): +def test_stop(args_stop, caplog): MassPnfSim(args_stop).stop() - msg = capfd.readouterr() for instance in range(SIM_INSTANCES): instance_ip_offset = instance * 16 ip_offset = 2 assert f'Stopping pnf-sim-lw-{instance} instance:' in caplog.text - assert f'PNF-Sim IP: {str(ip_address(IPSTART) + ip_offset + instance_ip_offset)}' in msg.out + assert f'PNF-Sim IP: {str(ip_address(IPSTART) + ip_offset + instance_ip_offset)}' in caplog.text + assert f'ROP_file_creator.sh {instance} successfully killed' in caplog.text assert f"ROP_file_creator.sh {instance}" not in popen('ps afx').read() caplog.clear() -def test_stop_idempotence(args_stop, caplog, capfd): +def test_stop_status(args_status, docker_containers, caplog): + MassPnfSim(args_status).status() + for instance in range(SIM_INSTANCES): + assert f"{PNF_SIM_CONTAINER_NAME}{instance}" not in docker_containers + assert 'Simulator containers are down' in caplog.text + caplog.clear() + +def test_stop_idempotence(args_stop, caplog, docker_containers): MassPnfSim(args_stop).stop() - msg = capfd.readouterr() for instance in range(SIM_INSTANCES): assert f'Stopping pnf-sim-lw-{instance} instance:' in caplog.text - assert 'ROP_file_creator.sh already not running' in msg.out - assert 'Simulator containers are already down' in msg.out + assert f'ROP_file_creator.sh {instance} already not running' in caplog.text + assert 'Simulator containers are already down' in caplog.text + assert f"ROP_file_creator.sh {instance}" not in popen('ps afx').read() + assert f"{PNF_SIM_CONTAINER_NAME}{instance}" not in docker_containers caplog.clear() def test_clean(args_clean): -- 2.16.6