test_configuration.py (1015:d195f2361ecf) test_configuration.py (1017:887a4bbabf1e)
1import unittest
2import unit
3
1import unittest
2import unit
3
4class TestUnitConfiguration(unit.TestUnitControl):
5
4
5class TestUnitConfiguration(unit.TestUnitControl):
6 def setUpClass():
7 unit.TestUnit().check_modules('python')
8
9 def test_json_empty(self):
10 self.assertIn('error', self.conf(''), 'empty')
11
12 def test_json_leading_zero(self):
13 self.assertIn('error', self.conf('00'), 'leading zero')
14
15 def test_json_unicode(self):
6 def setUpClass():
7 unit.TestUnit().check_modules('python')
8
9 def test_json_empty(self):
10 self.assertIn('error', self.conf(''), 'empty')
11
12 def test_json_leading_zero(self):
13 self.assertIn('error', self.conf('00'), 'leading zero')
14
15 def test_json_unicode(self):
16 self.assertIn('success', self.conf(b"""
16 self.assertIn(
17 'success',
18 self.conf(
19 b"""
17 {
18 "ap\u0070": {
19 "type": "\u0070ython",
20 "processes": { "spare": 0 },
21 "path": "\u002Fapp",
22 "module": "wsgi"
23 }
24 }
20 {
21 "ap\u0070": {
22 "type": "\u0070ython",
23 "processes": { "spare": 0 },
24 "path": "\u002Fapp",
25 "module": "wsgi"
26 }
27 }
25 """, 'applications'), 'unicode')
28 """,
29 'applications',
30 ),
31 'unicode',
32 )
26
33
27 self.assertDictEqual(self.conf_get('applications'), {
28 "app": {
29 "type": "python",
30 "processes": { "spare": 0 },
31 "path": "/app",
32 "module": "wsgi"
33 }
34 }, 'unicode get')
34 self.assertDictEqual(
35 self.conf_get('applications'),
36 {
37 "app": {
38 "type": "python",
39 "processes": {"spare": 0},
40 "path": "/app",
41 "module": "wsgi",
42 }
43 },
44 'unicode get',
45 )
35
36 def test_json_unicode_2(self):
46
47 def test_json_unicode_2(self):
37 self.assertIn('success', self.conf({
38 "приложение": {
39 "type": "python",
40 "processes": { "spare": 0 },
41 "path": "/app",
42 "module": "wsgi"
43 }
44 }, 'applications'), 'unicode 2')
48 self.assertIn(
49 'success',
50 self.conf(
51 {
52 "приложение": {
53 "type": "python",
54 "processes": {"spare": 0},
55 "path": "/app",
56 "module": "wsgi",
57 }
58 },
59 'applications',
60 ),
61 'unicode 2',
62 )
45
63
46 self.assertIn('приложение', self.conf_get('applications'),
47 'unicode 2 get')
64 self.assertIn(
65 'приложение', self.conf_get('applications'), 'unicode 2 get'
66 )
48
49 def test_json_unicode_number(self):
67
68 def test_json_unicode_number(self):
50 self.assertIn('error', self.conf(b"""
69 self.assertIn(
70 'error',
71 self.conf(
72 b"""
51 {
52 "app": {
53 "type": "python",
54 "processes": { "spare": \u0030 },
55 "path": "/app",
56 "module": "wsgi"
57 }
58 }
73 {
74 "app": {
75 "type": "python",
76 "processes": { "spare": \u0030 },
77 "path": "/app",
78 "module": "wsgi"
79 }
80 }
59 """, 'applications'), 'unicode number')
81 """,
82 'applications',
83 ),
84 'unicode number',
85 )
60
61 def test_applications_open_brace(self):
62 self.assertIn('error', self.conf('{', 'applications'), 'open brace')
63
64 def test_applications_string(self):
65 self.assertIn('error', self.conf('"{}"', 'applications'), 'string')
66
67 def test_applications_type_only(self):
86
87 def test_applications_open_brace(self):
88 self.assertIn('error', self.conf('{', 'applications'), 'open brace')
89
90 def test_applications_string(self):
91 self.assertIn('error', self.conf('"{}"', 'applications'), 'string')
92
93 def test_applications_type_only(self):
68 self.skip_alerts.extend([
69 r'python module is empty',
70 r'failed to apply new conf',
71 r'process \d+ exited on signal'
72 ])
94 self.skip_alerts.extend(
95 [
96 r'python module is empty',
97 r'failed to apply new conf',
98 r'process \d+ exited on signal',
99 ]
100 )
73
101
74 self.assertIn('error', self.conf({
75 "app": {
76 "type": "python"
77 }
78 }, 'applications'), 'type only')
102 self.assertIn(
103 'error',
104 self.conf({"app": {"type": "python"}}, 'applications'),
105 'type only',
106 )
79
80 def test_applications_miss_quote(self):
107
108 def test_applications_miss_quote(self):
81 self.assertIn('error', self.conf("""
109 self.assertIn(
110 'error',
111 self.conf(
112 """
82 {
83 app": {
84 "type": "python",
85 "processes": { "spare": 0 },
86 "path": "/app",
87 "module": "wsgi"
88 }
89 }
113 {
114 app": {
115 "type": "python",
116 "processes": { "spare": 0 },
117 "path": "/app",
118 "module": "wsgi"
119 }
120 }
90 """, 'applications'), 'miss quote')
121 """,
122 'applications',
123 ),
124 'miss quote',
125 )
91
92 def test_applications_miss_colon(self):
126
127 def test_applications_miss_colon(self):
93 self.assertIn('error', self.conf("""
128 self.assertIn(
129 'error',
130 self.conf(
131 """
94 {
95 "app" {
96 "type": "python",
97 "processes": { "spare": 0 },
98 "path": "/app",
99 "module": "wsgi"
100 }
101 }
132 {
133 "app" {
134 "type": "python",
135 "processes": { "spare": 0 },
136 "path": "/app",
137 "module": "wsgi"
138 }
139 }
102 """, 'applications'), 'miss colon')
140 """,
141 'applications',
142 ),
143 'miss colon',
144 )
103
104 def test_applications_miss_comma(self):
145
146 def test_applications_miss_comma(self):
105 self.assertIn('error', self.conf("""
147 self.assertIn(
148 'error',
149 self.conf(
150 """
106 {
107 "app": {
108 "type": "python"
109 "processes": { "spare": 0 },
110 "path": "/app",
111 "module": "wsgi"
112 }
113 }
151 {
152 "app": {
153 "type": "python"
154 "processes": { "spare": 0 },
155 "path": "/app",
156 "module": "wsgi"
157 }
158 }
114 """, 'applications'), 'miss comma')
159 """,
160 'applications',
161 ),
162 'miss comma',
163 )
115
116 def test_applications_skip_spaces(self):
164
165 def test_applications_skip_spaces(self):
117 self.assertIn('success', self.conf(b'{ \n\r\t}', 'applications'),
118 'skip spaces')
166 self.assertIn(
167 'success', self.conf(b'{ \n\r\t}', 'applications'), 'skip spaces'
168 )
119
120 def test_applications_relative_path(self):
169
170 def test_applications_relative_path(self):
121 self.assertIn('success', self.conf({
122 "app": {
123 "type": "python",
124 "processes": { "spare": 0 },
125 "path": "../app",
126 "module": "wsgi"
127 }
128 }, 'applications'), 'relative path')
171 self.assertIn(
172 'success',
173 self.conf(
174 {
175 "app": {
176 "type": "python",
177 "processes": {"spare": 0},
178 "path": "../app",
179 "module": "wsgi",
180 }
181 },
182 'applications',
183 ),
184 'relative path',
185 )
129
130 @unittest.expectedFailure
131 def test_listeners_empty(self):
132 self.skip_sanitizer = True
186
187 @unittest.expectedFailure
188 def test_listeners_empty(self):
189 self.skip_sanitizer = True
133 self.skip_alerts.extend([
134 r'failed to apply previous configuration',
135 r'process \d+ exited on signal'
136 ])
190 self.skip_alerts.extend(
191 [
192 r'failed to apply previous configuration',
193 r'process \d+ exited on signal',
194 ]
195 )
137
196
138 self.assertIn('error', self.conf({"*:7080":{}}, 'listeners'),
139 'listener empty')
197 self.assertIn(
198 'error', self.conf({"*:7080": {}}, 'listeners'), 'listener empty'
199 )
140
141 def test_listeners_no_app(self):
200
201 def test_listeners_no_app(self):
142 self.assertIn('error', self.conf({"*:7080":{"application":"app"}},
143 'listeners'), 'listeners no app')
202 self.assertIn(
203 'error',
204 self.conf({"*:7080": {"application": "app"}}, 'listeners'),
205 'listeners no app',
206 )
144
145 def test_listeners_wildcard(self):
207
208 def test_listeners_wildcard(self):
146 self.assertIn('success', self.conf({
147 "listeners": {
148 "*:7080": {
149 "application":"app"
209 self.assertIn(
210 'success',
211 self.conf(
212 {
213 "listeners": {"*:7080": {"application": "app"}},
214 "applications": {
215 "app": {
216 "type": "python",
217 "processes": {"spare": 0},
218 "path": "/app",
219 "module": "wsgi",
220 }
221 },
150 }
222 }
151 },
152 "applications": {
153 "app": {
154 "type": "python",
155 "processes": { "spare": 0 },
156 "path": "/app",
157 "module": "wsgi"
158 }
159 }
160 }), 'listeners wildcard')
223 ),
224 'listeners wildcard',
225 )
161
162 def test_listeners_explicit(self):
226
227 def test_listeners_explicit(self):
163 self.assertIn('success', self.conf({
164 "listeners": {
165 "127.0.0.1:7080": {
166 "application":"app"
228 self.assertIn(
229 'success',
230 self.conf(
231 {
232 "listeners": {"127.0.0.1:7080": {"application": "app"}},
233 "applications": {
234 "app": {
235 "type": "python",
236 "processes": {"spare": 0},
237 "path": "/app",
238 "module": "wsgi",
239 }
240 },
167 }
241 }
168 },
169 "applications": {
170 "app": {
171 "type": "python",
172 "processes": { "spare": 0 },
173 "path": "/app",
174 "module": "wsgi"
175 }
176 }
177 }), 'explicit')
242 ),
243 'explicit',
244 )
178
179 def test_listeners_explicit_ipv6(self):
245
246 def test_listeners_explicit_ipv6(self):
180 self.assertIn('success', self.conf({
181 "listeners": {
182 "[::1]:7080": {
183 "application":"app"
247 self.assertIn(
248 'success',
249 self.conf(
250 {
251 "listeners": {"[::1]:7080": {"application": "app"}},
252 "applications": {
253 "app": {
254 "type": "python",
255 "processes": {"spare": 0},
256 "path": "/app",
257 "module": "wsgi",
258 }
259 },
184 }
260 }
185 },
186 "applications": {
187 "app": {
188 "type": "python",
189 "processes": { "spare": 0 },
190 "path": "/app",
191 "module": "wsgi"
192 }
193 }
194 }), 'explicit ipv6')
261 ),
262 'explicit ipv6',
263 )
195
196 def test_listeners_no_port(self):
264
265 def test_listeners_no_port(self):
197 self.skip_alerts.extend([
198 r'invalid listener "127\.0\.0\.1"',
199 r'failed to apply new conf',
200 r'process \d+ exited on signal'
201 ])
266 self.skip_alerts.extend(
267 [
268 r'invalid listener "127\.0\.0\.1"',
269 r'failed to apply new conf',
270 r'process \d+ exited on signal',
271 ]
272 )
202
273
203 self.assertIn('error', self.conf({
204 "listeners": {
205 "127.0.0.1": {
206 "application":"app"
274 self.assertIn(
275 'error',
276 self.conf(
277 {
278 "listeners": {"127.0.0.1": {"application": "app"}},
279 "applications": {
280 "app": {
281 "type": "python",
282 "processes": {"spare": 0},
283 "path": "/app",
284 "module": "wsgi",
285 }
286 },
207 }
287 }
208 },
209 "applications": {
210 "app": {
211 "type": "python",
212 "processes": { "spare": 0 },
213 "path": "/app",
214 "module": "wsgi"
215 }
216 }
217 }), 'no port')
288 ),
289 'no port',
290 )
218
219 def test_json_application_name_large(self):
220 name = "X" * 1024 * 1024
221
291
292 def test_json_application_name_large(self):
293 name = "X" * 1024 * 1024
294
222 self.assertIn('success', self.conf({
223 "listeners": {
224 "*:7080": {
225 "application": name
295 self.assertIn(
296 'success',
297 self.conf(
298 {
299 "listeners": {"*:7080": {"application": name}},
300 "applications": {
301 name: {
302 "type": "python",
303 "processes": {"spare": 0},
304 "path": "/app",
305 "module": "wsgi",
306 }
307 },
226 }
308 }
227 },
228 "applications": {
229 name: {
230 "type": "python",
231 "processes": { "spare": 0 },
232 "path": "/app",
233 "module": "wsgi"
234 }
235 }
236 }))
309 ),
310 )
237
238 @unittest.expectedFailure
239 def test_json_application_many(self):
311
312 @unittest.expectedFailure
313 def test_json_application_many(self):
240 self.skip_alerts.extend([
241 r'eventfd.+failed',
242 r'epoll.+failed',
243 r'failed to apply'
244 ])
314 self.skip_alerts.extend(
315 [r'eventfd.+failed', r'epoll.+failed', r'failed to apply']
316 )
245 apps = 999
246
247 conf = {
317 apps = 999
318
319 conf = {
248 "applications":
249 {"app-" + str(a): {
320 "applications": {
321 "app-"
322 + str(a): {
250 "type": "python",
323 "type": "python",
251 "processes": { "spare": 0 },
324 "processes": {"spare": 0},
252 "path": "/app",
325 "path": "/app",
253 "module": "wsgi"
254 } for a in range(apps)
326 "module": "wsgi",
327 }
328 for a in range(apps)
255 },
256 "listeners": {
329 },
330 "listeners": {
257 "*:" + str(7000 + a): {
258 "application": "app-" + str(a)
259 } for a in range(apps)
260 }
331 "*:" + str(7000 + a): {"application": "app-" + str(a)}
332 for a in range(apps)
333 },
261 }
262
263 self.assertIn('success', self.conf(conf))
264
265 def test_json_application_many2(self):
334 }
335
336 self.assertIn('success', self.conf(conf))
337
338 def test_json_application_many2(self):
266 self.skip_alerts.extend([
267 r'eventfd.+failed',
268 r'epoll.+failed',
269 r'failed to apply'
270 ])
339 self.skip_alerts.extend(
340 [r'eventfd.+failed', r'epoll.+failed', r'failed to apply']
341 )
271
272 conf = {
342
343 conf = {
273 "applications":
274 {"app-" + str(a): {
344 "applications": {
345 "app-"
346 + str(a): {
275 "type": "python",
347 "type": "python",
276 "processes": { "spare": 0 },
348 "processes": {"spare": 0},
277 "path": "/app",
349 "path": "/app",
278 "module": "wsgi"
279 } for a in range(999)
280 },
281 "listeners": {
282 "*:7001": {
283 "application": "app-1"
350 "module": "wsgi",
284 }
351 }
285 }
352 for a in range(999)
353 },
354 "listeners": {"*:7001": {"application": "app-1"}},
286 }
287
288 self.assertIn('success', self.conf(conf))
289
355 }
356
357 self.assertIn('success', self.conf(conf))
358
359
290if __name__ == '__main__':
291 TestUnitConfiguration.main()
360if __name__ == '__main__':
361 TestUnitConfiguration.main()