proxygen
EnvUtilTest.cpp
Go to the documentation of this file.
1 /*
2  * Copyright 2017-present Facebook, Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
18 
19 #include <boost/algorithm/string.hpp>
20 #include <folly/Memory.h>
21 #include <folly/Subprocess.h>
25 #include <glog/logging.h>
26 #include <spawn.h>
27 #include <system_error>
28 
29 using namespace folly;
33 
35  env_util_subprocess_binary,
36  "./env_util_subprocess",
37  "Location of the `env_util_subprocess` test helper program");
38 
39 TEST(EnvVarSaverTest, ExampleNew) {
40  auto key = "hahahahaha";
41  EXPECT_EQ(nullptr, getenv(key));
42 
43  PCHECK(0 == setenv(key, "", true));
44  EXPECT_STREQ("", getenv(key));
45  PCHECK(0 == unsetenv(key));
46  EXPECT_EQ(nullptr, getenv(key));
47 
48  auto saver = std::make_unique<EnvVarSaver>();
49  PCHECK(0 == setenv(key, "blah", true));
50  EXPECT_STREQ("blah", getenv(key));
51  saver = nullptr;
52  EXPECT_EQ(nullptr, getenv(key));
53 }
54 
55 TEST(EnvVarSaverTest, ExampleExisting) {
56  auto key = "PATH";
57  EXPECT_NE(nullptr, getenv(key));
58  auto value = std::string{getenv(key)};
59 
60  auto saver = std::make_unique<EnvVarSaver>();
61  PCHECK(0 == setenv(key, "blah", true));
62  EXPECT_STREQ("blah", getenv(key));
63  saver = nullptr;
64  EXPECT_EQ(value, getenv(key));
65 }
66 
67 TEST(EnvVarSaverTest, Movable) {
68  Optional<EnvVarSaver> pSaver1;
69  pSaver1.emplace();
70  auto key = "PATH";
71  EXPECT_NE(nullptr, getenv(key));
72  auto value = std::string{getenv(key)};
73  Optional<EnvVarSaver> pSaver2;
74  pSaver2.emplace(std::move(*pSaver1));
75  pSaver1.clear();
76  PCHECK(0 == setenv(key, "blah", true));
77  EXPECT_STREQ("blah", getenv(key));
78  pSaver2.clear();
79  EXPECT_EQ(value, getenv(key));
80 }
81 
82 TEST(EnvironmentStateTest, FailOnEmptyString) {
83  EnvVarSaver saver{};
84  char test[4] = "A=B";
85  PCHECK(0 == putenv(test));
86  auto okState = EnvironmentState::fromCurrentEnvironment();
87  test[0] = 0;
89  EnvironmentState::fromCurrentEnvironment(), MalformedEnvironment);
90 }
91 
92 TEST(EnvironmentStateTest, MovableAndCopyable) {
93  auto initialState = EnvironmentState::fromCurrentEnvironment();
94  auto copiedState1 = EnvironmentState::empty();
95  copiedState1.operator=(initialState);
96  EnvironmentState copiedState2{initialState};
97  EXPECT_EQ(*initialState, *copiedState1);
98  EXPECT_EQ(*initialState, *copiedState2);
99  (*initialState)["foo"] = "bar";
100  EXPECT_EQ(0, copiedState1->count("foo"));
101  EXPECT_EQ(0, copiedState2->count("foo"));
102  auto movedState1 = EnvironmentState::empty();
103  movedState1.operator=(std::move(copiedState1));
104  EnvironmentState movedState2{std::move(copiedState2)};
105  EXPECT_EQ(0, movedState1->count("foo"));
106  EXPECT_EQ(0, movedState2->count("foo"));
107  initialState->erase("foo");
108  EXPECT_EQ(*initialState, *movedState1);
109  EXPECT_EQ(*initialState, *movedState2);
110 }
111 
112 TEST(EnvironmentStateTest, FailOnDuplicate) {
113  EnvVarSaver saver{};
114  char test[7] = "PATG=B";
115  PCHECK(0 == putenv(test));
116  auto okState = EnvironmentState::fromCurrentEnvironment();
117  test[3] = 'H';
118  EXPECT_THROW(
119  EnvironmentState::fromCurrentEnvironment(), MalformedEnvironment);
120 }
121 
122 TEST(EnvironmentStateTest, Separation) {
123  EnvVarSaver saver{};
124  auto initialState = EnvironmentState::fromCurrentEnvironment();
125  PCHECK(0 == setenv("spork", "foon", true));
126  auto updatedState = EnvironmentState::fromCurrentEnvironment();
127  EXPECT_EQ(0, initialState->count("spork"));
128  EXPECT_EQ(1, updatedState->count("spork"));
129  EXPECT_EQ("foon", (*updatedState)["spork"]);
130  updatedState->erase("spork");
131  EXPECT_EQ(0, updatedState->count("spork"));
132  EXPECT_STREQ("foon", getenv("spork"));
133 }
134 
135 TEST(EnvironmentStateTest, Update) {
136  EnvVarSaver saver{};
137  auto env = EnvironmentState::fromCurrentEnvironment();
138  EXPECT_EQ(nullptr, getenv("spork"));
139  (*env)["spork"] = "foon";
140  EXPECT_EQ(nullptr, getenv("spork"));
141  env.setAsCurrentEnvironment();
142  EXPECT_STREQ("foon", getenv("spork"));
143 }
144 
145 TEST(EnvironmentStateTest, forSubprocess) {
146  auto env = EnvironmentState::empty();
147  (*env)["spork"] = "foon";
148  std::vector<std::string> expected = {"spork=foon"};
149  auto vec = env.toVector();
150  EXPECT_EQ(expected, vec);
151  Subprocess subProcess{{fLS::FLAGS_env_util_subprocess_binary},
152  {},
153  fLS::FLAGS_env_util_subprocess_binary.c_str(),
154  &vec};
155  EXPECT_EQ(0, subProcess.wait().exitStatus());
156 }
157 
158 TEST(EnvironmentStateTest, forC) {
159  auto env = EnvironmentState::empty();
160  (*env)["spork"] = "foon";
161  EXPECT_STREQ("spork=foon", env.toPointerArray().get()[0]);
162  EXPECT_EQ(nullptr, env.toPointerArray().get()[1]);
163  char const* program = fLS::FLAGS_env_util_subprocess_binary.c_str();
164  pid_t pid;
165  PCHECK(
166  0 ==
167  posix_spawn(
168  &pid,
169  program,
170  nullptr,
171  nullptr,
172  nullptr,
173  env.toPointerArray().get()));
174  int result;
175  PCHECK(pid == waitpid(pid, &result, 0));
176  EXPECT_EQ(0, result);
177 }
178 
179 TEST(EnvVarSaverTest, ExampleDeleting) {
180  auto key = "PATH";
181  EXPECT_NE(nullptr, getenv(key));
182  auto value = std::string{getenv(key)};
183 
184  auto saver = std::make_unique<EnvVarSaver>();
185  PCHECK(0 == unsetenv(key));
186  EXPECT_EQ(nullptr, getenv(key));
187  saver = nullptr;
188  EXPECT_TRUE(value == getenv(key));
189 }
#define EXPECT_THROW(statement, expected_exception)
Definition: gtest.h:1843
#define EXPECT_EQ(val1, val2)
Definition: gtest.h:1922
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
—— Concurrent Priority Queue Implementation ——
Definition: AtomicBitSet.h:29
#define EXPECT_STREQ(s1, s2)
Definition: gtest.h:1995
constexpr auto empty(C const &c) -> decltype(c.empty())
Definition: Access.h:55
Definition: Traits.h:588
Value & emplace(Args &&...args)
Definition: Optional.h:231
DEFINE_string(env_util_subprocess_binary,"./env_util_subprocess","Location of the `env_util_subprocess` test helper program")
#define EXPECT_TRUE(condition)
Definition: gtest.h:1859
const char * string
Definition: Conv.cpp:212
#define EXPECT_NE(val1, val2)
Definition: gtest.h:1926
uint64_t value(const typename LockFreeRingBuffer< T, Atom >::Cursor &rbcursor)
TEST(SequencedExecutor, CPUThreadPoolExecutor)
void clear() noexcept
Definition: Optional.h:251