123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290 |
- /*=============================================================================
-
- Library: CTK
-
- Copyright (c) German Cancer Research Center,
- Division of Medical and Biological Informatics
-
- 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.
-
- =============================================================================*/
- #include <ctkCmdLineModuleManager.h>
- #include <ctkCmdLineModuleFactory.h>
- #include <ctkCmdLineModule.h>
- #include <ctkCmdLineModuleReference.h>
- #include <ctkCmdLineModuleDescription.h>
- #include <ctkCmdLineModuleParameter.h>
- #include <ctkCmdLineModuleRunException.h>
- #include <ctkCmdLineModuleFuture.h>
- #include "ctkCmdLineModuleSignalTester.h"
- #include <QVariant>
- #include <QCoreApplication>
- #include <QDebug>
- #include <QFutureWatcher>
- #include <cstdlib>
- class ctkCmdLineModuleTestInstanceFactory : public ctkCmdLineModuleFactory
- {
- public:
- virtual ctkCmdLineModule* create(const ctkCmdLineModuleReference& moduleRef)
- {
- struct ModuleTestInstance : public ctkCmdLineModule
- {
- ModuleTestInstance(const ctkCmdLineModuleReference& moduleRef) : ctkCmdLineModule(moduleRef) {}
- virtual QObject* guiHandle() const { return NULL; }
- virtual QVariant value(const QString& parameter) const
- {
- QVariant value = currentValues[parameter];
- if (!value.isValid())
- return this->moduleReference().description().parameter(parameter).defaultValue();
- return value;
- }
- virtual void setValue(const QString& parameter, const QVariant& value)
- {
- currentValues[parameter] = value;
- }
- private:
- QHash<QString, QVariant> currentValues;
- };
- return new ModuleTestInstance(moduleRef);
- }
- };
- bool futureTestStartFinish(ctkCmdLineModule* module)
- {
- qDebug() << "Testing ctkCmdLineModuleFuture start/finish signals.";
- QList<QString> expectedSignals;
- expectedSignals.push_back("module.started");
- expectedSignals.push_back("module.finished");
- ctkCmdLineModuleSignalTester signalTester;
- QFutureWatcher<ctkCmdLineModuleResult> watcher;
- QObject::connect(&watcher, SIGNAL(started()), &signalTester, SLOT(moduleStarted()));
- QObject::connect(&watcher, SIGNAL(finished()), &signalTester, SLOT(moduleFinished()));
- qDebug() << module->commandLineArguments();
- ctkCmdLineModuleFuture future = module->run();
- watcher.setFuture(future);
- try
- {
- future.waitForFinished();
- }
- catch (const ctkCmdLineModuleRunException& e)
- {
- qDebug() << e;
- return false;
- }
- // process pending events
- QCoreApplication::processEvents();
- return signalTester.checkSignals(expectedSignals);
- }
- bool futureTestProgress(ctkCmdLineModule* module)
- {
- qDebug() << "Testing ctkCmdLineModuleFuture progress signals.";
- QList<QString> expectedSignals;
- expectedSignals.push_back("module.started");
- // this signal is send when connecting a QFutureWatcher to
- // an already started QFuture
- expectedSignals.push_back("module.progressValueChanged");
- // the following two signals are send when the module reports "filter start"
- expectedSignals.push_back("module.progressValueChanged");
- expectedSignals.push_back("module.progressTextChanged");
- // this signal is send when the module reports progress for "output1"
- expectedSignals.push_back("module.progressValueChanged");
- // the following two signal are sent at the end to report
- // completion and the full standard output text.
- expectedSignals.push_back("module.progressValueChanged");
- expectedSignals.push_back("module.progressTextChanged");
- expectedSignals.push_back("module.finished");
- ctkCmdLineModuleSignalTester signalTester;
- QFutureWatcher<ctkCmdLineModuleResult> watcher;
- QObject::connect(&watcher, SIGNAL(started()), &signalTester, SLOT(moduleStarted()));
- QObject::connect(&watcher, SIGNAL(progressValueChanged(int)), &signalTester, SLOT(moduleProgressValueChanged(int)));
- QObject::connect(&watcher, SIGNAL(progressTextChanged(QString)), &signalTester, SLOT(moduleProgressTextChanged(QString)));
- QObject::connect(&watcher, SIGNAL(finished()), &signalTester, SLOT(moduleFinished()));
- module->setValue("numOutputsVar", 1);
- ctkCmdLineModuleFuture future = module->run();
- watcher.setFuture(future);
- try
- {
- future.waitForFinished();
- }
- catch (const ctkCmdLineModuleRunException& e)
- {
- qDebug() << e;
- return false;
- }
- // process pending events
- QCoreApplication::processEvents();
- return signalTester.checkSignals(expectedSignals);
- }
- bool futureTestPauseAndCancel(ctkCmdLineModule* module)
- {
- qDebug() << "Testing ctkCmdLineModuleFuture pause and cancel capabilities";
- QList<QString> expectedSignals;
- expectedSignals.push_back("module.started");
- expectedSignals.push_back("module.finished");
- ctkCmdLineModuleSignalTester signalTester;
- QFutureWatcher<ctkCmdLineModuleResult> watcher;
- QObject::connect(&watcher, SIGNAL(started()), &signalTester, SLOT(moduleStarted()));
- QObject::connect(&watcher, SIGNAL(progressValueChanged(int)), &signalTester, SLOT(moduleProgressValueChanged(int)));
- QObject::connect(&watcher, SIGNAL(progressTextChanged(QString)), &signalTester, SLOT(moduleProgressTextChanged(QString)));
- QObject::connect(&watcher, SIGNAL(finished()), &signalTester, SLOT(moduleFinished()));
- module->setValue("runtimeVar", 60);
- ctkCmdLineModuleFuture future = module->run();
- watcher.setFuture(future);
- try
- {
- future.cancel();
- future.waitForFinished();
- }
- catch (const ctkCmdLineModuleRunException& e)
- {
- qDebug() << e;
- return false;
- }
- // process pending events
- QCoreApplication::processEvents();
- if (!signalTester.checkSignals(expectedSignals))
- {
- return false;
- }
- if (!(future.isCanceled() && future.isFinished()))
- {
- qDebug() << "Cancel state wrong";
- return false;
- }
- return true;
- }
- bool futureTestError(ctkCmdLineModule* module)
- {
- qDebug() << "Testing ctkCmdLineModuleFuture error reporting.";
- module->setValue("fileVar", "output1");
- module->setValue("exitCodeVar", 24);
- module->setValue("errorTextVar", "Some error occured\n");
- QFutureWatcher<ctkCmdLineModuleResult> watcher;
- ctkCmdLineModuleFuture future = module->run();
- watcher.setFuture(future);
- try
- {
- future.waitForFinished();
- return EXIT_FAILURE;
- }
- catch (const ctkCmdLineModuleRunException& e)
- {
- Q_ASSERT_X(e.errorCode() == 24, __FUNCTION__, "Error code mismatch");
- Q_ASSERT_X(e.errorString() == "Some error occured\n", __FUNCTION__, "Error text mismatch");
- }
- // process pending events
- QCoreApplication::processEvents();
- return true;
- }
- int ctkCmdLineModuleFutureTest(int argc, char* argv[])
- {
- QCoreApplication app(argc, argv);
- ctkCmdLineModuleTestInstanceFactory factory;
- ctkCmdLineModuleManager manager(&factory);
- QString moduleFilename = app.applicationDirPath() + "/ctkCmdLineModuleTestBed";
- ctkCmdLineModuleReference moduleRef = manager.registerModule(moduleFilename);
- if (!moduleRef)
- {
- qCritical() << "Module at" << moduleFilename << "could not be registered";
- }
- {
- QScopedPointer<ctkCmdLineModule> module(manager.createModule(moduleRef));
- if (!futureTestStartFinish(module.data()))
- {
- return EXIT_FAILURE;
- }
- }
- {
- QScopedPointer<ctkCmdLineModule> module(manager.createModule(moduleRef));
- if (!futureTestProgress(module.data()))
- {
- return EXIT_FAILURE;
- }
- }
- {
- QScopedPointer<ctkCmdLineModule> module(manager.createModule(moduleRef));
- if (!futureTestError(module.data()))
- {
- return EXIT_FAILURE;
- }
- }
- {
- QScopedPointer<ctkCmdLineModule> module(manager.createModule(moduleRef));
- if (!futureTestPauseAndCancel(module.data()))
- {
- return EXIT_FAILURE;
- }
- }
- // if (!futureTestResultReady(module.data()))
- // {
- // return EXIT_FAILURE;
- // }
- return EXIT_SUCCESS;
- }
|