mirror of
https://github.com/openai/codex.git
synced 2026-10-18 17:18:52 +00:00
Balance Windows Bazel test shards using duration estimates (#49103)
## Why Hash-based sharding does not account for differences in test duration. Use estimated test time to balance the Windows Bazel workload across shards. ## What changed - Add checked-in duration weights and a deterministic selector that assigns the longest targets first to the least-loaded shard. - Assign every queried target exactly once, default missing weights to one second, and ignore stale weights. - Run queries and selection in the foreground so failures stop the job before tests run with a partial target list. - Emit LF-delimited target labels for Git Bash and report estimated shard loads on stderr. ## Testing Add seven passing selector tests covering deterministic coverage and balancing, missing and stale weights, invalid inputs, duration-file overrides, and CLI output. Run them on the first Windows CI shard. GitOrigin-RevId: d415ae093bfe57794ee53a2eb9d712022202dad8
This commit is contained in:
@@ -0,0 +1,103 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
"""Assign Windows Bazel test targets using checked-in duration estimates."""
|
||||
|
||||
import argparse
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
DEFAULT_DURATION_SECONDS = 1
|
||||
DURATIONS_PATH = Path(__file__).with_name("windows_bazel_test_durations.tsv")
|
||||
|
||||
|
||||
def read_durations(path: Path) -> dict[str, int]:
|
||||
durations = {}
|
||||
for line_number, line in enumerate(
|
||||
path.read_text(encoding="utf-8").splitlines(), 1
|
||||
):
|
||||
if not line.strip() or line.lstrip().startswith("#"):
|
||||
continue
|
||||
fields = line.split("\t")
|
||||
if len(fields) != 2 or not fields[0] or not fields[1].isdecimal():
|
||||
raise ValueError(
|
||||
f"{path}:{line_number}: expected target<TAB>positive integer"
|
||||
)
|
||||
target, duration_text = fields
|
||||
duration = int(duration_text)
|
||||
if duration < 1:
|
||||
raise ValueError(f"{path}:{line_number}: duration must be positive")
|
||||
if target in durations:
|
||||
raise ValueError(f"{path}:{line_number}: duplicate target {target}")
|
||||
durations[target] = duration
|
||||
return durations
|
||||
|
||||
|
||||
def assign_targets(
|
||||
targets: list[str], durations: dict[str, int], shard_count: int
|
||||
) -> tuple[list[list[str]], list[int]]:
|
||||
if shard_count < 1:
|
||||
raise ValueError("shard count must be positive")
|
||||
if not targets:
|
||||
raise ValueError("no Bazel test targets were provided")
|
||||
if any(not target.strip() for target in targets):
|
||||
raise ValueError("Bazel test target labels must not be empty")
|
||||
if len(targets) != len(set(targets)):
|
||||
raise ValueError("duplicate Bazel test target labels were provided")
|
||||
|
||||
assignments: list[list[str]] = [[] for _ in range(shard_count)]
|
||||
loads = [0] * shard_count
|
||||
# Place the longest targets first, breaking ties by label and shard number.
|
||||
for target in sorted(
|
||||
targets,
|
||||
key=lambda target: (-durations.get(target, DEFAULT_DURATION_SECONDS), target),
|
||||
):
|
||||
shard = min(range(shard_count), key=lambda shard: (loads[shard], shard))
|
||||
assignments[shard].append(target)
|
||||
loads[shard] += durations.get(target, DEFAULT_DURATION_SECONDS)
|
||||
for assignment in assignments:
|
||||
assignment.sort()
|
||||
return assignments, loads
|
||||
|
||||
|
||||
def main() -> None:
|
||||
parser = argparse.ArgumentParser(description=__doc__)
|
||||
parser.add_argument("--shard", required=True, type=int)
|
||||
parser.add_argument("--shard-count", required=True, type=int)
|
||||
parser.add_argument(
|
||||
"--durations",
|
||||
type=Path,
|
||||
default=DURATIONS_PATH,
|
||||
help="use this timing file instead of the checked-in default",
|
||||
)
|
||||
args = parser.parse_args()
|
||||
if not 1 <= args.shard <= args.shard_count:
|
||||
parser.error("shard must be between 1 and shard count")
|
||||
|
||||
try:
|
||||
durations = read_durations(args.durations)
|
||||
targets = sys.stdin.read().splitlines()
|
||||
assignments, loads = assign_targets(targets, durations, args.shard_count)
|
||||
except (OSError, ValueError) as error:
|
||||
parser.error(str(error))
|
||||
|
||||
selected_targets = assignments[args.shard - 1]
|
||||
if not selected_targets:
|
||||
parser.error(
|
||||
f"no Bazel test targets selected for shard {args.shard}/{args.shard_count}"
|
||||
)
|
||||
|
||||
target_set = set(targets)
|
||||
print(
|
||||
f"Windows Bazel shards: targets={[len(assignment) for assignment in assignments]}, "
|
||||
f"estimated test-seconds={loads}, default weights={len(target_set - durations.keys())}, "
|
||||
f"unused weights={len(durations.keys() - target_set)}. "
|
||||
f"Selected shard {args.shard}/{args.shard_count}.",
|
||||
file=sys.stderr,
|
||||
)
|
||||
# Keep LF delimiters when native Windows Python feeds Git Bash mapfile.
|
||||
sys.stdout.buffer.write(("\n".join(selected_targets) + "\n").encode("utf-8"))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -0,0 +1,147 @@
|
||||
import subprocess
|
||||
import sys
|
||||
import tempfile
|
||||
import unittest
|
||||
from pathlib import Path
|
||||
|
||||
from select_windows_bazel_targets import DURATIONS_PATH
|
||||
from select_windows_bazel_targets import assign_targets
|
||||
from select_windows_bazel_targets import read_durations
|
||||
|
||||
|
||||
class SelectWindowsBazelTargetsTest(unittest.TestCase):
|
||||
def test_balances_targets_with_complete_deterministic_coverage(self) -> None:
|
||||
durations = {
|
||||
f"//test:{name}": duration
|
||||
for name, duration in zip("abcdefgh", range(8, 0, -1))
|
||||
}
|
||||
targets = list(durations)
|
||||
|
||||
assignments, loads = assign_targets(targets, durations, 4)
|
||||
|
||||
self.assertEqual(loads, [9, 9, 9, 9])
|
||||
self.assertEqual(
|
||||
sorted(target for shard in assignments for target in shard), sorted(targets)
|
||||
)
|
||||
self.assertEqual(
|
||||
assign_targets(list(reversed(targets)), durations, 4), (assignments, loads)
|
||||
)
|
||||
self.assertTrue(all(shard == sorted(shard) for shard in assignments))
|
||||
|
||||
def test_missing_weights_use_one_and_unused_weights_do_not_create_targets(
|
||||
self,
|
||||
) -> None:
|
||||
targets = ["//test:c", "//test:a", "//test:b"]
|
||||
|
||||
assignments, loads = assign_targets(targets, {"//test:stale": 100}, 2)
|
||||
|
||||
self.assertEqual(assignments, [["//test:a", "//test:c"], ["//test:b"]])
|
||||
self.assertEqual(loads, [2, 1])
|
||||
|
||||
def test_rejects_empty_or_duplicate_target_input(self) -> None:
|
||||
for targets in ([], [""], ["//test:a", "//test:a"]):
|
||||
with self.subTest(targets=targets), self.assertRaises(ValueError):
|
||||
assign_targets(targets, {}, 4)
|
||||
|
||||
def test_reads_duration_file_and_rejects_invalid_weights(self) -> None:
|
||||
with tempfile.TemporaryDirectory() as temp_dir:
|
||||
path = Path(temp_dir) / "durations.tsv"
|
||||
path.write_text(
|
||||
"# comment\n\n//test:a\t12\n//test:b\t1\n", encoding="utf-8"
|
||||
)
|
||||
self.assertEqual(read_durations(path), {"//test:a": 12, "//test:b": 1})
|
||||
|
||||
for contents in (
|
||||
"//test:a 12\n",
|
||||
"//test:a\t0\n",
|
||||
"//test:a\t-1\n",
|
||||
"//test:a\t1.5\n",
|
||||
"//test:a\t1\n//test:a\t2\n",
|
||||
):
|
||||
with self.subTest(contents=contents), self.assertRaises(ValueError):
|
||||
path.write_text(contents, encoding="utf-8")
|
||||
read_durations(path)
|
||||
|
||||
def test_cli_uses_checked_in_weights_and_writes_only_lf_delimited_targets(
|
||||
self,
|
||||
) -> None:
|
||||
durations = read_durations(DURATIONS_PATH)
|
||||
known = sorted(durations, key=lambda target: (-durations[target], target))[:4]
|
||||
self.assertEqual(len(known), 4)
|
||||
targets = [*known, "//test:new-target"]
|
||||
expected, _ = assign_targets(targets, durations, 4)
|
||||
script = DURATIONS_PATH.with_name("select_windows_bazel_targets.py")
|
||||
|
||||
for shard, assignment in enumerate(expected, 1):
|
||||
command = [
|
||||
sys.executable,
|
||||
str(script),
|
||||
"--shard",
|
||||
str(shard),
|
||||
"--shard-count",
|
||||
"4",
|
||||
]
|
||||
for ordered_targets in (targets, list(reversed(targets))):
|
||||
with self.subTest(shard=shard, ordered_targets=ordered_targets):
|
||||
result = subprocess.run(
|
||||
command,
|
||||
input=("\r\n".join(ordered_targets) + "\r\n").encode(),
|
||||
capture_output=True,
|
||||
check=True,
|
||||
)
|
||||
self.assertEqual(
|
||||
result.stdout, ("\n".join(assignment) + "\n").encode()
|
||||
)
|
||||
self.assertIn(b"default weights=1", result.stderr)
|
||||
|
||||
def test_cli_uses_only_the_requested_duration_file(self) -> None:
|
||||
script = DURATIONS_PATH.with_name("select_windows_bazel_targets.py").resolve()
|
||||
with tempfile.TemporaryDirectory() as temp_dir:
|
||||
path = Path(temp_dir) / "durations.tsv"
|
||||
path.write_text("//test:a\t1\n//test:b\t9\n", encoding="utf-8")
|
||||
command = [sys.executable, str(script), "--shard-count", "2"]
|
||||
for shard, expected in ((1, b"//test:b\n"), (2, b"//test:a\n//test:c\n")):
|
||||
with self.subTest(shard=shard):
|
||||
result = subprocess.run(
|
||||
[*command, "--shard", str(shard), "--durations", path.name],
|
||||
input=b"//test:a\n//test:b\n//test:c\n",
|
||||
cwd=temp_dir,
|
||||
capture_output=True,
|
||||
check=True,
|
||||
)
|
||||
self.assertEqual(result.stdout, expected)
|
||||
self.assertIn(b"estimated test-seconds=[9, 2]", result.stderr)
|
||||
self.assertIn(b"unused weights=0", result.stderr)
|
||||
|
||||
result = subprocess.run(
|
||||
[*command, "--shard", "1", "--durations", "missing.tsv"],
|
||||
input=b"//test:a\n",
|
||||
cwd=temp_dir,
|
||||
capture_output=True,
|
||||
check=False,
|
||||
)
|
||||
self.assertNotEqual(result.returncode, 0)
|
||||
self.assertEqual(result.stdout, b"")
|
||||
self.assertIn(b"missing.tsv", result.stderr)
|
||||
|
||||
def test_cli_rejects_bad_or_empty_selection_without_partial_output(self) -> None:
|
||||
script = DURATIONS_PATH.with_name("select_windows_bazel_targets.py")
|
||||
for targets, error in (
|
||||
(b"", b"no Bazel test targets were provided"),
|
||||
(b"//test:a\n//test:a\n", b"duplicate Bazel test target labels"),
|
||||
(b"//test:a\n", b"no Bazel test targets selected for shard 2/2"),
|
||||
):
|
||||
with self.subTest(targets=targets):
|
||||
result = subprocess.run(
|
||||
[sys.executable, str(script), "--shard", "2", "--shard-count", "2"],
|
||||
input=targets,
|
||||
capture_output=True,
|
||||
check=False,
|
||||
)
|
||||
self.assertNotEqual(result.returncode, 0)
|
||||
self.assertEqual(result.stdout, b"")
|
||||
self.assertIn(error, result.stderr)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
@@ -0,0 +1,253 @@
|
||||
# Windows Bazel duration weights; columns: target<TAB>seconds.
|
||||
# Seeded from 24 successful public openai/codex Windows job logs across six main
|
||||
# runs, September 21-23, 2026. Public GitHub Actions run IDs:
|
||||
# 35638529858, 35665540272, 35694732932, 35912411800, 35919297566, 35924169500.
|
||||
# To refresh, take the median summed inner-run time (N * average) from clean,
|
||||
# uncached PASSED summaries, excluding partial cache hits and FLAKY results.
|
||||
# Round up to positive integer seconds. These weights exclude build/download time.
|
||||
# Every queried target is assigned; missing weights default to 1 and stale entries are ignored.
|
||||
//codex-rs/agent-graph-store:agent-graph-store-unit-tests 76
|
||||
//codex-rs/agent-identity:agent-identity-unit-tests 66
|
||||
//codex-rs/agent-roles:agent-roles-unit-tests 48
|
||||
//codex-rs/analytics:analytics-unit-tests 29
|
||||
//codex-rs/app-server-client:app-server-client-unit-tests 51
|
||||
//codex-rs/app-server-daemon:app-server-daemon-unit-tests 4
|
||||
//codex-rs/app-server-protocol:app-server-protocol-unit-tests 19
|
||||
//codex-rs/app-server-test-client:app-server-test-client-unit-tests 25
|
||||
//codex-rs/app-server-test-client:codex-app-server-test-client-bin-unit-tests 1
|
||||
//codex-rs/app-server-transport:app-server-transport-unit-tests 65
|
||||
//codex-rs/app-server/tests/common:common-unit-tests 26
|
||||
//codex-rs/app-server:app-server-all-test-windows-cross 2835
|
||||
//codex-rs/app-server:app-server-unit-tests 399
|
||||
//codex-rs/app-server:codex-app-server-bin-unit-tests 48
|
||||
//codex-rs/app-server:codex-app-server-test-notify-capture-bin-unit-tests 1
|
||||
//codex-rs/app-server:exec-server-bin-unit-tests 1
|
||||
//codex-rs/app-server:test_notify_capture-bin-unit-tests 1
|
||||
//codex-rs/apply-patch:apply-patch-all-test-windows-cross 50
|
||||
//codex-rs/apply-patch:apply-patch-unit-tests 48
|
||||
//codex-rs/apply-patch:apply_patch-bin-unit-tests 24
|
||||
//codex-rs/arg0:arg0-unit-tests 24
|
||||
//codex-rs/backend-client:backend-client-unit-tests 41
|
||||
//codex-rs/chatgpt:chatgpt-all-test-windows-cross 26
|
||||
//codex-rs/chatgpt:chatgpt-unit-tests 27
|
||||
//codex-rs/cli:cli-app_server-test-windows-cross 3
|
||||
//codex-rs/cli:cli-app_server_daemon-test-windows-cross 1
|
||||
//codex-rs/cli:cli-cloud_auth-test-windows-cross 47
|
||||
//codex-rs/cli:cli-cloud_config-test-windows-cross 3
|
||||
//codex-rs/cli:cli-daemon_startup-test-windows-cross 4
|
||||
//codex-rs/cli:cli-daemon_telemetry-test-windows-cross 1
|
||||
//codex-rs/cli:cli-debug_clear_memories-test-windows-cross 4
|
||||
//codex-rs/cli:cli-debug_models-test-windows-cross 2
|
||||
//codex-rs/cli:cli-delete-test-windows-cross 2
|
||||
//codex-rs/cli:cli-doctor_enterprise_network-test-windows-cross 3
|
||||
//codex-rs/cli:cli-doctor_path_safety-test-windows-cross 47
|
||||
//codex-rs/cli:cli-exec_server-test-windows-cross 39
|
||||
//codex-rs/cli:cli-exec_server_websocket_auth-test-windows-cross 4
|
||||
//codex-rs/cli:cli-execpolicy-test-windows-cross 2
|
||||
//codex-rs/cli:cli-features-test-windows-cross 3
|
||||
//codex-rs/cli:cli-login-test-windows-cross 4
|
||||
//codex-rs/cli:cli-marketplace_add-test-windows-cross 2
|
||||
//codex-rs/cli:cli-marketplace_remove-test-windows-cross 1
|
||||
//codex-rs/cli:cli-marketplace_upgrade-test-windows-cross 2
|
||||
//codex-rs/cli:cli-mcp_add_remove-test-windows-cross 3
|
||||
//codex-rs/cli:cli-mcp_list-test-windows-cross 2
|
||||
//codex-rs/cli:cli-mcp_login-test-windows-cross 2
|
||||
//codex-rs/cli:cli-plugin_cli-test-windows-cross 7
|
||||
//codex-rs/cli:cli-queue-test-windows-cross 1
|
||||
//codex-rs/cli:cli-sandbox_cloud_config-test-windows-cross 48
|
||||
//codex-rs/cli:cli-sandbox_network_proxy-test-windows-cross 1
|
||||
//codex-rs/cli:cli-sandbox_tty-test-windows-cross 1
|
||||
//codex-rs/cli:cli-unit-tests 2
|
||||
//codex-rs/cli:cli-update-test-windows-cross 47
|
||||
//codex-rs/cli:cli-worktree-test-windows-cross 12
|
||||
//codex-rs/cli:codex-bin-unit-tests 60
|
||||
//codex-rs/cli:logs_client-bin-unit-tests 1
|
||||
//codex-rs/cloud-config:cloud-config-unit-tests 47
|
||||
//codex-rs/cloud-tasks-client:cloud-tasks-client-unit-tests 35
|
||||
//codex-rs/cloud-tasks-mock-client:cloud-tasks-mock-client-unit-tests 59
|
||||
//codex-rs/cloud-tasks:cloud-tasks-env_filter-test-windows-cross 1
|
||||
//codex-rs/cloud-tasks:cloud-tasks-unit-tests 1
|
||||
//codex-rs/code-mode-host:code-mode-host-grpc-test-windows-cross 28
|
||||
//codex-rs/code-mode-host:code-mode-host-grpc_notifications-test-windows-cross 25
|
||||
//codex-rs/code-mode-host:code-mode-host-grpc_tcp-test-windows-cross 1
|
||||
//codex-rs/code-mode-host:code-mode-host-grpc_timing-test-windows-cross 7
|
||||
//codex-rs/code-mode-host:code-mode-host-stdio-test-windows-cross 11
|
||||
//codex-rs/code-mode-host:code-mode-host-unit-tests 2
|
||||
//codex-rs/code-mode-host:codex-code-mode-host-bin-unit-tests 1
|
||||
//codex-rs/code-mode-protocol:code-mode-protocol-unit-tests 62
|
||||
//codex-rs/code-mode-runtime:code-mode-runtime-array_sort-test-windows-cross 24
|
||||
//codex-rs/code-mode-runtime:code-mode-runtime-jit-test-windows-cross 1
|
||||
//codex-rs/code-mode-runtime:code-mode-runtime-unit-tests 7
|
||||
//codex-rs/code-mode:code-mode-unit-tests 49
|
||||
//codex-rs/codex-api:codex-api-clients-test-windows-cross 75
|
||||
//codex-rs/codex-api:codex-api-models_integration-test-windows-cross 66
|
||||
//codex-rs/codex-api:codex-api-realtime_websocket_e2e-test-windows-cross 63
|
||||
//codex-rs/codex-api:codex-api-realtime_websocket_tls-test-windows-cross 66
|
||||
//codex-rs/codex-api:codex-api-sse_end_to_end-test-windows-cross 48
|
||||
//codex-rs/codex-api:codex-api-unit-tests 60
|
||||
//codex-rs/codex-home:codex-home-unit-tests 13
|
||||
//codex-rs/codex-mcp:codex-mcp-unit-tests 61
|
||||
//codex-rs/config-schema:codex-write-config-schema-bin-unit-tests 48
|
||||
//codex-rs/config:config-unit-tests 75
|
||||
//codex-rs/connectors:connectors-unit-tests 39
|
||||
//codex-rs/context-fragments:context-fragments-unit-tests 59
|
||||
//codex-rs/core-api:core-api-unit-tests 1
|
||||
//codex-rs/core-plugins:core-plugins-unit-tests 20
|
||||
//codex-rs/core/tests/common:common-unit-tests 48
|
||||
//codex-rs/core:core-all-test-windows-cross 3162
|
||||
//codex-rs/core:core-mcp_trace_propagation-test-windows-cross 2
|
||||
//codex-rs/core:core-responses_headers-test-windows-cross 5
|
||||
//codex-rs/core:core-unit-tests 251
|
||||
//codex-rs/exec-server-protocol:exec-server-protocol-unit-tests 48
|
||||
//codex-rs/exec-server/tests/support:support-unit-tests 48
|
||||
//codex-rs/exec-server:exec-server-accepted_websocket-test-windows-cross 1
|
||||
//codex-rs/exec-server:exec-server-capability_discovery-test-windows-cross 1
|
||||
//codex-rs/exec-server:exec-server-chatgpt_cloudflare_affinity-test-windows-cross 1
|
||||
//codex-rs/exec-server:exec-server-deferred_environment-test-windows-cross 1
|
||||
//codex-rs/exec-server:exec-server-environment-test-windows-cross 10
|
||||
//codex-rs/exec-server:exec-server-environment_config-test-windows-cross 1
|
||||
//codex-rs/exec-server:exec-server-exec_process-test-windows-cross 1
|
||||
//codex-rs/exec-server:exec-server-file_stream-test-windows-cross 1
|
||||
//codex-rs/exec-server:exec-server-file_system_unix-test-windows-cross 1
|
||||
//codex-rs/exec-server:exec-server-file_system_windows-test-windows-cross 11
|
||||
//codex-rs/exec-server:exec-server-forward-test-windows-cross 10
|
||||
//codex-rs/exec-server:exec-server-health-test-windows-cross 1
|
||||
//codex-rs/exec-server:exec-server-http_client-test-windows-cross 2
|
||||
//codex-rs/exec-server:exec-server-http_request-test-windows-cross 1
|
||||
//codex-rs/exec-server:exec-server-http_request_logging-test-windows-cross 3
|
||||
//codex-rs/exec-server:exec-server-initialize-test-windows-cross 1
|
||||
//codex-rs/exec-server:exec-server-macos_fs_spawn-test-windows-cross 1
|
||||
//codex-rs/exec-server:exec-server-process-test-windows-cross 4
|
||||
//codex-rs/exec-server:exec-server-relay-test-windows-cross 8
|
||||
//codex-rs/exec-server:exec-server-selected_capability_roots-test-windows-cross 1
|
||||
//codex-rs/exec-server:exec-server-unit-tests 116
|
||||
//codex-rs/exec-server:exec-server-websocket-test-windows-cross 1
|
||||
//codex-rs/exec:codex-exec-bin-unit-tests 1
|
||||
//codex-rs/exec:exec-all-test-windows-cross 331
|
||||
//codex-rs/exec:exec-event_processor_with_json_output-test-windows-cross 1
|
||||
//codex-rs/exec:exec-unit-tests 47
|
||||
//codex-rs/ext/agent-message-board:agent-message-board-local_board-test-windows-cross 46
|
||||
//codex-rs/ext/agent-message-board:agent-message-board-unit-tests 30
|
||||
//codex-rs/ext/agent:agent-agent_service-test-windows-cross 3
|
||||
//codex-rs/ext/agent:agent-unit-tests 1
|
||||
//codex-rs/ext/connectors:connectors-unit-tests 47
|
||||
//codex-rs/ext/extension-api:extension-api-capabilities-test-windows-cross 14
|
||||
//codex-rs/ext/extension-api:extension-api-registry-test-windows-cross 31
|
||||
//codex-rs/ext/extension-api:extension-api-state-test-windows-cross 57
|
||||
//codex-rs/ext/extension-api:extension-api-unit-tests 35
|
||||
//codex-rs/ext/git-attribution:git-attribution-unit-tests 30
|
||||
//codex-rs/ext/goal:goal-accounting-test-windows-cross 1
|
||||
//codex-rs/ext/goal:goal-goal_extension_backend-test-windows-cross 9
|
||||
//codex-rs/ext/goal:goal-steering-test-windows-cross 1
|
||||
//codex-rs/ext/goal:goal-unit-tests 47
|
||||
//codex-rs/ext/guardian-reviewer:guardian-reviewer-unit-tests 36
|
||||
//codex-rs/ext/guardian-v2:guardian-v2-unit-tests 50
|
||||
//codex-rs/ext/history-notes:history-notes-history_notes_extension-test-windows-cross 1
|
||||
//codex-rs/ext/history-notes:history-notes-image_model_input-test-windows-cross 2
|
||||
//codex-rs/ext/history-notes:history-notes-unit-tests 1
|
||||
//codex-rs/ext/image-generation:image-generation-unit-tests 47
|
||||
//codex-rs/ext/mcp:mcp-hosted_apps_mcp-test-windows-cross 26
|
||||
//codex-rs/ext/mcp:mcp-plugin_mcp-test-windows-cross 5
|
||||
//codex-rs/ext/mcp:mcp-unit-tests 48
|
||||
//codex-rs/ext/memories:memories-unit-tests 28
|
||||
//codex-rs/ext/queue:queue-queue_service-test-windows-cross 9
|
||||
//codex-rs/ext/queue:queue-unit-tests 25
|
||||
//codex-rs/ext/skills:skills-executor_file_system_authority-test-windows-cross 36
|
||||
//codex-rs/ext/skills:skills-skills_extension-test-windows-cross 7
|
||||
//codex-rs/ext/skills:skills-unit-tests 8
|
||||
//codex-rs/ext/web-search:web-search-unit-tests 1
|
||||
//codex-rs/external-agent-migration:external-agent-migration-unit-tests 4
|
||||
//codex-rs/features:features-unit-tests 47
|
||||
//codex-rs/feedback:feedback-unit-tests 77
|
||||
//codex-rs/file-system:file-system-unit-tests 48
|
||||
//codex-rs/git-utils:git-utils-unit-tests 83
|
||||
//codex-rs/guardian-context:guardian-context-cache_prefix-test-windows-cross 66
|
||||
//codex-rs/guardian-context:guardian-context-unit-tests 67
|
||||
//codex-rs/history:history-unit-tests 59
|
||||
//codex-rs/hooks:hooks-unit-tests 16
|
||||
//codex-rs/hooks:write_hooks_schema_fixtures-bin-unit-tests 48
|
||||
//codex-rs/lmstudio:lmstudio-unit-tests 1
|
||||
//codex-rs/login:login-all-test-windows-cross 5
|
||||
//codex-rs/login:login-unit-tests 320
|
||||
//codex-rs/memories/read:read-unit-tests 62
|
||||
//codex-rs/memories/write:write-unit-tests 20
|
||||
//codex-rs/message-history:message-history-unit-tests 74
|
||||
//codex-rs/model-provider-info:model-provider-info-unit-tests 63
|
||||
//codex-rs/model-provider:model-provider-unit-tests 64
|
||||
//codex-rs/models-manager:models-manager-unit-tests 35
|
||||
//codex-rs/mxc-sandbox:mxc-sandbox-unit-tests 36
|
||||
//codex-rs/network-proxy:codex-network-proxy-bin-unit-tests 48
|
||||
//codex-rs/network-proxy:network-proxy-unit-tests 85
|
||||
//codex-rs/network-proxy:network-proxy-windows_stable_ingress-test-windows-cross 37
|
||||
//codex-rs/ollama:ollama-unit-tests 1
|
||||
//codex-rs/otel:otel-tests-test-windows-cross 17
|
||||
//codex-rs/otel:otel-unit-tests 48
|
||||
//codex-rs/plugin:plugin-unit-tests 74
|
||||
//codex-rs/prompts:prompts-unit-tests 62
|
||||
//codex-rs/protocol:protocol-unit-tests 67
|
||||
//codex-rs/response-debug-context:response-debug-context-unit-tests 66
|
||||
//codex-rs/rmcp-client:rmcp-client-foreign_stdio_cwd-test-windows-cross 48
|
||||
//codex-rs/rmcp-client:rmcp-client-mcp_2026_discovery-test-windows-cross 4
|
||||
//codex-rs/rmcp-client:rmcp-client-mcp_2026_message_limits-test-windows-cross 4
|
||||
//codex-rs/rmcp-client:rmcp-client-mcp_2026_mrtr-test-windows-cross 2
|
||||
//codex-rs/rmcp-client:rmcp-client-mcp_2026_oauth_discovery-test-windows-cross 1
|
||||
//codex-rs/rmcp-client:rmcp-client-mcp_2026_sse_discovery-test-windows-cross 1
|
||||
//codex-rs/rmcp-client:rmcp-client-mcp_2026_stdio-test-windows-cross 39
|
||||
//codex-rs/rmcp-client:rmcp-client-mcp_2026_stdio_discovery-test-windows-cross 2
|
||||
//codex-rs/rmcp-client:rmcp-client-mcp_events-test-windows-cross 2
|
||||
//codex-rs/rmcp-client:rmcp-client-process_group_cleanup-test-windows-cross 1
|
||||
//codex-rs/rmcp-client:rmcp-client-resources-test-windows-cross 1
|
||||
//codex-rs/rmcp-client:rmcp-client-stdio_descriptor_boundary-test-windows-cross 1
|
||||
//codex-rs/rmcp-client:rmcp-client-stdio_message_limits-test-windows-cross 3
|
||||
//codex-rs/rmcp-client:rmcp-client-stdio_stderr_cleanup-test-windows-cross 1
|
||||
//codex-rs/rmcp-client:rmcp-client-streamable_http_oauth_startup-test-windows-cross 6
|
||||
//codex-rs/rmcp-client:rmcp-client-streamable_http_oauth_store_pinning-test-windows-cross 38
|
||||
//codex-rs/rmcp-client:rmcp-client-streamable_http_oauth_tool_call-test-windows-cross 2
|
||||
//codex-rs/rmcp-client:rmcp-client-streamable_http_recovery-test-windows-cross 51
|
||||
//codex-rs/rmcp-client:rmcp-client-streamable_http_remote-test-windows-cross 3
|
||||
//codex-rs/rmcp-client:rmcp-client-streamable_http_test_support-test-windows-cross 1
|
||||
//codex-rs/rmcp-client:rmcp-client-streamable_http_user_agent-test-windows-cross 1
|
||||
//codex-rs/rmcp-client:rmcp-client-unit-tests 50
|
||||
//codex-rs/rmcp-client:rmcp_test_server-bin-unit-tests 39
|
||||
//codex-rs/rmcp-client:test_mcp_2026_discovery_stdio_server-bin-unit-tests 43
|
||||
//codex-rs/rmcp-client:test_mcp_2026_stdio_server-bin-unit-tests 25
|
||||
//codex-rs/rmcp-client:test_stdio_server-bin-unit-tests 41
|
||||
//codex-rs/rmcp-client:test_streamable_http_server-bin-unit-tests 40
|
||||
//codex-rs/rollout-trace:rollout-trace-unit-tests 76
|
||||
//codex-rs/rollout:rollout-unit-tests 56
|
||||
//codex-rs/sandboxing:sandboxing-unit-tests 74
|
||||
//codex-rs/secrets:secrets-unit-tests 57
|
||||
//codex-rs/shell-command:shell-command-unit-tests 60
|
||||
//codex-rs/shell-escalation:codex-execve-wrapper-bin-unit-tests 62
|
||||
//codex-rs/shell-escalation:shell-escalation-unit-tests 60
|
||||
//codex-rs/skills:skills-unit-tests 59
|
||||
//codex-rs/state:state-unit-tests 242
|
||||
//codex-rs/test-binary-support:test-binary-support-unit-tests 48
|
||||
//codex-rs/thread-manager-sample:codex-thread-manager-sample-bin-unit-tests 47
|
||||
//codex-rs/thread-store:thread-store-unit-tests 95
|
||||
//codex-rs/tools:tools-json_schema_policy_fixtures-test-windows-cross 34
|
||||
//codex-rs/tools:tools-unit-tests 37
|
||||
//codex-rs/tui:codex-tui-bin-unit-tests 2
|
||||
//codex-rs/tui:md-events-bin-unit-tests 1
|
||||
//codex-rs/tui:tui-all-test-windows-cross 36
|
||||
//codex-rs/tui:tui-manager_dependency_regression-test-windows-cross 2
|
||||
//codex-rs/tui:tui-test_backend-test-windows-cross 25
|
||||
//codex-rs/tui:tui-unit-tests 1003
|
||||
//codex-rs/utils/approval-presets:approval-presets-unit-tests 66
|
||||
//codex-rs/utils/audio:audio-unit-tests 76
|
||||
//codex-rs/utils/cli:cli-unit-tests 64
|
||||
//codex-rs/utils/git-discovery:git-discovery-unit-tests 59
|
||||
//codex-rs/utils/oss:oss-unit-tests 1
|
||||
//codex-rs/utils/output-truncation:output-truncation-unit-tests 60
|
||||
//codex-rs/utils/plugins:plugins-unit-tests 36
|
||||
//codex-rs/utils/sandbox-summary:sandbox-summary-unit-tests 66
|
||||
//codex-rs/windows-sandbox-rs:codex-command-runner-bin-unit-tests 1
|
||||
//codex-rs/windows-sandbox-rs:codex-windows-managed-deny-probe-bin-unit-tests 1
|
||||
//codex-rs/windows-sandbox-rs:codex-windows-sandbox-setup-bin-unit-tests 1
|
||||
//codex-rs/windows-sandbox-rs:windows-sandbox-rs-helper_manifest-test-windows-cross 1
|
||||
//codex-rs/windows-sandbox-rs:windows-sandbox-rs-unit-tests 23
|
||||
//codex-rs/windows-sandbox-service:codex-windows-sandbox-service-bin-unit-tests 46
|
||||
//codex-rs/windows-sandbox-service:windows-sandbox-service-unit-tests 12
|
||||
//codex-rs/worktree:worktree-settings-test-windows-cross 59
|
||||
//codex-rs/worktree:worktree-unit-tests 76
|
||||
//codex-rs/worktree:worktree-worktree-test-windows-cross 92
|
||||
|
Reference in New Issue
Block a user