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