Bitcoin Core  31.0.0
P2P Digital Currency
flatfile_tests.cpp
Go to the documentation of this file.
1 // Copyright (c) 2019-present 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>
10 
11 #include <boost/test/unit_test.hpp>
12 
14 
15 BOOST_AUTO_TEST_CASE(flatfile_filename)
16 {
17  const auto data_dir = m_args.GetDataDirBase();
18 
19  FlatFilePos pos(456, 789);
20 
21  FlatFileSeq seq1(data_dir, "a", 16 * 1024);
22  BOOST_CHECK_EQUAL(seq1.FileName(pos), data_dir / "a00456.dat");
23 
24  FlatFileSeq seq2(data_dir / "a", "b", 16 * 1024);
25  BOOST_CHECK_EQUAL(seq2.FileName(pos), data_dir / "a" / "b00456.dat");
26 
27  // Check default constructor IsNull
29 }
30 
31 BOOST_AUTO_TEST_CASE(flatfile_open)
32 {
33  const auto data_dir = m_args.GetDataDirBase();
34  FlatFileSeq seq(data_dir, "a", 16 * 1024);
35 
36  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  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  uint64_t pos1{0};
43  uint64_t pos2{pos1 + GetSerializeSize(line1)};
44 
45  // Write first line to file.
46  {
47  AutoFile file{seq.Open(FlatFilePos(0, pos1))};
48  file << LIMITED_STRING(line1, 256);
49  BOOST_REQUIRE_EQUAL(file.fclose(), 0);
50  }
51 
52  // Attempt to append to file opened in read-only mode.
53  {
54  AutoFile file{seq.Open(FlatFilePos(0, pos2), true)};
55  BOOST_CHECK_THROW(file << LIMITED_STRING(line2, 256), std::ios_base::failure);
56  }
57 
58  // Append second line to file.
59  {
60  AutoFile file{seq.Open(FlatFilePos(0, pos2))};
61  file << LIMITED_STRING(line2, 256);
62  BOOST_REQUIRE_EQUAL(file.fclose(), 0);
63  }
64 
65  // Read text from file in read-only mode.
66  {
67  std::string text;
68  AutoFile file{seq.Open(FlatFilePos(0, pos1), true)};
69 
70  file >> LIMITED_STRING(text, 256);
71  BOOST_CHECK_EQUAL(text, line1);
72 
73  file >> LIMITED_STRING(text, 256);
74  BOOST_CHECK_EQUAL(text, line2);
75  }
76 
77  // Read text from file with position offset.
78  {
79  std::string text;
80  AutoFile file{seq.Open(FlatFilePos(0, pos2))};
81 
82  file >> LIMITED_STRING(text, 256);
83  BOOST_CHECK_EQUAL(text, line2);
84  BOOST_REQUIRE_EQUAL(file.fclose(), 0);
85  }
86 
87  // Ensure another file in the sequence has no data.
88  {
89  std::string text;
90  AutoFile file{seq.Open(FlatFilePos(1, pos2))};
91  BOOST_CHECK_THROW(file >> LIMITED_STRING(text, 256), std::ios_base::failure);
92  BOOST_REQUIRE_EQUAL(file.fclose(), 0);
93  }
94 }
95 
96 BOOST_AUTO_TEST_CASE(flatfile_allocate)
97 {
98  const auto data_dir = m_args.GetDataDirBase();
99  FlatFileSeq seq(data_dir, "a", 100);
100 
101  bool out_of_space;
102 
103  BOOST_CHECK_EQUAL(seq.Allocate(FlatFilePos(0, 0), 1, out_of_space), 100U);
104  BOOST_CHECK_EQUAL(fs::file_size(seq.FileName(FlatFilePos(0, 0))), 100U);
105  BOOST_CHECK(!out_of_space);
106 
107  BOOST_CHECK_EQUAL(seq.Allocate(FlatFilePos(0, 99), 1, out_of_space), 0U);
108  BOOST_CHECK_EQUAL(fs::file_size(seq.FileName(FlatFilePos(0, 99))), 100U);
109  BOOST_CHECK(!out_of_space);
110 
111  BOOST_CHECK_EQUAL(seq.Allocate(FlatFilePos(0, 99), 2, out_of_space), 101U);
112  BOOST_CHECK_EQUAL(fs::file_size(seq.FileName(FlatFilePos(0, 99))), 200U);
113  BOOST_CHECK(!out_of_space);
114 }
115 
116 BOOST_AUTO_TEST_CASE(flatfile_flush)
117 {
118  const auto data_dir = m_args.GetDataDirBase();
119  FlatFileSeq seq(data_dir, "a", 100);
120 
121  bool out_of_space;
122  seq.Allocate(FlatFilePos(0, 0), 1, out_of_space);
123 
124  // Flush without finalize should not truncate file.
125  seq.Flush(FlatFilePos(0, 1));
126  BOOST_CHECK_EQUAL(fs::file_size(seq.FileName(FlatFilePos(0, 1))), 100U);
127 
128  // Flush with finalize should truncate file.
129  seq.Flush(FlatFilePos(0, 1), true);
130  BOOST_CHECK_EQUAL(fs::file_size(seq.FileName(FlatFilePos(0, 1))), 1U);
131 }
132 
#define BOOST_CHECK_THROW(stmt, excMatch)
Definition: object.cpp:18
assert(!tx.IsCoinBase())
bool IsNull() const
Definition: flatfile.h:32
Non-refcounted RAII wrapper for FILE*.
Definition: streams.h:372
Basic testing setup.
Definition: setup_common.h:64
size_t Allocate(const FlatFilePos &pos, size_t add_size, bool &out_of_space) const
Allocate additional space in a file after the given starting position.
Definition: flatfile.cpp:58
BOOST_FIXTURE_TEST_SUITE(cuckoocache_tests, BasicTestingSetup)
Test Suite for CuckooCache.
BOOST_AUTO_TEST_SUITE_END()
uint64_t GetSerializeSize(const T &t)
Definition: serialize.h:1095
bool Flush(const FlatFilePos &pos, bool finalize=false) const
Commit a file to disk, and optionally truncate off extra pre-allocated bytes if final.
Definition: flatfile.cpp:87
FILE * Open(const FlatFilePos &pos, bool read_only=false) const
Open a handle to the file at the given position.
Definition: flatfile.cpp:34
fs::path FileName(const FlatFilePos &pos) const
Get the name of the file at the given position.
Definition: flatfile.cpp:29
#define BOOST_CHECK_EQUAL(v1, v2)
Definition: object.cpp:17
BOOST_AUTO_TEST_CASE(flatfile_filename)
#define LIMITED_STRING(obj, n)
Definition: serialize.h:493
FlatFileSeq represents a sequence of numbered files storing raw data.
Definition: flatfile.h:41
#define BOOST_CHECK(expr)
Definition: object.cpp:16