rippled
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 <ripple/nodestore/Database.h>
24 #include <ripple/basics/random.h>
25 #include <ripple/basics/StringUtilities.h>
26 #include <ripple/beast/unit_test.h>
27 #include <ripple/beast/utility/rngfill.h>
28 #include <ripple/beast/xor_shift_engine.h>
29 #include <ripple/nodestore/Backend.h>
30 #include <ripple/nodestore/Types.h>
31 #include <boost/algorithm/string.hpp>
32 #include <iomanip>
33 
34 namespace ripple {
35 namespace NodeStore {
36 
44 struct LessThan
45 {
46  bool
48  std::shared_ptr<NodeObject> const& lhs,
49  std::shared_ptr<NodeObject> const& rhs) const noexcept
50  {
51  return lhs->getHash () < rhs->getHash ();
52  }
53 };
54 
56 inline
58  std::shared_ptr<NodeObject> const& rhs)
59 {
60  return
61  (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 //
68 class TestBase : public beast::unit_test::suite
69 {
70 public:
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 
77 public:
78  // Create a predictable batch of objects
79  static
81  int numObjects, std::uint64_t seed)
82  {
83  Batch batch;
84  batch.reserve (numObjects);
85 
86  beast::xor_shift_engine rng (seed);
87 
88  for (int i = 0; i < numObjects; ++i)
89  {
90  NodeObjectType type;
91 
92  switch (rand_int(rng, 3))
93  {
94  case 0: type = hotLEDGER; break;
95  case 1: type = hotACCOUNT_NODE; break;
96  case 2: type = hotTRANSACTION_NODE; break;
97  case 3: type = hotUNKNOWN; break;
98  }
99 
100  uint256 hash;
101  beast::rngfill (hash.begin(), hash.size(), rng);
102 
103  Blob blob (
104  rand_int(rng,
106  beast::rngfill (blob.data(), blob.size(), rng);
107 
108  batch.push_back (
110  type, std::move(blob), hash));
111  }
112 
113  return batch;
114  }
115 
116  // Compare two batches for equality
117  static bool areBatchesEqual (Batch const& lhs, Batch const& rhs)
118  {
119  bool result = true;
120 
121  if (lhs.size () == rhs.size ())
122  {
123  for (int i = 0; i < lhs.size (); ++i)
124  {
125  if (! isSame(lhs[i], rhs[i]))
126  {
127  result = false;
128  break;
129  }
130  }
131  }
132  else
133  {
134  result = false;
135  }
136 
137  return result;
138  }
139 
140  // Store a batch in a backend
141  void storeBatch (Backend& backend, Batch const& batch)
142  {
143  for (int i = 0; i < batch.size (); ++i)
144  {
145  backend.store (batch [i]);
146  }
147  }
148 
149  // Get a copy of a batch in a backend
150  void fetchCopyOfBatch (Backend& backend, Batch* pCopy, Batch const& batch)
151  {
152  pCopy->clear ();
153  pCopy->reserve (batch.size ());
154 
155  for (int i = 0; i < batch.size (); ++i)
156  {
158 
159  Status const status = backend.fetch (
160  batch [i]->getHash ().cbegin (), &object);
161 
162  BEAST_EXPECT(status == ok);
163 
164  if (status == ok)
165  {
166  BEAST_EXPECT(object != nullptr);
167 
168  pCopy->push_back (object);
169  }
170  }
171  }
172 
173  void fetchMissing(Backend& backend, Batch const& batch)
174  {
175  for (int i = 0; i < batch.size (); ++i)
176  {
178 
179  Status const status = backend.fetch (
180  batch [i]->getHash ().cbegin (), &object);
181 
182  BEAST_EXPECT(status == notFound);
183  }
184  }
185 
186  // Store all objects in a batch
187  static void storeBatch (Database& db, Batch const& batch)
188  {
189  for (int i = 0; i < batch.size (); ++i)
190  {
191  std::shared_ptr<NodeObject> const object (batch [i]);
192 
193  Blob data (object->getData ());
194 
195  db.store (object->getType (),
196  std::move (data),
197  object->getHash (),
198  db.earliestLedgerSeq());
199  }
200  }
201 
202  // Fetch all the hashes in one batch, into another batch.
203  static void fetchCopyOfBatch (Database& db,
204  Batch* pCopy,
205  Batch const& batch)
206  {
207  pCopy->clear ();
208  pCopy->reserve (batch.size ());
209 
210  for (int i = 0; i < batch.size (); ++i)
211  {
212  std::shared_ptr<NodeObject> object = db.fetch (
213  batch [i]->getHash (), 0);
214 
215  if (object != nullptr)
216  pCopy->push_back (object);
217  }
218  }
219 };
220 
221 }
222 }
223 
224 #endif
ripple::hotUNKNOWN
@ hotUNKNOWN
Definition: NodeObject.h:35
ripple::NodeStore::Database
Persistency layer for NodeObject.
Definition: Database.h:53
ripple::NodeStore::TestBase
Definition: TestBase.h:68
std::shared_ptr< NodeObject >
ripple::NodeStore::ok
@ ok
Definition: nodestore/Types.h:47
ripple::NodeStore::TestBase::maxPayloadBytes
static const std::size_t maxPayloadBytes
Definition: TestBase.h:74
std::vector::reserve
T reserve(T... args)
ripple::hotACCOUNT_NODE
@ hotACCOUNT_NODE
Definition: NodeObject.h:37
std::vector< std::shared_ptr< NodeObject > >
std::vector::size
T size(T... args)
ripple::NodeObjectType
NodeObjectType
The types of node objects.
Definition: NodeObject.h:32
ripple::NodeStore::LessThan
Binary function that satisfies the strict-weak-ordering requirement.
Definition: TestBase.h:44
ripple::NodeObject::createObject
static std::shared_ptr< NodeObject > createObject(NodeObjectType type, Blob &&data, uint256 const &hash)
Create an object from fields.
Definition: NodeObject.cpp:39
ripple::rand_int
std::enable_if_t< std::is_integral< Integral >::value &&detail::is_engine< Engine >::value, Integral > rand_int(Engine &engine, Integral min, Integral max)
Return a uniformly distributed random integer.
Definition: ripple/basics/random.h:121
ripple::hotTRANSACTION_NODE
@ hotTRANSACTION_NODE
Definition: NodeObject.h:38
ripple::NodeStore::Backend::store
virtual void store(std::shared_ptr< NodeObject > const &object)=0
Store a single object.
std::vector::clear
T clear(T... args)
ripple::base_uint::size
constexpr static std::size_t size()
Definition: base_uint.h:417
ripple::NodeStore::TestBase::areBatchesEqual
static bool areBatchesEqual(Batch const &lhs, Batch const &rhs)
Definition: TestBase.h:117
std::vector::push_back
T push_back(T... args)
ripple::NodeStore::notFound
@ notFound
Definition: nodestore/Types.h:48
ripple::base_uint< 256 >
ripple::NodeStore::Database::store
virtual void store(NodeObjectType type, Blob &&data, uint256 const &hash, std::uint32_t seq)=0
Store the object.
ripple::NodeStore::TestBase::storeBatch
static void storeBatch(Database &db, Batch const &batch)
Definition: TestBase.h:187
ripple::NodeStore::TestBase::fetchMissing
void fetchMissing(Backend &backend, Batch const &batch)
Definition: TestBase.h:173
ripple::NodeStore::Database::fetch
virtual std::shared_ptr< NodeObject > fetch(uint256 const &hash, std::uint32_t seq)=0
Fetch an object.
ripple::NodeStore::TestBase::fetchCopyOfBatch
void fetchCopyOfBatch(Backend &backend, Batch *pCopy, Batch const &batch)
Definition: TestBase.h:150
std::uint64_t
ripple::NodeStore::Database::earliestLedgerSeq
std::uint32_t earliestLedgerSeq() const
Definition: Database.h:220
ripple::NodeStore::Status
Status
Return codes from Backend operations.
Definition: nodestore/Types.h:45
ripple::NodeStore::TestBase::numObjectsToTest
static const int numObjectsToTest
Definition: TestBase.h:75
ripple::NodeStore::TestBase::createPredictableBatch
static Batch createPredictableBatch(int numObjects, std::uint64_t seed)
Definition: TestBase.h:80
ripple
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition: RCLCensorshipDetector.h:29
ripple::NodeStore::LessThan::operator()
bool operator()(std::shared_ptr< NodeObject > const &lhs, std::shared_ptr< NodeObject > const &rhs) const noexcept
Definition: TestBase.h:47
ripple::base_uint::begin
iterator begin()
Definition: base_uint.h:106
ripple::NodeStore::TestBase::minPayloadBytes
static const std::size_t minPayloadBytes
Definition: TestBase.h:73
iomanip
beast::rngfill
void rngfill(void *buffer, std::size_t bytes, Generator &g)
Definition: rngfill.h:32
ripple::NodeStore::TestBase::fetchCopyOfBatch
static void fetchCopyOfBatch(Database &db, Batch *pCopy, Batch const &batch)
Definition: TestBase.h:203
ripple::NodeStore::isSame
bool isSame(std::shared_ptr< NodeObject > const &lhs, std::shared_ptr< NodeObject > const &rhs)
Returns true if objects are identical.
Definition: TestBase.h:57
std::size_t
ripple::hotLEDGER
@ hotLEDGER
Definition: NodeObject.h:36
beast::detail::xor_shift_engine
Definition: xor_shift_engine.h:32
ripple::NodeStore::TestBase::storeBatch
void storeBatch(Backend &backend, Batch const &batch)
Definition: TestBase.h:141
std::vector::data
T data(T... args)
ripple::NodeStore::Backend::fetch
virtual Status fetch(void const *key, std::shared_ptr< NodeObject > *pObject)=0
Fetch a single object.
ripple::NodeStore::Backend
A backend used for the NodeStore.
Definition: Backend.h:37