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