| // 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, NULL, 0), (DWORD)0);             \ | 
 |     ASSERT_EQ(                                                                \ | 
 |         ::GetEnvironmentVariableA(blaze_util::AsLower(key).c_str(), NULL, 0), \ | 
 |         (DWORD)0);                                                            \ | 
 |     ASSERT_EQ(::GetEnvironmentVariableW(                                      \ | 
 |                   blaze_util::CstringToWstring(key).c_str(), NULL, 0),        \ | 
 |               (DWORD)0);                                                      \ | 
 |     ASSERT_EQ(                                                                \ | 
 |         ::GetEnvironmentVariableW(                                            \ | 
 |             blaze_util::CstringToWstring(blaze_util::AsLower(key)).c_str(),   \ | 
 |             NULL, 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(), NULL, 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(), NULL, 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_UNSET("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_UNSET(long_key.c_str()); | 
 | } | 
 |  | 
 | TEST(BlazeUtilWindowsTest, TestUnsetEnv) { | 
 |   ASSERT_ENVVAR_UNSET("Bazel_TEST_Key1"); | 
 |   SetEnv("Bazel_TEST_Key1", "some_VALUE"); | 
 |   ASSERT_ENVVAR("Bazel_TEST_Key1", "some_VALUE"); | 
 |   UnsetEnv("Bazel_TEST_Key1"); | 
 |   ASSERT_ENVVAR_UNSET("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()); | 
 |   UnsetEnv(long_key); | 
 |   ASSERT_ENVVAR_UNSET(long_key.c_str()); | 
 | } | 
 |  | 
 | }  // namespace blaze |