rippled
Loading...
Searching...
No Matches
TestBase.h
1//------------------------------------------------------------------------------
2/*
3 This file is part of rippled: https://github.com/ripple/rippled
4 Copyright (c) 2012, 2013 Ripple Labs Inc.
5
6 Permission to use, copy, modify, and/or distribute this software for any
7 purpose with or without fee is hereby granted, provided that the above
8 copyright notice and this permission notice appear in all copies.
9
10 THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17*/
18//==============================================================================
19
20#ifndef RIPPLE_NODESTORE_BASE_H_INCLUDED
21#define RIPPLE_NODESTORE_BASE_H_INCLUDED
22
23#include <xrpld/nodestore/Backend.h>
24#include <xrpld/nodestore/Database.h>
25#include <xrpld/nodestore/Types.h>
26
27#include <xrpl/basics/StringUtilities.h>
28#include <xrpl/basics/random.h>
29#include <xrpl/beast/unit_test.h>
30#include <xrpl/beast/utility/rngfill.h>
31#include <xrpl/beast/xor_shift_engine.h>
32
33#include <boost/algorithm/string.hpp>
34
35#include <iomanip>
36
37namespace ripple {
38namespace NodeStore {
39
48{
49 bool
52 std::shared_ptr<NodeObject> const& rhs) const noexcept
53 {
54 return lhs->getHash() < rhs->getHash();
55 }
56};
57
59inline bool
63{
64 return (lhs->getType() == rhs->getType()) &&
65 (lhs->getHash() == rhs->getHash()) &&
66 (lhs->getData() == rhs->getData());
67}
68
69// Some common code for the unit tests
70//
72{
73public:
74 // Tunable parameters
75 //
76 static std::size_t const minPayloadBytes = 1;
77 static std::size_t const maxPayloadBytes = 2000;
78 static int const numObjectsToTest = 2000;
79
80public:
81 // Create a predictable batch of objects
82 static Batch
84 {
86 batch.reserve(numObjects);
87
89
90 for (int i = 0; i < numObjects; ++i)
91 {
92 NodeObjectType const type = [&] {
93 switch (rand_int(rng, 3))
94 {
95 case 0:
96 return hotLEDGER;
97 case 1:
98 return hotACCOUNT_NODE;
99 case 2:
100 return hotTRANSACTION_NODE;
101 case 3:
102 return hotUNKNOWN;
103 }
104 // will never happen, but make static analysys tool happy.
105 return hotUNKNOWN;
106 }();
107
108 uint256 hash;
109 beast::rngfill(hash.begin(), hash.size(), rng);
110
112 beast::rngfill(blob.data(), blob.size(), rng);
113
114 batch.push_back(
115 NodeObject::createObject(type, std::move(blob), hash));
116 }
117
118 return batch;
119 }
120
121 // Compare two batches for equality
122 static bool
123 areBatchesEqual(Batch const& lhs, Batch const& rhs)
124 {
125 bool result = true;
126
127 if (lhs.size() == rhs.size())
128 {
129 for (int i = 0; i < lhs.size(); ++i)
130 {
131 if (!isSame(lhs[i], rhs[i]))
132 {
133 result = false;
134 break;
135 }
136 }
137 }
138 else
139 {
140 result = false;
141 }
142
143 return result;
144 }
145
146 // Store a batch in a backend
147 void
148 storeBatch(Backend& backend, Batch const& batch)
149 {
150 for (int i = 0; i < batch.size(); ++i)
151 {
152 backend.store(batch[i]);
153 }
154 }
155
156 // Get a copy of a batch in a backend
157 void
158 fetchCopyOfBatch(Backend& backend, Batch* pCopy, Batch const& batch)
159 {
160 pCopy->clear();
161 pCopy->reserve(batch.size());
162
163 for (int i = 0; i < batch.size(); ++i)
164 {
166
167 Status const status =
168 backend.fetch(batch[i]->getHash().cbegin(), &object);
169
170 BEAST_EXPECT(status == ok);
171
172 if (status == ok)
173 {
174 BEAST_EXPECT(object != nullptr);
175
176 pCopy->push_back(object);
177 }
178 }
179 }
180
181 void
182 fetchMissing(Backend& backend, Batch const& batch)
183 {
184 for (int i = 0; i < batch.size(); ++i)
185 {
187
188 Status const status =
189 backend.fetch(batch[i]->getHash().cbegin(), &object);
190
191 BEAST_EXPECT(status == notFound);
192 }
193 }
194
195 // Store all objects in a batch
196 static void
198 {
199 for (int i = 0; i < batch.size(); ++i)
200 {
201 std::shared_ptr<NodeObject> const object(batch[i]);
202
203 Blob data(object->getData());
204
205 db.store(
206 object->getType(),
207 std::move(data),
208 object->getHash(),
209 db.earliestLedgerSeq());
210 }
211 }
212
213 // Fetch all the hashes in one batch, into another batch.
214 static void
216 {
217 pCopy->clear();
218 pCopy->reserve(batch.size());
219
220 for (int i = 0; i < batch.size(); ++i)
221 {
223 db.fetchNodeObject(batch[i]->getHash(), 0);
224
225 if (object != nullptr)
226 pCopy->push_back(object);
227 }
228 }
229};
230
231} // namespace NodeStore
232} // namespace ripple
233
234#endif
A testsuite class.
Definition: suite.h:55
static std::shared_ptr< NodeObject > createObject(NodeObjectType type, Blob &&data, uint256 const &hash)
Create an object from fields.
Definition: NodeObject.cpp:38
A backend used for the NodeStore.
Definition: Backend.h:40
virtual Status fetch(void const *key, std::shared_ptr< NodeObject > *pObject)=0
Fetch a single object.
virtual void store(std::shared_ptr< NodeObject > const &object)=0
Store a single object.
Persistency layer for NodeObject.
Definition: Database.h:52
std::shared_ptr< NodeObject > fetchNodeObject(uint256 const &hash, std::uint32_t ledgerSeq=0, FetchType fetchType=FetchType::synchronous, bool duplicate=false)
Fetch a node object.
Definition: Database.cpp:241
virtual void store(NodeObjectType type, Blob &&data, uint256 const &hash, std::uint32_t ledgerSeq)=0
Store the object.
std::uint32_t earliestLedgerSeq() const noexcept
Definition: Database.h:222
static int const numObjectsToTest
Definition: TestBase.h:78
static Batch createPredictableBatch(int numObjects, std::uint64_t seed)
Definition: TestBase.h:83
static bool areBatchesEqual(Batch const &lhs, Batch const &rhs)
Definition: TestBase.h:123
static void fetchCopyOfBatch(Database &db, Batch *pCopy, Batch const &batch)
Definition: TestBase.h:215
static void storeBatch(Database &db, Batch const &batch)
Definition: TestBase.h:197
void fetchCopyOfBatch(Backend &backend, Batch *pCopy, Batch const &batch)
Definition: TestBase.h:158
static std::size_t const maxPayloadBytes
Definition: TestBase.h:77
void storeBatch(Backend &backend, Batch const &batch)
Definition: TestBase.h:148
static std::size_t const minPayloadBytes
Definition: TestBase.h:76
void fetchMissing(Backend &backend, Batch const &batch)
Definition: TestBase.h:182
iterator begin()
Definition: base_uint.h:136
static constexpr std::size_t size()
Definition: base_uint.h:526
T clear(T... args)
T data(T... args)
void rngfill(void *buffer, std::size_t bytes, Generator &g)
Definition: rngfill.h:34
bool isSame(std::shared_ptr< NodeObject > const &lhs, std::shared_ptr< NodeObject > const &rhs)
Returns true if objects are identical.
Definition: TestBase.h:60
Status
Return codes from Backend operations.
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition: algorithm.h:26
std::enable_if_t< std::is_integral< Integral >::value, Integral > rand_int()
NodeObjectType
The types of node objects.
Definition: NodeObject.h:32
@ hotACCOUNT_NODE
Definition: NodeObject.h:35
@ hotTRANSACTION_NODE
Definition: NodeObject.h:36
@ hotUNKNOWN
Definition: NodeObject.h:33
@ hotLEDGER
Definition: NodeObject.h:34
T push_back(T... args)
T reserve(T... args)
T size(T... args)
Binary function that satisfies the strict-weak-ordering requirement.
Definition: TestBase.h:48
bool operator()(std::shared_ptr< NodeObject > const &lhs, std::shared_ptr< NodeObject > const &rhs) const noexcept
Definition: TestBase.h:50