Remove appveyor integration from catch

This commit is contained in:
baldurk
2022-05-17 12:41:12 +01:00
parent abe645f031
commit d6c7bbb90d
-209
View File
@@ -41,215 +41,6 @@ rdcstr DoStringise(const Catch::SourceLineInfo &el)
return StringFormat::Fmt("%s:%zu", el.file, el.line);
}
struct AppVeyorListener : Catch::TestEventListenerBase
{
using TestEventListenerBase::TestEventListenerBase; // inherit constructor
rdcstr errorList;
double durationInSeconds = 0.0;
struct TestCase
{
double durationInSeconds;
bool passed;
rdcstr errorList;
rdcstr name;
rdcstr filename;
rdcstr MakeJSON();
};
rdcarray<TestCase> m_testcases;
virtual bool assertionEnded(Catch::AssertionStats const &assertionStats) override
{
Catch::TestEventListenerBase::assertionEnded(assertionStats);
using namespace Catch;
if(!assertionStats.assertionResult.isOk())
{
std::ostringstream msg;
msg << "-------------------------------------------------------------------------------\n";
for(size_t i = 0; i < m_sectionStack.size(); i++)
{
if(i > 0)
msg << " > ";
msg << m_sectionStack[i].name;
msg << "\n";
}
msg << "-------------------------------------------------------------------------------\n";
msg << assertionStats.assertionResult.getSourceInfo() << ": ";
switch(assertionStats.assertionResult.getResultType())
{
case ResultWas::ExpressionFailed: msg << "Failed"; break;
case ResultWas::ThrewException: msg << "Threw exception"; break;
case ResultWas::FatalErrorCondition: msg << "Fatal error'd"; break;
case ResultWas::DidntThrowException: msg << "Didn't throw expected exception"; break;
case ResultWas::ExplicitFailure: msg << "Explicitly failed"; break;
case ResultWas::Ok:
case ResultWas::Info:
case ResultWas::Warning:
case ResultWas::Unknown:
case ResultWas::FailureBit:
case ResultWas::Exception: break;
}
if(assertionStats.infoMessages.size() >= 1)
msg << " with message(s):";
for(auto it = assertionStats.infoMessages.begin(); it != assertionStats.infoMessages.end(); ++it)
msg << "\n" << it->message;
if(assertionStats.assertionResult.hasExpression())
{
msg << "\n " << assertionStats.assertionResult.getExpressionInMacro()
<< "\nwith expansion:\n " << assertionStats.assertionResult.getExpandedExpression()
<< "\n";
}
std::string formatted = msg.str();
errorList += rdcstr(formatted.c_str(), formatted.size());
}
return true;
}
virtual void sectionEnded(Catch::SectionStats const &sectionStats) override
{
durationInSeconds += sectionStats.durationInSeconds;
Catch::TestEventListenerBase::sectionEnded(sectionStats);
}
virtual void testCaseEnded(Catch::TestCaseStats const &testCaseStats) override
{
m_testcases.push_back({
durationInSeconds, testCaseStats.totals.assertions.allOk(), errorList,
rdcstr(testCaseStats.testInfo.name.c_str(), testCaseStats.testInfo.name.size()),
testCaseStats.testInfo.lineInfo.file,
});
errorList.clear();
durationInSeconds = 0.0;
Catch::TestEventListenerBase::testCaseEnded(testCaseStats);
}
// we dump all the test data at the end, because appveyor can't be trusted to get it right
// incrementally. This means if the program crashes mid-run we don't get partial test output, but
// it should at least by identified as an issue.
virtual void testRunEnded(Catch::TestRunStats const &testRunStats) override
{
rdcstr url = Process::GetEnvVariable("APPVEYOR_API_URL");
if(!url.empty())
{
if(!url.beginsWith("http://"))
return;
const char *urlc = url.c_str();
urlc += 7;
const char *sep = strchr(urlc, ':');
if(!sep)
return;
rdcstr hostname = rdcstr(urlc, sep - urlc);
urlc = sep + 1;
uint16_t port = 0;
while(*urlc >= '0' && *urlc <= '9')
{
port *= 10;
port += int((*urlc) - '0');
urlc++;
}
Network::Socket *sock = Network::CreateClientSocket(hostname, port, 10);
if(sock)
{
rdcstr json;
json += "[\n";
for(size_t i = 0; i < m_testcases.size(); i++)
{
json += m_testcases[i].MakeJSON();
if(i + 1 < m_testcases.size())
json += ",";
json += "\n";
}
json += "]";
rdcstr http;
http += StringFormat::Fmt("POST /api/tests/batch HTTP/1.1\r\n");
http += StringFormat::Fmt("Host: %s\r\n", hostname.c_str());
http += "Connection: close\r\n";
http += "Content-Type: application/json\r\n";
http += StringFormat::Fmt("Content-Length: %zu\r\n", json.size());
http += "User-Agent: Catch.hpp appveyor updater\r\n";
http += "\r\n";
http += json;
sock->SendDataBlocking(http.c_str(), (uint32_t)http.size());
}
SAFE_DELETE(sock);
}
}
};
static rdcstr escape(const rdcstr &input)
{
rdcstr ret = input;
int i = ret.find_first_of("\"\n\\", 0);
while(i >= 0)
{
if(ret[i] == '"')
ret.replace(i, 1, "\\\"");
else if(ret[i] == '\\')
ret.replace(i, 1, "\\\\");
else if(ret[i] == '\n')
ret.replace(i, 1, "\\n");
i = ret.find_first_of("\"\n\\", i + 2);
}
return ret;
}
rdcstr AppVeyorListener::TestCase::MakeJSON()
{
rdcstr json;
errorList.trim();
return StringFormat::Fmt(
R"({
"testName": "%s",
"testFramework": "Catch.hpp",
"fileName": "%s",
"outcome": "%s",
"durationMilliseconds": "%d",
"ErrorMessage": "%s",
"ErrorStackTrace": "",
"StdOut": "",
"StdErr": ""
})",
escape(name).c_str(), escape(filename).c_str(), passed ? "Passed" : "Failed",
(int)RDCMAX(durationInSeconds * 1000.0, 0.0), escape(errorList).c_str());
}
CATCH_REGISTER_LISTENER(AppVeyorListener)
class LogOutputter : public std::stringbuf
{
public: