From d2f117439f93b9c2045c1475a1298f87ece65994 Mon Sep 17 00:00:00 2001 From: Samuel Jackson <samueljackson@outlook.com> Date: Tue, 17 Oct 2017 16:11:02 +0100 Subject: [PATCH] Refs #20855 Begin to get thread manager under test --- qt/widgets/common/CMakeLists.txt | 7 ++- .../Common/FindFilesThreadPoolManager.h | 1 + .../FindFilesThreadPoolManagerMockObjects.h | 45 ++++++++++++++++++ .../common/src/FindFilesThreadPoolManager.cpp | 18 +++++-- qt/widgets/common/src/MWRunFiles.cpp | 2 +- .../test/FindFilesThreadPoolManagerTest.h | 47 +++++++++++++++++++ 6 files changed, 112 insertions(+), 8 deletions(-) create mode 100644 qt/widgets/common/inc/MantidQtWidgets/Common/FindFilesThreadPoolManagerMockObjects.h create mode 100644 qt/widgets/common/test/FindFilesThreadPoolManagerTest.h diff --git a/qt/widgets/common/CMakeLists.txt b/qt/widgets/common/CMakeLists.txt index 4cfe6557a00..d040c9eb429 100644 --- a/qt/widgets/common/CMakeLists.txt +++ b/qt/widgets/common/CMakeLists.txt @@ -203,7 +203,6 @@ set ( MOC_FILES inc/MantidQtWidgets/Common/DoubleSpinBox.h inc/MantidQtWidgets/Common/FindReplaceDialog.h inc/MantidQtWidgets/Common/FindDialog.h - inc/MantidQtWidgets/Common/FindFilesThreadPoolManager.h inc/MantidQtWidgets/Common/FitPropertyBrowser.h inc/MantidQtWidgets/Common/FitOptionsBrowser.h inc/MantidQtWidgets/Common/FunctionBrowser.h @@ -255,6 +254,8 @@ set ( MOC_FILES inc/MantidQtWidgets/Common/QtPropertyBrowser/StringDialogEditor.h inc/MantidQtWidgets/Common/QtPropertyBrowser/StringEditorFactory.h inc/MantidQtWidgets/Common/QtPropertyBrowser/WorkspaceEditorFactory.h + inc/MantidQtWidgets/Common/FindFilesThreadPoolManager.h + inc/MantidQtWidgets/Common/FindFilesThreadPoolManagerMockObjects.h ) # Include files aren't required, but this makes them appear in Visual Studio @@ -393,7 +394,8 @@ set ( INC_FILES inc/MantidQtWidgets/Common/QtPropertyBrowser/qtpropertymanager.h inc/MantidQtWidgets/Common/QtPropertyBrowser/qttreepropertybrowser.h inc/MantidQtWidgets/Common/QtPropertyBrowser/qtvariantproperty.h - + inc/MantidQtWidgets/Common/FindFilesThreadPoolManager.h + inc/MantidQtWidgets/Common/FindFilesThreadPoolManagerMockObjects.h ) set ( UI_FILES @@ -433,6 +435,7 @@ set ( TEST_PY_FILES set( TEST_FILES BatchAlgorithmRunnerTest.h FileDialogHandlerTest.h + FindFilesThreadPoolManagerTest.h InterfaceManagerTest.h MantidColorMapTest.h NonOrthogonalTest.h diff --git a/qt/widgets/common/inc/MantidQtWidgets/Common/FindFilesThreadPoolManager.h b/qt/widgets/common/inc/MantidQtWidgets/Common/FindFilesThreadPoolManager.h index a36ee8268ca..3965d6371e3 100644 --- a/qt/widgets/common/inc/MantidQtWidgets/Common/FindFilesThreadPoolManager.h +++ b/qt/widgets/common/inc/MantidQtWidgets/Common/FindFilesThreadPoolManager.h @@ -96,6 +96,7 @@ public: const FindFilesSearchParameters& parameters); void cancelWorker(const QObject *parent); bool isSearchRunning() const; + void waitForDone() const; private: // make a local thread pool diff --git a/qt/widgets/common/inc/MantidQtWidgets/Common/FindFilesThreadPoolManagerMockObjects.h b/qt/widgets/common/inc/MantidQtWidgets/Common/FindFilesThreadPoolManagerMockObjects.h new file mode 100644 index 00000000000..2f4fbc31a09 --- /dev/null +++ b/qt/widgets/common/inc/MantidQtWidgets/Common/FindFilesThreadPoolManagerMockObjects.h @@ -0,0 +1,45 @@ +#ifndef MANTIDQT_API_FINDFILESTHREADPOOLMANAGERTESTMOCKOBJECTS_H_ +#define MANTIDQT_API_FINDFILESTHREADPOOLMANAGERTESTMOCKOBJECTS_H_ + +#include "FindFilesThreadPoolManager.h" + +#include <QObject> + +namespace MantidQt { +namespace API { + +class FakeMWRunFiles : public QObject { +Q_OBJECT +public slots: + /// Slot called when file finding thread has finished. + void inspectThreadResult(const FindFilesSearchResults& result) { + m_results = result; + } + + /// Slot called when the file finding thread has finished. + void setSignalRecieved() { + m_finishedSignalRecieved = true; + } + +signals: + void fileFindingFinished(); + +public: + FakeMWRunFiles() : m_results(), m_finishedSignalRecieved(false) { + connect(this, SIGNAL(fileFindingFinished()), + this, SLOT(setSignalRecieved()), + Qt::DirectConnection); + } + + FindFilesSearchResults getResults() { return m_results; }; + bool isFinishedSignalRecieved() { return m_finishedSignalRecieved; }; + +private: + FindFilesSearchResults m_results; + bool m_finishedSignalRecieved; +}; + +} +} + +#endif /* MANTIDQT_API_FINDFILESTHREADPOOLMANAGERTESTMOCKOBJECTS_H_ */ diff --git a/qt/widgets/common/src/FindFilesThreadPoolManager.cpp b/qt/widgets/common/src/FindFilesThreadPoolManager.cpp index 6f85f6ac525..5cd5b2971f7 100644 --- a/qt/widgets/common/src/FindFilesThreadPoolManager.cpp +++ b/qt/widgets/common/src/FindFilesThreadPoolManager.cpp @@ -125,7 +125,7 @@ void FindFilesThread::run() { m_filenames.clear(); } - const auto result = createFindFilesSearchResult(); + auto result = createFindFilesSearchResult(); emit finished(result); } @@ -196,13 +196,18 @@ void FindFilesThreadPoolManager::createWorker( m_currentWorker = new FindFilesThread(); - // Hook up slots for when the thread finishes + // Hook up slots for when the thread finishes. By default Qt uses queued + // connections when connecting signals/slots between threads. Instead here + // we explicitly choose to use a direct connection so the found result is + // immediately returned to the GUI thread. parent->connect(m_currentWorker, SIGNAL(finished(const FindFilesSearchResults &)), parent, - SLOT(inspectThreadResult(const FindFilesSearchResults &))); + SLOT(inspectThreadResult(const FindFilesSearchResults &)), + Qt::DirectConnection); parent->connect(m_currentWorker, SIGNAL(finished(const FindFilesSearchResults &)), parent, - SIGNAL(fileFindingFinished())); + SIGNAL(fileFindingFinished()), + Qt::DirectConnection); // Set the search parameters m_currentWorker->set(parameters); @@ -219,10 +224,13 @@ void FindFilesThreadPoolManager::cancelWorker(const QObject *parent) { // Just disconnect any signals from the worker. We leave the worker to // continue running in the background because 1) terminating it directly // is dangerous (we have no idea what it's currently doing from here) and 2) - // waiting for it to finish locks up the GUI event loop. + // waiting for it to finish before starting a new thread locks up the GUI + // event loop. m_currentWorker->disconnect(parent); } bool FindFilesThreadPoolManager::isSearchRunning() const { return m_currentWorker != nullptr; } + +void FindFilesThreadPoolManager::waitForDone() const { m_pool.waitForDone(); } diff --git a/qt/widgets/common/src/MWRunFiles.cpp b/qt/widgets/common/src/MWRunFiles.cpp index f3bede0f402..d927933f3a4 100644 --- a/qt/widgets/common/src/MWRunFiles.cpp +++ b/qt/widgets/common/src/MWRunFiles.cpp @@ -572,7 +572,7 @@ void MWRunFiles::findFiles() { if (!searchText.isEmpty()) { const auto parameters = createFindFilesSearchParameters(searchText); - m_pool.createWorker(this, parameters); + // m_pool.createWorker(this, parameters); } } else { diff --git a/qt/widgets/common/test/FindFilesThreadPoolManagerTest.h b/qt/widgets/common/test/FindFilesThreadPoolManagerTest.h new file mode 100644 index 00000000000..b23a1b1c758 --- /dev/null +++ b/qt/widgets/common/test/FindFilesThreadPoolManagerTest.h @@ -0,0 +1,47 @@ +#ifndef MANTIDQT_API_FINDFILESTHREADPOOLMANAGERTEST_H_ +#define MANTIDQT_API_FINDFILESTHREADPOOLMANAGERTEST_H_ + +#include "MantidQtWidgets/Common/FindFilesThreadPoolManager.h" +#include "MantidQtWidgets/Common/FindFilesThreadPoolManagerMockObjects.h" + +#include <gmock/gmock.h> +#include <gtest/gtest.h> +#include <cxxtest/TestSuite.h> + +using MantidQt::API::FindFilesThreadPoolManager; +using MantidQt::API::FindFilesSearchParameters; +using MantidQt::API::FindFilesSearchResults; +using MantidQt::API::FakeMWRunFiles; + +class FindFilesThreadPoolManagerTest : public CxxTest::TestSuite { +public: + // This pair of boilerplate methods prevent the suite being created statically + // This means the constructor isn't called when running other tests + static FindFilesThreadPoolManagerTest *createSuite() { return new FindFilesThreadPoolManagerTest(); } + static void destroySuite(FindFilesThreadPoolManagerTest *suite) { delete suite; } + + void test_find_single_file() { + // Arrange + FakeMWRunFiles widget; + FindFilesSearchParameters parameters; + parameters.searchText = "SomeFileThatDontExist"; + parameters.isOptional = false; + parameters.isForRunFiles = false; + parameters.algorithmProperty = "Filename"; + parameters.algorithmName = "Load"; + + // Act + FindFilesThreadPoolManager poolManager; + poolManager.createWorker(&widget, parameters); + // Block and wait for all the threads to process + poolManager.waitForDone(); + + // Assert + const auto results = widget.getResults(); + TS_ASSERT(widget.isFinishedSignalRecieved()) + TS_ASSERT_EQUALS(results.error, "") + } + +}; + +#endif /* MANTIDQT_API_FINDFILESTHREADPOOLMANAGERTEST */ -- GitLab