| // Copyright 2017 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. |
| |
| #ifndef WIN32_LEAN_AND_MEAN |
| #define WIN32_LEAN_AND_MEAN |
| #endif |
| #include <windows.h> |
| |
| #include <algorithm> |
| #include <memory> |
| #include <string> |
| |
| #include "src/main/cpp/blaze_util.h" |
| #include "src/main/cpp/blaze_util_platform.h" |
| #include "src/main/cpp/util/file.h" |
| #include "src/main/cpp/util/strings.h" |
| #include "googletest/include/gtest/gtest.h" |
| |
| namespace blaze { |
| |
| using std::string; |
| using std::unique_ptr; |
| using std::wstring; |
| |
| // Asserts that the envvar named `key` is unset. |
| // Exercises GetEnvironmentVariable{A,W}, both with `key` and its lower case |
| // version, to make sure that envvar retrieval is case-insensitive (envvar names |
| // are case-insensitive on Windows). |
| // |
| // This is a macro so the assertions will have the correct line number. |
| #define ASSERT_ENVVAR_UNSET(/* const char* */ key) \ |
| { \ |
| ASSERT_EQ(::GetEnvironmentVariableA(key, nullptr, 0), (DWORD)0); \ |
| ASSERT_EQ(::GetEnvironmentVariableA(blaze_util::AsLower(key).c_str(), \ |
| nullptr, 0), \ |
| (DWORD)0); \ |
| ASSERT_EQ(::GetEnvironmentVariableW( \ |
| blaze_util::CstringToWstring(key).c_str(), nullptr, 0), \ |
| (DWORD)0); \ |
| ASSERT_EQ( \ |
| ::GetEnvironmentVariableW( \ |
| blaze_util::CstringToWstring(blaze_util::AsLower(key)).c_str(), \ |
| nullptr, 0), \ |
| (DWORD)0); \ |
| } |
| |
| // Asserts that the envvar named `key` is set to the `expected` value. |
| // Exercises GetEnvironmentVariable{A,W}, both with `key` and its lower case |
| // version, to make sure that envvar retrieval is case-insensitive (envvar names |
| // are case-insensitive on Windows). |
| // |
| // This is a macro so the assertions will have the correct line number. |
| #define ASSERT_ENVVAR(/* const (char* | string&) */ _key, \ |
| /* const (char* | string&) */ _expected) \ |
| { \ |
| string key(_key); \ |
| string expected(_expected); \ |
| DWORD size = ::GetEnvironmentVariableA(key.c_str(), nullptr, 0); \ |
| ASSERT_GT(size, (DWORD)0); \ |
| unique_ptr<char[]> buf(new char[size]); \ |
| \ |
| /* Assert that GetEnvironmentVariableA can retrieve the value. */ \ |
| ASSERT_EQ(::GetEnvironmentVariableA(key.c_str(), buf.get(), size), \ |
| size - 1); \ |
| ASSERT_EQ(string(buf.get()), expected); \ |
| \ |
| /* Assert that envvar keys are case-insensitive. */ \ |
| string lkey(blaze_util::AsLower(key)); \ |
| ASSERT_EQ(::GetEnvironmentVariableA(lkey.c_str(), buf.get(), size), \ |
| size - 1); \ |
| ASSERT_EQ(string(buf.get()), expected); \ |
| \ |
| /* Assert that GetEnvironmentVariableW can retrieve the value. */ \ |
| wstring wkey(blaze_util::CstringToWstring(key)); \ |
| wstring wexpected(blaze_util::CstringToWstring(expected)); \ |
| size = ::GetEnvironmentVariableW(wkey.c_str(), nullptr, 0); \ |
| ASSERT_GT(size, (DWORD)0); \ |
| unique_ptr<WCHAR[]> wbuf(new WCHAR[size]); \ |
| ASSERT_EQ(::GetEnvironmentVariableW(wkey.c_str(), wbuf.get(), size), \ |
| size - 1); \ |
| ASSERT_EQ(wstring(wbuf.get()), wexpected); \ |
| \ |
| /* Assert that widechar envvar keys are case-insensitive. */ \ |
| wstring wlkey(blaze_util::CstringToWstring(lkey)); \ |
| ASSERT_EQ(::GetEnvironmentVariableW(wlkey.c_str(), wbuf.get(), size), \ |
| size - 1); \ |
| ASSERT_EQ(wstring(wbuf.get()), wexpected); \ |
| } |
| |
| TEST(BlazeUtilWindowsTest, TestGetEnv) { |
| #define _STR(x) #x |
| #define STR(x) _STR(x) |
| const char* envvar = "BAZEL_TEST_" STR(__LINE__); |
| #undef STR |
| #undef _STR |
| |
| ASSERT_TRUE(SetEnvironmentVariableA(envvar, "A\\B c")); |
| ASSERT_EQ(GetEnv(envvar), "A\\B c"); |
| } |
| |
| TEST(BlazeUtilWindowsTest, TestGetPathEnv) { |
| #define _STR(x) #x |
| #define STR(x) _STR(x) |
| const char* envvar = "BAZEL_TEST_" STR(__LINE__); |
| #undef STR |
| #undef _STR |
| |
| ASSERT_TRUE(SetEnvironmentVariableA(envvar, "A\\B c")); |
| ASSERT_EQ(GetPathEnv(envvar), "A/B c"); |
| |
| ASSERT_TRUE(SetEnvironmentVariableA(envvar, "\\\\?\\A:\\B c")); |
| ASSERT_EQ(GetPathEnv(envvar), "A:/B c"); |
| } |
| |
| TEST(BlazeUtilWindowsTest, TestSetEnv) { |
| ASSERT_ENVVAR_UNSET("Bazel_TEST_Key1"); |
| SetEnv("Bazel_TEST_Key1", "some_VALUE"); |
| ASSERT_ENVVAR("Bazel_TEST_Key1", "some_VALUE"); |
| SetEnv("Bazel_TEST_Key1", ""); |
| ASSERT_ENVVAR("Bazel_TEST_Key1", ""); |
| |
| string long_string(MAX_PATH, 'a'); |
| string long_key = string("Bazel_TEST_Key2_") + long_string; |
| string long_value = string("Bazel_TEST_Value2_") + long_string; |
| |
| ASSERT_ENVVAR_UNSET(long_key.c_str()); |
| SetEnv(long_key, long_value); |
| ASSERT_ENVVAR(long_key.c_str(), long_value.c_str()); |
| SetEnv(long_key, ""); |
| ASSERT_ENVVAR(long_key.c_str(), ""); |
| } |
| |
| TEST(BlazeUtilWindowsTest, TestUnsetEnv) { |
| ASSERT_ENVVAR_UNSET("Bazel_TEST_Key3"); |
| SetEnv("Bazel_TEST_Key3", "some_VALUE"); |
| ASSERT_ENVVAR("Bazel_TEST_Key3", "some_VALUE"); |
| UnsetEnv("Bazel_TEST_Key3"); |
| ASSERT_ENVVAR_UNSET("Bazel_TEST_Key3"); |
| |
| string long_string(MAX_PATH, 'a'); |
| string long_key = string("Bazel_TEST_Key4_") + long_string; |
| string long_value = string("Bazel_TEST_Value4_") + long_string; |
| |
| ASSERT_ENVVAR_UNSET(long_key.c_str()); |
| SetEnv(long_key, long_value); |
| ASSERT_ENVVAR(long_key.c_str(), long_value.c_str()); |
| UnsetEnv(long_key); |
| ASSERT_ENVVAR_UNSET(long_key.c_str()); |
| } |
| |
| } // namespace blaze |