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