11396Szelenkov@nginx.comimport os 21396Szelenkov@nginx.comimport re 31477Szelenkov@nginx.com 41396Szelenkov@nginx.comfrom unit.applications.lang.python import TestApplicationPython 5*1730Szelenkov@nginx.comfrom unit.option import option 61396Szelenkov@nginx.com 71396Szelenkov@nginx.com 81396Szelenkov@nginx.comclass TestUpstreamsRR(TestApplicationPython): 91467Szelenkov@nginx.com prerequisites = {'modules': {'python': 'any'}} 101396Szelenkov@nginx.com 111596Szelenkov@nginx.com def setup_method(self): 121596Szelenkov@nginx.com assert 'success' in self.conf( 131596Szelenkov@nginx.com { 141596Szelenkov@nginx.com "listeners": { 151596Szelenkov@nginx.com "*:7080": {"pass": "upstreams/one"}, 161596Szelenkov@nginx.com "*:7090": {"pass": "upstreams/two"}, 171596Szelenkov@nginx.com "*:7081": {"pass": "routes/one"}, 181596Szelenkov@nginx.com "*:7082": {"pass": "routes/two"}, 191596Szelenkov@nginx.com "*:7083": {"pass": "routes/three"}, 201596Szelenkov@nginx.com }, 211596Szelenkov@nginx.com "upstreams": { 221596Szelenkov@nginx.com "one": { 231596Szelenkov@nginx.com "servers": { 241596Szelenkov@nginx.com "127.0.0.1:7081": {}, 251596Szelenkov@nginx.com "127.0.0.1:7082": {}, 261396Szelenkov@nginx.com }, 271396Szelenkov@nginx.com }, 281596Szelenkov@nginx.com "two": { 291596Szelenkov@nginx.com "servers": { 301596Szelenkov@nginx.com "127.0.0.1:7081": {}, 311596Szelenkov@nginx.com "127.0.0.1:7082": {}, 321596Szelenkov@nginx.com }, 331396Szelenkov@nginx.com }, 341396Szelenkov@nginx.com }, 351596Szelenkov@nginx.com "routes": { 361596Szelenkov@nginx.com "one": [{"action": {"return": 200}}], 371596Szelenkov@nginx.com "two": [{"action": {"return": 201}}], 381596Szelenkov@nginx.com "three": [{"action": {"return": 202}}], 391596Szelenkov@nginx.com }, 401596Szelenkov@nginx.com "applications": {}, 411596Szelenkov@nginx.com }, 421596Szelenkov@nginx.com ), 'upstreams initial configuration' 431396Szelenkov@nginx.com 441396Szelenkov@nginx.com self.cpu_count = os.cpu_count() 451396Szelenkov@nginx.com 461396Szelenkov@nginx.com def get_resps(self, req=100, port=7080): 471396Szelenkov@nginx.com resps = [0] 481445Szelenkov@nginx.com 491396Szelenkov@nginx.com for _ in range(req): 501445Szelenkov@nginx.com status = self.get(port=port)['status'] 511445Szelenkov@nginx.com if 200 > status or status > 209: 521445Szelenkov@nginx.com continue 531396Szelenkov@nginx.com 541445Szelenkov@nginx.com ups = status % 10 551445Szelenkov@nginx.com if ups > len(resps) - 1: 561445Szelenkov@nginx.com resps.extend([0] * (ups - len(resps) + 1)) 571396Szelenkov@nginx.com 581445Szelenkov@nginx.com resps[ups] += 1 591396Szelenkov@nginx.com 601396Szelenkov@nginx.com return resps 611396Szelenkov@nginx.com 621396Szelenkov@nginx.com def get_resps_sc(self, req=100, port=7080): 631396Szelenkov@nginx.com to_send = b"""GET / HTTP/1.1 641396Szelenkov@nginx.comHost: localhost 651396Szelenkov@nginx.com 661396Szelenkov@nginx.com""" * ( 671396Szelenkov@nginx.com req - 1 681396Szelenkov@nginx.com ) 691396Szelenkov@nginx.com 701396Szelenkov@nginx.com to_send += b"""GET / HTTP/1.1 711396Szelenkov@nginx.comHost: localhost 721396Szelenkov@nginx.comConnection: close 731396Szelenkov@nginx.com 741396Szelenkov@nginx.com""" 751396Szelenkov@nginx.com 761396Szelenkov@nginx.com resp = self.http(to_send, raw_resp=True, raw=True, port=port) 771445Szelenkov@nginx.com status = re.findall(r'HTTP\/\d\.\d\s(\d\d\d)', resp) 781445Szelenkov@nginx.com status = list(filter(lambda x: x[:2] == '20', status)) 791445Szelenkov@nginx.com ups = list(map(lambda x: int(x[-1]), status)) 801396Szelenkov@nginx.com 811445Szelenkov@nginx.com resps = [0] * (max(ups) + 1) 821396Szelenkov@nginx.com for i in range(len(ups)): 831445Szelenkov@nginx.com resps[ups[i]] += 1 841396Szelenkov@nginx.com 851396Szelenkov@nginx.com return resps 861396Szelenkov@nginx.com 871396Szelenkov@nginx.com def test_upstreams_rr_no_weight(self): 881396Szelenkov@nginx.com resps = self.get_resps() 891596Szelenkov@nginx.com assert sum(resps) == 100, 'no weight sum' 901596Szelenkov@nginx.com assert abs(resps[0] - resps[1]) <= self.cpu_count, 'no weight' 911396Szelenkov@nginx.com 921596Szelenkov@nginx.com assert 'success' in self.conf_delete( 931596Szelenkov@nginx.com 'upstreams/one/servers/127.0.0.1:7081' 941596Szelenkov@nginx.com ), 'no weight server remove' 951396Szelenkov@nginx.com 961396Szelenkov@nginx.com resps = self.get_resps(req=50) 971596Szelenkov@nginx.com assert resps[1] == 50, 'no weight 2' 981396Szelenkov@nginx.com 991596Szelenkov@nginx.com assert 'success' in self.conf( 1001596Szelenkov@nginx.com {}, 'upstreams/one/servers/127.0.0.1:7081' 1011596Szelenkov@nginx.com ), 'no weight server revert' 1021396Szelenkov@nginx.com 1031396Szelenkov@nginx.com resps = self.get_resps() 1041596Szelenkov@nginx.com assert sum(resps) == 100, 'no weight 3 sum' 1051596Szelenkov@nginx.com assert abs(resps[0] - resps[1]) <= self.cpu_count, 'no weight 3' 1061396Szelenkov@nginx.com 1071596Szelenkov@nginx.com assert 'success' in self.conf( 1081596Szelenkov@nginx.com {}, 'upstreams/one/servers/127.0.0.1:7083' 1091596Szelenkov@nginx.com ), 'no weight server new' 1101396Szelenkov@nginx.com 1111396Szelenkov@nginx.com resps = self.get_resps() 1121596Szelenkov@nginx.com assert sum(resps) == 100, 'no weight 4 sum' 1131596Szelenkov@nginx.com assert max(resps) - min(resps) <= self.cpu_count, 'no weight 4' 1141396Szelenkov@nginx.com 1151396Szelenkov@nginx.com resps = self.get_resps_sc(req=30) 1161596Szelenkov@nginx.com assert resps[0] == 10, 'no weight 4 0' 1171596Szelenkov@nginx.com assert resps[1] == 10, 'no weight 4 1' 1181596Szelenkov@nginx.com assert resps[2] == 10, 'no weight 4 2' 1191396Szelenkov@nginx.com 1201396Szelenkov@nginx.com def test_upstreams_rr_weight(self): 1211596Szelenkov@nginx.com assert 'success' in self.conf( 1221596Szelenkov@nginx.com {"weight": 3}, 'upstreams/one/servers/127.0.0.1:7081' 1231596Szelenkov@nginx.com ), 'configure weight' 1241396Szelenkov@nginx.com 1251396Szelenkov@nginx.com resps = self.get_resps_sc() 1261596Szelenkov@nginx.com assert resps[0] == 75, 'weight 3 0' 1271596Szelenkov@nginx.com assert resps[1] == 25, 'weight 3 1' 1281396Szelenkov@nginx.com 1291596Szelenkov@nginx.com assert 'success' in self.conf_delete( 1301596Szelenkov@nginx.com 'upstreams/one/servers/127.0.0.1:7081/weight' 1311596Szelenkov@nginx.com ), 'configure weight remove' 1321396Szelenkov@nginx.com resps = self.get_resps_sc(req=10) 1331596Szelenkov@nginx.com assert resps[0] == 5, 'weight 0 0' 1341596Szelenkov@nginx.com assert resps[1] == 5, 'weight 0 1' 1351396Szelenkov@nginx.com 1361596Szelenkov@nginx.com assert 'success' in self.conf( 1371596Szelenkov@nginx.com '1', 'upstreams/one/servers/127.0.0.1:7081/weight' 1381596Szelenkov@nginx.com ), 'configure weight 1' 1391396Szelenkov@nginx.com 1401396Szelenkov@nginx.com resps = self.get_resps_sc() 1411596Szelenkov@nginx.com assert resps[0] == 50, 'weight 1 0' 1421596Szelenkov@nginx.com assert resps[1] == 50, 'weight 1 1' 1431396Szelenkov@nginx.com 1441596Szelenkov@nginx.com assert 'success' in self.conf( 1451596Szelenkov@nginx.com { 1461596Szelenkov@nginx.com "127.0.0.1:7081": {"weight": 3}, 1471596Szelenkov@nginx.com "127.0.0.1:7083": {"weight": 2}, 1481596Szelenkov@nginx.com }, 1491596Szelenkov@nginx.com 'upstreams/one/servers', 1501596Szelenkov@nginx.com ), 'configure weight 2' 1511396Szelenkov@nginx.com 1521396Szelenkov@nginx.com resps = self.get_resps_sc() 1531596Szelenkov@nginx.com assert resps[0] == 60, 'weight 2 0' 1541596Szelenkov@nginx.com assert resps[2] == 40, 'weight 2 1' 1551396Szelenkov@nginx.com 1561441Szelenkov@nginx.com def test_upstreams_rr_weight_rational(self): 1571441Szelenkov@nginx.com def set_weights(w1, w2): 1581596Szelenkov@nginx.com assert 'success' in self.conf( 1591596Szelenkov@nginx.com { 1601596Szelenkov@nginx.com "127.0.0.1:7081": {"weight": w1}, 1611596Szelenkov@nginx.com "127.0.0.1:7082": {"weight": w2}, 1621596Szelenkov@nginx.com }, 1631596Szelenkov@nginx.com 'upstreams/one/servers', 1641596Szelenkov@nginx.com ), 'configure weights' 1651441Szelenkov@nginx.com 1661441Szelenkov@nginx.com def check_reqs(w1, w2, reqs=10): 1671441Szelenkov@nginx.com resps = self.get_resps_sc(req=reqs) 1681596Szelenkov@nginx.com assert resps[0] == reqs * w1 / (w1 + w2), 'weight 1' 1691596Szelenkov@nginx.com assert resps[1] == reqs * w2 / (w1 + w2), 'weight 2' 1701441Szelenkov@nginx.com 1711441Szelenkov@nginx.com def check_weights(w1, w2): 1721441Szelenkov@nginx.com set_weights(w1, w2) 1731441Szelenkov@nginx.com check_reqs(w1, w2) 1741441Szelenkov@nginx.com 1751441Szelenkov@nginx.com check_weights(0, 1) 1761441Szelenkov@nginx.com check_weights(0, 999999.0123456) 1771441Szelenkov@nginx.com check_weights(1, 9) 1781441Szelenkov@nginx.com check_weights(100000, 900000) 1791596Szelenkov@nginx.com check_weights(1, 0.25) 1801441Szelenkov@nginx.com check_weights(1, 0.25) 1811596Szelenkov@nginx.com check_weights(0.2, 0.8) 1821441Szelenkov@nginx.com check_weights(1, 1.5) 1831596Szelenkov@nginx.com check_weights(1e-3, 1e-3) 1841441Szelenkov@nginx.com check_weights(1e-20, 1e-20) 1851441Szelenkov@nginx.com check_weights(1e4, 1e4) 1861441Szelenkov@nginx.com check_weights(1000000, 1000000) 1871441Szelenkov@nginx.com 1881441Szelenkov@nginx.com set_weights(0.25, 0.25) 1891596Szelenkov@nginx.com assert 'success' in self.conf_delete( 1901596Szelenkov@nginx.com 'upstreams/one/servers/127.0.0.1:7081/weight' 1911596Szelenkov@nginx.com ), 'delete weight' 1921441Szelenkov@nginx.com check_reqs(1, 0.25) 1931441Szelenkov@nginx.com 1941596Szelenkov@nginx.com assert 'success' in self.conf( 1951596Szelenkov@nginx.com { 1961596Szelenkov@nginx.com "127.0.0.1:7081": {"weight": 0.1}, 1971596Szelenkov@nginx.com "127.0.0.1:7082": {"weight": 1}, 1981596Szelenkov@nginx.com "127.0.0.1:7083": {"weight": 0.9}, 1991596Szelenkov@nginx.com }, 2001596Szelenkov@nginx.com 'upstreams/one/servers', 2011596Szelenkov@nginx.com ), 'configure weights' 2021441Szelenkov@nginx.com resps = self.get_resps_sc(req=20) 2031596Szelenkov@nginx.com assert resps[0] == 1, 'weight 3 1' 2041596Szelenkov@nginx.com assert resps[1] == 10, 'weight 3 2' 2051596Szelenkov@nginx.com assert resps[2] == 9, 'weight 3 3' 2061441Szelenkov@nginx.com 2071396Szelenkov@nginx.com def test_upstreams_rr_independent(self): 2081396Szelenkov@nginx.com def sum_resps(*args): 2091396Szelenkov@nginx.com sum = [0] * len(args[0]) 2101396Szelenkov@nginx.com for arg in args: 2111396Szelenkov@nginx.com sum = [x + y for x, y in zip(sum, arg)] 2121396Szelenkov@nginx.com 2131396Szelenkov@nginx.com return sum 2141396Szelenkov@nginx.com 2151396Szelenkov@nginx.com resps = self.get_resps_sc(req=30, port=7090) 2161596Szelenkov@nginx.com assert resps[0] == 15, 'dep two before 0' 2171596Szelenkov@nginx.com assert resps[1] == 15, 'dep two before 1' 2181396Szelenkov@nginx.com 2191396Szelenkov@nginx.com resps = self.get_resps_sc(req=30) 2201596Szelenkov@nginx.com assert resps[0] == 15, 'dep one before 0' 2211596Szelenkov@nginx.com assert resps[1] == 15, 'dep one before 1' 2221396Szelenkov@nginx.com 2231596Szelenkov@nginx.com assert 'success' in self.conf( 2241596Szelenkov@nginx.com '2', 'upstreams/two/servers/127.0.0.1:7081/weight' 2251596Szelenkov@nginx.com ), 'configure dep weight' 2261396Szelenkov@nginx.com 2271396Szelenkov@nginx.com resps = self.get_resps_sc(req=30, port=7090) 2281596Szelenkov@nginx.com assert resps[0] == 20, 'dep two 0' 2291596Szelenkov@nginx.com assert resps[1] == 10, 'dep two 1' 2301396Szelenkov@nginx.com 2311396Szelenkov@nginx.com resps = self.get_resps_sc(req=30) 2321596Szelenkov@nginx.com assert resps[0] == 15, 'dep one 0' 2331596Szelenkov@nginx.com assert resps[1] == 15, 'dep one 1' 2341396Szelenkov@nginx.com 2351596Szelenkov@nginx.com assert 'success' in self.conf( 2361596Szelenkov@nginx.com '1', 'upstreams/two/servers/127.0.0.1:7081/weight' 2371596Szelenkov@nginx.com ), 'configure dep weight 1' 2381396Szelenkov@nginx.com 2391396Szelenkov@nginx.com r_one, r_two = [0, 0], [0, 0] 2401396Szelenkov@nginx.com for _ in range(10): 2411396Szelenkov@nginx.com r_one = sum_resps(r_one, self.get_resps(req=10)) 2421396Szelenkov@nginx.com r_two = sum_resps(r_two, self.get_resps(req=10, port=7090)) 2431396Szelenkov@nginx.com 2441596Szelenkov@nginx.com assert sum(r_one) == 100, 'dep one mix sum' 2451596Szelenkov@nginx.com assert abs(r_one[0] - r_one[1]) <= self.cpu_count, 'dep one mix' 2461596Szelenkov@nginx.com assert sum(r_two) == 100, 'dep two mix sum' 2471596Szelenkov@nginx.com assert abs(r_two[0] - r_two[1]) <= self.cpu_count, 'dep two mix' 2481396Szelenkov@nginx.com 2491396Szelenkov@nginx.com def test_upstreams_rr_delay(self): 2501596Szelenkov@nginx.com assert 'success' in self.conf( 2511596Szelenkov@nginx.com { 2521596Szelenkov@nginx.com "listeners": { 2531596Szelenkov@nginx.com "*:7080": {"pass": "upstreams/one"}, 2541596Szelenkov@nginx.com "*:7081": {"pass": "routes"}, 2551596Szelenkov@nginx.com "*:7082": {"pass": "routes"}, 2561596Szelenkov@nginx.com }, 2571596Szelenkov@nginx.com "upstreams": { 2581596Szelenkov@nginx.com "one": { 2591596Szelenkov@nginx.com "servers": { 2601596Szelenkov@nginx.com "127.0.0.1:7081": {}, 2611596Szelenkov@nginx.com "127.0.0.1:7082": {}, 2621445Szelenkov@nginx.com }, 2631445Szelenkov@nginx.com }, 2641596Szelenkov@nginx.com }, 2651596Szelenkov@nginx.com "routes": [ 2661596Szelenkov@nginx.com { 2671596Szelenkov@nginx.com "match": {"destination": "*:7081"}, 2681596Szelenkov@nginx.com "action": {"pass": "applications/delayed"}, 2691596Szelenkov@nginx.com }, 2701596Szelenkov@nginx.com { 2711596Szelenkov@nginx.com "match": {"destination": "*:7082"}, 2721596Szelenkov@nginx.com "action": {"return": 201}, 2731445Szelenkov@nginx.com }, 2741596Szelenkov@nginx.com ], 2751596Szelenkov@nginx.com "applications": { 2761596Szelenkov@nginx.com "delayed": { 2771596Szelenkov@nginx.com "type": "python", 2781596Szelenkov@nginx.com "processes": {"spare": 0}, 2791596Szelenkov@nginx.com "path": option.test_dir + "/python/delayed", 2801596Szelenkov@nginx.com "working_directory": option.test_dir 2811596Szelenkov@nginx.com + "/python/delayed", 2821596Szelenkov@nginx.com "module": "wsgi", 2831596Szelenkov@nginx.com } 2841445Szelenkov@nginx.com }, 2851596Szelenkov@nginx.com }, 2861596Szelenkov@nginx.com ), 'upstreams initial configuration' 2871396Szelenkov@nginx.com 2881396Szelenkov@nginx.com req = 50 2891396Szelenkov@nginx.com 2901396Szelenkov@nginx.com socks = [] 2911396Szelenkov@nginx.com for i in range(req): 2921445Szelenkov@nginx.com delay = 1 if i % 5 == 0 else 0 2931396Szelenkov@nginx.com _, sock = self.get( 2941445Szelenkov@nginx.com headers={ 2951445Szelenkov@nginx.com 'Host': 'localhost', 2961445Szelenkov@nginx.com 'Content-Length': '0', 2971445Szelenkov@nginx.com 'X-Delay': str(delay), 2981445Szelenkov@nginx.com 'Connection': 'close', 2991445Szelenkov@nginx.com }, 3001396Szelenkov@nginx.com start=True, 3011396Szelenkov@nginx.com no_recv=True, 3021396Szelenkov@nginx.com ) 3031396Szelenkov@nginx.com socks.append(sock) 3041396Szelenkov@nginx.com 3051396Szelenkov@nginx.com resps = [0, 0] 3061396Szelenkov@nginx.com for i in range(req): 3071396Szelenkov@nginx.com resp = self.recvall(socks[i]).decode() 3081396Szelenkov@nginx.com socks[i].close() 3091396Szelenkov@nginx.com 3101596Szelenkov@nginx.com m = re.search(r'HTTP/1.1 20(\d)', resp) 3111596Szelenkov@nginx.com assert m is not None, 'status' 3121396Szelenkov@nginx.com resps[int(m.group(1))] += 1 3131396Szelenkov@nginx.com 3141596Szelenkov@nginx.com assert sum(resps) == req, 'delay sum' 3151596Szelenkov@nginx.com assert abs(resps[0] - resps[1]) <= self.cpu_count, 'delay' 3161396Szelenkov@nginx.com 3171396Szelenkov@nginx.com def test_upstreams_rr_active_req(self): 3181396Szelenkov@nginx.com conns = 5 3191396Szelenkov@nginx.com socks = [] 3201396Szelenkov@nginx.com socks2 = [] 3211396Szelenkov@nginx.com 3221396Szelenkov@nginx.com for _ in range(conns): 3231396Szelenkov@nginx.com _, sock = self.get(start=True, no_recv=True) 3241396Szelenkov@nginx.com socks.append(sock) 3251396Szelenkov@nginx.com 3261396Szelenkov@nginx.com _, sock2 = self.http( 3271396Szelenkov@nginx.com b"""POST / HTTP/1.1 3281396Szelenkov@nginx.comHost: localhost 3291396Szelenkov@nginx.comContent-Length: 10 3301396Szelenkov@nginx.comConnection: close 3311396Szelenkov@nginx.com 3321396Szelenkov@nginx.com""", 3331396Szelenkov@nginx.com start=True, 3341396Szelenkov@nginx.com no_recv=True, 3351396Szelenkov@nginx.com raw=True, 3361396Szelenkov@nginx.com ) 3371396Szelenkov@nginx.com socks2.append(sock2) 3381396Szelenkov@nginx.com 3391396Szelenkov@nginx.com # Send one more request and read response to make sure that previous 3401396Szelenkov@nginx.com # requests had enough time to reach server. 3411396Szelenkov@nginx.com 3421596Szelenkov@nginx.com assert self.get()['body'] == '' 3431396Szelenkov@nginx.com 3441596Szelenkov@nginx.com assert 'success' in self.conf( 3451596Szelenkov@nginx.com {"127.0.0.1:7083": {"weight": 2}}, 'upstreams/one/servers', 3461596Szelenkov@nginx.com ), 'active req new server' 3471596Szelenkov@nginx.com assert 'success' in self.conf_delete( 3481596Szelenkov@nginx.com 'upstreams/one/servers/127.0.0.1:7083' 3491596Szelenkov@nginx.com ), 'active req server remove' 3501596Szelenkov@nginx.com assert 'success' in self.conf_delete( 3511596Szelenkov@nginx.com 'listeners/*:7080' 3521596Szelenkov@nginx.com ), 'delete listener' 3531596Szelenkov@nginx.com assert 'success' in self.conf_delete( 3541596Szelenkov@nginx.com 'upstreams/one' 3551596Szelenkov@nginx.com ), 'active req upstream remove' 3561396Szelenkov@nginx.com 3571396Szelenkov@nginx.com for i in range(conns): 3581596Szelenkov@nginx.com assert ( 3591596Szelenkov@nginx.com self.http(b'', sock=socks[i], raw=True)['body'] == '' 3601596Szelenkov@nginx.com ), 'active req GET' 3611396Szelenkov@nginx.com 3621596Szelenkov@nginx.com assert ( 3631596Szelenkov@nginx.com self.http(b"""0123456789""", sock=socks2[i], raw=True)['body'] 3641596Szelenkov@nginx.com == '' 3651596Szelenkov@nginx.com ), 'active req POST' 3661396Szelenkov@nginx.com 3671396Szelenkov@nginx.com def test_upstreams_rr_bad_server(self): 3681596Szelenkov@nginx.com assert 'success' in self.conf( 3691596Szelenkov@nginx.com {"weight": 1}, 'upstreams/one/servers/127.0.0.1:7084' 3701596Szelenkov@nginx.com ), 'configure bad server' 3711396Szelenkov@nginx.com 3721396Szelenkov@nginx.com resps = self.get_resps_sc(req=30) 3731596Szelenkov@nginx.com assert resps[0] == 10, 'bad server 0' 3741596Szelenkov@nginx.com assert resps[1] == 10, 'bad server 1' 3751596Szelenkov@nginx.com assert sum(resps) == 20, 'bad server sum' 3761396Szelenkov@nginx.com 3771396Szelenkov@nginx.com def test_upstreams_rr_pipeline(self): 3781396Szelenkov@nginx.com resps = self.get_resps_sc() 3791396Szelenkov@nginx.com 3801596Szelenkov@nginx.com assert resps[0] == 50, 'pipeline 0' 3811596Szelenkov@nginx.com assert resps[1] == 50, 'pipeline 1' 3821396Szelenkov@nginx.com 3831396Szelenkov@nginx.com def test_upstreams_rr_post(self): 3841396Szelenkov@nginx.com resps = [0, 0] 3851396Szelenkov@nginx.com for _ in range(50): 3861445Szelenkov@nginx.com resps[self.get()['status'] % 10] += 1 3871445Szelenkov@nginx.com resps[self.post(body='0123456789')['status'] % 10] += 1 3881396Szelenkov@nginx.com 3891596Szelenkov@nginx.com assert sum(resps) == 100, 'post sum' 3901596Szelenkov@nginx.com assert abs(resps[0] - resps[1]) <= self.cpu_count, 'post' 3911396Szelenkov@nginx.com 3921654Szelenkov@nginx.com def test_upstreams_rr_unix(self, temp_dir): 3931654Szelenkov@nginx.com addr_0 = temp_dir + '/sock_0' 3941654Szelenkov@nginx.com addr_1 = temp_dir + '/sock_1' 3951396Szelenkov@nginx.com 3961596Szelenkov@nginx.com assert 'success' in self.conf( 3971596Szelenkov@nginx.com { 3981596Szelenkov@nginx.com "*:7080": {"pass": "upstreams/one"}, 3991596Szelenkov@nginx.com "unix:" + addr_0: {"pass": "routes/one"}, 4001596Szelenkov@nginx.com "unix:" + addr_1: {"pass": "routes/two"}, 4011596Szelenkov@nginx.com }, 4021596Szelenkov@nginx.com 'listeners', 4031596Szelenkov@nginx.com ), 'configure listeners unix' 4041396Szelenkov@nginx.com 4051596Szelenkov@nginx.com assert 'success' in self.conf( 4061596Szelenkov@nginx.com {"unix:" + addr_0: {}, "unix:" + addr_1: {}}, 4071596Szelenkov@nginx.com 'upstreams/one/servers', 4081596Szelenkov@nginx.com ), 'configure servers unix' 4091396Szelenkov@nginx.com 4101396Szelenkov@nginx.com resps = self.get_resps_sc() 4111396Szelenkov@nginx.com 4121596Szelenkov@nginx.com assert resps[0] == 50, 'unix 0' 4131596Szelenkov@nginx.com assert resps[1] == 50, 'unix 1' 4141396Szelenkov@nginx.com 4151396Szelenkov@nginx.com def test_upstreams_rr_ipv6(self): 4161596Szelenkov@nginx.com assert 'success' in self.conf( 4171596Szelenkov@nginx.com { 4181596Szelenkov@nginx.com "*:7080": {"pass": "upstreams/one"}, 4191596Szelenkov@nginx.com "[::1]:7081": {"pass": "routes/one"}, 4201596Szelenkov@nginx.com "[::1]:7082": {"pass": "routes/two"}, 4211596Szelenkov@nginx.com }, 4221596Szelenkov@nginx.com 'listeners', 4231596Szelenkov@nginx.com ), 'configure listeners ipv6' 4241396Szelenkov@nginx.com 4251596Szelenkov@nginx.com assert 'success' in self.conf( 4261596Szelenkov@nginx.com {"[::1]:7081": {}, "[::1]:7082": {}}, 'upstreams/one/servers' 4271596Szelenkov@nginx.com ), 'configure servers ipv6' 4281396Szelenkov@nginx.com 4291396Szelenkov@nginx.com resps = self.get_resps_sc() 4301396Szelenkov@nginx.com 4311596Szelenkov@nginx.com assert resps[0] == 50, 'ipv6 0' 4321596Szelenkov@nginx.com assert resps[1] == 50, 'ipv6 1' 4331396Szelenkov@nginx.com 4341396Szelenkov@nginx.com def test_upstreams_rr_servers_empty(self): 4351596Szelenkov@nginx.com assert 'success' in self.conf( 4361596Szelenkov@nginx.com {}, 'upstreams/one/servers' 4371596Szelenkov@nginx.com ), 'configure servers empty' 4381596Szelenkov@nginx.com assert self.get()['status'] == 502, 'servers empty' 4391396Szelenkov@nginx.com 4401596Szelenkov@nginx.com assert 'success' in self.conf( 4411596Szelenkov@nginx.com {"127.0.0.1:7081": {"weight": 0}}, 'upstreams/one/servers' 4421596Szelenkov@nginx.com ), 'configure servers empty one' 4431596Szelenkov@nginx.com assert self.get()['status'] == 502, 'servers empty one' 4441596Szelenkov@nginx.com assert 'success' in self.conf( 4451596Szelenkov@nginx.com { 4461596Szelenkov@nginx.com "127.0.0.1:7081": {"weight": 0}, 4471596Szelenkov@nginx.com "127.0.0.1:7082": {"weight": 0}, 4481596Szelenkov@nginx.com }, 4491596Szelenkov@nginx.com 'upstreams/one/servers', 4501596Szelenkov@nginx.com ), 'configure servers empty two' 4511596Szelenkov@nginx.com assert self.get()['status'] == 502, 'servers empty two' 4521396Szelenkov@nginx.com 4531396Szelenkov@nginx.com def test_upstreams_rr_invalid(self): 4541596Szelenkov@nginx.com assert 'error' in self.conf({}, 'upstreams'), 'upstreams empty' 4551596Szelenkov@nginx.com assert 'error' in self.conf( 4561596Szelenkov@nginx.com {}, 'upstreams/one' 4571596Szelenkov@nginx.com ), 'named upstreams empty' 4581596Szelenkov@nginx.com assert 'error' in self.conf( 4591596Szelenkov@nginx.com {}, 'upstreams/one/servers/127.0.0.1' 4601596Szelenkov@nginx.com ), 'invalid address' 4611596Szelenkov@nginx.com assert 'error' in self.conf( 4621596Szelenkov@nginx.com {}, 'upstreams/one/servers/127.0.0.1:7081/blah' 4631596Szelenkov@nginx.com ), 'invalid server option' 4641441Szelenkov@nginx.com 4651441Szelenkov@nginx.com def check_weight(w): 4661596Szelenkov@nginx.com assert 'error' in self.conf( 4671596Szelenkov@nginx.com w, 'upstreams/one/servers/127.0.0.1:7081/weight' 4681596Szelenkov@nginx.com ), 'invalid weight option' 4691596Szelenkov@nginx.com 4701441Szelenkov@nginx.com check_weight({}) 4711441Szelenkov@nginx.com check_weight('-1') 4721441Szelenkov@nginx.com check_weight('1.') 4731441Szelenkov@nginx.com check_weight('1.1.') 4741441Szelenkov@nginx.com check_weight('.') 4751441Szelenkov@nginx.com check_weight('.01234567890123') 4761441Szelenkov@nginx.com check_weight('1000001') 4771441Szelenkov@nginx.com check_weight('2e6') 478