Skip to content

Commit d77eec4

Browse files
committed
macOS CI: 1 worker, task test longer sleep, tools on macOS
- API/task workers: 1+1 (halves 84s startup to ~42s) - Task tests: 60s pickup wait on darwin instead of 1s - Server detection: HTTP readiness check (not just port open) - Tools job: add macOS matrix (skip build-logger, bazel)
1 parent b3852c0 commit d77eec4

3 files changed

Lines changed: 29 additions & 21 deletions

File tree

.github/workflows/test.yml

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -46,23 +46,31 @@ jobs:
4646
4747
tools:
4848
name: Tools (report-converter, etc.)
49-
runs-on: ubuntu-24.04
49+
runs-on: ${{ matrix.os }}
50+
continue-on-error: ${{ matrix.os == 'macos-latest' }}
51+
52+
strategy:
53+
matrix:
54+
os: [ubuntu-24.04, macos-latest]
5055

5156
steps:
5257
- uses: actions/checkout@v2
5358
- uses: actions/setup-python@v4
5459
with:
5560
python-version: '3.10'
5661
- name: Setup Bazel
62+
if: runner.os == 'Linux'
5763
uses: abhinavsingh/setup-bazel@v3
5864
with:
5965
version: 4.0.0
6066
- name: Install common dependencies
67+
if: runner.os == 'Linux'
6168
run: |
6269
sudo apt-get update -q
6370
sudo apt-get install gcc-multilib
6471
6572
- name: Run build-logger tests
73+
if: runner.os == 'Linux'
6674
working-directory: analyzer/tools/build-logger
6775
run: |
6876
pip install -r requirements_py/dev/requirements.txt
@@ -95,6 +103,7 @@ jobs:
95103
make test
96104
97105
- name: Run bazel-compile-commands tests
106+
if: runner.os == 'Linux'
98107
working-directory: tools/bazel
99108
run: |
100109
pip install -r requirements_py/dev/requirements.txt
@@ -215,8 +224,8 @@ jobs:
215224
cd web
216225
make test_matrix_sqlite
217226
env:
218-
CC_TEST_API_WORKERS: "2"
219-
CC_TEST_TASK_WORKERS: "2"
227+
CC_TEST_API_WORKERS: "1"
228+
CC_TEST_TASK_WORKERS: "1"
220229

221230
- name: Run unit tests coverage
222231
working-directory: web

web/tests/functional/tasks/test_task_management.py

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -13,20 +13,22 @@
1313
from datetime import datetime, timezone
1414
import os
1515
import shutil
16-
import unittest
16+
import sys
1717
import time
18+
import unittest
1819
from typing import List, Optional, cast
1920

2021
import multiprocess
2122

22-
import sys
23-
2423
from codechecker_api_shared.ttypes import RequestFailed, Ternary
2524
from codechecker_api.codeCheckerServersideTasks_v6.ttypes import \
2625
AdministratorTaskInfo, TaskFilter, TaskInfo, TaskStatus
2726

2827
from libtest import codechecker, env
2928

29+
# On macOS, spawn workers need time to import before processing tasks.
30+
_TASK_PICKUP_WAIT = 60 if sys.platform == "darwin" else 1
31+
3032

3133
# Stop events for the CodeChecker servers.
3234
STOP_SERVER = multiprocess.Event()
@@ -39,9 +41,6 @@
3941
# Note: Test names in this file follow a strict ordinal convention, because
4042
# the assertions are created with a specific execution history!
4143

42-
@unittest.skipIf(sys.platform == "darwin",
43-
"Spawn workers take ~84s to import on macOS CI; "
44-
"task timing assumptions (1s) are incompatible.")
4544
class TaskManagementAPITests(unittest.TestCase):
4645
def setup_class(self):
4746
global TEST_WORKSPACE
@@ -139,7 +138,7 @@ def setup_method(self, _):
139138
def test_task_1_query_status(self):
140139
task_token = self._anonymous_task_client.createDummyTask(2, False)
141140

142-
time.sleep(1)
141+
time.sleep(_TASK_PICKUP_WAIT)
143142
task_info: TaskInfo = self._anonymous_task_client.getTaskInfo(
144143
task_token)
145144
self.assertEqual(task_info.token, task_token)
@@ -166,7 +165,7 @@ def test_task_1_query_status(self):
166165
def test_task_2_query_status_of_failed(self):
167166
task_token = self._anonymous_task_client.createDummyTask(2, True)
168167

169-
time.sleep(1)
168+
time.sleep(_TASK_PICKUP_WAIT)
170169
task_info: TaskInfo = self._anonymous_task_client.getTaskInfo(
171170
task_token)
172171
self.assertEqual(task_info.token, task_token)
@@ -183,7 +182,7 @@ def test_task_2_query_status_of_failed(self):
183182
def test_task_3_cancel(self):
184183
task_token = self._anonymous_task_client.createDummyTask(3, False)
185184

186-
time.sleep(1)
185+
time.sleep(_TASK_PICKUP_WAIT)
187186
cancel_req: bool = self._privileged_task_client.cancelTask(task_token)
188187
self.assertTrue(cancel_req)
189188

@@ -366,7 +365,7 @@ def test_task_5_info_query_filters(self):
366365
# Let every task terminate. We should only need 1 second per task,
367366
# running likely in a multithreaded environment.
368367
# Let's have some leeway, though...
369-
time.sleep(2)
368+
time.sleep(_TASK_PICKUP_WAIT + 2)
370369

371370
task_infos = self._privileged_task_client.getTasks(TaskFilter(
372371
enqueuedAfterEpoch=current_time_epoch,

web/tests/libtest/codechecker.py

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -687,17 +687,17 @@ def wait_for_server_start(stdoutfile, port=None):
687687
f"{n}s. Output:")
688688
print(out[-2000:])
689689

690-
# Fallback: check if port is accepting connections.
690+
# Fallback: check if server can handle HTTP requests.
691691
if port and n > 3:
692-
import socket
692+
import urllib.request
693693
try:
694-
s = socket.create_connection(
695-
("localhost", port), timeout=1)
696-
s.close()
697-
print(f"Server port {port} open after {n}s "
698-
"(file detection missed it)")
694+
urllib.request.urlopen(
695+
f"http://localhost:{port}/", timeout=1)
696+
except urllib.error.HTTPError:
697+
# Any HTTP response (even 404) means server is ready.
698+
print(f"Server responding on port {port} after {n}s")
699699
return
700-
except (ConnectionRefusedError, OSError):
700+
except (ConnectionRefusedError, OSError, urllib.error.URLError):
701701
pass
702702

703703
if n > server_start_timeout.total_seconds():

0 commit comments

Comments
 (0)