aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--tests/fuzzy-test/commandlineparser.cpp8
-rw-r--r--tests/fuzzy-test/commandlineparser.h2
-rw-r--r--tests/fuzzy-test/fuzzytester.cpp68
-rw-r--r--tests/fuzzy-test/fuzzytester.h8
-rw-r--r--tests/fuzzy-test/main.cpp17
5 files changed, 80 insertions, 23 deletions
diff --git a/tests/fuzzy-test/commandlineparser.cpp b/tests/fuzzy-test/commandlineparser.cpp
index 9588c00ce..c49381757 100644
--- a/tests/fuzzy-test/commandlineparser.cpp
+++ b/tests/fuzzy-test/commandlineparser.cpp
@@ -37,6 +37,7 @@ static QString profileOption() { return "--profile"; }
static QString startCommitOption() { return "--start-commit"; }
static QString maxDurationoption() { return "--max-duration"; }
static QString jobCountOption() { return "--jobs"; }
+static QString logOption() { return "--log"; }
CommandLineParser::CommandLineParser()
{
@@ -48,6 +49,7 @@ void CommandLineParser::parse(const QStringList &commandLine)
m_startCommit.clear();
m_maxDuration = 0;
m_jobCount = 0;
+ m_log = false;
m_commandLine = commandLine;
Q_ASSERT(!m_commandLine.isEmpty());
m_command = m_commandLine.takeFirst();
@@ -61,6 +63,8 @@ void CommandLineParser::parse(const QStringList &commandLine)
assignOptionArgument(arg, m_jobCount);
else if (arg == maxDurationoption())
parseDuration();
+ else if (arg == logOption())
+ m_log = true;
else
throw ParseException(QString::fromLocal8Bit("Unknown parameter '%1'").arg(arg));
}
@@ -73,9 +77,9 @@ void CommandLineParser::parse(const QStringList &commandLine)
QString CommandLineParser::usageString() const
{
return QString::fromLocal8Bit("%1 %2 <profile> %3 <start commit> [%4 <duration>] "
- "[%5 <job count>]")
+ "[%5 <job count>] [%6]")
.arg(QFileInfo(m_command).fileName(), profileOption(), startCommitOption(),
- maxDurationoption(), jobCountOption());
+ maxDurationoption(), jobCountOption(), logOption());
}
void CommandLineParser::assignOptionArgument(const QString &option, QString &argument)
diff --git a/tests/fuzzy-test/commandlineparser.h b/tests/fuzzy-test/commandlineparser.h
index 8682e9ef4..963ae78e1 100644
--- a/tests/fuzzy-test/commandlineparser.h
+++ b/tests/fuzzy-test/commandlineparser.h
@@ -57,6 +57,7 @@ public:
QString startCommit() const { return m_startCommit; }
int maxDurationInMinutes() const { return m_maxDuration; }
int jobCount() const { return m_jobCount; }
+ bool log() const { return m_log; }
QString usageString() const;
@@ -71,6 +72,7 @@ private:
QString m_startCommit;
int m_maxDuration;
int m_jobCount;
+ bool m_log;
};
#endif // Include guard.
diff --git a/tests/fuzzy-test/fuzzytester.cpp b/tests/fuzzy-test/fuzzytester.cpp
index eb5fdb468..d465a3bdc 100644
--- a/tests/fuzzy-test/fuzzytester.cpp
+++ b/tests/fuzzy-test/fuzzytester.cpp
@@ -31,21 +31,27 @@
#include <QDir>
#include <QElapsedTimer>
+#include <QFile>
#include <QProcess>
#include <algorithm>
#include <cstdlib>
#include <ctime>
+static QString resolveIncrementalActivity() { return "resolve-incremental"; }
+static QString buildIncrementalActivity() { return "build-incremental"; }
+static QString buildFromScratchActivity() { return "build-from-scratch"; }
+
FuzzyTester::FuzzyTester()
{
}
void FuzzyTester::runTest(const QString &profile, const QString &startCommit,
- int maxDurationInMinutes, int jobCount)
+ int maxDurationInMinutes, int jobCount, bool log)
{
m_profile = profile;
m_jobCount = jobCount;
+ m_log = log;
runGit(QStringList() << "rev-parse" << "HEAD", &m_headCommit);
qDebug("HEAD is %s", qPrintable(m_headCommit));
@@ -78,6 +84,7 @@ void FuzzyTester::runTest(const QString &profile, const QString &startCommit,
break;
}
+ m_currentCommit = currentCommit;
buildSequence << currentCommit;
checkoutCommit(currentCommit);
qDebug("Testing incremental build #%d (%s)", buildSequence.count() - 1,
@@ -86,23 +93,32 @@ void FuzzyTester::runTest(const QString &profile, const QString &startCommit,
// Doing "resolve" and "build" separately introduces additional possibilities
// for errors, as information from change tracking has to be serialized correctly.
QString qbsError;
+ m_currentActivity = resolveIncrementalActivity();
bool success = runQbs(defaultBuildDir(), QLatin1String("resolve"), &qbsError);
- if (success)
+ if (success) {
+ m_currentActivity = buildIncrementalActivity();
success = runQbs(defaultBuildDir(), QLatin1String("build"), &qbsError);
+ }
+ m_currentActivity = buildFromScratchActivity();
if (success) {
if (!doCleanBuild(&qbsError)) {
- const QString message = QString::fromLocal8Bit("An incremental build succeeded "
- "with a commit for which a clean build failed.\n"
- "The qbs error message for the clean build was: '%1'").arg(qbsError);
+ QString message = "An incremental build succeeded "
+ "with a commit for which a clean build failed.";
+ if (!m_log) {
+ message += QString::fromLocal8Bit("\nThe qbs error message "
+ "for the clean build was: '%1'").arg(qbsError);
+ }
throwIncrementalBuildError(message, buildSequence);
}
} else {
qDebug("Incremental build failed. Checking whether clean build works...");
if (doCleanBuild()) {
- const QString message = QString::fromLocal8Bit("An incremental build failed "
- "with a commit for which a clean build succeeded.\n"
- "The qbs error message for the incremental build was: '%1'")
- .arg(qbsError);
+ QString message = "An incremental build failed "
+ "with a commit for which a clean build succeeded.";
+ if (!m_log) {
+ message += QString::fromLocal8Bit("\nThe qbs error message for "
+ "the incremental build was: '%1'").arg(qbsError);
+ }
throwIncrementalBuildError(message, buildSequence);
} else {
qDebug("Clean build also fails. Continuing.");
@@ -128,17 +144,19 @@ QStringList FuzzyTester::findAllCommits(const QString &startCommit)
QString allCommitsString;
runGit(QStringList() << "log" << (startCommit + "~1.." + m_headCommit) << "--format=format:%h",
&allCommitsString);
- return allCommitsString.simplified().split(QLatin1Char(' '));
+ return allCommitsString.simplified().split(QLatin1Char(' '), QString::SkipEmptyParts);
}
QString FuzzyTester::findWorkingStartCommit(const QString &startCommit)
{
const QStringList allCommits = findAllCommits(startCommit);
QString qbsError;
+ m_currentActivity = buildFromScratchActivity();
for (int i = allCommits.count() - 1; i >= 0; --i) {
QString currentCommit = allCommits.at(i);
checkoutCommit(currentCommit);
removeDir(defaultBuildDir());
+ m_currentCommit = currentCommit;
if (runQbs(defaultBuildDir(), QLatin1String("build"), &qbsError))
return currentCommit;
qDebug("Commit %s is not buildable.", qPrintable(currentCommit));
@@ -168,13 +186,32 @@ bool FuzzyTester::runQbs(const QString &buildDir, const QString &command, QStrin
if (errorOutput)
errorOutput->clear();
QProcess qbs;
- QStringList commandLine = QStringList(command) << "-qq" << "-d" << buildDir;
+ QStringList commandLine = QStringList(command) << "-d" << buildDir;
+ if (m_log) {
+ commandLine << "-vv";
+ const int maxLoggedCommits = 2;
+ Q_ASSERT(m_commitsWithLogFiles.count() <= maxLoggedCommits + 1);
+ if (m_commitsWithLogFiles.count() == maxLoggedCommits + 1) {
+ static const QStringList allActivities = QStringList() << resolveIncrementalActivity()
+ << buildIncrementalActivity() << buildFromScratchActivity();
+ const QString oldCommit = m_commitsWithLogFiles.dequeue();
+ foreach (const QString &a, allActivities)
+ QFile::remove(logFilePath(oldCommit, a));
+ }
+ qbs.setStandardErrorFile(logFilePath(m_currentCommit, m_currentActivity));
+ if (m_commitsWithLogFiles.isEmpty() || m_commitsWithLogFiles.last() != m_currentCommit)
+ m_commitsWithLogFiles.enqueue(m_currentCommit);
+ } else {
+ commandLine << "-qq";
+ }
if (m_jobCount != 0)
commandLine << "--jobs" << QString::number(m_jobCount);
commandLine << ("profile:" + m_profile);
qbs.start("qbs", commandLine);
- if (!qbs.waitForStarted())
- throw TestError("Failed to start qbs. It is expected to be in the PATH.");
+ if (!qbs.waitForStarted()) {
+ throw TestError(QString::fromLocal8Bit("Failed to start qbs. It is expected to be "
+ "in the PATH. QProcess error string: '%1'").arg(qbs.errorString()));
+ }
if (!qbs.waitForFinished(-1) || qbs.exitCode() != 0) {
if (errorOutput)
*errorOutput = QString::fromLocal8Bit(qbs.readAllStandardError());
@@ -208,6 +245,11 @@ void FuzzyTester::throwIncrementalBuildError(const QString &message,
"The sequence of commits was: %2.").arg(message, commitSequenceString));
}
+QString FuzzyTester::logFilePath(const QString &commit, const QString &activity)
+{
+ return "log." + commit + '.' + activity;
+}
+
QString FuzzyTester::defaultBuildDir()
{
return "fuzzytest-build";
diff --git a/tests/fuzzy-test/fuzzytester.h b/tests/fuzzy-test/fuzzytester.h
index 4639e7394..1ae8a602c 100644
--- a/tests/fuzzy-test/fuzzytester.h
+++ b/tests/fuzzy-test/fuzzytester.h
@@ -30,6 +30,7 @@
#ifndef QBS_FUZZYTESTER_H
#define QBS_FUZZYTESTER_H
+#include <QQueue>
#include <QString>
#include <exception>
@@ -56,7 +57,7 @@ public:
FuzzyTester();
void runTest(const QString &profile, const QString &startCommit, int maxDurationInMinutes,
- int jobCount);
+ int jobCount, bool log);
private:
void checkoutCommit(const QString &commit);
@@ -68,11 +69,16 @@ private:
bool doCleanBuild(QString *errorMessage = 0);
void throwIncrementalBuildError(const QString &message, const QStringList &commitSequence);
+ static QString logFilePath(const QString &commit, const QString &activity);
static QString defaultBuildDir();
QString m_profile;
int m_jobCount;
+ bool m_log;
QString m_headCommit;
+ QString m_currentCommit;
+ QString m_currentActivity;
+ QQueue<QString> m_commitsWithLogFiles;
};
#endif // Include guard.
diff --git a/tests/fuzzy-test/main.cpp b/tests/fuzzy-test/main.cpp
index efc503d1f..1bd8ee26c 100644
--- a/tests/fuzzy-test/main.cpp
+++ b/tests/fuzzy-test/main.cpp
@@ -37,9 +37,9 @@
#include <iostream>
static bool parseCommandLine(const QStringList &commandLine, QString &profile,
- QString &startCommi, int &maxDuration, int &jobCount);
+ QString &startCommi, int &maxDuration, int &jobCount, bool &log);
static bool runTest(const QString &profile, const QString &startCommit, int maxDuration,
- int jobCount);
+ int jobCount, bool log);
int main(int argc, char *argv[])
{
@@ -49,16 +49,17 @@ int main(int argc, char *argv[])
QString startCommit;
int maxDuration;
int jobCount;
- if (!parseCommandLine(app.arguments(), profile, startCommit, maxDuration, jobCount))
+ bool log;
+ if (!parseCommandLine(app.arguments(), profile, startCommit, maxDuration, jobCount, log))
return EXIT_FAILURE;
- if (!runTest(profile, startCommit, maxDuration, jobCount))
+ if (!runTest(profile, startCommit, maxDuration, jobCount, log))
return EXIT_FAILURE;
std::cout << "Test finished successfully." << std::endl;
return EXIT_SUCCESS;
}
bool parseCommandLine(const QStringList &commandLine, QString &profile, QString &startCommit,
- int &maxDuration, int &jobCount)
+ int &maxDuration, int &jobCount, bool &log)
{
CommandLineParser cmdParser;
try {
@@ -72,13 +73,15 @@ bool parseCommandLine(const QStringList &commandLine, QString &profile, QString
startCommit = cmdParser.startCommit();
maxDuration = cmdParser.maxDurationInMinutes();
jobCount = cmdParser.jobCount();
+ log = cmdParser.log();
return true;
}
-bool runTest(const QString &profile, const QString &startCommit, int maxDuration, int jobCount)
+bool runTest(const QString &profile, const QString &startCommit, int maxDuration, int jobCount,
+ bool log)
{
try {
- FuzzyTester().runTest(profile, startCommit, maxDuration, jobCount);
+ FuzzyTester().runTest(profile, startCommit, maxDuration, jobCount, log);
} catch (const TestError &e) {
std::cerr << qPrintable(e.errorMessage) << std::endl;
return false;