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/core/impl/Workers.h>
21 #include <ripple/beast/unit_test.h>
22 #include <ripple/basics/PerfLog.h>
23 #include <ripple/core/JobTypes.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 
41  : public PerfLog
42 {
43  void rpcStart(std::string const &method, std::uint64_t requestId) override
44  {}
45 
46  void rpcFinish(std::string const &method, std::uint64_t requestId) override
47  {}
48 
49  void rpcError(std::string const &method, std::uint64_t dur) override
50  {}
51 
52  void jobQueue(JobType const type) override
53  {}
54 
55  void jobStart(JobType const type,
58  int instance) override
59  {}
60 
62  int instance) override
63  {}
64 
65  Json::Value countersJson() const override
66  {
67  return Json::Value();
68  }
69 
70  Json::Value currentJson() const override
71  {
72  return Json::Value();
73  }
74 
75  void resizeJobs(int const resize) override
76  {}
77 
78  void rotate() override
79  {}
80 };
81 
82 } // perf
83 
84 //------------------------------------------------------------------------------
85 
86 class Workers_test : public beast::unit_test::suite
87 {
88 public:
90  {
91  void processTask(int instance) override
92  {
93  std::lock_guard lk{mut};
94  if (--count == 0)
95  cv.notify_all();
96  }
97 
100  int count = 0;
101  };
102 
103  void testThreads(int const tc1, int const tc2, int const tc3)
104  {
105  testcase("threadCounts: " + std::to_string(tc1) +
106  " -> " + std::to_string(tc2) + " -> " + std::to_string(tc3));
107 
108  TestCallback cb;
110  std::make_unique<perf::PerfLogTest>();
111 
112  Workers w(cb, perfLog.get(), "Test", tc1);
113  BEAST_EXPECT(w.getNumberOfThreads() == tc1);
114 
115  auto testForThreadCount = [this, &cb, &w] (int const threadCount)
116  {
117  // Prepare the callback.
118  cb.count = threadCount;
119 
120  // Execute the test.
121  w.setNumberOfThreads(threadCount);
122  BEAST_EXPECT(w.getNumberOfThreads() == threadCount);
123 
124  for (int i = 0; i < threadCount; ++i)
125  w.addTask();
126 
127  // 10 seconds should be enough to finish on any system
128  //
129  using namespace std::chrono_literals;
131  bool const signaled = cb.cv.wait_for(lk, 10s, [&cb]{return cb.count == 0;});
132  BEAST_EXPECT(signaled);
133  BEAST_EXPECT(cb.count == 0);
134  };
135  testForThreadCount (tc1);
136  testForThreadCount (tc2);
137  testForThreadCount (tc3);
139 
140  // We had better finished all our work!
141  BEAST_EXPECT(cb.count == 0);
142  }
143 
144  void run() override
145  {
146  testThreads( 0, 0, 0);
147  testThreads( 1, 0, 1);
148  testThreads( 2, 1, 2);
149  testThreads( 4, 3, 5);
150  testThreads(16, 4, 15);
151  testThreads(64, 3, 65);
152  }
153 };
154 
155 BEAST_DEFINE_TESTSUITE(Workers, core, ripple);
156 
157 }
ripple::Workers_test::run
void run() override
Definition: Workers_test.cpp:144
std::string
STL class.
ripple::BEAST_DEFINE_TESTSUITE
BEAST_DEFINE_TESTSUITE(AccountTxPaging, app, ripple)
ripple::perf::PerfLogTest::resizeJobs
void resizeJobs(int const resize) override
Ensure enough room to store each currently executing job.
Definition: Workers_test.cpp:75
ripple::Workers_test::testThreads
void testThreads(int const tc1, int const tc2, int const tc3)
Definition: Workers_test.cpp:103
ripple::Workers::getNumberOfThreads
int getNumberOfThreads() const noexcept
Retrieve the desired number of threads.
Definition: Workers.cpp:52
ripple::perf::PerfLogTest::rpcError
void rpcError(std::string const &method, std::uint64_t dur) override
Log errored RPC call.
Definition: Workers_test.cpp:49
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:61
std::unique_ptr::get
T get(T... args)
ripple::Workers::setNumberOfThreads
void setNumberOfThreads(int numberOfThreads)
Set the desired number of threads.
Definition: Workers.cpp:61
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:44
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:55
ripple::Workers::Callback
Called to perform tasks as needed.
Definition: Workers.h:44
ripple::Workers_test::TestCallback::processTask
void processTask(int instance) override
Perform a task.
Definition: Workers_test.cpp:91
ripple::Workers_test::TestCallback::cv
std::condition_variable cv
Definition: Workers_test.cpp:98
ripple::Workers_test::TestCallback::count
int count
Definition: Workers_test.cpp:100
ripple::Workers_test::TestCallback
Definition: Workers_test.cpp:89
ripple::Workers_test::TestCallback::mut
std::mutex mut
Definition: Workers_test.cpp:99
ripple::perf::PerfLogTest::countersJson
Json::Value countersJson() const override
Render performance counters in Json.
Definition: Workers_test.cpp:65
chrono
std::unique_lock
STL class.
std::to_string
T to_string(T... args)
std::chrono::time_point
ripple::Workers::pauseAllThreadsAndWait
void pauseAllThreadsAndWait()
Pause all threads and wait until they are paused.
Definition: Workers.cpp:111
cstdint
std::uint64_t
memory
ripple::Workers
A group of threads that process tasks.
Definition: Workers.h:40
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:70
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:78
ripple::Workers::addTask
void addTask()
Add a task to be performed.
Definition: Workers.cpp:122
ripple::Workers_test
Definition: Workers_test.cpp:86
mutex
ripple::JobType
JobType
Definition: Job.h:33
ripple::perf::PerfLogTest::jobQueue
void jobQueue(JobType const type) override
Log queued job.
Definition: Workers_test.cpp:52
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:46
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:141
string