From 198225983df9f402bb368b449f1abeea95ff0dce Mon Sep 17 00:00:00 2001 From: Gabriel de Dietrich Date: Wed, 11 Oct 2017 18:42:32 -0700 Subject: QShortcut: Fall back to cross platform code in absence of QPA menu MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit On macOS, absence of a QPA menu means that we should be using our own internal logic since there's no entity on the QCocoaMenuDelegate to take care of the shortcuts. Change-Id: I35ed8f0b55445f61d0528709d4debb636a502002 Task-number: QTBUG-61039 Reviewed-by: Tor Arne Vestbø Reviewed-by: Shawn Rutledge --- tests/auto/widgets/widgets/qmenu/tst_qmenu.cpp | 28 ++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) (limited to 'tests') diff --git a/tests/auto/widgets/widgets/qmenu/tst_qmenu.cpp b/tests/auto/widgets/widgets/qmenu/tst_qmenu.cpp index f0fb7bc367..ad30db501a 100644 --- a/tests/auto/widgets/widgets/qmenu/tst_qmenu.cpp +++ b/tests/auto/widgets/widgets/qmenu/tst_qmenu.cpp @@ -133,6 +133,7 @@ private slots: void menuSize_Scrolling_data(); void menuSize_Scrolling(); void tearOffMenuNotDisplayed(); + void QTBUG_61039_menu_shortcuts(); protected slots: void onActivated(QAction*); @@ -1609,5 +1610,32 @@ void tst_QMenu::tearOffMenuNotDisplayed() QVERIFY(!torn->isVisible()); } +void tst_QMenu::QTBUG_61039_menu_shortcuts() +{ + QAction *actionKamen = new QAction("Action Kamen"); + actionKamen->setShortcut(QKeySequence(QLatin1String("K"))); + + QAction *actionJoe = new QAction("Action Joe"); + actionJoe->setShortcut(QKeySequence(QLatin1String("Ctrl+J"))); + + QMenu menu; + menu.addAction(actionKamen); + menu.addAction(actionJoe); + QVERIFY(!menu.platformMenu()); + + QWidget widget; + widget.addAction(menu.menuAction()); + widget.show(); + QVERIFY(QTest::qWaitForWindowActive(&widget)); + + QSignalSpy actionKamenSpy(actionKamen, &QAction::triggered); + QTest::keyClick(&widget, Qt::Key_K); + QTRY_COMPARE(actionKamenSpy.count(), 1); + + QSignalSpy actionJoeSpy(actionJoe, &QAction::triggered); + QTest::keyClick(&widget, Qt::Key_J, Qt::ControlModifier); + QTRY_COMPARE(actionJoeSpy.count(), 1); +} + QTEST_MAIN(tst_QMenu) #include "tst_qmenu.moc" -- cgit v1.2.3 From b16add0dc6db16b20f730b763ffa080f953b52e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A5rten=20Nordheim?= Date: Fri, 13 Oct 2017 14:38:49 +0200 Subject: QNetworkReply: Reduce noise and a fail when building with no-ssl A few tests would QSKIP depending on the inclusion of SSL, producing multiple lines of noise in the output. And one test used https in one of its configurations without checking to see if it could, causing an UnknownProtocolError. Change-Id: I5f54bf1005f962cc027c099b816fbe245dc43d3f Reviewed-by: Timur Pocheptsov Reviewed-by: Edward Welbourne --- .../access/qnetworkreply/tst_qnetworkreply.cpp | 39 ++++++++++------------ 1 file changed, 17 insertions(+), 22 deletions(-) (limited to 'tests') diff --git a/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp b/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp index 16f06b2d15..439f1cd618 100644 --- a/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp +++ b/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp @@ -8167,7 +8167,9 @@ void tst_QNetworkReply::ioHttpRedirectErrors_data() "location: http://localhost:%1\r\n\r\n"); QTest::newRow("too-many-redirects") << "http://localhost" << tempRedirectReply << QNetworkReply::TooManyRedirectsError; +#if QT_CONFIG(ssl) QTest::newRow("insecure-redirect") << "https://localhost" << tempRedirectReply << QNetworkReply::InsecureRedirectError; +#endif QTest::newRow("unknown-redirect") << "http://localhost"<< tempRedirectReply.replace("http", "bad_protocol") << QNetworkReply::ProtocolUnknownError; } @@ -8178,7 +8180,7 @@ void tst_QNetworkReply::ioHttpRedirectErrors() QFETCH(QNetworkReply::NetworkError, error); QUrl localhost(url); - MiniHttpServer server("", localhost.scheme() == "https"); + MiniHttpServer server("", localhost.scheme() == QLatin1String("https")); localhost.setPort(server.serverPort()); @@ -8228,11 +8230,13 @@ void tst_QNetworkReply::ioHttpRedirectPolicy_data() QTest::addColumn("statusCode"); QTest::newRow("manual-nossl") << QNetworkRequest::ManualRedirectPolicy << false << 0 << 307; - QTest::newRow("manual-ssl") << QNetworkRequest::ManualRedirectPolicy << true << 0 << 307; QTest::newRow("nolesssafe-nossl") << QNetworkRequest::NoLessSafeRedirectPolicy << false << 1 << 200; - QTest::newRow("nolesssafe-ssl") << QNetworkRequest::NoLessSafeRedirectPolicy << true << 1 << 200; QTest::newRow("same-origin-nossl") << QNetworkRequest::SameOriginRedirectPolicy << false << 1 << 200; +#if QT_CONFIG(ssl) + QTest::newRow("manual-ssl") << QNetworkRequest::ManualRedirectPolicy << true << 0 << 307; + QTest::newRow("nolesssafe-ssl") << QNetworkRequest::NoLessSafeRedirectPolicy << true << 1 << 200; QTest::newRow("same-origin-ssl") << QNetworkRequest::SameOriginRedirectPolicy << true << 1 << 200; +#endif } void tst_QNetworkReply::ioHttpRedirectPolicy() @@ -8240,10 +8244,6 @@ void tst_QNetworkReply::ioHttpRedirectPolicy() QFETCH(const QNetworkRequest::RedirectPolicy, policy); QFETCH(const bool, ssl); -#ifdef QT_NO_SSL - if (ssl) - QSKIP("SSL is not supported"); -#endif QFETCH(const int, redirectCount); QFETCH(const int, statusCode); @@ -8251,11 +8251,7 @@ void tst_QNetworkReply::ioHttpRedirectPolicy() // Setup HTTP server. SameOriginRedirector redirectServer("", ssl); - QUrl url(QLatin1String( -#ifndef QT_NO_SSL - ssl ? "https://localhost" : -#endif - "http://localhost")); + QUrl url(QLatin1String(ssl ? "https://localhost" : "http://localhost")); url.setPort(redirectServer.serverPort()); redirectServer.responses.push_back(httpEmpty200Response); @@ -8291,27 +8287,35 @@ void tst_QNetworkReply::ioHttpRedirectPolicyErrors_data() // 1. NoLessSafeRedirectsPolicy QTest::newRow("nolesssafe-nossl-nossl-too-many") << QNetworkRequest::NoLessSafeRedirectPolicy << false << QString("http://localhost:%1") << 0 << QNetworkReply::TooManyRedirectsError; +#if QT_CONFIG(ssl) QTest::newRow("nolesssafe-ssl-ssl-too-many") << QNetworkRequest::NoLessSafeRedirectPolicy << true << QString("https:/localhost:%1") << 0 << QNetworkReply::TooManyRedirectsError; QTest::newRow("nolesssafe-ssl-nossl-insecure-redirect") << QNetworkRequest::NoLessSafeRedirectPolicy << true << QString("http://localhost:%1") << 50 << QNetworkReply::InsecureRedirectError; +#endif // 2. SameOriginRedirectsPolicy QTest::newRow("same-origin-nossl-nossl-too-many") << QNetworkRequest::SameOriginRedirectPolicy << false << QString("http://localhost:%1") << 0 << QNetworkReply::TooManyRedirectsError; +#if QT_CONFIG(ssl) QTest::newRow("same-origin-ssl-ssl-too-many") << QNetworkRequest::SameOriginRedirectPolicy << true << QString("https://localhost:%1") << 0 << QNetworkReply::TooManyRedirectsError; QTest::newRow("same-origin-https-http-wrong-protocol") << QNetworkRequest::SameOriginRedirectPolicy << true << QString("http://localhost:%1") << 50 << QNetworkReply::InsecureRedirectError; +#endif QTest::newRow("same-origin-http-https-wrong-protocol") << QNetworkRequest::SameOriginRedirectPolicy << false << QString("https://localhost:%1") << 50 << QNetworkReply::InsecureRedirectError; QTest::newRow("same-origin-http-http-wrong-host") << QNetworkRequest::SameOriginRedirectPolicy << false << QString("http://not-so-localhost:%1") << 50 << QNetworkReply::InsecureRedirectError; +#if QT_CONFIG(ssl) QTest::newRow("same-origin-https-https-wrong-host") << QNetworkRequest::SameOriginRedirectPolicy << true << QString("https://not-so-localhost:%1") << 50 << QNetworkReply::InsecureRedirectError; +#endif QTest::newRow("same-origin-http-http-wrong-port") << QNetworkRequest::SameOriginRedirectPolicy << false << QString("http://localhost/%1") << 50 << QNetworkReply::InsecureRedirectError; +#if QT_CONFIG(ssl) QTest::newRow("same-origin-https-https-wrong-port") << QNetworkRequest::SameOriginRedirectPolicy << true << QString("https://localhost/%1") << 50 << QNetworkReply::InsecureRedirectError; +#endif } void tst_QNetworkReply::ioHttpRedirectPolicyErrors() @@ -8325,20 +8329,11 @@ void tst_QNetworkReply::ioHttpRedirectPolicyErrors() QFETCH(const int, maxRedirects); QFETCH(const QNetworkReply::NetworkError, expectedError); -#ifdef QT_NO_SSL - if (ssl || location.contains("https")) - QSKIP("SSL required to run this test"); -#endif - // Setup the server. MiniHttpServer server("", ssl); server.setDataToTransmit(tempRedirectReplyStr().arg(location.arg(server.serverPort())).toLatin1()); - QUrl url(QLatin1String( -#ifndef QT_NO_SSL - ssl ? "https://localhost" : -#endif - "http://localhost")); + QUrl url(QLatin1String(ssl ? "https://localhost" : "http://localhost")); url.setPort(server.serverPort()); QNetworkRequest request(url); -- cgit v1.2.3 From db333d6dba7703a67834a49e42e64c1e04b9ed3a Mon Sep 17 00:00:00 2001 From: Timur Pocheptsov Date: Mon, 16 Oct 2017 12:32:02 +0200 Subject: QNAM (redirects) - clear 'raw' headers before sending the next request MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We already cleared 'cookedHeaders', which is a QHash for 'known headers' (enumerators as keys instead of strings), now do the same for 'rawHeaders'- not to end up with some weird mix of headers from all possible redirect responses and the final response. Task-number: QTBUG-61300 Change-Id: Ifd6655c4167840bb00d29446d36ce65ba2d5491a Reviewed-by: Mårten Nordheim Reviewed-by: Edward Welbourne --- .../network/access/qnetworkreply/tst_qnetworkreply.cpp | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) (limited to 'tests') diff --git a/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp b/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp index 439f1cd618..97fe9e04bf 100644 --- a/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp +++ b/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp @@ -516,6 +516,17 @@ bool tst_QNetworkReply::seedCreated = false; QFAIL(qPrintable(errorMsg)); \ } while (0) +static bool validateRedirectedResponseHeaders(QNetworkReplyPtr reply) +{ + // QTBUG-61300: previously we were mixing 'raw' headers from all responses + // along the redirect chain. The simplest test is to check/verify we have + // no 'location' header anymore. + Q_ASSERT(reply.data()); + + return !reply->hasRawHeader("location") + && !reply->header(QNetworkRequest::LocationHeader).isValid(); +} + #ifndef QT_NO_SSL static void setupSslServer(QSslSocket* serverSocket) { @@ -8106,6 +8117,7 @@ void tst_QNetworkReply::ioHttpSingleRedirect() // Reply url is set to the redirect url QCOMPARE(reply->url(), redirectUrl); QCOMPARE(reply->error(), QNetworkReply::NoError); + QVERIFY(validateRedirectedResponseHeaders(reply)); } void tst_QNetworkReply::ioHttpChangeMaxRedirects() @@ -8154,6 +8166,7 @@ void tst_QNetworkReply::ioHttpChangeMaxRedirects() QCOMPARE(redSpy2.count(), 2); QCOMPARE(reply2->url(), server3Url); QCOMPARE(reply2->error(), QNetworkReply::NoError); + QVERIFY(validateRedirectedResponseHeaders(reply2)); } void tst_QNetworkReply::ioHttpRedirectErrors_data() @@ -8274,6 +8287,7 @@ void tst_QNetworkReply::ioHttpRedirectPolicy() QCOMPARE(finishedSpy.count(), 1); QCOMPARE(redirectSpy.count(), redirectCount); QCOMPARE(reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(), statusCode); + QVERIFY(validateRedirectedResponseHeaders(reply) || statusCode != 200); } void tst_QNetworkReply::ioHttpRedirectPolicyErrors_data() @@ -8406,6 +8420,7 @@ void tst_QNetworkReply::ioHttpUserVerifiedRedirect() waitForFinish(reply); QCOMPARE(finishedSpy.count(), 1); QCOMPARE(reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(), statusCode); + QVERIFY(validateRedirectedResponseHeaders(reply) || statusCode != 200); } void tst_QNetworkReply::ioHttpCookiesDuringRedirect() @@ -8433,6 +8448,7 @@ void tst_QNetworkReply::ioHttpCookiesDuringRedirect() QVERIFY(waitForFinish(reply) == Success); QVERIFY(target.receivedData.contains("\r\nCookie: hello=world\r\n")); + QVERIFY(validateRedirectedResponseHeaders(reply)); } void tst_QNetworkReply::ioHttpRedirect_data() @@ -8471,6 +8487,7 @@ void tst_QNetworkReply::ioHttpRedirect() QCOMPARE(waitForFinish(reply), int(Success)); QCOMPARE(reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(), 200); + QVERIFY(validateRedirectedResponseHeaders(reply)); } #ifndef QT_NO_SSL -- cgit v1.2.3 From 0aba5546ef69bddeb42c3dabe22e2856f0213b19 Mon Sep 17 00:00:00 2001 From: Gatis Paeglis Date: Thu, 7 Sep 2017 14:40:58 +0200 Subject: tests: fix and un-blacklist tst_qgraphicsview::hoverLeave MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Tests should not use QCursor to emulate mouse move, see QCursor::setPos() docs. The flakiness of the test on XCB is not surprising when the test queries geometry even before the window has been shown. With the re-factored version I could not reproduce flakiness anymore. Removed Q_OS_MAC and closed QTBUG-26274 as test passes on macOS from which I assume that the underlying issue has been fixed. Removed Q_OS_QNX ifdef as test does not rely on QCursor anymore. This patch also fixes the issues on minimal / offscreen platform plugins. QCursor::setPos() is evil for auto test purposes. Note: We intentionally use QTest::mouseMove(QWindow *window, ..), not the QWidget overload. The QWindow version gets routed through QWSI, which ensures that all necessary events are generated as expect. In QWidget code path this is currently disabled by QTEST_QPA_MOUSE_HANDLING. Change-Id: I285c26cff09e3f2750f8c2abbb1f46c8f7be984a Reviewed-by: Tor Arne Vestbø (cherry picked from commit 1af927976ac953f922e35d71a16a32d328bb2efd) Reviewed-by: Tony Sarajärvi Reviewed-by: Friedemann Kleint Reviewed-by: Liang Qi --- .../widgets/graphicsview/qgraphicsview/BLACKLIST | 2 - .../qgraphicsview/tst_qgraphicsview.cpp | 48 +++++++++------------- 2 files changed, 19 insertions(+), 31 deletions(-) (limited to 'tests') diff --git a/tests/auto/widgets/graphicsview/qgraphicsview/BLACKLIST b/tests/auto/widgets/graphicsview/qgraphicsview/BLACKLIST index 3cba8bad7e..40d106e3ba 100644 --- a/tests/auto/widgets/graphicsview/qgraphicsview/BLACKLIST +++ b/tests/auto/widgets/graphicsview/qgraphicsview/BLACKLIST @@ -12,7 +12,5 @@ xcb xcb [forwardMousePress] xcb -[hoverLeave] -xcb [resizeAnchor] xcb diff --git a/tests/auto/widgets/graphicsview/qgraphicsview/tst_qgraphicsview.cpp b/tests/auto/widgets/graphicsview/qgraphicsview/tst_qgraphicsview.cpp index 121836234d..5900c85627 100644 --- a/tests/auto/widgets/graphicsview/qgraphicsview/tst_qgraphicsview.cpp +++ b/tests/auto/widgets/graphicsview/qgraphicsview/tst_qgraphicsview.cpp @@ -4777,8 +4777,6 @@ class GraphicsItemWithHover : public QGraphicsRectItem { public: GraphicsItemWithHover() - : receivedEnterEvent(false), receivedLeaveEvent(false), - enterWidget(0), leaveWidget(0) { setRect(0, 0, 100, 100); setAcceptHoverEvents(true); @@ -4786,6 +4784,9 @@ public: bool sceneEvent(QEvent *event) { + if (!checkEvents) // ensures that we don't look at stray events before we are ready + return QGraphicsRectItem::sceneEvent(event); + if (event->type() == QEvent::GraphicsSceneHoverEnter) { receivedEnterEvent = true; enterWidget = static_cast(event)->widget(); @@ -4796,50 +4797,39 @@ public: return QGraphicsRectItem::sceneEvent(event); } - bool receivedEnterEvent; - bool receivedLeaveEvent; - QWidget *enterWidget; - QWidget *leaveWidget; + bool receivedEnterEvent = false; + bool receivedLeaveEvent = false; + QWidget *enterWidget = nullptr; + QWidget *leaveWidget = nullptr; + bool checkEvents = false; }; void tst_QGraphicsView::hoverLeave() { - if (platformName == QStringLiteral("cocoa")) { - QSKIP("Insignificant on OSX"); - } else if (platformName == QStringLiteral("minimal") - || (platformName == QStringLiteral("offscreen"))) { - QSKIP("Fails in minimal/offscreen platforms if forwardMouseDoubleClick has been run"); - } - const QRect availableGeometry = QGuiApplication::primaryScreen()->availableGeometry(); QGraphicsScene scene; QGraphicsView view(&scene); view.resize(160, 160); - view.move(availableGeometry.center() - QPoint(80, 80)); GraphicsItemWithHover *item = new GraphicsItemWithHover; scene.addItem(item); - // move the cursor out of the way - const QPoint outOfWindow = view.geometry().topRight() + QPoint(50, 0); - QCursor::setPos(outOfWindow); - view.showNormal(); qApp->setActiveWindow(&view); - QVERIFY(QTest::qWaitForWindowActive(&view)); - - QPoint pos = view.viewport()->mapToGlobal(view.mapFromScene(item->mapToScene(10, 10))); - QCursor::setPos(pos); + QVERIFY(QTest::qWaitForWindowExposed(&view)); -#if defined(Q_OS_QNX) - QEXPECT_FAIL("", "QCursor does not set native cursor on QNX", Abort); -#endif + QWindow *viewWindow = view.window()->windowHandle(); + QPoint posOutsideItem = view.mapFromScene(item->mapToScene(0, 0)) - QPoint(5, 0); + QPoint posOutsideItemGlobal = view.mapToGlobal(posOutsideItem); + QPoint posOutsideItemInWindow = viewWindow->mapFromGlobal(posOutsideItemGlobal); + QTest::mouseMove(viewWindow, posOutsideItemInWindow); + item->checkEvents = true; + QPoint posInItemGlobal = view.mapToGlobal(view.mapFromScene(item->mapToScene(10, 10))); + QTest::mouseMove(viewWindow, viewWindow->mapFromGlobal(posInItemGlobal)); QTRY_VERIFY(item->receivedEnterEvent); QCOMPARE(item->enterWidget, view.viewport()); - QCursor::setPos(outOfWindow); -#ifdef Q_OS_MAC - QEXPECT_FAIL("", "QTBUG-26274 - behaviour regression", Abort); -#endif + QTest::mouseMove(viewWindow, posOutsideItemInWindow); + QTRY_VERIFY(item->receivedLeaveEvent); QCOMPARE(item->leaveWidget, view.viewport()); } -- cgit v1.2.3 From 377d2502e3d3116c4cbe7398c2aa6f4afbe32851 Mon Sep 17 00:00:00 2001 From: Gatis Paeglis Date: Tue, 26 Sep 2017 12:20:30 +0200 Subject: tests: make exposeEventOnShrink_QTBUG54040 not flakey on xcb MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit From: https://tronche.com/gui/x/xlib/events/exposure/expose.html "The circumstances in which the X server generates Expose events are not as definite as those for other events." On windows with XCB_GRAVITY_NORTH_WEST flag set we should not get expose events according to e2665600c09358854bb0b29389cc873a2684f77b, but as stated earlier this might not always be true. Nevertheless, sometimes we get expose event from X server when shrinking window, but most of the time we don't. Make the test not flakey by checking that we get at least 1 expose event, instead of exactly 1. Now running test 500 times in a loop does not fail. Task-number: QTBUG-63424 Change-Id: I8004e622020cc09e11b7d592faf6d9ee1b9cfee2 Reviewed-by: Tor Arne Vestbø (cherry picked from commit 542e11ab2bd4a607fda8f559cc7efc32371b4e0e) Reviewed-by: Tony Sarajärvi Reviewed-by: Friedemann Kleint Reviewed-by: Liang Qi --- tests/auto/gui/kernel/qwindow/tst_qwindow.cpp | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) (limited to 'tests') diff --git a/tests/auto/gui/kernel/qwindow/tst_qwindow.cpp b/tests/auto/gui/kernel/qwindow/tst_qwindow.cpp index e1366ce2eb..6452b9ecd0 100644 --- a/tests/auto/gui/kernel/qwindow/tst_qwindow.cpp +++ b/tests/auto/gui/kernel/qwindow/tst_qwindow.cpp @@ -394,13 +394,17 @@ void tst_QWindow::exposeEventOnShrink_QTBUG54040() QVERIFY(QTest::qWaitForWindowExposed(&window)); - const int initialExposeCount = window.received(QEvent::Expose); + int exposeCount = window.received(QEvent::Expose); window.resize(window.width(), window.height() - 5); - QTRY_COMPARE(window.received(QEvent::Expose), initialExposeCount + 1); + QTRY_VERIFY(window.received(QEvent::Expose) > exposeCount); + + exposeCount = window.received(QEvent::Expose); window.resize(window.width() - 5, window.height()); - QTRY_COMPARE(window.received(QEvent::Expose), initialExposeCount + 2); + QTRY_VERIFY(window.received(QEvent::Expose) > exposeCount); + + exposeCount = window.received(QEvent::Expose); window.resize(window.width() - 5, window.height() - 5); - QTRY_COMPARE(window.received(QEvent::Expose), initialExposeCount + 3); + QTRY_VERIFY(window.received(QEvent::Expose) > exposeCount); } void tst_QWindow::positioning_data() -- cgit v1.2.3 From 8a39384e907e830c907f73009f498c486b22bd20 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A5rten=20Nordheim?= Date: Tue, 10 Oct 2017 15:54:04 +0200 Subject: Open a session during redirects when needed In some cases when a session isn't needed (i.e. for localhost), the session is not opened at all. If a program (e.g. our tests) redirects from localhost to a different system (e.g. the qt network test servers, or the internet) it will wait for a session forever. So, we need to check if a session is needed for the redirect-target and then open one. It is usually opened in QNetworkReplyHttpImplPrivate::_q_startOperation Change-Id: Id3b78182a3fb3f63f0235ecb1fb665df8bd0c4ca Reviewed-by: Edward Welbourne Reviewed-by: Timur Pocheptsov --- .../access/qnetworkreply/tst_qnetworkreply.cpp | 28 ++++++++++++++++++++++ 1 file changed, 28 insertions(+) (limited to 'tests') diff --git a/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp b/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp index 97fe9e04bf..d236ef0490 100644 --- a/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp +++ b/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp @@ -490,6 +490,7 @@ private Q_SLOTS: void ioHttpCookiesDuringRedirect(); void ioHttpRedirect_data(); void ioHttpRedirect(); + void ioHttpRedirectFromLocalToRemote(); #ifndef QT_NO_SSL void putWithServerClosingConnectionImmediately(); #endif @@ -8490,6 +8491,33 @@ void tst_QNetworkReply::ioHttpRedirect() QVERIFY(validateRedirectedResponseHeaders(reply)); } +void tst_QNetworkReply::ioHttpRedirectFromLocalToRemote() +{ + QUrl targetUrl("http://" + QtNetworkSettings::serverName() + "/qtest/rfc3252.txt"); + + QString redirectReply = tempRedirectReplyStr().arg(targetUrl.toString()); + MiniHttpServer redirectServer(redirectReply.toLatin1(), false); + QUrl url("http://localhost/"); + url.setPort(redirectServer.serverPort()); + + QFile reference(testDataDir + "/rfc3252.txt"); + QVERIFY(reference.open(QIODevice::ReadOnly)); + QNetworkRequest request(url); + + auto oldRedirectPolicy = manager.redirectPolicy(); + manager.setRedirectPolicy(QNetworkRequest::RedirectPolicy::NoLessSafeRedirectPolicy); + QNetworkReplyPtr reply(manager.get(request)); + // Restore previous policy + manager.setRedirectPolicy(oldRedirectPolicy); + + QCOMPARE(waitForFinish(reply), int(Success)); + + QCOMPARE(reply->url(), targetUrl); + QCOMPARE(reply->error(), QNetworkReply::NoError); + QCOMPARE(reply->header(QNetworkRequest::ContentLengthHeader).toLongLong(), reference.size()); + QCOMPARE(reply->readAll(), reference.readAll()); +} + #ifndef QT_NO_SSL class PutWithServerClosingConnectionImmediatelyHandler: public QObject -- cgit v1.2.3 From c4cf90b1f739c47383672de3d66b1d9d5427f5db Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A5rten=20Nordheim?= Date: Mon, 9 Oct 2017 14:57:46 +0200 Subject: Fix redirecting POST for HTTP 307 and 308 All POST requests that were redirected would previously turn into GET requests. This does not follow the standard for HTTP codes 307 and 308. Task-number: QTBUG-63142 Change-Id: Ibd25a9566066e589670a9bc34e5dc5111f8139d5 Reviewed-by: Timur Pocheptsov Reviewed-by: Edward Welbourne --- .../access/qnetworkreply/tst_qnetworkreply.cpp | 152 ++++++++++++++++++++- 1 file changed, 149 insertions(+), 3 deletions(-) (limited to 'tests') diff --git a/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp b/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp index d236ef0490..d22850ba4e 100644 --- a/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp +++ b/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp @@ -491,6 +491,10 @@ private Q_SLOTS: void ioHttpRedirect_data(); void ioHttpRedirect(); void ioHttpRedirectFromLocalToRemote(); + void ioHttpRedirectPost_data(); + void ioHttpRedirectPost(); + void ioHttpRedirectMultipartPost_data(); + void ioHttpRedirectMultipartPost(); #ifndef QT_NO_SSL void putWithServerClosingConnectionImmediately(); #endif @@ -542,7 +546,7 @@ static void setupSslServer(QSslSocket* serverSocket) } #endif -// Does not work for POST/PUT! +// Does not work for PUT! Limited support for POST. class MiniHttpServer: public QTcpServer { Q_OBJECT @@ -557,6 +561,10 @@ public: bool multiple; int totalConnections; + bool hasContent = false; + int contentRead = 0; + int contentLength = 0; + MiniHttpServer(const QByteArray &data, bool ssl = false, QThread *thread = 0, bool useipv6 = false) : dataToTransmit(data), doClose(true), doSsl(ssl), ipv6(useipv6), multiple(false), totalConnections(0) @@ -633,6 +641,18 @@ private: this, SLOT(slotError(QAbstractSocket::SocketError))); } + void parseContentLength() + { + int index = receivedData.indexOf("Content-Length:"); + index += sizeof("Content-Length:") - 1; + const auto end = std::find(receivedData.cbegin() + index, receivedData.cend(), '\r'); + auto num = receivedData.mid(index, std::distance(receivedData.cbegin() + index, end)); + bool ok; + contentLength = num.toInt(&ok); + if (!ok) + contentLength = -1; + } + private slots: #ifndef QT_NO_SSL void slotSslErrors(const QList& errors) @@ -654,12 +674,20 @@ public slots: { Q_ASSERT(!client.isNull()); receivedData += client->readAll(); - int doubleEndlPos = receivedData.indexOf("\r\n\r\n"); + const int doubleEndlPos = receivedData.indexOf("\r\n\r\n"); if (doubleEndlPos != -1) { + const int endOfHeader = doubleEndlPos + 4; + hasContent = receivedData.startsWith("POST"); + if (hasContent && contentLength == 0) + parseContentLength(); + contentRead = receivedData.length() - endOfHeader; + if (hasContent && contentRead < contentLength) + return; + // multiple requests incoming. remove the bytes of the current one if (multiple) - receivedData.remove(0, doubleEndlPos+4); + receivedData.remove(0, endOfHeader); reply(); } @@ -8518,6 +8546,124 @@ void tst_QNetworkReply::ioHttpRedirectFromLocalToRemote() QCOMPARE(reply->readAll(), reference.readAll()); } +void tst_QNetworkReply::ioHttpRedirectPost_data() +{ + QTest::addColumn("status"); + QTest::addColumn("data"); + QTest::addColumn("contentType"); + + QByteArray data; + data = "hello world"; + QTest::addRow("307") << "307 Temporary Redirect" << data << "text/plain"; + QString permanentRedirect = "308 Permanent Redirect"; + QTest::addRow("308") << permanentRedirect << data << "text/plain"; + + // Some data from ::putToFile_data + data = ""; + QTest::newRow("empty") << permanentRedirect << data << "application/octet-stream"; + + data = QByteArray("abcd\0\1\2\abcd",12); + QTest::newRow("with-nul") << permanentRedirect << data << "application/octet-stream"; + + data = QByteArray(4097, '\4'); + QTest::newRow("4k+1") << permanentRedirect << data << "application/octet-stream"; + + data = QByteArray(128*1024+1, '\177'); + QTest::newRow("128k+1") << permanentRedirect << data << "application/octet-stream"; + + data = QByteArray(2*1024*1024+1, '\177'); + QTest::newRow("2MB+1") << permanentRedirect << data << "application/octet-stream"; +} + +void tst_QNetworkReply::ioHttpRedirectPost() +{ + QFETCH(QString, status); + QFETCH(QByteArray, data); + QFETCH(QString, contentType); + + QUrl targetUrl("http://" + QtNetworkSettings::serverName() + "/qtest/cgi-bin/md5sum.cgi"); + + QString redirectReply = QStringLiteral("HTTP/1.1 %1\r\n" + "Content-Type: text/plain\r\n" + "location: %2\r\n" + "\r\n").arg(status, targetUrl.toString()); + MiniHttpServer redirectServer(redirectReply.toLatin1()); + QUrl url("http://localhost/"); + url.setPort(redirectServer.serverPort()); + QNetworkRequest request(url); + request.setHeader(QNetworkRequest::KnownHeaders::ContentTypeHeader, contentType); + auto oldRedirectPolicy = manager.redirectPolicy(); + manager.setRedirectPolicy(QNetworkRequest::RedirectPolicy::NoLessSafeRedirectPolicy); + + QNetworkReplyPtr reply(manager.post(request, data)); + // Restore previous policy: + manager.setRedirectPolicy(oldRedirectPolicy); + + QCOMPARE(waitForFinish(reply), int(Success)); + QCOMPARE(reply->readAll().trimmed(), md5sum(data).toHex()); +} + +void tst_QNetworkReply::ioHttpRedirectMultipartPost_data() +{ + postToHttpMultipart_data(); +} + +void tst_QNetworkReply::ioHttpRedirectMultipartPost() +{ + // Note: This code is heavily based on postToHttpMultipart + QFETCH(QUrl, url); + + static QSet boundaries; + + QNetworkReplyPtr reply; + + QFETCH(QHttpMultiPart *, multiPart); + QFETCH(QByteArray, expectedReplyData); + QFETCH(QByteArray, contentType); + + QString redirectReply = tempRedirectReplyStr().arg(url.toString()); + MiniHttpServer redirectServer(redirectReply.toLatin1()); + QUrl redirectUrl("http://localhost/"); + redirectUrl.setPort(redirectServer.serverPort()); + QNetworkRequest request(redirectUrl); + + // Restore policy when we leave this scope: + struct PolicyRestorer + { + QNetworkAccessManager &qnam; + QNetworkRequest::RedirectPolicy policy; + PolicyRestorer(QNetworkAccessManager &qnam) + : qnam(qnam), policy(qnam.redirectPolicy()) + { qnam.setRedirectPolicy(QNetworkRequest::RedirectPolicy::NoLessSafeRedirectPolicy); } + ~PolicyRestorer() { qnam.setRedirectPolicy(policy); } + } policyRestorer(manager); + + // hack for testing the setting of the content-type header by hand: + if (contentType == "custom") { + QByteArray contentType("multipart/custom; boundary=\"" + multiPart->boundary() + "\""); + request.setHeader(QNetworkRequest::ContentTypeHeader, contentType); + } + + QVERIFY2(! boundaries.contains(multiPart->boundary()), "boundary '" + multiPart->boundary() + "' has been created twice"); + boundaries.insert(multiPart->boundary()); + + RUN_REQUEST(runMultipartRequest(request, reply, multiPart, "POST")); + multiPart->deleteLater(); + + QCOMPARE(reply->url(), url); + QCOMPARE(reply->error(), QNetworkReply::NoError); + + QCOMPARE(reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(), 200); // 200 OK + + QVERIFY(multiPart->boundary().count() > 20); // check that there is randomness after the "boundary_.oOo._" string + QVERIFY(multiPart->boundary().count() < 70); + QByteArray replyData = reply->readAll(); + + expectedReplyData.prepend("content type: multipart/" + contentType + "; boundary=\"" + multiPart->boundary() + "\"\n"); +// QEXPECT_FAIL("nested", "the server does not understand nested multipart messages", Continue); // see above + QCOMPARE(replyData, expectedReplyData); +} + #ifndef QT_NO_SSL class PutWithServerClosingConnectionImmediatelyHandler: public QObject -- cgit v1.2.3 From fc988786588bf86ebc46fdd12629efbec8ae1841 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A5rten=20Nordheim?= Date: Tue, 17 Oct 2017 15:16:40 +0200 Subject: Fix cookie path matching for empty url path The path wouldn't match if the cookie's path was root ('/') and the URLs path was empty. Change-Id: I6dcd10f1fdf4f48f14e50f1b169cbdfda7005849 Reviewed-by: Thiago Macieira Reviewed-by: Timur Pocheptsov Reviewed-by: Edward Welbourne --- .../access/qnetworkcookiejar/tst_qnetworkcookiejar.cpp | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'tests') diff --git a/tests/auto/network/access/qnetworkcookiejar/tst_qnetworkcookiejar.cpp b/tests/auto/network/access/qnetworkcookiejar/tst_qnetworkcookiejar.cpp index a0459021be..ed5d0c69a0 100644 --- a/tests/auto/network/access/qnetworkcookiejar/tst_qnetworkcookiejar.cpp +++ b/tests/auto/network/access/qnetworkcookiejar/tst_qnetworkcookiejar.cpp @@ -340,6 +340,17 @@ void tst_QNetworkCookieJar::cookiesForUrl_data() QTest::newRow("no-match-domain-dot") << allCookies << "http://example.com" << result; result += cookieDot; QTest::newRow("match-domain-dot") << allCookies << "http://example.com." << result; + + // Root path in cookie, empty url path + allCookies.clear(); + QNetworkCookie rootCookie; + rootCookie.setName("a"); + rootCookie.setPath("/"); + rootCookie.setDomain("qt-project.org"); + allCookies += rootCookie; + result.clear(); + result += rootCookie; + QTest::newRow("root-path-match") << allCookies << "http://qt-project.org" << result; } void tst_QNetworkCookieJar::cookiesForUrl() -- cgit v1.2.3 From 9c58dd15885d813aeb5d83d2869c0f3a3ee5fcfe Mon Sep 17 00:00:00 2001 From: Sami Nurmenniemi Date: Fri, 20 Oct 2017 16:09:29 +0300 Subject: Blacklist and skip failing tests for Boot2Qt / 64 bit arm MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Task-number: QTBUG-60263 Change-Id: I05978915b5bb7ae31069e8e9ae1dc273e483ddb0 Reviewed-by: Tony Sarajärvi --- tests/auto/auto.pro | 5 +++++ tests/auto/corelib/global/qlogging/BLACKLIST | 3 +++ 2 files changed, 8 insertions(+) create mode 100644 tests/auto/corelib/global/qlogging/BLACKLIST (limited to 'tests') diff --git a/tests/auto/auto.pro b/tests/auto/auto.pro index 0f8129cb74..3caa6a3b65 100644 --- a/tests/auto/auto.pro +++ b/tests/auto/auto.pro @@ -43,3 +43,8 @@ else:!qtConfig(process): SUBDIRS -= tools SUBDIRS -= dbus } } + +# QTBUG-63915 +boot2qt: { + contains(QT_ARCH, arm64): SUBDIRS -= dbus +} diff --git a/tests/auto/corelib/global/qlogging/BLACKLIST b/tests/auto/corelib/global/qlogging/BLACKLIST new file mode 100644 index 0000000000..1dcee92361 --- /dev/null +++ b/tests/auto/corelib/global/qlogging/BLACKLIST @@ -0,0 +1,3 @@ +[qMessagePattern:backtrace depth,separator] +# QTBUG-63915 +b2qt 64bit -- cgit v1.2.3