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