xref: /unit/test/test_ruby_application.py (revision 1025:3469f5185562)
1import unittest
2from unit.applications.lang.ruby import TestApplicationRuby
3
4
5class TestRubyApplication(TestApplicationRuby):
6    prerequisites = ['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    @unittest.expectedFailure
87    def test_ruby_application_query_string_absent(self):
88        self.load('query_string')
89
90        resp = self.get()
91
92        self.assertEqual(resp['status'], 200, 'query string absent status')
93        self.assertEqual(
94            resp['headers']['Query-String'], '', 'query string absent'
95        )
96
97    @unittest.expectedFailure
98    def test_ruby_application_server_port(self):
99        self.load('server_port')
100
101        self.assertEqual(
102            self.get()['headers']['Server-Port'], '7080', 'Server-Port header'
103        )
104
105    def test_ruby_application_status_int(self):
106        self.load('status_int')
107
108        self.assertEqual(self.get()['status'], 200, 'status int')
109
110    def test_ruby_application_input_read_empty(self):
111        self.load('input_read_empty')
112
113        self.assertEqual(self.get()['body'], '', 'read empty')
114
115    def test_ruby_application_input_read_parts(self):
116        self.load('input_read_parts')
117
118        self.assertEqual(
119            self.post(body='0123456789')['body'],
120            '012345678',
121            'input read parts',
122        )
123
124    def test_ruby_application_input_read_buffer(self):
125        self.load('input_read_buffer')
126
127        self.assertEqual(
128            self.post(body='0123456789')['body'],
129            '0123456789',
130            'input read buffer',
131        )
132
133    def test_ruby_application_input_read_buffer_not_empty(self):
134        self.load('input_read_buffer_not_empty')
135
136        self.assertEqual(
137            self.post(body='0123456789')['body'],
138            '0123456789',
139            'input read buffer not empty',
140        )
141
142    def test_ruby_application_input_gets(self):
143        self.load('input_gets')
144
145        body = '0123456789'
146
147        self.assertEqual(self.post(body=body)['body'], body, 'input gets')
148
149    def test_ruby_application_input_gets_2(self):
150        self.load('input_gets')
151
152        self.assertEqual(
153            self.post(body='01234\n56789\n')['body'], '01234\n', 'input gets 2'
154        )
155
156    def test_ruby_application_input_gets_all(self):
157        self.load('input_gets_all')
158
159        body = '\n01234\n56789\n\n'
160
161        self.assertEqual(self.post(body=body)['body'], body, 'input gets all')
162
163    def test_ruby_application_input_each(self):
164        self.load('input_each')
165
166        body = '\n01234\n56789\n\n'
167
168        self.assertEqual(self.post(body=body)['body'], body, 'input each')
169
170    @unittest.expectedFailure
171    def test_ruby_application_input_rewind(self):
172        self.load('input_rewind')
173
174        body = '0123456789'
175
176        self.assertEqual(self.post(body=body)['body'], body, 'input rewind')
177
178    @unittest.expectedFailure
179    def test_ruby_application_syntax_error(self):
180        self.skip_alerts.extend(
181            [
182                r'Failed to parse rack script',
183                r'syntax error',
184                r'new_from_string',
185                r'parse_file',
186            ]
187        )
188        self.load('syntax_error')
189
190        self.assertEqual(self.get()['status'], 500, 'syntax error')
191
192    def test_ruby_application_errors_puts(self):
193        self.load('errors_puts')
194
195        self.get()
196
197        self.stop()
198
199        self.assertIsNotNone(
200            self.search_in_log(r'\[error\].+Error in application'),
201            'errors puts',
202        )
203
204    def test_ruby_application_errors_puts_int(self):
205        self.load('errors_puts_int')
206
207        self.get()
208
209        self.stop()
210
211        self.assertIsNotNone(
212            self.search_in_log(r'\[error\].+1234567890'), 'errors puts int'
213        )
214
215    def test_ruby_application_errors_write(self):
216        self.load('errors_write')
217
218        self.get()
219
220        self.stop()
221
222        self.assertIsNotNone(
223            self.search_in_log(r'\[error\].+Error in application'),
224            'errors write',
225        )
226
227    def test_ruby_application_errors_write_to_s_custom(self):
228        self.load('errors_write_to_s_custom')
229
230        self.assertEqual(self.get()['status'], 200, 'errors write to_s custom')
231
232    def test_ruby_application_errors_write_int(self):
233        self.load('errors_write_int')
234
235        self.get()
236
237        self.stop()
238
239        self.assertIsNotNone(
240            self.search_in_log(r'\[error\].+1234567890'), 'errors write int'
241        )
242
243    def test_ruby_application_at_exit(self):
244        self.load('at_exit')
245
246        self.get()
247
248        self.conf({"listeners": {}, "applications": {}})
249
250        self.stop()
251
252        self.assertIsNotNone(
253            self.search_in_log(r'\[error\].+At exit called\.'), 'at exit'
254        )
255
256    def test_ruby_application_header_custom(self):
257        self.load('header_custom')
258
259        resp = self.post(body="\ntc=one,two\ntc=three,four,\n\n")
260
261        self.assertEqual(
262            resp['headers']['Custom-Header'],
263            ['', 'tc=one,two', 'tc=three,four,', '', ''],
264            'header custom',
265        )
266
267    @unittest.expectedFailure
268    def test_ruby_application_header_custom_non_printable(self):
269        self.load('header_custom')
270
271        self.assertEqual(
272            self.post(body='\b')['status'], 500, 'header custom non printable'
273        )
274
275    def test_ruby_application_header_status(self):
276        self.load('header_status')
277
278        self.assertEqual(self.get()['status'], 200, 'header status')
279
280    @unittest.expectedFailure
281    def test_ruby_application_header_rack(self):
282        self.load('header_rack')
283
284        self.assertEqual(self.get()['status'], 500, 'header rack')
285
286    def test_ruby_application_body_empty(self):
287        self.load('body_empty')
288
289        self.assertEqual(self.get()['body'], '0\r\n\r\n', 'body empty')
290
291    def test_ruby_application_body_array(self):
292        self.load('body_array')
293
294        self.assertEqual(self.get()['body'], '0123456789', 'body array')
295
296    def test_ruby_application_body_large(self):
297        self.load('mirror')
298
299        body = '0123456789' * 1000
300
301        self.assertEqual(self.post(body=body)['body'], body, 'body large')
302
303    @unittest.expectedFailure
304    def test_ruby_application_body_each_error(self):
305        self.load('body_each_error')
306
307        self.assertEqual(self.get()['status'], 500, 'body each error status')
308
309        self.stop()
310
311        self.assertIsNotNone(
312            self.search_in_log(r'\[error\].+Failed to run ruby script'),
313            'body each error',
314        )
315
316    def test_ruby_application_body_file(self):
317        self.load('body_file')
318
319        self.assertEqual(self.get()['body'], 'body\n', 'body file')
320
321    def test_ruby_keepalive_body(self):
322        self.load('mirror')
323
324        (resp, sock) = self.post(
325            headers={
326                'Host': 'localhost',
327                'Connection': 'keep-alive',
328                'Content-Type': 'text/html',
329            },
330            start=True,
331            body='0123456789' * 500,
332        )
333
334        self.assertEqual(resp['body'], '0123456789' * 500, 'keep-alive 1')
335
336        resp = self.post(
337            headers={
338                'Host': 'localhost',
339                'Connection': 'close',
340                'Content-Type': 'text/html',
341            },
342            sock=sock,
343            body='0123456789',
344        )
345
346        self.assertEqual(resp['body'], '0123456789', 'keep-alive 2')
347
348
349if __name__ == '__main__':
350    TestRubyApplication.main()
351