Bitcoin Core  22.99.0
P2P Digital Currency
flatfile_tests.cpp
Go to the documentation of this file.
1 // Copyright (c) 2019-2020 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>
9 #include <util/system.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 
28 BOOST_AUTO_TEST_CASE(flatfile_open)
29 {
30  const auto data_dir = m_args.GetDataDirBase();
31  FlatFileSeq seq(data_dir, "a", 16 * 1024);
32 
33  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  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  size_t pos2 = pos1 + GetSerializeSize(line1, CLIENT_VERSION);
41 
42  // Write first line to file.
43  {
44  CAutoFile file(seq.Open(FlatFilePos(0, pos1)), SER_DISK, CLIENT_VERSION);
45  file << LIMITED_STRING(line1, 256);
46  }
47 
48  // Attempt to append to file opened in read-only mode.
49  {
50  CAutoFile file(seq.Open(FlatFilePos(0, pos2), true), SER_DISK, CLIENT_VERSION);
51  BOOST_CHECK_THROW(file << LIMITED_STRING(line2, 256), std::ios_base::failure);
52  }
53 
54  // Append second line to file.
55  {
56  CAutoFile file(seq.Open(FlatFilePos(0, pos2)), SER_DISK, CLIENT_VERSION);
57  file << LIMITED_STRING(line2, 256);
58  }
59 
60  // Read text from file in read-only mode.
61  {
62  std::string text;
63  CAutoFile file(seq.Open(FlatFilePos(0, pos1), true), SER_DISK, CLIENT_VERSION);
64 
65  file >> LIMITED_STRING(text, 256);
66  BOOST_CHECK_EQUAL(text, line1);
67 
68  file >> LIMITED_STRING(text, 256);
69  BOOST_CHECK_EQUAL(text, line2);
70  }
71 
72  // Read text from file with position offset.
73  {
74  std::string text;
75  CAutoFile file(seq.Open(FlatFilePos(0, pos2)), SER_DISK, CLIENT_VERSION);
76 
77  file >> LIMITED_STRING(text, 256);
78  BOOST_CHECK_EQUAL(text, line2);
79  }
80 
81  // Ensure another file in the sequence has no data.
82  {
83  std::string text;
84  CAutoFile file(seq.Open(FlatFilePos(1, pos2)), SER_DISK, CLIENT_VERSION);
85  BOOST_CHECK_THROW(file >> LIMITED_STRING(text, 256), std::ios_base::failure);
86  }
87 }
88 
89 BOOST_AUTO_TEST_CASE(flatfile_allocate)
90 {
91  const auto data_dir = m_args.GetDataDirBase();
92  FlatFileSeq seq(data_dir, "a", 100);
93 
94  bool out_of_space;
95 
96  BOOST_CHECK_EQUAL(seq.Allocate(FlatFilePos(0, 0), 1, out_of_space), 100U);
97  BOOST_CHECK_EQUAL(fs::file_size(seq.FileName(FlatFilePos(0, 0))), 100U);
98  BOOST_CHECK(!out_of_space);
99 
100  BOOST_CHECK_EQUAL(seq.Allocate(FlatFilePos(0, 99), 1, out_of_space), 0U);
101  BOOST_CHECK_EQUAL(fs::file_size(seq.FileName(FlatFilePos(0, 99))), 100U);
102  BOOST_CHECK(!out_of_space);
103 
104  BOOST_CHECK_EQUAL(seq.Allocate(FlatFilePos(0, 99), 2, out_of_space), 101U);
105  BOOST_CHECK_EQUAL(fs::file_size(seq.FileName(FlatFilePos(0, 99))), 200U);
106  BOOST_CHECK(!out_of_space);
107 }
108 
109 BOOST_AUTO_TEST_CASE(flatfile_flush)
110 {
111  const auto data_dir = m_args.GetDataDirBase();
112  FlatFileSeq seq(data_dir, "a", 100);
113 
114  bool out_of_space;
115  seq.Allocate(FlatFilePos(0, 0), 1, out_of_space);
116 
117  // Flush without finalize should not truncate file.
118  seq.Flush(FlatFilePos(0, 1));
119  BOOST_CHECK_EQUAL(fs::file_size(seq.FileName(FlatFilePos(0, 1))), 100U);
120 
121  // Flush with finalize should truncate file.
122  seq.Flush(FlatFilePos(0, 1), true);
123  BOOST_CHECK_EQUAL(fs::file_size(seq.FileName(FlatFilePos(0, 1))), 1U);
124 }
125 
GetSerializeSize
size_t GetSerializeSize(const T &t, int nVersion=0)
Definition: serialize.h:1080
BOOST_AUTO_TEST_CASE
BOOST_AUTO_TEST_CASE(flatfile_filename)
Definition: flatfile_tests.cpp:15
SER_DISK
@ SER_DISK
Definition: serialize.h:139
streams.h
setup_common.h
flatfile.h
FlatFileSeq::Allocate
size_t Allocate(const FlatFilePos &pos, size_t add_size, bool &out_of_space)
Allocate additional space in a file after the given starting position.
Definition: flatfile.cpp:55
clientversion.h
BOOST_FIXTURE_TEST_SUITE
#define BOOST_FIXTURE_TEST_SUITE(a, b)
Definition: object.cpp:14
BOOST_AUTO_TEST_SUITE_END
BOOST_AUTO_TEST_SUITE_END()
CAutoFile
Non-refcounted RAII wrapper for FILE*.
Definition: streams.h:564
FlatFileSeq
FlatFileSeq represents a sequence of numbered files storing raw data.
Definition: flatfile.h:46
FlatFileSeq::Open
FILE * Open(const FlatFilePos &pos, bool read_only=false)
Open a handle to the file at the given position.
Definition: flatfile.cpp:33
FlatFilePos
Definition: flatfile.h:14
BasicTestingSetup
Basic testing setup.
Definition: setup_common.h:76
system.h
FlatFileSeq::FileName
fs::path FileName(const FlatFilePos &pos) const
Get the name of the file at the given position.
Definition: flatfile.cpp:28
CLIENT_VERSION
static const int CLIENT_VERSION
bitcoind-res.rc includes this file, but it cannot cope with real c++ code.
Definition: clientversion.h:33
BOOST_CHECK_THROW
#define BOOST_CHECK_THROW(stmt, excMatch)
Definition: object.cpp:19
LIMITED_STRING
#define LIMITED_STRING(obj, n)
Definition: serialize.h:445
FlatFileSeq::Flush
bool Flush(const FlatFilePos &pos, bool finalize=false)
Commit a file to disk, and optionally truncate off extra pre-allocated bytes if final.
Definition: flatfile.cpp:81
BOOST_CHECK
#define BOOST_CHECK(expr)
Definition: object.cpp:17
BOOST_CHECK_EQUAL
#define BOOST_CHECK_EQUAL(v1, v2)
Definition: object.cpp:18