From 6dd045ea428a6c8f7aade0661b57545820529d95 Mon Sep 17 00:00:00 2001 From: freetlab Date: Thu, 28 May 2026 23:59:32 +0200 Subject: [PATCH] fix(ci): clean up flutter test processes --- .gitea/workflows/build.yml | 89 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 86 insertions(+), 3 deletions(-) diff --git a/.gitea/workflows/build.yml b/.gitea/workflows/build.yml index e344284..e262737 100644 --- a/.gitea/workflows/build.yml +++ b/.gitea/workflows/build.yml @@ -33,31 +33,114 @@ jobs: - name: Ejecutar tests críticos run: | python3 - <<'PY' + import os + import signal import subprocess import sys + import time tests = [ 'test/servicios/servicio_programacion_alarmas_test.dart', 'test/estado/estado_alarmas_test.dart', ] + use_process_group = hasattr(os, 'killpg') and os.name != 'nt' + + def cleanup_process_group(pid): + if not use_process_group: + return + try: + os.killpg(pid, signal.SIGTERM) + time.sleep(1) + os.killpg(pid, signal.SIGKILL) + except ProcessLookupError: + pass + for test_path in tests: cmd = [ 'flutter', 'test', + '--no-pub', '--concurrency=1', '--timeout=60s', '--reporter=expanded', test_path, ] print('$ ' + ' '.join(cmd), flush=True) + process = subprocess.Popen(cmd, start_new_session=use_process_group) try: - result = subprocess.run(cmd, timeout=180) + returncode = process.wait(timeout=180) except subprocess.TimeoutExpired: print(f'ERROR: timeout ejecutando {test_path}', file=sys.stderr, flush=True) + cleanup_process_group(process.pid) sys.exit(124) - if result.returncode != 0: - sys.exit(result.returncode) + finally: + cleanup_process_group(process.pid) + + if returncode != 0: + sys.exit(returncode) + PY + + - name: Limpiar procesos Flutter de tests + if: always() + run: | + python3 - <<'PY' + import os + import signal + import subprocess + import time + + workspace = os.getcwd() + test_paths = ( + 'test/estado/estado_alarmas_test.dart', + 'test/servicios/servicio_programacion_alarmas_test.dart', + ) + patterns = ( + 'flutter_tester', + 'flutter_tools.snapshot', + 'frontend_server', + 'dartvm', + 'dartaotruntime', + ) + test_paths + current_pid = os.getpid() + ps = subprocess.run( + ['ps', '-axww', '-o', 'pid=', '-o', 'command='], + text=True, + stdout=subprocess.PIPE, + check=False, + ) + killed = [] + for raw in ps.stdout.splitlines(): + line = raw.strip() + if not line: + continue + pid_text, _, command = line.partition(' ') + try: + pid = int(pid_text) + except ValueError: + continue + if pid == current_pid: + continue + if workspace not in command and not any(path in command for path in test_paths): + continue + if not any(pattern in command for pattern in patterns): + continue + try: + os.kill(pid, signal.SIGTERM) + killed.append(pid) + except ProcessLookupError: + pass + + if killed: + print('Procesos Flutter de test terminados: ' + ', '.join(map(str, killed))) + time.sleep(1) + for pid in killed: + try: + os.kill(pid, signal.SIGKILL) + except ProcessLookupError: + pass + else: + print('No quedaron procesos Flutter de test vivos') PY build: