xref: /unit/test/test_configuration.py (revision 1871)
11596Szelenkov@nginx.comimport pytest
21848Szelenkov@nginx.com
3*1871Szelenkov@nginx.comimport socket
41019Szelenkov@nginx.comfrom unit.control import TestControl
5484Szelenkov@nginx.com
61017Szelenkov@nginx.com
71019Szelenkov@nginx.comclass TestConfiguration(TestControl):
81467Szelenkov@nginx.com    prerequisites = {'modules': {'python': 'any'}}
9484Szelenkov@nginx.com
10719Szelenkov@nginx.com    def test_json_empty(self):
111596Szelenkov@nginx.com        assert 'error' in self.conf(''), 'empty'
12719Szelenkov@nginx.com
13495Szelenkov@nginx.com    def test_json_leading_zero(self):
141596Szelenkov@nginx.com        assert 'error' in self.conf('00'), 'leading zero'
15484Szelenkov@nginx.com
16495Szelenkov@nginx.com    def test_json_unicode(self):
171596Szelenkov@nginx.com        assert 'success' in self.conf(
181635Szelenkov@nginx.com            u"""
19495Szelenkov@nginx.com            {
20495Szelenkov@nginx.com                "ap\u0070": {
21495Szelenkov@nginx.com                    "type": "\u0070ython",
22507Smax.romanov@nginx.com                    "processes": { "spare": 0 },
23495Szelenkov@nginx.com                    "path": "\u002Fapp",
24495Szelenkov@nginx.com                    "module": "wsgi"
25495Szelenkov@nginx.com                }
26495Szelenkov@nginx.com            }
271017Szelenkov@nginx.com            """,
281596Szelenkov@nginx.com            'applications',
291596Szelenkov@nginx.com        ), 'unicode'
30484Szelenkov@nginx.com
311596Szelenkov@nginx.com        assert self.conf_get('applications') == {
321596Szelenkov@nginx.com            "app": {
331596Szelenkov@nginx.com                "type": "python",
341596Szelenkov@nginx.com                "processes": {"spare": 0},
351596Szelenkov@nginx.com                "path": "/app",
361596Szelenkov@nginx.com                "module": "wsgi",
371596Szelenkov@nginx.com            }
381596Szelenkov@nginx.com        }, 'unicode get'
391596Szelenkov@nginx.com
401596Szelenkov@nginx.com    def test_json_unicode_2(self):
411596Szelenkov@nginx.com        assert 'success' in self.conf(
421017Szelenkov@nginx.com            {
431596Szelenkov@nginx.com                "приложение": {
441017Szelenkov@nginx.com                    "type": "python",
451017Szelenkov@nginx.com                    "processes": {"spare": 0},
461017Szelenkov@nginx.com                    "path": "/app",
471017Szelenkov@nginx.com                    "module": "wsgi",
481017Szelenkov@nginx.com                }
491017Szelenkov@nginx.com            },
501596Szelenkov@nginx.com            'applications',
511596Szelenkov@nginx.com        ), 'unicode 2'
52555Szelenkov@nginx.com
531596Szelenkov@nginx.com        assert 'приложение' in self.conf_get('applications'), 'unicode 2 get'
54555Szelenkov@nginx.com
55495Szelenkov@nginx.com    def test_json_unicode_number(self):
561635Szelenkov@nginx.com        assert 'success' in self.conf(
571635Szelenkov@nginx.com            u"""
58495Szelenkov@nginx.com            {
59495Szelenkov@nginx.com                "app": {
60495Szelenkov@nginx.com                    "type": "python",
61507Smax.romanov@nginx.com                    "processes": { "spare": \u0030 },
62495Szelenkov@nginx.com                    "path": "/app",
63495Szelenkov@nginx.com                    "module": "wsgi"
64495Szelenkov@nginx.com                }
65495Szelenkov@nginx.com            }
661017Szelenkov@nginx.com            """,
671596Szelenkov@nginx.com            'applications',
681596Szelenkov@nginx.com        ), 'unicode number'
69495Szelenkov@nginx.com
701426Szelenkov@nginx.com    def test_json_utf8_bom(self):
711596Szelenkov@nginx.com        assert 'success' in self.conf(
721596Szelenkov@nginx.com            b"""\xEF\xBB\xBF
731426Szelenkov@nginx.com            {
741426Szelenkov@nginx.com                "app": {
751426Szelenkov@nginx.com                    "type": "python",
761426Szelenkov@nginx.com                    "processes": {"spare": 0},
771426Szelenkov@nginx.com                    "path": "/app",
781426Szelenkov@nginx.com                    "module": "wsgi"
791426Szelenkov@nginx.com                }
801426Szelenkov@nginx.com            }
811426Szelenkov@nginx.com            """,
821596Szelenkov@nginx.com            'applications',
831596Szelenkov@nginx.com        ), 'UTF-8 BOM'
841426Szelenkov@nginx.com
851427Szelenkov@nginx.com    def test_json_comment_single_line(self):
861596Szelenkov@nginx.com        assert 'success' in self.conf(
871596Szelenkov@nginx.com            b"""
881427Szelenkov@nginx.com            // this is bridge
891427Szelenkov@nginx.com            {
901427Szelenkov@nginx.com                "//app": {
911427Szelenkov@nginx.com                    "type": "python", // end line
921427Szelenkov@nginx.com                    "processes": {"spare": 0},
931427Szelenkov@nginx.com                    // inside of block
941427Szelenkov@nginx.com                    "path": "/app",
951427Szelenkov@nginx.com                    "module": "wsgi"
961427Szelenkov@nginx.com                }
971427Szelenkov@nginx.com                // double //
981427Szelenkov@nginx.com            }
991427Szelenkov@nginx.com            // end of json \xEF\t
1001427Szelenkov@nginx.com            """,
1011596Szelenkov@nginx.com            'applications',
1021596Szelenkov@nginx.com        ), 'single line comments'
1031427Szelenkov@nginx.com
1041427Szelenkov@nginx.com    def test_json_comment_multi_line(self):
1051596Szelenkov@nginx.com        assert 'success' in self.conf(
1061596Szelenkov@nginx.com            b"""
1071427Szelenkov@nginx.com            /* this is bridge */
1081427Szelenkov@nginx.com            {
1091427Szelenkov@nginx.com                "/*app": {
1101427Szelenkov@nginx.com                /**
1111427Szelenkov@nginx.com                 * multiple lines
1121427Szelenkov@nginx.com                 **/
1131427Szelenkov@nginx.com                    "type": "python",
1141427Szelenkov@nginx.com                    "processes": /* inline */ {"spare": 0},
1151427Szelenkov@nginx.com                    "path": "/app",
1161427Szelenkov@nginx.com                    "module": "wsgi"
1171427Szelenkov@nginx.com                    /*
1181427Szelenkov@nginx.com                    // end of block */
1191427Szelenkov@nginx.com                }
1201427Szelenkov@nginx.com                /* blah * / blah /* blah */
1211427Szelenkov@nginx.com            }
1221427Szelenkov@nginx.com            /* end of json \xEF\t\b */
1231427Szelenkov@nginx.com            """,
1241596Szelenkov@nginx.com            'applications',
1251596Szelenkov@nginx.com        ), 'multi line comments'
1261427Szelenkov@nginx.com
1271427Szelenkov@nginx.com    def test_json_comment_invalid(self):
1281596Szelenkov@nginx.com        assert 'error' in self.conf(b'/{}', 'applications'), 'slash'
1291596Szelenkov@nginx.com        assert 'error' in self.conf(b'//{}', 'applications'), 'comment'
1301596Szelenkov@nginx.com        assert 'error' in self.conf(b'{} /', 'applications'), 'slash end'
1311596Szelenkov@nginx.com        assert 'error' in self.conf(b'/*{}', 'applications'), 'slash star'
1321596Szelenkov@nginx.com        assert 'error' in self.conf(b'{} /*', 'applications'), 'slash star end'
1331427Szelenkov@nginx.com
134495Szelenkov@nginx.com    def test_applications_open_brace(self):
1351596Szelenkov@nginx.com        assert 'error' in self.conf('{', 'applications'), 'open brace'
136495Szelenkov@nginx.com
137495Szelenkov@nginx.com    def test_applications_string(self):
1381596Szelenkov@nginx.com        assert 'error' in self.conf('"{}"', 'applications'), 'string'
139495Szelenkov@nginx.com
1401596Szelenkov@nginx.com    @pytest.mark.skip('not yet, unsafe')
141495Szelenkov@nginx.com    def test_applications_type_only(self):
1421596Szelenkov@nginx.com        assert 'error' in self.conf(
1431596Szelenkov@nginx.com            {"app": {"type": "python"}}, 'applications'
1441596Szelenkov@nginx.com        ), 'type only'
145484Szelenkov@nginx.com
146495Szelenkov@nginx.com    def test_applications_miss_quote(self):
1471596Szelenkov@nginx.com        assert 'error' in self.conf(
1481596Szelenkov@nginx.com            """
149484Szelenkov@nginx.com            {
150484Szelenkov@nginx.com                app": {
151484Szelenkov@nginx.com                    "type": "python",
152507Smax.romanov@nginx.com                    "processes": { "spare": 0 },
153484Szelenkov@nginx.com                    "path": "/app",
154484Szelenkov@nginx.com                    "module": "wsgi"
155484Szelenkov@nginx.com                }
156484Szelenkov@nginx.com            }
1571017Szelenkov@nginx.com            """,
1581596Szelenkov@nginx.com            'applications',
1591596Szelenkov@nginx.com        ), 'miss quote'
160484Szelenkov@nginx.com
161495Szelenkov@nginx.com    def test_applications_miss_colon(self):
1621596Szelenkov@nginx.com        assert 'error' in self.conf(
1631596Szelenkov@nginx.com            """
164484Szelenkov@nginx.com            {
165484Szelenkov@nginx.com                "app" {
166484Szelenkov@nginx.com                    "type": "python",
167507Smax.romanov@nginx.com                    "processes": { "spare": 0 },
168484Szelenkov@nginx.com                    "path": "/app",
169484Szelenkov@nginx.com                    "module": "wsgi"
170484Szelenkov@nginx.com                }
171484Szelenkov@nginx.com            }
1721017Szelenkov@nginx.com            """,
1731596Szelenkov@nginx.com            'applications',
1741596Szelenkov@nginx.com        ), 'miss colon'
175484Szelenkov@nginx.com
176495Szelenkov@nginx.com    def test_applications_miss_comma(self):
1771596Szelenkov@nginx.com        assert 'error' in self.conf(
1781596Szelenkov@nginx.com            """
179484Szelenkov@nginx.com            {
180484Szelenkov@nginx.com                "app": {
181484Szelenkov@nginx.com                    "type": "python"
182507Smax.romanov@nginx.com                    "processes": { "spare": 0 },
183484Szelenkov@nginx.com                    "path": "/app",
184484Szelenkov@nginx.com                    "module": "wsgi"
185484Szelenkov@nginx.com                }
186484Szelenkov@nginx.com            }
1871017Szelenkov@nginx.com            """,
1881596Szelenkov@nginx.com            'applications',
1891596Szelenkov@nginx.com        ), 'miss comma'
190484Szelenkov@nginx.com
191495Szelenkov@nginx.com    def test_applications_skip_spaces(self):
1921596Szelenkov@nginx.com        assert 'success' in self.conf(
1931596Szelenkov@nginx.com            b'{ \n\r\t}', 'applications'
1941596Szelenkov@nginx.com        ), 'skip spaces'
195484Szelenkov@nginx.com
196495Szelenkov@nginx.com    def test_applications_relative_path(self):
1971596Szelenkov@nginx.com        assert 'success' in self.conf(
1981596Szelenkov@nginx.com            {
1991596Szelenkov@nginx.com                "app": {
2001596Szelenkov@nginx.com                    "type": "python",
2011596Szelenkov@nginx.com                    "processes": {"spare": 0},
2021596Szelenkov@nginx.com                    "path": "../app",
2031596Szelenkov@nginx.com                    "module": "wsgi",
2041596Szelenkov@nginx.com                }
2051596Szelenkov@nginx.com            },
2061596Szelenkov@nginx.com            'applications',
2071596Szelenkov@nginx.com        ), 'relative path'
2081596Szelenkov@nginx.com
2091596Szelenkov@nginx.com    @pytest.mark.skip('not yet, unsafe')
2101596Szelenkov@nginx.com    def test_listeners_empty(self):
2111596Szelenkov@nginx.com        assert 'error' in self.conf(
2121596Szelenkov@nginx.com            {"*:7080": {}}, 'listeners'
2131596Szelenkov@nginx.com        ), 'listener empty'
2141596Szelenkov@nginx.com
2151596Szelenkov@nginx.com    def test_listeners_no_app(self):
2161596Szelenkov@nginx.com        assert 'error' in self.conf(
2171596Szelenkov@nginx.com            {"*:7080": {"pass": "applications/app"}}, 'listeners'
2181596Szelenkov@nginx.com        ), 'listeners no app'
2191596Szelenkov@nginx.com
2201596Szelenkov@nginx.com    def test_listeners_wildcard(self):
2211596Szelenkov@nginx.com        assert 'success' in self.conf(
2221596Szelenkov@nginx.com            {
2231596Szelenkov@nginx.com                "listeners": {"*:7080": {"pass": "applications/app"}},
2241596Szelenkov@nginx.com                "applications": {
2251017Szelenkov@nginx.com                    "app": {
2261017Szelenkov@nginx.com                        "type": "python",
2271017Szelenkov@nginx.com                        "processes": {"spare": 0},
2281596Szelenkov@nginx.com                        "path": "/app",
2291017Szelenkov@nginx.com                        "module": "wsgi",
2301017Szelenkov@nginx.com                    }
2311017Szelenkov@nginx.com                },
2321596Szelenkov@nginx.com            }
2331596Szelenkov@nginx.com        ), 'listeners wildcard'
234495Szelenkov@nginx.com
235495Szelenkov@nginx.com    def test_listeners_explicit(self):
2361596Szelenkov@nginx.com        assert 'success' in self.conf(
2371596Szelenkov@nginx.com            {
2381596Szelenkov@nginx.com                "listeners": {"127.0.0.1:7080": {"pass": "applications/app"}},
2391596Szelenkov@nginx.com                "applications": {
2401596Szelenkov@nginx.com                    "app": {
2411596Szelenkov@nginx.com                        "type": "python",
2421596Szelenkov@nginx.com                        "processes": {"spare": 0},
2431596Szelenkov@nginx.com                        "path": "/app",
2441596Szelenkov@nginx.com                        "module": "wsgi",
2451596Szelenkov@nginx.com                    }
2461596Szelenkov@nginx.com                },
2471596Szelenkov@nginx.com            }
2481596Szelenkov@nginx.com        ), 'explicit'
249484Szelenkov@nginx.com
250495Szelenkov@nginx.com    def test_listeners_explicit_ipv6(self):
2511596Szelenkov@nginx.com        assert 'success' in self.conf(
2521596Szelenkov@nginx.com            {
2531596Szelenkov@nginx.com                "listeners": {"[::1]:7080": {"pass": "applications/app"}},
2541596Szelenkov@nginx.com                "applications": {
2551596Szelenkov@nginx.com                    "app": {
2561596Szelenkov@nginx.com                        "type": "python",
2571596Szelenkov@nginx.com                        "processes": {"spare": 0},
2581596Szelenkov@nginx.com                        "path": "/app",
2591596Szelenkov@nginx.com                        "module": "wsgi",
2601596Szelenkov@nginx.com                    }
2611596Szelenkov@nginx.com                },
2621596Szelenkov@nginx.com            }
2631596Szelenkov@nginx.com        ), 'explicit ipv6'
264495Szelenkov@nginx.com
265*1871Szelenkov@nginx.com    def test_listeners_port_release(self):
266*1871Szelenkov@nginx.com        for i in range(10):
267*1871Szelenkov@nginx.com            fail = False
268*1871Szelenkov@nginx.com            with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
269*1871Szelenkov@nginx.com                s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
270*1871Szelenkov@nginx.com
271*1871Szelenkov@nginx.com                self.conf(
272*1871Szelenkov@nginx.com                    {
273*1871Szelenkov@nginx.com                        "listeners": {"127.0.0.1:7080": {"pass": "routes"}},
274*1871Szelenkov@nginx.com                        "routes": [],
275*1871Szelenkov@nginx.com                    }
276*1871Szelenkov@nginx.com                )
277*1871Szelenkov@nginx.com
278*1871Szelenkov@nginx.com                resp = self.conf({"listeners": {}, "applications": {}})
279*1871Szelenkov@nginx.com
280*1871Szelenkov@nginx.com                try:
281*1871Szelenkov@nginx.com                    s.bind(('127.0.0.1', 7080))
282*1871Szelenkov@nginx.com                    s.listen()
283*1871Szelenkov@nginx.com
284*1871Szelenkov@nginx.com                except OSError:
285*1871Szelenkov@nginx.com                    fail = True
286*1871Szelenkov@nginx.com
287*1871Szelenkov@nginx.com                if fail:
288*1871Szelenkov@nginx.com                    pytest.fail('cannot bind or listen to the address')
289*1871Szelenkov@nginx.com
290*1871Szelenkov@nginx.com                assert 'success' in resp, 'port release'
291*1871Szelenkov@nginx.com
2921596Szelenkov@nginx.com    @pytest.mark.skip('not yet, unsafe')
293495Szelenkov@nginx.com    def test_listeners_no_port(self):
2941596Szelenkov@nginx.com        assert 'error' in self.conf(
2951596Szelenkov@nginx.com            {
2961596Szelenkov@nginx.com                "listeners": {"127.0.0.1": {"pass": "applications/app"}},
2971596Szelenkov@nginx.com                "applications": {
2981596Szelenkov@nginx.com                    "app": {
2991596Szelenkov@nginx.com                        "type": "python",
3001596Szelenkov@nginx.com                        "processes": {"spare": 0},
3011596Szelenkov@nginx.com                        "path": "/app",
3021596Szelenkov@nginx.com                        "module": "wsgi",
3031596Szelenkov@nginx.com                    }
3041596Szelenkov@nginx.com                },
3051596Szelenkov@nginx.com            }
3061596Szelenkov@nginx.com        ), 'no port'
307484Szelenkov@nginx.com
308917Szelenkov@nginx.com    def test_json_application_name_large(self):
309917Szelenkov@nginx.com        name = "X" * 1024 * 1024
310917Szelenkov@nginx.com
3111596Szelenkov@nginx.com        assert 'success' in self.conf(
3121596Szelenkov@nginx.com            {
3131596Szelenkov@nginx.com                "listeners": {"*:7080": {"pass": "applications/" + name}},
3141596Szelenkov@nginx.com                "applications": {
3151596Szelenkov@nginx.com                    name: {
3161596Szelenkov@nginx.com                        "type": "python",
3171596Szelenkov@nginx.com                        "processes": {"spare": 0},
3181596Szelenkov@nginx.com                        "path": "/app",
3191596Szelenkov@nginx.com                        "module": "wsgi",
3201596Szelenkov@nginx.com                    }
3211596Szelenkov@nginx.com                },
3221596Szelenkov@nginx.com            }
3231017Szelenkov@nginx.com        )
324917Szelenkov@nginx.com
3251596Szelenkov@nginx.com    @pytest.mark.skip('not yet')
326917Szelenkov@nginx.com    def test_json_application_many(self):
327946Szelenkov@nginx.com        apps = 999
328917Szelenkov@nginx.com
329917Szelenkov@nginx.com        conf = {
3301017Szelenkov@nginx.com            "applications": {
3311017Szelenkov@nginx.com                "app-"
3321017Szelenkov@nginx.com                + str(a): {
333917Szelenkov@nginx.com                    "type": "python",
3341017Szelenkov@nginx.com                    "processes": {"spare": 0},
335917Szelenkov@nginx.com                    "path": "/app",
3361017Szelenkov@nginx.com                    "module": "wsgi",
3371017Szelenkov@nginx.com                }
3381017Szelenkov@nginx.com                for a in range(apps)
339917Szelenkov@nginx.com            },
340917Szelenkov@nginx.com            "listeners": {
3411041Svbart@nginx.com                "*:" + str(7000 + a): {"pass": "applications/app-" + str(a)}
3421017Szelenkov@nginx.com                for a in range(apps)
3431017Szelenkov@nginx.com            },
344917Szelenkov@nginx.com        }
345917Szelenkov@nginx.com
3461596Szelenkov@nginx.com        assert 'success' in self.conf(conf)
347917Szelenkov@nginx.com
3481006Smax.romanov@nginx.com    def test_json_application_many2(self):
3491006Smax.romanov@nginx.com        conf = {
3501017Szelenkov@nginx.com            "applications": {
3511017Szelenkov@nginx.com                "app-"
3521017Szelenkov@nginx.com                + str(a): {
3531006Smax.romanov@nginx.com                    "type": "python",
3541017Szelenkov@nginx.com                    "processes": {"spare": 0},
3551006Smax.romanov@nginx.com                    "path": "/app",
3561017Szelenkov@nginx.com                    "module": "wsgi",
3571017Szelenkov@nginx.com                }
3581551Smax.romanov@nginx.com                # Larger number of applications can cause test fail with default
3591551Smax.romanov@nginx.com                # open files limit due to the lack of file descriptors.
3601551Smax.romanov@nginx.com                for a in range(100)
3611006Smax.romanov@nginx.com            },
3621232Szelenkov@nginx.com            "listeners": {"*:7080": {"pass": "applications/app-1"}},
3631006Smax.romanov@nginx.com        }
3641006Smax.romanov@nginx.com
3651596Szelenkov@nginx.com        assert 'success' in self.conf(conf)
3661006Smax.romanov@nginx.com
3671736Szelenkov@nginx.com    def test_unprivileged_user_error(self, is_su, skip_alert):
3681596Szelenkov@nginx.com        skip_alert(r'cannot set user "root"', r'failed to apply new conf')
3691596Szelenkov@nginx.com        if is_su:
3701596Szelenkov@nginx.com            pytest.skip('unprivileged tests')
3711569St.nateldemoura@f5.com
3721596Szelenkov@nginx.com        assert 'error' in self.conf(
3731596Szelenkov@nginx.com            {
3741596Szelenkov@nginx.com                "app": {
3751596Szelenkov@nginx.com                    "type": "external",
3761596Szelenkov@nginx.com                    "processes": 1,
3771596Szelenkov@nginx.com                    "executable": "/app",
3781596Szelenkov@nginx.com                    "user": "root",
3791596Szelenkov@nginx.com                }
3801596Szelenkov@nginx.com            },
3811596Szelenkov@nginx.com            'applications',
3821596Szelenkov@nginx.com        ), 'setting user'
383