QTestLib: Add helper function to check for keychain access issues

To be used in network-related tests where we potentially are
using private/public keys and (on macOS) end-up with keychain
access blocking a test with dialogs requesting a permission
to access the keychain.

Task-number: QTBUG-132645
Pick-to: 6.9 6.8
Change-Id: Ide74633bf88b0453d5d8f8de56282c8cf8207380
Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io>
This commit is contained in:
Timur Pocheptsov 2025-01-08 13:24:59 +01:00 committed by Tor Arne Vestbø
parent e4fbbdea05
commit 13109ba350
6 changed files with 51 additions and 56 deletions

View File

@ -30,6 +30,14 @@
#include <QtWidgets/QWidget>
#endif
#ifdef QT_NETWORK_LIB
#if QT_CONFIG(ssl)
#include <QtCore/qoperatingsystemversion.h>
#include <QtCore/qsystemdetection.h>
#include <QtNetwork/qsslsocket.h>
#endif // QT_CONFIG(ssl)
#endif // QT_NETWORK_LIB
QT_BEGIN_NAMESPACE
namespace QTestPrivate {
@ -83,6 +91,31 @@ static inline void androidCompatibleShow(QWidget *widget)
}
#endif // QT_WIDGETS_LIB
#ifdef QT_NETWORK_LIB
inline bool isSecureTransportBlockingTest()
{
#ifdef Q_OS_MACOS
#if QT_CONFIG(ssl)
if (QSslSocket::activeBackend() == QLatin1String("securetransport")) {
#if QT_MACOS_IOS_PLATFORM_SDK_EQUAL_OR_ABOVE(150000, 180000)
// Starting from macOS 15 our temporary keychain is ignored.
// We have to use kSecImportToMemoryOnly/kCFBooleanTrue key/value
// instead. This way we don't have to use QT_SSL_USE_TEMPORARY_KEYCHAIN anymore.
return false;
#else
if (QOperatingSystemVersion::current() >= QOperatingSystemVersion::MacOSSequoia) {
// We were built with SDK below 15, and running on/above 15, but file-based
// keychains are not working anymore on macOS 15, blocking the test execution.
return true;
}
#endif // Platform SDK.
}
#endif // QT_CONFIG(ssl)
#endif // Q_OS_MACOS
return false;
}
#endif // QT_NETWORK_LIB
} // namespace QTestPrivate
QT_END_NAMESPACE

View File

@ -1,41 +0,0 @@
// Copyright (C) 2024 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#include <QtNetwork/qtnetworkglobal.h>
#include <QtCore/qoperatingsystemversion.h>
#include <QtCore/qsystemdetection.h>
#if QT_CONFIG(ssl)
#include <QtNetwork/qsslsocket.h>
#endif
namespace QtNetworkTestHelpers
{
bool isSecureTransportBlockingTest()
{
#ifdef Q_OS_MACOS
#if QT_CONFIG(ssl)
if (QSslSocket::activeBackend() == QLatin1String("securetransport")) {
#if QT_MACOS_IOS_PLATFORM_SDK_EQUAL_OR_ABOVE(150000, 180000)
// Starting from macOS 15 our temporary keychain is ignored.
// We have to use kSecImportToMemoryOnly/kCFBooleanTrue key/value
// instead. This way we don't have to use QT_SSL_USE_TEMPORARY_KEYCHAIN anymore.
return false;
#else
if (QOperatingSystemVersion::current() >= QOperatingSystemVersion::MacOSSequoia) {
// We were built with SDK below 15, and running on/above 15, but file-based
// keychains are not working anymore on macOS 15, blocking the test execution.
return true;
}
#endif // Platform SDK.
}
#endif // QT_CONFIG(ssl)
#endif // Q_OS_MACOS
return false;
}
}

View File

