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 [ + - ]: 2 : file << LIMITED_STRING(line1, 256);
49 : 0 : }
50 : :
51 : : // Attempt to append to file opened in read-only mode.
52 : 1 : {
53 [ + - + - ]: 1 : AutoFile file{seq.Open(FlatFilePos(0, pos2), true)};
54 [ + - - + : 2 : BOOST_CHECK_THROW(file << LIMITED_STRING(line2, 256), std::ios_base::failure);
- - - - -
+ + - +
- ]
55 : 0 : }
56 : :
57 : : // Append second line to file.
58 : 1 : {
59 [ + - + - ]: 1 : AutoFile file{seq.Open(FlatFilePos(0, pos2))};
60 [ + - ]: 2 : file << LIMITED_STRING(line2, 256);
61 : 0 : }
62 : :
63 : : // Read text from file in read-only mode.
64 : 1 : {
65 [ + - ]: 1 : std::string text;
66 [ + - + - ]: 1 : AutoFile file{seq.Open(FlatFilePos(0, pos1), true)};
67 : :
68 [ + - ]: 1 : file >> LIMITED_STRING(text, 256);
69 [ + - + - ]: 1 : BOOST_CHECK_EQUAL(text, line1);
70 : :
71 [ + - ]: 1 : file >> LIMITED_STRING(text, 256);
72 [ + - + - ]: 1 : BOOST_CHECK_EQUAL(text, line2);
73 : 1 : }
74 : :
75 : : // Read text from file with position offset.
76 : 1 : {
77 [ + - ]: 1 : std::string text;
78 [ + - + - ]: 1 : AutoFile file{seq.Open(FlatFilePos(0, pos2))};
79 : :
80 [ + - ]: 1 : file >> LIMITED_STRING(text, 256);
81 [ + - + - ]: 1 : BOOST_CHECK_EQUAL(text, line2);
82 : 1 : }
83 : :
84 : : // Ensure another file in the sequence has no data.
85 : 1 : {
86 [ + - ]: 1 : std::string text;
87 [ + - + - ]: 1 : AutoFile file{seq.Open(FlatFilePos(1, pos2))};
88 [ + - - + : 2 : BOOST_CHECK_THROW(file >> LIMITED_STRING(text, 256), std::ios_base::failure);
- - - - -
+ + - +
- ]
89 : 1 : }
90 : 3 : }
91 : :
92 [ + - + - : 7 : BOOST_AUTO_TEST_CASE(flatfile_allocate)
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- ]
93 : : {
94 : 1 : const auto data_dir = m_args.GetDataDirBase();
95 [ + - + - ]: 1 : FlatFileSeq seq(data_dir, "a", 100);
96 : :
97 : 1 : bool out_of_space;
98 : :
99 [ + - + - : 1 : BOOST_CHECK_EQUAL(seq.Allocate(FlatFilePos(0, 0), 1, out_of_space), 100U);
+ - ]
100 [ + - + - : 1 : BOOST_CHECK_EQUAL(fs::file_size(seq.FileName(FlatFilePos(0, 0))), 100U);
+ - + - ]
101 [ + - + - : 2 : BOOST_CHECK(!out_of_space);
+ - ]
102 : :
103 [ + - + - : 1 : BOOST_CHECK_EQUAL(seq.Allocate(FlatFilePos(0, 99), 1, out_of_space), 0U);
+ - ]
104 [ + - + - : 1 : BOOST_CHECK_EQUAL(fs::file_size(seq.FileName(FlatFilePos(0, 99))), 100U);
+ - + - ]
105 [ + - + - : 2 : BOOST_CHECK(!out_of_space);
+ - ]
106 : :
107 [ + - + - : 1 : BOOST_CHECK_EQUAL(seq.Allocate(FlatFilePos(0, 99), 2, out_of_space), 101U);
+ - ]
108 [ + - + - : 1 : BOOST_CHECK_EQUAL(fs::file_size(seq.FileName(FlatFilePos(0, 99))), 200U);
+ - + - ]
109 [ + - + - ]: 2 : BOOST_CHECK(!out_of_space);
110 : 2 : }
111 : :
112 [ + - + - : 7 : BOOST_AUTO_TEST_CASE(flatfile_flush)
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- ]
113 : : {
114 : 1 : const auto data_dir = m_args.GetDataDirBase();
115 [ + - + - ]: 1 : FlatFileSeq seq(data_dir, "a", 100);
116 : :
117 : 1 : bool out_of_space;
118 [ + - ]: 1 : seq.Allocate(FlatFilePos(0, 0), 1, out_of_space);
119 : :
120 : : // Flush without finalize should not truncate file.
121 [ + - ]: 1 : seq.Flush(FlatFilePos(0, 1));
122 [ + - + - : 1 : BOOST_CHECK_EQUAL(fs::file_size(seq.FileName(FlatFilePos(0, 1))), 100U);
+ - + - ]
123 : :
124 : : // Flush with finalize should truncate file.
125 [ + - ]: 1 : seq.Flush(FlatFilePos(0, 1), true);
126 [ + - + - : 2 : BOOST_CHECK_EQUAL(fs::file_size(seq.FileName(FlatFilePos(0, 1))), 1U);
+ - + - ]
127 : 2 : }
128 : :
129 : : BOOST_AUTO_TEST_SUITE_END()
|