junit.h 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. #include "registar.h"
  2. #include <util/datetime/base.h>
  3. #include <util/generic/maybe.h>
  4. #include <util/system/tempfile.h>
  5. #include <optional>
  6. namespace NUnitTest {
  7. extern const TString Y_UNITTEST_OUTPUT_CMDLINE_OPTION;
  8. extern const TString Y_UNITTEST_TEST_FILTER_FILE_OPTION;
  9. class TJUnitProcessor : public ITestSuiteProcessor {
  10. struct TFailure {
  11. TString Message;
  12. TString BackTrace;
  13. };
  14. struct TTestCase {
  15. TString Name;
  16. bool Success;
  17. TVector<TFailure> Failures;
  18. TString StdOut;
  19. TString StdErr;
  20. double DurationSecods = 0.0;
  21. size_t GetFailuresCount() const {
  22. return Failures.size();
  23. }
  24. };
  25. struct TTestSuite {
  26. TMap<TString, TTestCase> Cases;
  27. size_t GetTestsCount() const {
  28. return Cases.size();
  29. }
  30. size_t GetFailuresCount() const {
  31. size_t sum = 0;
  32. for (const auto& [name, testCase] : Cases) {
  33. sum += testCase.GetFailuresCount();
  34. }
  35. return sum;
  36. }
  37. double GetDurationSeconds() const {
  38. double sum = 0.0;
  39. for (const auto& [name, testCase] : Cases) {
  40. sum += testCase.DurationSecods;
  41. }
  42. return sum;
  43. }
  44. };
  45. // Holds a copy of TTest structure for current test
  46. class TCurrentTest {
  47. public:
  48. TCurrentTest(const TTest* test)
  49. : TestName(test->name)
  50. , Unit(*test->unit)
  51. , Test{&Unit, TestName.c_str()}
  52. {
  53. }
  54. operator const TTest*() const {
  55. return &Test;
  56. }
  57. private:
  58. TString TestName;
  59. TUnit Unit;
  60. TTest Test;
  61. };
  62. struct TOutputCapturer;
  63. public:
  64. enum class EOutputFormat {
  65. Xml,
  66. Json,
  67. };
  68. TJUnitProcessor(TString file, TString exec, EOutputFormat outputFormat);
  69. ~TJUnitProcessor();
  70. void SetForkTestsParams(bool forkTests, bool isForked) override;
  71. void OnBeforeTest(const TTest* test) override;
  72. void OnError(const TError* descr) override;
  73. void OnFinish(const TFinish* descr) override;
  74. private:
  75. TTestCase* GetTestCase(const TTest* test) {
  76. auto& suite = Suites[test->unit->name];
  77. return &suite.Cases[test->name];
  78. }
  79. void Save();
  80. size_t GetTestsCount() const {
  81. size_t sum = 0;
  82. for (const auto& [name, suite] : Suites) {
  83. sum += suite.GetTestsCount();
  84. }
  85. return sum;
  86. }
  87. size_t GetFailuresCount() const {
  88. size_t sum = 0;
  89. for (const auto& [name, suite] : Suites) {
  90. sum += suite.GetFailuresCount();
  91. }
  92. return sum;
  93. }
  94. void SerializeToFile();
  95. void SerializeToXml();
  96. void SerializeToJson();
  97. void MergeSubprocessReport();
  98. TString BuildFileName(size_t index, const TStringBuf extension) const;
  99. TStringBuf GetFileExtension() const;
  100. void MakeReportFileName();
  101. void MakeTmpFileNameForForkedTests();
  102. static void TransferFromCapturer(THolder<TJUnitProcessor::TOutputCapturer>& capturer, TString& out, IOutputStream& outStream);
  103. static void CaptureSignal(TJUnitProcessor* processor);
  104. static void UncaptureSignal();
  105. static void SignalHandler(int signal);
  106. private:
  107. const TString FileName; // cmd line param
  108. const TString ExecName; // cmd line param
  109. const EOutputFormat OutputFormat;
  110. TString ResultReportFileName;
  111. TMaybe<TTempFile> TmpReportFile;
  112. TMap<TString, TTestSuite> Suites;
  113. THolder<TOutputCapturer> StdErrCapturer;
  114. THolder<TOutputCapturer> StdOutCapturer;
  115. TInstant StartCurrentTestTime;
  116. void (*PrevAbortHandler)(int) = nullptr;
  117. void (*PrevSegvHandler)(int) = nullptr;
  118. std::optional<TCurrentTest> CurrentTest;
  119. };
  120. } // namespace NUnitTest