fix(ci): poll flutter test output from file
This commit is contained in:
+34
-11
@@ -31,13 +31,14 @@ jobs:
|
|||||||
run: flutter analyze --no-fatal-infos --no-fatal-warnings
|
run: flutter analyze --no-fatal-infos --no-fatal-warnings
|
||||||
|
|
||||||
- name: Ejecutar tests criticos
|
- name: Ejecutar tests criticos
|
||||||
|
timeout-minutes: 4
|
||||||
run: |
|
run: |
|
||||||
python3 - <<'PY'
|
python3 - <<'PY'
|
||||||
import os
|
import os
|
||||||
import select
|
|
||||||
import signal
|
import signal
|
||||||
import subprocess
|
import subprocess
|
||||||
import sys
|
import sys
|
||||||
|
import tempfile
|
||||||
import time
|
import time
|
||||||
|
|
||||||
test_paths = [
|
test_paths = [
|
||||||
@@ -113,26 +114,40 @@ jobs:
|
|||||||
path,
|
path,
|
||||||
]
|
]
|
||||||
print('$ ' + ' '.join(cmd), flush=True)
|
print('$ ' + ' '.join(cmd), flush=True)
|
||||||
|
output_path = None
|
||||||
|
try:
|
||||||
|
with tempfile.NamedTemporaryFile(delete=False) as tmp:
|
||||||
|
output_path = tmp.name
|
||||||
|
with open(output_path, 'w', encoding='utf-8', errors='replace') as writer:
|
||||||
process = subprocess.Popen(
|
process = subprocess.Popen(
|
||||||
cmd,
|
cmd,
|
||||||
stdout=subprocess.PIPE,
|
stdout=writer,
|
||||||
stderr=subprocess.STDOUT,
|
stderr=subprocess.STDOUT,
|
||||||
text=True,
|
|
||||||
bufsize=1,
|
|
||||||
start_new_session=use_process_group,
|
start_new_session=use_process_group,
|
||||||
)
|
)
|
||||||
deadline = time.monotonic() + 120
|
deadline = time.monotonic() + 90
|
||||||
success_deadline = None
|
success_deadline = None
|
||||||
while True:
|
|
||||||
if process.stdout is not None and select.select([process.stdout], [], [], 1)[0]:
|
def flush_new_output():
|
||||||
line = process.stdout.readline()
|
nonlocal success_deadline
|
||||||
if line:
|
with open(output_path, 'r', encoding='utf-8', errors='replace') as reader:
|
||||||
print(line, end='', flush=True)
|
reader.seek(flush_new_output.offset)
|
||||||
if 'All tests passed!' in line:
|
chunk = reader.read()
|
||||||
|
flush_new_output.offset = reader.tell()
|
||||||
|
if not chunk:
|
||||||
|
return
|
||||||
|
print(chunk, end='', flush=True)
|
||||||
|
if 'All tests passed!' in chunk and success_deadline is None:
|
||||||
success_deadline = time.monotonic() + 5
|
success_deadline = time.monotonic() + 5
|
||||||
|
|
||||||
|
flush_new_output.offset = 0
|
||||||
|
|
||||||
|
while True:
|
||||||
|
flush_new_output()
|
||||||
|
|
||||||
returncode = process.poll()
|
returncode = process.poll()
|
||||||
if returncode is not None:
|
if returncode is not None:
|
||||||
|
flush_new_output()
|
||||||
cleanup_flutter_processes()
|
cleanup_flutter_processes()
|
||||||
return returncode
|
return returncode
|
||||||
if success_deadline is not None and time.monotonic() >= success_deadline:
|
if success_deadline is not None and time.monotonic() >= success_deadline:
|
||||||
@@ -141,14 +156,22 @@ jobs:
|
|||||||
flush=True,
|
flush=True,
|
||||||
)
|
)
|
||||||
kill_process_group(process.pid)
|
kill_process_group(process.pid)
|
||||||
|
flush_new_output()
|
||||||
cleanup_flutter_processes()
|
cleanup_flutter_processes()
|
||||||
return 0
|
return 0
|
||||||
if time.monotonic() >= deadline:
|
if time.monotonic() >= deadline:
|
||||||
print(f'ERROR: timeout ejecutando test critico {path}', file=sys.stderr, flush=True)
|
print(f'ERROR: timeout ejecutando test critico {path}', file=sys.stderr, flush=True)
|
||||||
kill_process_group(process.pid)
|
kill_process_group(process.pid)
|
||||||
|
flush_new_output()
|
||||||
cleanup_flutter_processes()
|
cleanup_flutter_processes()
|
||||||
return 124
|
return 124
|
||||||
time.sleep(1)
|
time.sleep(1)
|
||||||
|
finally:
|
||||||
|
if output_path:
|
||||||
|
try:
|
||||||
|
os.unlink(output_path)
|
||||||
|
except FileNotFoundError:
|
||||||
|
pass
|
||||||
|
|
||||||
cleanup_flutter_processes()
|
cleanup_flutter_processes()
|
||||||
for path in test_paths:
|
for path in test_paths:
|
||||||
|
|||||||
Reference in New Issue
Block a user