xrpld
Loading...
Searching...
No Matches
reporter.h
1// Distributed under the Boost Software License, Version 1.0. (See accompanying
2// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
3//
4
5#pragma once
6
7#include <xrpl/beast/unit_test/amount.h>
8#include <xrpl/beast/unit_test/recorder.h>
9
10#include <boost/lexical_cast.hpp>
11#include <boost/optional.hpp>
12
13#include <algorithm>
14#include <chrono>
15#include <iomanip>
16#include <iostream>
17#include <sstream>
18#include <string>
19#include <utility>
20
21namespace beast::unit_test {
22
23namespace detail {
24
28template <class = void>
29class Reporter : public Runner
30{
31private:
33
35 {
39
40 explicit CaseResults(std::string name = "") : name(std::move(name))
41 {
42 }
43 };
44
46 {
51 clock_type::time_point start = clock_type::now();
52
53 explicit SuiteResults(std::string name = "") : name(std::move(name))
54 {
55 }
56
57 void
58 add(CaseResults const& r);
59 };
60
61 struct Results
62 {
64
65 static constexpr auto kMaxTop = 10;
66
72 clock_type::time_point start = clock_type::now();
73
74 void
75 add(SuiteResults const& r);
76 };
77
82
83public:
84 Reporter(Reporter const&) = delete;
86 operator=(Reporter const&) = delete;
87
88 ~Reporter() override;
89
90 explicit Reporter(std::ostream& os = std::cout);
91
92private:
93 static std::string
94 fmtdur(clock_type::duration const& d);
95
96 void
97 onSuiteBegin(SuiteInfo const& info) override;
98
99 void
100 onSuiteEnd() override;
101
102 void
103 onCaseBegin(std::string const& name) override;
104
105 void
106 onCaseEnd() override;
107
108 void
109 onPass() override;
110
111 void
112 onFail(std::string const& reason) override;
113
114 void
115 onLog(std::string const& s) override;
116};
117
118//------------------------------------------------------------------------------
119
120template <class Unused>
121void
123{
124 ++cases;
125 total += r.total;
126 failed += r.failed;
127}
128
129template <class Unused>
130void
132{
133 ++suites;
134 total += r.total;
135 cases += r.cases;
136 failed += r.failed;
137 auto const elapsed = clock_type::now() - r.start;
138 if (elapsed >= std::chrono::seconds{1})
139 {
140 auto const iter = std::lower_bound(
141 top.begin(),
142 top.end(),
143 elapsed,
144 [](run_time const& t1, clock_type::duration const& t2) { return t1.second > t2; });
145 if (iter != top.end())
146 {
147 if (top.size() == kMaxTop)
148 top.resize(top.size() - 1);
149 top.emplace(iter, r.name, elapsed);
150 }
151 else if (top.size() < kMaxTop)
152 {
153 top.emplace_back(r.name, elapsed);
154 }
155 }
156}
157
158//------------------------------------------------------------------------------
159
160template <class Unused>
164
165template <class Unused>
167{
168 if (results_.top.size() > 0)
169 {
170 os_ << "Longest suite times:\n";
171 for (auto const& i : results_.top)
172 os_ << std::setw(8) << fmtdur(i.second) << " " << i.first << '\n';
173 }
174 auto const elapsed = clock_type::now() - results_.start;
175 os_ << fmtdur(elapsed) << ", " << Amount{results_.suites, "suite"} << ", "
176 << Amount{results_.cases, "case"} << ", " << Amount{results_.total, "test"} << " total, "
177 << Amount{results_.failed, "failure"} << std::endl;
178}
179
180template <class Unused>
182Reporter<Unused>::fmtdur(clock_type::duration const& d)
183{
184 using namespace std::chrono;
185 auto const ms = duration_cast<milliseconds>(d);
186 if (ms < seconds{1})
187 return boost::lexical_cast<std::string>(ms.count()) + "ms";
189 ss << std::fixed << std::setprecision(1) << (ms.count() / 1000.) << "s";
190 return ss.str();
191}
192
193template <class Unused>
194void
199
200template <class Unused>
201void
206
207template <class Unused>
208void
210{
212 os_ << suiteResults_.name << (caseResults_.name.empty() ? "" : (" " + caseResults_.name))
213 << std::endl;
214}
215
216template <class Unused>
217void
222
223template <class Unused>
224void
226{
227 ++caseResults_.total;
228}
229
230template <class Unused>
231void
233{
234 ++caseResults_.failed;
235 ++caseResults_.total;
236 os_ << "#" << caseResults_.total << " failed" << (reason.empty() ? "" : ": ") << reason
237 << std::endl;
238}
239
240template <class Unused>
241void
243{
244 os_ << s;
245}
246
247} // namespace detail
248
250
251} // namespace beast::unit_test
Utility for producing nicely composed output of amounts with units.
Associates a unit test type with metadata.
Definition suite_info.h:18
std::string fullName() const
Return the canonical suite name as a string.
Definition suite_info.h:72
A simple test runner that writes everything to a stream in real time.
Definition reporter.h:30
void onSuiteBegin(SuiteInfo const &info) override
Called when a new suite starts.
Definition reporter.h:195
void onFail(std::string const &reason) override
Called for each failing condition.
Definition reporter.h:232
Reporter(Reporter const &)=delete
void onCaseEnd() override
Called when a new case ends.
Definition reporter.h:218
static std::string fmtdur(clock_type::duration const &d)
Definition reporter.h:182
void onSuiteEnd() override
Called when a suite ends.
Definition reporter.h:202
void onPass() override
Called for each passing condition.
Definition reporter.h:225
Reporter & operator=(Reporter const &)=delete
void onCaseBegin(std::string const &name) override
Called when a new case starts.
Definition reporter.h:209
std::chrono::steady_clock clock_type
Definition reporter.h:32
void onLog(std::string const &s) override
Called when a test logs output.
Definition reporter.h:242
T duration_cast(T... args)
T empty(T... args)
T endl(T... args)
T fixed(T... args)
T lower_bound(T... args)
detail::Reporter<> reporter
Definition reporter.h:249
STL namespace.
T setprecision(T... args)
T setw(T... args)
T str(T... args)
void add(SuiteResults const &r)
Definition reporter.h:131
std::pair< std::string, clock_type::duration > run_time
Definition reporter.h:63