Skip to content

Commit 788c3a7

Browse files
authored
Merge branch 'dev' into req-24-ios-inspector
2 parents 8c63c17 + 67c3846 commit 788c3a7

22 files changed

Lines changed: 977 additions & 1226 deletions

File tree

Framework/Built_In_Automation/Database/BuiltInFunctions.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -246,10 +246,10 @@ def db_get_connection(session_name):
246246
port=db_port
247247
)
248248
elif "mariadb" in db_type:
249-
import mariadb
249+
import pymysql
250250

251251
# Connect to db
252-
db_con = mariadb.connect(
252+
db_con = pymysql.connect(
253253
user=db_user_id,
254254
password=db_password,
255255
database=db_name,

Framework/MainDriverApi.py

Lines changed: 24 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1246,7 +1246,7 @@ def send_dom_variables():
12461246
res = RequestFormatter.request("post",
12471247
RequestFormatter.form_uri("node_ai_contents/"),
12481248
data=json.dumps(data),
1249-
verify=False
1249+
timeout=600
12501250
)
12511251
if res.status_code == 500:
12521252
CommonUtil.ExecLog(sModuleInfo, res.json()["info"], 2)
@@ -1465,7 +1465,7 @@ def upload_step_report(run_id: str, tc_id: str, step_seq: int, step_id: int, exe
14651465
"execution_detail": execution_detail,
14661466
})
14671467
},
1468-
verify=False
1468+
timeout=600
14691469
)
14701470
duration = round(res.elapsed.total_seconds(), 2)
14711471
# if res.status_code == 200:
@@ -1506,17 +1506,18 @@ def upload_reports_and_zips(temp_ini_file, run_id):
15061506
"post",
15071507
RequestFormatter.form_uri("create_report_log_api/"),
15081508
data={"execution_report": json.dumps(tc_report)},
1509-
verify=False
1509+
timeout=600
15101510
)
15111511
else:
15121512
res = RequestFormatter.request("post",
1513-
RequestFormatter.form_uri("create_report_log_api/"),
1514-
data={
1515-
"execution_report": json.dumps(tc_report),
1516-
"processed_tc_id":processed_tc_id
1517-
},
1518-
files=[("file",perf_report_html)],
1519-
verify=False)
1513+
RequestFormatter.form_uri("create_report_log_api/"),
1514+
data={
1515+
"execution_report": json.dumps(tc_report),
1516+
"processed_tc_id": processed_tc_id
1517+
},
1518+
files=[("file", perf_report_html)],
1519+
timeout=600
1520+
)
15201521

15211522
if res.status_code == 200:
15221523
CommonUtil.ExecLog(sModuleInfo, f"Successfully uploaded the execution report of run_id {run_id}", 1)
@@ -1582,10 +1583,11 @@ def upload_reports_and_zips(temp_ini_file, run_id):
15821583
for zips in opened_zips:
15831584
files_list.append(("file",zips))
15841585
res = RequestFormatter.request("post",
1585-
RequestFormatter.form_uri("save_log_and_attachment_api/"),
1586-
files=files_list,
1587-
data={"machine_name": Userid},
1588-
verify=False)
1586+
RequestFormatter.form_uri("save_log_and_attachment_api/"),
1587+
files=files_list,
1588+
data={"machine_name": Userid},
1589+
timeout=600
1590+
)
15891591
if res.status_code == 200:
15901592
try:
15911593
res_json = res.json()
@@ -1629,19 +1631,21 @@ def retry_failed_report_upload():
16291631
report_json_path = failed_report_dir / folder / 'report.json'
16301632
report_json = json.load(open(report_json_path))
16311633
if not report_json.get('perf_filepath'):
1632-
res = RequestFormatter.request("post",
1634+
res = RequestFormatter.request(
1635+
"post",
16331636
RequestFormatter.form_uri("create_report_log_api/"),
16341637
data={"execution_report": report_json.get('execution_report')},
1635-
verify=False)
1638+
timeout=600
1639+
)
16361640
else:
16371641
res = RequestFormatter.request("post",
16381642
RequestFormatter.form_uri("create_report_log_api/"),
16391643
data={"execution_report": report_json.get('execution_report'),
16401644
"processed_tc_id":report_json.get('processed_tc_id')
1641-
1642-
},
1645+
},
16431646
files=[("file",open(failed_report_dir / folder / 'files' /report_json.get('perf_filepath'),'rb'))],
1644-
verify=False)
1647+
timeout=600
1648+
)
16451649

