Files
qt-creator/src/plugins/autotest/boost/boosttestconfiguration.cpp
Jarek Kobus 4f70aa7052 TestRunner: Reuse TaskTree
Get rid of QFutureInterface argument from
ITestConfiguration::createOutputReader() and from
TestOutputReader c'tor.

The fine-grained progress reporting was broken anyway:

1. The assumption was that testCaseCount was meant to be
   the total number of test functions executed. It didn't
   include the initTestCase() and cleanupTestCase(),
   while those were reported on runtime apparently
   (and exceeding the max progress by 2).
2. In case of tst_qtcprocess, when the whole test was run,
   the testCaseCount reported 41, while the real
   number of functions was 26 (+2 = 28 for init/cleanup).
3. While the max progress was set to testCaseCount initially,
   the corresponding FutureProgress rendered the progress
   always in 0-100 range, what didn't match the reality.

Instead, rely on TaskTree progress, which resolution
is per test as a whole. So, when executing a series
of tests this should scale fine. In addition, the
progress advances fluently according to the expected
run time - with 10 seconds hardcoded.

The original code locations, where progress was bumped,
are left with a TODO comment for any possible future tweaks.
Like in case of result reporting, fine-grained progress
reporting may be implemented by providing additional signal,
so there is no need for QFutureInterface inside
TestOutputReader.

Change-Id: Idc11d55e3a49dac8d1788948b9a82f68199203c6
Reviewed-by: <github-actions-qt-creator@cristianadam.eu>
Reviewed-by: Christian Stenger <christian.stenger@qt.io>
2023-02-03 08:15:58 +00:00

130 lines
4.9 KiB
C++

// Copyright (C) 2019 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#include "boosttestconfiguration.h"
#include "boosttestoutputreader.h"
#include "boosttestsettings.h"
#include "../autotestplugin.h"
#include "../itestframework.h"
#include "../testsettings.h"
#include <utils/algorithm.h>
using namespace Utils;
namespace Autotest {
namespace Internal {
TestOutputReader *BoostTestConfiguration::createOutputReader(QtcProcess *app) const
{
auto settings = static_cast<BoostTestSettings *>(framework()->testSettings());
return new BoostTestOutputReader(app, buildDirectory(), projectFile(),
LogLevel(settings->logLevel.value()),
ReportLevel(settings->reportLevel.value()));
}
enum class InterferingType { Options, EnvironmentVariables };
static QStringList interfering(InterferingType type)
{
const QStringList knownInterfering { "log_level", "log_format", "log_sink",
"report_level", "report_format", "report_sink",
"output_format",
"catch_system_errors", "no_catch_system_errors",
"detect_fp_exceptions", "no_detect_fp_exceptions",
"detect_memory_leaks", "random", "run_test",
"show_progress", "result_code", "no_result_code",
"help", "list_content", "list_labels", "version"
};
switch (type) {
case InterferingType::Options:
return Utils::transform(knownInterfering, [](const QString &item) {
return QString("--" + item);
});
case InterferingType::EnvironmentVariables:
return Utils::transform(knownInterfering, [](const QString &item) {
return QString("BOOST_TEST_" + item).toUpper();
});
}
return QStringList();
}
static QStringList filterInterfering(const QStringList &provided, QStringList *omitted)
{
const QStringList knownInterfering = interfering(InterferingType::Options);
const QString interferingSingleWithParam = "efklortcpsx?";
QStringList allowed;
bool filterNextArg = false;
bool ignoreRest = false;
for (const auto &arg : provided) {
bool filterArg = filterNextArg;
filterNextArg = false;
if (ignoreRest) {
allowed.append(arg);
continue;
}
bool interferes = false;
if (filterArg && !arg.startsWith('-')) {
interferes = true;
} else if (arg.startsWith("--")) {
if (arg.size() == 2)
ignoreRest = true;
else
interferes = knownInterfering.contains(arg.left(arg.indexOf('=')));
} else if (arg.startsWith('-') && arg.size() > 1) {
interferes = interferingSingleWithParam.contains(arg.at(1));
filterNextArg = interferes;
}
if (!interferes)
allowed.append(arg);
else if (omitted)
omitted->append(arg);
}
return allowed;
}
QStringList BoostTestConfiguration::argumentsForTestRunner(QStringList *omitted) const
{
auto boostSettings = static_cast<BoostTestSettings *>(framework()->testSettings());
QStringList arguments;
arguments << "-l" << BoostTestSettings::logLevelToOption(LogLevel(boostSettings->logLevel.value()));
arguments << "-r" << BoostTestSettings::reportLevelToOption(ReportLevel(boostSettings->reportLevel.value()));
if (boostSettings->randomize.value())
arguments << QString("--random=").append(QString::number(boostSettings->seed.value()));
if (boostSettings->systemErrors.value())
arguments << "-s";
if (boostSettings->fpExceptions.value())
arguments << "--detect_fp_exceptions";
if (!boostSettings->memLeaks.value())
arguments << "--detect_memory_leaks=0";
// TODO improve the test case gathering and arguments building to avoid too long command lines
for (const QString &test : testCases())
arguments << "-t" << test;
if (AutotestPlugin::settings()->processArgs) {
arguments << filterInterfering(runnable().command.arguments().split(
' ', Qt::SkipEmptyParts), omitted);
}
return arguments;
}
Environment BoostTestConfiguration::filteredEnvironment(const Environment &original) const
{
const QStringList interferingEnv = interfering(InterferingType::EnvironmentVariables);
Environment result = original;
if (!result.hasKey("BOOST_TEST_COLOR_OUTPUT"))
result.set("BOOST_TEST_COLOR_OUTPUT", "1"); // use colored output by default
for (const QString &key : interferingEnv)
result.unset(key);
return result;
}
} // namespace Internal
} // namespace Autotest