1import time 2 3from unit.applications.lang.python import ApplicationPython 4from unit.option import option 5from unit.status import Status 6 7prerequisites = {'modules': {'python': 'any'}} 8 9client = ApplicationPython() 10 11 12def check_connections(accepted, active, idle, closed): 13 assert Status.get('/connections') == { 14 'accepted': accepted, 15 'active': active, 16 'idle': idle, 17 'closed': closed, 18 } 19 20 21def app_default(name="empty", module="wsgi"): 22 name_dir = f'{option.test_dir}/python/{name}' 23 return { 24 "type": client.get_application_type(), 25 "processes": {"spare": 0}, 26 "path": name_dir, 27 "working_directory": name_dir, 28 "module": module, 29 } 30 31 32def test_status(): 33 assert 'error' in client.conf_delete('/status'), 'DELETE method' 34 35 36def test_status_requests(skip_alert): 37 skip_alert(r'Python failed to import module "blah"') 38 39 assert 'success' in client.conf( 40 { 41 "listeners": { 42 "*:8080": {"pass": "routes"}, 43 "*:8081": {"pass": "applications/empty"}, 44 "*:8082": {"pass": "applications/blah"}, 45 }, 46 "routes": [{"action": {"return": 200}}], 47 "applications": { 48 "empty": app_default(), 49 "blah": { 50 "type": client.get_application_type(), 51 "processes": {"spare": 0}, 52 "module": "blah", 53 }, 54 }, 55 }, 56 ) 57 58 Status.init() 59 60 assert client.get()['status'] == 200 61 assert Status.get('/requests/total') == 1, '2xx' 62 63 assert client.get(port=8081)['status'] == 200 64 assert Status.get('/requests/total') == 2, '2xx app' 65 66 assert ( 67 client.get(headers={'Host': '/', 'Connection': 'close'})['status'] 68 == 400 69 ) 70 assert Status.get('/requests/total') == 3, '4xx' 71 72 assert client.get(port=8082)['status'] == 503 73 assert Status.get('/requests/total') == 4, '5xx' 74 75 client.http( 76 b"""GET / HTTP/1.1 77Host: localhost 78 79GET / HTTP/1.1 80Host: localhost 81Connection: close 82 83""", 84 raw=True, 85 ) 86 assert Status.get('/requests/total') == 6, 'pipeline' 87 88 sock = client.get(port=8081, no_recv=True) 89 90 time.sleep(1) 91 92 assert Status.get('/requests/total') == 7, 'no receive' 93 94 sock.close() 95 96 97def test_status_connections(): 98 assert 'success' in client.conf( 99 { 100 "listeners": { 101 "*:8080": {"pass": "routes"}, 102 "*:8081": {"pass": "applications/delayed"}, 103 }, 104 "routes": [{"action": {"return": 200}}], 105 "applications": { 106 "delayed": app_default("delayed"), 107 }, 108 }, 109 ) 110 111 Status.init() 112 113 # accepted, closed 114 115 assert client.get()['status'] == 200 116 check_connections(1, 0, 0, 1) 117 118 # idle 119 120 (_, sock) = client.get( 121 headers={'Host': 'localhost', 'Connection': 'keep-alive'}, 122 start=True, 123 read_timeout=1, 124 ) 125 126 check_connections(2, 0, 1, 1) 127 128 client.get(sock=sock) 129 check_connections(2, 0, 0, 2) 130 131 # active 132 133 (_, sock) = client.get( 134 headers={ 135 'Host': 'localhost', 136 'X-Delay': '2', 137 'Connection': 'close', 138 }, 139 port=8081, 140 start=True, 141 read_timeout=1, 142 ) 143 check_connections(3, 1, 0, 2) 144 145 client.get(sock=sock) 146 check_connections(3, 0, 0, 3) 147 148 149def test_status_applications(): 150 def check_applications(expert): 151 apps = list(client.conf_get('/status/applications').keys()).sort() 152 assert apps == expert.sort() 153 154 def check_application(name, running, starting, idle, active): 155 assert Status.get(f'/applications/{name}') == { 156 'processes': { 157 'running': running, 158 'starting': starting, 159 'idle': idle, 160 }, 161 'requests': {'active': active}, 162 } 163 164 client.load('delayed') 165 Status.init() 166 167 check_applications(['delayed']) 168 check_application('delayed', 0, 0, 0, 0) 169 170 # idle 171 172 assert client.get()['status'] == 200 173 check_application('delayed', 1, 0, 1, 0) 174 175 assert 'success' in client.conf('4', 'applications/delayed/processes') 176 check_application('delayed', 4, 0, 4, 0) 177 178 # active 179 180 (_, sock) = client.get( 181 headers={ 182 'Host': 'localhost', 183 'X-Delay': '2', 184 'Connection': 'close', 185 }, 186 start=True, 187 read_timeout=1, 188 ) 189 check_application('delayed', 4, 0, 3, 1) 190 sock.close() 191 192 # starting 193 194 assert 'success' in client.conf( 195 { 196 "listeners": { 197 "*:8080": {"pass": "applications/restart"}, 198 "*:8081": {"pass": "applications/delayed"}, 199 }, 200 "routes": [], 201 "applications": { 202 "restart": app_default("restart", "longstart"), 203 "delayed": app_default("delayed"), 204 }, 205 }, 206 ) 207 Status.init() 208 209 check_applications(['delayed', 'restart']) 210 check_application('restart', 0, 0, 0, 0) 211 check_application('delayed', 0, 0, 0, 0) 212 213 client.get(read_timeout=1) 214 215 check_application('restart', 0, 1, 0, 1) 216 check_application('delayed', 0, 0, 0, 0) 217 218 219def test_status_proxy(): 220 assert 'success' in client.conf( 221 { 222 "listeners": { 223 "*:8080": {"pass": "routes"}, 224 "*:8081": {"pass": "applications/empty"}, 225 }, 226 "routes": [ 227 { 228 "match": {"uri": "/"}, 229 "action": {"proxy": "http://127.0.0.1:8081"}, 230 } 231 ], 232 "applications": { 233 "empty": app_default(), 234 }, 235 }, 236 ) 237 238 Status.init() 239 240 assert client.get()['status'] == 200 241 check_connections(2, 0, 0, 2) 242 assert Status.get('/requests/total') == 2, 'proxy' 243