@ -27,6 +27,7 @@ qt_internal_add_test(tst_qnetworkreply
LIBRARIES
Qt::CorePrivate
Qt::NetworkPrivate
Qt::TestPrivate
TESTDATA ${test_data}
QT_TEST_SERVER_LIST "vsftpd" "apache2" "ftp-proxy" "danted" "squid"
BUNDLE_ANDROID_OPENSSL_LIBS

View File

@ -84,7 +84,8 @@ Q_DECLARE_METATYPE(QSharedPointer<char>)
#include <time.h>
#include "../../../network-settings.h"
#include "../../../network-helpers.h"
#include <QtTest/private/qtesthelpers_p.h>
#ifdef Q_OS_INTEGRITY
#include "qplatformdefs.h"
@ -5617,7 +5618,7 @@ void tst_QNetworkReply::ioPostToHttpsUploadProgress()
{
//QFile sourceFile(testDataDir + "/bigfile");
//QVERIFY(sourceFile.open(QIODevice::ReadOnly));
if (QtNetworkTestHelpers::isSecureTransportBlockingTest())
if (QTestPrivate::isSecureTransportBlockingTest())
QSKIP("SecureTransport: temporary keychain is not working on this version of macOS");
qint64 wantedSize = 2*1024*1024; // 2 MB
@ -5697,7 +5698,7 @@ void tst_QNetworkReply::ioGetFromBuiltinHttp()
QFETCH(bool, https);
QFETCH(int, bufferSize);
if (https && QtNetworkTestHelpers::isSecureTransportBlockingTest())
if (https && QTestPrivate::isSecureTransportBlockingTest())
QSKIP("SecureTransport: temporary keychain is not working on this version of macOS");
QByteArray testData;
@ -6461,7 +6462,7 @@ void tst_QNetworkReply::httpProxyCommands_data()
<< QByteArray("HTTP/1.0 200 OK\r\nProxy-Connection: close\r\nContent-Length: 1\r\n\r\n1")
<< "GET http://0.0.0.0:4443/http-request HTTP/1.";
#if QT_CONFIG(ssl)
if (QtNetworkTestHelpers::isSecureTransportBlockingTest())
if (QTestPrivate::isSecureTransportBlockingTest())
QSKIP("SecureTransport: temporary keychain is not working on this version of macOS");
QTest::newRow("https")
@ -6690,7 +6691,7 @@ void tst_QNetworkReply::httpConnectionCount_data()
QTest::addRow("http/1.1") << false << false;
QTest::addRow("http/2") << true << false;
#if QT_CONFIG(ssl)
if (!QtNetworkTestHelpers::isSecureTransportBlockingTest()) {
if (!QTestPrivate::isSecureTransportBlockingTest()) {
QTest::addRow("https/1.1") << false << true;
QTest::addRow("https/2") << true << true;
}
@ -7051,7 +7052,7 @@ void tst_QNetworkReply::encrypted()
void tst_QNetworkReply::abortOnEncrypted()
{
if (QtNetworkTestHelpers::isSecureTransportBlockingTest())
if (QTestPrivate::isSecureTransportBlockingTest())
QSKIP("SecureTransport: temporary keychain is not working on this version of macOS");
SslServer server;
@ -9149,7 +9150,7 @@ void tst_QNetworkReply::ioHttpRedirectErrors()
QFETCH(QNetworkReply::NetworkError, error);
QUrl localhost(url);
if (localhost.scheme() == QLatin1String("https") && QtNetworkTestHelpers::isSecureTransportBlockingTest())
if (localhost.scheme() == QLatin1String("https") && QTestPrivate::isSecureTransportBlockingTest())
QSKIP("SecureTransport: temporary keychain is not working on this version of macOS");
MiniHttpServer server("", localhost.scheme() == QLatin1String("https"));
@ -9228,7 +9229,7 @@ void tst_QNetworkReply::ioHttpRedirectPolicy()
QFETCH(const QNetworkRequest::RedirectPolicy, policy);
QFETCH(const bool, ssl);
if (ssl && QtNetworkTestHelpers::isSecureTransportBlockingTest())
if (ssl && QTestPrivate::isSecureTransportBlockingTest())
QSKIP("SecureTransport: temporary keychain is not working on this version of macOS");
QFETCH(const int, redirectCount);
@ -9312,7 +9313,7 @@ void tst_QNetworkReply::ioHttpRedirectPolicyErrors()
QVERIFY(policy != QNetworkRequest::ManualRedirectPolicy);
QFETCH(const bool, ssl);
if (ssl && QtNetworkTestHelpers::isSecureTransportBlockingTest())
if (ssl && QTestPrivate::isSecureTransportBlockingTest())
QSKIP("SecureTransport: temporary keychain is not working on this version of macOS");
QFETCH(const QString, location);
QFETCH(const int, maxRedirects);
@ -9899,7 +9900,7 @@ public slots:
void tst_QNetworkReply::putWithServerClosingConnectionImmediately()
{
if (QtNetworkTestHelpers::isSecureTransportBlockingTest())
if (QTestPrivate::isSecureTransportBlockingTest())
QSKIP("SecureTransport: temporary keychain is not working on this version of macOS");
const int numUploads = 40;

View File

@ -24,6 +24,7 @@ qt_internal_add_test(tst_qsslserver
LIBRARIES
Qt::CorePrivate
Qt::NetworkPrivate
Qt::TestPrivate
TESTDATA ${test_data}
BUNDLE_ANDROID_OPENSSL_LIBS
)

View File

@ -10,7 +10,7 @@
#include <QtNetwork/QSslKey>
#include "private/qtlsbackend_p.h"
#include "../../../network-helpers.h"
#include <QtTest/private/qtesthelpers_p.h>
class tst_QSslServer : public QObject
{
@ -127,7 +127,7 @@ QSslConfiguration tst_QSslServer::createQSslConfiguration(QString keyFileName,
void tst_QSslServer::testOneSuccessfulConnection()
{
if (QtNetworkTestHelpers::isSecureTransportBlockingTest())
if (QTestPrivate::isSecureTransportBlockingTest())
QSKIP("SecureTransport will block this test while requesting keychain access");
// Setup server
QSslConfiguration serverConfiguration = selfSignedServerQSslConfiguration();
@ -208,7 +208,7 @@ void tst_QSslServer::testOneSuccessfulConnection()
void tst_QSslServer::testSelfSignedCertificateRejectedByServer()
{
if (QtNetworkTestHelpers::isSecureTransportBlockingTest())
if (QTestPrivate::isSecureTransportBlockingTest())
QSKIP("SecureTransport will block this test while requesting keychain access");
// Set up server that verifies client
QSslConfiguration serverConfiguration = selfSignedServerQSslConfiguration();
@ -263,7 +263,7 @@ void tst_QSslServer::testSelfSignedCertificateRejectedByServer()
void tst_QSslServer::testSelfSignedCertificateRejectedByClient()
{
if (QtNetworkTestHelpers::isSecureTransportBlockingTest())
if (QTestPrivate::isSecureTransportBlockingTest())
QSKIP("SecureTransport will block this test while requesting keychain access");
// Set up server without verification of client
QSslConfiguration serverConfiguration = selfSignedServerQSslConfiguration();
@ -498,7 +498,7 @@ void tst_QSslServer::quietClient()
void tst_QSslServer::twoGoodAndManyBadClients()
{
if (QtNetworkTestHelpers::isSecureTransportBlockingTest())
if (QTestPrivate::isSecureTransportBlockingTest())
QSKIP("SecureTransport will block this test while requesting keychain access");
QSslConfiguration serverConfiguration = selfSignedServerQSslConfiguration();