Commit 3e03c064 authored by hjk's avatar hjk Committed by hjk
Browse files

debugger: start automization of manual tests



Change-Id: I33bd046eca253130049d0a80de7a1a3f3e442307
Reviewed-by: default avatarhjk <qthjk@ovi.com>
parent 0a48570f
......@@ -65,6 +65,7 @@
#include <QtCore/QDebug>
#include <QtCore/QTimer>
#include <QtCore/QFile>
#include <QtCore/QFutureInterface>
#include <QtGui/QMessageBox>
......@@ -158,7 +159,8 @@ public:
m_watchHandler(engine),
m_disassemblerAgent(engine),
m_memoryAgent(engine),
m_isStateDebugging(false)
m_isStateDebugging(false),
m_testsPossible(true)
{
connect(&m_locationTimer, SIGNAL(timeout()), SLOT(resetLocation()));
if (sp.toolChainAbi.os() == ProjectExplorer::Abi::MacOS)
......@@ -285,6 +287,14 @@ public:
QTimer m_locationTimer;
bool m_isStateDebugging;
// Testing
void handleAutoTests();
void handleAutoTestLine(int line);
void reportTestError(const QString &);
bool m_testsPossible;
QStringList m_testContents;
QString m_testErrors;
};
......@@ -1100,6 +1110,9 @@ void DebuggerEngine::setState(DebuggerState state, bool forced)
BreakHandler *handler = breakHandler();
foreach (BreakpointModelId id, handler->engineBreakpointIds(this))
handler->notifyBreakpointReleased(id);
if (!d->m_testErrors.isEmpty())
showMessage(_("\nTest Errors\n\n") + d->m_testErrors);
}
const bool running = d->m_state == InferiorRunOk;
......@@ -1654,6 +1667,98 @@ void DebuggerEngine::setStateDebugging(bool on)
d->m_isStateDebugging = on;
}
void DebuggerEngine::handleAutoTests()
{
d->handleAutoTests();
}
void DebuggerEnginePrivate::handleAutoTests()
{
if (!m_testsPossible)
return;
StackFrame frame = m_engine->stackHandler()->currentFrame();
if (!frame.file.endsWith(QLatin1String("debugger/simple/simple_test_app.cpp")))
return;
if (m_testContents.isEmpty()) {
QFile file(frame.file);
file.open(QIODevice::ReadOnly);
QTextStream ts(&file);
m_testContents = ts.readAll().split(QLatin1Char('\n'));
if (m_testContents.isEmpty()) {
m_testsPossible = false;
return;
}
foreach (const QString &s, m_testContents) {
if (s.startsWith(QLatin1String("#define USE_AUTORUN"))) {
m_testsPossible = s.startsWith(QLatin1String("#define USE_AUTORUN 1"));
break;
}
}
}
if (!m_testsPossible)
return;
int line = frame.line;
if (line > 1 && line < m_testContents.size())
handleAutoTestLine(line);
}
void DebuggerEnginePrivate::handleAutoTestLine(int line)
{
QString s = m_testContents.at(line).trimmed();
if (s.endsWith(QLatin1Char('.')))
s.chop(1);
int pos = s.indexOf(QLatin1String("//"));
if (pos == -1)
return;
s = s.mid(pos + 2).trimmed();
QString cmd = s.section(QLatin1Char(' '), 0, 0);
if (cmd == QLatin1String("Expand")) {
m_engine->showMessage(_("'Expand' found in line %1, but not implemented yet.").arg(line));
handleAutoTestLine(line + 1);
} else if (cmd == QLatin1String("Expand")) {
m_engine->showMessage(_("'Expand' found in line %1, but not implemented yet.").arg(line));
handleAutoTestLine(line + 1);
} else if (cmd == QLatin1String("Check")) {
QString name = s.section(QLatin1Char(' '), 1, 1);
if (name.isEmpty()) {
reportTestError(_("Check in line %1 needs arguments.").arg(line));
} else {
QByteArray iname = "local." + name.toLatin1();
const WatchData *data = m_engine->watchHandler()->findItem(iname);
if (data) {
QString needle = s.section(QLatin1Char(' '), 2, -1);
QString found = data->value + QString::fromLatin1(" " + data->type);
if (needle == found) {
m_engine->showMessage(_("Check in line %1 for %2 was successful")
.arg(line).arg(needle));
} else {
reportTestError(_("Check in line %1 for %2 failed. Got %3.")
.arg(line).arg(needle).arg(found));
}
} else {
reportTestError(_("### Check in line %1 referes to unknown variable %2.")
.arg(line).arg(name));
}
}
handleAutoTestLine(line + 1);
} else if (cmd == QLatin1String("Continue")) {
m_engine->showMessage(_("Continue in line %1 processed.").arg(line));
m_engine->continueInferior();
}
}
void DebuggerEnginePrivate::reportTestError(const QString &error)
{
m_engine->showMessage(_("### ") + error);
m_testErrors.append(error);
m_testErrors.append(QLatin1Char('\n'));
}
} // namespace Debugger
#include "debuggerengine.moc"
......@@ -394,6 +394,8 @@ protected:
virtual void slaveEngineStateChanged(DebuggerEngine *engine,
DebuggerState state);
virtual void handleAutoTests();
private:
// Wrapper engine needs access to state of its subengines.
friend class Internal::QmlCppEngine;
......
......@@ -5091,7 +5091,6 @@ void GdbEngine::scheduleTestResponse(int testCase, const QByteArray &response)
m_scheduledTestResponses[token] = response;
}
//
// Factory
//
......
......@@ -191,6 +191,7 @@ void GdbEngine::handleStackFramePython(const GdbResponse &response)
}
if (!partial)
emit stackFrameCompleted();
handleAutoTests();
} else {
showMessage(_("DUMPER FAILED: " + response.toString()));
}
......
......@@ -42,6 +42,18 @@
// Default: 0
#define USE_AUTOBREAK 0
// With USE_AUTORUN, creator will automatically "execute" the commands
// in a comment following a BREAK_HERE line.
// The following commands are supported:
// // Check <name> <value> <type>
// - Checks whether the local variable is displayed with value and type.
// // Continue
// - Continues execution
// If the line after a BREAK_HERE line does not contain one of the
// supported commands, the test stops.
// Default: 0
#define USE_AUTORUN 0
// With USE_UNINITIALIZE_AUTOBREAK, the debugger will stop automatically
// on all lines containing the BREAK_UNINITIALIZED_HERE macro.
// This should be enabled during manual testing.
......@@ -3235,6 +3247,11 @@ namespace basic {
const int c = 44;
const Ref d = a;
BREAK_HERE;
// Check a 43 int.
// Check b 43 int.
// Check b 44 int.
// Check b 43 int.
// Continue.
dummyStatement(&a, &b, &c, &d);
}
......@@ -4142,7 +4159,14 @@ namespace sanity {
obj.setObjectName("An Object");
BREAK_HERE;
// Expand all.
// Check list <3 items> QStringList
// Check list2 <5 items> QList<char const*>
// Check obj "An Object" QObject
// Check qv <1 items> QVector<int>
// Check s "hallohallo" string
// Check v <1 items> vector<int>
// Continue
dummyStatement(&s, &qv, &v, &list, &list2, &obj);
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment