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#include <xrpl/basics/StringUtilities.h>
27#include <xrpl/basics/random.h>
28#include <xrpl/beast/unit_test.h>
29#include <xrpl/beast/utility/rngfill.h>
30#include <xrpl/beast/xor_shift_engine.h>
31#include <boost/algorithm/string.hpp>
32#include <iomanip>
33
34namespace ripple {
35namespace NodeStore {
36
45{
46 bool
49 std::shared_ptr<NodeObject> const& rhs) const noexcept
50 {
51 return lhs->getHash() < rhs->getHash();
52 }
53};
54
56inline bool
60{
61 return (lhs->getType() == rhs->getType()) &&
62 (lhs->getHash() == rhs->getHash()) &&
63 (lhs->getData() == rhs->getData());
64}
65
66// Some common code for the unit tests
67//
69{
70public:
71 // Tunable parameters
72 //
73 static std::size_t const minPayloadBytes = 1;
74 static std::size_t const maxPayloadBytes = 2000;
75 static int const numObjectsToTest = 2000;
76
77public:
78 // Create a predictable batch of objects
79 static Batch
81 {
82 Batch batch;
83 batch.reserve(numObjects);
84
86
87 for (int i = 0; i < numObjects; ++i)
88 {
89 NodeObjectType const type = [&] {
90 switch (rand_int(rng, 3))
91 {
92 case 0:
93 return hotLEDGER;
94 case 1:
95 return hotACCOUNT_NODE;
96 case 2:
98 case 3:
99 return hotUNKNOWN;
100 }
101 // will never happen, but make static analysys tool happy.
102 return hotUNKNOWN;
103 }();
104
105 uint256 hash;
106 beast::rngfill(hash.begin(), hash.size(), rng);
107
109 beast::rngfill(blob.data(), blob.size(), rng);
110
111 batch.push_back(
112 NodeObject::createObject(type, std::move(blob), hash));
113 }
114
115 return batch;
116 }
117
118 // Compare two batches for equality
119 static bool
120 areBatchesEqual(Batch const& lhs, Batch const& rhs)
121 {
122 bool result = true;
123
124 if (lhs.size() == rhs.size())
125 {
126 for (int i = 0; i < lhs.size(); ++i)
127 {
128 if (!isSame(lhs[i], rhs[i]))
129 {
130 result = false;
131 break;
132 }
133 }
134 }
135 else
136 {
137 result = false;
138 }
139
140 return result;
141 }
142
143 // Store a batch in a backend
144 void
145 storeBatch(Backend& backend, Batch const& batch)
146 {
147 for (int i = 0; i < batch.size(); ++i)
148 {
149 backend.store(batch[i]);
150 }
151 }
152
153 // Get a copy of a batch in a backend
154 void
155 fetchCopyOfBatch(Backend& backend, Batch* pCopy, Batch const& batch)
156 {
157 pCopy->clear();
158 pCopy->reserve(batch.size());
159
160 for (int i = 0; i < batch.size(); ++i)
161 {
163
164 Status const status =
165 backend.fetch(batch[i]->getHash().cbegin(), &object);
166
167 BEAST_EXPECT(status == ok);
168
169 if (status == ok)
170 {
171 BEAST_EXPECT(object != nullptr);
172
173 pCopy->push_back(object);
174 }
175 }
176 }
177
178 void
179 fetchMissing(Backend& backend, Batch const& batch)
180 {
181 for (int i = 0; i < batch.size(); ++i)
182 {
184
185 Status const status =
186 backend.fetch(batch[i]->getHash().cbegin(), &object);
187
188 BEAST_EXPECT(status == notFound);
189 }
190 }
191
192 // Store all objects in a batch
193 static void
194 storeBatch(Database& db, Batch const& batch)
195 {
196 for (int i = 0; i < batch.size(); ++i)
197 {
198 std::shared_ptr<NodeObject> const object(batch[i]);
199
200 Blob data(object->getData());
201
202 db.store(
203 object->getType(),
204 std::move(data),
205 object->getHash(),
206 db.earliestLedgerSeq());
207 }
208 }
209
210 // Fetch all the hashes in one batch, into another batch.
211 static void
212 fetchCopyOfBatch(Database& db, Batch* pCopy, Batch const& batch)
213 {
214 pCopy->clear();
215 pCopy->reserve(batch.size());
216
217 for (int i = 0; i < batch.size(); ++i)
218 {
220 db.fetchNodeObject(batch[i]->getHash(), 0);
221
222 if (object != nullptr)
223 pCopy->push_back(object);
224 }
225 }
226};
227
228} // namespace NodeStore
229} // namespace ripple
230
231#endif
A testsuite class.
Definition: suite.h:53
static std::shared_ptr< NodeObject > createObject(NodeObjectType type, Blob &&data, uint256 const &hash)
Create an object from fields.
Definition: NodeObject.cpp:37
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:50
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:239
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:220
static int const numObjectsToTest
Definition: TestBase.h:75
static Batch createPredictableBatch(int numObjects, std::uint64_t seed)
Definition: TestBase.h:80
static bool areBatchesEqual(Batch const &lhs, Batch const &rhs)
Definition: TestBase.h:120
static void fetchCopyOfBatch(Database &db, Batch *pCopy, Batch const &batch)
Definition: TestBase.h:212
static void storeBatch(Database &db, Batch const &batch)
Definition: TestBase.h:194
void fetchCopyOfBatch(Backend &backend, Batch *pCopy, Batch const &batch)
Definition: TestBase.h:155
static std::size_t const maxPayloadBytes
Definition: TestBase.h:74
void storeBatch(Backend &backend, Batch const &batch)
Definition: TestBase.h:145
static std::size_t const minPayloadBytes
Definition: TestBase.h:73
void fetchMissing(Backend &backend, Batch const &batch)
Definition: TestBase.h:179
iterator begin()
Definition: base_uint.h:135
static constexpr std::size_t size()
Definition: base_uint.h:525
T clear(T... args)
T data(T... args)
void rngfill(void *buffer, std::size_t bytes, Generator &g)
Definition: rngfill.h:33
bool isSame(std::shared_ptr< NodeObject > const &lhs, std::shared_ptr< NodeObject > const &rhs)
Returns true if objects are identical.
Definition: TestBase.h:57
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:45
bool operator()(std::shared_ptr< NodeObject > const &lhs, std::shared_ptr< NodeObject > const &rhs) const noexcept
Definition: TestBase.h:47