aboutsummaryrefslogtreecommitdiffstats
path: root/tests/auto
diff options
context:
space:
mode:
authorChristian Kandeler <christian.kandeler@digia.com>2014-05-22 12:02:12 +0200
committerChristian Kandeler <christian.kandeler@digia.com>2014-07-02 16:46:11 +0200
commite264281c4810bb0afb07e8f590fc31e504d5e4d0 (patch)
tree1bf8a9f0aaf1f6734e4acf53003a681048156efd /tests/auto
parent9297ea217284e2279f2d4471b3f8fc754dc5fe71 (diff)
Make it possible to set profiles per product.
Use case 1: Build product A for architecture X and product B for architecture Y (e.g. host tools vs target libraries). Use case 2: Build product A for architectures X and Y and product B only for architecture X (e.g. Android multi-arch packages). Change-Id: I2eb721c37cdd12c298ee12bad60e21e94b04676b Reviewed-by: Joerg Bornemann <joerg.bornemann@digia.com>
Diffstat (limited to 'tests/auto')
-rw-r--r--tests/auto/api/testdata/multi-arch/host+target.input0
-rw-r--r--tests/auto/api/testdata/multi-arch/host-tool.input0
-rw-r--r--tests/auto/api/testdata/multi-arch/project.qbs44
-rw-r--r--tests/auto/api/tst_api.cpp95
-rw-r--r--tests/auto/api/tst_api.h1
-rw-r--r--tests/auto/blackbox/tst_blackbox.cpp26
-rw-r--r--tests/auto/blackbox/tst_blackbox.h1
7 files changed, 155 insertions, 12 deletions
diff --git a/tests/auto/api/testdata/multi-arch/host+target.input b/tests/auto/api/testdata/multi-arch/host+target.input
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/tests/auto/api/testdata/multi-arch/host+target.input
diff --git a/tests/auto/api/testdata/multi-arch/host-tool.input b/tests/auto/api/testdata/multi-arch/host-tool.input
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/tests/auto/api/testdata/multi-arch/host-tool.input
diff --git a/tests/auto/api/testdata/multi-arch/project.qbs b/tests/auto/api/testdata/multi-arch/project.qbs
new file mode 100644
index 000000000..1d8221b97
--- /dev/null
+++ b/tests/auto/api/testdata/multi-arch/project.qbs
@@ -0,0 +1,44 @@
+import qbs
+import qbs.FileInfo
+import qbs.TextFile
+
+Project {
+ property string hostProfile
+ property string targetProfile
+ Product {
+ name: "p1"
+ type: "output"
+ profiles: [project.targetProfile, project.hostProfile]
+ Group {
+ files: "host+target.input"
+ fileTags: "input"
+ }
+ }
+ Product {
+ name: "p2"
+ type: "output"
+ profiles: project.hostProfile
+ Group {
+ files: "host-tool.input"
+ fileTags: "input"
+ }
+ }
+
+ Rule {
+ inputs: "input"
+ Artifact {
+ fileName: FileInfo.baseName(input.fileName) + ".output"
+ fileTags: "output"
+ }
+ prepare: {
+ var cmd = new JavaScriptCommand();
+ cmd.description = "generating " + output.fileName;
+ cmd.sourceCode = function() {
+ var file = new TextFile(output.filePath, TextFile.WriteOnly);
+ file.write(product.moduleProperty("qbs", "architecture"));
+ file.close();
+ }
+ return cmd;
+ }
+ }
+}
diff --git a/tests/auto/api/tst_api.cpp b/tests/auto/api/tst_api.cpp
index 124665b1e..2040a14f9 100644
--- a/tests/auto/api/tst_api.cpp
+++ b/tests/auto/api/tst_api.cpp
@@ -35,16 +35,18 @@
#include <api/project.h>
#include <api/projectdata.h>
#include <logging/ilogsink.h>
+#include <tools/buildoptions.h>
#include <tools/fileinfo.h>
#include <tools/hostosinfo.h>
-#include <tools/buildoptions.h>
#include <tools/installoptions.h>
#include <tools/preferences.h>
+#include <tools/profile.h>
#include <tools/setupprojectparameters.h>
#include <QCoreApplication>
#include <QDir>
#include <QEventLoop>
+#include <QFile>
#include <QFileInfo>
#include <QScopedPointer>
#include <QStringList>
@@ -585,6 +587,94 @@ void TestApi::listBuildSystemFiles()
+ QLatin1String("/subproject2/subproject3/subproject3.qbs")));
}
+void TestApi::multiArch()
+{
+ qbs::SetupProjectParameters setupParams = defaultSetupParameters();
+ setupParams.setDryRun(false);
+ const QString projectDir
+ = QDir::cleanPath(m_workingDataDir + "/multi-arch");
+ const QString topLevelProjectFile = projectDir + QLatin1String("/project.qbs");
+ setupParams.setBuildRoot(projectDir);
+ setupParams.setProjectFilePath(topLevelProjectFile);
+ SettingsPtr settings = qbsSettings(QString());
+ qbs::Internal::TemporaryProfile tph("host", settings.data());
+ qbs::Profile hostProfile = tph.p;
+ hostProfile.setValue("qbs.architecture", "host-arch");
+ qbs::Internal::TemporaryProfile tpt("target", settings.data());
+ qbs::Profile targetProfile = tpt.p;
+ targetProfile.setValue("qbs.architecture", "target-arch");
+ QVariantMap overriddenValues;
+ overriddenValues.insert("project.hostProfile", hostProfile.name());
+ overriddenValues.insert("project.targetProfile", targetProfile.name());
+ overriddenValues.insert("qbs.endianness", "little"); // TODO: Why does the qbs module require this?
+ setupParams.setOverriddenValues(overriddenValues);
+ QScopedPointer<qbs::SetupProjectJob> setupJob(qbs::Project::setupProject(setupParams,
+ m_logSink, 0));
+ waitForFinished(setupJob.data());
+ QVERIFY2(!setupJob->error().hasError(), qPrintable(setupJob->error().toString()));
+ const qbs::Project &project = setupJob->project();
+ QCOMPARE(project.profile(), QLatin1String("qbs_autotests"));
+ const QList<qbs::ProductData> &products = project.projectData().products();
+ QCOMPARE(products.count(), 3);
+ QList<qbs::ProductData> hostProducts;
+ QList<qbs::ProductData> targetProducts;
+ foreach (const qbs::ProductData &p, products) {
+ QVERIFY2(p.profile() == hostProfile.name() || p.profile() == targetProfile.name(),
+ qPrintable(p.profile()));
+ if (p.profile() == hostProfile.name())
+ hostProducts << p;
+ else
+ targetProducts << p;
+ }
+ QCOMPARE(hostProducts.count(), 2);
+ QCOMPARE(targetProducts.count(), 1);
+ QCOMPARE(targetProducts.first().name(), QLatin1String("p1"));
+ QStringList hostProductNames
+ = QStringList() << hostProducts.first().name() << hostProducts.last().name();
+ QCOMPARE(hostProductNames.count("p1"), 1);
+ QCOMPARE(hostProductNames.count("p2"), 1);
+
+ QScopedPointer<qbs::BuildJob> buildJob(project.buildAllProducts(qbs::BuildOptions()));
+ waitForFinished(buildJob.data());
+ QVERIFY2(!buildJob->error().hasError(), qPrintable(buildJob->error().toString()));
+ const QString outputBaseDir(setupParams.buildRoot() + "/qbs_autotests-debug");
+ QFile p1HostArtifact(outputBaseDir + "/p1.host/host+target.output");
+ QVERIFY2(p1HostArtifact.exists(), qPrintable(p1HostArtifact.fileName()));
+ QVERIFY2(p1HostArtifact.open(QIODevice::ReadOnly), qPrintable(p1HostArtifact.errorString()));
+ QCOMPARE(p1HostArtifact.readAll().constData(), "host-arch");
+ QFile p1TargetArtifact(outputBaseDir + "/p1.target/host+target.output");
+ QVERIFY2(p1TargetArtifact.exists(), qPrintable(p1TargetArtifact.fileName()));
+ QVERIFY2(p1TargetArtifact.open(QIODevice::ReadOnly), qPrintable(p1TargetArtifact.errorString()));
+ QCOMPARE(p1TargetArtifact.readAll().constData(), "target-arch");
+ QFile p2Artifact(outputBaseDir + "/p2.host/host-tool.output");
+ QVERIFY2(p2Artifact.exists(), qPrintable(p2Artifact.fileName()));
+ QVERIFY2(p2Artifact.open(QIODevice::ReadOnly), qPrintable(p2Artifact.errorString()));
+ QCOMPARE(p2Artifact.readAll().constData(), "host-arch");
+
+ // Error check: Try to build for the same profile twice.
+ overriddenValues.insert("project.targetProfile", hostProfile.name());
+ setupParams.setOverriddenValues(overriddenValues);
+ setupJob.reset(qbs::Project::setupProject(setupParams, m_logSink, 0));
+ waitForFinished(setupJob.data());
+ QVERIFY(setupJob->error().hasError());
+ QVERIFY2(setupJob->error().toString().contains(hostProfile.name())
+ && setupJob->error().toString().contains("not allowed"),
+ qPrintable(setupJob->error().toString()));
+
+ // Error check: Try to build for the same profile twice, this time attaching
+ // the properties via the product name.
+ overriddenValues.clear();
+ overriddenValues.insert("p1.profiles", targetProfile.name() + ',' + targetProfile.name());
+ overriddenValues.insert("qbs.endianness", "little"); // TODO: Meh.
+ setupParams.setOverriddenValues(overriddenValues);
+ setupJob.reset(qbs::Project::setupProject(setupParams, m_logSink, 0));
+ waitForFinished(setupJob.data());
+ QVERIFY(setupJob->error().hasError());
+ QVERIFY2(setupJob->error().toString().contains(targetProfile.name())
+ && setupJob->error().toString().contains("not allowed"),
+ qPrintable(setupJob->error().toString()));
+}
+
void TestApi::nonexistingProjectPropertyFromProduct()
{
qbs::SetupProjectParameters setupParams = defaultSetupParameters();
@@ -622,7 +712,7 @@ qbs::SetupProjectParameters TestApi::defaultSetupParameters() const
{
qbs::SetupProjectParameters setupParams;
setupParams.setDryRun(true); // So no build graph gets created.
- setupParams.setBuildRoot(QLatin1String("/blubb")); // Must be set and be absolute.
+ setupParams.setBuildRoot(m_workingDataDir);
setupParams.setRestoreBehavior(qbs::SetupProjectParameters::ResolveOnly); // No restoring.
const QString qbsRootPath = QDir::cleanPath(QCoreApplication::applicationDirPath()
@@ -679,6 +769,7 @@ void TestApi::sourceFileInBuildDir()
const qbs::ProjectData projectData = job->project().projectData();
QCOMPARE(projectData.allProducts().count(), 1);
const qbs::ProductData product = projectData.allProducts().first();
+ QCOMPARE(product.profile(), QLatin1String("qbs_autotests"));
QCOMPARE(product.groups().count(), 1);
const qbs::GroupData group = product.groups().first();
QCOMPARE(group.allFilePaths().count(), 1);
diff --git a/tests/auto/api/tst_api.h b/tests/auto/api/tst_api.h
index 0ad65c5e5..7d1157512 100644
--- a/tests/auto/api/tst_api.h
+++ b/tests/auto/api/tst_api.h
@@ -57,6 +57,7 @@ private slots:
void installableFiles();
void isRunnable();
void listBuildSystemFiles();
+ void multiArch();
void nonexistingProjectPropertyFromProduct();
void nonexistingProjectPropertyFromCommandLine();
void references();
diff --git a/tests/auto/blackbox/tst_blackbox.cpp b/tests/auto/blackbox/tst_blackbox.cpp
index 148066009..d7d6129d1 100644
--- a/tests/auto/blackbox/tst_blackbox.cpp
+++ b/tests/auto/blackbox/tst_blackbox.cpp
@@ -776,8 +776,8 @@ void TestBlackbox::track_qobject_change()
QCOMPARE(runQbs(), 0);
const QString productFilePath = executableFilePath("i");
QVERIFY2(regularFileExists(productFilePath), qPrintable(productFilePath));
- QString moc_bla_objectFileName
- = buildDir + "/i/.obj/GeneratedFiles/moc_bla.cpp" QTC_HOST_OBJECT_SUFFIX;
+ QString moc_bla_objectFileName = productBuildDir("i")
+ + "/.obj/GeneratedFiles/moc_bla.cpp" QTC_HOST_OBJECT_SUFFIX;
QVERIFY2(regularFileExists(moc_bla_objectFileName), qPrintable(moc_bla_objectFileName));
QTest::qSleep(1000);
@@ -992,7 +992,8 @@ void TestBlackbox::trackRemoveFileTag()
QCOMPARE(runQbs(), 0);
// check if the artifacts are here that will become stale in the 2nd step
- QVERIFY(regularFileExists(buildDir + "/someapp/.obj/main_foo.cpp" QTC_HOST_OBJECT_SUFFIX));
+ QVERIFY(regularFileExists(productBuildDir("someapp")
+ + "/.obj/main_foo.cpp" QTC_HOST_OBJECT_SUFFIX));
QVERIFY(regularFileExists(productBuildDir("someapp") + "/main_foo.cpp"));
QVERIFY(regularFileExists(productBuildDir("someapp") + "/main.foo"));
@@ -2147,8 +2148,8 @@ void TestBlackbox::testWiX()
QVERIFY(m_qbsStdout.contains("compiling QbsBootstrapper.wxs"));
QVERIFY(m_qbsStdout.contains("linking qbs-" + arch + ".msi"));
QVERIFY(m_qbsStdout.contains("linking qbs-setup-" + arch + ".exe"));
- QVERIFY(regularFileExists(buildDir + "/QbsSetup/qbs-" + arch + ".msi"));
- QVERIFY(regularFileExists(buildDir + "/QbsBootstrapper/qbs-setup-" + arch + ".exe"));
+ QVERIFY(regularFileExists(productBuildDir("QbsSetup") + "/qbs-" + arch + ".msi"));
+ QVERIFY(regularFileExists(productBuildDir("QbsBootstrapper") + "/qbs-setup-" + arch + ".exe"));
}
static QString findExecutable(const QStringList &fileNames)
@@ -2188,7 +2189,7 @@ void TestBlackbox::testNodeJs()
params.command = QLatin1String("run");
QCOMPARE(runQbs(params), 0);
QVERIFY((bool)m_qbsStdout.contains("hello world"));
- QVERIFY(regularFileExists(buildDir + "/hello/hello.js"));
+ QVERIFY(regularFileExists(productBuildDir("hello") + "/hello.js"));
}
void TestBlackbox::testTypeScript()
@@ -2205,14 +2206,19 @@ void TestBlackbox::testTypeScript()
params.arguments = QStringList() << "-p" << "animals";
QCOMPARE(runQbs(params), 0);
- QVERIFY(regularFileExists(buildDir + "/animals/animals.js"));
- QVERIFY(regularFileExists(buildDir + "/animals/extra.js"));
- QVERIFY(regularFileExists(buildDir + "/animals/main.js"));
+ QVERIFY(regularFileExists(productBuildDir("animals") + "/animals.js"));
+ QVERIFY(regularFileExists(productBuildDir("animals") + "/extra.js"));
+ QVERIFY(regularFileExists(productBuildDir("animals") + "/main.js"));
+}
+
+QString TestBlackbox::uniqueProductName(const QString &productName) const
+{
+ return productName + '.' + buildProfileName;
}
QString TestBlackbox::productBuildDir(const QString &productName) const
{
- return buildDir + '/' + productName;
+ return buildDir + '/' + uniqueProductName(productName);
}
QString TestBlackbox::executableFilePath(const QString &productName) const
diff --git a/tests/auto/blackbox/tst_blackbox.h b/tests/auto/blackbox/tst_blackbox.h
index 568d1c08e..6076e4fda 100644
--- a/tests/auto/blackbox/tst_blackbox.h
+++ b/tests/auto/blackbox/tst_blackbox.h
@@ -183,6 +183,7 @@ private slots:
void testTypeScript();
private:
+ QString uniqueProductName(const QString &productName) const;
QString productBuildDir(const QString &productName) const;
QString executableFilePath(const QString &productName) const;