218 lines
5.7 KiB
C++
218 lines
5.7 KiB
C++
|
/*-------------------------------------------------------------------------
|
||
|
* drawElements Quality Program Test Executor
|
||
|
* ------------------------------------------
|
||
|
*
|
||
|
* Copyright 2014 The Android Open Source Project
|
||
|
*
|
||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||
|
* you may not use this file except in compliance with the License.
|
||
|
* You may obtain a copy of the License at
|
||
|
*
|
||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||
|
*
|
||
|
* Unless required by applicable law or agreed to in writing, software
|
||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||
|
* See the License for the specific language governing permissions and
|
||
|
* limitations under the License.
|
||
|
*
|
||
|
*//*!
|
||
|
* \file
|
||
|
* \brief Merge two test logs.
|
||
|
*
|
||
|
* \todo [2013-11-08 pyry] Write variant that can operate with less memory.
|
||
|
*//*--------------------------------------------------------------------*/
|
||
|
|
||
|
#include "xeTestLogParser.hpp"
|
||
|
#include "xeTestResultParser.hpp"
|
||
|
#include "xeTestLogWriter.hpp"
|
||
|
#include "deString.h"
|
||
|
|
||
|
#include <vector>
|
||
|
#include <string>
|
||
|
#include <cstdio>
|
||
|
#include <cstdlib>
|
||
|
#include <fstream>
|
||
|
#include <iostream>
|
||
|
#include <stdexcept>
|
||
|
|
||
|
using std::vector;
|
||
|
using std::string;
|
||
|
using std::set;
|
||
|
using std::map;
|
||
|
|
||
|
enum Flags
|
||
|
{
|
||
|
FLAG_USE_LAST_INFO = (1<<0)
|
||
|
};
|
||
|
|
||
|
struct CommandLine
|
||
|
{
|
||
|
CommandLine (void)
|
||
|
: flags(0)
|
||
|
{
|
||
|
}
|
||
|
|
||
|
vector<string> srcFilenames;
|
||
|
string dstFilename;
|
||
|
deUint32 flags;
|
||
|
};
|
||
|
|
||
|
class LogHandler : public xe::TestLogHandler
|
||
|
{
|
||
|
public:
|
||
|
LogHandler (xe::BatchResult* batchResult, deUint32 flags)
|
||
|
: m_batchResult (batchResult)
|
||
|
, m_flags (flags)
|
||
|
{
|
||
|
}
|
||
|
|
||
|
void setSessionInfo (const xe::SessionInfo& info)
|
||
|
{
|
||
|
xe::SessionInfo& combinedInfo = m_batchResult->getSessionInfo();
|
||
|
|
||
|
if (m_flags & FLAG_USE_LAST_INFO)
|
||
|
{
|
||
|
if (!info.targetName.empty()) combinedInfo.targetName = info.targetName;
|
||
|
if (!info.releaseId.empty()) combinedInfo.releaseId = info.releaseId;
|
||
|
if (!info.releaseName.empty()) combinedInfo.releaseName = info.releaseName;
|
||
|
if (!info.candyTargetName.empty()) combinedInfo.candyTargetName = info.candyTargetName;
|
||
|
if (!info.configName.empty()) combinedInfo.configName = info.configName;
|
||
|
if (!info.resultName.empty()) combinedInfo.resultName = info.resultName;
|
||
|
if (!info.timestamp.empty()) combinedInfo.timestamp = info.timestamp;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if (combinedInfo.targetName.empty()) combinedInfo.targetName = info.targetName;
|
||
|
if (combinedInfo.releaseId.empty()) combinedInfo.releaseId = info.releaseId;
|
||
|
if (combinedInfo.releaseName.empty()) combinedInfo.releaseName = info.releaseName;
|
||
|
if (combinedInfo.candyTargetName.empty()) combinedInfo.candyTargetName = info.candyTargetName;
|
||
|
if (combinedInfo.configName.empty()) combinedInfo.configName = info.configName;
|
||
|
if (combinedInfo.resultName.empty()) combinedInfo.resultName = info.resultName;
|
||
|
if (combinedInfo.timestamp.empty()) combinedInfo.timestamp = info.timestamp;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
xe::TestCaseResultPtr startTestCaseResult (const char* casePath)
|
||
|
{
|
||
|
if (m_batchResult->hasTestCaseResult(casePath))
|
||
|
{
|
||
|
xe::TestCaseResultPtr existingResult = m_batchResult->getTestCaseResult(casePath);
|
||
|
existingResult->clear();
|
||
|
return existingResult;
|
||
|
}
|
||
|
else
|
||
|
return m_batchResult->createTestCaseResult(casePath);
|
||
|
}
|
||
|
|
||
|
void testCaseResultUpdated (const xe::TestCaseResultPtr&)
|
||
|
{
|
||
|
// Ignored.
|
||
|
}
|
||
|
|
||
|
void testCaseResultComplete (const xe::TestCaseResultPtr&)
|
||
|
{
|
||
|
// Ignored.
|
||
|
}
|
||
|
|
||
|
private:
|
||
|
xe::BatchResult* const m_batchResult;
|
||
|
const deUint32 m_flags;
|
||
|
};
|
||
|
|
||
|
static void readLogFile (xe::BatchResult* dstResult, const char* filename, deUint32 flags)
|
||
|
{
|
||
|
std::ifstream in (filename, std::ifstream::binary|std::ifstream::in);
|
||
|
LogHandler resultHandler (dstResult, flags);
|
||
|
xe::TestLogParser parser (&resultHandler);
|
||
|
deUint8 buf [2048];
|
||
|
int numRead = 0;
|
||
|
|
||
|
if (!in.good())
|
||
|
throw std::runtime_error(string("Failed to open '") + filename + "'");
|
||
|
|
||
|
for (;;)
|
||
|
{
|
||
|
in.read((char*)&buf[0], DE_LENGTH_OF_ARRAY(buf));
|
||
|
numRead = (int)in.gcount();
|
||
|
|
||
|
if (numRead <= 0)
|
||
|
break;
|
||
|
|
||
|
parser.parse(&buf[0], numRead);
|
||
|
}
|
||
|
|
||
|
in.close();
|
||
|
}
|
||
|
|
||
|
static void mergeTestLogs (const CommandLine& cmdLine)
|
||
|
{
|
||
|
xe::BatchResult batchResult;
|
||
|
|
||
|
for (vector<string>::const_iterator filename = cmdLine.srcFilenames.begin(); filename != cmdLine.srcFilenames.end(); ++filename)
|
||
|
readLogFile(&batchResult, filename->c_str(), cmdLine.flags);
|
||
|
|
||
|
if (!cmdLine.dstFilename.empty())
|
||
|
xe::writeBatchResultToFile(batchResult, cmdLine.dstFilename.c_str());
|
||
|
else
|
||
|
xe::writeTestLog(batchResult, std::cout);
|
||
|
}
|
||
|
|
||
|
static void printHelp (const char* binName)
|
||
|
{
|
||
|
printf("%s: [filename] [[filename 2] ...]\n", binName);
|
||
|
printf(" --dst=[filename] Write final log to file, otherwise written to stdout.\n");
|
||
|
printf(" --info=[first|last] Select which session info to use (default: first).\n");
|
||
|
}
|
||
|
|
||
|
static bool parseCommandLine (CommandLine& cmdLine, int argc, const char* const* argv)
|
||
|
{
|
||
|
for (int argNdx = 1; argNdx < argc; argNdx++)
|
||
|
{
|
||
|
const char* arg = argv[argNdx];
|
||
|
|
||
|
if (!deStringBeginsWith(arg, "--"))
|
||
|
cmdLine.srcFilenames.push_back(arg);
|
||
|
else if (deStringBeginsWith(arg, "--dst="))
|
||
|
{
|
||
|
if (!cmdLine.dstFilename.empty())
|
||
|
return false;
|
||
|
cmdLine.dstFilename = arg+6;
|
||
|
}
|
||
|
else if (deStringEqual(arg, "--info=first"))
|
||
|
cmdLine.flags &= ~FLAG_USE_LAST_INFO;
|
||
|
else if (deStringEqual(arg, "--info=last"))
|
||
|
cmdLine.flags |= FLAG_USE_LAST_INFO;
|
||
|
else
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
if (cmdLine.srcFilenames.empty())
|
||
|
return false;
|
||
|
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
int main (int argc, const char* const* argv)
|
||
|
{
|
||
|
try
|
||
|
{
|
||
|
CommandLine cmdLine;
|
||
|
|
||
|
if (!parseCommandLine(cmdLine, argc, argv))
|
||
|
{
|
||
|
printHelp(argv[0]);
|
||
|
return -1;
|
||
|
}
|
||
|
|
||
|
mergeTestLogs(cmdLine);
|
||
|
}
|
||
|
catch (const std::exception& e)
|
||
|
{
|
||
|
printf("FATAL ERROR: %s\n", e.what());
|
||
|
return -1;
|
||
|
}
|
||
|
|
||
|
return 0;
|
||
|
}
|