16461650
if res.status_code == 200:
16471651
CommonUtil.ExecLog(sModuleInfo, f"Successfully uploaded the execution report of run_id {report_json.get('run_id')}", 1)
@@ -1705,7 +1709,7 @@ def download_attachment(attachment_info: Dict[str, Any]):
17051709
file_name = url[file_name_start_pos:]
17061710
file_path = attachment_info["download_dir"] / file_name
17071711

1708-
r = RequestFormatter.request("get", url, stream=True)
1712+
r = RequestFormatter.request("get", url, stream=True, timeout=600)
17091713
if r.status_code == requests.codes.ok:
17101714
with open(file_path, 'wb') as f:
17111715
for data in r.iter_content(chunk_size=512*1024):

Framework/Utilities/RequestFormatter.py

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# -- coding: utf-8 --
22
# -- coding: cp1252 --
3-
3+
import asyncio
44
from . import ConfigModule
55
import os
66
import requests
@@ -169,13 +169,27 @@ def request(*args, **kwargs):
169169
"""
170170
request() is a wrapper for requests.request which handles automatic session
171171
management.
172+
Default values:
173+
verify = False
174+
timeout = 70 sec
172175
"""
173176
renew_token_with_expiry_check()
174177
if "verify" not in kwargs:
175178
kwargs["verify"] = False
179+
if "timeout" not in kwargs:
180+
kwargs["timeout"] = 70
181+
176182

177183
return session.request(*args, **kwargs)
178184

185+
# async wrapper
186+
async def async_request(*args, **kwargs):
187+
"""
188+
Runs the blocking request() in a worker thread
189+
so the event loop is not blocked.
190+
"""
191+
return await asyncio.to_thread(request, *args, **kwargs)
192+
179193

180194
def Post(resource_path, payload=None, **kwargs):
181195
renew_token_with_expiry_check()
@@ -210,16 +224,12 @@ def Get(resource_path, payload=None, **kwargs):
210224
**kwargs
211225
).json()
212226

213-
except requests.exceptions.RequestException:
214-
print(
215-
"Exception in UpdateGet: Authentication Failed. Please check your server, username and password. "
216-
"Please include full server name. Example: https://zeuz.zeuz.ai.\n"
217-
"If you are using IP Address: Type in just the IP without http. Example: 12.15.10.6"
218-
)
227+
except requests.exceptions.RequestException as e:
228+
print(e)
219229
return ""
220230

221231
except Exception as e:
222-
print("Get Exception: {}".format(e))
232+
print(e)
223233
return {}
224234

225235

Framework/attachment_db.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,7 @@ def download_attachment(self, url: str):
134134

135135
headers = RequestFormatter.add_api_key_to_headers({})
136136

137-
with RequestFormatter.request("get", url, stream=True, verify=False,**headers) as r:
137+
with RequestFormatter.request("get", url, stream=True, timeout=600,**headers) as r:
138138
r.raise_for_status()
139139
with open(path_to_downloaded_attachment, 'wb') as f:
140140
for chunk in r.iter_content(chunk_size=8192):

Framework/deploy_handler/long_poll_handler.py

Lines changed: 65 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
from colorama import Fore
1010
from pathlib import Path
1111
from urllib.parse import urlparse
12+
import requests
1213

