Debugger: Make some of the plugin tests compilable again

Change-Id: I5c3885cb385dc1c15dce14f2ff52bf70edee8399
Reviewed-by: Christian Stenger <christian.stenger@theqtcompany.com>
This commit is contained in:
hjk
2016-03-09 19:16:14 +01:00
parent 6cecb7e4db
commit 35a16cc394
11 changed files with 241 additions and 286 deletions

View File

@@ -34,6 +34,7 @@
#include "debuggerdialogs.h"
#include "debuggerengine.h"
#include "debuggericons.h"
#include "debuggeritem.h"
#include "debuggeritemmanager.h"
#include "debuggermainwindow.h"
#include "debuggerrunconfigurationaspect.h"
@@ -84,7 +85,6 @@
#include <coreplugin/editormanager/documentmodel.h>
#include <coreplugin/editormanager/editormanager.h>
#include <coreplugin/find/itemviewfind.h>
#include <coreplugin/findplaceholder.h>
#include <coreplugin/icore.h>
#include <coreplugin/imode.h>
#include <coreplugin/messagebox.h>
@@ -98,8 +98,6 @@
#include <cppeditor/cppeditorconstants.h>
#include <cpptools/cppmodelmanager.h>
#include <extensionsystem/invoker.h>
#include <projectexplorer/buildconfiguration.h>
#include <projectexplorer/buildmanager.h>
#include <projectexplorer/devicesupport/deviceprocessesdialog.h>
@@ -160,14 +158,11 @@
#include <QVariant>
#include <QtPlugin>
using namespace Core;
using namespace Utils;
using namespace Core::Constants;
using namespace ProjectExplorer;
using namespace Debugger;
using namespace Debugger::Internal;
#ifdef WITH_TESTS
#include <cpptools/cpptoolstestcase.h>
#include <cpptools/projectinfo.h>
#include <QTest>
#include <QSignalSpy>
#include <QTestEventLoop>
@@ -414,6 +409,7 @@ sg1: }
\endcode */
using namespace Core;
using namespace Core::Constants;
using namespace Debugger::Constants;
using namespace Debugger::Internal;
using namespace ExtensionSystem;
@@ -427,16 +423,6 @@ namespace PE = ProjectExplorer::Constants;
namespace Debugger {
namespace Internal {
struct TestCallBack
{
TestCallBack() : receiver(0), slot(0) {}
TestCallBack(QObject *ob, const char *s) : receiver(ob), slot(s) {}
QObject *receiver;
const char *slot;
QVariant cookie;
};
void addCdbOptionPages(QList<IOptionsPage*> *opts);
void addGdbOptionPages(QList<IOptionsPage*> *opts);
QObject *createDebuggerRunControlFactory(QObject *parent);
@@ -718,7 +704,7 @@ public:
void attachToRunningApplication();
void attachToUnstartedApplicationDialog();
void attachToQmlPort();
Q_SLOT void runScheduled();
void runScheduled();
void attachCore();
void enableReverseDebuggingTriggered(const QVariant &value);
@@ -745,31 +731,6 @@ public:
void coreShutdown();
#ifdef WITH_TESTS
public slots:
void testLoadProject(const QString &proFile, const TestCallBack &cb);
void testProjectLoaded(Project *project);
void testProjectEvaluated();
void testProjectBuilt(bool success);
void testUnloadProject();
void testFinished();
void testRunProject(const DebuggerRunParameters &sp, const TestCallBack &cb);
void testRunControlFinished();
// void testStateMachine1();
// void testStateMachine2();
// void testStateMachine3();
void testBenchmark1();
public:
Project *m_testProject;
bool m_testSuccess;
QList<TestCallBack> m_testCallbacks;
#endif
public:
void updateDebugActions();
@@ -1227,7 +1188,7 @@ void DebuggerPluginPrivate::parseCommandLineArguments()
MessageManager::write(errorMessage);
}
if (!m_scheduledStarts.isEmpty())
QTimer::singleShot(0, this, SLOT(runScheduled()));
QTimer::singleShot(0, this, &DebuggerPluginPrivate::runScheduled);
}
bool DebuggerPluginPrivate::initialize(const QStringList &arguments,
@@ -3583,146 +3544,93 @@ bool operator==(const AnalyzerConnection &c1, const AnalyzerConnection &c2)
&& c1.analyzerPort == c2.analyzerPort;
}
namespace Internal {
static bool s_testRun = false;
bool isTestRun() { return s_testRun; }
#ifdef WITH_TESTS
void DebuggerPluginPrivate::testLoadProject(const QString &proFile, const TestCallBack &cb)
class DebuggerUnitTests : public QObject
{
connect(ProjectTree::instance(), &ProjectTree::currentProjectChanged,
this, &DebuggerPluginPrivate::testProjectLoaded);
Q_OBJECT
m_testCallbacks.append(cb);
ProjectExplorerPlugin::OpenProjectResult result = ProjectExplorerPlugin::openProject(proFile);
if (result) {
// Will end up in callback below due to the connections to
// signal currentProjectChanged().
return;
}
public:
DebuggerUnitTests() {}
// Project opening failed. Eat the unused callback.
qWarning("Cannot open %s: %s", qPrintable(proFile), qPrintable(result.errorMessage()));
QVERIFY(false);
m_testCallbacks.pop_back();
private slots:
void initTestCase();
void cleanupTestCase();
void testDebuggerMatching_data();
void testDebuggerMatching();
void testBenchmark();
void testStateMachine();
private:
CppTools::Tests::TemporaryCopiedDir *m_tmpDir = 0;
};
void DebuggerUnitTests::initTestCase()
{
// const QList<Kit *> allKits = KitManager::kits();
// if (allKits.count() != 1)
// QSKIP("This test requires exactly one kit to be present");
// const ToolChain * const toolchain = ToolChainKitInformation::toolChain(allKits.first());
// if (!toolchain)
// QSKIP("This test requires that there is a kit with a toolchain.");
// bool hasClangExecutable;
// clangExecutableFromSettings(toolchain->typeId(), &hasClangExecutable);
// if (!hasClangExecutable)
// QSKIP("No clang suitable for analyzing found");
s_testRun = true;
m_tmpDir = new CppTools::Tests::TemporaryCopiedDir(QLatin1String(":/unit-tests"));
QVERIFY(m_tmpDir->isValid());
}
void DebuggerPluginPrivate::testProjectLoaded(Project *project)
void DebuggerUnitTests::cleanupTestCase()
{
if (!project) {
qWarning("Changed to null project.");
return;
}
m_testProject = project;
connect(project, SIGNAL(proFilesEvaluated()), SLOT(testProjectEvaluated()));
project->configureAsExampleProject({ });
delete m_tmpDir;
}
void DebuggerPluginPrivate::testProjectEvaluated()
void DebuggerUnitTests::testStateMachine()
{
QString fileName = m_testProject->projectFilePath().toUserOutput();
QVERIFY(!fileName.isEmpty());
qWarning("Project %s loaded", qPrintable(fileName));
connect(BuildManager::instance(), SIGNAL(buildQueueFinished(bool)),
this, SLOT(testProjectBuilt(bool)));
ProjectExplorerPlugin::buildProject(m_testProject);
}
QString proFile = m_tmpDir->absolutePath("simple/simple.pro");
void DebuggerPluginPrivate::testProjectBuilt(bool success)
{
QVERIFY(success);
QVERIFY(!m_testCallbacks.isEmpty());
TestCallBack cb = m_testCallbacks.takeLast();
invoke<void>(cb.receiver, cb.slot);
}
CppTools::Tests::ProjectOpenerAndCloser projectManager;
const CppTools::ProjectInfo projectInfo = projectManager.open(proFile, true);
QVERIFY(projectInfo.isValid());
void DebuggerPluginPrivate::testUnloadProject()
{
ProjectExplorerPlugin *pe = ProjectExplorerPlugin::instance();
invoke<void>(pe, "unloadProject");
}
QEventLoop loop;
connect(BuildManager::instance(), &BuildManager::buildQueueFinished,
&loop, &QEventLoop::quit);
ProjectExplorerPlugin::buildProject(SessionManager::startupProject());
loop.exec();
//static Target *activeTarget()
//{
// Project *project = ProjectExplorerPlugin::instance()->currentProject();
// return project->activeTarget();
//}
DebuggerRunParameters rp;
Target *t = SessionManager::startupProject()->activeTarget();
QVERIFY(t);
Kit *kit = t->kit();
QVERIFY(kit);
RunConfiguration *rc = t->activeRunConfiguration();
QVERIFY(rc);
rp.inferior = rc->runnable().as<StandardRunnable>();
rp.testCase = TestNoBoundsOfCurrentFunction;
DebuggerRunControl *runControl = createAndScheduleRun(rp, kit);
//static Kit *currentKit()
//{
// Target *t = activeTarget();
// if (!t || !t->isEnabled())
// return 0;
// return t->kit();
//}
connect(runControl, &RunControl::finished, this, [this] {
QTestEventLoop::instance().exitLoop();
});
//static LocalApplicationRunConfiguration *activeLocalRunConfiguration()
//{
// Target *t = activeTarget();
// return t ? qobject_cast<LocalApplicationRunConfiguration *>(t->activeRunConfiguration()) : 0;
//}
void DebuggerPluginPrivate::testRunProject(const DebuggerRunParameters &rp, const TestCallBack &cb)
{
m_testCallbacks.append(cb);
RunControl *rc = createAndScheduleRun(rp, 0);
connect(rc, &RunControl::finished, this, &DebuggerPluginPrivate::testRunControlFinished);
}
void DebuggerPluginPrivate::testRunControlFinished()
{
QVERIFY(!m_testCallbacks.isEmpty());
TestCallBack cb = m_testCallbacks.takeLast();
ExtensionSystem::invoke<void>(cb.receiver, cb.slot);
}
void DebuggerPluginPrivate::testFinished()
{
QTestEventLoop::instance().exitLoop();
QVERIFY(m_testSuccess);
}
///////////////////////////////////////////////////////////////////////////
//void DebuggerPlugin::testStateMachine()
//{
// dd->testStateMachine1();
//}
//void DebuggerPluginPrivate::testStateMachine1()
//{
// m_testSuccess = true;
// QString proFile = ICore::resourcePath();
// if (Utils::HostOsInfo::isMacHost())
// proFile += QLatin1String("/../..");
// proFile += QLatin1String("/../../tests/manual/debugger/simple/simple.pro");
// testLoadProject(proFile, TestCallBack(this, "testStateMachine2"));
// QVERIFY(m_testSuccess);
// QTestEventLoop::instance().enterLoop(20);
//}
//void DebuggerPluginPrivate::testStateMachine2()
//{
// DebuggerRunParameters sp;
// fillParameters(&sp, currentKit());
// sp.executable = activeLocalRunConfiguration()->executable();
// sp.testCase = TestNoBoundsOfCurrentFunction;
// testRunProject(sp, TestCallBack(this, "testStateMachine3"));
//}
//void DebuggerPluginPrivate::testStateMachine3()
//{
// testUnloadProject();
// testFinished();
//}
///////////////////////////////////////////////////////////////////////////
void DebuggerPlugin::testBenchmark()
{
dd->testBenchmark1();
}
enum FakeEnum { FakeDebuggerCommonSettingsId };
void DebuggerPluginPrivate::testBenchmark1()
void DebuggerUnitTests::testBenchmark()
{
#ifdef WITH_BENCHMARK
CALLGRIND_START_INSTRUMENTATION;
@@ -3737,9 +3645,124 @@ void DebuggerPluginPrivate::testBenchmark1()
#endif
}
void DebuggerUnitTests::testDebuggerMatching_data()
{
QTest::addColumn<QStringList>("debugger");
QTest::addColumn<QString>("target");
QTest::addColumn<int>("result");
QTest::newRow("Invalid data")
<< QStringList()
<< QString()
<< int(DebuggerItem::DoesNotMatch);
QTest::newRow("Invalid debugger")
<< QStringList()
<< QString::fromLatin1("x86-linux-generic-elf-32bit")
<< int(DebuggerItem::DoesNotMatch);
QTest::newRow("Invalid target")
<< (QStringList() << QLatin1String("x86-linux-generic-elf-32bit"))
<< QString()
<< int(DebuggerItem::DoesNotMatch);
QTest::newRow("Fuzzy match 1")
<< (QStringList() << QLatin1String("unknown-unknown-unknown-unknown-0bit"))
<< QString::fromLatin1("x86-linux-generic-elf-32bit")
<< int(DebuggerItem::MatchesWell); // Is this the expected behavior?
QTest::newRow("Fuzzy match 2")
<< (QStringList() << QLatin1String("unknown-unknown-unknown-unknown-0bit"))
<< QString::fromLatin1("arm-windows-msys-pe-64bit")
<< int(DebuggerItem::MatchesWell); // Is this the expected behavior?
QTest::newRow("Architecture mismatch")
<< (QStringList() << QLatin1String("x86-linux-generic-elf-32bit"))
<< QString::fromLatin1("arm-linux-generic-elf-32bit")
<< int(DebuggerItem::DoesNotMatch);
QTest::newRow("OS mismatch")
<< (QStringList() << QLatin1String("x86-linux-generic-elf-32bit"))
<< QString::fromLatin1("x86-macosx-generic-elf-32bit")
<< int(DebuggerItem::DoesNotMatch);
QTest::newRow("Format mismatch")
<< (QStringList() << QLatin1String("x86-linux-generic-elf-32bit"))
<< QString::fromLatin1("x86-linux-generic-pe-32bit")
<< int(DebuggerItem::DoesNotMatch);
QTest::newRow("Linux perfect match")
<< (QStringList() << QLatin1String("x86-linux-generic-elf-32bit"))
<< QString::fromLatin1("x86-linux-generic-elf-32bit")
<< int(DebuggerItem::MatchesWell);
QTest::newRow("Linux match")
<< (QStringList() << QLatin1String("x86-linux-generic-elf-64bit"))
<< QString::fromLatin1("x86-linux-generic-elf-32bit")
<< int(DebuggerItem::MatchesSomewhat);
QTest::newRow("Windows perfect match 1")
<< (QStringList() << QLatin1String("x86-windows-msvc2013-pe-64bit"))
<< QString::fromLatin1("x86-windows-msvc2013-pe-64bit")
<< int(DebuggerItem::MatchesWell);
QTest::newRow("Windows perfect match 2")
<< (QStringList() << QLatin1String("x86-windows-msvc2013-pe-64bit"))
<< QString::fromLatin1("x86-windows-msvc2012-pe-64bit")
<< int(DebuggerItem::MatchesWell);
QTest::newRow("Windows match 1")
<< (QStringList() << QLatin1String("x86-windows-msvc2013-pe-64bit"))
<< QString::fromLatin1("x86-windows-msvc2013-pe-32bit")
<< int(DebuggerItem::MatchesSomewhat);
QTest::newRow("Windows match 2")
<< (QStringList() << QLatin1String("x86-windows-msvc2013-pe-64bit"))
<< QString::fromLatin1("x86-windows-msvc2012-pe-32bit")
<< int(DebuggerItem::MatchesSomewhat);
QTest::newRow("Windows mismatch on word size")
<< (QStringList() << QLatin1String("x86-windows-msvc2013-pe-32bit"))
<< QString::fromLatin1("x86-windows-msvc2013-pe-64bit")
<< int(DebuggerItem::DoesNotMatch);
QTest::newRow("Windows mismatch on osflavor 1")
<< (QStringList() << QLatin1String("x86-windows-msvc2013-pe-32bit"))
<< QString::fromLatin1("x86-windows-msys-pe-64bit")
<< int(DebuggerItem::DoesNotMatch);
QTest::newRow("Windows mismatch on osflavor 2")
<< (QStringList() << QLatin1String("x86-windows-msys-pe-32bit"))
<< QString::fromLatin1("x86-windows-msvc2010-pe-64bit")
<< int(DebuggerItem::DoesNotMatch);
}
void DebuggerUnitTests::testDebuggerMatching()
{
QFETCH(QStringList, debugger);
QFETCH(QString, target);
QFETCH(int, result);
DebuggerItem::MatchLevel expectedLevel = static_cast<DebuggerItem::MatchLevel>(result);
QList<Abi> debuggerAbis;
foreach (const QString &abi, debugger)
debuggerAbis << Abi(abi);
DebuggerItem item;
item.setAbis(debuggerAbis);
DebuggerItem::MatchLevel level = item.matchTarget(Abi(target));
if (level == DebuggerItem::MatchesPerfectly)
level = DebuggerItem::MatchesWell;
QCOMPARE(expectedLevel, level);
}
QList<QObject *> DebuggerPlugin::createTestObjects() const
{
return { new DebuggerUnitTests };
}
#else // ^-- if WITH_TESTS else --v
QList<QObject *> DebuggerPlugin::createTestObjects() const
{
return {};
}
#endif // if WITH_TESTS
} // namespace Internal
} // namespace Debugger
#include "debuggerplugin.moc"