Drop shell wrapper for stopping simulator instances 26/108726/3
authorBartek Grzybowski <b.grzybowski@partner.samsung.com>
Wed, 3 Jun 2020 09:46:51 +0000 (11:46 +0200)
committerMorgan Richomme <morgan.richomme@orange.com>
Fri, 5 Jun 2020 13:47:18 +0000 (13:47 +0000)
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 <b.grzybowski@partner.samsung.com>
test/mocks/mass-pnf-sim/MassPnfSim.py
test/mocks/mass-pnf-sim/test_lifecycle.py

index b6a32fe..42424e6 100755 (executable)
@@ -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):
index c61b72d..beaa084 100644 (file)
@@ -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):