facter 3.9.6.cfacter.20180612 → 3.11.0.cfacter.20180319
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/ext/facter/facter/CMakeLists.txt +1 -1
- data/ext/facter/facter/acceptance/Gemfile +3 -4
- data/ext/facter/facter/acceptance/Rakefile +342 -2
- data/ext/facter/facter/acceptance/config/aio/options.rb +6 -0
- data/ext/facter/facter/acceptance/config/git/options.rb +5 -1
- data/ext/facter/facter/acceptance/setup/aio/pre-suite/010_Install.rb +22 -0
- data/ext/facter/facter/acceptance/setup/aio/pre-suite/021_InstallAristaModule.rb +12 -0
- data/ext/facter/facter/acceptance/setup/aio/pre-suite/022_Remove_LD_PRELOAD.rb +11 -0
- data/ext/facter/facter/acceptance/setup/common/00_EnvSetup.rb +64 -0
- data/ext/facter/facter/acceptance/setup/common/pre-suite/000-delete-puppet-when-none.rb +11 -0
- data/ext/facter/facter/acceptance/setup/git/pre-suite/01_TestSetup.rb +31 -0
- data/ext/facter/facter/acceptance/tests/ticket_1238_hostname_fqdn.rb +20 -0
- data/ext/facter/facter/lib/CMakeLists.txt +3 -2
- data/ext/facter/facter/lib/Doxyfile +1 -1
- data/ext/facter/facter/lib/inc/facter/facts/fact.hpp +5 -0
- data/ext/facter/facter/lib/inc/internal/facts/aix/networking_resolver.hpp +0 -7
- data/ext/facter/facter/lib/inc/internal/facts/freebsd/networking_resolver.hpp +0 -7
- data/ext/facter/facter/lib/inc/internal/facts/linux/fips_resolver.hpp +31 -0
- data/ext/facter/facter/lib/inc/internal/facts/linux/networking_resolver.hpp +0 -7
- data/ext/facter/facter/lib/inc/internal/facts/openbsd/networking_resolver.hpp +0 -7
- data/ext/facter/facter/lib/inc/internal/facts/osx/networking_resolver.hpp +0 -7
- data/ext/facter/facter/lib/inc/internal/facts/posix/networking_resolver.hpp +0 -7
- data/ext/facter/facter/lib/inc/internal/facts/resolvers/fips_resolver.hpp +46 -0
- data/ext/facter/facter/lib/inc/internal/facts/resolvers/networking_resolver.hpp +2 -3
- data/ext/facter/facter/lib/inc/internal/facts/resolvers/ssh_resolver.hpp +6 -0
- data/ext/facter/facter/lib/inc/internal/facts/solaris/networking_resolver.hpp +0 -7
- data/ext/facter/facter/lib/schema/facter.yaml +38 -18
- data/ext/facter/facter/lib/src/cwrapper.cc +5 -0
- data/ext/facter/facter/lib/src/facts/aix/disk_resolver.cc +2 -11
- data/ext/facter/facter/lib/src/facts/aix/networking_resolver.cc +0 -5
- data/ext/facter/facter/lib/src/facts/freebsd/dmi_resolver.cc +5 -1
- data/ext/facter/facter/lib/src/facts/freebsd/networking_resolver.cc +1 -10
- data/ext/facter/facter/lib/src/facts/freebsd/virtualization_resolver.cc +1 -4
- data/ext/facter/facter/lib/src/facts/linux/collection.cc +2 -0
- data/ext/facter/facter/lib/src/facts/linux/fips_resolver.cc +31 -0
- data/ext/facter/facter/lib/src/facts/linux/networking_resolver.cc +1 -10
- data/ext/facter/facter/lib/src/facts/openbsd/networking_resolver.cc +1 -10
- data/ext/facter/facter/lib/src/facts/osx/networking_resolver.cc +1 -10
- data/ext/facter/facter/lib/src/facts/posix/networking_resolver.cc +2 -3
- data/ext/facter/facter/lib/src/facts/posix/ssh_resolver.cc +3 -2
- data/ext/facter/facter/lib/src/facts/resolvers/fips_resolver.cc +23 -0
- data/ext/facter/facter/lib/src/facts/resolvers/networking_resolver.cc +7 -23
- data/ext/facter/facter/lib/src/facts/resolvers/ssh_resolver.cc +1 -0
- data/ext/facter/facter/lib/src/facts/solaris/networking_resolver.cc +0 -5
- data/ext/facter/facter/lib/tests/facts/resolvers/ssh_resolver.cc +8 -1
- data/ext/facter/facter/lib/tests/facts/schema.cc +17 -0
- data/ext/facter/facter/locales/FACTER.pot +2 -23
- data/ext/facter/leatherman/CHANGELOG.md +16 -9
- data/ext/facter/leatherman/CMakeLists.txt +1 -2
- data/ext/facter/leatherman/appveyor.yml +26 -19
- data/ext/facter/leatherman/catch/CMakeLists.txt +1 -1
- data/ext/facter/leatherman/curl/tests/client_test.cc +396 -398
- data/ext/facter/leatherman/curl/tests/mock_curl.cc +2 -0
- data/ext/facter/leatherman/curl/tests/request_test.cc +66 -68
- data/ext/facter/leatherman/curl/tests/response_test.cc +50 -52
- data/ext/facter/leatherman/dynamic_library/tests/dynamic_library_tests.cc +71 -75
- data/ext/facter/leatherman/execution/src/execution.cc +3 -0
- data/ext/facter/leatherman/execution/src/posix/execution.cc +5 -6
- data/ext/facter/leatherman/execution/src/windows/execution.cc +2 -0
- data/ext/facter/leatherman/execution/tests/windows/execution.cc +4 -2
- data/ext/facter/leatherman/file_util/tests/directory_utils_test.cc +66 -68
- data/ext/facter/leatherman/file_util/tests/file_utils_test.cc +175 -177
- data/ext/facter/leatherman/json_container/inc/leatherman/json_container/json_container.hpp +7 -0
- data/ext/facter/leatherman/json_container/src/json_container.cc +10 -1
- data/ext/facter/leatherman/json_container/tests/json_container_test.cc +152 -8
- data/ext/facter/leatherman/locale/CMakeLists.txt +0 -7
- data/ext/facter/leatherman/locales/leatherman.pot +8 -13
- data/ext/facter/leatherman/logging/src/logging.cc +2 -0
- data/ext/facter/leatherman/util/tests/timer.cc +1 -3
- data/ext/facter/leatherman/vendor/Catch-1.10.0.zip +0 -0
- data/ext/facter/leatherman/vendor/nowide/doc/Doxyfile +4 -4
- data/ext/facter/leatherman/vendor/nowide/doc/LICENSE_1_0.txt +23 -0
- data/ext/facter/leatherman/vendor/nowide/doc/main.txt +62 -54
- data/ext/facter/leatherman/vendor/nowide/include/boost/nowide/convert.hpp +16 -16
- data/ext/facter/leatherman/vendor/nowide/include/boost/nowide/cstdio.hpp +4 -4
- data/ext/facter/leatherman/vendor/nowide/include/boost/nowide/utf8_codecvt.hpp +1 -1
- data/ext/facter/leatherman/vendor/nowide/src/iostream.cpp +32 -30
- data/ext/facter/leatherman/vendor/nowide/standalone/convert +6 -6
- data/ext/facter/leatherman/vendor/nowide/standalone/encoding_utf.hpp +1 -1
- data/ext/facter/leatherman/vendor/nowide/standalone/run_convert_and_build.sh +1 -3
- metadata +15 -6
- data/ext/facter/leatherman/cmake/FindICU.cmake +0 -690
- data/ext/facter/leatherman/scripts/travis_target.sh +0 -79
- data/ext/facter/leatherman/vendor/catch-1.4.0.zip +0 -0
@@ -161,6 +161,7 @@ namespace leatherman { namespace execution {
|
|
161
161
|
// Represents information about a pipe
|
162
162
|
struct pipe
|
163
163
|
{
|
164
|
+
// cppcheck-suppress passedByValue
|
164
165
|
pipe(string pipe_name, scoped_descriptor desc, function<bool(string const&)> cb) :
|
165
166
|
name(move(pipe_name)),
|
166
167
|
descriptor(move(desc)),
|
@@ -169,6 +170,7 @@ namespace leatherman { namespace execution {
|
|
169
170
|
{
|
170
171
|
}
|
171
172
|
|
173
|
+
// cppcheck-suppress passedByValue
|
172
174
|
pipe(string pipe_name, scoped_descriptor desc, string buf) :
|
173
175
|
name(move(pipe_name)),
|
174
176
|
descriptor(move(desc)),
|
@@ -221,8 +223,7 @@ namespace leatherman { namespace execution {
|
|
221
223
|
int result = select(max + 1, &read_set, &write_set, nullptr, timeout ? &read_timeout : nullptr);
|
222
224
|
if (result == -1) {
|
223
225
|
if (errno != EINTR) {
|
224
|
-
|
225
|
-
throw execution_exception(_("child i/o failed."));
|
226
|
+
throw execution_exception(format_error(_("select call failed waiting for child i/o")));
|
226
227
|
}
|
227
228
|
// Interrupted by signal
|
228
229
|
LOG_DEBUG("select call was interrupted and will be retried.");
|
@@ -505,15 +506,13 @@ namespace leatherman { namespace execution {
|
|
505
506
|
struct sigaction sa = {};
|
506
507
|
sa.sa_handler = timer_handler;
|
507
508
|
if (sigaction(SIGALRM, &sa, nullptr) == -1) {
|
508
|
-
|
509
|
-
throw execution_exception(format_error(_("failed to setup timer")));
|
509
|
+
throw execution_exception(format_error(_("sigaction failed while setting up timeout")));
|
510
510
|
}
|
511
511
|
|
512
512
|
itimerval timer = {};
|
513
513
|
timer.it_value.tv_sec = static_cast<decltype(timer.it_interval.tv_sec)>(timeout);
|
514
514
|
if (setitimer(ITIMER_REAL, &timer, nullptr) == -1) {
|
515
|
-
|
516
|
-
throw execution_exception(format_error(_("failed to setup timer")));
|
515
|
+
throw execution_exception(format_error(_("setitimer failed while setting up timeout")));
|
517
516
|
}
|
518
517
|
|
519
518
|
// Set the resource to disable the timer
|
@@ -215,6 +215,7 @@ namespace leatherman { namespace execution {
|
|
215
215
|
// Represents information about a pipe
|
216
216
|
struct pipe
|
217
217
|
{
|
218
|
+
// cppcheck-suppress passedByValue
|
218
219
|
pipe(string pipe_name, scoped_handle pipe_handle, function<bool(string const&)> cb) :
|
219
220
|
name(move(pipe_name)),
|
220
221
|
handle(move(pipe_handle)),
|
@@ -226,6 +227,7 @@ namespace leatherman { namespace execution {
|
|
226
227
|
init();
|
227
228
|
}
|
228
229
|
|
230
|
+
// cppcheck-suppress passedByValue
|
229
231
|
pipe(string pipe_name, scoped_handle pipe_handle, string buf) :
|
230
232
|
name(move(pipe_name)),
|
231
233
|
handle(move(pipe_handle)),
|
@@ -143,8 +143,10 @@ SCENARIO("executing commands with execution::execute") {
|
|
143
143
|
auto exec = execute("cmd.exe", { "/c", CMAKE_BIN_DIRECTORY "/lth_cat.exe", "prefix", "suffix", "overwhelm", "stderr" },
|
144
144
|
"hello\ngoodbye", 0, { execution_options::merge_environment });
|
145
145
|
REQUIRE(exec.success);
|
146
|
-
|
147
|
-
|
146
|
+
auto expected = lth_cat::prefix+lth_cat::overwhelm+"hello\n"+lth_cat::overwhelm+"goodbye\n"+lth_cat::overwhelm+lth_cat::suffix;
|
147
|
+
boost::replace_all(expected, "\n", "\r\n");
|
148
|
+
REQUIRE(exec.output == expected);
|
149
|
+
REQUIRE(exec.error == "hello\r\ngoodbye\r\n");
|
148
150
|
REQUIRE(exec.exit_code == 0);
|
149
151
|
}
|
150
152
|
WHEN("requested to write stdout to file") {
|
@@ -4,86 +4,84 @@
|
|
4
4
|
#include "fixtures.hpp"
|
5
5
|
#include <boost/filesystem.hpp>
|
6
6
|
|
7
|
-
namespace leatherman
|
7
|
+
using namespace leatherman::file_util;
|
8
8
|
|
9
|
-
|
9
|
+
TEST_CASE("file_util::each_file", "[utils]") {
|
10
10
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
11
|
+
temp_directory directory;
|
12
|
+
atomic_write_to_file("1\n", directory.get_dir_name() + "/test1");
|
13
|
+
atomic_write_to_file("2\n", directory.get_dir_name() + "/test2");
|
14
|
+
atomic_write_to_file("3\n", directory.get_dir_name() + "/test3");
|
15
15
|
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
SECTION("can find a file to match a pattern") {
|
29
|
-
std::string content = "N/A";
|
30
|
-
each_file(directory.get_dir_name(), [&content](std::string const &path) {
|
31
|
-
return read(path, content);
|
32
|
-
}, "[0-1]");
|
33
|
-
REQUIRE(content == "1\n");
|
34
|
-
}
|
16
|
+
SECTION("each file should be visited") {
|
17
|
+
std::set<std::string> file_contents;
|
18
|
+
each_file(directory.get_dir_name(), [&file_contents](std::string const &path) {
|
19
|
+
file_contents.insert(read(path));
|
20
|
+
return true;
|
21
|
+
});
|
22
|
+
REQUIRE(file_contents.size() == 3u);
|
23
|
+
REQUIRE(file_contents.find("1\n") != file_contents.end());
|
24
|
+
REQUIRE(file_contents.find("2\n") != file_contents.end());
|
25
|
+
REQUIRE(file_contents.find("3\n") != file_contents.end());
|
26
|
+
}
|
35
27
|
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
}
|
28
|
+
SECTION("can find a file to match a pattern") {
|
29
|
+
std::string content = "N/A";
|
30
|
+
each_file(directory.get_dir_name(), [&content](std::string const &path) {
|
31
|
+
return read(path, content);
|
32
|
+
}, "[0-1]");
|
33
|
+
REQUIRE(content == "1\n");
|
34
|
+
}
|
44
35
|
|
36
|
+
SECTION("only one file returned from false callback"){
|
37
|
+
int count = 0;
|
38
|
+
each_file(directory.get_dir_name(), [&count](std::string const& path){
|
39
|
+
count++;
|
40
|
+
return false;
|
41
|
+
});
|
42
|
+
REQUIRE(count == 1);
|
45
43
|
}
|
46
44
|
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
45
|
+
}
|
46
|
+
|
47
|
+
TEST_CASE("file_util::each_subdirectory", "[utils]") {
|
48
|
+
temp_directory directory;
|
49
|
+
boost::filesystem::create_directory(directory.get_dir_name() + "/test1");
|
50
|
+
atomic_write_to_file("1", directory.get_dir_name() + "/test1/t1");
|
51
|
+
boost::filesystem::create_directory(directory.get_dir_name() + "/test2");
|
52
|
+
atomic_write_to_file("2a", directory.get_dir_name() + "/test2/t2a");
|
53
|
+
atomic_write_to_file("2b", directory.get_dir_name() + "/test2/t2b");
|
54
54
|
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
return true;
|
61
|
-
});
|
55
|
+
SECTION("each subdirectory should be visited") {
|
56
|
+
int counter = 0;
|
57
|
+
each_subdirectory(directory.get_dir_name(), [&counter](std::string const &path) {
|
58
|
+
each_file(path, [&counter](std::string const &file) {
|
59
|
+
counter++;
|
62
60
|
return true;
|
63
61
|
});
|
64
|
-
|
65
|
-
}
|
62
|
+
return true;
|
63
|
+
});
|
64
|
+
REQUIRE(counter == 3);
|
65
|
+
}
|
66
66
|
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
return true;
|
73
|
-
});
|
67
|
+
SECTION("can find directories that match a pattern") {
|
68
|
+
int counter = 0;
|
69
|
+
each_subdirectory(directory.get_dir_name(), [&counter](std::string const &path) {
|
70
|
+
each_file(path, [&counter](std::string const &file) {
|
71
|
+
counter++;
|
74
72
|
return true;
|
75
|
-
}, "[2-3]");
|
76
|
-
REQUIRE(counter == 2);
|
77
|
-
}
|
78
|
-
|
79
|
-
SECTION("only one directory found from false callback"){
|
80
|
-
int count = 0;
|
81
|
-
each_subdirectory(directory.get_dir_name(), [&count](std::string const& path){
|
82
|
-
count++;
|
83
|
-
return false;
|
84
73
|
});
|
85
|
-
|
86
|
-
}
|
74
|
+
return true;
|
75
|
+
}, "[2-3]");
|
76
|
+
REQUIRE(counter == 2);
|
87
77
|
}
|
88
78
|
|
89
|
-
|
79
|
+
SECTION("only one directory found from false callback"){
|
80
|
+
int count = 0;
|
81
|
+
each_subdirectory(directory.get_dir_name(), [&count](std::string const& path){
|
82
|
+
count++;
|
83
|
+
return false;
|
84
|
+
});
|
85
|
+
REQUIRE(count == 1);
|
86
|
+
}
|
87
|
+
}
|
@@ -7,191 +7,189 @@
|
|
7
7
|
#include <windows.h>
|
8
8
|
#endif
|
9
9
|
|
10
|
-
namespace leatherman
|
10
|
+
using namespace leatherman::file_util;
|
11
11
|
|
12
|
-
|
12
|
+
TEST_CASE("file_util::tilde_expand", "[utils]") {
|
13
13
|
|
14
14
|
#ifdef _WIN32
|
15
|
-
|
15
|
+
_putenv("USERPROFILE=/testhome");
|
16
16
|
#else
|
17
|
-
|
17
|
+
setenv("HOME", "/testhome", 1);
|
18
18
|
#endif
|
19
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
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
20
|
+
SECTION("empty path should be empty") {
|
21
|
+
REQUIRE(tilde_expand("") == "");
|
22
|
+
}
|
23
|
+
|
24
|
+
SECTION("spaces should be preserved") {
|
25
|
+
REQUIRE(tilde_expand("i like spaces") == "i like spaces");
|
26
|
+
}
|
27
|
+
|
28
|
+
SECTION("should expand using environment variable") {
|
29
|
+
CHECK(tilde_expand("~") == "/testhome");
|
30
|
+
CHECK(tilde_expand("~/") == "/testhome/");
|
31
|
+
CHECK(tilde_expand("~/foo") == "/testhome/foo");
|
32
|
+
}
|
33
|
+
|
34
|
+
SECTION("only a ~ at the start") {
|
35
|
+
REQUIRE(tilde_expand("/foo/bar~") == "/foo/bar~");
|
36
|
+
}
|
37
|
+
|
38
|
+
SECTION("~baz/foo does not expand") {
|
39
|
+
REQUIRE(tilde_expand("~baz/foo") == "~baz/foo");
|
40
|
+
}
|
41
|
+
|
42
|
+
SECTION("it should expand the home directory path") {
|
43
|
+
REQUIRE(tilde_expand("~/foo") != "~/foo");
|
44
|
+
}
|
45
|
+
|
46
|
+
SECTION("it should not expand the working directory path") {
|
47
|
+
REQUIRE(tilde_expand("./foo") == "./foo");
|
48
|
+
}
|
49
|
+
|
50
|
+
auto home_path = get_home_path();
|
51
|
+
|
52
|
+
SECTION("it should expand ~ to the HOME env var") {
|
53
|
+
REQUIRE(tilde_expand("~") == home_path);
|
54
|
+
}
|
55
|
+
|
56
|
+
SECTION("it should expand ~ as the base directory") {
|
57
|
+
std::string expected_path{home_path + "/spam"};
|
58
|
+
std::string expanded_path{tilde_expand("~/spam")};
|
59
|
+
REQUIRE(expanded_path == expected_path);
|
60
|
+
}
|
61
|
+
}
|
62
|
+
|
63
|
+
TEST_CASE("shell_quote", "[utils]") {
|
64
|
+
SECTION("empty string") {
|
65
|
+
REQUIRE(shell_quote("") == "\"\"");
|
66
|
+
}
|
67
|
+
|
68
|
+
SECTION("single word") {
|
69
|
+
REQUIRE(shell_quote("plain") == "\"plain\"");
|
70
|
+
}
|
71
|
+
|
72
|
+
SECTION("words separated by space") {
|
73
|
+
REQUIRE(shell_quote("a space") == "\"a space\"");
|
74
|
+
}
|
75
|
+
|
76
|
+
SECTION("exclamation mark") {
|
77
|
+
REQUIRE(shell_quote("!csh") == "\"!csh\"");
|
78
|
+
}
|
79
|
+
|
80
|
+
SECTION("single quote before expression") {
|
81
|
+
REQUIRE(shell_quote("'open quote") == "\"'open quote\"");
|
82
|
+
}
|
83
|
+
|
84
|
+
SECTION("single quote after expression") {
|
85
|
+
REQUIRE(shell_quote("close quote'") == "\"close quote'\"");
|
86
|
+
}
|
87
|
+
|
88
|
+
SECTION("double quote before expression") {
|
89
|
+
REQUIRE(shell_quote("\"open doublequote")
|
90
|
+
== "\"\\\"open doublequote\"");
|
91
|
+
}
|
92
|
+
|
93
|
+
SECTION("double quote after expression") {
|
94
|
+
REQUIRE(shell_quote("close doublequote\"")
|
95
|
+
== "\"close doublequote\\\"\"");
|
96
|
+
}
|
97
|
+
}
|
98
|
+
|
99
|
+
TEST_CASE("lth_file::file_readable", "[utils]") {
|
100
|
+
SECTION("it can check that a file does not exist") {
|
101
|
+
auto file_path = unique_fixture_path().string();
|
102
|
+
CAPTURE(file_path);
|
103
|
+
REQUIRE_FALSE(file_readable(file_path));
|
104
|
+
}
|
105
|
+
|
106
|
+
SECTION("directories are not readable") {
|
107
|
+
temp_directory dir_path;
|
108
|
+
REQUIRE_FALSE(file_readable(dir_path.get_dir_name()));
|
109
|
+
}
|
110
|
+
}
|
111
|
+
|
112
|
+
TEST_CASE("lth_file::atomic_write_to_file", "[utils]") {
|
113
|
+
SECTION("it can write to a regular file, ensure it exists, and delete it") {
|
114
|
+
auto file_path = unique_fixture_path().string();
|
115
|
+
REQUIRE_FALSE(file_readable(file_path));
|
116
|
+
atomic_write_to_file("test\n", file_path);
|
117
|
+
REQUIRE(file_readable(file_path));
|
118
|
+
boost::filesystem::remove(file_path);
|
119
|
+
REQUIRE_FALSE(file_readable(file_path));
|
120
|
+
}
|
121
|
+
|
122
|
+
SECTION("can write to an existing file") {
|
123
|
+
temp_file file("existing file");
|
124
|
+
REQUIRE(file_readable(file.get_file_name()));
|
125
|
+
atomic_write_to_file("test", file.get_file_name());
|
126
|
+
REQUIRE(file_readable(file.get_file_name()));
|
127
|
+
REQUIRE(read(file.get_file_name()) == "test");
|
128
|
+
}
|
129
129
|
|
130
130
|
#ifndef _WIN32
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
131
|
+
SECTION("can write a file with permissions") {
|
132
|
+
auto file_path = unique_fixture_path().string();
|
133
|
+
REQUIRE_FALSE(file_readable(file_path));
|
134
|
+
auto perms = boost::filesystem::owner_read | boost::filesystem::owner_write;
|
135
|
+
atomic_write_to_file("test\n", file_path, perms, std::ios::binary);
|
136
|
+
REQUIRE(file_readable(file_path));
|
137
|
+
auto stat = boost::filesystem::status(file_path);
|
138
|
+
REQUIRE(stat.permissions() == perms);
|
139
|
+
boost::filesystem::remove(file_path);
|
140
|
+
REQUIRE_FALSE(file_readable(file_path));
|
141
|
+
}
|
142
142
|
#endif
|
143
|
+
}
|
144
|
+
|
145
|
+
TEST_CASE("file_util::read", "[utils]") {
|
146
|
+
|
147
|
+
SECTION("trying to read a nonexistent file returns the empty string"){
|
148
|
+
std::string contents;
|
149
|
+
REQUIRE(read("does_not_exist") == "");
|
150
|
+
REQUIRE_FALSE(read("does_not_exist", contents));
|
151
|
+
REQUIRE(contents.empty());
|
152
|
+
}
|
153
|
+
|
154
|
+
SECTION("it can read from a file") {
|
155
|
+
auto file_path = unique_fixture_path().string();
|
156
|
+
atomic_write_to_file("test\n", file_path);
|
157
|
+
REQUIRE(file_readable(file_path));
|
158
|
+
std::string contents;
|
159
|
+
REQUIRE(read(file_path, contents));
|
160
|
+
REQUIRE(contents == "test\n");
|
161
|
+
REQUIRE(read(file_path) == "test\n");
|
162
|
+
boost::filesystem::remove(file_path);
|
143
163
|
}
|
164
|
+
}
|
144
165
|
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
SECTION("an action is performed on each line of a file") {
|
176
|
-
temp_file file("test1\ntest2\ntest3\n");
|
177
|
-
int i = 0;
|
178
|
-
REQUIRE(each_line(file.get_file_name(), [&i](std::string const &line) {
|
179
|
-
i++;
|
180
|
-
return line == ("test" + std::to_string(i));
|
181
|
-
}));
|
182
|
-
REQUIRE(i == 3);
|
183
|
-
}
|
184
|
-
|
185
|
-
SECTION("a callback that returns false stops at the first line"){
|
186
|
-
temp_file file("test1\ntest2\ntest3\n");
|
187
|
-
std::vector<std::string> lines;
|
188
|
-
REQUIRE(each_line(file.get_file_name(), [&](std::string& line) {
|
189
|
-
lines.emplace_back(move(line));
|
190
|
-
return false;
|
191
|
-
}));
|
192
|
-
REQUIRE(lines.size() == 1u);
|
193
|
-
REQUIRE(lines[0] == "test1");
|
194
|
-
}
|
195
|
-
}
|
196
|
-
|
197
|
-
}} // namespace leatherman::file_util
|
166
|
+
TEST_CASE("file_util::each_line", "[utils]") {
|
167
|
+
|
168
|
+
SECTION("trying to read a nonexistent file returns false") {
|
169
|
+
REQUIRE_FALSE(each_line("does_not_exist", [](std::string &line) {
|
170
|
+
FAIL("should not be called");
|
171
|
+
return true;
|
172
|
+
}));
|
173
|
+
}
|
174
|
+
|
175
|
+
SECTION("an action is performed on each line of a file") {
|
176
|
+
temp_file file("test1\ntest2\ntest3\n");
|
177
|
+
int i = 0;
|
178
|
+
REQUIRE(each_line(file.get_file_name(), [&i](std::string const &line) {
|
179
|
+
i++;
|
180
|
+
return line == ("test" + std::to_string(i));
|
181
|
+
}));
|
182
|
+
REQUIRE(i == 3);
|
183
|
+
}
|
184
|
+
|
185
|
+
SECTION("a callback that returns false stops at the first line"){
|
186
|
+
temp_file file("test1\ntest2\ntest3\n");
|
187
|
+
std::vector<std::string> lines;
|
188
|
+
REQUIRE(each_line(file.get_file_name(), [&](std::string& line) {
|
189
|
+
lines.emplace_back(move(line));
|
190
|
+
return false;
|
191
|
+
}));
|
192
|
+
REQUIRE(lines.size() == 1u);
|
193
|
+
REQUIRE(lines[0] == "test1");
|
194
|
+
}
|
195
|
+
}
|