Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 30 additions & 7 deletions scripts/run-tests-parallel.sh
Original file line number Diff line number Diff line change
Expand Up @@ -48,16 +48,32 @@ mkdir -p "$LOGDIR"
# setup. Two idempotent steps: protect the DIRECTORY (inheritance flags are
# directory-only — a /T re-root leaves files with empty deny-all DACLs),
# then /reset the children to re-inherit the clean set.
case "$(uname -s 2>/dev/null)" in
MINGW* | MSYS*)
stamp_windows_build_dir() {
local when="$1"
case "$(uname -s 2>/dev/null)" in
MINGW* | MSYS*) ;;
*) return 0 ;;
esac
local runner_dir_w me stamp_out reset_out
runner_dir_w="$(cygpath -w "$(dirname "$RUNNER")")"
me="$(whoami | tr -d '\r')"
MSYS2_ARG_CONV_EXCL='*' icacls "$runner_dir_w" /inheritance:r \
stamp_out=$(MSYS2_ARG_CONV_EXCL='*' icacls "$runner_dir_w" /inheritance:r \
/grant:r "${me}:(OI)(CI)F" '*S-1-5-18:(OI)(CI)F' '*S-1-5-32-544:(OI)(CI)F' \
/Q >/dev/null 2>&1 || true
MSYS2_ARG_CONV_EXCL='*' icacls "${runner_dir_w}\\*" /reset /T /C /Q >/dev/null 2>&1 || true
;;
esac
/Q 2>&1) || echo "WARN: build-dir DACL stamp ($when) failed (user=$me dir=$runner_dir_w): $stamp_out"
reset_out=$(MSYS2_ARG_CONV_EXCL='*' icacls "${runner_dir_w}\\*" /reset /T /C /Q 2>&1) ||
echo "WARN: build-dir child DACL reset ($when) failed: $(printf '%s' "$reset_out" | tail -2)"
# The stamp is load-bearing for the install-flow suites: verify it and say
# so, in either direction — a silent stamp once cost a full CI round to
# even see WHETHER it had run.
if MSYS2_ARG_CONV_EXCL='*' icacls "$runner_dir_w" 2>/dev/null |
grep -qE 'Authenticated Users|CREATOR OWNER'; then
echo "WARN: build-dir DACL still grants cross-account mutation after $when stamp:"
MSYS2_ARG_CONV_EXCL='*' icacls "$runner_dir_w" 2>&1 | head -8
else
echo "build-dir DACL stamped clean ($when, $runner_dir_w, user=$me)"
fi
}
stamp_windows_build_dir pre-wave

SUITES_FILE="$LOGDIR/suites.txt"
RESULTS_FILE="$LOGDIR/results.txt"
Expand Down Expand Up @@ -232,6 +248,13 @@ while IFS= read -r sname; do
echo "$sname" >> "$FLEX_FILE"
fi
done < "$SER_FILE"
# Wave suites spawn Cygwin-family tooling that can rewrite the build
# directory's DACL behind the first stamp (observed: an arm shard whose
# tail held the install-flow suites failed the source-directory policy
# minutes after a clean pre-wave stamp, while its sibling shard passed).
# Re-stamp at the tail boundary so the deadline-sensitive tail — which
# hosts those suites — always starts from the verified-clean shape.
stamp_windows_build_dir pre-tail
xargs -P "${CBM_TAIL_JOBS:-2}" -I{} bash -c 'run_one "$@"' _ {} < "$FLEX_FILE"
while IFS= read -r sname; do
run_one "$sname"
Expand Down
16 changes: 15 additions & 1 deletion src/daemon/service.c
Original file line number Diff line number Diff line change
Expand Up @@ -856,12 +856,26 @@ static bool windows_private_file_prepare(const char *directory, const char *base
* to the ~16 ms timer granularity, and a permanently obstructed path
* (e.g. a directory squatting on it) must fail fast — a rejected client
* is waiting behind this on the hello path with its own timeout. */
ULONGLONG deadline = GetTickCount64() + 250;
ULONGLONG obstruction_deadline = GetTickCount64() + 250;
/* Genuine share collisions get a wider budget than obstruction: with
* many concurrent appenders on a loaded, sanitized CI runner the
* last-in-line writer can legitimately spend more than 250 ms behind
* its peers' brief exclusive windows, and the no-drop contract for
* conflict events outranks latency there — while a permanently
* obstructed path (a directory squatting on the name) still fails
* inside 250 ms, because a rejected client is waiting behind this on
* the hello path with its own timeout. */
ULONGLONG contention_deadline = GetTickCount64() + 2000;
for (;;) {
SetLastError(ERROR_SUCCESS);
FILE *file = cbm_daemon_ipc_private_log_open(directory, base, SIZE_MAX);
if (file) {
return fclose(file) == 0;
}
DWORD open_error = GetLastError();
bool transient_collision =
open_error == ERROR_SHARING_VIOLATION || open_error == ERROR_LOCK_VIOLATION;
ULONGLONG deadline = transient_collision ? contention_deadline : obstruction_deadline;
if (GetTickCount64() >= deadline) {
return false;
}
Expand Down
7 changes: 6 additions & 1 deletion tests/test_daemon_application.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,12 @@
#include <stdlib.h>
#include <string.h>

enum { APP_TEST_TIMEOUT_MS = 2000, APP_TEST_PATH_CAP = 1024 };
/* Observation-wait budget. This is a HANG DETECTOR, not a latency
* assertion: every waiter returns the moment its condition holds, so green
* runs never pay it. It must absorb ThreadSanitizer's 5-20x slowdown on a
* loaded 3-core CI runner — at 2000 ms the cancel-delivery wait lost the
* tail of that distribution once in seven otherwise-green TSan rounds. */
enum { APP_TEST_TIMEOUT_MS = 10000, APP_TEST_PATH_CAP = 1024 };

typedef struct {
char runtime_parent[APP_TEST_PATH_CAP];
Expand Down
Loading