mirror of
https://github.com/baldurk/renderdoc.git
synced 2026-05-04 09:00:44 +00:00
Remove appveyor integration from catch
This commit is contained in:
Vendored
-209
@@ -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 §ionStats) 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:
|
||||
|
||||
Reference in New Issue
Block a user