--- old/test/hotspot/gtest/runtime/test_os_windows.cpp 2019-09-27 10:20:21.230952400 +0200 +++ new/test/hotspot/gtest/runtime/test_os_windows.cpp 2019-09-27 10:20:20.558950800 +0200 @@ -85,27 +85,29 @@ << "Failed to allocate memory at requested location " << expected_location << " of size " << expected_allocation_size; } - -// Test which tries to find out if the os::stat, os::open and os::dir_is_empty methods -// can handle long path names correctly. +// The types of path modifications we randomly apply to a path. They should not change the file designated by the path. enum ModsFilter { - Allow_None = 0, - Allow_Sep_Mods = 1, - Allow_Dot_Path = 2, - Allow_Dot_Dot_Path = 4, + Allow_None = 0, // No modifications + Allow_Sep_Mods = 1, // Replace '\\' by any sequence of '/' or '\\' or at least length 1. + Allow_Dot_Path = 2, // Add /. segments at random positions + Allow_Dot_Dot_Path = 4, // Add /../ segments at random positions. Allow_All = Allow_Sep_Mods | Allow_Dot_Path | Allow_Dot_Dot_Path }; +// The mode in which to run. enum Mode { - TEST, - EXAMPLES, - BENCH + TEST, // Runs the test. This is the normal modus. + EXAMPLES, // Runs example which document the behaviour of the Windows system calls. + BENCH // Runs a small benchmark which tries to show the costs of using the *W variants/_wfullpath. }; +// Parameters of the test. static ModsFilter mods_filter = Allow_All; -static int mods_per_path = 50; +static int mods_per_path = 50; // The number of variants of a path we try. static Mode mode = TEST; + +// Utility methods static void get_current_dir_w(wchar_t* path, size_t size) { DWORD count = GetCurrentDirectoryW((DWORD) size, path); EXPECT_GT((int) count, 0) << "Failed to get current directory: " << GetLastError(); @@ -160,10 +162,6 @@ return err == ERROR_SUCCESS; } -static const wchar_t* sep_replacements[] = { - L"\\", L"\\/", L"/", L"//", L"\\\\/\\", L"//\\/" -}; - static wchar_t* my_wcscpy_s(wchar_t* dest, size_t size, wchar_t* start, const wchar_t* to_copy) { size_t already_used = dest - start; size_t len = wcslen(to_copy); @@ -175,6 +173,12 @@ return dest + wcslen(to_copy); } +// The currently finite list of seperator sequences we might use instead of '\\'. +static const wchar_t* sep_replacements[] = { + L"\\", L"\\/", L"/", L"//", L"\\\\/\\", L"//\\/" +}; + +// Takes a path and modifies it in a way that it should still designate the same file. static bool unnormalize_path(wchar_t* result, size_t size, bool is_dir, const wchar_t* path) { wchar_t* dest = result; const wchar_t* src = path; @@ -312,6 +316,20 @@ static void check_file(wchar_t* path) { check_file_impl(path); + // Check os::same_files at least somewhat. + char buf[JVM_MAXPATHLEN]; + + if (convert_to_cstring(buf, JVM_MAXPATHLEN, path)) { + wchar_t mod[JVM_MAXPATHLEN]; + + if (unnormalize_path(mod, JVM_MAXPATHLEN, false, path)) { + char mod_c[JVM_MAXPATHLEN]; + if (convert_to_cstring(mod_c, JVM_MAXPATHLEN, mod)) { + EXPECT_EQ(os::same_files(buf, mod_c), true) << "os::same files failed for \\" << path << "\" and \"" << mod_c << "\""; + } + } + } + for (int i = 0; mods_filter != Allow_None && i < mods_per_path; ++i) { wchar_t tmp[JVM_MAXPATHLEN]; if (unnormalize_path(tmp, JVM_MAXPATHLEN, false, path)) { @@ -367,6 +385,7 @@ succ = true; } + // Note that we really don't use the full path name, but just add the cost of running _wfullpath. os::free(tmp); } if (!succ) { @@ -448,6 +467,8 @@ #define NAME_PART_50 L"01234567890123456789012345678901234567890123456789" #define NAME_PART_250 NAME_PART_50 NAME_PART_50 NAME_PART_50 NAME_PART_50 NAME_PART_50 +// Test which tries to find out if the os::stat, os::open and os::dir_is_empty methods +// can handle long path names correctly. TEST_VM(os_windows, handle_long_paths) { static wchar_t cwd[JVM_MAXPATHLEN]; static wchar_t nearly_long_rel_path[JVM_MAXPATHLEN];