rippled
Workers_test.cpp
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 #include <ripple/basics/PerfLog.h>
21 #include <ripple/beast/unit_test.h>
22 #include <ripple/core/JobTypes.h>
23 #include <ripple/core/impl/Workers.h>
24 #include <ripple/json/json_value.h>
25 #include <chrono>
26 #include <condition_variable>
27 #include <cstdint>
28 #include <memory>
29 #include <mutex>
30 #include <string>
31 
32 namespace ripple {
33 
38 namespace perf {
39 
40 class PerfLogTest : public PerfLog
41 {
42  void
43  rpcStart(std::string const& method, std::uint64_t requestId) override
44  {
45  }
46 
47  void
48  rpcFinish(std::string const& method, std::uint64_t requestId) override
49  {
50  }
51 
52  void
53  rpcError(std::string const& method, std::uint64_t dur) override
54  {
55  }
56 
57  void
58  jobQueue(JobType const type) override
59  {
60  }
61 
62  void
64  JobType const type,
67  int instance) override
68  {
69  }
70 
71  void
72  jobFinish(JobType const type, std::chrono::microseconds dur, int instance)
73  override
74  {
75  }
76 
78  countersJson() const override
79  {
80  return Json::Value();
81  }
82 
84  currentJson() const override
85  {
86  return Json::Value();
87  }
88 
89  void
90  resizeJobs(int const resize) override
91  {
92  }
93 
94  void
95  rotate() override
96  {
97  }
98 };
99 
100 } // namespace perf
101 
102 //------------------------------------------------------------------------------
103 
104 class Workers_test : public beast::unit_test::suite
105 {
106 public:
108  {
109  void
110  processTask(int instance) override
111  {
112  std::lock_guard lk{mut};
113  if (--count == 0)
114  cv.notify_all();
115  }
116 
119  int count = 0;
120  };
121 
122  void
123  testThreads(int const tc1, int const tc2, int const tc3)
124  {
125  testcase(
126  "threadCounts: " + std::to_string(tc1) + " -> " +
127  std::to_string(tc2) + " -> " + std::to_string(tc3));
128 
129  TestCallback cb;
131  std::make_unique<perf::PerfLogTest>();
132 
133  Workers w(cb, perfLog.get(), "Test", tc1);
134  BEAST_EXPECT(w.getNumberOfThreads() == tc1);
135 
136  auto testForThreadCount = [this, &cb, &w](int const threadCount) {
137  // Prepare the callback.
138  cb.count = threadCount;
139 
140  // Execute the test.
141  w.setNumberOfThreads(threadCount);
142  BEAST_EXPECT(w.getNumberOfThreads() == threadCount);
143 
144  for (int i = 0; i < threadCount; ++i)
145  w.addTask();
146 
147  // 10 seconds should be enough to finish on any system
148  //
149  using namespace std::chrono_literals;
151  bool const signaled =
152  cb.cv.wait_for(lk, 10s, [&cb] { return cb.count == 0; });
153  BEAST_EXPECT(signaled);
154  BEAST_EXPECT(cb.count == 0);
155  };
156  testForThreadCount(tc1);
157  testForThreadCount(tc2);
158  testForThreadCount(tc3);
159  w.stop();
160 
161  // We had better finished all our work!
162  BEAST_EXPECT(cb.count == 0);
163  }
164 
165  void
166  run() override
167  {
168  testThreads(0, 0, 0);
169  testThreads(1, 0, 1);
170  testThreads(2, 1, 2);
171  testThreads(4, 3, 5);
172  testThreads(16, 4, 15);
173  testThreads(64, 3, 65);
174  }
175 };
176 
177 BEAST_DEFINE_TESTSUITE(Workers, core, ripple);
178 
179 } // namespace ripple
ripple::Workers_test::run
void run() override
Definition: Workers_test.cpp:166
std::string
STL class.
ripple::BEAST_DEFINE_TESTSUITE
BEAST_DEFINE_TESTSUITE(AccountTxPaging, app, ripple)
ripple::Workers::stop
void stop()
Pause all threads and wait until they are paused.
Definition: Workers.cpp:114
ripple::perf::PerfLogTest::resizeJobs
void resizeJobs(int const resize) override
Ensure enough room to store each currently executing job.
Definition: Workers_test.cpp:90
ripple::Workers_test::testThreads
void testThreads(int const tc1, int const tc2, int const tc3)
Definition: Workers_test.cpp:123
ripple::Workers::getNumberOfThreads
int getNumberOfThreads() const noexcept
Retrieve the desired number of threads.
Definition: Workers.cpp:53
ripple::perf::PerfLogTest::rpcError
void rpcError(std::string const &method, std::uint64_t dur) override
Log errored RPC call.
Definition: Workers_test.cpp:53
std::chrono::microseconds
ripple::perf::PerfLogTest::jobFinish
void jobFinish(JobType const type, std::chrono::microseconds dur, int instance) override
Log job finishing.
Definition: Workers_test.cpp:72
std::unique_ptr::get
T get(T... args)
ripple::Workers::setNumberOfThreads
void setNumberOfThreads(int numberOfThreads)
Set the desired number of threads.
Definition: Workers.cpp:63
std::lock_guard
STL class.
ripple::perf::PerfLog
Singleton class that maintains performance counters and optionally writes Json-formatted data to a di...
Definition: PerfLog.h:48
ripple::perf::PerfLogTest::jobStart
void jobStart(JobType const type, std::chrono::microseconds dur, std::chrono::time_point< std::chrono::steady_clock > startTime, int instance) override
Definition: Workers_test.cpp:63
ripple::Workers::Callback
Called to perform tasks as needed.
Definition: Workers.h:83
ripple::Workers_test::TestCallback::processTask
void processTask(int instance) override
Perform a task.
Definition: Workers_test.cpp:110
ripple::Workers_test::TestCallback::cv
std::condition_variable cv
Definition: Workers_test.cpp:117
ripple::Workers_test::TestCallback::count
int count
Definition: Workers_test.cpp:119
ripple::Workers_test::TestCallback
Definition: Workers_test.cpp:107
ripple::Workers_test::TestCallback::mut
std::mutex mut
Definition: Workers_test.cpp:118
ripple::perf::PerfLogTest::countersJson
Json::Value countersJson() const override
Render performance counters in Json.
Definition: Workers_test.cpp:78
chrono
std::unique_lock
STL class.
std::to_string
T to_string(T... args)
std::chrono::time_point
cstdint
std::uint64_t
memory
ripple::Workers
Workers is effectively a thread pool.
Definition: Workers.h:79
std::condition_variable::wait_for
T wait_for(T... args)
ripple::perf::PerfLogTest::currentJson
Json::Value currentJson() const override
Render currently executing jobs and RPC calls and durations in Json.
Definition: Workers_test.cpp:84
ripple::perf::PerfLogTest
Definition: Workers_test.cpp:40
ripple
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition: RCLCensorshipDetector.h:29
condition_variable
ripple::perf::PerfLogTest::rotate
void rotate() override
Rotate perf log file.
Definition: Workers_test.cpp:95
ripple::Workers::addTask
void addTask()
Add a task to be performed.
Definition: Workers.cpp:126
ripple::Workers_test
Definition: Workers_test.cpp:104
mutex
ripple::JobType
JobType
Definition: Job.h:35
ripple::perf::PerfLogTest::jobQueue
void jobQueue(JobType const type) override
Log queued job.
Definition: Workers_test.cpp:58
ripple::perf::PerfLogTest::rpcFinish
void rpcFinish(std::string const &method, std::uint64_t requestId) override
Log successful finish of RPC call.
Definition: Workers_test.cpp:48
std::unique_ptr
STL class.
std::condition_variable::notify_all
T notify_all(T... args)
ripple::perf::PerfLogTest::rpcStart
void rpcStart(std::string const &method, std::uint64_t requestId) override
Log start of RPC call.
Definition: Workers_test.cpp:43
Json::Value
Represents a JSON value.
Definition: json_value.h:145
string