xref: /unit/test/test_ruby_application.py (revision 1165:998b521bbdb8)
1import unittest
2from unit.applications.lang.ruby import TestApplicationRuby
3
4
5class TestRubyApplication(TestApplicationRuby):
6    prerequisites = {'modules': ['ruby']}
7
8    def test_ruby_application(self):
9        self.load('variables')
10
11        body = 'Test body string.'
12
13        resp = self.post(
14            headers={
15                'Host': 'localhost',
16                'Content-Type': 'text/html',
17                'Custom-Header': 'blah',
18                'Connection': 'close',
19            },
20            body=body,
21        )
22
23        self.assertEqual(resp['status'], 200, 'status')
24        headers = resp['headers']
25        header_server = headers.pop('Server')
26        self.assertRegex(header_server, r'Unit/[\d\.]+', 'server header')
27        self.assertEqual(
28            headers.pop('Server-Software'),
29            header_server,
30            'server software header',
31        )
32
33        date = headers.pop('Date')
34        self.assertEqual(date[-4:], ' GMT', 'date header timezone')
35        self.assertLess(
36            abs(self.date_to_sec_epoch(date) - self.sec_epoch()),
37            5,
38            'date header',
39        )
40
41        self.assertDictEqual(
42            headers,
43            {
44                'Connection': 'close',
45                'Content-Length': str(len(body)),
46                'Content-Type': 'text/html',
47                'Request-Method': 'POST',
48                'Request-Uri': '/',
49                'Http-Host': 'localhost',
50                'Server-Protocol': 'HTTP/1.1',
51                'Custom-Header': 'blah',
52                'Rack-Version': '13',
53                'Rack-Url-Scheme': 'http',
54                'Rack-Multithread': 'false',
55                'Rack-Multiprocess': 'true',
56                'Rack-Run-Once': 'false',
57                'Rack-Hijack-Q': 'false',
58                'Rack-Hijack': '',
59                'Rack-Hijack-IO': '',
60            },
61            'headers',
62        )
63        self.assertEqual(resp['body'], body, 'body')
64
65    def test_ruby_application_query_string(self):
66        self.load('query_string')
67
68        resp = self.get(url='/?var1=val1&var2=val2')
69
70        self.assertEqual(
71            resp['headers']['Query-String'],
72            'var1=val1&var2=val2',
73            'Query-String header',
74        )
75
76    def test_ruby_application_query_string_empty(self):
77        self.load('query_string')
78
79        resp = self.get(url='/?')
80
81        self.assertEqual(resp['status'], 200, 'query string empty status')
82        self.assertEqual(
83            resp['headers']['Query-String'], '', 'query string empty'
84        )
85
86    def test_ruby_application_query_string_absent(self):
87        self.load('query_string')
88
89        resp = self.get()
90
91        self.assertEqual(resp['status'], 200, 'query string absent status')
92        self.assertEqual(
93            resp['headers']['Query-String'], '', 'query string absent'
94        )
95
96    @unittest.skip('not yet')
97    def test_ruby_application_server_port(self):
98        self.load('server_port')
99
100        self.assertEqual(
101            self.get()['headers']['Server-Port'], '7080', 'Server-Port header'
102        )
103
104    def test_ruby_application_status_int(self):
105        self.load('status_int')
106
107        self.assertEqual(self.get()['status'], 200, 'status int')
108
109    def test_ruby_application_input_read_empty(self):
110        self.load('input_read_empty')
111
112        self.assertEqual(self.get()['body'], '', 'read empty')
113
114    def test_ruby_application_input_read_parts(self):
115        self.load('input_read_parts')
116
117        self.assertEqual(
118            self.post(body='0123456789')['body'],
119            '012345678',
120            'input read parts',
121        )
122
123    def test_ruby_application_input_read_buffer(self):
124        self.load('input_read_buffer')
125
126        self.assertEqual(
127            self.post(body='0123456789')['body'],
128            '0123456789',
129            'input read buffer',
130        )
131
132    def test_ruby_application_input_read_buffer_not_empty(self):
133        self.load('input_read_buffer_not_empty')
134
135        self.assertEqual(
136            self.post(body='0123456789')['body'],
137            '0123456789',
138            'input read buffer not empty',
139        )
140
141    def test_ruby_application_input_gets(self):
142        self.load('input_gets')
143
144        body = '0123456789'
145
146        self.assertEqual(self.post(body=body)['body'], body, 'input gets')
147
148    def test_ruby_application_input_gets_2(self):
149        self.load('input_gets')
150
151        self.assertEqual(
152            self.post(body='01234\n56789\n')['body'], '01234\n', 'input gets 2'
153        )
154
155    def test_ruby_application_input_gets_all(self):
156        self.load('input_gets_all')
157
158        body = '\n01234\n56789\n\n'
159
160        self.assertEqual(self.post(body=body)['body'], body, 'input gets all')
161
162    def test_ruby_application_input_each(self):
163        self.load('input_each')
164
165        body = '\n01234\n56789\n\n'
166
167        self.assertEqual(self.post(body=body)['body'], body, 'input each')
168
169    @unittest.skip('not yet')
170    def test_ruby_application_input_rewind(self):
171        self.load('input_rewind')
172
173        body = '0123456789'
174
175        self.assertEqual(self.post(body=body)['body'], body, 'input rewind')
176
177    @unittest.skip('not yet')
178    def test_ruby_application_syntax_error(self):
179        self.skip_alerts.extend(
180            [
181                r'Failed to parse rack script',
182                r'syntax error',
183                r'new_from_string',
184                r'parse_file',
185            ]
186        )
187        self.load('syntax_error')
188
189        self.assertEqual(self.get()['status'], 500, 'syntax error')
190
191    def test_ruby_application_errors_puts(self):
192        self.load('errors_puts')
193
194        self.get()
195
196        self.stop()
197
198        self.assertIsNotNone(
199            self.wait_for_record(r'\[error\].+Error in application'),
200            'errors puts',
201        )
202
203    def test_ruby_application_errors_puts_int(self):
204        self.load('errors_puts_int')
205
206        self.get()
207
208        self.stop()
209
210        self.assertIsNotNone(
211            self.wait_for_record(r'\[error\].+1234567890'), 'errors puts int'
212        )
213
214    def test_ruby_application_errors_write(self):
215        self.load('errors_write')
216
217        self.get()
218
219        self.stop()
220
221        self.assertIsNotNone(
222            self.wait_for_record(r'\[error\].+Error in application'),
223            'errors write',
224        )
225
226    def test_ruby_application_errors_write_to_s_custom(self):
227        self.load('errors_write_to_s_custom')
228
229        self.assertEqual(self.get()['status'], 200, 'errors write to_s custom')
230
231    def test_ruby_application_errors_write_int(self):
232        self.load('errors_write_int')
233
234        self.get()
235
236        self.stop()
237
238        self.assertIsNotNone(
239            self.wait_for_record(r'\[error\].+1234567890'), 'errors write int'
240        )
241
242    def test_ruby_application_at_exit(self):
243        self.load('at_exit')
244
245        self.get()
246
247        self.conf({"listeners": {}, "applications": {}})
248
249        self.stop()
250
251        self.assertIsNotNone(
252            self.wait_for_record(r'\[error\].+At exit called\.'), 'at exit'
253        )
254
255    def test_ruby_application_header_custom(self):
256        self.load('header_custom')
257
258        resp = self.post(body="\ntc=one,two\ntc=three,four,\n\n")
259
260        self.assertEqual(
261            resp['headers']['Custom-Header'],
262            ['', 'tc=one,two', 'tc=three,four,', '', ''],
263            'header custom',
264        )
265
266    @unittest.skip('not yet')
267    def test_ruby_application_header_custom_non_printable(self):
268        self.load('header_custom')
269
270        self.assertEqual(
271            self.post(body='\b')['status'], 500, 'header custom non printable'
272        )
273
274    def test_ruby_application_header_status(self):
275        self.load('header_status')
276
277        self.assertEqual(self.get()['status'], 200, 'header status')
278
279    @unittest.skip('not yet')
280    def test_ruby_application_header_rack(self):
281        self.load('header_rack')
282
283        self.assertEqual(self.get()['status'], 500, 'header rack')
284
285    def test_ruby_application_body_empty(self):
286        self.load('body_empty')
287
288        self.assertEqual(self.get()['body'], '0\r\n\r\n', 'body empty')
289
290    def test_ruby_application_body_array(self):
291        self.load('body_array')
292
293        self.assertEqual(self.get()['body'], '0123456789', 'body array')
294
295    def test_ruby_application_body_large(self):
296        self.load('mirror')
297
298        body = '0123456789' * 1000
299
300        self.assertEqual(self.post(body=body)['body'], body, 'body large')
301
302    @unittest.skip('not yet')
303    def test_ruby_application_body_each_error(self):
304        self.load('body_each_error')
305
306        self.assertEqual(self.get()['status'], 500, 'body each error status')
307
308        self.stop()
309
310        self.assertIsNotNone(
311            self.wait_for_record(r'\[error\].+Failed to run ruby script'),
312            'body each error',
313        )
314
315    def test_ruby_application_body_file(self):
316        self.load('body_file')
317
318        self.assertEqual(self.get()['body'], 'body\n', 'body file')
319
320    def test_ruby_keepalive_body(self):
321        self.load('mirror')
322
323        self.assertEqual(self.get()['status'], 200, 'init')
324
325        (resp, sock) = self.post(
326            headers={
327                'Host': 'localhost',
328                'Connection': 'keep-alive',
329                'Content-Type': 'text/html',
330            },
331            start=True,
332            body='0123456789' * 500,
333            read_timeout=1,
334        )
335
336        self.assertEqual(resp['body'], '0123456789' * 500, 'keep-alive 1')
337
338        resp = self.post(
339            headers={
340                'Host': 'localhost',
341                'Connection': 'close',
342                'Content-Type': 'text/html',
343            },
344            sock=sock,
345            body='0123456789',
346        )
347
348        self.assertEqual(resp['body'], '0123456789', 'keep-alive 2')
349
350
351if __name__ == '__main__':
352    TestRubyApplication.main()
353