diff options
author | 2017-02-10 10:38:14 +0000 | |
---|---|---|
committer | 2017-02-10 15:36:03 +0000 | |
commit | d2cba292a6904d188d5a903d5baee3ba873b0ec5 (patch) | |
tree | c2c111650fe560f1cf1b3c5541c2cbfea70455f8 /src/test/cpp/util/windows_test_util.cc | |
parent | da3099a0816f3c0e206a08962e5ffd77a0aac2de (diff) |
Bazel client, Windows, tests: `rm -rf TEST_TMPDIR`
Add test helpers to recursively delete the
TEST_TMPDIR in the TearDown method of tests, to
ensure each test sees a fresh temp directory.
Also add tests for these test helpers.
--
PiperOrigin-RevId: 147135561
MOS_MIGRATED_REVID=147135561
Diffstat (limited to 'src/test/cpp/util/windows_test_util.cc')
-rw-r--r-- | src/test/cpp/util/windows_test_util.cc | 104 |
1 files changed, 104 insertions, 0 deletions
diff --git a/src/test/cpp/util/windows_test_util.cc b/src/test/cpp/util/windows_test_util.cc new file mode 100644 index 0000000000..dfea7b05bb --- /dev/null +++ b/src/test/cpp/util/windows_test_util.cc @@ -0,0 +1,104 @@ +// Copyright 2016 The Bazel Authors. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +#include <windows.h> + +#include <algorithm> +#include <memory> +#include <string> + +#include "src/test/cpp/util/windows_test_util.h" + +#if !defined(COMPILER_MSVC) && !defined(__CYGWIN__) +#error("This test should only be run on Windows") +#endif // !defined(COMPILER_MSVC) && !defined(__CYGWIN__) + +namespace blaze_util { + +using std::unique_ptr; +using std::wstring; + +wstring GetTestTmpDirW() { + DWORD size = ::GetEnvironmentVariableW(L"TEST_TMPDIR", NULL, 0); + unique_ptr<WCHAR[]> buf(new WCHAR[size]); + ::GetEnvironmentVariableW(L"TEST_TMPDIR", buf.get(), size); + wstring result(buf.get()); + std::replace(result.begin(), result.end(), '/', '\\'); + return result; +} + +bool DeleteAllUnder(wstring path) { + static const wstring kDot(L"."); + static const wstring kDotDot(L".."); + + // Prepend UNC prefix if the path doesn't have it already. Don't bother + // checking if the path is shorter than MAX_PATH, let's just do it + // unconditionally; this is a test after all, performance isn't paramount. + if (path.find(L"\\\\?\\") != 0) { + path = wstring(L"\\\\?\\") + path; + } + // Append "\" if necessary. + if (path.back() != '\\') { + path.push_back('\\'); + } + + WIN32_FIND_DATAW metadata; + HANDLE handle = FindFirstFileW((path + L"*").c_str(), &metadata); + if (handle == INVALID_HANDLE_VALUE) { + return true; // directory doesn't exist + } + + bool result = true; + do { + wstring childname = metadata.cFileName; + if (kDot != childname && kDotDot != childname) { + wstring childpath = path + childname; + if ((metadata.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0) { + // If this is not a junction, delete its contents recursively. + // Finally delete this directory/junction too. + if (((metadata.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) == 0 && + !DeleteAllUnder(childpath)) || + !::RemoveDirectoryW(childpath.c_str())) { + result = false; + break; + } + } else { + if (!::DeleteFileW(childpath.c_str())) { + result = false; + break; + } + } + } + } while (FindNextFileW(handle, &metadata)); + FindClose(handle); + return result; +} + +bool CreateDummyFile(const wstring& path) { + HANDLE handle = + ::CreateFileW(path.c_str(), GENERIC_WRITE, FILE_SHARE_READ, NULL, + CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); + if (handle == INVALID_HANDLE_VALUE) { + return false; + } + bool result = true; + DWORD actually_written = 0; + if (!::WriteFile(handle, "hello", 5, &actually_written, NULL) && + actually_written != 5) { + result = false; + } + CloseHandle(handle); + return result; +} + +} // namespace blaze_util |