Skip to content
This repository was archived by the owner on Dec 8, 2021. It is now read-only.

Commit 3dc8e30

Browse files
authored
feat: add new support for testing with environment variables (#180)
`ScopedEnvironment` is an RAII object that will, upon destruction, restore the previous state of the environment variable it modified. For example: ``` // ${VAR} has some initial state. { ScopedEnvironment env("VAR", "value"); // ${VAR} now holds "value". } // The initial state of ${VAR} has been restored. ```
1 parent bc0d111 commit 3dc8e30

File tree

6 files changed

+164
-1
lines changed

6 files changed

+164
-1
lines changed

google/cloud/testing_util/CMakeLists.txt

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@ if (BUILD_TESTING OR GOOGLE_CLOUD_CPP_TESTING_UTIL_ENABLE_INSTALL)
3232
expect_future_error.h
3333
init_google_mock.cc
3434
init_google_mock.h
35+
scoped_environment.cc
36+
scoped_environment.h
3537
testing_types.cc
3638
testing_types.h)
3739
target_link_libraries(
@@ -41,7 +43,8 @@ if (BUILD_TESTING OR GOOGLE_CLOUD_CPP_TESTING_UTIL_ENABLE_INSTALL)
4143

4244
create_bazel_config(google_cloud_cpp_testing YEAR 2019)
4345

44-
set(google_cloud_cpp_testing_unit_tests assert_ok_test.cc)
46+
set(google_cloud_cpp_testing_unit_tests assert_ok_test.cc
47+
scoped_environment_test.cc)
4548

4649
# Export the list of unit tests so the Bazel BUILD file can pick it up.
4750
export_list_to_bazel("google_cloud_cpp_testing_unit_tests.bzl"

google/cloud/testing_util/google_cloud_cpp_testing.bzl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ google_cloud_cpp_testing_hdrs = [
2525
"expect_exception.h",
2626
"expect_future_error.h",
2727
"init_google_mock.h",
28+
"scoped_environment.h",
2829
"testing_types.h",
2930
]
3031

@@ -34,5 +35,6 @@ google_cloud_cpp_testing_srcs = [
3435
"custom_google_mock_main.cc",
3536
"environment_variable_restore.cc",
3637
"init_google_mock.cc",
38+
"scoped_environment.cc",
3739
"testing_types.cc",
3840
]

google/cloud/testing_util/google_cloud_cpp_testing_unit_tests.bzl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,4 +18,5 @@
1818

1919
google_cloud_cpp_testing_unit_tests = [
2020
"assert_ok_test.cc",
21+
"scoped_environment_test.cc",
2122
]
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
// Copyright 2020 Google LLC
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
#include "google/cloud/testing_util/scoped_environment.h"
16+
#include "google/cloud/internal/getenv.h"
17+
#include "google/cloud/internal/setenv.h"
18+
19+
namespace google {
20+
namespace cloud {
21+
inline namespace GOOGLE_CLOUD_CPP_NS {
22+
namespace testing_util {
23+
24+
ScopedEnvironment::ScopedEnvironment(std::string variable,
25+
optional<std::string> const& value)
26+
: variable_(std::move(variable)),
27+
prev_value_(internal::GetEnv(variable_.c_str())) {
28+
internal::SetEnv(variable_.c_str(), value);
29+
}
30+
31+
ScopedEnvironment::~ScopedEnvironment() {
32+
internal::SetEnv(variable_.c_str(), std::move(prev_value_));
33+
}
34+
35+
} // namespace testing_util
36+
} // namespace GOOGLE_CLOUD_CPP_NS
37+
} // namespace cloud
38+
} // namespace google
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
// Copyright 2020 Google LLC
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
#ifndef GOOGLE_CLOUD_CPP_GOOGLE_CLOUD_TESTING_UTIL_SCOPED_ENVIRONMENT_H
16+
#define GOOGLE_CLOUD_CPP_GOOGLE_CLOUD_TESTING_UTIL_SCOPED_ENVIRONMENT_H
17+
18+
#include "google/cloud/optional.h"
19+
#include "google/cloud/version.h"
20+
#include <string>
21+
22+
namespace google {
23+
namespace cloud {
24+
inline namespace GOOGLE_CLOUD_CPP_NS {
25+
namespace testing_util {
26+
27+
/**
28+
* Helper class to (un)set and restore the value of an environment variable.
29+
*/
30+
class ScopedEnvironment {
31+
public:
32+
/**
33+
* Set the @p variable environment variable to @p value. If @value is
34+
* an unset optional then the variable is unset. The previous value of
35+
* the variable will be restored upon destruction.
36+
*/
37+
ScopedEnvironment(std::string variable, optional<std::string> const& value);
38+
39+
~ScopedEnvironment();
40+
41+
// Movable, but not copyable.
42+
ScopedEnvironment(ScopedEnvironment const&) = delete;
43+
ScopedEnvironment(ScopedEnvironment&&) = default;
44+
ScopedEnvironment& operator=(ScopedEnvironment const&) = delete;
45+
ScopedEnvironment& operator=(ScopedEnvironment&&) = default;
46+
47+
private:
48+
std::string variable_;
49+
optional<std::string> prev_value_;
50+
};
51+
52+
} // namespace testing_util
53+
} // namespace GOOGLE_CLOUD_CPP_NS
54+
} // namespace cloud
55+
} // namespace google
56+
57+
#endif // GOOGLE_CLOUD_CPP_GOOGLE_CLOUD_TESTING_UTIL_SCOPED_ENVIRONMENT_H
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
// Copyright 2020 Google LLC
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
#include "google/cloud/testing_util/scoped_environment.h"
16+
#include "google/cloud/internal/getenv.h"
17+
#include "google/cloud/internal/setenv.h"
18+
#include <gtest/gtest.h>
19+
20+
namespace google {
21+
namespace cloud {
22+
inline namespace GOOGLE_CLOUD_CPP_NS {
23+
namespace testing_util {
24+
namespace {
25+
26+
constexpr auto kVarName = "SCOPED_ENVIRONMENT_TEST";
27+
28+
TEST(ScopedEnvironment, SetOverSet) {
29+
ScopedEnvironment env_outer(kVarName, "foo");
30+
EXPECT_EQ(*internal::GetEnv(kVarName), "foo");
31+
{
32+
ScopedEnvironment env_inner(kVarName, "bar");
33+
EXPECT_EQ(*internal::GetEnv(kVarName), "bar");
34+
}
35+
EXPECT_EQ(*internal::GetEnv(kVarName), "foo");
36+
}
37+
38+
TEST(ScopedEnvironment, SetOverUnset) {
39+
ScopedEnvironment env_outer(kVarName, {});
40+
EXPECT_FALSE(internal::GetEnv(kVarName).has_value());
41+
{
42+
ScopedEnvironment env_inner(kVarName, "bar");
43+
EXPECT_EQ(*internal::GetEnv(kVarName), "bar");
44+
}
45+
EXPECT_FALSE(internal::GetEnv(kVarName).has_value());
46+
}
47+
48+
TEST(ScopedEnvironment, UnsetOverSet) {
49+
ScopedEnvironment env_outer(kVarName, "foo");
50+
EXPECT_EQ(*internal::GetEnv(kVarName), "foo");
51+
{
52+
ScopedEnvironment env_inner(kVarName, {});
53+
EXPECT_FALSE(internal::GetEnv(kVarName).has_value());
54+
}
55+
EXPECT_EQ(*internal::GetEnv(kVarName), "foo");
56+
}
57+
58+
} // namespace
59+
} // namespace testing_util
60+
} // namespace GOOGLE_CLOUD_CPP_NS
61+
} // namespace cloud
62+
} // namespace google

0 commit comments

Comments
 (0)