1314
from Framework.Utilities import RequestFormatter, ConfigModule, CommonUtil
1415
from Framework.Utilities.RequestFormatter import REQUEST_TIMEOUT
@@ -237,7 +238,6 @@ def respond_to_key_request(self, request_id: str, private_key_pem: str) -> None:
237238
"donor_node_id": node_id,
238239
"private_key": private_key_pem
239240
},
240-
verify=False
241241
)
242242

243243
if response.ok:
@@ -253,80 +253,74 @@ def respond_to_key_request(self, request_id: str, private_key_pem: str) -> None:
253253

254254
async def run(self, host: str) -> None:
255255
reconnect = False
256-
server_online = False
257-
async with httpx.AsyncClient(timeout=httpx.Timeout(70.0), verify=False) as client:
258-
while True:
259-
if STATE.reconnect_with_credentials is not None:
256+
print_online = False
257+
while True:
258+
if STATE.reconnect_with_credentials is not None:
259+
break
260+
261+
if reconnect:
262+
await asyncio.sleep(random.randint(1, 3))
263+
264+
await self.on_connect_callback(reconnect)
265+
266+
try:
267+
reconnect = True
268+
resp = await RequestFormatter.async_request("get", host, timeout=70)
269+
if resp is None:
260270
break
261271

262-
if reconnect:
263-
if server_online:
264-
await asyncio.sleep(0.1)
265-
else:
266-
await asyncio.sleep(random.randint(1, 3))
272+
if resp.content.startswith(self.ERROR_PREFIX):
273+
self.on_error(resp.content)
274+
continue
267275

268-
await self.on_connect_callback(reconnect)
276+
if resp.ok and print_online:
277+
print_online = False
278+
node_id = CommonUtil.MachineInfo().getLocalUser().lower()
279+
print(f"🟢 {node_id} back to online")
269280

270-
try:
271-
reconnect = True
272-
resp = await self.fetch(host, client)
273-
if resp is None:
274-
break
275-
276-
if resp.content.startswith(self.ERROR_PREFIX):
277-
server_online = False
278-
self.on_error(resp.content)
279-
continue
280-
281-
if resp.status_code == httpx.codes.NO_CONTENT:
282-
server_online = False
283-
continue
284-
285-
if not resp.is_success:
286-
server_online = False
287-
print(
288-
"[deploy] facing difficulty communicating with the server, status code:",
289-
resp.status_code,
290-
" | reconnecting",
291-
)
292-
try:
293-
print(Fore.YELLOW + str(resp.content))
294-
except Exception:
295-
pass
296-
297-
# Encountered a server error, retry.
298-
await asyncio.sleep(random.randint(1, 3))
299-
return
300-
301-
should_quit = await self.on_message(resp.content)
302-
if should_quit:
303-
break
304-
305-
reconnect = False
306-
server_online = True
307-
except httpx.ReadTimeout:
308-
pass
309-
except Exception:
310-
traceback.print_exc()
311-
print("[deploy] RETRYING...")
312-
313-
async def fetch(self, host: str, client: httpx.AsyncClient) -> httpx.Response | None:
314-
try:
315-
api_key = ConfigModule.get_config_value("Authentication", "api-key")
316-
headers = {"X-API-KEY": api_key}
317-
318-
while True:
281+
if resp.status_code == httpx.codes.NO_CONTENT:
282+
continue
283+
284+
if resp.status_code == httpx.codes.BAD_GATEWAY:
285+
print_online = True
286+
print(Fore.YELLOW + "Server offline. Retrying after 30s")
287+
await asyncio.sleep(30)
288+
continue
289+
290+
if not resp.ok:
291+
print(
292+
"[deploy] Request Error, status code:",
293+
resp.status_code,
294+
"| reconnecting",
295+
)
296+
297+
# Encountered a server error, retry.
298+
await asyncio.sleep(random.randint(1, 3))
299+
continue
300+
301+
should_quit = await self.on_message(resp.content)
302+
if should_quit:
303+
break
304+
305+
reconnect = False
306+
except (
307+
requests.exceptions.ConnectTimeout,
308+
requests.exceptions.ReadTimeout,
309+
requests.exceptions.ConnectionError,
310+
) as e:
311+
# Nginx down, VM down, network issue, docker-compose stopped
319312
if STATE.reconnect_with_credentials is not None:
320313
return None
321-
322-
try:
323-
resp = await client.get(host, headers=headers)
324-
return resp
325-
except asyncio.CancelledError:
314+
print_online = True
315+
print(e)
316+
print(Fore.YELLOW + "Retrying after 30s")
317+
await asyncio.sleep(30)
318+
319+
except Exception as e:
320+
if STATE.reconnect_with_credentials is not None:
326321
return None
327-
except Exception:
328-
if STATE.reconnect_with_credentials is not None:
329-
return None
330-
await asyncio.sleep(0.1)
331-
except Exception:
332-
return None
322+
print_online = True
323+
print(e)
324+
print(Fore.YELLOW + "Retrying after 30s")
325+
await asyncio.sleep(30)
326+

