From a3b530614757cd9521b5720d181cd362865a0671 Mon Sep 17 00:00:00 2001 From: Jarek Kobus Date: Wed, 28 Apr 2021 15:59:18 +0200 Subject: [PATCH] Add TestStringTable scenario This scenario is used for testing against regression in StringTable. If the scenario went OK, the creator finishes and doesn't crash. Later, this scenario will be invoked from additional test, so that the second instance of creator will run and the test will check if the subprocess finished OK. So it's going to be combined with autotests in the follow up patch. In order to test it, run creator with the following command line: "-settingspath ~/.config -scenario TestStringTable". Make sure, that you point settingspath to creator settings which have proper kit with a toolchain and Qt setup. The regression may be tested by restoring the src/plugins/cpptools/stringtable.cpp to the parent of f4ab1279fd55a00e2bede18ec9ad283c668b46bd and by applying on top of it this patch (simple conflict may need to be resolved). In this case running this scenario ends up with a crash (so, it confirms this test fails on the old code form before the fix). Change-Id: Icbb56233495047fd68bfb605fcd088f352a16323 Reviewed-by: hjk Reviewed-by: Qt CI Bot --- src/plugins/autotest/CMakeLists.txt | 4 +- src/plugins/autotest/autotest.pro | 4 +- src/plugins/autotest/autotest.qbs | 2 + src/plugins/autotest/autotestplugin.cpp | 8 ++ src/plugins/autotest/loadprojectscenario.cpp | 100 +++++++++++++++++++ src/plugins/autotest/loadprojectscenario.h | 58 +++++++++++ src/plugins/cpptools/stringtable.cpp | 11 ++ 7 files changed, 184 insertions(+), 3 deletions(-) create mode 100644 src/plugins/autotest/loadprojectscenario.cpp create mode 100644 src/plugins/autotest/loadprojectscenario.h diff --git a/src/plugins/autotest/CMakeLists.txt b/src/plugins/autotest/CMakeLists.txt index 7b1438ab01b..0571ee65147 100644 --- a/src/plugins/autotest/CMakeLists.txt +++ b/src/plugins/autotest/CMakeLists.txt @@ -80,5 +80,7 @@ add_qtc_plugin(AutoTest extend_qtc_plugin(AutoTest CONDITION WITH_TESTS - SOURCES autotestunittests.cpp autotestunittests.h + SOURCES + autotestunittests.cpp autotestunittests.h + loadprojectscenario.cpp loadprojectscenario.h ) diff --git a/src/plugins/autotest/autotest.pro b/src/plugins/autotest/autotest.pro index 6bfd57bbe1a..d7f708d63c8 100644 --- a/src/plugins/autotest/autotest.pro +++ b/src/plugins/autotest/autotest.pro @@ -156,7 +156,7 @@ FORMS += \ testsettingspage.ui equals(TEST, 1) { - HEADERS += autotestunittests.h - SOURCES += autotestunittests.cpp + HEADERS += autotestunittests.h loadprojectscenario.h + SOURCES += autotestunittests.cpp loadprojectscenario.cpp RESOURCES += autotestunittests.qrc } diff --git a/src/plugins/autotest/autotest.qbs b/src/plugins/autotest/autotest.qbs index cd9d0a55080..065159142d6 100644 --- a/src/plugins/autotest/autotest.qbs +++ b/src/plugins/autotest/autotest.qbs @@ -133,6 +133,8 @@ QtcPlugin { "autotestunittests.cpp", "autotestunittests.h", "autotestunittests.qrc", + "loadprojectscenario.cpp", + "loadprojectscenario.h", ] } diff --git a/src/plugins/autotest/autotestplugin.cpp b/src/plugins/autotest/autotestplugin.cpp index 47c53628caa..43e54ec58cc 100644 --- a/src/plugins/autotest/autotestplugin.cpp +++ b/src/plugins/autotest/autotestplugin.cpp @@ -79,6 +79,7 @@ #ifdef WITH_TESTS #include "autotestunittests.h" +#include "loadprojectscenario.h" #endif using namespace Core; @@ -111,6 +112,9 @@ public: TestTreeModel m_testTreeModel{&m_testCodeParser}; TestRunner m_testRunner; TestFrameworkManager m_frameworkManager; +#ifdef WITH_TESTS + LoadProjectScenario m_loadProjectScenario{&m_testTreeModel}; +#endif }; static AutotestPluginPrivate *dd = nullptr; @@ -273,6 +277,10 @@ bool AutotestPlugin::initialize(const QStringList &arguments, QString *errorStri Q_UNUSED(errorString) dd = new AutotestPluginPrivate; +#ifdef WITH_TESTS + ExtensionSystem::PluginManager::registerScenario("TestStringTable", + [this]() { return dd->m_loadProjectScenario(); }); +#endif return true; } diff --git a/src/plugins/autotest/loadprojectscenario.cpp b/src/plugins/autotest/loadprojectscenario.cpp new file mode 100644 index 00000000000..40e9173493d --- /dev/null +++ b/src/plugins/autotest/loadprojectscenario.cpp @@ -0,0 +1,100 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +****************************************************************************/ + +#include "loadprojectscenario.h" + +#include +#include + +#include + +#include + +using namespace Core; +using namespace ProjectExplorer; +using namespace Utils; + +namespace Autotest { +namespace Internal { + +LoadProjectScenario::LoadProjectScenario(TestTreeModel *model, QObject *parent) + : QObject(parent), + m_model(model) +{ +} + +LoadProjectScenario::~LoadProjectScenario() +{ + delete m_tmpDir; +} + +bool LoadProjectScenario::operator()() +{ + return init() && loadProject(); +} + +bool LoadProjectScenario::init() +{ + const QList allKits = KitManager::kits(); + if (allKits.count() == 0) { + qWarning() << "This scenario requires at least one kit to be present"; + return false; + } + + m_kit = findOr(allKits, nullptr, [](Kit *k) { + return k->isValid() && QtSupport::QtKitAspect::qtVersion(k) != nullptr; + }); + if (!m_kit) { + qWarning() << "The scenario requires at least one valid kit with a valid Qt"; + return false; + } + + if (!QtSupport::QtKitAspect::qtVersion(m_kit)) { + qWarning() << "Could not figure out which Qt version is used for default kit."; + return false; + } + + const ToolChain * const toolchain = ToolChainKitAspect::cxxToolChain(m_kit); + if (!toolchain) { + qWarning() << "This test requires that there is a kit with a toolchain."; + return false; + } + + m_tmpDir = new CppTools::Tests::TemporaryCopiedDir(":/unit_test"); + return true; +} + +bool LoadProjectScenario::loadProject() +{ + const QString projectFilePath = m_tmpDir->path() + "/plain/plain.pro"; + + CppTools::Tests::ProjectOpenerAndCloser projectManager; + // This code must trigger a call to PluginManager::finishScenario() at some later point. + const CppTools::ProjectInfo projectInfo = projectManager.open(projectFilePath, true, m_kit); + return projectInfo.isValid(); +} + +} // namespace Internal +} // namespace Autotest diff --git a/src/plugins/autotest/loadprojectscenario.h b/src/plugins/autotest/loadprojectscenario.h new file mode 100644 index 00000000000..f96932df084 --- /dev/null +++ b/src/plugins/autotest/loadprojectscenario.h @@ -0,0 +1,58 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +****************************************************************************/ + +#pragma once + +#include + +namespace CppTools { namespace Tests { class TemporaryCopiedDir; } } +namespace ProjectExplorer { class Kit; } + +namespace Autotest { + +class TestTreeModel; + +namespace Internal { + +class LoadProjectScenario : public QObject +{ + Q_OBJECT +public: + explicit LoadProjectScenario(TestTreeModel *model, QObject *parent = nullptr); + ~LoadProjectScenario(); + + bool operator()(); + +private: + bool init(); + bool loadProject(); + + TestTreeModel *m_model = nullptr; + CppTools::Tests::TemporaryCopiedDir *m_tmpDir = nullptr; + ProjectExplorer::Kit *m_kit = nullptr; +}; + +} // namespace Internal +} // namespace Autotest diff --git a/src/plugins/cpptools/stringtable.cpp b/src/plugins/cpptools/stringtable.cpp index 331a56faa1a..9eac24b8811 100644 --- a/src/plugins/cpptools/stringtable.cpp +++ b/src/plugins/cpptools/stringtable.cpp @@ -35,6 +35,10 @@ #include #include +#ifdef WITH_TESTS +#include +#endif + using namespace CppTools::Internal; enum { @@ -145,6 +149,13 @@ static inline bool isQStringInUse(const QString &string) void StringTablePrivate::GC(QFutureInterface &futureInterface) { +#ifdef WITH_TESTS + if (ExtensionSystem::PluginManager::isScenarioRunning("TestStringTable")) { + if (ExtensionSystem::PluginManager::finishScenario()) + QThread::currentThread()->sleep(5); + } +#endif + int initialSize = 0; QElapsedTimer timer; if (DebugStringTable) {