aboutsummaryrefslogtreecommitdiffstats
path: root/tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests')
-rw-r--r--tests/auto/auto.qbs3
-rw-r--r--tests/auto/blackbox/CMakeLists.txt9
-rw-r--r--tests/auto/blackbox/blackbox-windows.pro18
-rw-r--r--tests/auto/blackbox/blackbox-windows.qbs21
-rw-r--r--tests/auto/blackbox/testdata-baremetal/compiler-listing/compiler-listing.qbs (renamed from tests/auto/blackbox/testdata-baremetal/generate-compiler-listing/generate-compiler-listing.qbs)4
-rw-r--r--tests/auto/blackbox/testdata-baremetal/compiler-listing/fun.c (renamed from tests/auto/blackbox/testdata-baremetal/do-not-generate-compiler-listing/fun.c)0
-rw-r--r--tests/auto/blackbox/testdata-baremetal/compiler-listing/main.c (renamed from tests/auto/blackbox/testdata-baremetal/do-not-generate-compiler-listing/main.c)0
-rw-r--r--tests/auto/blackbox/testdata-baremetal/do-not-generate-compiler-listing/do-not-generate-compiler-listing.qbs16
-rw-r--r--tests/auto/blackbox/testdata-baremetal/external-static-libraries/external-static-libraries.qbs14
-rw-r--r--tests/auto/blackbox/testdata-baremetal/generate-compiler-listing/fun.c4
-rw-r--r--tests/auto/blackbox/testdata-baremetal/generate-compiler-listing/main.c6
-rw-r--r--tests/auto/blackbox/testdata-baremetal/linker-map/linker-map.qbs6
-rw-r--r--tests/auto/blackbox/testdata-windows/codesign/app.cpp1
-rw-r--r--tests/auto/blackbox/testdata-windows/codesign/codesign.qbs37
-rw-r--r--tests/auto/blackbox/tst_blackboxbaremetal.cpp96
-rw-r--r--tests/auto/blackbox/tst_blackboxwindows.cpp174
-rw-r--r--tests/auto/blackbox/tst_blackboxwindows.h51
-rw-r--r--tests/auto/tools/tst_tools.cpp24
-rw-r--r--tests/auto/tools/tst_tools.h1
19 files changed, 400 insertions, 85 deletions
diff --git a/tests/auto/auto.qbs b/tests/auto/auto.qbs
index 8dd301f68..0d87af9fe 100644
--- a/tests/auto/auto.qbs
+++ b/tests/auto/auto.qbs
@@ -4,7 +4,6 @@ Project {
name: "Autotests"
references: [
"api/api.qbs",
- "blackbox/blackbox.qbs",
"blackbox/blackbox-android.qbs",
"blackbox/blackbox-apple.qbs",
"blackbox/blackbox-baremetal.qbs",
@@ -13,6 +12,8 @@ Project {
"blackbox/blackbox-java.qbs",
"blackbox/blackbox-joblimits.qbs",
"blackbox/blackbox-qt.qbs",
+ "blackbox/blackbox-windows.qbs",
+ "blackbox/blackbox.qbs",
"buildgraph/buildgraph.qbs",
"cmdlineparser/cmdlineparser.qbs",
"language/language.qbs",
diff --git a/tests/auto/blackbox/CMakeLists.txt b/tests/auto/blackbox/CMakeLists.txt
index 88eed4b42..0bf79a433 100644
--- a/tests/auto/blackbox/CMakeLists.txt
+++ b/tests/auto/blackbox/CMakeLists.txt
@@ -70,3 +70,12 @@ add_qbs_test(blackbox-qt
tst_blackboxqt.cpp
tst_blackboxqt.h
)
+
+add_qbs_test(blackbox-windows
+ SOURCES
+ ../shared.h
+ tst_blackboxbase.cpp
+ tst_blackboxbase.h
+ tst_blackboxwindows.cpp
+ tst_blackboxwindows.h
+ )
diff --git a/tests/auto/blackbox/blackbox-windows.pro b/tests/auto/blackbox/blackbox-windows.pro
new file mode 100644
index 000000000..a9e8fdbd2
--- /dev/null
+++ b/tests/auto/blackbox/blackbox-windows.pro
@@ -0,0 +1,18 @@
+TARGET = tst_blackbox-windows
+
+HEADERS = tst_blackboxwindows.h tst_blackboxbase.h
+SOURCES = tst_blackboxwindows.cpp tst_blackboxbase.cpp
+OBJECTS_DIR = windows
+MOC_DIR = $${OBJECTS_DIR}-moc
+
+include(../auto.pri)
+
+DATA_DIRS = testdata-windows ../find
+
+for(data_dir, DATA_DIRS) {
+ files = $$files($$PWD/$$data_dir/*, true)
+ win32:files ~= s|\\\\|/|g
+ for(file, files):!exists($$file/*):FILES += $$file
+}
+
+OTHER_FILES += $$FILES
diff --git a/tests/auto/blackbox/blackbox-windows.qbs b/tests/auto/blackbox/blackbox-windows.qbs
new file mode 100644
index 000000000..e32421e3b
--- /dev/null
+++ b/tests/auto/blackbox/blackbox-windows.qbs
@@ -0,0 +1,21 @@
+import qbs.Utilities
+
+QbsAutotest {
+ testName: "blackbox-windows"
+ Depends { name: "qbs_app" }
+ Depends { name: "qbs-setup-toolchains" }
+ Group {
+ name: "testdata"
+ prefix: "testdata-windows/"
+ files: ["**/*"]
+ fileTags: []
+ }
+ files: [
+ "../shared.h",
+ "tst_blackboxbase.cpp",
+ "tst_blackboxbase.h",
+ "tst_blackboxwindows.cpp",
+ "tst_blackboxwindows.h",
+ ]
+ cpp.defines: base.concat(["SRCDIR=" + Utilities.cStringQuote(path)])
+}
diff --git a/tests/auto/blackbox/testdata-baremetal/generate-compiler-listing/generate-compiler-listing.qbs b/tests/auto/blackbox/testdata-baremetal/compiler-listing/compiler-listing.qbs
index a6731d224..bcf983c88 100644
--- a/tests/auto/blackbox/testdata-baremetal/generate-compiler-listing/generate-compiler-listing.qbs
+++ b/tests/auto/blackbox/testdata-baremetal/compiler-listing/compiler-listing.qbs
@@ -3,14 +3,12 @@ import "../BareMetalApplication.qbs" as BareMetalApplication
BareMetalApplication {
condition: {
if (!qbs.toolchain.contains("gcc")) {
- if (cpp.compilerName.startsWith("armcc"))
- console.info("using short listing file names");
+ console.info("compiler listing suffix: %%" + cpp.compilerListingSuffix + "%%");
return true;
}
console.info("unsupported toolset: %%"
+ qbs.toolchainType + "%%, %%" + qbs.architecture + "%%");
return false;
}
- cpp.generateCompilerListingFiles: true
files: ["main.c", "fun.c"]
}
diff --git a/tests/auto/blackbox/testdata-baremetal/do-not-generate-compiler-listing/fun.c b/tests/auto/blackbox/testdata-baremetal/compiler-listing/fun.c
index 3b8c8f2f4..3b8c8f2f4 100644
--- a/tests/auto/blackbox/testdata-baremetal/do-not-generate-compiler-listing/fun.c
+++ b/tests/auto/blackbox/testdata-baremetal/compiler-listing/fun.c
diff --git a/tests/auto/blackbox/testdata-baremetal/do-not-generate-compiler-listing/main.c b/tests/auto/blackbox/testdata-baremetal/compiler-listing/main.c
index 2c3d7726c..2c3d7726c 100644
--- a/tests/auto/blackbox/testdata-baremetal/do-not-generate-compiler-listing/main.c
+++ b/tests/auto/blackbox/testdata-baremetal/compiler-listing/main.c
diff --git a/tests/auto/blackbox/testdata-baremetal/do-not-generate-compiler-listing/do-not-generate-compiler-listing.qbs b/tests/auto/blackbox/testdata-baremetal/do-not-generate-compiler-listing/do-not-generate-compiler-listing.qbs
deleted file mode 100644
index 1bc4ba208..000000000
--- a/tests/auto/blackbox/testdata-baremetal/do-not-generate-compiler-listing/do-not-generate-compiler-listing.qbs
+++ /dev/null
@@ -1,16 +0,0 @@
-import "../BareMetalApplication.qbs" as BareMetalApplication
-
-BareMetalApplication {
- condition: {
- if (!qbs.toolchain.contains("gcc")) {
- if (cpp.compilerName.startsWith("armcc"))
- console.info("using short listing file names");
- return true;
- }
- console.info("unsupported toolset: %%"
- + qbs.toolchainType + "%%, %%" + qbs.architecture + "%%");
- return false;
- }
- cpp.generateCompilerListingFiles: false
- files: ["main.c", "fun.c"]
-}
diff --git a/tests/auto/blackbox/testdata-baremetal/external-static-libraries/external-static-libraries.qbs b/tests/auto/blackbox/testdata-baremetal/external-static-libraries/external-static-libraries.qbs
index 6fbbb8647..fffb6a03d 100644
--- a/tests/auto/blackbox/testdata-baremetal/external-static-libraries/external-static-libraries.qbs
+++ b/tests/auto/blackbox/testdata-baremetal/external-static-libraries/external-static-libraries.qbs
@@ -2,20 +2,6 @@ import "../BareMetalApplication.qbs" as BareMetalApplication
import "../BareMetalStaticLibrary.qbs" as BareMetalStaticLibrary
Project {
- condition: {
- // The KEIL C51/C251/C166 toolchains support only a
- // full paths to the external libraries.
- if (qbs.toolchainType === "keil") {
- if (qbs.architecture === "mcs51"
- || qbs.architecture === "mcs251"
- || qbs.architecture === "c166") {
- console.info("unsupported toolset: %%"
- + qbs.toolchainType + "%%, %%" + qbs.architecture + "%%");
- return false;
- }
- }
- return true;
- }
property string outputLibrariesDirectory: sourceDirectory + "/libs"
BareMetalStaticLibrary {
name: "lib-a"
diff --git a/tests/auto/blackbox/testdata-baremetal/generate-compiler-listing/fun.c b/tests/auto/blackbox/testdata-baremetal/generate-compiler-listing/fun.c
deleted file mode 100644
index 3b8c8f2f4..000000000
--- a/tests/auto/blackbox/testdata-baremetal/generate-compiler-listing/fun.c
+++ /dev/null
@@ -1,4 +0,0 @@
-int f(void)
-{
- return 0;
-}
diff --git a/tests/auto/blackbox/testdata-baremetal/generate-compiler-listing/main.c b/tests/auto/blackbox/testdata-baremetal/generate-compiler-listing/main.c
deleted file mode 100644
index 2c3d7726c..000000000
--- a/tests/auto/blackbox/testdata-baremetal/generate-compiler-listing/main.c
+++ /dev/null
@@ -1,6 +0,0 @@
-extern int f(void);
-
-int main(void)
-{
- return f();
-}
diff --git a/tests/auto/blackbox/testdata-baremetal/linker-map/linker-map.qbs b/tests/auto/blackbox/testdata-baremetal/linker-map/linker-map.qbs
index 676221e11..fe93ac144 100644
--- a/tests/auto/blackbox/testdata-baremetal/linker-map/linker-map.qbs
+++ b/tests/auto/blackbox/testdata-baremetal/linker-map/linker-map.qbs
@@ -1,10 +1,8 @@
import "../BareMetalApplication.qbs" as BareMetalApplication
BareMetalApplication {
- condition: {
- console.info("current toolset: %%"
- + qbs.toolchainType + "%%, %%" + qbs.architecture + "%%");
- return true;
+ property bool dummy: {
+ console.info("linker map suffix: %%" + cpp.linkerMapSuffix + "%%");
}
files: ["main.c"]
}
diff --git a/tests/auto/blackbox/testdata-windows/codesign/app.cpp b/tests/auto/blackbox/testdata-windows/codesign/app.cpp
new file mode 100644
index 000000000..76e819701
--- /dev/null
+++ b/tests/auto/blackbox/testdata-windows/codesign/app.cpp
@@ -0,0 +1 @@
+int main() { return 0; }
diff --git a/tests/auto/blackbox/testdata-windows/codesign/codesign.qbs b/tests/auto/blackbox/testdata-windows/codesign/codesign.qbs
new file mode 100644
index 000000000..2b48c67ff
--- /dev/null
+++ b/tests/auto/blackbox/testdata-windows/codesign/codesign.qbs
@@ -0,0 +1,37 @@
+Project {
+ name: "p"
+
+ property bool enableSigning: true
+ property string hashAlgorithm
+ property string subjectName
+ property string signingTimestamp
+
+ CppApplication {
+ name: "A"
+ files: "app.cpp"
+ codesign.enableCodeSigning: project.enableSigning
+ codesign.hashAlgorithm: project.hashAlgorithm
+ codesign.subjectName: project.subjectName
+ codesign.signingTimestamp: project.signingTimestamp
+ install: true
+ installDir: ""
+ property bool dummy: {
+ console.info("signtool path: %%" + codesign.codesignPath + "%%");
+ }
+ }
+
+ DynamicLibrary {
+ Depends { name: "cpp" }
+ name: "B"
+ files: "app.cpp"
+ codesign.enableCodeSigning: project.enableSigning
+ codesign.hashAlgorithm: project.hashAlgorithm
+ codesign.subjectName: project.subjectName
+ codesign.signingTimestamp: project.signingTimestamp
+ install: true
+ installDir: ""
+ property bool dummy: {
+ console.info("signtool path: %%" + codesign.codesignPath + "%%");
+ }
+ }
+}
diff --git a/tests/auto/blackbox/tst_blackboxbaremetal.cpp b/tests/auto/blackbox/tst_blackboxbaremetal.cpp
index a5feedd48..e0a068bc6 100644
--- a/tests/auto/blackbox/tst_blackboxbaremetal.cpp
+++ b/tests/auto/blackbox/tst_blackboxbaremetal.cpp
@@ -59,6 +59,16 @@ static bool extractCompilerIncludePaths(const QByteArray &output, QStringList &c
return true;
}
+static bool extractQuitedValue(const QByteArray &output, QString &pattern)
+{
+ const QRegularExpression re("%%(.+)%%");
+ const QRegularExpressionMatch match = re.match(output);
+ if (!match.hasMatch())
+ return false;
+ pattern = match.captured(1);
+ return true;
+}
+
static QByteArray unsupportedToolsetMessage(const QByteArray &output)
{
QByteArray toolchain;
@@ -68,17 +78,6 @@ static QByteArray unsupportedToolsetMessage(const QByteArray &output)
+ "' for architecture '" + architecture + "'";
}
-static QString linkerMapFileExtension(const QByteArray &toolchain, const QByteArray &architecture)
-{
- if (toolchain == "keil") {
- if (architecture == "mcs51")
- return QStringLiteral(".m51");
- if (architecture == "c166")
- return QStringLiteral(".m66");
- }
- return QStringLiteral(".map");
-}
-
TestBlackboxBareMetal::TestBlackboxBareMetal()
: TestBlackboxBase (SRCDIR "/testdata-baremetal", "blackbox-baremetal")
{
@@ -187,61 +186,84 @@ void TestBlackboxBareMetal::defines()
void TestBlackboxBareMetal::compilerListingFiles_data()
{
- QTest::addColumn<QString>("testPath");
QTest::addColumn<bool>("generateListing");
- QTest::newRow("do-not-generate-compiler-listing") << "/do-not-generate-compiler-listing" << false;
- QTest::newRow("generate-compiler-listing") << "/generate-compiler-listing" << true;
+ QTest::addColumn<QString>("customListingSuffix");
+ QTest::newRow("do-not-generate-compiler-listing") << false << "";
+ QTest::newRow("generate-default-compiler-listing") << true << "";
+ QTest::newRow("generate-custom-compiler-listing") << true << ".lll";
}
void TestBlackboxBareMetal::compilerListingFiles()
{
- QFETCH(QString, testPath);
QFETCH(bool, generateListing);
- QDir::setCurrent(testDataDir + testPath);
- QCOMPARE(runQbs(QbsRunParameters("resolve", QStringList("-n"))), 0);
+ QFETCH(QString, customListingSuffix);
+ QDir::setCurrent(testDataDir + "/compiler-listing");
+
+ rmDirR(relativeBuildDir());
+ QStringList args = {QStringLiteral("modules.cpp.generateCompilerListingFiles:%1")
+ .arg(generateListing ? "true" : "false")};
+ if (!customListingSuffix.isEmpty())
+ args << QStringLiteral("modules.cpp.compilerListingSuffix:%1").arg(customListingSuffix);
+
+ QCOMPARE(runQbs(QbsRunParameters("resolve", args)), 0);
if (m_qbsStdout.contains("unsupported toolset:"))
QSKIP(unsupportedToolsetMessage(m_qbsStdout));
- QCOMPARE(runQbs(), 0);
- const bool isShortListingNames = m_qbsStdout.contains("using short listing file names");
- const QString productName = testPath.mid(1);
- const QString productBuildDir = relativeProductBuildDir(productName);
+ if (!m_qbsStdout.contains("compiler listing suffix:"))
+ QFAIL("No current compiler listing suffix pattern exists");
+
+ QString compilerListingSuffix;
+ if (!extractQuitedValue(m_qbsStdout, compilerListingSuffix))
+ QFAIL("Unable to extract current compiler listing suffix");
+
+ if (!customListingSuffix.isEmpty())
+ QCOMPARE(compilerListingSuffix, customListingSuffix);
+
+ QCOMPARE(runQbs(QbsRunParameters(args)), 0);
+ const QString productBuildDir = relativeProductBuildDir("compiler-listing");
const QString hash = inputDirHash(".");
- const QString mainListing = productBuildDir + "/" + hash + (isShortListingNames ? "/main.lst" : "/main.c.lst");
+ const QString mainListing = productBuildDir + "/" + hash
+ + "/main.c" + compilerListingSuffix;
QCOMPARE(regularFileExists(mainListing), generateListing);
- const QString funListing = productBuildDir + "/" + hash + (isShortListingNames ? "/fun.lst" : "/fun.c.lst");
+ const QString funListing = productBuildDir + "/" + hash
+ + "/fun.c" + compilerListingSuffix;
QCOMPARE(regularFileExists(funListing), generateListing);
}
void TestBlackboxBareMetal::linkerMapFile_data()
{
QTest::addColumn<bool>("generateMap");
- QTest::newRow("do-not-generate-linker-map") << false;
- QTest::newRow("generate-linker-map") << true;
+ QTest::addColumn<QString>("customMapSuffix");
+ QTest::newRow("do-not-generate-linker-map") << false << "";
+ QTest::newRow("generate-default-linker-map") << true << "";
+ QTest::newRow("generate-custom-linker-map") << true << ".mmm";
}
void TestBlackboxBareMetal::linkerMapFile()
{
QFETCH(bool, generateMap);
+ QFETCH(QString, customMapSuffix);
QDir::setCurrent(testDataDir + "/linker-map");
rmDirR(relativeBuildDir());
- const QStringList args = {QStringLiteral("modules.cpp.generateLinkerMapFile:%1")
- .arg(generateMap ? "true" : "false")};
+ QStringList args = {QStringLiteral("modules.cpp.generateLinkerMapFile:%1")
+ .arg(generateMap ? "true" : "false")};
+ if (!customMapSuffix.isEmpty())
+ args << QStringLiteral("modules.cpp.linkerMapSuffix:%1").arg(customMapSuffix);
+
QCOMPARE(runQbs(QbsRunParameters("resolve", args)), 0);
- if (m_qbsStdout.contains("unsupported toolset:"))
- QSKIP(unsupportedToolsetMessage(m_qbsStdout));
- if (!m_qbsStdout.contains("current toolset:"))
- QFAIL("No current toolset pattern exists");
+ if (!m_qbsStdout.contains("linker map suffix:"))
+ QFAIL("No current linker map suffix pattern exists");
- QByteArray toolchain;
- QByteArray architecture;
- if (!extractToolset(m_qbsStdout, toolchain, architecture))
- QFAIL("Unable to extract current toolset");
+ QString linkerMapSuffix;
+ if (!extractQuitedValue(m_qbsStdout, linkerMapSuffix))
+ QFAIL("Unable to extract current linker map suffix");
+
+ if (!customMapSuffix.isEmpty())
+ QCOMPARE(linkerMapSuffix, customMapSuffix);
QCOMPARE(runQbs(QbsRunParameters(args)), 0);
const QString productBuildDir = relativeProductBuildDir("linker-map");
- const auto extension = linkerMapFileExtension(toolchain, architecture);
- const QString linkerMap = productBuildDir + "/linker-map" + extension;
+ const QString linkerMap = productBuildDir + "/linker-map" + linkerMapSuffix;
QCOMPARE(regularFileExists(linkerMap), generateMap);
}
diff --git a/tests/auto/blackbox/tst_blackboxwindows.cpp b/tests/auto/blackbox/tst_blackboxwindows.cpp
new file mode 100644
index 000000000..0c82754fb
--- /dev/null
+++ b/tests/auto/blackbox/tst_blackboxwindows.cpp
@@ -0,0 +1,174 @@
+/****************************************************************************
+**
+** Copyright (C) 2021 Denis Shienkov <denis.shienkov@gmail.com>
+** Contact: https://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_blackboxwindows.h"
+
+#include "../shared.h"
+
+#include <tools/hostosinfo.h>
+
+#include <QtCore/qdir.h>
+#include <QtCore/qregularexpression.h>
+
+using qbs::Internal::HostOsInfo;
+
+struct SigntoolInfo
+{
+ enum class CodeSignResult { Failed = 0, Signed, Unsigned };
+ CodeSignResult result = CodeSignResult::Failed;
+ bool timestamped = false;
+ QString hashAlgorithm;
+ QString subjectName;
+};
+
+Q_DECLARE_METATYPE(SigntoolInfo::CodeSignResult)
+
+static SigntoolInfo extractSigntoolInfo(const QString &signtoolPath, const QString &appPath)
+{
+ QProcess signtool;
+ signtool.start(signtoolPath, { QStringLiteral("verify"), QStringLiteral("/v"), appPath });
+ if (!signtool.waitForStarted() || !signtool.waitForFinished())
+ return {};
+ const auto output = signtool.readAllStandardError();
+ SigntoolInfo signtoolInfo;
+ if (output.contains("No signature found")) {
+ signtoolInfo.result = SigntoolInfo::CodeSignResult::Unsigned;
+ } else {
+ signtoolInfo.result = SigntoolInfo::CodeSignResult::Signed;
+ const auto output = signtool.readAllStandardOutput();
+ const auto lines = output.split('\n');
+ for (const auto &line: lines) {
+ {
+ const QRegularExpression re("^Hash of file \\((.+)\\):.+$");
+ const QRegularExpressionMatch match = re.match(line);
+ if (match.hasMatch()) {
+ signtoolInfo.hashAlgorithm = match.captured(1).toLocal8Bit();
+ continue;
+ }
+ }
+ {
+ const QRegularExpression re("Issued to: (.+)");
+ const QRegularExpressionMatch match = re.match(line);
+ if (match.hasMatch()) {
+ signtoolInfo.subjectName = match.captured(1).toLocal8Bit().trimmed();
+ continue;
+ }
+ }
+ if (line.startsWith("The signature is timestamped:")) {
+ signtoolInfo.timestamped = true;
+ break;
+ } else if (line.startsWith("File is not timestamped.")) {
+ break;
+ }
+ }
+ }
+ return signtoolInfo;
+}
+
+static QString extractSigntoolPath(const QByteArray &output)
+{
+ const QRegularExpression re("%%(.+)%%");
+ QRegularExpressionMatchIterator it = re.globalMatch(output);
+ if (!it.hasNext())
+ return {};
+ const QRegularExpressionMatch match = it.next();
+ return match.captured(1).toUtf8();
+}
+
+TestBlackboxWindows::TestBlackboxWindows()
+ : TestBlackboxBase (SRCDIR "/testdata-windows", "blackbox-windows")
+{
+}
+
+void TestBlackboxWindows::initTestCase()
+{
+ if (!HostOsInfo::isWindowsHost()) {
+ QSKIP("only applies on Windows");
+ return;
+ }
+
+ TestBlackboxBase::initTestCase();
+}
+
+void TestBlackboxWindows::standaloneCodesign()
+{
+ QFETCH(SigntoolInfo::CodeSignResult, result);
+ QFETCH(QString, hashAlgorithm);
+ QFETCH(QString, subjectName);
+ QFETCH(QString, signingTimestamp);
+
+ QDir::setCurrent(testDataDir + "/codesign");
+ QbsRunParameters params(QStringList{"qbs.installPrefix:''"});
+ params.arguments << QStringLiteral("project.enableSigning:%1").arg(
+ (result == SigntoolInfo::CodeSignResult::Signed) ? "true" : "false")
+ << QStringLiteral("project.hashAlgorithm:%1").arg(hashAlgorithm)
+ << QStringLiteral("project.subjectName:%1").arg(subjectName)
+ << QStringLiteral("project.signingTimestamp:%1").arg(signingTimestamp);
+
+ rmDirR(relativeBuildDir());
+ QCOMPARE(runQbs(params), 0);
+
+ if (!m_qbsStdout.contains("signtool path:"))
+ QFAIL("No current signtool path pattern exists");
+
+ const auto signtoolPath = extractSigntoolPath(m_qbsStdout);
+ QVERIFY(QFileInfo(signtoolPath).exists());
+
+ const QStringList outputBinaries = {"A.exe", "B.dll"};
+ for (const auto &outputBinary : outputBinaries) {
+ const auto outputBinaryPath = defaultInstallRoot + "/" + outputBinary;
+ QVERIFY(QFileInfo(outputBinaryPath).exists());
+
+ const SigntoolInfo signtoolInfo = extractSigntoolInfo(signtoolPath, outputBinaryPath);
+ QVERIFY(signtoolInfo.result != SigntoolInfo::CodeSignResult::Failed);
+ QCOMPARE(signtoolInfo.result, result);
+ QCOMPARE(signtoolInfo.hashAlgorithm, hashAlgorithm);
+ QCOMPARE(signtoolInfo.subjectName, subjectName);
+ QCOMPARE(signtoolInfo.timestamped, !signingTimestamp.isEmpty());
+ }
+}
+
+void TestBlackboxWindows::standaloneCodesign_data()
+{
+ QTest::addColumn<SigntoolInfo::CodeSignResult>("result");
+ QTest::addColumn<QString>("hashAlgorithm");
+ QTest::addColumn<QString>("subjectName");
+ QTest::addColumn<QString>("signingTimestamp");
+
+ QTest::newRow("standalone, unsigned")
+ << SigntoolInfo::CodeSignResult::Unsigned << "" << "" << "";
+ QTest::newRow("standalone, signed, sha1, qbs@community.test, no timestamp")
+ << SigntoolInfo::CodeSignResult::Signed << "sha1" << "qbs@community.test" << "";
+ QTest::newRow("standalone, signed, sha256, qbs@community.test, RFC3061 timestamp")
+ << SigntoolInfo::CodeSignResult::Signed << "sha256" << "qbs@community.test"
+ << "http://timestamp.digicert.com";
+}
+
+QTEST_MAIN(TestBlackboxWindows)
diff --git a/tests/auto/blackbox/tst_blackboxwindows.h b/tests/auto/blackbox/tst_blackboxwindows.h
new file mode 100644
index 000000000..fbc597313
--- /dev/null
+++ b/tests/auto/blackbox/tst_blackboxwindows.h
@@ -0,0 +1,51 @@
+/****************************************************************************
+**
+** Copyright (C) 2021 Denis Shienkov <denis.shienkov@gmail.com>
+** Contact: https://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.
+**
+****************************************************************************/
+
+#ifndef TST_BLACKBOXWINDOWS_H
+#define TST_BLACKBOXWINDOWS_H
+
+#include "tst_blackboxbase.h"
+
+class TestBlackboxWindows : public TestBlackboxBase
+{
+ Q_OBJECT
+
+public:
+ TestBlackboxWindows();
+
+public slots:
+ void initTestCase() override;
+
+private slots:
+ void standaloneCodesign();
+ void standaloneCodesign_data();
+};
+
+#endif // TST_BLACKBOXWINDOWS_H
diff --git a/tests/auto/tools/tst_tools.cpp b/tests/auto/tools/tst_tools.cpp
index edf5a1308..92e0978b5 100644
--- a/tests/auto/tools/tst_tools.cpp
+++ b/tests/auto/tools/tst_tools.cpp
@@ -673,6 +673,30 @@ void TestTools::set_containsSet()
QVERIFY(set3.contains(set4));
}
+void TestTools::set_find()
+{
+ Set<QString> set1;
+
+ for (int i = 0; i < 500; ++i) {
+ QVERIFY(set1.find(QString::number(i)) == set1.end());
+ set1.insert(QString::number(i));
+ const auto it = set1.find(QString::number(i));
+ QVERIFY(it != set1.end());
+ QVERIFY(*it == QString::number(i));
+ }
+
+ QCOMPARE(set1.size(), size_t { 500 });
+
+ for (int j = 0; j < 500; ++j) {
+ int i = (j * 17) % 500;
+ const auto it = set1.find(QString::number(i));
+ QVERIFY(it != set1.end());
+ QVERIFY(*it == QString::number(i));
+ set1.remove(QString::number(i));
+ QVERIFY(set1.find(QString::number(i)) == set1.end());
+ }
+}
+
void TestTools::set_begin()
{
Set<int> set1;
diff --git a/tests/auto/tools/tst_tools.h b/tests/auto/tools/tst_tools.h
index bd8538be2..d1ba0a57b 100644
--- a/tests/auto/tools/tst_tools.h
+++ b/tests/auto/tools/tst_tools.h
@@ -79,6 +79,7 @@ private slots:
void set_remove();
void set_contains();
void set_containsSet();
+ void set_find();
void set_begin();
void set_end();
void set_insert();