Bitcoin Core  31.0.0
P2P Digital Currency
fs_tests.cpp
Go to the documentation of this file.
1 // Copyright (c) 2011-present 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 //
6 #include <util/fs.h>
7 #include <util/fs_helpers.h>
8 
9 #include <boost/test/unit_test.hpp>
10 
11 #include <fstream>
12 #include <ios>
13 #include <string>
14 
16 
17 BOOST_AUTO_TEST_CASE(fsbridge_pathtostring)
18 {
19  std::string u8_str = "fs_tests_₿_🏃";
20  std::u8string str8{u8"fs_tests_₿_🏃"};
22  BOOST_CHECK_EQUAL(fs::u8path(u8_str).utf8string(), u8_str);
23  BOOST_CHECK_EQUAL(fs::path(str8).utf8string(), u8_str);
24  BOOST_CHECK(fs::path(str8).u8string() == str8);
25  BOOST_CHECK_EQUAL(fs::PathFromString(u8_str).utf8string(), u8_str);
27 #ifndef WIN32
28  // On non-windows systems, verify that arbitrary byte strings containing
29  // invalid UTF-8 can be round tripped successfully with PathToString and
30  // PathFromString. On non-windows systems, paths are just byte strings so
31  // these functions do not do any encoding. On windows, paths are Unicode,
32  // and these functions do encoding and decoding, so the behavior of this
33  // test would be undefined.
34  std::string invalid_u8_str = "\xf0";
35  BOOST_CHECK_EQUAL(invalid_u8_str.size(), 1);
36  BOOST_CHECK_EQUAL(fs::PathToString(fs::PathFromString(invalid_u8_str)), invalid_u8_str);
37 #endif
38 }
39 
40 BOOST_AUTO_TEST_CASE(fsbridge_stem)
41 {
42  std::string test_filename = "fs_tests_₿_🏃.dat";
43  std::string expected_stem = "fs_tests_₿_🏃";
44  BOOST_CHECK_EQUAL(fs::PathToString(fs::PathFromString(test_filename).stem()), expected_stem);
45 }
46 
47 BOOST_AUTO_TEST_CASE(fsbridge_fstream)
48 {
49  fs::path tmpfolder = m_args.GetDataDirBase();
50  // tmpfile1 should be the same as tmpfile2
51  fs::path tmpfile1 = tmpfolder / fs::u8path("fs_tests_₿_🏃");
52  fs::path tmpfile2 = tmpfolder / fs::path(u8"fs_tests_₿_🏃");
53  {
54  std::ofstream file{tmpfile1.std_path()};
55  file << "bitcoin";
56  }
57  {
58  std::ifstream file{tmpfile2.std_path()};
59  std::string input_buffer;
60  file >> input_buffer;
61  BOOST_CHECK_EQUAL(input_buffer, "bitcoin");
62  }
63  {
64  std::ifstream file{tmpfile1.std_path(), std::ios_base::in | std::ios_base::ate};
65  std::string input_buffer;
66  file >> input_buffer;
67  BOOST_CHECK_EQUAL(input_buffer, "");
68  }
69  {
70  std::ofstream file{tmpfile2.std_path(), std::ios_base::out | std::ios_base::app};
71  file << "tests";
72  }
73  {
74  std::ifstream file{tmpfile1.std_path()};
75  std::string input_buffer;
76  file >> input_buffer;
77  BOOST_CHECK_EQUAL(input_buffer, "bitcointests");
78  }
79  {
80  std::ofstream file{tmpfile2.std_path(), std::ios_base::out | std::ios_base::trunc};
81  file << "bitcoin";
82  }
83  {
84  std::ifstream file{tmpfile1.std_path()};
85  std::string input_buffer;
86  file >> input_buffer;
87  BOOST_CHECK_EQUAL(input_buffer, "bitcoin");
88  }
89  {
90  // Join an absolute path and a relative path.
91  fs::path p = fsbridge::AbsPathJoin(tmpfolder, fs::u8path("fs_tests_₿_🏃"));
92  BOOST_CHECK(p.is_absolute());
93  BOOST_CHECK_EQUAL(tmpfile1, p);
94  }
95  {
96  // Join two absolute paths.
97  fs::path p = fsbridge::AbsPathJoin(tmpfile1, tmpfile2);
98  BOOST_CHECK(p.is_absolute());
99  BOOST_CHECK_EQUAL(tmpfile2, p);
100  }
101  {
102  // Ensure joining with empty paths does not add trailing path components.
103  BOOST_CHECK_EQUAL(tmpfile1, fsbridge::AbsPathJoin(tmpfile1, ""));
104  BOOST_CHECK_EQUAL(tmpfile1, fsbridge::AbsPathJoin(tmpfile1, {}));
105  }
106 }
107 
109 {
110  const fs::path tmpfolder{m_args.GetDataDirBase()};
111 
112  const fs::path path1{tmpfolder / "a"};
113  const fs::path path2{tmpfolder / "b"};
114 
115  const std::string path1_contents{"1111"};
116  const std::string path2_contents{"2222"};
117 
118  {
119  std::ofstream file{path1.std_path()};
120  file << path1_contents;
121  }
122 
123  {
124  std::ofstream file{path2.std_path()};
125  file << path2_contents;
126  }
127 
128  // Rename path1 -> path2.
129  BOOST_CHECK(RenameOver(path1, path2));
130 
131  BOOST_CHECK(!fs::exists(path1));
132 
133  {
134  std::ifstream file{path2.std_path()};
135  std::string contents;
136  file >> contents;
137  BOOST_CHECK_EQUAL(contents, path1_contents);
138  }
139  fs::remove(path2);
140 }
141 
fs::path AbsPathJoin(const fs::path &base, const fs::path &path)
Helper function for joining two paths.
Definition: fs.cpp:34
Basic testing setup.
Definition: setup_common.h:64
bool RenameOver(fs::path src, fs::path dest)
Rename src to dest.
Definition: fs_helpers.cpp:243
static bool exists(const path &p)
Definition: fs.h:95
BOOST_AUTO_TEST_CASE(fsbridge_pathtostring)
Definition: fs_tests.cpp:17
BOOST_FIXTURE_TEST_SUITE(cuckoocache_tests, BasicTestingSetup)
Test Suite for CuckooCache.
BOOST_AUTO_TEST_SUITE_END()
#define BOOST_CHECK_EQUAL(v1, v2)
Definition: object.cpp:17
static std::string PathToString(const path &path)
Convert path object to a byte string.
Definition: fs.h:157
static path u8path(std::string_view utf8_str)
Definition: fs.h:81
unsigned char u8
static path PathFromString(const std::string &string)
Convert byte string to path object.
Definition: fs.h:180
Path class wrapper to block calls to the fs::path(std::string) implicit constructor and the fs::path:...
Definition: fs.h:33
std::filesystem::path & std_path()
Definition: fs.h:39
#define BOOST_CHECK(expr)
Definition: object.cpp:16