xref: /unit/test/test_access_log.py (revision 1248:1cdb6a4dd024)
1import os
2import re
3import time
4import unittest
5from subprocess import call
6from unit.applications.lang.python import TestApplicationPython
7
8
9class TestAccessLog(TestApplicationPython):
10    prerequisites = {'modules': ['python']}
11
12    def load(self, script):
13        super().load(script)
14
15        self.assertIn(
16            'success',
17            self.conf('"' + self.testdir + '/access.log"', 'access_log'),
18            'access_log configure',
19        )
20
21    def wait_for_record(self, pattern, name='access.log'):
22        return super().wait_for_record(pattern, name)
23
24    def test_access_log_keepalive(self):
25        self.load('mirror')
26
27        self.assertEqual(self.get()['status'], 200, 'init')
28
29        (resp, sock) = self.post(
30            headers={
31                'Host': 'localhost',
32                'Connection': 'keep-alive',
33                'Content-Type': 'text/html',
34            },
35            start=True,
36            body='01234',
37            read_timeout=1,
38        )
39
40        self.assertIsNotNone(
41            self.wait_for_record(r'"POST / HTTP/1.1" 200 5'), 'keepalive 1'
42        )
43
44        resp = self.post(
45            headers={
46                'Host': 'localhost',
47                'Connection': 'close',
48                'Content-Type': 'text/html',
49            },
50            sock=sock,
51            body='0123456789',
52        )
53
54        self.stop()
55
56        self.assertIsNotNone(
57            self.wait_for_record(r'"POST / HTTP/1.1" 200 10'), 'keepalive 2'
58        )
59
60    def test_access_log_pipeline(self):
61        self.load('empty')
62
63        self.http(
64            b"""GET / HTTP/1.1
65Host: localhost
66Referer: Referer-1
67
68GET / HTTP/1.1
69Host: localhost
70Referer: Referer-2
71
72GET / HTTP/1.1
73Host: localhost
74Referer: Referer-3
75Connection: close
76
77""",
78            raw_resp=True,
79            raw=True,
80        )
81
82        self.stop()
83
84        self.assertIsNotNone(
85            self.wait_for_record(r'"GET / HTTP/1.1" 200 0 "Referer-1" "-"'),
86            'pipeline 1',
87        )
88        self.assertIsNotNone(
89            self.wait_for_record(r'"GET / HTTP/1.1" 200 0 "Referer-2" "-"'),
90            'pipeline 2',
91        )
92        self.assertIsNotNone(
93            self.wait_for_record(r'"GET / HTTP/1.1" 200 0 "Referer-3" "-"'),
94            'pipeline 3',
95        )
96
97    def test_access_log_ipv6(self):
98        self.load('empty')
99
100        self.conf({"[::1]:7080": {"pass": "applications/empty"}}, 'listeners')
101
102        self.get(sock_type='ipv6')
103
104        self.stop()
105
106        self.assertIsNotNone(
107            self.wait_for_record(
108                r'::1 - - \[.+\] "GET / HTTP/1.1" 200 0 "-" "-"'
109            ),
110            'ipv6',
111        )
112
113    def test_access_log_unix(self):
114        self.load('empty')
115
116        addr = self.testdir + '/sock'
117
118        self.conf(
119            {"unix:" + addr: {"pass": "applications/empty"}}, 'listeners'
120        )
121
122        self.get(sock_type='unix', addr=addr)
123
124        self.stop()
125
126        self.assertIsNotNone(
127            self.wait_for_record(
128                r'unix: - - \[.+\] "GET / HTTP/1.1" 200 0 "-" "-"'
129            ),
130            'unix',
131        )
132
133    def test_access_log_referer(self):
134        self.load('empty')
135
136        self.get(
137            headers={
138                'Host': 'localhost',
139                'Referer': 'referer-value',
140                'Connection': 'close',
141            }
142        )
143
144        self.stop()
145
146        self.assertIsNotNone(
147            self.wait_for_record(
148                r'"GET / HTTP/1.1" 200 0 "referer-value" "-"'
149            ),
150            'referer',
151        )
152
153    def test_access_log_user_agent(self):
154        self.load('empty')
155
156        self.get(
157            headers={
158                'Host': 'localhost',
159                'User-Agent': 'user-agent-value',
160                'Connection': 'close',
161            }
162        )
163
164        self.stop()
165
166        self.assertIsNotNone(
167            self.wait_for_record(
168                r'"GET / HTTP/1.1" 200 0 "-" "user-agent-value"'
169            ),
170            'user agent',
171        )
172
173    def test_access_log_http10(self):
174        self.load('empty')
175
176        self.get(http_10=True)
177
178        self.stop()
179
180        self.assertIsNotNone(
181            self.wait_for_record(r'"GET / HTTP/1.0" 200 0 "-" "-"'), 'http 1.0'
182        )
183
184    def test_access_log_partial(self):
185        self.load('empty')
186
187        self.assertEqual(self.post()['status'], 200, 'init')
188
189        resp = self.http(b"""GE""", raw=True, read_timeout=1)
190
191        time.sleep(1)
192
193        self.stop()
194
195        self.assertIsNotNone(
196            self.wait_for_record(r'"GE" 400 0 "-" "-"'), 'partial'
197        )
198
199    def test_access_log_partial_2(self):
200        self.load('empty')
201
202        self.assertEqual(self.post()['status'], 200, 'init')
203
204        self.http(b"""GET /\n""", raw=True)
205
206        self.stop()
207
208        self.assertIsNotNone(
209            self.wait_for_record(r'"GET /" 400 \d+ "-" "-"'), 'partial 2'
210        )
211
212    def test_access_log_partial_3(self):
213        self.load('empty')
214
215        self.assertEqual(self.post()['status'], 200, 'init')
216
217        resp = self.http(b"""GET / HTTP/1.1""", raw=True, read_timeout=1)
218
219        time.sleep(1)
220
221        self.stop()
222
223        self.assertIsNotNone(
224            self.wait_for_record(r'"GET /" 400 0 "-" "-"'), 'partial 3'
225        )
226
227    def test_access_log_partial_4(self):
228        self.load('empty')
229
230        self.assertEqual(self.post()['status'], 200, 'init')
231
232        resp = self.http(b"""GET / HTTP/1.1\n""", raw=True, read_timeout=1)
233
234        time.sleep(1)
235
236        self.stop()
237
238        self.assertIsNotNone(
239            self.wait_for_record(r'"GET / HTTP/1.1" 400 0 "-" "-"'),
240            'partial 4',
241        )
242
243    @unittest.skip('not yet')
244    def test_access_log_partial_5(self):
245        self.load('empty')
246
247        self.assertEqual(self.post()['status'], 200, 'init')
248
249        self.get(headers={'Connection': 'close'})
250
251        self.stop()
252
253        self.assertIsNotNone(
254            self.wait_for_record(r'"GET / HTTP/1.1" 400 \d+ "-" "-"'),
255            'partial 5',
256        )
257
258    def test_access_log_get_parameters(self):
259        self.load('empty')
260
261        self.get(url='/?blah&var=val')
262
263        self.stop()
264
265        self.assertIsNotNone(
266            self.wait_for_record(
267                r'"GET /\?blah&var=val HTTP/1.1" 200 0 "-" "-"'
268            ),
269            'get parameters',
270        )
271
272    def test_access_log_delete(self):
273        self.load('empty')
274
275        self.conf_delete('access_log')
276
277        self.get(url='/delete')
278
279        self.stop()
280
281        self.assertIsNone(
282            self.search_in_log(r'/delete', 'access.log'), 'delete'
283        )
284
285    def test_access_log_change(self):
286        self.load('empty')
287
288        self.get()
289
290        self.conf('"' + self.testdir + '/new.log"', 'access_log')
291
292        self.get()
293
294        self.stop()
295
296        self.assertIsNotNone(
297            self.wait_for_record(r'"GET / HTTP/1.1" 200 0 "-" "-"', 'new.log'),
298            'change',
299        )
300
301if __name__ == '__main__':
302    TestAccessLog.main()
303