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