diff options
author | Anton Samokhvalov <pg83@yandex.ru> | 2022-02-10 16:45:15 +0300 |
---|---|---|
committer | Daniil Cherednik <dcherednik@yandex-team.ru> | 2022-02-10 16:45:15 +0300 |
commit | 72cb13b4aff9bc9cf22e49251bc8fd143f82538f (patch) | |
tree | da2c34829458c7d4e74bdfbdf85dff449e9e7fb8 /library/cpp/testing | |
parent | 778e51ba091dc39e7b7fcab2b9cf4dbedfb6f2b5 (diff) | |
download | ydb-72cb13b4aff9bc9cf22e49251bc8fd143f82538f.tar.gz |
Restoring authorship annotation for Anton Samokhvalov <pg83@yandex.ru>. Commit 1 of 2.
Diffstat (limited to 'library/cpp/testing')
26 files changed, 1381 insertions, 1381 deletions
diff --git a/library/cpp/testing/benchmark/bench.cpp b/library/cpp/testing/benchmark/bench.cpp index 08d8708005..be9bfbad3b 100644 --- a/library/cpp/testing/benchmark/bench.cpp +++ b/library/cpp/testing/benchmark/bench.cpp @@ -1,5 +1,5 @@ -#include "bench.h" - +#include "bench.h" + #include <contrib/libs/re2/re2/re2.h> #include <library/cpp/colorizer/output.h> @@ -7,287 +7,287 @@ #include <library/cpp/json/json_value.h> #include <library/cpp/linear_regression/linear_regression.h> #include <library/cpp/threading/poor_man_openmp/thread_helper.h> - -#include <util/system/hp_timer.h> + +#include <util/system/hp_timer.h> #include <util/system/info.h> -#include <util/stream/output.h> -#include <util/datetime/base.h> -#include <util/random/random.h> -#include <util/string/cast.h> -#include <util/generic/xrange.h> -#include <util/generic/algorithm.h> -#include <util/generic/singleton.h> -#include <util/system/spinlock.h> -#include <util/generic/function.h> -#include <util/generic/maybe.h> -#include <util/generic/strbuf.h> -#include <util/generic/intrlist.h> +#include <util/stream/output.h> +#include <util/datetime/base.h> +#include <util/random/random.h> +#include <util/string/cast.h> +#include <util/generic/xrange.h> +#include <util/generic/algorithm.h> +#include <util/generic/singleton.h> +#include <util/system/spinlock.h> +#include <util/generic/function.h> +#include <util/generic/maybe.h> +#include <util/generic/strbuf.h> +#include <util/generic/intrlist.h> #include <util/stream/format.h> -#include <util/system/yield.h> - +#include <util/system/yield.h> + using re2::RE2; -using namespace NBench; -using namespace NColorizer; -using namespace NLastGetopt; - -namespace { - struct TOptions { - double TimeBudget; - }; - - struct TResult { - TStringBuf TestName; - ui64 Samples; - ui64 Iterations; - TMaybe<double> CyclesPerIteration; - TMaybe<double> SecondsPerIteration; - double RunTime; +using namespace NBench; +using namespace NColorizer; +using namespace NLastGetopt; + +namespace { + struct TOptions { + double TimeBudget; + }; + + struct TResult { + TStringBuf TestName; + ui64 Samples; + ui64 Iterations; + TMaybe<double> CyclesPerIteration; + TMaybe<double> SecondsPerIteration; + double RunTime; size_t TestId; // Sequential test id (zero-based) - }; - - struct ITestRunner: public TIntrusiveListItem<ITestRunner> { + }; + + struct ITestRunner: public TIntrusiveListItem<ITestRunner> { virtual ~ITestRunner() = default; - void Register(); - - virtual TStringBuf Name() const noexcept = 0; - virtual TResult Run(const TOptions& opts) = 0; + void Register(); + + virtual TStringBuf Name() const noexcept = 0; + virtual TResult Run(const TOptions& opts) = 0; size_t SequentialId = 0; - }; - - struct TCpuBenchmark: public ITestRunner { - inline TCpuBenchmark(const char* name, NCpu::TUserFunc func) - : F(func) - , N(name) - { - Register(); - } - + }; + + struct TCpuBenchmark: public ITestRunner { + inline TCpuBenchmark(const char* name, NCpu::TUserFunc func) + : F(func) + , N(name) + { + Register(); + } + TResult Run(const TOptions& opts) override; - + TStringBuf Name() const noexcept override { - return N; - } - - std::function<NCpu::TUserFunc> F; - const TStringBuf N; - }; - + return N; + } + + std::function<NCpu::TUserFunc> F; + const TStringBuf N; + }; + inline TString DoFmtTime(double t) { - if (t > 0.1) { - return ToString(t) + " seconds"; - } - - t *= 1000.0; - - if (t > 0.1) { - return ToString(t) + " milliseconds"; - } - - t *= 1000.0; - - if (t > 0.1) { - return ToString(t) + " microseconds"; - } - - t *= 1000.0; - - if (t < 0.05) { - t = 0.0; - } - - return ToString(t) + " nanoseconds"; - } - - struct THiPerfTimer: public THPTimer { + if (t > 0.1) { + return ToString(t) + " seconds"; + } + + t *= 1000.0; + + if (t > 0.1) { + return ToString(t) + " milliseconds"; + } + + t *= 1000.0; + + if (t > 0.1) { + return ToString(t) + " microseconds"; + } + + t *= 1000.0; + + if (t < 0.05) { + t = 0.0; + } + + return ToString(t) + " nanoseconds"; + } + + struct THiPerfTimer: public THPTimer { static inline TString FmtTime(double t) { - return DoFmtTime(t); - } - }; - - struct TSimpleTimer { - inline double Passed() const noexcept { - return (TInstant::Now() - N).MicroSeconds() / 1000000.0; - } - + return DoFmtTime(t); + } + }; + + struct TSimpleTimer { + inline double Passed() const noexcept { + return (TInstant::Now() - N).MicroSeconds() / 1000000.0; + } + static inline TString FmtTime(double t) { - return DoFmtTime(t); - } - - const TInstant N = TInstant::Now(); - }; - - struct TCycleTimer { - inline ui64 Passed() const noexcept { - return GetCycleCount() - N; - } - + return DoFmtTime(t); + } + + const TInstant N = TInstant::Now(); + }; + + struct TCycleTimer { + inline ui64 Passed() const noexcept { + return GetCycleCount() - N; + } + static inline TString FmtTime(double t) { - if (t < 0.5) { - t = 0.0; - } - + if (t < 0.5) { + t = 0.0; + } + TString hr; if (t > 10 * 1000) { hr = " (" + ToString(HumanReadableSize(t, ESizeFormat::SF_QUANTITY)) + ")"; } return ToString(t) + hr + " cycles"; - } - - const ui64 N = GetCycleCount(); - }; - - template <class TMyTimer, class T> - inline double Measure(T&& t, size_t n) { - TMyTimer timer; - - t(n); - - return timer.Passed(); - } - - struct TSampleIterator { - inline size_t Next() noexcept { - return M++; - - N *= 1.02; - M += 1; - - return Max<double>(N, M); - } - - double N = 1.0; - size_t M = 1; - }; - - using TSample = std::pair<size_t, double>; + } + + const ui64 N = GetCycleCount(); + }; + + template <class TMyTimer, class T> + inline double Measure(T&& t, size_t n) { + TMyTimer timer; + + t(n); + + return timer.Passed(); + } + + struct TSampleIterator { + inline size_t Next() noexcept { + return M++; + + N *= 1.02; + M += 1; + + return Max<double>(N, M); + } + + double N = 1.0; + size_t M = 1; + }; + + using TSample = std::pair<size_t, double>; using TSamples = TVector<TSample>; - - struct TLinFunc { - double A; - double B; - - inline double operator()(double x) const noexcept { - return A * x + B; - } - }; - + + struct TLinFunc { + double A; + double B; + + inline double operator()(double x) const noexcept { + return A * x + B; + } + }; + TLinFunc CalcModel(const TSamples& s) { - TKahanSLRSolver solver; - - for (const auto& p : s) { - solver.Add(p.first, p.second); - } - - double c = 0; - double i = 0; - - solver.Solve(c, i); - - return TLinFunc{c, i}; - } - + TKahanSLRSolver solver; + + for (const auto& p : s) { + solver.Add(p.first, p.second); + } + + double c = 0; + double i = 0; + + solver.Solve(c, i); + + return TLinFunc{c, i}; + } + inline TSamples RemoveOutliers(const TSamples& s, double fraction) { if (s.size() < 20) { - return s; - } - - const auto predictor = CalcModel(s); - - const auto errfunc = [&predictor](const TSample& p) -> double { - //return (1.0 + fabs(predictor(p.first) - p.second)) / (1.0 + fabs(p.second)); - //return fabs((predictor(p.first) - p.second)) / (1.0 + fabs(p.second)); - //return fabs((predictor(p.first) - p.second)) / (1.0 + p.first); - return fabs((predictor(p.first) - p.second)); - }; - - using TSampleWithError = std::pair<const TSample*, double>; + return s; + } + + const auto predictor = CalcModel(s); + + const auto errfunc = [&predictor](const TSample& p) -> double { + //return (1.0 + fabs(predictor(p.first) - p.second)) / (1.0 + fabs(p.second)); + //return fabs((predictor(p.first) - p.second)) / (1.0 + fabs(p.second)); + //return fabs((predictor(p.first) - p.second)) / (1.0 + p.first); + return fabs((predictor(p.first) - p.second)); + }; + + using TSampleWithError = std::pair<const TSample*, double>; TVector<TSampleWithError> v; - + v.reserve(s.size()); - - for (const auto& p : s) { - v.emplace_back(&p, errfunc(p)); - } - - Sort(v.begin(), v.end(), [](const TSampleWithError& l, const TSampleWithError& r) -> bool { - return (l.second < r.second) || ((l.second == r.second) && (l.first < r.first)); - }); - - if (0) { - for (const auto& x : v) { - Cout << x.first->first << ", " << x.first->second << " -> " << x.second << Endl; - } - } - - TSamples ret; - + + for (const auto& p : s) { + v.emplace_back(&p, errfunc(p)); + } + + Sort(v.begin(), v.end(), [](const TSampleWithError& l, const TSampleWithError& r) -> bool { + return (l.second < r.second) || ((l.second == r.second) && (l.first < r.first)); + }); + + if (0) { + for (const auto& x : v) { + Cout << x.first->first << ", " << x.first->second << " -> " << x.second << Endl; + } + } + + TSamples ret; + ret.reserve(v.size()); - + for (const auto i : xrange<size_t>(0, fraction * v.size())) { - ret.push_back(*v[i].first); - } - - return ret; - } - - template <class TMyTimer, class T> - static inline TResult RunTest(T&& func, double budget, ITestRunner& test) { - THPTimer start; - - start.Passed(); - - TSampleIterator sample; - TSamples samples; - ui64 iters = 0; - - //warm up - func(1); - - while (start.Passed() < budget) { + ret.push_back(*v[i].first); + } + + return ret; + } + + template <class TMyTimer, class T> + static inline TResult RunTest(T&& func, double budget, ITestRunner& test) { + THPTimer start; + + start.Passed(); + + TSampleIterator sample; + TSamples samples; + ui64 iters = 0; + + //warm up + func(1); + + while (start.Passed() < budget) { if (start.Passed() < ((budget * samples.size()) / 2000000.0)) { - ThreadYield(); - } else { - const size_t n = sample.Next(); - - iters += (ui64)n; - samples.emplace_back(n, Measure<TMyTimer>(func, n)); - } - } - - auto filtered = RemoveOutliers(samples, 0.9); - + ThreadYield(); + } else { + const size_t n = sample.Next(); + + iters += (ui64)n; + samples.emplace_back(n, Measure<TMyTimer>(func, n)); + } + } + + auto filtered = RemoveOutliers(samples, 0.9); + return {test.Name(), filtered.size(), iters, CalcModel(filtered).A, Nothing(), start.Passed(), test.SequentialId}; - } - - using TTests = TIntrusiveListWithAutoDelete<ITestRunner, TDestructor>; - + } + + using TTests = TIntrusiveListWithAutoDelete<ITestRunner, TDestructor>; + inline TTests& Tests() { - return *Singleton<TTests>(); - } - - void ITestRunner::Register() { - Tests().PushBack(this); - } - - TResult TCpuBenchmark::Run(const TOptions& opts) { - return RunTest<TCycleTimer>([this](size_t n) { - NCpu::TParams params{n}; - - F(params); + return *Singleton<TTests>(); + } + + void ITestRunner::Register() { + Tests().PushBack(this); + } + + TResult TCpuBenchmark::Run(const TOptions& opts) { + return RunTest<TCycleTimer>([this](size_t n) { + NCpu::TParams params{n}; + + F(params); }, opts.TimeBudget, *this); - } + } enum EOutFormat { F_CONSOLE = 0 /* "console" */, - F_CSV /* "csv" */, - F_JSON /* "json" */ + F_CSV /* "csv" */, + F_JSON /* "json" */ }; TAdaptiveLock STDOUT_LOCK; - struct IReporter { + struct IReporter { virtual void Report(TResult&& result) = 0; virtual void Finish() { @@ -297,7 +297,7 @@ namespace { } }; - class TConsoleReporter: public IReporter { + class TConsoleReporter: public IReporter { public: ~TConsoleReporter() override { } @@ -309,7 +309,7 @@ namespace { } }; - class TCSVReporter: public IReporter { + class TCSVReporter: public IReporter { public: TCSVReporter() { Cout << "Name\tSamples\tIterations\tRun_time\tPer_iteration_sec\tPer_iteration_cycles" << Endl; @@ -344,7 +344,7 @@ namespace { } }; - class TJSONReporter: public IReporter { + class TJSONReporter: public IReporter { public: ~TJSONReporter() override { } @@ -427,15 +427,15 @@ namespace { case F_CSV: return MakeHolder<TCSVReporter>(); - + case F_JSON: return MakeHolder<TJSONReporter>(); - - default: - break; + + default: + break; } - - return MakeHolder<TConsoleReporter>(); // make compiler happy + + return MakeHolder<TConsoleReporter>(); // make compiler happy } THolder<IReporter> MakeOrderedReporter(const EOutFormat type) { @@ -447,12 +447,12 @@ namespace { tests[id]->SequentialId = id; } } -} +} template <> EOutFormat FromStringImpl<EOutFormat>(const char* data, size_t len) { const auto s = TStringBuf{data, len}; - + if (TStringBuf("console") == s) { return F_CONSOLE; } else if (TStringBuf("csv") == s) { @@ -462,55 +462,55 @@ EOutFormat FromStringImpl<EOutFormat>(const char* data, size_t len) { } ythrow TFromStringException{} << "failed to convert '" << s << '\''; -} - -template <> +} + +template <> void Out<TResult>(IOutputStream& out, const TResult& r) { - out << "----------- " << LightRed() << r.TestName << Old() << " ---------------" << Endl - << " samples: " << White() << r.Samples << Old() << Endl - << " iterations: " << White() << r.Iterations << Old() << Endl + out << "----------- " << LightRed() << r.TestName << Old() << " ---------------" << Endl + << " samples: " << White() << r.Samples << Old() << Endl + << " iterations: " << White() << r.Iterations << Old() << Endl << " iterations hr: " << White() << HumanReadableSize(r.Iterations, SF_QUANTITY) << Old() << Endl - << " run time: " << White() << r.RunTime << Old() << Endl; - - if (r.CyclesPerIteration) { - out << " per iteration: " << White() << TCycleTimer::FmtTime(*r.CyclesPerIteration) << Old() << Endl; - } - - if (r.SecondsPerIteration) { - out << " per iteration: " << White() << DoFmtTime(*r.SecondsPerIteration) << Old() << Endl; - } -} - -NCpu::TRegistar::TRegistar(const char* name, TUserFunc func) { + << " run time: " << White() << r.RunTime << Old() << Endl; + + if (r.CyclesPerIteration) { + out << " per iteration: " << White() << TCycleTimer::FmtTime(*r.CyclesPerIteration) << Old() << Endl; + } + + if (r.SecondsPerIteration) { + out << " per iteration: " << White() << DoFmtTime(*r.SecondsPerIteration) << Old() << Endl; + } +} + +NCpu::TRegistar::TRegistar(const char* name, TUserFunc func) { static_assert(sizeof(TCpuBenchmark) + alignof(TCpuBenchmark) < sizeof(Buf), "fix Buf size"); - + new (AlignUp(Buf, alignof(TCpuBenchmark))) TCpuBenchmark(name, func); -} - -namespace { - struct TProgOpts { - TProgOpts(int argc, char** argv) { - TOpts opts = TOpts::Default(); - - opts.AddHelpOption(); - - opts.AddLongOption('b', "budget") - .StoreResult(&TimeBudget) +} + +namespace { + struct TProgOpts { + TProgOpts(int argc, char** argv) { + TOpts opts = TOpts::Default(); + + opts.AddHelpOption(); + + opts.AddLongOption('b', "budget") + .StoreResult(&TimeBudget) .RequiredArgument("SEC") - .Optional() - .Help("overall time budget"); - - opts.AddLongOption('l', "list") + .Optional() + .Help("overall time budget"); + + opts.AddLongOption('l', "list") .NoArgument() .StoreValue(&ListTests, true) - .Help("list all tests"); - - opts.AddLongOption('t', "threads") - .StoreResult(&Threads) + .Help("list all tests"); + + opts.AddLongOption('t', "threads") + .StoreResult(&Threads) .OptionalValue(ToString((NSystemInfo::CachedNumberOfCpus() + 1) / 2), "JOBS") .DefaultValue("1") - .Help("run benchmarks in parallel"); - + .Help("run benchmarks in parallel"); + opts.AddLongOption('f', "format") .AddLongName("benchmark_format") .StoreResult(&OutFormat) @@ -521,18 +521,18 @@ namespace { opts.SetFreeArgDefaultTitle("REGEXP", "RE2 regular expression to filter tests"); const TOptsParseResult parseResult{&opts, argc, argv}; - + for (const auto& regexp : parseResult.GetFreeArgs()) { Filters.push_back(MakeHolder<RE2>(regexp.data(), RE2::Quiet)); Y_ENSURE(Filters.back()->ok(), "incorrect RE2 expression '" << regexp << "'"); } - } - - bool MatchFilters(const TStringBuf& name) const { - if (!Filters) { - return true; - } - + } + + bool MatchFilters(const TStringBuf& name) const { + if (!Filters) { + return true; + } + for (auto&& re : Filters) { if (RE2::FullMatchN({name.data(), name.size()}, *re, nullptr, 0)) { return true; @@ -542,50 +542,50 @@ namespace { return false; } - bool ListTests = false; - double TimeBudget = -1.0; + bool ListTests = false; + double TimeBudget = -1.0; TVector<THolder<RE2>> Filters; - size_t Threads = 0; + size_t Threads = 0; EOutFormat OutFormat; - }; -} - + }; +} + int NBench::Main(int argc, char** argv) { const TProgOpts opts(argc, argv); - + TVector<ITestRunner*> tests; for (auto&& it : Tests()) { if (opts.MatchFilters(it.Name())) { tests.push_back(&it); - } + } } EnumerateTests(tests); - + if (opts.ListTests) { for (const auto* const it : tests) { Cout << it->Name() << Endl; - } - + } + return 0; } - + if (!tests) { return 0; } - + double timeBudget = opts.TimeBudget; - + if (timeBudget < 0) { timeBudget = 5.0 * tests.size(); } - + const TOptions testOpts = {timeBudget / tests.size()}; const auto reporter = MakeOrderedReporter(opts.OutFormat); - - std::function<void(ITestRunner**)> func = [&](ITestRunner** it) { + + std::function<void(ITestRunner**)> func = [&](ITestRunner** it) { auto&& res = (*it)->Run(testOpts); - + reporter->Report(std::move(res)); }; @@ -596,9 +596,9 @@ int NBench::Main(int argc, char** argv) { for (auto it : tests) { func(&it); } - } + } reporter->Finish(); return 0; -} +} diff --git a/library/cpp/testing/benchmark/bench.h b/library/cpp/testing/benchmark/bench.h index 21551ad0dd..6f7a9f3f44 100644 --- a/library/cpp/testing/benchmark/bench.h +++ b/library/cpp/testing/benchmark/bench.h @@ -1,29 +1,29 @@ -#pragma once - +#pragma once + #include <util/system/compiler.h> -#include <util/system/types.h> - +#include <util/system/types.h> + #include <utility> -namespace NBench { - namespace NCpu { - struct TParams { - inline size_t Iterations() const noexcept { - return Iterations_; - } - - const size_t Iterations_; - }; - - using TUserFunc = void(TParams&); - - struct TRegistar { - TRegistar(const char* name, TUserFunc func); - - char Buf[128]; - }; - } - +namespace NBench { + namespace NCpu { + struct TParams { + inline size_t Iterations() const noexcept { + return Iterations_; + } + + const size_t Iterations_; + }; + + using TUserFunc = void(TParams&); + + struct TRegistar { + TRegistar(const char* name, TUserFunc func); + + char Buf[128]; + }; + } + /** * Functions that states "I can read and write everywhere in memory". * @@ -42,10 +42,10 @@ namespace NBench { #if defined(__GNUC__) Y_FORCE_INLINE void Clobber() { - asm volatile("" - : - : - : "memory"); + asm volatile("" + : + : + : "memory"); } #elif defined(_MSC_VER) Y_FORCE_INLINE void Clobber() { @@ -60,10 +60,10 @@ namespace NBench { #if defined(__GNUC__) template <typename T> Y_FORCE_INLINE void Escape(T* p) { - asm volatile("" - : - : "g"(p) - : "memory"); + asm volatile("" + : + : "g"(p) + : "memory"); } #else template <typename T> @@ -77,16 +77,16 @@ namespace NBench { * @param Unused variable (e.g. return value of benchmarked function). */ template <typename T> - Y_FORCE_INLINE void DoNotOptimize(T&& datum) { + Y_FORCE_INLINE void DoNotOptimize(T&& datum) { ::DoNotOptimizeAway(std::forward<T>(datum)); - } + } int Main(int argc, char** argv); -} - +} + #define Y_CPU_BENCHMARK(name, cnt) \ namespace N_bench_##name { \ static void Run(::NBench::NCpu::TParams&); \ const ::NBench::NCpu::TRegistar benchmark(#name, &Run); \ } \ - static void N_bench_##name::Run(::NBench::NCpu::TParams& cnt) + static void N_bench_##name::Run(::NBench::NCpu::TParams& cnt) diff --git a/library/cpp/testing/benchmark/examples/main.cpp b/library/cpp/testing/benchmark/examples/main.cpp index ddd8b05ffc..508d12111e 100644 --- a/library/cpp/testing/benchmark/examples/main.cpp +++ b/library/cpp/testing/benchmark/examples/main.cpp @@ -1,186 +1,186 @@ #include <library/cpp/testing/benchmark/bench.h> - -#include <util/generic/xrange.h> -#include <util/generic/algorithm.h> -#include <util/generic/vector.h> -#include <util/generic/yexception.h> -#include <util/generic/bt_exception.h> - -Y_CPU_BENCHMARK(F, iface) { + +#include <util/generic/xrange.h> +#include <util/generic/algorithm.h> +#include <util/generic/vector.h> +#include <util/generic/yexception.h> +#include <util/generic/bt_exception.h> + +Y_CPU_BENCHMARK(F, iface) { TVector<size_t> x; - - x.reserve(iface.Iterations()); - - for (size_t i = 0; i < iface.Iterations(); ++i) { - x.push_back(i); - } -} - -Y_CPU_BENCHMARK(EmptyF, iface) { - (void)iface; -} - -Y_CPU_BENCHMARK(AlmostEmptyF, iface) { - (void)iface; - + + x.reserve(iface.Iterations()); + + for (size_t i = 0; i < iface.Iterations(); ++i) { + x.push_back(i); + } +} + +Y_CPU_BENCHMARK(EmptyF, iface) { + (void)iface; +} + +Y_CPU_BENCHMARK(AlmostEmptyF, iface) { + (void)iface; + TVector<size_t> x; - x.resize(1); -} - -Y_CPU_BENCHMARK(TestThrow, iface) { - for (size_t i = 0; i < iface.Iterations(); ++i) { - try { - ythrow yexception() << i; - } catch (...) { - //CurrentExceptionMessage(); - } - } -} - -Y_CPU_BENCHMARK(TestThrowBT, iface) { - for (size_t i = 0; i < iface.Iterations(); ++i) { - try { - ythrow TWithBackTrace<yexception>() << i; - } catch (...) { - //CurrentExceptionMessage(); - } - } -} - -Y_CPU_BENCHMARK(TestThrowCatch, iface) { - for (size_t i = 0; i < iface.Iterations(); ++i) { - try { - ythrow yexception() << i; - } catch (...) { - Y_DO_NOT_OPTIMIZE_AWAY(CurrentExceptionMessage()); - } - } -} - -Y_CPU_BENCHMARK(TestThrowCatchBT, iface) { - for (size_t i = 0; i < iface.Iterations(); ++i) { - try { - ythrow TWithBackTrace<yexception>() << i; - } catch (...) { - Y_DO_NOT_OPTIMIZE_AWAY(CurrentExceptionMessage()); - } - } -} - -Y_CPU_BENCHMARK(TestRobust, iface) { - if (iface.Iterations() % 100 == 0) { - usleep(100000); - } -} - -Y_CPU_BENCHMARK(IterationSpeed, iface) { - const auto n = iface.Iterations(); - - for (size_t i = 0; i < n; ++i) { - Y_DO_NOT_OPTIMIZE_AWAY(i); - } -} - -Y_CPU_BENCHMARK(XRangeSpeed, iface) { - for (auto i : xrange<size_t>(0, iface.Iterations())) { - Y_DO_NOT_OPTIMIZE_AWAY(i); - } -} - -Y_NO_INLINE int FFF() { - return 0; -} - -Y_NO_INLINE int FFF(int x) { - return x; -} - -Y_NO_INLINE int FFF(int x, int y) { - return x + y; -} - -Y_NO_INLINE size_t FS1(TStringBuf x) { + x.resize(1); +} + +Y_CPU_BENCHMARK(TestThrow, iface) { + for (size_t i = 0; i < iface.Iterations(); ++i) { + try { + ythrow yexception() << i; + } catch (...) { + //CurrentExceptionMessage(); + } + } +} + +Y_CPU_BENCHMARK(TestThrowBT, iface) { + for (size_t i = 0; i < iface.Iterations(); ++i) { + try { + ythrow TWithBackTrace<yexception>() << i; + } catch (...) { + //CurrentExceptionMessage(); + } + } +} + +Y_CPU_BENCHMARK(TestThrowCatch, iface) { + for (size_t i = 0; i < iface.Iterations(); ++i) { + try { + ythrow yexception() << i; + } catch (...) { + Y_DO_NOT_OPTIMIZE_AWAY(CurrentExceptionMessage()); + } + } +} + +Y_CPU_BENCHMARK(TestThrowCatchBT, iface) { + for (size_t i = 0; i < iface.Iterations(); ++i) { + try { + ythrow TWithBackTrace<yexception>() << i; + } catch (...) { + Y_DO_NOT_OPTIMIZE_AWAY(CurrentExceptionMessage()); + } + } +} + +Y_CPU_BENCHMARK(TestRobust, iface) { + if (iface.Iterations() % 100 == 0) { + usleep(100000); + } +} + +Y_CPU_BENCHMARK(IterationSpeed, iface) { + const auto n = iface.Iterations(); + + for (size_t i = 0; i < n; ++i) { + Y_DO_NOT_OPTIMIZE_AWAY(i); + } +} + +Y_CPU_BENCHMARK(XRangeSpeed, iface) { + for (auto i : xrange<size_t>(0, iface.Iterations())) { + Y_DO_NOT_OPTIMIZE_AWAY(i); + } +} + +Y_NO_INLINE int FFF() { + return 0; +} + +Y_NO_INLINE int FFF(int x) { + return x; +} + +Y_NO_INLINE int FFF(int x, int y) { + return x + y; +} + +Y_NO_INLINE size_t FS1(TStringBuf x) { return x.size(); -} - -Y_NO_INLINE size_t FS1_2(TStringBuf x, TStringBuf y) { +} + +Y_NO_INLINE size_t FS1_2(TStringBuf x, TStringBuf y) { return x.size() + y.size(); -} - -Y_NO_INLINE size_t FS2(const TStringBuf& x) { +} + +Y_NO_INLINE size_t FS2(const TStringBuf& x) { return x.size(); -} - -Y_NO_INLINE size_t FS2_2(const TStringBuf& x, const TStringBuf& y) { +} + +Y_NO_INLINE size_t FS2_2(const TStringBuf& x, const TStringBuf& y) { return x.size() + y.size(); -} - -Y_CPU_BENCHMARK(FunctionCallCost_StringBufVal1, iface) { - TStringBuf x; - - for (auto i : xrange<size_t>(0, iface.Iterations())) { - (void)i; +} + +Y_CPU_BENCHMARK(FunctionCallCost_StringBufVal1, iface) { + TStringBuf x; + + for (auto i : xrange<size_t>(0, iface.Iterations())) { + (void)i; NBench::Escape(&x); - Y_DO_NOT_OPTIMIZE_AWAY(FS1(x)); + Y_DO_NOT_OPTIMIZE_AWAY(FS1(x)); NBench::Clobber(); - } -} - -Y_CPU_BENCHMARK(FunctionCallCost_StringBufRef1, iface) { - TStringBuf x; - - for (auto i : xrange<size_t>(0, iface.Iterations())) { - (void)i; + } +} + +Y_CPU_BENCHMARK(FunctionCallCost_StringBufRef1, iface) { + TStringBuf x; + + for (auto i : xrange<size_t>(0, iface.Iterations())) { + (void)i; NBench::Escape(&x); - Y_DO_NOT_OPTIMIZE_AWAY(FS2(x)); + Y_DO_NOT_OPTIMIZE_AWAY(FS2(x)); NBench::Clobber(); - } -} - -Y_CPU_BENCHMARK(FunctionCallCost_StringBufVal2, iface) { - TStringBuf x; - TStringBuf y; - - for (auto i : xrange<size_t>(0, iface.Iterations())) { - (void)i; + } +} + +Y_CPU_BENCHMARK(FunctionCallCost_StringBufVal2, iface) { + TStringBuf x; + TStringBuf y; + + for (auto i : xrange<size_t>(0, iface.Iterations())) { + (void)i; NBench::Escape(&x); NBench::Escape(&y); - Y_DO_NOT_OPTIMIZE_AWAY(FS1_2(x, y)); + Y_DO_NOT_OPTIMIZE_AWAY(FS1_2(x, y)); NBench::Clobber(); - } -} - -Y_CPU_BENCHMARK(FunctionCallCost_StringBufRef2, iface) { - TStringBuf x; - TStringBuf y; - - for (auto i : xrange<size_t>(0, iface.Iterations())) { - (void)i; + } +} + +Y_CPU_BENCHMARK(FunctionCallCost_StringBufRef2, iface) { + TStringBuf x; + TStringBuf y; + + for (auto i : xrange<size_t>(0, iface.Iterations())) { + (void)i; NBench::Escape(&x); NBench::Escape(&y); - Y_DO_NOT_OPTIMIZE_AWAY(FS2_2(x, y)); + Y_DO_NOT_OPTIMIZE_AWAY(FS2_2(x, y)); NBench::Clobber(); - } -} - -Y_CPU_BENCHMARK(FunctionCallCost_NoArg, iface) { - for (auto i : xrange<size_t>(0, iface.Iterations())) { - (void)i; - Y_DO_NOT_OPTIMIZE_AWAY(FFF()); - } -} - -Y_CPU_BENCHMARK(FunctionCallCost_OneArg, iface) { - for (auto i : xrange<size_t>(0, iface.Iterations())) { - Y_DO_NOT_OPTIMIZE_AWAY(FFF(i)); - } -} - -Y_CPU_BENCHMARK(FunctionCallCost_TwoArg, iface) { - for (auto i : xrange<size_t>(0, iface.Iterations())) { - Y_DO_NOT_OPTIMIZE_AWAY(FFF(i, i)); - } -} + } +} + +Y_CPU_BENCHMARK(FunctionCallCost_NoArg, iface) { + for (auto i : xrange<size_t>(0, iface.Iterations())) { + (void)i; + Y_DO_NOT_OPTIMIZE_AWAY(FFF()); + } +} + +Y_CPU_BENCHMARK(FunctionCallCost_OneArg, iface) { + for (auto i : xrange<size_t>(0, iface.Iterations())) { + Y_DO_NOT_OPTIMIZE_AWAY(FFF(i)); + } +} + +Y_CPU_BENCHMARK(FunctionCallCost_TwoArg, iface) { + for (auto i : xrange<size_t>(0, iface.Iterations())) { + Y_DO_NOT_OPTIMIZE_AWAY(FFF(i, i)); + } +} /* An example of incorrect benchmark. As of r2581591 Clang 3.7 produced following assembly: * @code diff --git a/library/cpp/testing/benchmark/examples/ya.make b/library/cpp/testing/benchmark/examples/ya.make index 7e696e127a..c5c435ce10 100644 --- a/library/cpp/testing/benchmark/examples/ya.make +++ b/library/cpp/testing/benchmark/examples/ya.make @@ -4,9 +4,9 @@ OWNER( ) Y_BENCHMARK() - -SRCS( - main.cpp -) - -END() + +SRCS( + main.cpp +) + +END() diff --git a/library/cpp/testing/benchmark/main/main.cpp b/library/cpp/testing/benchmark/main/main.cpp index aabcb89c43..3ef4a4f348 100644 --- a/library/cpp/testing/benchmark/main/main.cpp +++ b/library/cpp/testing/benchmark/main/main.cpp @@ -8,9 +8,9 @@ int main(int argc, char** argv) { try { return NBench::Main(argc, argv); - } catch (...) { + } catch (...) { Cerr << CurrentExceptionMessage() << Endl; } - - return EXIT_FAILURE; + + return EXIT_FAILURE; } diff --git a/library/cpp/testing/benchmark/main/ya.make b/library/cpp/testing/benchmark/main/ya.make index d00cdcf9fc..9a088cfcea 100644 --- a/library/cpp/testing/benchmark/main/ya.make +++ b/library/cpp/testing/benchmark/main/ya.make @@ -6,7 +6,7 @@ OWNER( ) SRCS( - GLOBAL main.cpp + GLOBAL main.cpp ) PEERDIR( diff --git a/library/cpp/testing/benchmark/ya.make b/library/cpp/testing/benchmark/ya.make index f42be80698..a2c23a50fb 100644 --- a/library/cpp/testing/benchmark/ya.make +++ b/library/cpp/testing/benchmark/ya.make @@ -1,12 +1,12 @@ -LIBRARY() - +LIBRARY() + OWNER( pg yazevnul ) SRCS( - bench.cpp + bench.cpp dummy.cpp ) diff --git a/library/cpp/testing/gmock_in_unittest/gmock.h b/library/cpp/testing/gmock_in_unittest/gmock.h index 31f6aee1c3..5406c58e6e 100644 --- a/library/cpp/testing/gmock_in_unittest/gmock.h +++ b/library/cpp/testing/gmock_in_unittest/gmock.h @@ -1,5 +1,5 @@ #pragma once - + #include <library/cpp/testing/gtest_extensions/gtest_extensions.h> #include <gmock/gmock.h> diff --git a/library/cpp/testing/gmock_in_unittest/registration.cpp b/library/cpp/testing/gmock_in_unittest/registration.cpp index c2872a4c27..e6186a1bc6 100644 --- a/library/cpp/testing/gmock_in_unittest/registration.cpp +++ b/library/cpp/testing/gmock_in_unittest/registration.cpp @@ -17,4 +17,4 @@ namespace { NUnitTest::NPlugin::TPluginRegistrator registerGMock(new TGMockUnittestPlugin()); -} +} diff --git a/library/cpp/testing/unittest/checks.cpp b/library/cpp/testing/unittest/checks.cpp index c5712ae9d2..95baf5c9c2 100644 --- a/library/cpp/testing/unittest/checks.cpp +++ b/library/cpp/testing/unittest/checks.cpp @@ -6,7 +6,7 @@ bool CheckExceptionMessage(const char* msg, TString& err) { // Операция успешно завершена [cp1251] "\xce\xef\xe5\xf0\xe0\xf6\xe8\xff\x20\xf3\xf1\xef\xe5\xf8\xed\xee\x20\xe7\xe0\xe2\xe5\xf0\xf8\xe5\xed\xe0", "The operation completed successfully", - "No error"}; + "No error"}; err.clear(); diff --git a/library/cpp/testing/unittest/env.h b/library/cpp/testing/unittest/env.h index 4807539ab2..568a1c8e8f 100644 --- a/library/cpp/testing/unittest/env.h +++ b/library/cpp/testing/unittest/env.h @@ -1,3 +1,3 @@ // just shortcut #include <library/cpp/testing/common/env.h> - + diff --git a/library/cpp/testing/unittest/example_ut.cpp b/library/cpp/testing/unittest/example_ut.cpp index bcc1ce33f0..52790f1fc6 100644 --- a/library/cpp/testing/unittest/example_ut.cpp +++ b/library/cpp/testing/unittest/example_ut.cpp @@ -1,12 +1,12 @@ #include <library/cpp/testing/unittest/registar.h> - -/* - * just copy-paste it for good start point - */ - + +/* + * just copy-paste it for good start point + */ + Y_UNIT_TEST_SUITE(TUnitTest) { Y_UNIT_TEST(TestEqual) { - UNIT_ASSERT_EQUAL(0, 0); - UNIT_ASSERT_EQUAL(1, 1); - } -} + UNIT_ASSERT_EQUAL(0, 0); + UNIT_ASSERT_EQUAL(1, 1); + } +} diff --git a/library/cpp/testing/unittest/gtest.cpp b/library/cpp/testing/unittest/gtest.cpp index ebad1ea4d6..38f29dcdf8 100644 --- a/library/cpp/testing/unittest/gtest.cpp +++ b/library/cpp/testing/unittest/gtest.cpp @@ -1,67 +1,67 @@ -#include "gtest.h" +#include "gtest.h" #include "simple.h" - -#include <util/generic/map.h> -#include <util/generic/vector.h> + +#include <util/generic/map.h> +#include <util/generic/vector.h> #include <util/system/type_name.h> - -using namespace NUnitTest; -using namespace NUnitTest::NPrivate; - + +using namespace NUnitTest; +using namespace NUnitTest::NPrivate; + IGTestFactory::~IGTestFactory() { -} - -namespace { +} + +namespace { struct TCurrentTest: public TSimpleTestExecutor { - inline TCurrentTest(TStringBuf name) - : MyName(name) - { - } - + inline TCurrentTest(TStringBuf name) + : MyName(name) + { + } + TString TypeId() const override { return TypeName(*this) + "-" + MyName; - } - + } + TString Name() const noexcept override { return TString(MyName); - } - - const TStringBuf MyName; - }; - - struct TGTestFactory: public IGTestFactory { - inline TGTestFactory(TStringBuf name) - : Test(name) - { - } - + } + + const TStringBuf MyName; + }; + + struct TGTestFactory: public IGTestFactory { + inline TGTestFactory(TStringBuf name) + : Test(name) + { + } + ~TGTestFactory() override { - } - + } + TString Name() const noexcept override { - return Test.Name(); - } - + return Test.Name(); + } + TTestBase* ConstructTest() override { - return new TCurrentTest(Test); - } - + return new TCurrentTest(Test); + } + void AddTest(const char* name, void (*body)(TTestContext&), bool forceFork) override { Test.Tests.push_back(TBaseTestCase(name, body, forceFork)); - } - - TCurrentTest Test; - }; -} - -IGTestFactory* NUnitTest::NPrivate::ByName(const char* name) { + } + + TCurrentTest Test; + }; +} + +IGTestFactory* NUnitTest::NPrivate::ByName(const char* name) { static TMap<TStringBuf, TAutoPtr<TGTestFactory>> tests; - - auto& ret = tests[name]; - - if (!ret) { - ret = new TGTestFactory(name); - } - - return ret.Get(); -} + + auto& ret = tests[name]; + + if (!ret) { + ret = new TGTestFactory(name); + } + + return ret.Get(); +} diff --git a/library/cpp/testing/unittest/gtest.h b/library/cpp/testing/unittest/gtest.h index b6768b1bf0..9db9e89757 100644 --- a/library/cpp/testing/unittest/gtest.h +++ b/library/cpp/testing/unittest/gtest.h @@ -1,108 +1,108 @@ -#pragma once - +#pragma once + // WARNING: this is a legacy header that tries to mimic the gtest interface while using unittest // under the hood. Avoid using this interface -- use the genuine gtest instead (the GTEST macro). // If you're already using GTEST macro and you've found yourself here, you probably meant // to include `library/cpp/testing/gtest/gtest.h`. -#include "registar.h" - -#include <util/generic/ymath.h> -#include <util/generic/ylimits.h> - -namespace NUnitTest { - namespace NPrivate { - struct IGTestFactory: public ITestBaseFactory { +#include "registar.h" + +#include <util/generic/ymath.h> +#include <util/generic/ylimits.h> + +namespace NUnitTest { + namespace NPrivate { + struct IGTestFactory: public ITestBaseFactory { ~IGTestFactory() override; - + virtual void AddTest(const char* name, void (*body)(TTestContext&), bool forceFork) = 0; - }; - - IGTestFactory* ByName(const char* name); - } -} - -namespace NTesting { - struct TTest { - virtual void SetUp() { - } - - virtual void TearDown() { - } - + }; + + IGTestFactory* ByName(const char* name); + } +} + +namespace NTesting { + struct TTest { + virtual void SetUp() { + } + + virtual void TearDown() { + } + inline TTest* _This() noexcept { - return this; - } - }; -} - -namespace testing { - struct Test: public ::NTesting::TTest { - }; -} - -#define TEST_IMPL(N, NN, FF) \ + return this; + } + }; +} + +namespace testing { + struct Test: public ::NTesting::TTest { + }; +} + +#define TEST_IMPL(N, NN, FF) \ void Test##N##NN(NUnitTest::TTestContext&); \ - namespace NTestSuite##N##NN { \ - struct TReg { \ - inline TReg() { \ - ::NUnitTest::NPrivate::ByName(#N)->AddTest(#NN, &(Test##N##NN), FF); \ - } \ - }; \ - static TReg reg; \ - } \ + namespace NTestSuite##N##NN { \ + struct TReg { \ + inline TReg() { \ + ::NUnitTest::NPrivate::ByName(#N)->AddTest(#NN, &(Test##N##NN), FF); \ + } \ + }; \ + static TReg reg; \ + } \ void Test##N##NN(NUnitTest::TTestContext&) - -#define TEST_F_IMPL(N, NN, FF) \ - namespace NTestSuite##N##NN { \ - struct TTestSuite: public N { \ - inline TTestSuite() { \ - this->_This()->SetUp(); \ - } \ - inline ~TTestSuite() { \ - this->_This()->TearDown(); \ - } \ - void NN(); \ - }; \ - }; \ - TEST_IMPL(N, NN, FF) { \ - NTestSuite##N##NN::TTestSuite().NN(); \ - } \ - void NTestSuite##N##NN::TTestSuite::NN() - -#define TEST(A, B) TEST_IMPL(A, B, false) -#define TEST_FORKED(A, B) TEST_IMPL(A, B, true) - -#define TEST_F(A, B) TEST_F_IMPL(A, B, false) -#define TEST_F_FORKED(A, B) TEST_F_IMPL(A, B, true) - -#define EXPECT_EQ(A, B) UNIT_ASSERT_VALUES_EQUAL(A, B) -#define EXPECT_NE(A, B) UNIT_ASSERT_UNEQUAL(A, B) + +#define TEST_F_IMPL(N, NN, FF) \ + namespace NTestSuite##N##NN { \ + struct TTestSuite: public N { \ + inline TTestSuite() { \ + this->_This()->SetUp(); \ + } \ + inline ~TTestSuite() { \ + this->_This()->TearDown(); \ + } \ + void NN(); \ + }; \ + }; \ + TEST_IMPL(N, NN, FF) { \ + NTestSuite##N##NN::TTestSuite().NN(); \ + } \ + void NTestSuite##N##NN::TTestSuite::NN() + +#define TEST(A, B) TEST_IMPL(A, B, false) +#define TEST_FORKED(A, B) TEST_IMPL(A, B, true) + +#define TEST_F(A, B) TEST_F_IMPL(A, B, false) +#define TEST_F_FORKED(A, B) TEST_F_IMPL(A, B, true) + +#define EXPECT_EQ(A, B) UNIT_ASSERT_VALUES_EQUAL(A, B) +#define EXPECT_NE(A, B) UNIT_ASSERT_UNEQUAL(A, B) #define EXPECT_LE(A, B) UNIT_ASSERT((A) <= (B)) -#define EXPECT_LT(A, B) UNIT_ASSERT((A) < (B)) +#define EXPECT_LT(A, B) UNIT_ASSERT((A) < (B)) #define EXPECT_GE(A, B) UNIT_ASSERT((A) >= (B)) -#define EXPECT_GT(A, B) UNIT_ASSERT((A) > (B)) -#define EXPECT_NO_THROW(A) UNIT_ASSERT_NO_EXCEPTION(A) -#define EXPECT_THROW(A, B) UNIT_ASSERT_EXCEPTION(A, B) -#define EXPECT_NEAR(A, B, D) UNIT_ASSERT_DOUBLES_EQUAL(A, B, D) -#define EXPECT_STREQ(A, B) UNIT_ASSERT_VALUES_EQUAL(A, B) - +#define EXPECT_GT(A, B) UNIT_ASSERT((A) > (B)) +#define EXPECT_NO_THROW(A) UNIT_ASSERT_NO_EXCEPTION(A) +#define EXPECT_THROW(A, B) UNIT_ASSERT_EXCEPTION(A, B) +#define EXPECT_NEAR(A, B, D) UNIT_ASSERT_DOUBLES_EQUAL(A, B, D) +#define EXPECT_STREQ(A, B) UNIT_ASSERT_VALUES_EQUAL(A, B) + #define EXPECT_DOUBLE_EQ_TOLERANCE(A, B, tolerance) UNIT_ASSERT_C(fabs((A) - (B)) < tolerance * std::numeric_limits<decltype(A)>::epsilon(), TString("\n") + ToString(A) + " <> " + ToString(B)) #define EXPECT_DOUBLE_EQ(A, B) EXPECT_DOUBLE_EQ_TOLERANCE(A, B, 4.0) - -//conflicts with util/system/defaults.h -#undef EXPECT_TRUE -#define EXPECT_TRUE(X) UNIT_ASSERT(X) -#undef EXPECT_FALSE -#define EXPECT_FALSE(X) UNIT_ASSERT(!(X)) - -#define ASSERT_EQ(A, B) EXPECT_EQ(A, B) -#define ASSERT_NE(A, B) EXPECT_NE(A, B) -#define ASSERT_GT(A, B) EXPECT_GT(A, B) -#define ASSERT_LT(A, B) EXPECT_LT(A, B) -#define ASSERT_FALSE(X) EXPECT_FALSE(X) -#define ASSERT_TRUE(X) EXPECT_TRUE(X) -#define ASSERT_THROW(A, B) EXPECT_THROW(A, B) -#define ASSERT_NO_THROW(A) EXPECT_NO_THROW(A) -#define ASSERT_DOUBLE_EQ(A, B) EXPECT_DOUBLE_EQ(A, B) -#define ASSERT_STREQ(A, B) EXPECT_STREQ(A, B) + +//conflicts with util/system/defaults.h +#undef EXPECT_TRUE +#define EXPECT_TRUE(X) UNIT_ASSERT(X) +#undef EXPECT_FALSE +#define EXPECT_FALSE(X) UNIT_ASSERT(!(X)) + +#define ASSERT_EQ(A, B) EXPECT_EQ(A, B) +#define ASSERT_NE(A, B) EXPECT_NE(A, B) +#define ASSERT_GT(A, B) EXPECT_GT(A, B) +#define ASSERT_LT(A, B) EXPECT_LT(A, B) +#define ASSERT_FALSE(X) EXPECT_FALSE(X) +#define ASSERT_TRUE(X) EXPECT_TRUE(X) +#define ASSERT_THROW(A, B) EXPECT_THROW(A, B) +#define ASSERT_NO_THROW(A) EXPECT_NO_THROW(A) +#define ASSERT_DOUBLE_EQ(A, B) EXPECT_DOUBLE_EQ(A, B) +#define ASSERT_STREQ(A, B) EXPECT_STREQ(A, B) diff --git a/library/cpp/testing/unittest/plugin.cpp b/library/cpp/testing/unittest/plugin.cpp index 543112f7ac..f03484a089 100644 --- a/library/cpp/testing/unittest/plugin.cpp +++ b/library/cpp/testing/unittest/plugin.cpp @@ -46,5 +46,5 @@ namespace NUnitTest { TPlugins::Instance().OnStopMain(argc, argv); } - } -} + } +} diff --git a/library/cpp/testing/unittest/plugin.h b/library/cpp/testing/unittest/plugin.h index 102f2c1469..f030654f97 100644 --- a/library/cpp/testing/unittest/plugin.h +++ b/library/cpp/testing/unittest/plugin.h @@ -25,5 +25,5 @@ namespace NUnitTest { TPluginRegistrator(TSimpleSharedPtr<IPlugin> plugin); }; - } -} + } +} diff --git a/library/cpp/testing/unittest/registar.cpp b/library/cpp/testing/unittest/registar.cpp index 3679b768ed..606e18cefd 100644 --- a/library/cpp/testing/unittest/registar.cpp +++ b/library/cpp/testing/unittest/registar.cpp @@ -11,27 +11,27 @@ #include <util/system/tls.h> #include <util/system/error.h> #include <util/string/cast.h> - + bool NUnitTest::ShouldColorizeDiff = true; bool NUnitTest::ContinueOnFail = false; TString NUnitTest::RandomString(size_t len, ui32 seed) { - TReallyFastRng32 rand(seed); + TReallyFastRng32 rand(seed); TString ret; - - ret.reserve(len); - - for (size_t i = 0; i < len; ++i) { - ret.push_back(char(rand.Uniform(1, 128))); - } - - return ret; -} - -Y_POD_STATIC_THREAD(bool) -UnittestThread; -Y_POD_STATIC_THREAD(NUnitTest::TTestBase*) -currentTest; + + ret.reserve(len); + + for (size_t i = 0; i < len; ++i) { + ret.push_back(char(rand.Uniform(1, 128))); + } + + return ret; +} + +Y_POD_STATIC_THREAD(bool) +UnittestThread; +Y_POD_STATIC_THREAD(NUnitTest::TTestBase*) +currentTest; ::NUnitTest::TRaiseErrorHandler RaiseErrorHandler; void ::NUnitTest::NPrivate::RaiseError(const char* what, const TString& msg, bool fatalFailure) { @@ -78,8 +78,8 @@ struct TDiffColorizer { explicit TDiffColorizer(bool reverse = false) : Reverse(reverse) - { - } + { + } TString Special(TStringBuf str) const { return ToString(Colors.YellowColor()) + str; @@ -111,8 +111,8 @@ struct TTraceDiffFormatter { explicit TTraceDiffFormatter(bool reverse = false) : Reverse(reverse) - { - } + { + } TString Special(TStringBuf str) const { return ToString(str); @@ -124,14 +124,14 @@ struct TTraceDiffFormatter { TString Left(TArrayRef<const char> str) const { return NUnitTest::GetFormatTag("good") + - TString(str.begin(), str.end()) + - NUnitTest::GetResetTag(); + TString(str.begin(), str.end()) + + NUnitTest::GetResetTag(); } TString Right(TArrayRef<const char> str) const { return NUnitTest::GetFormatTag("bad") + - TString(str.begin(), str.end()) + - NUnitTest::GetResetTag(); + TString(str.begin(), str.end()) + + NUnitTest::GetResetTag(); } }; @@ -149,7 +149,7 @@ TString NUnitTest::ColoredDiff(TStringBuf s1, TStringBuf s2, const TString& deli NDiff::InlineDiff(chunks, s1, s2, delims); if (NUnitTest::ShouldColorizeDiff) { NDiff::PrintChunks(res, TDiffColorizer(reverse), chunks); - } else { + } else { res << NUnitTest::GetResetTag(); NDiff::PrintChunks(res, TTraceDiffFormatter(reverse), chunks); } @@ -290,10 +290,10 @@ void NUnitTest::ITestBaseFactory::Register() noexcept { } NUnitTest::TTestBase::TTestBase() noexcept - : Parent_(nullptr) - , TestErrors_() - , CurrentSubtest_() -{ + : Parent_(nullptr) + , TestErrors_() + , CurrentSubtest_() +{ } NUnitTest::TTestBase::~TTestBase() = default; diff --git a/library/cpp/testing/unittest/registar.h b/library/cpp/testing/unittest/registar.h index 44517a0092..3307ba7e55 100644 --- a/library/cpp/testing/unittest/registar.h +++ b/library/cpp/testing/unittest/registar.h @@ -1,20 +1,20 @@ #pragma once - + #include <library/cpp/dbg_output/dump.h> - + #include <util/generic/bt_exception.h> #include <util/generic/hash.h> #include <util/generic/intrlist.h> #include <util/generic/map.h> #include <util/generic/ptr.h> #include <util/generic/set.h> -#include <util/generic/typetraits.h> +#include <util/generic/typetraits.h> #include <util/generic/vector.h> #include <util/generic/yexception.h> - -#include <util/string/builder.h> -#include <util/string/cast.h> -#include <util/string/printf.h> + +#include <util/string/builder.h> +#include <util/string/cast.h> +#include <util/string/printf.h> #include <util/system/defaults.h> #include <util/system/type_name.h> @@ -23,21 +23,21 @@ #include <util/system/rusage.h> -#include <cmath> -#include <cstdio> +#include <cmath> +#include <cstdio> #include <functional> extern bool CheckExceptionMessage(const char*, TString&); + +namespace NUnitTest { + class TTestBase; -namespace NUnitTest { - class TTestBase; - - namespace NPrivate { + namespace NPrivate { void RaiseError(const char* what, const TString& msg, bool fatalFailure); - void SetUnittestThread(bool); + void SetUnittestThread(bool); void SetCurrentTest(TTestBase*); TTestBase* GetCurrentTest(); - } + } extern bool ShouldColorizeDiff; extern bool ContinueOnFail; @@ -64,13 +64,13 @@ namespace NUnitTest { struct TTestContext { TTestContext() - : Processor(nullptr) - { + : Processor(nullptr) + { } explicit TTestContext(ITestSuiteProcessor* processor) - : Processor(processor) - { + : Processor(processor) + { } using TMetrics = THashMap<TString, double>; @@ -79,59 +79,59 @@ namespace NUnitTest { ITestSuiteProcessor* Processor; }; - class ITestSuiteProcessor { - public: - struct TUnit { + class ITestSuiteProcessor { + public: + struct TUnit { const TString name; - }; - - struct TTest { + }; + + struct TTest { const TUnit* unit; const char* name; - }; - - struct TError { + }; + + struct TError { const TTest* test; const char* msg; TString BackTrace; TTestContext* Context; - }; - + }; + struct TFinish { const TTest* test; TTestContext* Context; bool Success; - }; - + }; + ITestSuiteProcessor(); - + virtual ~ITestSuiteProcessor(); - + void Start(); - + void End(); - + void UnitStart(const TUnit& unit); - + void UnitStop(const TUnit& unit); - + void Error(const TError& descr); - + void BeforeTest(const TTest& test); - + void Finish(const TFinish& descr); - + unsigned GoodTests() const noexcept; unsigned FailTests() const noexcept; - + unsigned GoodTestsInCurrentUnit() const noexcept; - + unsigned FailTestsInCurrentUnit() const noexcept; - + // Should execute test suite? virtual bool CheckAccess(TString /*name*/, size_t /*num*/); - + // Should execute a test whitin suite? virtual bool CheckAccessTest(TString /*suite*/, const char* /*name*/); @@ -143,142 +143,142 @@ namespace NUnitTest { // --fork-tests is set (warning: this may be false, but never the less test will be forked if called inside UNIT_FORKED_TEST) virtual bool GetForkTests() const; - private: + private: virtual void OnStart(); - + virtual void OnEnd(); - + virtual void OnUnitStart(const TUnit* /*unit*/); - + virtual void OnUnitStop(const TUnit* /*unit*/); - + virtual void OnError(const TError* /*error*/); - + virtual void OnFinish(const TFinish* /*finish*/); - + virtual void OnBeforeTest(const TTest* /*test*/); void AddTestError(const TTest& test); void AddTestFinish(const TTest& test); - private: + private: TMap<TString, size_t> TestErrors_; TMap<TString, size_t> CurTestErrors_; - }; - - class TTestBase; - class TTestFactory; - - class ITestBaseFactory: public TIntrusiveListItem<ITestBaseFactory> { - public: + }; + + class TTestBase; + class TTestFactory; + + class ITestBaseFactory: public TIntrusiveListItem<ITestBaseFactory> { + public: ITestBaseFactory(); - + virtual ~ITestBaseFactory(); - + // name of test suite virtual TString Name() const noexcept = 0; - virtual TTestBase* ConstructTest() = 0; - - private: + virtual TTestBase* ConstructTest() = 0; + + private: void Register() noexcept; - }; - - class TTestBase { - friend class TTestFactory; + }; + + class TTestBase { + friend class TTestFactory; TRusage rusage; - - public: + + public: TTestBase() noexcept; - + virtual ~TTestBase(); - + virtual TString TypeId() const; - + virtual TString Name() const noexcept = 0; - virtual void Execute() = 0; - + virtual void Execute() = 0; + virtual void SetUp(); - + virtual void TearDown(); - + void AddError(const char* msg, const TString& backtrace = TString(), TTestContext* context = nullptr); void AddError(const char* msg, TTestContext* context); void RunAfterTest(std::function<void()> f); // function like atexit to run after current unit test - protected: + protected: bool CheckAccessTest(const char* test); void BeforeTest(const char* func); void Finish(const char* func, TTestContext* context); - + void AtStart(); - + void AtEnd(); - + void Run(std::function<void()> f, const TString& suite, const char* name, bool forceFork); - - class TCleanUp { - public: + + class TCleanUp { + public: explicit TCleanUp(TTestBase* base); - + ~TCleanUp(); - - private: - TTestBase* Base_; - }; - + + private: + TTestBase* Base_; + }; + void BeforeTest(); - + void AfterTest(); - + bool GetIsForked() const; bool GetForkTests() const; ITestSuiteProcessor* Processor() const noexcept; - - private: - TTestFactory* Parent_; + + private: + TTestFactory* Parent_; size_t TestErrors_; const char* CurrentSubtest_; TAdaptiveLock AfterTestFunctionsLock_; TVector<std::function<void()>> AfterTestFunctions_; - }; - -#define UNIT_TEST_SUITE(N) \ - typedef N TThisUnitTestSuite; \ - \ -public: \ - static TString StaticName() noexcept { \ - return TString(#N); \ - } \ - \ -private: \ - virtual TString Name() const noexcept override { \ - return this->StaticName(); \ - } \ - \ - virtual void Execute() override { \ - this->AtStart(); - -#define UNIT_TEST_SUITE_DEMANGLE(N) \ - typedef N TThisUnitTestSuite; \ - \ -public: \ - static TString StaticName() noexcept { \ + }; + +#define UNIT_TEST_SUITE(N) \ + typedef N TThisUnitTestSuite; \ + \ +public: \ + static TString StaticName() noexcept { \ + return TString(#N); \ + } \ + \ +private: \ + virtual TString Name() const noexcept override { \ + return this->StaticName(); \ + } \ + \ + virtual void Execute() override { \ + this->AtStart(); + +#define UNIT_TEST_SUITE_DEMANGLE(N) \ + typedef N TThisUnitTestSuite; \ + \ +public: \ + static TString StaticName() noexcept { \ return TypeName<N>(); \ - } \ - \ -private: \ - virtual TString Name() const noexcept override { \ - return this->StaticName(); \ - } \ - \ - virtual void Execute() override { \ + } \ + \ +private: \ + virtual TString Name() const noexcept override { \ + return this->StaticName(); \ + } \ + \ + virtual void Execute() override { \ this->AtStart(); #ifndef UT_SKIP_EXCEPTIONS @@ -289,21 +289,21 @@ private: \ #define CATCH_REACTION_BT(FN, e, context) throw #endif -#define UNIT_TEST_CHECK_TEST_IS_DECLARED_ONLY_ONCE(F) \ +#define UNIT_TEST_CHECK_TEST_IS_DECLARED_ONLY_ONCE(F) \ /* If you see this message - delete multiple UNIT_TEST(TestName) with same TestName. */ \ - /* It's forbidden to declare same test twice because it breaks --fork-tests logic. */ \ - int You_have_declared_test_##F##_multiple_times_This_is_forbidden; \ + /* It's forbidden to declare same test twice because it breaks --fork-tests logic. */ \ + int You_have_declared_test_##F##_multiple_times_This_is_forbidden; \ Y_UNUSED(You_have_declared_test_##F##_multiple_times_This_is_forbidden); -#define UNIT_TEST_RUN(F, FF, context) \ - this->BeforeTest((#F)); \ - { \ - struct T##F##Caller { \ - static void X(TThisUnitTestSuite* thiz, NUnitTest::TTestContext&) { \ - TCleanUp cleaner(thiz); \ - thiz->F(); \ - } \ - }; \ +#define UNIT_TEST_RUN(F, FF, context) \ + this->BeforeTest((#F)); \ + { \ + struct T##F##Caller { \ + static void X(TThisUnitTestSuite* thiz, NUnitTest::TTestContext&) { \ + TCleanUp cleaner(thiz); \ + thiz->F(); \ + } \ + }; \ this->TTestBase::Run(std::bind(&T##F##Caller::X, this, context), StaticName(), (#F), FF); \ } @@ -323,17 +323,17 @@ private: \ } \ this->Finish((#F), &context); \ } \ - } - + } + #define UNIT_TEST(F) UNIT_TEST_IMPL(F, false) - + #define UNIT_FORKED_TEST(F) UNIT_TEST_IMPL(F, true) -#define UNIT_TEST_EXCEPTION(F, E) \ - /* main process with "--fork-tests" flag treats exceptions as errors - it's result of forked test run */ \ - if (this->GetForkTests() && !this->GetIsForked()) { \ - UNIT_TEST_IMPL(F, false); \ - /* forked process (or main without "--fork-tests") treats some exceptions as success - it's exception test! */ \ +#define UNIT_TEST_EXCEPTION(F, E) \ + /* main process with "--fork-tests" flag treats exceptions as errors - it's result of forked test run */ \ + if (this->GetForkTests() && !this->GetIsForked()) { \ + UNIT_TEST_IMPL(F, false); \ + /* forked process (or main without "--fork-tests") treats some exceptions as success - it's exception test! */ \ } else { \ NUnitTest::TTestContext context(this->TTestBase::Processor()); \ if (this->CheckAccessTest((#F))) { \ @@ -342,7 +342,7 @@ private: \ this->AddError("exception expected", &context); \ } catch (const ::NUnitTest::TAssertException&) { \ } catch (const E& e) { \ - TString err; \ + TString err; \ if (!CheckExceptionMessage(e.what(), err)) \ this->AddError(err.c_str(), &context); \ } catch (const std::exception& e) { \ @@ -353,27 +353,27 @@ private: \ this->Finish((#F), &context); \ } \ } - -#define UNIT_TEST_SUITE_END() \ - this->AtEnd(); \ - } \ - \ -public: \ - /*for ; after macros*/ void sub##F() - -#define UNIT_FAIL_IMPL(R, M) \ - do { \ + +#define UNIT_TEST_SUITE_END() \ + this->AtEnd(); \ + } \ + \ +public: \ + /*for ; after macros*/ void sub##F() + +#define UNIT_FAIL_IMPL(R, M) \ + do { \ ::NUnitTest::NPrivate::RaiseError(R, ::TStringBuilder() << R << " at " << __LOCATION__ << ", " << __PRETTY_FUNCTION__ << ": " << M, true); \ } while (false) - + #define UNIT_FAIL_NONFATAL_IMPL(R, M) \ do { \ ::NUnitTest::NPrivate::RaiseError(R, ::TStringBuilder() << R << " at " << __LOCATION__ << ", " << __PRETTY_FUNCTION__ << ": " << M, false); \ } while (false) -#define UNIT_FAIL(M) UNIT_FAIL_IMPL("forced failure", M) +#define UNIT_FAIL(M) UNIT_FAIL_IMPL("forced failure", M) #define UNIT_FAIL_NONFATAL(M) UNIT_FAIL_NONFATAL_IMPL("forced failure", M) - + //types #define UNIT_ASSERT_TYPES_EQUAL(A, B) \ do { \ @@ -395,7 +395,7 @@ public: \ UNIT_FAIL_IMPL("assertion failure", failMsg); \ } \ } while (false) - + #define UNIT_ASSERT_DOUBLES_EQUAL_DEPRECATED(E, A, D) UNIT_ASSERT_DOUBLES_EQUAL_DEPRECATED_C(E, A, D, "") #define UNIT_ASSERT_DOUBLES_EQUAL_C(E, A, D, C) \ @@ -423,24 +423,24 @@ public: \ } while (false) #define UNIT_ASSERT_DOUBLES_EQUAL(E, A, D) UNIT_ASSERT_DOUBLES_EQUAL_C(E, A, D, "") - + //strings -#define UNIT_ASSERT_STRINGS_EQUAL_C(A, B, C) \ - do { \ - const TString _a(A); \ - const TString _b(B); \ - if (_a != _b) { \ +#define UNIT_ASSERT_STRINGS_EQUAL_C(A, B, C) \ + do { \ + const TString _a(A); \ + const TString _b(B); \ + if (_a != _b) { \ auto&& failMsg = Sprintf("%s != %s %s", ToString(_a).data(), ToString(_b).data(), (::TStringBuilder() << C).data()); \ UNIT_FAIL_IMPL("strings equal assertion failed", failMsg); \ - } \ + } \ } while (false) - + #define UNIT_ASSERT_STRINGS_EQUAL(A, B) UNIT_ASSERT_STRINGS_EQUAL_C(A, B, "") #define UNIT_ASSERT_STRING_CONTAINS_C(A, B, C) \ do { \ - const TString _a(A); \ - const TString _b(B); \ + const TString _a(A); \ + const TString _b(B); \ if (!_a.Contains(_b)) { \ auto&& msg = Sprintf("\"%s\" does not contain \"%s\", %s", ToString(_a).data(), ToString(_b).data(), (::TStringBuilder() << C).data()); \ UNIT_FAIL_IMPL("strings contains assertion failed", msg); \ @@ -449,26 +449,26 @@ public: \ #define UNIT_ASSERT_STRING_CONTAINS(A, B) UNIT_ASSERT_STRING_CONTAINS_C(A, B, "") -#define UNIT_ASSERT_NO_DIFF(A, B) \ - do { \ - const TString _a(A); \ - const TString _b(B); \ - if (_a != _b) { \ +#define UNIT_ASSERT_NO_DIFF(A, B) \ + do { \ + const TString _a(A); \ + const TString _b(B); \ + if (_a != _b) { \ UNIT_FAIL_IMPL("strings (" #A ") and (" #B ") are different", Sprintf("\n%s", ::NUnitTest::ColoredDiff(_a, _b, " \t\n.,:;'\"").data())); \ - } \ + } \ } while (false) //strings -#define UNIT_ASSERT_STRINGS_UNEQUAL_C(A, B, C) \ - do { \ - const TString _a(A); \ - const TString _b(B); \ - if (_a == _b) { \ +#define UNIT_ASSERT_STRINGS_UNEQUAL_C(A, B, C) \ + do { \ + const TString _a(A); \ + const TString _b(B); \ + if (_a == _b) { \ auto&& msg = Sprintf("%s == %s %s", ToString(_a).data(), ToString(_b).data(), (::TStringBuilder() << C).data()); \ - UNIT_FAIL_IMPL("strings unequal assertion failed", msg); \ - } \ + UNIT_FAIL_IMPL("strings unequal assertion failed", msg); \ + } \ } while (false) - + #define UNIT_ASSERT_STRINGS_UNEQUAL(A, B) UNIT_ASSERT_STRINGS_UNEQUAL_C(A, B, "") //bool @@ -478,9 +478,9 @@ public: \ UNIT_FAIL_IMPL("assertion failed", Sprintf("(%s) %s", #A, (::TStringBuilder() << C).data())); \ } \ } while (false) - + #define UNIT_ASSERT(A) UNIT_ASSERT_C(A, "") - + //general #define UNIT_ASSERT_EQUAL_C(A, B, C) \ do { \ @@ -488,16 +488,16 @@ public: \ UNIT_FAIL_IMPL("equal assertion failed", Sprintf("%s == %s %s", #A, #B, (::TStringBuilder() << C).data())); \ } \ } while (false) - + #define UNIT_ASSERT_EQUAL(A, B) UNIT_ASSERT_EQUAL_C(A, B, "") - + #define UNIT_ASSERT_UNEQUAL_C(A, B, C) \ do { \ if ((A) == (B)) { \ UNIT_FAIL_IMPL("unequal assertion failed", Sprintf("%s != %s %s", #A, #B, (::TStringBuilder() << C).data()));\ } \ } while (false) - + #define UNIT_ASSERT_UNEQUAL(A, B) UNIT_ASSERT_UNEQUAL_C(A, B, "") #define UNIT_ASSERT_LT_C(A, B, C) \ @@ -644,86 +644,86 @@ public: \ #define UNIT_ASSERT_NO_EXCEPTION_RESULT(A) UNIT_ASSERT_NO_EXCEPTION_RESULT_C(A, "") -#define UNIT_ASSERT_NO_EXCEPTION_C(A, C) \ - do { \ - try { \ - (void)(A); \ - } catch (const ::NUnitTest::TAssertException&) { \ - throw; \ - } catch (...) { \ +#define UNIT_ASSERT_NO_EXCEPTION_C(A, C) \ + do { \ + try { \ + (void)(A); \ + } catch (const ::NUnitTest::TAssertException&) { \ + throw; \ + } catch (...) { \ UNIT_FAIL_IMPL("exception-free assertion failed", Sprintf("%s throws %s\nException message: %s", #A, (::TStringBuilder() << C).data(), CurrentExceptionMessage().data())); \ - } \ + } \ } while (false) #define UNIT_ASSERT_NO_EXCEPTION(A) UNIT_ASSERT_NO_EXCEPTION_C(A, "") - namespace NPrivate { - template <class T, class U, bool Integers> - struct TCompareValuesImpl { - static inline bool Compare(const T& a, const U& b) { - return a == b; - } - }; - - template <class T, class U> - struct TCompareValuesImpl<T, U, true> { - static inline bool Compare(const T& a, const U& b) { - return ::ToString(a) == ::ToString(b); - } - }; - - template <class T, class U> + namespace NPrivate { + template <class T, class U, bool Integers> + struct TCompareValuesImpl { + static inline bool Compare(const T& a, const U& b) { + return a == b; + } + }; + + template <class T, class U> + struct TCompareValuesImpl<T, U, true> { + static inline bool Compare(const T& a, const U& b) { + return ::ToString(a) == ::ToString(b); + } + }; + + template <class T, class U> using TCompareValues = TCompareValuesImpl<T, U, std::is_integral<T>::value && std::is_integral<U>::value>; - - template <typename T, typename U> - static inline bool CompareEqual(const T& a, const U& b) { - return TCompareValues<T, U>::Compare(a, b); - } - - static inline bool CompareEqual(const char* a, const char* b) { - return 0 == strcmp(a, b); - } - - // helper method to avoid double evaluation of A and B expressions in UNIT_ASSERT_VALUES_EQUAL_C - template <typename T, typename U> + + template <typename T, typename U> + static inline bool CompareEqual(const T& a, const U& b) { + return TCompareValues<T, U>::Compare(a, b); + } + + static inline bool CompareEqual(const char* a, const char* b) { + return 0 == strcmp(a, b); + } + + // helper method to avoid double evaluation of A and B expressions in UNIT_ASSERT_VALUES_EQUAL_C + template <typename T, typename U> static inline bool CompareAndMakeStrings(const T& a, const U& b, TString& as, TString& asInd, TString& bs, TString& bsInd, bool& usePlainDiff, bool want) { - const bool have = CompareEqual(a, b); + const bool have = CompareEqual(a, b); usePlainDiff = std::is_integral<T>::value && std::is_integral<U>::value; - - if (want == have) { - return true; - } - - as = ::TStringBuilder() << ::DbgDump(a); - bs = ::TStringBuilder() << ::DbgDump(b); - asInd = ::TStringBuilder() << ::DbgDump(a).SetIndent(true); - bsInd = ::TStringBuilder() << ::DbgDump(b).SetIndent(true); - - return false; - } + + if (want == have) { + return true; + } + + as = ::TStringBuilder() << ::DbgDump(a); + bs = ::TStringBuilder() << ::DbgDump(b); + asInd = ::TStringBuilder() << ::DbgDump(a).SetIndent(true); + bsInd = ::TStringBuilder() << ::DbgDump(b).SetIndent(true); + + return false; + } } //values -#define UNIT_ASSERT_VALUES_EQUAL_IMPL(A, B, C, EQflag, EQstr, NEQstr) \ - do { \ - TString _as; \ - TString _bs; \ - TString _asInd; \ - TString _bsInd; \ - bool _usePlainDiff; \ - if (!::NUnitTest::NPrivate::CompareAndMakeStrings(A, B, _as, _asInd, _bs, _bsInd, _usePlainDiff, EQflag)) { \ +#define UNIT_ASSERT_VALUES_EQUAL_IMPL(A, B, C, EQflag, EQstr, NEQstr) \ + do { \ + TString _as; \ + TString _bs; \ + TString _asInd; \ + TString _bsInd; \ + bool _usePlainDiff; \ + if (!::NUnitTest::NPrivate::CompareAndMakeStrings(A, B, _as, _asInd, _bs, _bsInd, _usePlainDiff, EQflag)) { \ auto&& failMsg = Sprintf("(%s %s %s) failed: (%s %s %s) %s", #A, EQstr, #B, _as.data(), NEQstr, _bs.data(), (::TStringBuilder() << C).data()); \ - if (EQflag && !_usePlainDiff) { \ + if (EQflag && !_usePlainDiff) { \ failMsg += ", with diff:\n"; \ failMsg += ::NUnitTest::ColoredDiff(_asInd, _bsInd); \ - } \ + } \ UNIT_FAIL_IMPL("assertion failed", failMsg); \ - } \ + } \ } while (false) #define UNIT_ASSERT_VALUES_EQUAL_C(A, B, C) \ UNIT_ASSERT_VALUES_EQUAL_IMPL(A, B, C, true, "==", "!=") - + #define UNIT_ASSERT_VALUES_UNEQUAL_C(A, B, C) \ UNIT_ASSERT_VALUES_EQUAL_IMPL(A, B, C, false, "!=", "==") @@ -742,7 +742,7 @@ public: \ UNIT_FAIL_IMPL("fail test assertion failure", \ "code is expected to generate test failure, " \ "but it throws exception with message: " \ - << CurrentExceptionMessage()); \ + << CurrentExceptionMessage()); \ } \ if (!checker.Failed()) { \ UNIT_FAIL_IMPL("fail test assertion failure", \ @@ -754,46 +754,46 @@ public: \ #define UNIT_ADD_METRIC(name, value) ut_context.Metrics[name] = value - class TTestFactory { - friend class TTestBase; - friend class ITestBaseFactory; - - public: + class TTestFactory { + friend class TTestBase; + friend class ITestBaseFactory; + + public: static TTestFactory& Instance(); - + unsigned Execute(); - + void SetProcessor(ITestSuiteProcessor* processor); - - private: + + private: void Register(ITestBaseFactory* b) noexcept; - + ITestSuiteProcessor* Processor() const noexcept; - - private: + + private: explicit TTestFactory(ITestSuiteProcessor* processor); - + ~TTestFactory(); - - private: - TIntrusiveList<ITestBaseFactory> Items_; - ITestSuiteProcessor* Processor_; - }; - - template <class T> - class TTestBaseFactory: public ITestBaseFactory { - public: + + private: + TIntrusiveList<ITestBaseFactory> Items_; + ITestSuiteProcessor* Processor_; + }; + + template <class T> + class TTestBaseFactory: public ITestBaseFactory { + public: ~TTestBaseFactory() override = default; - + inline TTestBase* ConstructTest() override { - return new T; - } - + return new T; + } + inline TString Name() const noexcept override { return T::StaticName(); - } - }; - + } + }; + struct TBaseTestCase { // NOTE: since EACH test case is instantiated for listing tests, its // ctor/dtor are not the best place to do heavy preparations in test fixtures. @@ -802,15 +802,15 @@ public: \ inline TBaseTestCase() : TBaseTestCase(nullptr, nullptr, false) - { - } + { + } inline TBaseTestCase(const char* name, std::function<void(TTestContext&)> body, bool forceFork) : Name_(name) , Body_(std::move(body)) , ForceFork_(forceFork) - { - } + { + } virtual ~TBaseTestCase() = default; @@ -836,7 +836,7 @@ public: \ const char* Name_; std::function<void(TTestContext&)> Body_; bool ForceFork_; - }; + }; using TBaseFixture = TBaseTestCase; @@ -911,76 +911,76 @@ public: \ bool Failed_ = false; }; -#define UNIT_TEST_SUITE_REGISTRATION(T) \ +#define UNIT_TEST_SUITE_REGISTRATION(T) \ static const ::NUnitTest::TTestBaseFactory<T> Y_GENERATE_UNIQUE_ID(UTREG_); - + #define Y_UNIT_TEST_SUITE_IMPL_F(N, T, F) \ - namespace NTestSuite##N { \ + namespace NTestSuite##N { \ class TCurrentTestCase: public F { \ }; \ - class TCurrentTest: public T { \ - private: \ + class TCurrentTest: public T { \ + private: \ typedef std::function<THolder<NUnitTest::TBaseTestCase>()> TTestCaseFactory; \ typedef TVector<TTestCaseFactory> TTests; \ - \ - static TTests& Tests() { \ - static TTests tests; \ - return tests; \ - } \ - \ - public: \ - static TString StaticName() { \ - return #N; \ - } \ - virtual TString Name() const noexcept { \ - return StaticName(); \ - } \ - \ + \ + static TTests& Tests() { \ + static TTests tests; \ + return tests; \ + } \ + \ + public: \ + static TString StaticName() { \ + return #N; \ + } \ + virtual TString Name() const noexcept { \ + return StaticName(); \ + } \ + \ static void AddTest(const char* name, \ const std::function<void(NUnitTest::TTestContext&)>& body, bool forceFork) \ { \ Tests().push_back([=]{ return MakeHolder<NUnitTest::TBaseTestCase>(name, body, forceFork); }); \ - } \ - \ + } \ + \ static void AddTest(TTestCaseFactory testCaseFactory) { \ Tests().push_back(std::move(testCaseFactory)); \ } \ \ - virtual void Execute() { \ - this->AtStart(); \ + virtual void Execute() { \ + this->AtStart(); \ for (TTests::iterator it = Tests().begin(), ie = Tests().end(); it != ie; ++it) { \ const auto i = (*it)(); \ if (!this->CheckAccessTest(i->Name_)) { \ - continue; \ - } \ + continue; \ + } \ NUnitTest::TTestContext context(this->TTestBase::Processor()); \ - try { \ + try { \ this->BeforeTest(i->Name_); \ - { \ - TCleanUp cleaner(this); \ + { \ + TCleanUp cleaner(this); \ auto testCase = [&i, &context] { \ i->SetUp(context); \ i->Execute_(context); \ i->TearDown(context); \ }; \ this->T::Run(testCase, StaticName(), i->Name_, i->ForceFork_); \ - } \ - } catch (const ::NUnitTest::TAssertException&) { \ - } catch (const yexception& e) { \ + } \ + } catch (const ::NUnitTest::TAssertException&) { \ + } catch (const yexception& e) { \ CATCH_REACTION_BT(i->Name_, e, &context); \ - } catch (const std::exception& e) { \ + } catch (const std::exception& e) { \ CATCH_REACTION(i->Name_, e, &context); \ - } catch (...) { \ - this->AddError("non-std exception!", &context); \ - } \ + } catch (...) { \ + this->AddError("non-std exception!", &context); \ + } \ this->Finish(i->Name_, &context); \ - } \ - this->AtEnd(); \ - } \ - }; \ - UNIT_TEST_SUITE_REGISTRATION(TCurrentTest) \ - } \ - namespace NTestSuite##N + } \ + this->AtEnd(); \ + } \ + }; \ + UNIT_TEST_SUITE_REGISTRATION(TCurrentTest) \ + } \ + namespace NTestSuite##N #define Y_UNIT_TEST_SUITE_IMPL(N, T) Y_UNIT_TEST_SUITE_IMPL_F(N, T, ::NUnitTest::TBaseTestCase) #define Y_UNIT_TEST_SUITE(N) Y_UNIT_TEST_SUITE_IMPL(N, TTestBase) @@ -1016,7 +1016,7 @@ public: \ #define SIMPLE_UNIT_FORKED_TEST(N) Y_UNIT_TEST_IMPL(N, true, TCurrentTestCase) #define Y_UNIT_TEST_SUITE_IMPLEMENTATION(N) \ - namespace NTestSuite##N + namespace NTestSuite##N #define Y_UNIT_TEST_DECLARE(N) \ struct TTestCase##N @@ -1025,6 +1025,6 @@ public: \ friend NTestSuite##N::TTestCase##T \ TString RandomString(size_t len, ui32 seed = 0); -} - +} + using ::NUnitTest::TTestBase; diff --git a/library/cpp/testing/unittest/tests_data.cpp b/library/cpp/testing/unittest/tests_data.cpp index b51cbc4b87..08a4eb0790 100644 --- a/library/cpp/testing/unittest/tests_data.cpp +++ b/library/cpp/testing/unittest/tests_data.cpp @@ -11,7 +11,7 @@ public: TPortManagerImpl(bool reservePortsForCurrentTest) : EnableReservePortsForCurrentTest(reservePortsForCurrentTest) , DisableRandomPorts(!GetEnv("NO_RANDOM_PORTS").empty()) - { + { } ui16 GetPort(ui16 port) { diff --git a/library/cpp/testing/unittest/tests_data.h b/library/cpp/testing/unittest/tests_data.h index 6536bc1ae6..2c56bdb3b2 100644 --- a/library/cpp/testing/unittest/tests_data.h +++ b/library/cpp/testing/unittest/tests_data.h @@ -27,7 +27,7 @@ void SetReuseAddressAndPort(const TSocketType& sock) { #endif } -class TPortManager: public TNonCopyable { +class TPortManager: public TNonCopyable { public: TPortManager(bool reservePortsForCurrentTest = true); ~TPortManager(); diff --git a/library/cpp/testing/unittest/ut/main.cpp b/library/cpp/testing/unittest/ut/main.cpp index e303e21e30..cba1681c83 100644 --- a/library/cpp/testing/unittest/ut/main.cpp +++ b/library/cpp/testing/unittest/ut/main.cpp @@ -7,27 +7,27 @@ #include <util/system/env.h> #include <util/system/fs.h> -TEST(GTest, Test1) { - UNIT_ASSERT_EQUAL(1, 1); -} - -TEST(GTest, Test2) { - UNIT_ASSERT_EQUAL(2, 2); -} - -namespace { - struct TFixture : ::testing::Test { - TFixture() - : I(0) - { - } - +TEST(GTest, Test1) { + UNIT_ASSERT_EQUAL(1, 1); +} + +TEST(GTest, Test2) { + UNIT_ASSERT_EQUAL(2, 2); +} + +namespace { + struct TFixture : ::testing::Test { + TFixture() + : I(0) + { + } + void SetUp() override { - I = 5; - } - - int I; - }; + I = 5; + } + + int I; + }; struct TSimpleFixture : public NUnitTest::TBaseFixture { size_t Value = 24; @@ -50,11 +50,11 @@ namespace { Magic = 100; } }; -} - -TEST_F(TFixture, Test1) { - ASSERT_EQ(I, 5); -} +} + +TEST_F(TFixture, Test1) { + ASSERT_EQ(I, 5); +} TEST(ETest, Test1) { UNIT_CHECK_GENERATED_EXCEPTION(ythrow yexception(), yexception); diff --git a/library/cpp/testing/unittest/utmain.cpp b/library/cpp/testing/unittest/utmain.cpp index 305bc6b40f..9b46bee6ee 100644 --- a/library/cpp/testing/unittest/utmain.cpp +++ b/library/cpp/testing/unittest/utmain.cpp @@ -1,9 +1,9 @@ #include "plugin.h" -#include "registar.h" -#include "utmain.h" - +#include "registar.h" +#include "utmain.h" + #include <library/cpp/colorizer/colors.h> - + #include <library/cpp/json/writer/json.h> #include <library/cpp/json/writer/json_value.h> #include <library/cpp/testing/common/env.h> @@ -11,45 +11,45 @@ #include <util/datetime/base.h> -#include <util/generic/hash.h> +#include <util/generic/hash.h> #include <util/generic/hash_set.h> #include <util/generic/scope.h> #include <util/generic/string.h> -#include <util/generic/yexception.h> +#include <util/generic/yexception.h> -#include <util/network/init.h> +#include <util/network/init.h> #include <util/stream/file.h> #include <util/stream/output.h> #include <util/string/join.h> #include <util/string/util.h> - + #include <util/system/defaults.h> #include <util/system/execpath.h> #include <util/system/valgrind.h> #include <util/system/shellcommand.h> -#if defined(_win_) -#include <fcntl.h> -#include <io.h> -#include <windows.h> -#include <crtdbg.h> -#endif - -#if defined(_unix_) -#include <unistd.h> -#endif - +#if defined(_win_) +#include <fcntl.h> +#include <io.h> +#include <windows.h> +#include <crtdbg.h> +#endif + +#if defined(_unix_) +#include <unistd.h> +#endif + #ifdef WITH_VALGRIND #define NOTE_IN_VALGRIND(test) VALGRIND_PRINTF("%s::%s", test->unit->name.data(), test->name) #else -#define NOTE_IN_VALGRIND(test) +#define NOTE_IN_VALGRIND(test) #endif const size_t MAX_COMMENT_MESSAGE_LENGTH = 1024 * 1024; // 1 MB -using namespace NUnitTest; - +using namespace NUnitTest; + class TNullTraceWriterProcessor: public ITestSuiteProcessor { }; @@ -107,12 +107,12 @@ private: virtual TString BuildComment(const char* message, const char* backTrace) { return NUnitTest::GetFormatTag("bad") + - TString(message).substr(0, MAX_COMMENT_MESSAGE_LENGTH) + - NUnitTest::GetResetTag() + - TString("\n") + - NUnitTest::GetFormatTag("alt1") + - TString(backTrace).substr(0, MAX_COMMENT_MESSAGE_LENGTH) + - NUnitTest::GetResetTag(); + TString(message).substr(0, MAX_COMMENT_MESSAGE_LENGTH) + + NUnitTest::GetResetTag() + + TString("\n") + + NUnitTest::GetFormatTag("alt1") + + TString(backTrace).substr(0, MAX_COMMENT_MESSAGE_LENGTH) + + NUnitTest::GetResetTag(); } void OnBeforeTest(const TTest* test) override { @@ -164,75 +164,75 @@ private: } }; -class TColoredProcessor: public ITestSuiteProcessor, public NColorizer::TColors { -public: +class TColoredProcessor: public ITestSuiteProcessor, public NColorizer::TColors { +public: inline TColoredProcessor(const TString& appName) - : PrintBeforeSuite_(true) - , PrintBeforeTest_(true) + : PrintBeforeSuite_(true) + , PrintBeforeTest_(true) , PrintAfterTest_(true) , PrintAfterSuite_(true) - , PrintTimes_(false) + , PrintTimes_(false) , PrintSummary_(true) - , PrevTime_(TInstant::Now()) + , PrevTime_(TInstant::Now()) , ShowFails(true) - , Start(0) - , End(Max<size_t>()) - , AppName(appName) - , ForkTests(false) - , IsForked(false) - , Loop(false) - , ForkExitedCorrectly(false) + , Start(0) + , End(Max<size_t>()) + , AppName(appName) + , ForkTests(false) + , IsForked(false) + , Loop(false) + , ForkExitedCorrectly(false) , TraceProcessor(new TNullTraceWriterProcessor()) - { - } - + { + } + ~TColoredProcessor() override { - } - - inline void Disable(const char* name) { + } + + inline void Disable(const char* name) { size_t colon = TString(name).find("::"); if (colon == TString::npos) { - DisabledSuites_.insert(name); - } else { + DisabledSuites_.insert(name); + } else { TString suite = TString(name).substr(0, colon); - DisabledTests_.insert(name); - } - } - - inline void Enable(const char* name) { + DisabledTests_.insert(name); + } + } + + inline void Enable(const char* name) { size_t colon = TString(name).rfind("::"); if (colon == TString::npos) { - EnabledSuites_.insert(name); + EnabledSuites_.insert(name); EnabledTests_.insert(TString() + name + "::*"); - } else { + } else { TString suite = TString(name).substr(0, colon); - EnabledSuites_.insert(suite); + EnabledSuites_.insert(suite); EnabledSuites_.insert(name); - EnabledTests_.insert(name); + EnabledTests_.insert(name); EnabledTests_.insert(TString() + name + "::*"); - } - } - - inline void SetPrintBeforeSuite(bool print) { - PrintBeforeSuite_ = print; - } + } + } + + inline void SetPrintBeforeSuite(bool print) { + PrintBeforeSuite_ = print; + } inline void SetPrintAfterSuite(bool print) { PrintAfterSuite_ = print; } - inline void SetPrintBeforeTest(bool print) { - PrintBeforeTest_ = print; - } + inline void SetPrintBeforeTest(bool print) { + PrintBeforeTest_ = print; + } inline void SetPrintAfterTest(bool print) { PrintAfterTest_ = print; } - inline void SetPrintTimes(bool print) { - PrintTimes_ = print; - } - + inline void SetPrintTimes(bool print) { + PrintTimes_ = print; + } + inline void SetPrintSummary(bool print) { PrintSummary_ = print; } @@ -241,15 +241,15 @@ public: return PrintSummary_; } - inline void SetShowFails(bool show) { - ShowFails = show; - } + inline void SetShowFails(bool show) { + ShowFails = show; + } void SetContinueOnFail(bool val) { NUnitTest::ContinueOnFail = val; } - inline void BeQuiet() { + inline void BeQuiet() { SetPrintTimes(false); SetPrintBeforeSuite(false); SetPrintAfterSuite(false); @@ -258,117 +258,117 @@ public: SetPrintSummary(false); } - inline void SetStart(size_t val) { - Start = val; - } - - inline void SetEnd(size_t val) { - End = val; - } - - inline void SetForkTests(bool val) { - ForkTests = val; - } + inline void SetStart(size_t val) { + Start = val; + } + + inline void SetEnd(size_t val) { + End = val; + } + + inline void SetForkTests(bool val) { + ForkTests = val; + } inline bool GetForkTests() const override { - return ForkTests; - } + return ForkTests; + } - inline void SetIsForked(bool val) { - IsForked = val; - SetIsTTY(IsForked || CalcIsTTY(stderr)); - } + inline void SetIsForked(bool val) { + IsForked = val; + SetIsTTY(IsForked || CalcIsTTY(stderr)); + } inline bool GetIsForked() const override { - return IsForked; - } + return IsForked; + } - inline void SetLoop(bool loop) { - Loop = loop; - } - - inline bool IsLoop() const { - return Loop; - } + inline void SetLoop(bool loop) { + Loop = loop; + } + inline bool IsLoop() const { + return Loop; + } + inline void SetTraceProcessor(TAutoPtr<ITestSuiteProcessor> traceProcessor) { TraceProcessor = traceProcessor; } -private: +private: void OnUnitStart(const TUnit* unit) override { TraceProcessor->UnitStart(*unit); - if (IsForked) { - return; + if (IsForked) { + return; } - if (PrintBeforeSuite_ || PrintBeforeTest_) { + if (PrintBeforeSuite_ || PrintBeforeTest_) { fprintf(stderr, "%s<-----%s %s\n", LightBlueColor().data(), OldColor().data(), unit->name.data()); - } - } + } + } void OnUnitStop(const TUnit* unit) override { TraceProcessor->UnitStop(*unit); - if (IsForked) { - return; + if (IsForked) { + return; } if (!PrintAfterSuite_) { return; } - fprintf(stderr, "%s----->%s %s -> ok: %s%u%s", + fprintf(stderr, "%s----->%s %s -> ok: %s%u%s", LightBlueColor().data(), OldColor().data(), unit->name.data(), LightGreenColor().data(), GoodTestsInCurrentUnit(), OldColor().data()); - if (FailTestsInCurrentUnit()) { - fprintf(stderr, ", err: %s%u%s", + if (FailTestsInCurrentUnit()) { + fprintf(stderr, ", err: %s%u%s", LightRedColor().data(), FailTestsInCurrentUnit(), OldColor().data()); - } - fprintf(stderr, "\n"); - } - + } + fprintf(stderr, "\n"); + } + void OnBeforeTest(const TTest* test) override { TraceProcessor->BeforeTest(*test); - if (IsForked) { - return; + if (IsForked) { + return; } - if (PrintBeforeTest_) { + if (PrintBeforeTest_) { fprintf(stderr, "[%sexec%s] %s::%s...\n", LightBlueColor().data(), OldColor().data(), test->unit->name.data(), test->name); - } - } + } + } void OnError(const TError* descr) override { TraceProcessor->Error(*descr); - if (!IsForked && ForkExitedCorrectly) { - return; - } + if (!IsForked && ForkExitedCorrectly) { + return; + } if (!PrintAfterTest_) { return; } const TString err = Sprintf("[%sFAIL%s] %s::%s -> %s%s%s\n%s%s%s", LightRedColor().data(), OldColor().data(), descr->test->unit->name.data(), - descr->test->name, + descr->test->name, LightRedColor().data(), descr->msg, OldColor().data(), LightCyanColor().data(), descr->BackTrace.data(), OldColor().data()); const TDuration test_duration = SaveTestDuration(); - if (ShowFails) { + if (ShowFails) { if (PrintTimes_) { Fails.push_back(Sprintf("%s %s", test_duration.ToString().data(), err.data())); } else { Fails.push_back(err); } - } + } fprintf(stderr, "%s", err.data()); - NOTE_IN_VALGRIND(descr->test); + NOTE_IN_VALGRIND(descr->test); PrintTimes(test_duration); - if (IsForked) { - fprintf(stderr, "%s", ForkCorrectExitMsg); - } - } - + if (IsForked) { + fprintf(stderr, "%s", ForkCorrectExitMsg); + } + } + void OnFinish(const TFinish* descr) override { TraceProcessor->Finish(*descr); - if (!IsForked && ForkExitedCorrectly) { - return; - } + if (!IsForked && ForkExitedCorrectly) { + return; + } if (!PrintAfterTest_) { return; } @@ -382,9 +382,9 @@ private: if (IsForked) { fprintf(stderr, "%s", ForkCorrectExitMsg); } - } - } - + } + } + inline TDuration SaveTestDuration() { const TInstant now = TInstant::Now(); TDuration d = now - PrevTime_; @@ -393,101 +393,101 @@ private: } inline void PrintTimes(TDuration d) { - if (!PrintTimes_) { - return; - } - + if (!PrintTimes_) { + return; + } + Cerr << d << "\n"; - } - + } + void OnEnd() override { TraceProcessor->End(); - if (IsForked) { - return; - } + if (IsForked) { + return; + } if (!PrintSummary_) { return; } - fprintf(stderr, "[%sDONE%s] ok: %s%u%s", + fprintf(stderr, "[%sDONE%s] ok: %s%u%s", YellowColor().data(), OldColor().data(), LightGreenColor().data(), GoodTests(), OldColor().data()); - if (FailTests()) - fprintf(stderr, ", err: %s%u%s", + if (FailTests()) + fprintf(stderr, ", err: %s%u%s", LightRedColor().data(), FailTests(), OldColor().data()); - fprintf(stderr, "\n"); + fprintf(stderr, "\n"); - if (ShowFails) { - for (size_t i = 0; i < Fails.size(); ++i) { + if (ShowFails) { + for (size_t i = 0; i < Fails.size(); ++i) { printf("%s", Fails[i].data()); } - } - } - + } + } + bool CheckAccess(TString name, size_t num) override { - if (num < Start) { - return false; - } - - if (num >= End) { - return false; - } - + if (num < Start) { + return false; + } + + if (num >= End) { + return false; + } + if (DisabledSuites_.find(name.data()) != DisabledSuites_.end()) { - return false; - } - - if (EnabledSuites_.empty()) { - return true; - } - + return false; + } + + if (EnabledSuites_.empty()) { + return true; + } + return EnabledSuites_.find(name.data()) != EnabledSuites_.end(); - } - + } + bool CheckAccessTest(TString suite, const char* test) override { TString name = suite + "::" + test; - if (DisabledTests_.find(name) != DisabledTests_.end()) { - return false; - } - - if (EnabledTests_.empty()) { - return true; - } + if (DisabledTests_.find(name) != DisabledTests_.end()) { + return false; + } + + if (EnabledTests_.empty()) { + return true; + } if (EnabledTests_.find(TString() + suite + "::*") != EnabledTests_.end()) { - return true; - } + return true; + } - return EnabledTests_.find(name) != EnabledTests_.end(); - } + return EnabledTests_.find(name) != EnabledTests_.end(); + } void Run(std::function<void()> f, const TString& suite, const char* name, const bool forceFork) override { - if (!(ForkTests || forceFork) || GetIsForked()) { - return f(); + if (!(ForkTests || forceFork) || GetIsForked()) { + return f(); } TList<TString> args(1, "--is-forked-internal"); args.push_back(Sprintf("+%s::%s", suite.data(), name)); - // stdin is ignored - unittest should not need them... - TShellCommand cmd(AppName, args, - TShellCommandOptions().SetUseShell(false).SetCloseAllFdsOnExec(true).SetAsync(false).SetLatency(1)); - cmd.Run(); + // stdin is ignored - unittest should not need them... + TShellCommand cmd(AppName, args, + TShellCommandOptions().SetUseShell(false).SetCloseAllFdsOnExec(true).SetAsync(false).SetLatency(1)); + cmd.Run(); const TString& err = cmd.GetError(); - const size_t msgIndex = err.find(ForkCorrectExitMsg); + const size_t msgIndex = err.find(ForkCorrectExitMsg); - // everything is printed by parent process except test's result output ("good" or "fail") - // which is printed by child. If there was no output - parent process prints default message. + // everything is printed by parent process except test's result output ("good" or "fail") + // which is printed by child. If there was no output - parent process prints default message. ForkExitedCorrectly = msgIndex != TString::npos; - // TODO: stderr output is always printed after stdout - Cout.Write(cmd.GetOutput()); - Cerr.Write(err.c_str(), Min(msgIndex, err.size())); + // TODO: stderr output is always printed after stdout + Cout.Write(cmd.GetOutput()); + Cerr.Write(err.c_str(), Min(msgIndex, err.size())); - // do not use default case, so gcc will warn if new element in enum will be added - switch (cmd.GetStatus()) { + // do not use default case, so gcc will warn if new element in enum will be added + switch (cmd.GetStatus()) { case TShellCommand::SHELL_FINISHED: { // test could fail with zero status if it calls exit(0) in the middle. if (ForkExitedCorrectly) @@ -508,40 +508,40 @@ private: ythrow yexception() << "Forked test failed with internal error: " << cmd.GetInternalError(); } } - } + } -private: - bool PrintBeforeSuite_; - bool PrintBeforeTest_; +private: + bool PrintBeforeSuite_; + bool PrintBeforeTest_; bool PrintAfterTest_; bool PrintAfterSuite_; - bool PrintTimes_; + bool PrintTimes_; bool PrintSummary_; THashSet<TString> DisabledSuites_; THashSet<TString> EnabledSuites_; THashSet<TString> DisabledTests_; THashSet<TString> EnabledTests_; - TInstant PrevTime_; - bool ShowFails; + TInstant PrevTime_; + bool ShowFails; TVector<TString> Fails; - size_t Start; - size_t End; + size_t Start; + size_t End; TString AppName; - bool ForkTests; - bool IsForked; - bool Loop; - static const char* const ForkCorrectExitMsg; - bool ForkExitedCorrectly; + bool ForkTests; + bool IsForked; + bool Loop; + static const char* const ForkCorrectExitMsg; + bool ForkExitedCorrectly; TAutoPtr<ITestSuiteProcessor> TraceProcessor; -}; - -const char* const TColoredProcessor::ForkCorrectExitMsg = "--END--"; - +}; + +const char* const TColoredProcessor::ForkCorrectExitMsg = "--END--"; + class TEnumeratingProcessor: public ITestSuiteProcessor { public: TEnumeratingProcessor(bool verbose, IOutputStream& stream) noexcept - : Verbose_(verbose) - , Stream_(stream) + : Verbose_(verbose) + , Stream_(stream) { } @@ -571,7 +571,7 @@ private: class TWinEnvironment { public: TWinEnvironment() - : OutputCP(GetConsoleOutputCP()) + : OutputCP(GetConsoleOutputCP()) { setmode(fileno(stdout), _O_BINARY); SetConsoleOutputCP(CP_UTF8); @@ -593,7 +593,7 @@ public: SetConsoleOutputCP(OutputCP); // restore original output CP at program exit } - + private: UINT OutputCP; // original codepage }; @@ -648,15 +648,15 @@ int NUnitTest::RunMain(int argc, char** argv) { } #endif NTesting::THook::CallBeforeInit(); - InitNetworkSubSystem(); - - try { + InitNetworkSubSystem(); + + try { GetExecPath(); - } catch (...) { - } - + } catch (...) { + } + #ifndef UT_SKIP_EXCEPTIONS - try { + try { #endif NTesting::THook::CallBeforeRun(); Y_DEFER { NTesting::THook::CallAfterRun(); }; @@ -667,7 +667,7 @@ int NUnitTest::RunMain(int argc, char** argv) { TColoredProcessor processor(GetExecPath()); IOutputStream* listStream = &Cout; THolder<IOutputStream> listFile; - + enum EListType { DONT_LIST, LIST, @@ -675,17 +675,17 @@ int NUnitTest::RunMain(int argc, char** argv) { }; EListType listTests = DONT_LIST; - for (size_t i = 1; i < (size_t)argc; ++i) { - const char* name = argv[i]; - - if (name && *name) { + for (size_t i = 1; i < (size_t)argc; ++i) { + const char* name = argv[i]; + + if (name && *name) { if (strcmp(name, "--help") == 0 || strcmp(name, "-h") == 0) { return DoUsage(argv[0]); } else if (strcmp(name, "--list") == 0 || strcmp(name, "-l") == 0) { listTests = LIST; } else if (strcmp(name, "--list-verbose") == 0 || strcmp(name, "-A") == 0) { listTests = LIST_VERBOSE; - } else if (strcmp(name, "--print-before-suite=false") == 0) { + } else if (strcmp(name, "--print-before-suite=false") == 0) { processor.SetPrintBeforeSuite(false); } else if (strcmp(name, "--print-before-test=false") == 0) { processor.SetPrintBeforeTest(false); @@ -699,14 +699,14 @@ int NUnitTest::RunMain(int argc, char** argv) { processor.SetShowFails(false); } else if (strcmp(name, "--continue-on-fail") == 0) { processor.SetContinueOnFail(true); - } else if (strcmp(name, "--print-times") == 0) { - processor.SetPrintTimes(true); - } else if (strcmp(name, "--from") == 0) { - ++i; - processor.SetStart(FromString<size_t>(argv[i])); - } else if (strcmp(name, "--to") == 0) { - ++i; - processor.SetEnd(FromString<size_t>(argv[i])); + } else if (strcmp(name, "--print-times") == 0) { + processor.SetPrintTimes(true); + } else if (strcmp(name, "--from") == 0) { + ++i; + processor.SetStart(FromString<size_t>(argv[i])); + } else if (strcmp(name, "--to") == 0) { + ++i; + processor.SetEnd(FromString<size_t>(argv[i])); } else if (strcmp(name, "--fork-tests") == 0) { processor.SetForkTests(true); } else if (strcmp(name, "--is-forked-internal") == 0) { @@ -735,19 +735,19 @@ int NUnitTest::RunMain(int argc, char** argv) { } else if (TString(name).StartsWith("--")) { return DoUsage(argv[0]), 1; } else if (*name == '-') { - processor.Disable(name + 1); - } else if (*name == '+') { - processor.Enable(name + 1); - } else { - processor.Enable(name); - } - } + processor.Disable(name + 1); + } else if (*name == '+') { + processor.Enable(name + 1); + } else { + processor.Enable(name); + } + } } if (listTests != DONT_LIST) { return DoList(listTests == LIST_VERBOSE, *listStream); } - - TTestFactory::Instance().SetProcessor(&processor); + + TTestFactory::Instance().SetProcessor(&processor); unsigned ret; for (;;) { @@ -759,13 +759,13 @@ int NUnitTest::RunMain(int argc, char** argv) { if (0 != ret || !processor.IsLoop()) { break; } - } + } return ret; #ifndef UT_SKIP_EXCEPTIONS - } catch (...) { - Cerr << "caught exception in test suite(" << CurrentExceptionMessage() << ")" << Endl; - } + } catch (...) { + Cerr << "caught exception in test suite(" << CurrentExceptionMessage() << ")" << Endl; + } #endif - - return 1; -} + + return 1; +} diff --git a/library/cpp/testing/unittest/utmain.h b/library/cpp/testing/unittest/utmain.h index 65e8082ee1..07c288d5a5 100644 --- a/library/cpp/testing/unittest/utmain.h +++ b/library/cpp/testing/unittest/utmain.h @@ -1,5 +1,5 @@ -#pragma once - -namespace NUnitTest { - int RunMain(int argc, char** argv); -} +#pragma once + +namespace NUnitTest { + int RunMain(int argc, char** argv); +} diff --git a/library/cpp/testing/unittest/ya.make b/library/cpp/testing/unittest/ya.make index aaa4f2ba85..2d27845bb2 100644 --- a/library/cpp/testing/unittest/ya.make +++ b/library/cpp/testing/unittest/ya.make @@ -1,4 +1,4 @@ -LIBRARY() +LIBRARY() PROVIDES(test_framework) @@ -6,26 +6,26 @@ OWNER( pg galaxycrab ) - -PEERDIR( + +PEERDIR( library/cpp/colorizer library/cpp/dbg_output library/cpp/diff library/cpp/json/writer library/cpp/testing/common library/cpp/testing/hook -) - -SRCS( - gtest.cpp +) + +SRCS( + gtest.cpp checks.cpp plugin.cpp - registar.cpp + registar.cpp tests_data.cpp - utmain.cpp -) + utmain.cpp +) -END() +END() RECURSE_FOR_TESTS( fat diff --git a/library/cpp/testing/unittest_main/main.cpp b/library/cpp/testing/unittest_main/main.cpp index fc5d2d9418..e2cecd3a8f 100644 --- a/library/cpp/testing/unittest_main/main.cpp +++ b/library/cpp/testing/unittest_main/main.cpp @@ -1,5 +1,5 @@ #include <library/cpp/testing/unittest/utmain.h> - -int main(int argc, char** argv) { - return NUnitTest::RunMain(argc, argv); -} + +int main(int argc, char** argv) { + return NUnitTest::RunMain(argc, argv); +} diff --git a/library/cpp/testing/unittest_main/ya.make b/library/cpp/testing/unittest_main/ya.make index 80a6cc699b..43b36bde3f 100644 --- a/library/cpp/testing/unittest_main/ya.make +++ b/library/cpp/testing/unittest_main/ya.make @@ -1,14 +1,14 @@ -LIBRARY() - -OWNER(pg) - -PEERDIR( +LIBRARY() + +OWNER(pg) + +PEERDIR( library/cpp/testing/unittest library/cpp/terminate_handler -) - -SRCS( - main.cpp -) - -END() +) + +SRCS( + main.cpp +) + +END() |