Bitcoin Core  22.99.0
P2P Digital Currency
fs_tests.cpp
Go to the documentation of this file.
1 // Copyright (c) 2011-2021 The Bitcoin Core developers
2 // Distributed under the MIT software license, see the accompanying
3 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
4 //
5 #include <fs.h>
7 #include <util/system.h>
8 #include <util/getuniquepath.h>
9 
10 #include <boost/test/unit_test.hpp>
11 
12 #include <fstream>
13 #include <ios>
14 #include <string>
15 
17 
18 BOOST_AUTO_TEST_CASE(fsbridge_pathtostring)
19 {
20  std::string u8_str = "fs_tests_₿_🏃";
22  BOOST_CHECK_EQUAL(fs::u8path(u8_str).u8string(), u8_str);
23  BOOST_CHECK_EQUAL(fs::PathFromString(u8_str).u8string(), u8_str);
24  BOOST_CHECK_EQUAL(fs::PathToString(fs::u8path(u8_str)), u8_str);
25 #ifndef WIN32
26  // On non-windows systems, verify that arbitrary byte strings containing
27  // invalid UTF-8 can be round tripped successfully with PathToString and
28  // PathFromString. On non-windows systems, paths are just byte strings so
29  // these functions do not do any encoding. On windows, paths are Unicode,
30  // and these functions do encoding and decoding, so the behavior of this
31  // test would be undefined.
32  std::string invalid_u8_str = "\xf0";
33  BOOST_CHECK_EQUAL(invalid_u8_str.size(), 1);
34  BOOST_CHECK_EQUAL(fs::PathToString(fs::PathFromString(invalid_u8_str)), invalid_u8_str);
35 #endif
36 }
37 
38 BOOST_AUTO_TEST_CASE(fsbridge_stem)
39 {
40  std::string test_filename = "fs_tests_₿_🏃.dat";
41  std::string expected_stem = "fs_tests_₿_🏃";
42  BOOST_CHECK_EQUAL(fs::PathToString(fs::PathFromString(test_filename).stem()), expected_stem);
43 }
44 
45 BOOST_AUTO_TEST_CASE(fsbridge_fstream)
46 {
47  fs::path tmpfolder = m_args.GetDataDirBase();
48  // tmpfile1 should be the same as tmpfile2
49  fs::path tmpfile1 = tmpfolder / "fs_tests_₿_🏃";
50  fs::path tmpfile2 = tmpfolder / "fs_tests_₿_🏃";
51  {
52  std::ofstream file{tmpfile1};
53  file << "bitcoin";
54  }
55  {
56  std::ifstream file{tmpfile2};
57  std::string input_buffer;
58  file >> input_buffer;
59  BOOST_CHECK_EQUAL(input_buffer, "bitcoin");
60  }
61  {
62  std::ifstream file{tmpfile1, std::ios_base::in | std::ios_base::ate};
63  std::string input_buffer;
64  file >> input_buffer;
65  BOOST_CHECK_EQUAL(input_buffer, "");
66  }
67  {
68  std::ofstream file{tmpfile2, std::ios_base::out | std::ios_base::app};
69  file << "tests";
70  }
71  {
72  std::ifstream file{tmpfile1};
73  std::string input_buffer;
74  file >> input_buffer;
75  BOOST_CHECK_EQUAL(input_buffer, "bitcointests");
76  }
77  {
78  std::ofstream file{tmpfile2, std::ios_base::out | std::ios_base::trunc};
79  file << "bitcoin";
80  }
81  {
82  std::ifstream file{tmpfile1};
83  std::string input_buffer;
84  file >> input_buffer;
85  BOOST_CHECK_EQUAL(input_buffer, "bitcoin");
86  }
87  {
88  // Join an absolute path and a relative path.
89  fs::path p = fsbridge::AbsPathJoin(tmpfolder, "fs_tests_₿_🏃");
90  BOOST_CHECK(p.is_absolute());
91  BOOST_CHECK_EQUAL(tmpfile1, p);
92  }
93  {
94  // Join two absolute paths.
95  fs::path p = fsbridge::AbsPathJoin(tmpfile1, tmpfile2);
96  BOOST_CHECK(p.is_absolute());
97  BOOST_CHECK_EQUAL(tmpfile2, p);
98  }
99  {
100  // Ensure joining with empty paths does not add trailing path components.
101  BOOST_CHECK_EQUAL(tmpfile1, fsbridge::AbsPathJoin(tmpfile1, ""));
102  BOOST_CHECK_EQUAL(tmpfile1, fsbridge::AbsPathJoin(tmpfile1, {}));
103  }
104  {
105  fs::path p1 = GetUniquePath(tmpfolder);
106  fs::path p2 = GetUniquePath(tmpfolder);
107  fs::path p3 = GetUniquePath(tmpfolder);
108 
109  // Ensure that the parent path is always the same.
110  BOOST_CHECK_EQUAL(tmpfolder, p1.parent_path());
111  BOOST_CHECK_EQUAL(tmpfolder, p2.parent_path());
112  BOOST_CHECK_EQUAL(tmpfolder, p3.parent_path());
113 
114  // Ensure that generated paths are actually different.
115  BOOST_CHECK(p1 != p2);
116  BOOST_CHECK(p2 != p3);
117  BOOST_CHECK(p1 != p3);
118  }
119 }
120 
122 {
123  const fs::path tmpfolder{m_args.GetDataDirBase()};
124 
125  const fs::path path1{GetUniquePath(tmpfolder)};
126  const fs::path path2{GetUniquePath(tmpfolder)};
127 
128  const std::string path1_contents{"1111"};
129  const std::string path2_contents{"2222"};
130 
131  {
132  std::ofstream file{path1};
133  file << path1_contents;
134  }
135 
136  {
137  std::ofstream file{path2};
138  file << path2_contents;
139  }
140 
141  // Rename path1 -> path2.
142  BOOST_CHECK(RenameOver(path1, path2));
143 
144  BOOST_CHECK(!fs::exists(path1));
145 
146  {
147  std::ifstream file{path2};
148  std::string contents;
149  file >> contents;
150  BOOST_CHECK_EQUAL(contents, path1_contents);
151  }
152  fs::remove(path2);
153 }
154 
155 #ifndef WIN32
157 {
158  // Test fs::create_directories workaround.
159  const fs::path tmpfolder{m_args.GetDataDirBase()};
160 
161  const fs::path dir{GetUniquePath(tmpfolder)};
162  fs::create_directory(dir);
163  BOOST_CHECK(fs::exists(dir));
164  BOOST_CHECK(fs::is_directory(dir));
166 
167  const fs::path symlink{GetUniquePath(tmpfolder)};
168  fs::create_directory_symlink(dir, symlink);
169  BOOST_CHECK(fs::exists(symlink));
170  BOOST_CHECK(fs::is_symlink(symlink));
171  BOOST_CHECK(fs::is_directory(symlink));
173 
174  fs::remove(symlink);
175  fs::remove(dir);
176 }
177 #endif // WIN32
178 
fs::exists
static bool exists(const path &p)
Definition: fs.h:69
fs.h
setup_common.h
fsbridge::AbsPathJoin
fs::path AbsPathJoin(const fs::path &base, const fs::path &path)
Helper function for joining two paths.
Definition: fs.cpp:37
fs::PathToString
static std::string PathToString(const path &path)
Convert path object to a byte string.
Definition: fs.h:112
BOOST_FIXTURE_TEST_SUITE
#define BOOST_FIXTURE_TEST_SUITE(a, b)
Definition: object.cpp:14
BOOST_AUTO_TEST_SUITE_END
BOOST_AUTO_TEST_SUITE_END()
RenameOver
bool RenameOver(fs::path src, fs::path dest)
Rename src to dest.
Definition: system.cpp:1063
BOOST_AUTO_TEST_CASE
BOOST_AUTO_TEST_CASE(fsbridge_pathtostring)
Definition: fs_tests.cpp:18
fs::path
Path class wrapper to block calls to the fs::path(std::string) implicit constructor and the fs::path:...
Definition: fs.h:29
BasicTestingSetup
Basic testing setup.
Definition: setup_common.h:83
fs::PathFromString
static path PathFromString(const std::string &string)
Convert byte string to path object.
Definition: fs.h:135
system.h
fs::create_directories
static bool create_directories(const std::filesystem::path &p)
Create directory (and if necessary its parents), unless the leaf directory already exists or is a sym...
Definition: fs.h:150
getuniquepath.h
GetUniquePath
fs::path GetUniquePath(const fs::path &base)
Helper function for getting a unique path.
Definition: getuniquepath.cpp:9
BOOST_CHECK
#define BOOST_CHECK(expr)
Definition: object.cpp:17
BOOST_CHECK_EQUAL
#define BOOST_CHECK_EQUAL(v1, v2)
Definition: object.cpp:18