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