xref: /unit/test/test_respawn.py (revision 1654)
11471Szelenkov@nginx.comimport re
21477Szelenkov@nginx.comimport subprocess
31471Szelenkov@nginx.comimport time
41477Szelenkov@nginx.com
5*1654Szelenkov@nginx.comfrom conftest import option
61635Szelenkov@nginx.comfrom conftest import skip_alert
71471Szelenkov@nginx.comfrom unit.applications.lang.python import TestApplicationPython
81471Szelenkov@nginx.com
91471Szelenkov@nginx.com
101471Szelenkov@nginx.comclass TestRespawn(TestApplicationPython):
111471Szelenkov@nginx.com    prerequisites = {'modules': {'python': 'any'}}
121471Szelenkov@nginx.com
131471Szelenkov@nginx.com    PATTERN_ROUTER = 'unit: router'
141471Szelenkov@nginx.com    PATTERN_CONTROLLER = 'unit: controller'
151471Szelenkov@nginx.com
161596Szelenkov@nginx.com    def setup_method(self):
17*1654Szelenkov@nginx.com        self.app_name = "app-" + option.temp_dir.split('/')[-1]
181471Szelenkov@nginx.com
191471Szelenkov@nginx.com        self.load('empty', self.app_name)
201471Szelenkov@nginx.com
211596Szelenkov@nginx.com        assert 'success' in self.conf(
221596Szelenkov@nginx.com            '1', 'applications/' + self.app_name + '/processes'
231471Szelenkov@nginx.com        )
241471Szelenkov@nginx.com
251471Szelenkov@nginx.com    def pid_by_name(self, name):
261471Szelenkov@nginx.com        output = subprocess.check_output(['ps', 'ax']).decode()
271596Szelenkov@nginx.com        m = re.search(r'\s*(\d+).*' + name, output)
281471Szelenkov@nginx.com        return m if m is None else m.group(1)
291471Szelenkov@nginx.com
301471Szelenkov@nginx.com    def kill_pids(self, *pids):
311471Szelenkov@nginx.com        subprocess.call(['kill', '-9'] + list(pids))
321471Szelenkov@nginx.com
331471Szelenkov@nginx.com    def wait_for_process(self, process):
341471Szelenkov@nginx.com        for i in range(50):
351471Szelenkov@nginx.com            found = self.pid_by_name(process)
361471Szelenkov@nginx.com
371471Szelenkov@nginx.com            if found is not None:
381471Szelenkov@nginx.com                break
391471Szelenkov@nginx.com
401471Szelenkov@nginx.com            time.sleep(0.1)
411471Szelenkov@nginx.com
421471Szelenkov@nginx.com        return found
431471Szelenkov@nginx.com
441471Szelenkov@nginx.com    def smoke_test(self):
451471Szelenkov@nginx.com        for _ in range(5):
461596Szelenkov@nginx.com            assert 'success' in self.conf(
471596Szelenkov@nginx.com                '1', 'applications/' + self.app_name + '/processes'
481471Szelenkov@nginx.com            )
491596Szelenkov@nginx.com            assert self.get()['status'] == 200
501471Szelenkov@nginx.com
511471Szelenkov@nginx.com        # Check if the only one router, controller,
521471Szelenkov@nginx.com        # and application processes running.
531471Szelenkov@nginx.com
541471Szelenkov@nginx.com        output = subprocess.check_output(['ps', 'ax']).decode()
551596Szelenkov@nginx.com        assert len(re.findall(self.PATTERN_ROUTER, output)) == 1
561596Szelenkov@nginx.com        assert len(re.findall(self.PATTERN_CONTROLLER, output)) == 1
571596Szelenkov@nginx.com        assert len(re.findall(self.app_name, output)) == 1
581471Szelenkov@nginx.com
591471Szelenkov@nginx.com    def test_respawn_router(self):
601471Szelenkov@nginx.com        pid = self.pid_by_name(self.PATTERN_ROUTER)
611471Szelenkov@nginx.com
621471Szelenkov@nginx.com        self.kill_pids(pid)
631596Szelenkov@nginx.com        skip_alert(r'process %s exited on signal 9' % pid)
641471Szelenkov@nginx.com
651596Szelenkov@nginx.com        assert self.wait_for_process(self.PATTERN_ROUTER) is not None
661471Szelenkov@nginx.com
671471Szelenkov@nginx.com        self.smoke_test()
681471Szelenkov@nginx.com
691471Szelenkov@nginx.com    def test_respawn_controller(self):
701471Szelenkov@nginx.com        pid = self.pid_by_name(self.PATTERN_CONTROLLER)
711471Szelenkov@nginx.com
721471Szelenkov@nginx.com        self.kill_pids(pid)
731596Szelenkov@nginx.com        skip_alert(r'process %s exited on signal 9' % pid)
741471Szelenkov@nginx.com
751596Szelenkov@nginx.com        assert self.wait_for_process(self.PATTERN_CONTROLLER) is not None
761471Szelenkov@nginx.com
771596Szelenkov@nginx.com        assert self.get()['status'] == 200
781471Szelenkov@nginx.com
791471Szelenkov@nginx.com        self.smoke_test()
801471Szelenkov@nginx.com
811471Szelenkov@nginx.com    def test_respawn_application(self):
821471Szelenkov@nginx.com        pid = self.pid_by_name(self.app_name)
831471Szelenkov@nginx.com
841471Szelenkov@nginx.com        self.kill_pids(pid)
851596Szelenkov@nginx.com        skip_alert(r'process %s exited on signal 9' % pid)
861471Szelenkov@nginx.com
871596Szelenkov@nginx.com        assert self.wait_for_process(self.app_name) is not None
881471Szelenkov@nginx.com
891471Szelenkov@nginx.com        self.smoke_test()
90