Browse Source

deps: make gtest output tap

Teach gtest to produce TAP so we can integrate it better with our CI
tooling.

TAP is printed to stdout but it can also be written to file by passing
the `--gtest_output=tap:filename.tap` switch to cctest.

PR-URL: https://github.com/nodejs/node/pull/8034
Reviewed-By: James M Snell <jasnell@gmail.com>
v6
Ben Noordhuis 8 years ago
parent
commit
c56ae16db2
  1. 124
      deps/gtest/src/gtest.cc
  2. 1
      deps/gtest/src/gtest_main.cc

124
deps/gtest/src/gtest.cc

@ -3498,6 +3498,125 @@ std::string XmlUnitTestResultPrinter::RemoveInvalidXmlCharacters(
// </testsuite>
// </testsuites>
class TapUnitTestResultPrinter : public EmptyTestEventListener {
public:
TapUnitTestResultPrinter();
explicit TapUnitTestResultPrinter(const char* output_file);
virtual void OnTestIterationEnd(const UnitTest& unit_test, int iteration);
private:
static void PrintTapUnitTest(::std::ostream* stream,
const UnitTest& unit_test);
static void PrintTapTestCase(int* count,
::std::ostream* stream,
const TestCase& test_case);
static void OutputTapTestInfo(int* count,
::std::ostream* stream,
const char* test_case_name,
const TestInfo& test_info);
static void OutputTapComment(::std::ostream* stream, const char* comment);
const std::string output_file_;
GTEST_DISALLOW_COPY_AND_ASSIGN_(TapUnitTestResultPrinter);
};
TapUnitTestResultPrinter::TapUnitTestResultPrinter() {}
TapUnitTestResultPrinter::TapUnitTestResultPrinter(const char* output_file)
: output_file_(output_file) {
if (output_file_.c_str() == NULL || output_file_.empty()) {
fprintf(stderr, "TAP output file may not be null\n");
fflush(stderr);
exit(EXIT_FAILURE);
}
}
void TapUnitTestResultPrinter::OnTestIterationEnd(const UnitTest& unit_test,
int /*iteration*/) {
FILE* tapout = stdout;
if (!output_file_.empty()) {
FilePath output_file(output_file_);
FilePath output_dir(output_file.RemoveFileName());
tapout = NULL;
if (output_dir.CreateDirectoriesRecursively())
tapout = posix::FOpen(output_file_.c_str(), "w");
if (tapout == NULL) {
fprintf(stderr, "Unable to open file \"%s\"\n", output_file_.c_str());
fflush(stderr);
exit(EXIT_FAILURE);
}
}
std::stringstream stream;
PrintTapUnitTest(&stream, unit_test);
fprintf(tapout, "%s", StringStreamToString(&stream).c_str());
fflush(tapout);
if (tapout != stdout)
fclose(tapout);
}
void TapUnitTestResultPrinter::PrintTapUnitTest(std::ostream* stream,
const UnitTest& unit_test) {
*stream << "TAP version 13\n";
*stream << "1.." << unit_test.reportable_test_count() << "\n";
int count = 1;
for (int i = 0; i < unit_test.total_test_case_count(); ++i) {
const TestCase& test_case = *unit_test.GetTestCase(i);
if (test_case.reportable_test_count() > 0)
PrintTapTestCase(&count, stream, test_case);
}
*stream << "# failures: " << unit_test.failed_test_count() << "\n";
}
void TapUnitTestResultPrinter::PrintTapTestCase(int* count,
std::ostream* stream,
const TestCase& test_case) {
for (int i = 0; i < test_case.total_test_count(); ++i) {
const TestInfo& test_info = *test_case.GetTestInfo(i);
if (test_info.is_reportable())
OutputTapTestInfo(count, stream, test_case.name(), test_info);
}
}
void TapUnitTestResultPrinter::OutputTapTestInfo(int* count,
::std::ostream* stream,
const char* test_case_name,
const TestInfo& test_info) {
const TestResult& result = *test_info.result();
const char* status = result.Passed() ? "ok" : "not ok";
*stream << status << " " << *count << " - " <<
test_case_name << "." << test_info.name() << "\n";
*stream << " ---\n";
*stream << " duration_ms: " <<
FormatTimeInMillisAsSeconds(result.elapsed_time()) << "\n";
*stream << " ...\n";
for (int i = 0; i < result.total_part_count(); ++i) {
const TestPartResult& part = result.GetTestPartResult(i);
OutputTapComment(stream, part.message());
}
*count += 1;
}
void TapUnitTestResultPrinter::OutputTapComment(::std::ostream* stream,
const char* comment) {
const char* start = comment;
while (const char* end = strchr(start, '\n')) {
*stream << "# " << std::string(start, end) << "\n";
start = end + 1;
}
if (*start)
*stream << "# " << start << "\n";
}
// Formats the given time in milliseconds as seconds.
std::string FormatTimeInMillisAsSeconds(TimeInMillis ms) {
::std::stringstream ss;
@ -4314,7 +4433,7 @@ UnitTestImpl::UnitTestImpl(UnitTest* parent)
#endif
// Will be overridden by the flag before first use.
catch_exceptions_(false) {
listeners()->SetDefaultResultPrinter(new PrettyUnitTestResultPrinter);
listeners()->SetDefaultResultPrinter(new TapUnitTestResultPrinter);
}
UnitTestImpl::~UnitTestImpl() {
@ -4365,6 +4484,9 @@ void UnitTestImpl::ConfigureXmlOutput() {
if (output_format == "xml") {
listeners()->SetDefaultXmlGenerator(new XmlUnitTestResultPrinter(
UnitTestOptions::GetAbsolutePathToOutputFile().c_str()));
} else if (output_format == "tap") {
listeners()->SetDefaultXmlGenerator(new TapUnitTestResultPrinter(
UnitTestOptions::GetAbsolutePathToOutputFile().c_str()));
} else if (output_format != "") {
printf("WARNING: unrecognized output format \"%s\" ignored.\n",
output_format.c_str());

1
deps/gtest/src/gtest_main.cc

@ -32,7 +32,6 @@
#include "gtest/gtest.h"
GTEST_API_ int main(int argc, char **argv) {
printf("Running main() from gtest_main.cc\n");
testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}

Loading…
Cancel
Save