+ std::string outputFilename = ChildOutputFilename(testCase.childPid);
+ std::string testOutput = ReadAndEscape(outputFilename);
+
+ ofs << "<testcase component=\"CoreAPI/" << testSuiteName << "/default\" execution_type=\"auto\" id=\""
+ << testCase.name << "\" purpose=\"\" result=\"" << (testCase.result == 0 ? "PASS" : "FAIL") << "\">" << std::endl
+ << "<description><test_script_entry test_script_expected_result=\"0\">"
+ << pathToExecutable << testCase.name << "</test_script_entry>" << std::endl
+ << "</description>"
+ << "<result_info><actual_result>" << (testCase.result == 0 ? "PASS" : "FAIL") << "</actual_result>" << std::endl
+ << "<start>" << startTime << "</start>"
+ << "<end>" << endTime << "</end>"
+ << "<stdout><![CDATA[]]></stdout>"
+ << "<stderr><![CDATA[" << testOutput << "]]></stderr></result_info></testcase>" << std::endl;
+
+ unlink(outputFilename.c_str());
+}
+
+void OutputTestResults(const char* processName, RunningTestCases& children)
+{
+ std::ofstream ofs;
+ std::string filename = TestModuleFilename(processName);
+ std::string moduleName = TestModuleName(processName);
+ ofs.open(filename, std::ofstream::out | std::ofstream::app);
+
+ // Sort completed cases by original test case id
+ std::vector<TestCase> childTestCases;
+ childTestCases.reserve(children.size());
+ for(auto& element : children) childTestCases.push_back(element.second);
+ std::sort(childTestCases.begin(), childTestCases.end(), [](const TestCase& a, const TestCase& b) {
+ return a.testCase < b.testCase;
+ });
+
+ const int BUFSIZE = 256;
+ char buffer[BUFSIZE];
+ for(auto& testCase : childTestCases)
+ {
+ auto tt = system_clock::to_time_t(testCase.startSystemTime);
+ strftime(buffer, BUFSIZE, "%c", localtime(&tt));
+ std::string startTime(buffer);
+ OutputTestResult(ofs, processName, moduleName, testCase, startTime, startTime);
+ }
+
+ ofs.close();
+}
+
+void OutputStatistics(const char* processName, int32_t numPasses, int32_t numFailures)
+{
+ FILE* fp = fopen("summary.xml", "a");
+ if(fp != NULL)
+ {
+ fprintf(fp,
+ " <suite name=\"%s-tests\">\n"
+ " <total_case>%d</total_case>\n"
+ " <pass_case>%d</pass_case>\n"
+ " <pass_rate>%5.2f</pass_rate>\n"
+ " <fail_case>%d</fail_case>\n"
+ " <fail_rate>%5.2f</fail_rate>\n"
+ " <block_case>0</block_case>\n"
+ " <block_rate>0.00</block_rate>\n"
+ " <na_case>0</na_case>\n"
+ " <na_rate>0.00</na_rate>\n"
+ " </suite>\n",
+ basename(processName),
+ numPasses + numFailures,
+ numPasses,
+ (float)numPasses * 100.0f / (numPasses + numFailures),
+ numFailures,
+ (float)numFailures * 100.0f / (numPasses + numFailures));
+ fclose(fp);
+ }
+}
+
+int32_t RunTestCase(struct ::testcase_s& testCase)
+{
+ int32_t result = EXIT_STATUS_TESTCASE_FAILED;