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