blob: a6ab71c2a52a4da94e6770630f1643dfd0da3732 [file] [log] [blame]
// 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