aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarcus Tillmanns <[email protected]>2025-07-01 15:17:17 +0200
committerMarcus Tillmanns <[email protected]>2025-07-03 08:29:51 +0000
commit4cd016b4cb6dd4d276c3aaf9d26173c99585fae5 (patch)
treee0c728c368ea1dfe6a8bcda21c26dcca775adfc3
parent237dee6dc92b4b18f3294004174e330d175340d1 (diff)
Devcontainer: Add plugin testsHEADmaster
-rw-r--r--src/plugins/devcontainer/CMakeLists.txt13
-rw-r--r--src/plugins/devcontainer/devcontainer_test.cpp86
-rw-r--r--src/plugins/devcontainer/devcontainerdevice.cpp6
-rw-r--r--src/plugins/devcontainer/devcontainerdevice.h7
-rw-r--r--src/plugins/devcontainer/devcontainerplugin.cpp7
-rw-r--r--src/plugins/devcontainer/testdata/simpleproject/.devcontainer/devcontainer.json12
-rw-r--r--src/plugins/devcontainer/testdata/simpleproject/CMakeLists.txt7
-rw-r--r--src/plugins/devcontainer/testdata/simpleproject/main.cpp4
8 files changed, 141 insertions, 1 deletions
diff --git a/src/plugins/devcontainer/CMakeLists.txt b/src/plugins/devcontainer/CMakeLists.txt
index a412cfb63cf..e3fb9cefea9 100644
--- a/src/plugins/devcontainer/CMakeLists.txt
+++ b/src/plugins/devcontainer/CMakeLists.txt
@@ -1,5 +1,6 @@
add_qtc_plugin(DevContainerPlugin
PLUGIN_DEPENDS Core ProjectExplorer QtSupport
+ PLUGIN_TEST_DEPENDS CMakeProjectManager
DEPENDS DevContainer CmdBridgeClient
SOURCES
devcontainerplugin.cpp
@@ -8,3 +9,15 @@ add_qtc_plugin(DevContainerPlugin
devcontainerdevice.cpp
devcontainerdevice.h
)
+
+
+extend_qtc_plugin(DevContainerPlugin
+ CONDITION WITH_TESTS
+ DEFINES TESTDATA="${PROJECT_BINARY_DIR}/${IDE_DATA_PATH}/devcontainer_testdata"
+ SOURCES
+ devcontainer_test.cpp
+)
+
+qtc_copy_to_builddir(copy_devcontainerplugin_testdata
+ DIRECTORIES testdata
+ DESTINATION "${IDE_DATA_PATH}/devcontainer_testdata")
diff --git a/src/plugins/devcontainer/devcontainer_test.cpp b/src/plugins/devcontainer/devcontainer_test.cpp
new file mode 100644
index 00000000000..b0b08e68937
--- /dev/null
+++ b/src/plugins/devcontainer/devcontainer_test.cpp
@@ -0,0 +1,86 @@
+// Copyright (C) 2025 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#include <QtTest>
+
+#include <devcontainer/devcontainer.h>
+
+#include <projectexplorer/project.h>
+#include <projectexplorer/projectexplorer.h>
+
+#include <utils/algorithm.h>
+#include <utils/filepath.h>
+#include <utils/infobar.h>
+#include <utils/mimeutils.h>
+
+#include <coreplugin/icore.h>
+
+using namespace Utils;
+
+namespace DevContainer::Internal {
+
+class Tests : public QObject
+{
+ Q_OBJECT
+
+ const FilePath testData{TESTDATA};
+
+private slots:
+ void testSimpleProject()
+ {
+ const auto cmakelists = testData / "simpleproject" / "CMakeLists.txt";
+ ProjectExplorer::OpenProjectResult opr
+ = ProjectExplorer::ProjectExplorerPlugin::openProject(cmakelists);
+
+ QVERIFY(opr);
+
+ InstanceConfig instanceConfig;
+ instanceConfig.configFilePath = testData / "simpleproject" / ".devcontainer"
+ / "devcontainer.json";
+ instanceConfig.workspaceFolder = opr.project()->projectDirectory();
+
+ const auto infoBarEntryId = Utils::Id::fromString(
+ QString("DevContainer.Instantiate.InfoBar." + instanceConfig.devContainerId()));
+
+ Utils::InfoBar *infoBar = Core::ICore::infoBar();
+ QVERIFY(infoBar->containsInfo(infoBarEntryId));
+ Utils::InfoBarEntry entry
+ = Utils::findOrDefault(infoBar->entries(), [infoBarEntryId](const Utils::InfoBarEntry &e) {
+ return e.id() == infoBarEntryId;
+ });
+
+ QCOMPARE(entry.id(), infoBarEntryId);
+ QCOMPARE(entry.buttons().size(), 1);
+ auto yesButton = entry.buttons().first();
+
+ // Trigger loading the DevContainer instance
+ yesButton.callback();
+ FilePath expectedRootPath
+ = FilePath::fromParts(u"devcontainer", instanceConfig.devContainerId(), u"/");
+ QVERIFY(expectedRootPath.exists());
+ QVERIFY(!infoBar->containsInfo(infoBarEntryId));
+
+ FilePath expectedLibExecMountPoint = FilePath::fromParts(
+ u"devcontainer", instanceConfig.devContainerId(), u"/custom/libexec/mnt/point");
+ QVERIFY(expectedLibExecMountPoint.exists());
+ QVERIFY(expectedLibExecMountPoint.isReadableDir());
+
+ FilePath expectedWorkspaceFolder = FilePath::fromParts(
+ u"devcontainer", instanceConfig.devContainerId(), u"/custom/workspace");
+ QVERIFY(expectedWorkspaceFolder.exists());
+ QVERIFY(expectedWorkspaceFolder.isReadableDir());
+
+ FilePath expectedMainCpp = expectedWorkspaceFolder / "main.cpp";
+ QVERIFY(expectedMainCpp.exists());
+ QVERIFY(expectedMainCpp.isReadableFile());
+ }
+};
+
+QObject *createDevcontainerTest()
+{
+ return new Tests;
+}
+
+} // namespace DevContainer::Internal
+
+#include "devcontainer_test.moc"
diff --git a/src/plugins/devcontainer/devcontainerdevice.cpp b/src/plugins/devcontainer/devcontainerdevice.cpp
index e52387ef58c..d070c174311 100644
--- a/src/plugins/devcontainer/devcontainerdevice.cpp
+++ b/src/plugins/devcontainer/devcontainerdevice.cpp
@@ -23,6 +23,8 @@ namespace DevContainer {
Device::Device() {}
+Device::~Device() {} // Necessary for forward declared unique_ptr
+
ProjectExplorer::IDeviceWidget *Device::createWidget()
{
return nullptr;
@@ -75,6 +77,7 @@ Result<> Device::up(const FilePath &path, InstanceConfig instanceConfig)
{
m_instanceConfig = instanceConfig;
m_processInterfaceCreator = nullptr;
+ m_fileAccess.reset();
ProgressDialog progress;
@@ -149,7 +152,7 @@ Result<> Device::up(const FilePath &path, InstanceConfig instanceConfig)
if (!cmdBridgePath)
return ResultError(cmdBridgePath.error());
- const auto fileAccess = std::make_unique<CmdBridge::FileAccess>();
+ auto fileAccess = std::make_unique<CmdBridge::FileAccess>();
Utils::Result<> initResult = [&] {
if (options->copyCmdBridge) {
@@ -169,6 +172,7 @@ Result<> Device::up(const FilePath &path, InstanceConfig instanceConfig)
return initResult;
setFileAccess(fileAccess.get());
+ m_fileAccess = std::move(fileAccess);
return ResultOk;
}();
diff --git a/src/plugins/devcontainer/devcontainerdevice.h b/src/plugins/devcontainer/devcontainerdevice.h
index c0a011e8ba2..97951fd07a3 100644
--- a/src/plugins/devcontainer/devcontainerdevice.h
+++ b/src/plugins/devcontainer/devcontainerdevice.h
@@ -7,12 +7,18 @@
#include <utils/qtcprocess.h>
+namespace CmdBridge {
+class FileAccess;
+}
+
namespace DevContainer {
class Device : public ProjectExplorer::IDevice
{
public:
Device();
+ ~Device();
+
ProjectExplorer::IDeviceWidget *createWidget() override;
Utils::Result<> up(const Utils::FilePath &path, InstanceConfig instanceConfig);
@@ -26,6 +32,7 @@ public: // FilePath stuff
private:
Utils::Process::ProcessInterfaceCreator m_processInterfaceCreator;
InstanceConfig m_instanceConfig;
+ std::unique_ptr<CmdBridge::FileAccess> m_fileAccess;
};
} // namespace DevContainer
diff --git a/src/plugins/devcontainer/devcontainerplugin.cpp b/src/plugins/devcontainer/devcontainerplugin.cpp
index 045cce4c986..075b8fb2a93 100644
--- a/src/plugins/devcontainer/devcontainerplugin.cpp
+++ b/src/plugins/devcontainer/devcontainerplugin.cpp
@@ -33,6 +33,10 @@ struct Private
Q_GLOBAL_STATIC(Private, devContainerPluginPrivate)
+#ifdef WITH_TESTS
+QObject *createDevcontainerTest();
+#endif
+
static Utils::Result<std::shared_ptr<DevContainer::Device>> startDeviceForProject(
const Utils::FilePath &path,
ProjectExplorer::Project *project,
@@ -110,6 +114,9 @@ public:
void initialize() final
{
+#ifdef WITH_TESTS
+ addTestCreator(createDevcontainerTest);
+#endif
connect(ProjectManager::instance(), &ProjectManager::projectAdded, this, &onProjectAdded);
connect(ProjectManager::instance(), &ProjectManager::projectRemoved, this, &onProjectRemoved);
diff --git a/src/plugins/devcontainer/testdata/simpleproject/.devcontainer/devcontainer.json b/src/plugins/devcontainer/testdata/simpleproject/.devcontainer/devcontainer.json
new file mode 100644
index 00000000000..29f794e6c84
--- /dev/null
+++ b/src/plugins/devcontainer/testdata/simpleproject/.devcontainer/devcontainer.json
@@ -0,0 +1,12 @@
+{
+ "image": "alpine:latest",
+ "workspaceMount": "source=${localWorkspaceFolder},target=/custom/workspace,type=bind,consistency=cached",
+ "workspaceFolder": "/custom/workspace",
+ "customizations": {
+ "qt-creator": {
+ "device": {
+ "libexec-mount-point": "/custom/libexec/mnt/point"
+ }
+ }
+ }
+}
diff --git a/src/plugins/devcontainer/testdata/simpleproject/CMakeLists.txt b/src/plugins/devcontainer/testdata/simpleproject/CMakeLists.txt
new file mode 100644
index 00000000000..75e451d140e
--- /dev/null
+++ b/src/plugins/devcontainer/testdata/simpleproject/CMakeLists.txt
@@ -0,0 +1,7 @@
+cmake_minimum_required(VERSION 3.16)
+
+project(SimpleProject)
+
+add_executable(simpleproject
+ main.cpp
+)
diff --git a/src/plugins/devcontainer/testdata/simpleproject/main.cpp b/src/plugins/devcontainer/testdata/simpleproject/main.cpp
new file mode 100644
index 00000000000..905869dfa38
--- /dev/null
+++ b/src/plugins/devcontainer/testdata/simpleproject/main.cpp
@@ -0,0 +1,4 @@
+int main()
+{
+ return 0;
+}