Framework/install_handler/android/adb.py

Lines changed: 2 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -3,55 +3,15 @@
33
import platform
44
import os
55
from Framework.install_handler.utils import send_response
6+
from Framework.install_handler.android.android_sdk import update_android_sdk_path
67

78

89
async def check_status() -> bool:
910
"""Check if ADB (Android Debug Bridge) is installed."""
1011
print("[installer][android-adb] Checking status...")
1112

12-
# Dynamically refresh ANDROID_HOME and PATH from registry on Windows
13-
system = platform.system()
14-
if system == "Windows":
15-
try:
16-
import winreg
17-
with winreg.OpenKey(winreg.HKEY_CURRENT_USER, r"Environment", 0, winreg.KEY_READ) as key:
18-
try:
19-
android_home_reg, _ = winreg.QueryValueEx(key, "ANDROID_HOME")
20-
if android_home_reg:
21-
# Expand environment variables before checking if path exists
22-
android_home_expanded = os.path.expandvars(android_home_reg)
23-
if os.path.exists(android_home_expanded):
24-
os.environ['ANDROID_HOME'] = android_home_expanded
25-
# Update PATH with platform-tools (where ADB is located)
26-
platform_tools = os.path.join(android_home_expanded, "platform-tools")
27-
current_path = os.environ.get('PATH', '')
28-
if platform_tools not in current_path:
29-
os.environ['PATH'] = f"{platform_tools};{current_path}"
30-
print(f"[installer][android-adb] Refreshed ANDROID_HOME from registry: {android_home_expanded}")
31-
except FileNotFoundError:
32-
pass
33-
34-
# Also check ANDROID_SDK_ROOT if ANDROID_HOME not found
35-
if 'ANDROID_HOME' not in os.environ or not os.path.exists(os.environ.get('ANDROID_HOME', '')):
36-
try:
37-
android_sdk_root_reg, _ = winreg.QueryValueEx(key, "ANDROID_SDK_ROOT")
38-
if android_sdk_root_reg:
39-
# Expand environment variables before checking if path exists
40-
android_sdk_root_expanded = os.path.expandvars(android_sdk_root_reg)
41-
if os.path.exists(android_sdk_root_expanded):
42-
os.environ['ANDROID_SDK_ROOT'] = android_sdk_root_expanded
43-
# Update PATH with platform-tools (where ADB is located)
44-
platform_tools = os.path.join(android_sdk_root_expanded, "platform-tools")
45-
current_path = os.environ.get('PATH', '')
46-
if platform_tools not in current_path:
47-
os.environ['PATH'] = f"{platform_tools};{current_path}"
48-
print(f"[installer][android-adb] Refreshed ANDROID_SDK_ROOT from registry: {android_sdk_root_expanded}")
49-
except FileNotFoundError:
50-
pass
51-
except Exception as e:
52-
print(f"[installer][android-adb] Failed to refresh from registry: {e}")
53-
5413
try:
14+
5515
loop = asyncio.get_event_loop()
5616
result = await loop.run_in_executor(
5717
None,

0 commit comments

Comments
 (0)