diff options
author | Christian Kandeler <christian.kandeler@theqtcompany.com> | 2016-08-04 12:00:41 +0200 |
---|---|---|
committer | Christian Kandeler <christian.kandeler@qt.io> | 2016-08-08 20:17:04 +0000 |
commit | 188c160b658dc96a70afb08e80286866d6b4c507 (patch) | |
tree | ea72b10145ed31ffce5ec7b48051a391d47d1909 /tests/auto/blackbox/tst_blackboxjava.cpp | |
parent | 2c916bea64bc480282eeddfc1d55042be10fa4e9 (diff) |
Split off the Java-related blackbox tests
They take an extraordinary amount of time and should thus run in
parallel to the other tests.
Change-Id: I435dd5506cc3f26e351c700ce6be2476d041b6af
Reviewed-by: Jake Petroules <jake.petroules@qt.io>
Diffstat (limited to 'tests/auto/blackbox/tst_blackboxjava.cpp')
-rw-r--r-- | tests/auto/blackbox/tst_blackboxjava.cpp | 293 |
1 files changed, 293 insertions, 0 deletions
diff --git a/tests/auto/blackbox/tst_blackboxjava.cpp b/tests/auto/blackbox/tst_blackboxjava.cpp new file mode 100644 index 000000000..39d32a11a --- /dev/null +++ b/tests/auto/blackbox/tst_blackboxjava.cpp @@ -0,0 +1,293 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing +** +** This file is part of Qbs. +** +** 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 http://www.qt.io/terms-conditions. For further information +** use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +****************************************************************************/ + +#include "tst_blackboxjava.h" + +#include "../shared.h" +#include <tools/hostosinfo.h> +#include <tools/profile.h> +#include <tools/settings.h> + +#include <QJsonDocument> +#include <QTemporaryDir> + +using qbs::Internal::HostOsInfo; +using qbs::Profile; +using qbs::Settings; + +QMap<QString, QString> TestBlackboxJava::findAndroid(int *status) +{ + QTemporaryDir temp; + QDir::setCurrent(testDataDir + "/find"); + QbsRunParameters params = QStringList() << "-f" << "find-android.qbs"; + params.buildDirectory = temp.path(); + const int res = runQbs(params); + if (status) + *status = res; + QFile file(temp.path() + "/" + relativeProductBuildDir("find-android") + "/android.json"); + if (!file.open(QIODevice::ReadOnly)) + return QMap<QString, QString> { }; + const auto tools = QJsonDocument::fromJson(file.readAll()).toVariant().toMap(); + return QMap<QString, QString> { + {"sdk", QDir::fromNativeSeparators(tools["sdk"].toString())}, + {"ndk", QDir::fromNativeSeparators(tools["ndk"].toString())}, + }; +} + +TestBlackboxJava::TestBlackboxJava() : TestBlackboxBase (SRCDIR "/testdata-java", "blackbox-java") +{ +} + +void TestBlackboxJava::android() +{ + QFETCH(QString, projectDir); + QFETCH(QStringList, productNames); + QFETCH(QList<int>, apkFileCounts); + + int status; + const auto androidPaths = findAndroid(&status); + + const auto ndkPath = androidPaths["ndk"]; + static const QStringList ndkSamplesDirs = QStringList() << "teapot" << "no-native"; + if (!ndkPath.isEmpty() && !QFileInfo(ndkPath + "/samples").isDir() + && ndkSamplesDirs.contains(projectDir)) + QSKIP("NDK samples directory not present"); + + QDir::setCurrent(testDataDir + "/android/" + projectDir); + Settings s((QString())); + Profile p("qbs_autotests-android", &s); + if (!p.exists() || (status != 0 && !p.value("Android.sdk.ndkDir").isValid())) + QSKIP("No suitable Android test profile"); + QbsRunParameters params(QStringList("profile:" + p.name()) + << "Android.ndk.platform:android-21"); + params.useProfile = false; + QCOMPARE(runQbs(params), 0); + for (int i = 0; i < productNames.count(); ++i) { + const QString productName = productNames.at(i); + QVERIFY(m_qbsStdout.contains("Creating " + productName.toLocal8Bit() + ".apk")); + const QString apkFilePath = relativeProductBuildDir(productName, p.name()) + + '/' + productName + ".apk"; + QVERIFY2(regularFileExists(apkFilePath), qPrintable(apkFilePath)); + const QString jarFilePath = findExecutable(QStringList("jar")); + QVERIFY(!jarFilePath.isEmpty()); + QProcess jar; + jar.start(jarFilePath, QStringList() << "-tf" << apkFilePath); + QVERIFY2(jar.waitForStarted(), qPrintable(jar.errorString())); + QVERIFY2(jar.waitForFinished(), qPrintable(jar.errorString())); + QVERIFY2(jar.exitCode() == 0, qPrintable(jar.readAllStandardError().constData())); + QCOMPARE(jar.readAllStandardOutput().trimmed().split('\n').count(), apkFileCounts.at(i)); + } +} + +void TestBlackboxJava::android_data() +{ + QTest::addColumn<QString>("projectDir"); + QTest::addColumn<QStringList>("productNames"); + QTest::addColumn<QList<int>>("apkFileCounts"); + QTest::newRow("teapot") << "teapot" << QStringList("com.sample.teapot") << (QList<int>() << 25); + QTest::newRow("no native") << "no-native" + << QStringList("com.example.android.basicmediadecoder") << (QList<int>() << 22); + QTest::newRow("multiple libs") << "multiple-libs-per-apk" << QStringList("twolibs") + << (QList<int>() << 10); + QTest::newRow("multiple apks") << "multiple-apks-per-project" + << (QStringList() << "twolibs1" << "twolibs2") + << (QList<int>() << 15 << 9); +} + +static QProcessEnvironment processEnvironmentWithCurrentDirectoryInLibraryPath() +{ + QProcessEnvironment env = QProcessEnvironment::systemEnvironment(); + env.insert(HostOsInfo::libraryPathEnvironmentVariable(), + (QStringList() << env.value(HostOsInfo::libraryPathEnvironmentVariable()) << ".") + .join(HostOsInfo::pathListSeparator())); + return env; +} + +void TestBlackboxJava::java() +{ +#if defined(Q_OS_WIN32) && !defined(Q_OS_WIN64) + QSKIP("QTBUG-3845"); +#endif + + Settings settings((QString())); + Profile p(profileName(), &settings); + + int status; + const auto jdkTools = findJdkTools(&status); + QCOMPARE(status, 0); + + QDir::setCurrent(testDataDir + "/java"); + + status = runQbs(); + if (p.value("java.jdkPath").toString().isEmpty() + && status != 0 && m_qbsStderr.contains("jdkPath")) { + QSKIP("java.jdkPath not set and automatic detection failed"); + } + + QCOMPARE(status, 0); + + const QStringList classFiles = + QStringList() << "Jet" << "Ship" << "Vehicles"; + QStringList classFiles1 = QStringList(classFiles) << "io/qt/qbs/HelloWorld" << "NoPackage"; + for (int i = 0; i < classFiles1.count(); ++i) { + QString &classFile = classFiles1[i]; + classFile = relativeProductBuildDir("class_collection") + "/classes/" + + classFile + ".class"; + QVERIFY2(regularFileExists(classFile), qPrintable(classFile)); + } + + foreach (const QString &classFile, classFiles) { + const QString filePath = relativeProductBuildDir("jar_file") + "/classes/" + classFile + + ".class"; + QVERIFY2(regularFileExists(filePath), qPrintable(filePath)); + } + const QString jarFilePath = relativeProductBuildDir("jar_file") + '/' + "jar_file.jar"; + QVERIFY2(regularFileExists(jarFilePath), qPrintable(jarFilePath)); + + // Now check whether we correctly predicted the class file output paths. + QCOMPARE(runQbs(QbsRunParameters("clean")), 0); + foreach (const QString &classFile, classFiles1) { + QVERIFY2(!regularFileExists(classFile), qPrintable(classFile)); + } + + // This tests various things: java.manifestClassPath, JNI, etc. + QDir::setCurrent(relativeBuildDir() + "/install-root"); + QProcess process; + process.setProcessEnvironment(processEnvironmentWithCurrentDirectoryInLibraryPath()); + process.start(HostOsInfo::appendExecutableSuffix(jdkTools["java"]), + QStringList() << "-jar" << "jar_file.jar"); + if (process.waitForStarted()) { + QVERIFY2(process.waitForFinished(), qPrintable(process.errorString())); + QVERIFY2(process.exitCode() == 0, process.readAllStandardError().constData()); + const QByteArray stdOut = process.readAllStandardOutput(); + QVERIFY2(stdOut.contains("Driving!"), stdOut.constData()); + QVERIFY2(stdOut.contains("Flying!"), stdOut.constData()); + QVERIFY2(stdOut.contains("Flying (this is a space ship)!"), stdOut.constData()); + QVERIFY2(stdOut.contains("Sailing!"), stdOut.constData()); + QVERIFY2(stdOut.contains("Native code performing complex internal combustion process ("), + stdOut.constData()); + } + + process.start("unzip", QStringList() << "-p" << "jar_file.jar"); + if (process.waitForStarted()) { + QVERIFY2(process.waitForFinished(), qPrintable(process.errorString())); + const QByteArray stdOut = process.readAllStandardOutput(); + QVERIFY2(stdOut.contains("Class-Path: car_jar.jar random_stuff.jar"), stdOut.constData()); + QVERIFY2(stdOut.contains("Main-Class: Vehicles"), stdOut.constData()); + } +} + +static QString dpkgArch(const QString &prefix = QString()) +{ + QProcess dpkg; + dpkg.start("/usr/bin/dpkg", QStringList() << "--print-architecture"); + dpkg.waitForFinished(); + if (dpkg.exitStatus() == QProcess::NormalExit && dpkg.exitCode() == 0) + return prefix + QString::fromLocal8Bit(dpkg.readAllStandardOutput().trimmed()); + return QString(); +} + +void TestBlackboxJava::javaDependencyTracking() +{ + Settings settings((QString())); + Profile p(profileName(), &settings); + + auto getSpecificJdkVersion = [](const QString &jdkVersion) -> QString { + if (HostOsInfo::isMacosHost()) { + QProcess java_home; + java_home.start("/usr/libexec/java_home", QStringList() << "--version" << jdkVersion); + java_home.waitForFinished(); + if (java_home.exitStatus() == QProcess::NormalExit && java_home.exitCode() == 0) + return QString::fromLocal8Bit(java_home.readAllStandardOutput().trimmed()); + } else if (HostOsInfo::isWindowsHost()) { + QSettings settings("HKEY_LOCAL_MACHINE\\SOFTWARE\\JavaSoft\\Java Development Kit\\" + + jdkVersion, QSettings::NativeFormat); + return settings.value("JavaHome").toString(); + } else { + QString minorVersion = jdkVersion; + if (minorVersion.startsWith("1.")) + minorVersion.remove(0, 2); + + const QStringList searchPaths = { + "/usr/lib/jvm/java-" + minorVersion + "-openjdk" + dpkgArch("-"), // Debian + "/usr/lib/jvm/java-" + minorVersion + "-openjdk", // Arch + "/usr/lib/jvm/jre-1." + minorVersion + ".0-openjdk", // Fedora + }; + for (const QString &searchPath : searchPaths) { + if (QFile::exists(searchPath + "/bin/javac")) + return searchPath; + } + } + + return QString(); + }; + + auto runQbsTest = [&](const QString &jdkPath, const QString &javaVersion, + const QString &arg) { + QDir::setCurrent(testDataDir + "/java"); + QbsRunParameters rp; + rp.arguments.append(arg); + if (!jdkPath.isEmpty()) + rp.arguments << ("java.jdkPath:" + jdkPath); + if (!javaVersion.isEmpty()) + rp.arguments << ("java.languageVersion:" + javaVersion); + rmDirR(relativeBuildDir()); + QCOMPARE(runQbs(rp), 0); + }; + + static const auto knownJdkVersions = QStringList() << "1.6" << "1.7" << "1.8" << "1.9" + << QString(); // default JDK; + QStringList seenJdkVersions; + for (const auto &jdkVersion : knownJdkVersions) { + QString specificJdkPath = getSpecificJdkVersion(jdkVersion); + if (jdkVersion.isEmpty() || !specificJdkPath.isEmpty()) { + const auto jdkPath = jdkVersion.isEmpty() ? jdkVersion : specificJdkPath; + + if (!jdkVersion.isEmpty()) + seenJdkVersions << jdkVersion; + + if (!seenJdkVersions.isEmpty()) { + const auto javaVersions = QStringList() + << knownJdkVersions.mid(0, knownJdkVersions.indexOf(seenJdkVersions.last()) + 1) + << QString(); // also test with no explicitly specified source version + + for (const auto ¤tJavaVersion : javaVersions) { + runQbsTest(jdkPath, currentJavaVersion, "--check-outputs"); + runQbsTest(jdkPath, currentJavaVersion, "--dry-run"); + } + } + } + } + + if (seenJdkVersions.isEmpty()) + QSKIP("No JDKs installed"); +} + +QTEST_MAIN(TestBlackboxJava) |