xref: /unit/test/test_respawn.py (revision 1596)
11471Szelenkov@nginx.comimport re
21477Szelenkov@nginx.comimport subprocess
31471Szelenkov@nginx.comimport time
41477Szelenkov@nginx.com
51471Szelenkov@nginx.comfrom unit.applications.lang.python import TestApplicationPython
6*1596Szelenkov@nginx.comfrom conftest import skip_alert
71471Szelenkov@nginx.com
81471Szelenkov@nginx.com
91471Szelenkov@nginx.comclass TestRespawn(TestApplicationPython):
101471Szelenkov@nginx.com    prerequisites = {'modules': {'python': 'any'}}
111471Szelenkov@nginx.com
121471Szelenkov@nginx.com    PATTERN_ROUTER = 'unit: router'
131471Szelenkov@nginx.com    PATTERN_CONTROLLER = 'unit: controller'
141471Szelenkov@nginx.com
15*1596Szelenkov@nginx.com    def setup_method(self):
16*1596Szelenkov@nginx.com        super().setup_method()
171471Szelenkov@nginx.com
18*1596Szelenkov@nginx.com        self.app_name = "app-" + self.temp_dir.split('/')[-1]
191471Szelenkov@nginx.com
201471Szelenkov@nginx.com        self.load('empty', self.app_name)
211471Szelenkov@nginx.com
22*1596Szelenkov@nginx.com        assert 'success' in self.conf(
23*1596Szelenkov@nginx.com            '1', 'applications/' + self.app_name + '/processes'
241471Szelenkov@nginx.com        )
251471Szelenkov@nginx.com
261471Szelenkov@nginx.com    def pid_by_name(self, name):
271471Szelenkov@nginx.com        output = subprocess.check_output(['ps', 'ax']).decode()
28*1596Szelenkov@nginx.com        m = re.search(r'\s*(\d+).*' + name, output)
291471Szelenkov@nginx.com        return m if m is None else m.group(1)
301471Szelenkov@nginx.com
311471Szelenkov@nginx.com    def kill_pids(self, *pids):
321471Szelenkov@nginx.com        subprocess.call(['kill', '-9'] + list(pids))
331471Szelenkov@nginx.com
341471Szelenkov@nginx.com    def wait_for_process(self, process):
351471Szelenkov@nginx.com        for i in range(50):
361471Szelenkov@nginx.com            found = self.pid_by_name(process)
371471Szelenkov@nginx.com
381471Szelenkov@nginx.com            if found is not None:
391471Szelenkov@nginx.com                break
401471Szelenkov@nginx.com
411471Szelenkov@nginx.com            time.sleep(0.1)
421471Szelenkov@nginx.com
431471Szelenkov@nginx.com        return found
441471Szelenkov@nginx.com
451471Szelenkov@nginx.com    def smoke_test(self):
461471Szelenkov@nginx.com        for _ in range(5):
47*1596Szelenkov@nginx.com            assert 'success' in self.conf(
48*1596Szelenkov@nginx.com                '1', 'applications/' + self.app_name + '/processes'
491471Szelenkov@nginx.com            )
50*1596Szelenkov@nginx.com            assert self.get()['status'] == 200
511471Szelenkov@nginx.com
521471Szelenkov@nginx.com        # Check if the only one router, controller,
531471Szelenkov@nginx.com        # and application processes running.
541471Szelenkov@nginx.com
551471Szelenkov@nginx.com        output = subprocess.check_output(['ps', 'ax']).decode()
56*1596Szelenkov@nginx.com        assert len(re.findall(self.PATTERN_ROUTER, output)) == 1
57*1596Szelenkov@nginx.com        assert len(re.findall(self.PATTERN_CONTROLLER, output)) == 1
58*1596Szelenkov@nginx.com        assert len(re.findall(self.app_name, output)) == 1
591471Szelenkov@nginx.com
601471Szelenkov@nginx.com    def test_respawn_router(self):
611471Szelenkov@nginx.com        pid = self.pid_by_name(self.PATTERN_ROUTER)
621471Szelenkov@nginx.com
631471Szelenkov@nginx.com        self.kill_pids(pid)
64*1596Szelenkov@nginx.com        skip_alert(r'process %s exited on signal 9' % pid)
651471Szelenkov@nginx.com
66*1596Szelenkov@nginx.com        assert self.wait_for_process(self.PATTERN_ROUTER) is not None
671471Szelenkov@nginx.com
681471Szelenkov@nginx.com        self.smoke_test()
691471Szelenkov@nginx.com
701471Szelenkov@nginx.com    def test_respawn_controller(self):
711471Szelenkov@nginx.com        pid = self.pid_by_name(self.PATTERN_CONTROLLER)
721471Szelenkov@nginx.com
731471Szelenkov@nginx.com        self.kill_pids(pid)
74*1596Szelenkov@nginx.com        skip_alert(r'process %s exited on signal 9' % pid)
751471Szelenkov@nginx.com
76*1596Szelenkov@nginx.com        assert self.wait_for_process(self.PATTERN_CONTROLLER) is not None
771471Szelenkov@nginx.com
78*1596Szelenkov@nginx.com        assert self.get()['status'] == 200
791471Szelenkov@nginx.com
801471Szelenkov@nginx.com        self.smoke_test()
811471Szelenkov@nginx.com
821471Szelenkov@nginx.com    def test_respawn_application(self):
831471Szelenkov@nginx.com        pid = self.pid_by_name(self.app_name)
841471Szelenkov@nginx.com
851471Szelenkov@nginx.com        self.kill_pids(pid)
86*1596Szelenkov@nginx.com        skip_alert(r'process %s exited on signal 9' % pid)
871471Szelenkov@nginx.com
88*1596Szelenkov@nginx.com        assert self.wait_for_process(self.app_name) is not None
891471Szelenkov@nginx.com
901471Szelenkov@nginx.com        self.smoke_test()
91