diff options
author | Max Romanov <max.romanov@nginx.com> | 2021-07-29 19:50:39 +0300 |
---|---|---|
committer | Max Romanov <max.romanov@nginx.com> | 2021-07-29 19:50:39 +0300 |
commit | fa9fb29be221e0393562831a9e3bcba416652f60 (patch) | |
tree | bc3e1a28d7915735507c64a62199a189bfb8231f /test | |
parent | f3a1c1deb541784b2b0ed179514e4d5eba9fe626 (diff) | |
download | unit-fa9fb29be221e0393562831a9e3bcba416652f60.tar.gz unit-fa9fb29be221e0393562831a9e3bcba416652f60.tar.bz2 |
Application restart introduced.
When processing a restart request, the router sends a QUIT message to all
existing processes of the application. Then, a new shared application port is
created to ensure that new requests won't be handled by the old processes of
the application.
Diffstat (limited to 'test')
-rw-r--r-- | test/python/restart/longstart.py | 10 | ||||
-rw-r--r-- | test/python/restart/v1.py | 7 | ||||
-rw-r--r-- | test/python/restart/v2.py | 7 | ||||
-rw-r--r-- | test/test_python_procman.py | 79 | ||||
-rw-r--r-- | test/unit/applications/lang/python.py | 1 |
5 files changed, 104 insertions, 0 deletions
diff --git a/test/python/restart/longstart.py b/test/python/restart/longstart.py new file mode 100644 index 00000000..777398ac --- /dev/null +++ b/test/python/restart/longstart.py @@ -0,0 +1,10 @@ +import os +import time + +time.sleep(2) + +def application(environ, start_response): + body = str(os.getpid()).encode() + + start_response('200', [('Content-Length', str(len(body)))]) + return [body] diff --git a/test/python/restart/v1.py b/test/python/restart/v1.py new file mode 100644 index 00000000..2e45b269 --- /dev/null +++ b/test/python/restart/v1.py @@ -0,0 +1,7 @@ +import os + +def application(environ, start_response): + body = "v1".encode() + + start_response('200', [('Content-Length', str(len(body)))]) + return [body] diff --git a/test/python/restart/v2.py b/test/python/restart/v2.py new file mode 100644 index 00000000..59e3d30f --- /dev/null +++ b/test/python/restart/v2.py @@ -0,0 +1,7 @@ +import os + +def application(environ, start_response): + body = "v2".encode() + + start_response('200', [('Content-Length', str(len(body)))]) + return [body] diff --git a/test/test_python_procman.py b/test/test_python_procman.py index b0d0f5af..a95c5680 100644 --- a/test/test_python_procman.py +++ b/test/test_python_procman.py @@ -1,4 +1,5 @@ import re +import shutil import subprocess import time @@ -201,3 +202,81 @@ class TestPythonProcman(TestApplicationPython): assert 'success' in self.conf({"listeners": {}, "applications": {}}) assert len(self.pids_for_process()) == 0, 'stop all' + + def test_python_restart(self, temp_dir): + shutil.copyfile( + option.test_dir + '/python/restart/v1.py', temp_dir + '/wsgi.py' + ) + + self.load( + temp_dir, + name=self.app_name, + processes=1, + environment={'PYTHONDONTWRITEBYTECODE': '1'}, + ) + + b = self.get()['body'] + assert b == "v1", 'process started' + + shutil.copyfile( + option.test_dir + '/python/restart/v2.py', temp_dir + '/wsgi.py' + ) + + b = self.get()['body'] + assert b == "v1", 'still old process' + + assert 'success' in self.conf_get( + '/control/applications/' + self.app_name + '/restart' + ), 'restart processes' + + b = self.get()['body'] + assert b == "v2", 'new process started' + + assert 'error' in self.conf_get( + '/control/applications/blah/restart' + ), 'application incorrect' + + assert 'error' in self.conf_delete( + '/control/applications/' + self.app_name + '/restart' + ), 'method incorrect' + + def test_python_restart_multi(self): + self.conf_proc('2') + + pids = self.pids_for_process() + assert len(pids) == 2, 'restart 2 started' + + assert 'success' in self.conf_get( + '/control/applications/' + self.app_name + '/restart' + ), 'restart processes' + + new_pids = self.pids_for_process() + assert len(new_pids) == 2, 'restart still 2' + + assert len(new_pids.intersection(pids)) == 0, 'restart all new' + + def test_python_restart_longstart(self): + self.load( + 'restart', + name=self.app_name, + module="longstart", + processes={"spare": 1, "max": 2, "idle_timeout": 5}, + ) + + assert len(self.pids_for_process()) == 1, 'longstarts == 1' + + pid = self.get()['body'] + pids = self.pids_for_process() + assert len(pids) == 2, 'longstarts == 2' + + assert 'success' in self.conf_get( + '/control/applications/' + self.app_name + '/restart' + ), 'restart processes' + + # wait for longstarted app + time.sleep(2) + + new_pids = self.pids_for_process() + assert len(new_pids) == 1, 'restart 1' + + assert len(new_pids.intersection(pids)) == 0, 'restart all new' diff --git a/test/unit/applications/lang/python.py b/test/unit/applications/lang/python.py index b399dffd..215aa332 100644 --- a/test/unit/applications/lang/python.py +++ b/test/unit/applications/lang/python.py @@ -44,6 +44,7 @@ class TestApplicationPython(TestApplicationProto): for attr in ( 'callable', + 'environment', 'home', 'limits', 'path', |