diff --git a/src/test/shell/bin/bazel b/src/test/shell/bin/bazel index 985a15da082c30..6ed29a01c67f81 100755 --- a/src/test/shell/bin/bazel +++ b/src/test/shell/bin/bazel @@ -23,4 +23,9 @@ bazel_bin=$(rlocation io_bazel/src/bazel) unset RUNFILES_DIR unset RUNFILES_MANIFEST_FILE unset RUNFILES_MANIFEST_ONLY +# Also unset sharding related environment variables so that tests executed with +# bazel run do not inherit them from the integration test. +unset TEST_TOTAL_SHARDS +unset TEST_SHARD_INDEX +unset TEST_SHARD_STATUS_FILE exec $bazel_bin --nohome_rc --nosystem_rc --bazelrc=$TEST_TMPDIR/bazelrc "$@" diff --git a/tools/test/test-setup.sh b/tools/test/test-setup.sh index 952754c82dd62d..47d32cccdb9ace 100755 --- a/tools/test/test-setup.sh +++ b/tools/test/test-setup.sh @@ -75,6 +75,9 @@ fi if [[ -n "$TEST_SHARD_STATUS_FILE" ]]; then is_absolute "$TEST_SHARD_STATUS_FILE" || TEST_SHARD_STATUS_FILE="$PWD/$TEST_SHARD_STATUS_FILE" mkdir -p "$(dirname "$TEST_SHARD_STATUS_FILE")" + # Get the modification time in nano second granularity or record that it was missing. + TEST_SHARD_STATUS_FILE_MTIME_AT_START=$(stat -c '%.9Y' "$TEST_SHARD_STATUS_FILE" 2> /dev/null || + echo "missing") fi is_absolute "$RUNFILES_DIR" || RUNFILES_DIR="$PWD/$RUNFILES_DIR" @@ -368,6 +371,16 @@ kill_group SIGKILL $childPid kill_group SIGKILL $cleanupPid &> /dev/null wait $cleanupPid +# Sharding was requested, verify that the test runner actually supported it. +if [[ -n "$TEST_SHARD_STATUS_FILE" ]]; then + TEST_SHARD_STATUS_FILE_MTIME_AT_END=$(stat -c '%.9Y' "$TEST_SHARD_STATUS_FILE" 2> /dev/null || + echo "missing") + if [[ "$TEST_SHARD_STATUS_FILE_MTIME_AT_START" = "$TEST_SHARD_STATUS_FILE_MTIME_AT_END" ]]; then + echo >&2 "FAILED: Sharding requested, but the test runner did not advertise support for it by touching TEST_SHARD_STATUS_FILE. Either remove the 'shard_count' attribute or use a test runner that supports sharding." + exit 1 + fi +fi + for signal in $signals; do trap - ${signal} done diff --git a/tools/test/windows/tw.cc b/tools/test/windows/tw.cc index 2992acf2129d10..02cd142aa66dd0 100644 --- a/tools/test/windows/tw.cc +++ b/tools/test/windows/tw.cc @@ -605,6 +605,42 @@ bool ExportShardStatusFile(const Path& cwd) { CreateDirectories(status_file.Dirname()); } +bool GetLenientShardStatusFileModificationTime(uint64_t* mtime) { + Path status_file; + if (!GetPathEnv(L"TEST_SHARD_STATUS_FILE", &status_file) || + status_file.Get().empty()) { + return false; + } + + bazel::windows::AutoHandle handle(CreateFileW( + AddUncPrefixMaybe(status_file).c_str(), GENERIC_READ, + FILE_SHARE_READ | FILE_SHARE_DELETE, nullptr, OPEN_EXISTING, + FILE_ATTRIBUTE_NORMAL, nullptr)); + if (!handle.IsValid()) { + DWORD err = GetLastError(); + if (err != ERROR_FILE_NOT_FOUND) { + LogErrorWithArgAndValue( + __LINE__, "Failed to open shard status file", status_file.Get(), err); + } + *mtime = 0; + return true; + } + + FILETIME lastWriteTime; + if (!GetFileTime(handle, nullptr, nullptr, &lastWriteTime)) { + DWORD err = GetLastError(); + LogErrorWithArgAndValue( + __LINE__, "Failed to get file time of shard status file", + status_file.Get(), err); + *mtime = 0; + return true; + } + + *mtime = ((uint64_t) lastWriteTime.dwHighDateTime << 32) | + lastWriteTime.dwLowDateTime; + return true; +} + bool ExportGtestVariables(const Path& test_tmpdir) { // # Tell googletest about Bazel sharding. std::wstring total_shards_str; @@ -1925,6 +1961,7 @@ int TestWrapperMain(int argc, wchar_t** argv) { Path test_path, exec_root, srcdir, tmpdir, test_outerr, xml_log; UndeclaredOutputs undecl; std::wstring args; + uint64_t shard_status_file_mtime_start, shard_status_file_mtime_end; if (!AddCurrentDirectoryToPATH() || !ParseArgs(argc, argv, &argv0, &test_path_arg, &args) || !PrintTestLogStartMarker() || !GetCwd(&exec_root) || !ExportUserName() || @@ -1939,8 +1976,17 @@ int TestWrapperMain(int argc, wchar_t** argv) { return 1; } + GetLenientShardStatusFileModificationTime(&shard_status_file_mtime_start); Duration test_duration; int result = RunSubprocess(test_path, args, test_outerr, &test_duration); + if (GetLenientShardStatusFileModificationTime(&shard_status_file_mtime_end) && + shard_status_file_mtime_start == shard_status_file_mtime_end) { + LogError(__LINE__, "Sharding requested, but the test runner did not" + " advertise support for it by touching TEST_SHARD_STATUS_FILE. Either" + " remove the 'shard_count' attribute or use a test runner that supports" + " sharding."); + return 1; + } if (!CreateXmlLog(xml_log, test_outerr, test_duration, result, DeleteAfterwards::kEnabled, MainType::kTestWrapperMain) || !ArchiveUndeclaredOutputs(undecl) ||