aboutsummaryrefslogtreecommitdiffstats
path: root/tests/auto/blackbox
diff options
context:
space:
mode:
authorChristian Kandeler <christian.kandeler@qt.io>2017-02-23 16:42:37 +0100
committerChristian Kandeler <christian.kandeler@qt.io>2019-01-23 14:35:02 +0000
commitc2833b1a009bc7c382b30d94109b9b7a25a404a6 (patch)
tree5b960940919310f8867e503234ca6d4f4295bfbe /tests/auto/blackbox
parent1bfc30065371a3d28421e2e7af5653e1e78259f3 (diff)
Introduce module providers
If a dependency is not found, we now search for a matching module provider that can generate one for us. We also provide a generic fall-back provider which uses pkg-config to locate the dependency (but could be extended to incorporate other methods in the future). This is the most important part of this change for practical purposes, as it makes hundreds of popular libraries available for use in qbs projects without users having to write any boilerplate code. In a future patch, a module provider could also be used to implement the functionality of the qtprofilesetup library, relieving users of the need to create a profile for building Qt applications. [ChangeLog] The Depends item now falls back to pkg-config to locate dependencies whose names do not correspond to a qbs module. Fixes: QBS-1107 Change-Id: Ifd4f05c237cf58cd9fe707c3da648d3dbb33e82b Reviewed-by: Leena Miettinen <riitta-leena.miettinen@qt.io> Reviewed-by: Joerg Bornemann <joerg.bornemann@qt.io>
Diffstat (limited to 'tests/auto/blackbox')
-rw-r--r--tests/auto/blackbox/testdata/fallback-module-provider/fallback-module-provider.qbs8
-rw-r--r--tests/auto/blackbox/testdata/fallback-module-provider/libdir/qbsmetatestmodule.pc5
-rw-r--r--tests/auto/blackbox/testdata/fallback-module-provider/main.cpp5
-rw-r--r--tests/auto/blackbox/testdata/module-providers/main.cpp6
-rw-r--r--tests/auto/blackbox/testdata/module-providers/module-providers.qbs20
-rw-r--r--tests/auto/blackbox/testdata/module-providers/module-providers/mygenerator/provider.qbs31
-rw-r--r--tests/auto/blackbox/tst_blackbox.cpp100
-rw-r--r--tests/auto/blackbox/tst_blackbox.h3
8 files changed, 178 insertions, 0 deletions
diff --git a/tests/auto/blackbox/testdata/fallback-module-provider/fallback-module-provider.qbs b/tests/auto/blackbox/testdata/fallback-module-provider/fallback-module-provider.qbs
new file mode 100644
index 000000000..a798e15b3
--- /dev/null
+++ b/tests/auto/blackbox/testdata/fallback-module-provider/fallback-module-provider.qbs
@@ -0,0 +1,8 @@
+CppApplication {
+ name: "p"
+ property bool fallbacksEnabled
+ Depends { name: "pkgconfig"; required: false }
+ Depends { name: "qbsmetatestmodule"; required: false; enableFallback: fallbacksEnabled }
+ property bool dummy: { console.info("pkg-config present: " + pkgconfig.present); }
+ files: "main.cpp"
+}
diff --git a/tests/auto/blackbox/testdata/fallback-module-provider/libdir/qbsmetatestmodule.pc b/tests/auto/blackbox/testdata/fallback-module-provider/libdir/qbsmetatestmodule.pc
new file mode 100644
index 000000000..ae4daba89
--- /dev/null
+++ b/tests/auto/blackbox/testdata/fallback-module-provider/libdir/qbsmetatestmodule.pc
@@ -0,0 +1,5 @@
+Name: qbsmetatestmodule
+Description: just a test
+Version: 0.0.1
+
+Cflags: -DTHE_MAGIC_DEFINE
diff --git a/tests/auto/blackbox/testdata/fallback-module-provider/main.cpp b/tests/auto/blackbox/testdata/fallback-module-provider/main.cpp
new file mode 100644
index 000000000..442b755bf
--- /dev/null
+++ b/tests/auto/blackbox/testdata/fallback-module-provider/main.cpp
@@ -0,0 +1,5 @@
+#ifndef THE_MAGIC_DEFINE
+#error "missing the magic define"
+#endif
+
+int main() {}
diff --git a/tests/auto/blackbox/testdata/module-providers/main.cpp b/tests/auto/blackbox/testdata/module-providers/main.cpp
new file mode 100644
index 000000000..9cd29b1fe
--- /dev/null
+++ b/tests/auto/blackbox/testdata/module-providers/main.cpp
@@ -0,0 +1,6 @@
+#include <iostream>
+
+int main()
+{
+ std::cout << "The letters are " << LETTER1 << " and " << LETTER2 << std::endl;
+}
diff --git a/tests/auto/blackbox/testdata/module-providers/module-providers.qbs b/tests/auto/blackbox/testdata/module-providers/module-providers.qbs
new file mode 100644
index 000000000..d1ff79269
--- /dev/null
+++ b/tests/auto/blackbox/testdata/module-providers/module-providers.qbs
@@ -0,0 +1,20 @@
+Project {
+ CppApplication {
+ name: "app1"
+ Depends { name: "mygenerator.module1" }
+ Depends { name: "mygenerator.module2" }
+ moduleProviders.mygenerator.chooseLettersFrom: "beginning"
+ files: "main.cpp"
+ }
+ CppApplication {
+ name: "app2"
+ Depends { name: "mygenerator.module1" }
+ Depends { name: "mygenerator.module2" }
+ Profile {
+ name: "myProfile"
+ moduleProviders.mygenerator.chooseLettersFrom: "end"
+ }
+ qbs.profile: "myProfile"
+ files: "main.cpp"
+ }
+}
diff --git a/tests/auto/blackbox/testdata/module-providers/module-providers/mygenerator/provider.qbs b/tests/auto/blackbox/testdata/module-providers/module-providers/mygenerator/provider.qbs
new file mode 100644
index 000000000..dae02c03a
--- /dev/null
+++ b/tests/auto/blackbox/testdata/module-providers/module-providers/mygenerator/provider.qbs
@@ -0,0 +1,31 @@
+import qbs.File;
+import qbs.FileInfo;
+import qbs.TextFile;
+
+ModuleProvider {
+ property string chooseLettersFrom
+ relativeSearchPaths: {
+ console.info("Running setup script for " + name);
+ var startAtBeginning = chooseLettersFrom === "beginning";
+ var moduleBaseDir = FileInfo.joinPaths(outputBaseDir, "modules", "mygenerator");
+ var module1Dir = FileInfo.joinPaths(moduleBaseDir, "module1");
+ File.makePath(module1Dir);
+ var module1 = new TextFile(FileInfo.joinPaths(module1Dir, "module1.qbs"), TextFile.WriteOnly);
+ module1.writeLine("Module {");
+ module1.writeLine(" Depends { name: 'cpp' }");
+ module1.writeLine(" cpp.defines: 'LETTER1=" + (startAtBeginning ? "\\\'A\\\'" : "\\\'Z\\\'")
+ + "'");
+ module1.writeLine("}");
+ module1.close();
+ var module2Dir = FileInfo.joinPaths(moduleBaseDir, "module2");
+ File.makePath(module2Dir);
+ var module2 = new TextFile(FileInfo.joinPaths(module2Dir, "module2.qbs"), TextFile.WriteOnly);
+ module2.writeLine("Module {");
+ module2.writeLine(" Depends { name: 'cpp' }");
+ module2.writeLine(" cpp.defines: 'LETTER2=" + (startAtBeginning ? "\\\'B\\\'" : "\\\'Y\\\'")
+ + "'");
+ module2.writeLine("}");
+ module2.close();
+ return "";
+ }
+}
diff --git a/tests/auto/blackbox/tst_blackbox.cpp b/tests/auto/blackbox/tst_blackbox.cpp
index fbcd16eb8..82f29f320 100644
--- a/tests/auto/blackbox/tst_blackbox.cpp
+++ b/tests/auto/blackbox/tst_blackbox.cpp
@@ -6310,6 +6310,106 @@ void TestBlackbox::maximumCxxLanguageVersion()
m_qbsStdout.constData());
}
+void TestBlackbox::moduleProviders()
+{
+ QDir::setCurrent(testDataDir + "/module-providers");
+
+ // Resolving in dry-run mode must not leave any data behind.
+ QCOMPARE(runQbs(QbsRunParameters("resolve", QStringList("-n"))), 0);
+ QCOMPARE(m_qbsStdout.count("Running setup script for mygenerator"), 2);
+ QVERIFY(!QFile::exists(relativeBuildDir()));
+
+ // Initial build.
+ QCOMPARE(runQbs(QbsRunParameters("run", QStringList{"-p", "app1"})), 0);
+ QVERIFY(QFile::exists(relativeBuildDir()));
+ QCOMPARE(m_qbsStdout.count("Running setup script for mygenerator"), 2);
+ QVERIFY2(m_qbsStdout.contains("The letters are A and B"), m_qbsStdout.constData());
+ QCOMPARE(runQbs(QbsRunParameters("run", QStringList{"-p", "app2"})), 0);
+ QVERIFY2(m_qbsStdout.contains("The letters are Z and Y"), m_qbsStdout.constData());
+
+ // Rebuild with overridden module provider config. The output for product 2 must change,
+ // but no setup script must be re-run, because both config values have already been
+ // handled in the first run.
+ const QStringList resolveArgs("moduleProviders.mygenerator.chooseLettersFrom:beginning");
+ QCOMPARE(runQbs(QbsRunParameters("resolve", resolveArgs)), 0);
+ QVERIFY2(!m_qbsStdout.contains("Running setup script"), m_qbsStdout.constData());
+ QCOMPARE(runQbs(QbsRunParameters("run", QStringList{"-p", "app1"})), 0);
+ QVERIFY2(m_qbsStdout.contains("The letters are A and B"), m_qbsStdout.constData());
+ QCOMPARE(runQbs(QbsRunParameters("run", QStringList{"-p", "app2"})), 0);
+ QVERIFY2(m_qbsStdout.contains("The letters are A and B"), m_qbsStdout.constData());
+
+ // Forcing Probe execution triggers a re-run of the setup script. But only once,
+ // because the module provider config is the same now.
+ QCOMPARE(runQbs(QbsRunParameters("resolve", QStringList(resolveArgs)
+ << "--force-probe-execution")), 0);
+ QCOMPARE(m_qbsStdout.count("Running setup script for mygenerator"), 1);
+ QCOMPARE(runQbs(QbsRunParameters("run", QStringList{"-p", "app1"})), 0);
+ QVERIFY2(m_qbsStdout.contains("The letters are A and B"), m_qbsStdout.constData());
+ QCOMPARE(runQbs(QbsRunParameters("run", QStringList{"-p", "app2"})), 0);
+ QVERIFY2(m_qbsStdout.contains("The letters are A and B"), m_qbsStdout.constData());
+
+ // Now re-run without the module provider config override. Again, the setup script must
+ // run once, for the config value that was not present in the last run.
+ QCOMPARE(runQbs(QbsRunParameters("resolve")), 0);
+ QCOMPARE(m_qbsStdout.count("Running setup script for mygenerator"), 1);
+ QCOMPARE(runQbs(QbsRunParameters("run", QStringList{"-p", "app1"})), 0);
+ QVERIFY2(m_qbsStdout.contains("The letters are A and B"), m_qbsStdout.constData());
+ QCOMPARE(runQbs(QbsRunParameters("run", QStringList{"-p", "app2"})), 0);
+ QVERIFY2(m_qbsStdout.contains("The letters are Z and Y"), m_qbsStdout.constData());
+}
+
+void TestBlackbox::fallbackModuleProvider_data()
+{
+ QTest::addColumn<bool>("fallbacksEnabledGlobally");
+ QTest::addColumn<bool>("fallbacksEnabledInProduct");
+ QTest::addColumn<QStringList>("pkgConfigLibDirs");
+ QTest::addColumn<bool>("successExpected");
+ QTest::newRow("without custom lib dir, fallbacks disabled globally and in product")
+ << false << false << QStringList() << false;
+ QTest::newRow("without custom lib dir, fallbacks disabled globally, enabled in product")
+ << false << true << QStringList() << false;
+ QTest::newRow("without custom lib dir, fallbacks enabled globally, disabled in product")
+ << true << false << QStringList() << false;
+ QTest::newRow("without custom lib dir, fallbacks enabled globally and in product")
+ << true << true << QStringList() << false;
+ QTest::newRow("with custom lib dir, fallbacks disabled globally and in product")
+ << false << false << QStringList(testDataDir + "/fallback-module-provider/libdir")
+ << false;
+ QTest::newRow("with custom lib dir, fallbacks disabled globally, enabled in product")
+ << false << true << QStringList(testDataDir + "/fallback-module-provider/libdir")
+ << false;
+ QTest::newRow("with custom lib dir, fallbacks enabled globally, disabled in product")
+ << true << false << QStringList(testDataDir + "/fallback-module-provider/libdir")
+ << false;
+ QTest::newRow("with custom lib dir, fallbacks enabled globally and in product")
+ << true << true << QStringList(testDataDir + "/fallback-module-provider/libdir")
+ << true;
+}
+
+void TestBlackbox::fallbackModuleProvider()
+{
+ QFETCH(bool, fallbacksEnabledInProduct);
+ QFETCH(bool, fallbacksEnabledGlobally);
+ QFETCH(QStringList, pkgConfigLibDirs);
+ QFETCH(bool, successExpected);
+ QDir::setCurrent(testDataDir + "/fallback-module-provider");
+ static const auto b2s = [](bool b) { return QString(b ? "true" : "false"); };
+ QbsRunParameters resolveParams("resolve",
+ QStringList{"modules.pkgconfig.libDirs:" + pkgConfigLibDirs.join(','),
+ "products.p.fallbacksEnabled:" + b2s(fallbacksEnabledInProduct)});
+ if (!fallbacksEnabledGlobally)
+ resolveParams.arguments << "--no-fallback-module-provider";
+ QCOMPARE(runQbs(resolveParams), 0);
+ const bool pkgConfigPresent = m_qbsStdout.contains("pkg-config present: true");
+ const bool pkgConfigNotPresent = m_qbsStdout.contains("pkg-config present: false");
+ QVERIFY(pkgConfigPresent != pkgConfigNotPresent);
+ if (pkgConfigNotPresent)
+ successExpected = false;
+ QbsRunParameters buildParams;
+ buildParams.expectFailure = !successExpected;
+ QCOMPARE(runQbs(buildParams) == 0, successExpected);
+}
+
void TestBlackbox::minimumSystemVersion()
{
rmDirR(relativeBuildDir());
diff --git a/tests/auto/blackbox/tst_blackbox.h b/tests/auto/blackbox/tst_blackbox.h
index 313ad5d40..624cd5fbb 100644
--- a/tests/auto/blackbox/tst_blackbox.h
+++ b/tests/auto/blackbox/tst_blackbox.h
@@ -174,6 +174,9 @@ private slots:
void makefileGenerator();
void maximumCLanguageVersion();
void maximumCxxLanguageVersion();
+ void moduleProviders();
+ void fallbackModuleProvider_data();
+ void fallbackModuleProvider();
void minimumSystemVersion();
void minimumSystemVersion_data();
void missingBuildGraph();