Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code

Delta Between Two Patch Sets: tests/utils.py

Issue 29912588: Issue 7019 - [CMS] Refactor `test_server.py` (Closed)
Left Patch Set: Added test_and_wait to test server fixture Created Oct. 25, 2018, 12:22 p.m.
Right Patch Set: Addressed docstring nit Created Oct. 29, 2018, 11 a.m.
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
Left: Side by side diff | Download
Right: Side by side diff | Download
« no previous file with change/comment | « tests/test_page_outputs.py ('k') | tox.ini » ('j') | no next file with change/comment »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
LEFTRIGHT
1 # This file is part of the Adblock Plus web scripts, 1 # This file is part of the Adblock Plus web scripts,
2 # Copyright (C) 2006-present eyeo GmbH 2 # Copyright (C) 2006-present eyeo GmbH
3 # 3 #
4 # Adblock Plus is free software: you can redistribute it and/or modify 4 # Adblock Plus is free software: you can redistribute it and/or modify
5 # it under the terms of the GNU General Public License version 3 as 5 # it under the terms of the GNU General Public License version 3 as
6 # published by the Free Software Foundation. 6 # published by the Free Software Foundation.
7 # 7 #
8 # Adblock Plus is distributed in the hope that it will be useful, 8 # Adblock Plus is distributed in the hope that it will be useful,
9 # but WITHOUT ANY WARRANTY; without even the implied warranty of 9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # GNU General Public License for more details. 11 # GNU General Public License for more details.
12 # 12 #
13 # You should have received a copy of the GNU General Public License 13 # You should have received a copy of the GNU General Public License
14 # along with Adblock Plus. If not, see <http://www.gnu.org/licenses/>. 14 # along with Adblock Plus. If not, see <http://www.gnu.org/licenses/>.
15 15
16 import contextlib 16 import contextlib
17 import os 17 import os
18 import signal 18 import signal
19 import subprocess 19 import subprocess
20 import time 20 import time
21 import zipfile 21 import zipfile
22 from io import BytesIO 22 from io import BytesIO
23 import urllib2 23 import urllib2
24 import traceback
25 24
26 import pytest 25 import pytest
27 26
28 27
29 def get_dir_contents(path): 28 def get_dir_contents(path):
30 # TODO: This function is duplicated in test_page_outputs.py. 29 # TODO: This function is duplicated in test_page_outputs.py.
31 dirdata = {} 30 dirdata = {}
32 for dirpath, dirnames, filenames in os.walk(path): 31 for dirpath, dirnames, filenames in os.walk(path):
33 for output_file in filenames: 32 for output_file in filenames:
34 filepath = os.path.join(dirpath, output_file) 33 filepath = os.path.join(dirpath, output_file)
(...skipping 23 matching lines...) Expand all
58 The url where the server runs. 57 The url where the server runs.
59 58
60 """ 59 """
61 args = ['python', 'runserver.py', site_path] 60 args = ['python', 'runserver.py', site_path]
62 # Werkzeug is a dependency of flask which we are using for the mock api 61 # Werkzeug is a dependency of flask which we are using for the mock api
63 # however there is an issue with Werkzeug that prevents it from properly 62 # however there is an issue with Werkzeug that prevents it from properly
64 # handling the SIGTERM sent by p.kill() or terminate() 63 # handling the SIGTERM sent by p.kill() or terminate()
65 # Issue: https://github.com/pallets/werkzeug/issues/58 64 # Issue: https://github.com/pallets/werkzeug/issues/58
66 p = subprocess.Popen(args, stdout=subprocess.PIPE, preexec_fn=os.setsid, 65 p = subprocess.Popen(args, stdout=subprocess.PIPE, preexec_fn=os.setsid,
67 env=new_env) 66 env=new_env)
68 works, err = _test_server_and_wait() 67
69 if not works: 68 try:
69 _wait_for_server()
70 yield 'http://localhost:5000/'
71 finally:
70 os.killpg(os.getpgid(p.pid), signal.SIGINT) 72 os.killpg(os.getpgid(p.pid), signal.SIGINT)
Vasily Kuznetsov 2018/10/25 15:51:43 We can get rid of the replication of this line usi
Tudor Avram 2018/10/29 10:42:51 Done.
71 raise Exception('Could not get the server running on `http://localhost'
72 ':5000/`. See traceback:\n{}'.format(err))
73 yield 'http://localhost:5000/'
74 os.killpg(os.getpgid(p.pid), signal.SIGINT)
75 73
76 74
77 def _test_server_and_wait(): 75 def _wait_for_server():
78 """Test the server started by `run_test_server` and fail after 2s. 76 """Test the server started by `run_test_server` and fail after 2s.
79 77
80 Expects the server to be active at `http://localhost:5000/`. 78 Expects the server to be active at `http://localhost:5000/`.
81
82 Returns
83 -------
84 bool
85 True - if the server works as expected
86 False - otherwise
87 str or None
88 The traceback of the error - if the server connection fails
89 None - otherwise
90 79
91 Raises 80 Raises
92 ------ 81 ------
93 Exception 82 Exception
94 If the server is not running after retry-ing for 2 seconds. 83 If the server is not running after retry-ing for 2 seconds.
84 This will be the exception raised by `urllib2.urlopen`.
95 85
96 """ 86 """
97 start_time = time.time() 87 start_time = time.time()
98 88
99 while True: 89 while True:
100 try: 90 try:
101 urllib2.urlopen('http://localhost:5000/') 91 urllib2.urlopen('http://localhost:5000/')
102 return True, None 92 break
103 except Exception: 93 except Exception:
104 time.sleep(.1) 94 time.sleep(.1)
105 if time.time() - start_time > 2: 95 if time.time() - start_time > 2:
106 return False, traceback.format_exc() 96 raise
107 97
108 98
109 def create_in_memory_zip(file_names, file_data): 99 def create_in_memory_zip(file_names, file_data):
110 """Create a BytesIO object with the contents of a zip file. 100 """Create a BytesIO object with the contents of a zip file.
111 101
112 Parameters 102 Parameters
113 ---------- 103 ----------
114 file_names: iterable 104 file_names: iterable
115 Of file names. Should be the full paths of the file inside the zip. 105 Of file names. Should be the full paths of the file inside the zip.
116 file_data: iterable 106 file_data: iterable
(...skipping 13 matching lines...) Expand all
130 120
131 memory_zip.seek(0) 121 memory_zip.seek(0)
132 return memory_zip 122 return memory_zip
133 123
134 124
135 def exception_test(func, exception, exp_msg, *args, **kw): 125 def exception_test(func, exception, exp_msg, *args, **kw):
136 with pytest.raises(exception) as err: 126 with pytest.raises(exception) as err:
137 func(*args, **kw) 127 func(*args, **kw)
138 128
139 assert exp_msg in str(err.value) 129 assert exp_msg in str(err.value)
LEFTRIGHT

Powered by Google App Engine
This is Rietveld