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