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>
This commit is contained in:
Ben Noordhuis 2016-08-09 16:37:21 +02:00
Родитель 8dc2b422a9
Коммит c56ae16db2
2 изменённых файлов: 123 добавлений и 2 удалений

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();
}