-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmain.cpp
114 lines (87 loc) · 2.42 KB
/
main.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
#include "safe_env/safe_env.hpp"
#undef NDEBUG
#include <atomic>
#include <cassert>
#include <chrono>
#include <future>
#include <thread>
// NOLINTNEXTLINE (google-build-using-namespace)
using namespace burda;
namespace
{
void test_exceptions()
{
const auto execute_and_expect_exception = [&](auto&& function, auto... args)
{
try
{
function(args...);
}
catch (const std::invalid_argument& error)
{
assert(std::string{error.what()} == "Environment variable name is empty");
}
catch (...)
{
// we expect std::invalid_argument
assert(false);
}
};
execute_and_expect_exception(env::getenv, "");
execute_and_expect_exception(env::setenv, "", "value", true);
execute_and_expect_exception(env::unsetenv, "");
}
void test_single_threaded()
{
assert(env::getenv("foo").empty());
env::setenv("foo", "value", true);
assert(env::getenv("foo") == "value");
env::setenv("foo", "value2", false);
assert(env::getenv("foo") == "value");
env::setenv("foo", "value2", true);
assert(env::getenv("foo") == "value2");
env::unsetenv("foo");
assert(env::getenv("foo").empty());
}
void test_multi_threaded()
{
const auto duration = std::chrono::seconds{30};
std::atomic_bool run { true };
const auto runner = [&](const auto function)
{
std::size_t iterations = 0;
while(run)
{
function();
++iterations;
std::this_thread::yield();
}
return iterations;
};
auto setter = std::async(std::launch::async, [&](){ return runner([&]()
{
env::setenv("key", "value", true);
});});
auto reader = std::async(std::launch::async, [&](){ return runner([&]()
{
const std::string value = env::getenv("key");
assert(value.empty() || value == "value");
});});
auto deleter = std::async(std::launch::async, [&](){ return runner([&]()
{
env::unsetenv("key");
});});
std::this_thread::sleep_for(duration);
run = false;
assert(setter.get() > 0);
assert(reader.get() > 0);
assert(deleter.get() > 0);
}
} // namespace
// NOLINTNEXTLINE(bugprone-exception-escape)
int main([[maybe_unused]] const int argc, [[maybe_unused]] const char** argv)
{
test_exceptions();
test_single_threaded();
test_multi_threaded();
}