Branch data Line data Source code
1 : : // Copyright (c) 2019-2022 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 <clientversion.h>
6 : : #include <common/args.h>
7 : : #include <flatfile.h>
8 : : #include <streams.h>
9 : : #include <test/util/setup_common.h>
10 : :
11 : : #include <boost/test/unit_test.hpp>
12 : :
13 : 0 : BOOST_FIXTURE_TEST_SUITE(flatfile_tests, BasicTestingSetup)
14 : :
15 : 0 : BOOST_AUTO_TEST_CASE(flatfile_filename)
16 : : {
17 : 0 : const auto data_dir = m_args.GetDataDirBase();
18 : :
19 : 0 : FlatFilePos pos(456, 789);
20 : :
21 : 0 : FlatFileSeq seq1(data_dir, "a", 16 * 1024);
22 : 0 : BOOST_CHECK_EQUAL(seq1.FileName(pos), data_dir / "a00456.dat");
23 : :
24 : 0 : FlatFileSeq seq2(data_dir / "a", "b", 16 * 1024);
25 : 0 : BOOST_CHECK_EQUAL(seq2.FileName(pos), data_dir / "a" / "b00456.dat");
26 : :
27 : : // Check default constructor IsNull
28 : 0 : assert(FlatFilePos{}.IsNull());
29 : 0 : }
30 : :
31 : 0 : BOOST_AUTO_TEST_CASE(flatfile_open)
32 : : {
33 : 0 : const auto data_dir = m_args.GetDataDirBase();
34 : 0 : FlatFileSeq seq(data_dir, "a", 16 * 1024);
35 : :
36 : 0 : std::string line1("A purely peer-to-peer version of electronic cash would allow online "
37 : : "payments to be sent directly from one party to another without going "
38 : : "through a financial institution.");
39 : 0 : std::string line2("Digital signatures provide part of the solution, but the main benefits are "
40 : : "lost if a trusted third party is still required to prevent double-spending.");
41 : :
42 : 0 : size_t pos1 = 0;
43 : 0 : size_t pos2 = pos1 + GetSerializeSize(line1, CLIENT_VERSION);
44 : :
45 : : // Write first line to file.
46 : : {
47 : 0 : AutoFile file{seq.Open(FlatFilePos(0, pos1))};
48 : 0 : file << LIMITED_STRING(line1, 256);
49 : 0 : }
50 : :
51 : : // Attempt to append to file opened in read-only mode.
52 : : {
53 : 0 : AutoFile file{seq.Open(FlatFilePos(0, pos2), true)};
54 : 0 : BOOST_CHECK_THROW(file << LIMITED_STRING(line2, 256), std::ios_base::failure);
55 : 0 : }
56 : :
57 : : // Append second line to file.
58 : : {
59 : 0 : AutoFile file{seq.Open(FlatFilePos(0, pos2))};
60 : 0 : file << LIMITED_STRING(line2, 256);
61 : 0 : }
62 : :
63 : : // Read text from file in read-only mode.
64 : : {
65 : 0 : std::string text;
66 : 0 : AutoFile file{seq.Open(FlatFilePos(0, pos1), true)};
67 : :
68 : 0 : file >> LIMITED_STRING(text, 256);
69 : 0 : BOOST_CHECK_EQUAL(text, line1);
70 : :
71 : 0 : file >> LIMITED_STRING(text, 256);
72 : 0 : BOOST_CHECK_EQUAL(text, line2);
73 : 0 : }
74 : 0 :
75 : : // Read text from file with position offset.
76 : : {
77 : 0 : std::string text;
78 : 0 : AutoFile file{seq.Open(FlatFilePos(0, pos2))};
79 : :
80 : 0 : file >> LIMITED_STRING(text, 256);
81 : 0 : BOOST_CHECK_EQUAL(text, line2);
82 : 0 : }
83 : :
84 : : // Ensure another file in the sequence has no data.
85 : : {
86 : 0 : std::string text;
87 : 0 : AutoFile file{seq.Open(FlatFilePos(1, pos2))};
88 : 0 : BOOST_CHECK_THROW(file >> LIMITED_STRING(text, 256), std::ios_base::failure);
89 : 0 : }
90 : 0 : }
91 : :
92 : 0 : BOOST_AUTO_TEST_CASE(flatfile_allocate)
93 : : {
94 : 0 : const auto data_dir = m_args.GetDataDirBase();
95 : 0 : FlatFileSeq seq(data_dir, "a", 100);
96 : :
97 : : bool out_of_space;
98 : :
99 : 0 : BOOST_CHECK_EQUAL(seq.Allocate(FlatFilePos(0, 0), 1, out_of_space), 100U);
100 : 0 : BOOST_CHECK_EQUAL(fs::file_size(seq.FileName(FlatFilePos(0, 0))), 100U);
101 : 0 : BOOST_CHECK(!out_of_space);
102 : :
103 : 0 : BOOST_CHECK_EQUAL(seq.Allocate(FlatFilePos(0, 99), 1, out_of_space), 0U);
104 : 0 : BOOST_CHECK_EQUAL(fs::file_size(seq.FileName(FlatFilePos(0, 99))), 100U);
105 : 0 : BOOST_CHECK(!out_of_space);
106 : :
107 : 0 : BOOST_CHECK_EQUAL(seq.Allocate(FlatFilePos(0, 99), 2, out_of_space), 101U);
108 : 0 : BOOST_CHECK_EQUAL(fs::file_size(seq.FileName(FlatFilePos(0, 99))), 200U);
109 : 0 : BOOST_CHECK(!out_of_space);
110 : 0 : }
111 : :
112 : 0 : BOOST_AUTO_TEST_CASE(flatfile_flush)
113 : : {
114 : 0 : const auto data_dir = m_args.GetDataDirBase();
115 : 0 : FlatFileSeq seq(data_dir, "a", 100);
116 : :
117 : : bool out_of_space;
118 : 0 : seq.Allocate(FlatFilePos(0, 0), 1, out_of_space);
119 : :
120 : : // Flush without finalize should not truncate file.
121 : 0 : seq.Flush(FlatFilePos(0, 1));
122 : 0 : BOOST_CHECK_EQUAL(fs::file_size(seq.FileName(FlatFilePos(0, 1))), 100U);
123 : :
124 : : // Flush with finalize should truncate file.
125 : 0 : seq.Flush(FlatFilePos(0, 1), true);
126 : 0 : BOOST_CHECK_EQUAL(fs::file_size(seq.FileName(FlatFilePos(0, 1))), 1U);
127 : 0 : }
128 : :
129 : 0 : BOOST_AUTO_TEST_SUITE_END()
|