diff options
Diffstat (limited to 'tests')
-rw-r--r-- | tests/auto/auto.pro | 1 | ||||
-rw-r--r-- | tests/auto/qgraphicsview/tst_qgraphicsview.cpp | 24 | ||||
-rw-r--r-- | tests/auto/qgraphicswidget/tst_qgraphicswidget.cpp | 85 | ||||
-rw-r--r-- | tests/auto/qlistview/tst_qlistview.cpp | 24 | ||||
-rw-r--r-- | tests/auto/qnetworkreply/tst_qnetworkreply.cpp | 581 | ||||
-rw-r--r-- | tests/auto/qringbuffer/qringbuffer.pro | 6 | ||||
-rw-r--r-- | tests/auto/qringbuffer/tst_qringbuffer.cpp | 200 | ||||
-rw-r--r-- | tests/auto/qsqlquery/tst_qsqlquery.cpp | 22 | ||||
-rw-r--r-- | tests/auto/qsslsocket/tst_qsslsocket.cpp | 2 | ||||
-rw-r--r-- | tests/auto/qtreewidget/tst_qtreewidget.cpp | 20 |
10 files changed, 947 insertions, 18 deletions
diff --git a/tests/auto/auto.pro b/tests/auto/auto.pro index 443ee7e..a3a6916 100644 --- a/tests/auto/auto.pro +++ b/tests/auto/auto.pro @@ -238,6 +238,7 @@ SUBDIRS += bic \ qregexpvalidator \ qregion \ qresourceengine \ + qringbuffer \ qscriptable \ qscriptclass \ qscriptcontext \ diff --git a/tests/auto/qgraphicsview/tst_qgraphicsview.cpp b/tests/auto/qgraphicsview/tst_qgraphicsview.cpp index bb61f90..920cba7 100644 --- a/tests/auto/qgraphicsview/tst_qgraphicsview.cpp +++ b/tests/auto/qgraphicsview/tst_qgraphicsview.cpp @@ -204,6 +204,7 @@ private slots: void task239729_noViewUpdate(); void task239047_fitInViewSmallViewport(); void task245469_itemsAtPointWithClip(); + void task253415_reconnectUpdateSceneOnSceneChanged(); }; void tst_QGraphicsView::initTestCase() @@ -3200,5 +3201,28 @@ void tst_QGraphicsView::mouseTracking2() QCOMPARE(spy.count(), 1); } +void tst_QGraphicsView::task253415_reconnectUpdateSceneOnSceneChanged() +{ + QGraphicsView view; + QGraphicsView dummyView; + view.setWindowFlags(view.windowFlags() | Qt::WindowStaysOnTopHint); + view.resize(200, 200); + + QGraphicsScene scene1; + QObject::connect(&scene1, SIGNAL(changed(QList<QRectF>)), &dummyView, SLOT(updateScene(QList<QRectF>))); + view.setScene(&scene1); + + QTest::qWait(125); + + QGraphicsScene scene2; + QObject::connect(&scene2, SIGNAL(changed(QList<QRectF>)), &dummyView, SLOT(updateScene(QList<QRectF>))); + view.setScene(&scene2); + + QTest::qWait(125); + + bool wasConnected2 = QObject::disconnect(&scene2, SIGNAL(changed(QList<QRectF>)), &view, 0); + QVERIFY(wasConnected2); +} + QTEST_MAIN(tst_QGraphicsView) #include "tst_qgraphicsview.moc" diff --git a/tests/auto/qgraphicswidget/tst_qgraphicswidget.cpp b/tests/auto/qgraphicswidget/tst_qgraphicswidget.cpp index 56737c3..343aac6 100644 --- a/tests/auto/qgraphicswidget/tst_qgraphicswidget.cpp +++ b/tests/auto/qgraphicswidget/tst_qgraphicswidget.cpp @@ -50,6 +50,7 @@ #include <qcleanlooksstyle.h> #include <qlineedit.h> #include <qboxlayout.h> +#include <qaction.h> #include "../../shared/util.h" @@ -155,6 +156,7 @@ private slots: // Task fixes void task236127_bspTreeIndexFails(); void task243004_setStyleCrash(); + void task250119_shortcutContext(); }; @@ -2212,6 +2214,89 @@ void tst_QGraphicsWidget::task243004_setStyleCrash() delete item2; } +class GraphicsWidget_task250119 : public QGraphicsWidget +{ +public: + GraphicsWidget_task250119() + : shortcutEvents(0) + { + setFocusPolicy(Qt::StrongFocus); + resize(100, 100); + } + + int shortcutEvents; + +private: + bool event(QEvent *event) + { + if (event->type() == QEvent::Shortcut) + shortcutEvents++; + return QGraphicsWidget::event(event); + } + + void paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *) + { + if (hasFocus()) { + painter->setPen(QPen(Qt::black, 0, Qt::DashLine)); + painter->drawRect(rect()); + } + painter->setPen(QPen(Qt::black, 0, Qt::SolidLine)); + painter->fillRect(rect().adjusted(2, 2, -2, -2), Qt::yellow); + painter->drawRect(rect().adjusted(2, 2, -2, -2)); + } +}; + +void tst_QGraphicsWidget::task250119_shortcutContext() +{ + QGraphicsScene scene; + QGraphicsView view; + view.setScene(&scene); + view.show(); + QTest::qWait(100); + + + // *** Event: *** + + GraphicsWidget_task250119 w_event; + scene.addItem(&w_event); + + const int id = w_event.grabShortcut(Qt::Key_A, Qt::WidgetWithChildrenShortcut); + w_event.setShortcutEnabled(id, true); + + w_event.setFocus(); + QTest::keyPress(&view, Qt::Key_A); + QCOMPARE(w_event.shortcutEvents, 1); + + w_event.clearFocus(); + QTest::keyPress(&view, Qt::Key_A); + QCOMPARE(w_event.shortcutEvents, 1); + + scene.removeItem(&w_event); + + + // *** Signal: *** + + GraphicsWidget_task250119 w_signal; + scene.addItem(&w_signal); + + QAction action(0); + action.setShortcut(Qt::Key_B); + action.setShortcutContext(Qt::WidgetWithChildrenShortcut); + QSignalSpy spy(&action, SIGNAL(triggered())); + + w_signal.addAction(&action); + + w_signal.setFocus(); + QTest::keyPress(&view, Qt::Key_B); + QCOMPARE(spy.count(), 1); + + w_signal.clearFocus(); + QTest::keyPress(&view, Qt::Key_B); + QCOMPARE(spy.count(), 1); + + scene.removeItem(&w_signal); +} + QTEST_MAIN(tst_QGraphicsWidget) #include "tst_qgraphicswidget.moc" diff --git a/tests/auto/qlistview/tst_qlistview.cpp b/tests/auto/qlistview/tst_qlistview.cpp index 791a472..f70db14 100644 --- a/tests/auto/qlistview/tst_qlistview.cpp +++ b/tests/auto/qlistview/tst_qlistview.cpp @@ -106,6 +106,7 @@ private slots: void task228566_infiniteRelayout(); void task248430_crashWith0SizedItem(); void task250446_scrollChanged(); + void task196118_visualRegionForSelection(); void keyboardSearch(); }; @@ -1556,6 +1557,29 @@ void tst_QListView::task250446_scrollChanged() QCOMPARE(view.currentIndex(), index); } +void tst_QListView::task196118_visualRegionForSelection() +{ + class MyListView : public QListView + { + public: + QRegion visualRegionForSelection() const + { return QListView::visualRegionForSelection( selectionModel()->selection()); } + } view; + + QStandardItemModel model; + QStandardItem top1("top1"); + QStandardItem sub1("sub1"); + top1.appendRow(QList<QStandardItem*>() << &sub1); + model.appendColumn(QList<QStandardItem*>() << &top1); + view.setModel(&model); + view.setRootIndex(top1.index()); + + view.selectionModel()->select(top1.index(), QItemSelectionModel::Select); + + QCOMPARE(view.selectionModel()->selectedIndexes().count(), 1); + QVERIFY(view.visualRegionForSelection().isEmpty()); +} + void tst_QListView::keyboardSearch() { QStringList items; diff --git a/tests/auto/qnetworkreply/tst_qnetworkreply.cpp b/tests/auto/qnetworkreply/tst_qnetworkreply.cpp index 104b788..6c622f7 100644 --- a/tests/auto/qnetworkreply/tst_qnetworkreply.cpp +++ b/tests/auto/qnetworkreply/tst_qnetworkreply.cpp @@ -52,6 +52,7 @@ #include <QtNetwork/QTcpSocket> #include <QtNetwork/QLocalSocket> #include <QtNetwork/QLocalServer> +#include <QtNetwork/QHostInfo> #include <QtNetwork/QFtp> #include <QtNetwork/qauthenticator.h> #include <QtNetwork/qnetworkaccessmanager.h> @@ -91,6 +92,15 @@ class tst_QNetworkReply: public QObject { Q_OBJECT + struct ProxyData { + ProxyData(const QNetworkProxy &p, const QByteArray &t, bool auth) + : tag(t), proxy(p), requiresAuthentication(auth) + { } + QByteArray tag; + QNetworkProxy proxy; + bool requiresAuthentication; + }; + QEventLoop *loop; enum RunSimpleRequestReturn { Timeout = 0, Success, Failure }; int returnCode; @@ -99,6 +109,7 @@ class tst_QNetworkReply: public QObject QString wronlyFileName; #endif QString uniqueExtension; + QList<ProxyData> proxies; QNetworkAccessManager manager; MyCookieJar *cookieJar; #ifndef QT_NO_OPENSSL @@ -172,6 +183,8 @@ private Q_SLOTS: void ioGetFromHttpsWithIgnoreSslErrors(); void ioGetFromHttpsWithSslHandshakeError(); #endif + void ioGetFromHttpBrokenServer_data(); + void ioGetFromHttpBrokenServer(); void ioGetWithManyProxies_data(); void ioGetWithManyProxies(); @@ -190,11 +203,20 @@ private Q_SLOTS: void ioPutToHttpFromFile(); void ioPostToHttpFromFile_data(); void ioPostToHttpFromFile(); + void ioPostToHttpFromSocket_data(); + void ioPostToHttpFromSocket(); + void ioPostToHttpFromMiddleOfFileToEnd(); + void ioPostToHttpFromMiddleOfFileFiveBytes(); + void ioPostToHttpFromMiddleOfQBufferFiveBytes(); + void ioPostToHttpNoBufferFlag(); + void ioPostToHttpUploadProgress(); + void ioPostToHttpEmtpyUploadProgress(); void rateControl_data(); void rateControl(); void downloadPerformance(); void uploadPerformance(); + void httpUploadPerformance(); void performanceControlRate(); void downloadProgress_data(); @@ -364,6 +386,63 @@ public slots: } }; +class FixedSizeDataGenerator : public QIODevice +{ + Q_OBJECT + enum { Idle, Started, Stopped } state; +public: + FixedSizeDataGenerator(qint64 size) : state(Idle) + { open(ReadOnly | Unbuffered); + toBeGeneratedTotalCount = toBeGeneratedCount = size; + } + + virtual qint64 bytesAvailable() const + { + return state == Started ? toBeGeneratedCount + QIODevice::bytesAvailable() : 0; + } + + virtual bool isSequential() const{ + return false; + } + + virtual bool reset() const{ + return false; + } + + qint64 size() const { + return toBeGeneratedTotalCount; + } + +public slots: + void start() { state = Started; emit readyRead(); } + +protected: + virtual qint64 readData(char *data, qint64 maxlen) + { + memset(data, '@', maxlen); + + if (toBeGeneratedCount <= 0) { + return -1; + } + + qint64 n = qMin(maxlen, toBeGeneratedCount); + toBeGeneratedCount -= n; + + if (toBeGeneratedCount <= 0) { + // make sure this is a queued connection! + emit readChannelFinished(); + } + + return n; + } + virtual qint64 writeData(const char *, qint64) + { return -1; } + + qint64 toBeGeneratedCount; + qint64 toBeGeneratedTotalCount; +}; + + class DataGenerator: public QIODevice { Q_OBJECT @@ -384,6 +463,7 @@ protected: { if (state == Stopped) return -1; // EOF + // return as many bytes as are wanted memset(data, '@', maxlen); return maxlen; @@ -392,6 +472,8 @@ protected: { return -1; } }; + + class SocketPair: public QObject { Q_OBJECT @@ -629,7 +711,7 @@ protected: return; transferRate = totalBytes * 1000 / timer.elapsed(); - qDebug() << "receive rate:" << (transferRate / 1024) << "kB/s in" + qDebug() << "TimedSender::run" << "receive rate:" << (transferRate / 1024) << "kB/s in" << timer.elapsed() << "ms"; } @@ -643,12 +725,13 @@ protected: class ThreadedDataReader: public QThread { Q_OBJECT + // used to make the constructor only return after the tcp server started listening QSemaphore ready; QTcpSocket *client; int timeout; int port; public: - int transferRate; + qint64 transferRate; ThreadedDataReader() : port(-1), transferRate(-1) { @@ -676,12 +759,65 @@ protected: QTime timer; timer.start(); eventLoop.exec(); + qint64 elapsed = timer.elapsed(); - transferRate = reader.totalBytes * 1000 / timer.elapsed(); - qDebug() << "send rate:" << (transferRate / 1024) << "kB/s"; + transferRate = reader.totalBytes * 1000 / elapsed; + qDebug() << "ThreadedDataReader::run" << "send rate:" << (transferRate / 1024) << "kB/s in" << elapsed << "msec"; } }; +class ThreadedDataReaderHttpServer: public QThread +{ + Q_OBJECT + // used to make the constructor only return after the tcp server started listening + QSemaphore ready; + QTcpSocket *client; + int timeout; + int port; +public: + qint64 transferRate; + ThreadedDataReaderHttpServer() + : port(-1), transferRate(-1) + { + start(); + ready.acquire(); + } + + inline int serverPort() const { return port; } + +protected: + void run() + { + QTcpServer server; + server.listen(); + port = server.serverPort(); + ready.release(); + + server.waitForNewConnection(-1); + client = server.nextPendingConnection(); + client->write("HTTP/1.0 200 OK\r\n"); + client->write("Content-length: 0\r\n"); + client->write("\r\n"); + client->flush(); + + QCoreApplication::processEvents(); + + QEventLoop eventLoop; + DataReader reader(client, false); + QObject::connect(client, SIGNAL(disconnected()), &eventLoop, SLOT(quit())); + + QTime timer; + timer.start(); + eventLoop.exec(); + qint64 elapsed = timer.elapsed(); + + transferRate = reader.totalBytes * 1000 / elapsed; + qDebug() << "ThreadedDataReaderHttpServer::run" << "send rate:" << (transferRate / 1024) << "kB/s in" << elapsed << "msec"; + } +}; + + + tst_QNetworkReply::tst_QNetworkReply() { testFileName = QDir::currentPath() + "/testfile"; @@ -692,8 +828,28 @@ tst_QNetworkReply::tst_QNetworkReply() #endif cookieJar = new MyCookieJar; manager.setCookieJar(cookieJar); + + QHostInfo hostInfo = QHostInfo::fromName(QtNetworkSettings::serverName()); + + proxies << ProxyData(QNetworkProxy::NoProxy, "", false); + + if (hostInfo.error() == QHostInfo::NoError && !hostInfo.addresses().isEmpty()) { + QString proxyserver = hostInfo.addresses().first().toString(); + proxies << ProxyData(QNetworkProxy(QNetworkProxy::HttpProxy, proxyserver, 3128), "+proxy", false) + << ProxyData(QNetworkProxy(QNetworkProxy::HttpProxy, proxyserver, 3129), "+proxyauth", true) + // currently unsupported + // << ProxyData(QNetworkProxy(QNetworkProxy::HttpProxy, proxyserver, 3130), "+proxyauth-ntlm", true); + << ProxyData(QNetworkProxy(QNetworkProxy::Socks5Proxy, proxyserver, 1080), "+socks", false) + << ProxyData(QNetworkProxy(QNetworkProxy::Socks5Proxy, proxyserver, 1081), "+socksauth", true); + } else { + printf("==================================================================\n"); + printf("Proxy could not be looked up. No proxy will be used while testing!\n"); + printf("==================================================================\n"); + } } + + void tst_QNetworkReply::authenticationRequired(QNetworkReply*, QAuthenticator* auth) { auth->setUser("httptest"); @@ -1887,6 +2043,53 @@ void tst_QNetworkReply::ioGetFromHttpsWithSslHandshakeError() } #endif +void tst_QNetworkReply::ioGetFromHttpBrokenServer_data() +{ + QTest::addColumn<QByteArray>("dataToSend"); + QTest::addColumn<bool>("doDisconnect"); + + QTest::newRow("no-newline") << QByteArray("Hello World") << false; + QTest::newRow("just-newline") << QByteArray("\r\n") << false; + QTest::newRow("just-2newline") << QByteArray("\r\n\r\n") << false; + QTest::newRow("with-newlines") << QByteArray("Long first line\r\nLong second line") << false; + QTest::newRow("with-newlines2") << QByteArray("\r\nSecond line") << false; + QTest::newRow("with-newlines3") << QByteArray("ICY\r\nSecond line") << false; + QTest::newRow("invalid-version") << QByteArray("HTTP/123 200 \r\n") << false; + QTest::newRow("invalid-version2") << QByteArray("HTTP/a.\033 200 \r\n") << false; + QTest::newRow("invalid-reply-code") << QByteArray("HTTP/1.0 fuu \r\n") << false; + + QTest::newRow("empty+disconnect") << QByteArray() << true; + + QTest::newRow("no-newline+disconnect") << QByteArray("Hello World") << true; + QTest::newRow("just-newline+disconnect") << QByteArray("\r\n") << true; + QTest::newRow("just-2newline+disconnect") << QByteArray("\r\n\r\n") << true; + QTest::newRow("with-newlines+disconnect") << QByteArray("Long first line\r\nLong second line") << true; + QTest::newRow("with-newlines2+disconnect") << QByteArray("\r\nSecond line") << true; + QTest::newRow("with-newlines3+disconnect") << QByteArray("ICY\r\nSecond line") << true; + + QTest::newRow("invalid-version+disconnect") << QByteArray("HTTP/123 200 ") << true; + QTest::newRow("invalid-version2+disconnect") << QByteArray("HTTP/a.\033 200 ") << true; + QTest::newRow("invalid-reply-code+disconnect") << QByteArray("HTTP/1.0 fuu ") << true; +} + +void tst_QNetworkReply::ioGetFromHttpBrokenServer() +{ + QFETCH(QByteArray, dataToSend); + QFETCH(bool, doDisconnect); + MiniHttpServer server(dataToSend); + server.doClose = doDisconnect; + + QNetworkRequest request(QUrl("http://localhost:" + QString::number(server.serverPort()))); + QNetworkReplyPtr reply = manager.get(request); + + connect(reply, SIGNAL(finished()), &QTestEventLoop::instance(), SLOT(exitLoop())); + QTestEventLoop::instance().enterLoop(10); + QVERIFY(!QTestEventLoop::instance().timeout()); + + QCOMPARE(reply->url(), request.url()); + QVERIFY(reply->error() != QNetworkReply::NoError); +} + void tst_QNetworkReply::ioGetWithManyProxies_data() { QTest::addColumn<QList<QNetworkProxy> >("proxyList"); @@ -2452,6 +2655,320 @@ void tst_QNetworkReply::ioPostToHttpFromFile() QCOMPARE(reply->readAll().trimmed(), md5sum(sourceFile.readAll()).toHex()); } +void tst_QNetworkReply::ioPostToHttpFromSocket_data() +{ + QTest::addColumn<QByteArray>("data"); + QTest::addColumn<QByteArray>("md5sum"); + QTest::addColumn<QUrl>("url"); + QTest::addColumn<QNetworkProxy>("proxy"); + QTest::addColumn<int>("authenticationRequiredCount"); + QTest::addColumn<int>("proxyAuthenticationRequiredCount"); + + for (int i = 0; i < proxies.count(); ++i) + for (int auth = 0; auth < 2; ++auth) { + QUrl url; + if (auth) + url = "http://" + QtNetworkSettings::serverName() + "/qtest/protected/cgi-bin/md5sum.cgi"; + else + url = "http://" + QtNetworkSettings::serverName() + "/qtest/cgi-bin/md5sum.cgi"; + + QNetworkProxy proxy = proxies.at(i).proxy; + QByteArray testsuffix = QByteArray(auth ? "+auth" : "") + proxies.at(i).tag; + int proxyauthcount = proxies.at(i).requiresAuthentication; + + QByteArray data; + data = ""; + QTest::newRow("empty" + testsuffix) << data << md5sum(data) << url << proxy << auth << proxyauthcount; + + data = "This is a normal message."; + QTest::newRow("generic" + testsuffix) << data << md5sum(data) << url << proxy << auth << proxyauthcount; + + data = "This is a message to show that Qt rocks!\r\n\n"; + QTest::newRow("small" + testsuffix) << data << md5sum(data) << url << proxy << auth << proxyauthcount; + + data = QByteArray("abcd\0\1\2\abcd",12); + QTest::newRow("with-nul" + testsuffix) << data << md5sum(data) << url << proxy << auth << proxyauthcount; + + data = QByteArray(4097, '\4'); + QTest::newRow("4k+1" + testsuffix) << data << md5sum(data) << url << proxy << auth << proxyauthcount; + + data = QByteArray(128*1024+1, '\177'); + QTest::newRow("128k+1" + testsuffix) << data << md5sum(data) << url << proxy << auth << proxyauthcount; + } +} + +void tst_QNetworkReply::ioPostToHttpFromSocket() +{ + qRegisterMetaType<QNetworkProxy>(); // for QSignalSpy + qRegisterMetaType<QAuthenticator *>(); + qRegisterMetaType<QNetworkReply *>(); + + QFETCH(QByteArray, data); + QFETCH(QUrl, url); + QFETCH(QNetworkProxy, proxy); + SocketPair socketpair; + socketpair.create(); + QVERIFY(socketpair.endPoints[0] && socketpair.endPoints[1]); + + socketpair.endPoints[0]->write(data); + + QNetworkRequest request(url); + manager.setProxy(proxy); + QNetworkReplyPtr reply = manager.post(QNetworkRequest(url), socketpair.endPoints[1]); + socketpair.endPoints[0]->close(); + + connect(reply, SIGNAL(finished()), &QTestEventLoop::instance(), SLOT(exitLoop())); + connect(&manager, SIGNAL(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*)), + SLOT(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*))); + connect(&manager, SIGNAL(authenticationRequired(QNetworkReply*,QAuthenticator*)), + SLOT(authenticationRequired(QNetworkReply*,QAuthenticator*))); + + QSignalSpy authenticationRequiredSpy(&manager, SIGNAL(authenticationRequired(QNetworkReply*,QAuthenticator*))); + QSignalSpy proxyAuthenticationRequiredSpy(&manager, SIGNAL(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*))); + + QTestEventLoop::instance().enterLoop(1); + + disconnect(&manager, SIGNAL(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*)), + this, SLOT(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*))); + disconnect(&manager, SIGNAL(authenticationRequired(QNetworkReply*,QAuthenticator*)), + this, SLOT(authenticationRequired(QNetworkReply*,QAuthenticator*))); + QVERIFY(!QTestEventLoop::instance().timeout()); + + QCOMPARE(reply->url(), url); + QCOMPARE(reply->error(), QNetworkReply::NoError); + // verify that the HTTP status code is 200 Ok + QCOMPARE(reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(), 200); + + QCOMPARE(reply->readAll().trimmed(), md5sum(data).toHex()); + + QTEST(authenticationRequiredSpy.count(), "authenticationRequiredCount"); + QTEST(proxyAuthenticationRequiredSpy.count(), "proxyAuthenticationRequiredCount"); + } + +// this tests checks if rewinding the POST-data to some place in the middle +// worked. +void tst_QNetworkReply::ioPostToHttpFromMiddleOfFileToEnd() +{ + QFile sourceFile(SRCDIR "/rfc3252.txt"); + QVERIFY(sourceFile.open(QIODevice::ReadOnly)); + // seeking to the middle + sourceFile.seek(sourceFile.size() / 2); + + QUrl url = "http://" + QtNetworkSettings::serverName() + "/qtest/protected/cgi-bin/md5sum.cgi"; + QNetworkRequest request(url); + QNetworkReplyPtr reply = manager.post(QNetworkRequest(url), &sourceFile); + + connect(reply, SIGNAL(finished()), &QTestEventLoop::instance(), SLOT(exitLoop())); + connect(&manager, SIGNAL(authenticationRequired(QNetworkReply*,QAuthenticator*)), + SLOT(authenticationRequired(QNetworkReply*,QAuthenticator*))); + + QTestEventLoop::instance().enterLoop(2); + disconnect(&manager, SIGNAL(authenticationRequired(QNetworkReply*,QAuthenticator*)), + this, SLOT(authenticationRequired(QNetworkReply*,QAuthenticator*))); + QVERIFY(!QTestEventLoop::instance().timeout()); + + // compare half data + sourceFile.seek(sourceFile.size() / 2); + QByteArray data = sourceFile.readAll(); + QCOMPARE(reply->readAll().trimmed(), md5sum(data).toHex()); +} + +void tst_QNetworkReply::ioPostToHttpFromMiddleOfFileFiveBytes() +{ + QFile sourceFile(SRCDIR "/rfc3252.txt"); + QVERIFY(sourceFile.open(QIODevice::ReadOnly)); + // seeking to the middle + sourceFile.seek(sourceFile.size() / 2); + + QUrl url = "http://" + QtNetworkSettings::serverName() + "/qtest/protected/cgi-bin/md5sum.cgi"; + QNetworkRequest request(url); + // only send 5 bytes + request.setHeader(QNetworkRequest::ContentLengthHeader, 5); + QVERIFY(request.header(QNetworkRequest::ContentLengthHeader).isValid()); + QNetworkReplyPtr reply = manager.post(request, &sourceFile); + + connect(reply, SIGNAL(finished()), &QTestEventLoop::instance(), SLOT(exitLoop())); + connect(&manager, SIGNAL(authenticationRequired(QNetworkReply*,QAuthenticator*)), + SLOT(authenticationRequired(QNetworkReply*,QAuthenticator*))); + + QTestEventLoop::instance().enterLoop(2); + disconnect(&manager, SIGNAL(authenticationRequired(QNetworkReply*,QAuthenticator*)), + this, SLOT(authenticationRequired(QNetworkReply*,QAuthenticator*))); + QVERIFY(!QTestEventLoop::instance().timeout()); + + // compare half data + sourceFile.seek(sourceFile.size() / 2); + QByteArray data = sourceFile.read(5); + QCOMPARE(reply->readAll().trimmed(), md5sum(data).toHex()); +} + +void tst_QNetworkReply::ioPostToHttpFromMiddleOfQBufferFiveBytes() +{ + // test needed since a QBuffer goes with a different codepath than the QFile + // tested in ioPostToHttpFromMiddleOfFileFiveBytes + QBuffer uploadBuffer; + uploadBuffer.open(QIODevice::ReadWrite); + uploadBuffer.write("1234567890"); + uploadBuffer.seek(5); + + QUrl url = "http://" + QtNetworkSettings::serverName() + "/qtest/protected/cgi-bin/md5sum.cgi"; + QNetworkRequest request(url); + QNetworkReplyPtr reply = manager.post(request, &uploadBuffer); + + connect(reply, SIGNAL(finished()), &QTestEventLoop::instance(), SLOT(exitLoop())); + connect(&manager, SIGNAL(authenticationRequired(QNetworkReply*,QAuthenticator*)), + SLOT(authenticationRequired(QNetworkReply*,QAuthenticator*))); + + QTestEventLoop::instance().enterLoop(2); + disconnect(&manager, SIGNAL(authenticationRequired(QNetworkReply*,QAuthenticator*)), + this, SLOT(authenticationRequired(QNetworkReply*,QAuthenticator*))); + QVERIFY(!QTestEventLoop::instance().timeout()); + + // compare half data + uploadBuffer.seek(5); + QByteArray data = uploadBuffer.read(5); + QCOMPARE(reply->readAll().trimmed(), md5sum(data).toHex()); +} + + +void tst_QNetworkReply::ioPostToHttpNoBufferFlag() +{ + QByteArray data = QByteArray("daaaaaaataaaaaaa"); + // create a sequential QIODevice by feeding the data into a local TCP server + SocketPair socketpair; + socketpair.create(); + QVERIFY(socketpair.endPoints[0] && socketpair.endPoints[1]); + socketpair.endPoints[0]->write(data); + + QUrl url = "http://" + QtNetworkSettings::serverName() + "/qtest/protected/cgi-bin/md5sum.cgi"; + QNetworkRequest request(url); + // disallow buffering + request.setAttribute(QNetworkRequest::DoNotBufferUploadDataAttribute, true); + request.setHeader(QNetworkRequest::ContentLengthHeader, data.size()); + QNetworkReplyPtr reply = manager.post(request, socketpair.endPoints[1]); + socketpair.endPoints[0]->close(); + + connect(reply, SIGNAL(finished()), &QTestEventLoop::instance(), SLOT(exitLoop())); + connect(&manager, SIGNAL(authenticationRequired(QNetworkReply*,QAuthenticator*)), + SLOT(authenticationRequired(QNetworkReply*,QAuthenticator*))); + + QTestEventLoop::instance().enterLoop(2); + disconnect(&manager, SIGNAL(authenticationRequired(QNetworkReply*,QAuthenticator*)), + this, SLOT(authenticationRequired(QNetworkReply*,QAuthenticator*))); + + // verify: error code is QNetworkReply::ContentReSendError + QCOMPARE(reply->error(), QNetworkReply::ContentReSendError); +} + + +void tst_QNetworkReply::ioPostToHttpUploadProgress() +{ + QFile sourceFile(SRCDIR "/bigfile"); + QVERIFY(sourceFile.open(QIODevice::ReadOnly)); + + // emulate a minimal http server + QTcpServer server; + server.listen(QHostAddress(QHostAddress::LocalHost), 0); + + // create the request + QUrl url = QUrl(QString("http://127.0.0.1:%1/").arg(server.serverPort())); + QNetworkRequest request(url); + QNetworkReplyPtr reply = manager.post(request, &sourceFile); + QSignalSpy spy(reply, SIGNAL(uploadProgress(qint64,qint64))); + connect(&server, SIGNAL(newConnection()), &QTestEventLoop::instance(), SLOT(exitLoop())); + + // get the request started and the incoming socket connected + QTestEventLoop::instance().enterLoop(10); + QVERIFY(!QTestEventLoop::instance().timeout()); + QTcpSocket *incomingSocket = server.nextPendingConnection(); + QVERIFY(incomingSocket); + disconnect(&server, SIGNAL(newConnection()), &QTestEventLoop::instance(), SLOT(exitLoop())); + + incomingSocket->setReadBufferSize(1*1024); + QTestEventLoop::instance().enterLoop(2); + // some progress should have been made + QList<QVariant> args = spy.last(); + QVERIFY(!args.isEmpty()); + QVERIFY(args.at(0).toLongLong() > 0); + + incomingSocket->setReadBufferSize(32*1024); + incomingSocket->read(16*1024); + QTestEventLoop::instance().enterLoop(2); + // some more progress than before + QList<QVariant> args2 = spy.last(); + QVERIFY(!args2.isEmpty()); + QVERIFY(args2.at(0).toLongLong() > args.at(0).toLongLong()); + + // set the read buffer to unlimited + incomingSocket->setReadBufferSize(0); + QTestEventLoop::instance().enterLoop(10); + // progress should be finished + QList<QVariant> args3 = spy.last(); + QVERIFY(!args3.isEmpty()); + QVERIFY(args3.at(0).toLongLong() > args2.at(0).toLongLong()); + QCOMPARE(args3.at(0).toLongLong(), args3.at(1).toLongLong()); + QCOMPARE(args3.at(0).toLongLong(), sourceFile.size()); + + // after sending this, the QNAM should emit finished() + connect(reply, SIGNAL(finished()), &QTestEventLoop::instance(), SLOT(exitLoop())); + incomingSocket->write("HTTP/1.0 200 OK\r\n"); + incomingSocket->write("Content-Length: 0\r\n"); + incomingSocket->write("\r\n"); + QTestEventLoop::instance().enterLoop(10); + // not timeouted -> finished() was emitted + QVERIFY(!QTestEventLoop::instance().timeout()); + + incomingSocket->close(); + server.close(); +} + +void tst_QNetworkReply::ioPostToHttpEmtpyUploadProgress() +{ + QByteArray ba; + ba.resize(0); + QBuffer buffer(&ba,0); + QVERIFY(buffer.open(QIODevice::ReadOnly)); + + // emulate a minimal http server + QTcpServer server; + server.listen(QHostAddress(QHostAddress::LocalHost), 0); + + // create the request + QUrl url = QUrl(QString("http://127.0.0.1:%1/").arg(server.serverPort())); + QNetworkRequest request(url); + QNetworkReplyPtr reply = manager.post(request, &buffer); + QSignalSpy spy(reply, SIGNAL(uploadProgress(qint64,qint64))); + connect(&server, SIGNAL(newConnection()), &QTestEventLoop::instance(), SLOT(exitLoop())); + + + // get the request started and the incoming socket connected + QTestEventLoop::instance().enterLoop(10); + QVERIFY(!QTestEventLoop::instance().timeout()); + QTcpSocket *incomingSocket = server.nextPendingConnection(); + QVERIFY(incomingSocket); + + // after sending this, the QNAM should emit finished() + connect(reply, SIGNAL(finished()), &QTestEventLoop::instance(), SLOT(exitLoop())); + incomingSocket->write("HTTP/1.0 200 OK\r\n"); + incomingSocket->write("Content-Length: 0\r\n"); + incomingSocket->write("\r\n"); + incomingSocket->flush(); + QTestEventLoop::instance().enterLoop(10); + // not timeouted -> finished() was emitted + QVERIFY(!QTestEventLoop::instance().timeout()); + + // final check: only 1 uploadProgress has been emitted + QVERIFY(spy.length() == 1); + QList<QVariant> args = spy.last(); + QVERIFY(!args.isEmpty()); + QCOMPARE(args.at(0).toLongLong(), buffer.size()); + QCOMPARE(args.at(0).toLongLong(), buffer.size()); + + incomingSocket->close(); + server.close(); +} + + void tst_QNetworkReply::rateControl_data() { QTest::addColumn<int>("rate"); @@ -2488,8 +3005,8 @@ void tst_QNetworkReply::rateControl() QTestEventLoop::instance().enterLoop(40); int elapsedTime = loopTime.elapsed(); - qDebug() << "send rate:" << sender.transferRate; - qDebug() << "receive rate:" << reader.totalBytesRead * 1000 / elapsedTime + qDebug() << "tst_QNetworkReply::rateControl" << "send rate:" << sender.transferRate; + qDebug() << "tst_QNetworkReply::rateControl" << "receive rate:" << reader.totalBytesRead * 1000 / elapsedTime << "(it received" << reader.totalBytesRead << "bytes in" << elapsedTime << "ms)"; sender.wait(); @@ -2523,23 +3040,54 @@ void tst_QNetworkReply::downloadPerformance() sender.wait(); qint64 receivedBytes = reader.totalBytes; - qDebug() << "receive rate:" << (receivedBytes * 1000 / elapsedTime / 1024) << "kB/s and" + qDebug() << "tst_QNetworkReply::downloadPerformance" << "receive rate:" << (receivedBytes * 1000 / elapsedTime / 1024) << "kB/s and" << elapsedTime << "ms"; } void tst_QNetworkReply::uploadPerformance() { - ThreadedDataReader reader; - DataGenerator generator; - QNetworkRequest request("debugpipe://127.0.0.1:" + QString::number(reader.serverPort()) + "/?bare=1"); - QNetworkReplyPtr reply = manager.put(request, &generator); + ThreadedDataReader reader; + DataGenerator generator; - connect(&reader, SIGNAL(finished()), &QTestEventLoop::instance(), SLOT(exitLoop())); - QTimer::singleShot(5000, &generator, SLOT(stop())); - generator.start(); - QTestEventLoop::instance().enterLoop(40); + + QNetworkRequest request("debugpipe://127.0.0.1:" + QString::number(reader.serverPort()) + "/?bare=1"); + QNetworkReplyPtr reply = manager.put(request, &generator); + generator.start(); + connect(&reader, SIGNAL(finished()), &QTestEventLoop::instance(), SLOT(exitLoop())); + QTimer::singleShot(5000, &generator, SLOT(stop())); + + QTestEventLoop::instance().enterLoop(10); + QVERIFY(!QTestEventLoop::instance().timeout()); +} + +void tst_QNetworkReply::httpUploadPerformance() +{ + enum {UploadSize = 1000*1024*1024}; // 1000 MB + ThreadedDataReaderHttpServer reader; + FixedSizeDataGenerator generator(UploadSize); + + QNetworkRequest request(QUrl("http://127.0.0.1:" + QString::number(reader.serverPort()) + "/?bare=1")); + request.setHeader(QNetworkRequest::ContentLengthHeader,UploadSize); + + QNetworkReplyPtr reply = manager.put(request, &generator); + + connect(reply, SIGNAL(finished()), &QTestEventLoop::instance(), SLOT(exitLoop())); + + QTime time; + generator.start(); + time.start(); + QTestEventLoop::instance().enterLoop(40); + QVERIFY(!QTestEventLoop::instance().timeout()); + + qint64 elapsed = time.elapsed(); + qWarning() << "tst_QNetworkReply::httpUploadPerformance" << elapsed << "msec, " + << ((UploadSize/1024.0)/(elapsed/1000.0)) << " kB/sec"; + + reader.exit(); + reader.wait(3000); } + void tst_QNetworkReply::performanceControlRate() { // this is a control comparison for the other two above @@ -2560,7 +3108,7 @@ void tst_QNetworkReply::performanceControlRate() sender.wait(); qint64 receivedBytes = reader.totalBytes; - qDebug() << "receive rate:" << (receivedBytes * 1000 / elapsedTime / 1024) << "kB/s and" + qDebug() << "tst_QNetworkReply::performanceControlRate" << "receive rate:" << (receivedBytes * 1000 / elapsedTime / 1024) << "kB/s and" << elapsedTime << "ms"; } @@ -2592,6 +3140,7 @@ void tst_QNetworkReply::downloadProgress() QByteArray data(128, 'a'); QTcpSocket *sender = server.nextPendingConnection(); + QVERIFY(sender); QFETCH(int, loopCount); for (int i = 1; i <= loopCount; ++i) { diff --git a/tests/auto/qringbuffer/qringbuffer.pro b/tests/auto/qringbuffer/qringbuffer.pro new file mode 100644 index 0000000..91fb0a0 --- /dev/null +++ b/tests/auto/qringbuffer/qringbuffer.pro @@ -0,0 +1,6 @@ +load(qttest_p4) +SOURCES += tst_qringbuffer.cpp + +QT = core + + diff --git a/tests/auto/qringbuffer/tst_qringbuffer.cpp b/tests/auto/qringbuffer/tst_qringbuffer.cpp new file mode 100644 index 0000000..c741c2e --- /dev/null +++ b/tests/auto/qringbuffer/tst_qringbuffer.cpp @@ -0,0 +1,200 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** 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 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtTest/QtTest> + +#include <private/qringbuffer_p.h> + +class tst_QRingBuffer : public QObject +{ + Q_OBJECT + +public: + tst_QRingBuffer(); + virtual ~tst_QRingBuffer(); +public slots: + void initTestCase(); + void cleanupTestCase(); +private slots: + void readPointerAtPositionWriteRead(); + void readPointerAtPositionEmptyRead(); + void readPointerAtPositionWithHead(); + void readPointerAtPositionReadTooMuch(); + void sizeWhenEmpty(); + void sizeWhenReservedAndChopped(); + void sizeWhenReserved(); +}; + +tst_QRingBuffer::tst_QRingBuffer() +{ +} + +tst_QRingBuffer::~tst_QRingBuffer() +{ +} + +void tst_QRingBuffer::initTestCase() +{ +} + +void tst_QRingBuffer::cleanupTestCase() +{ +} + +void tst_QRingBuffer::sizeWhenReserved() +{ + QRingBuffer ringBuffer; + ringBuffer.reserve(5); + + QCOMPARE(ringBuffer.size(), 5); +} + +void tst_QRingBuffer::sizeWhenReservedAndChopped() +{ + QRingBuffer ringBuffer; + ringBuffer.reserve(31337); + ringBuffer.chop(31337); + + QCOMPARE(ringBuffer.size(), 0); +} + +void tst_QRingBuffer::sizeWhenEmpty() +{ + QRingBuffer ringBuffer; + + QCOMPARE(ringBuffer.size(), 0); +} + +void tst_QRingBuffer::readPointerAtPositionReadTooMuch() +{ + QRingBuffer ringBuffer; + + qint64 length; + const char *buf = ringBuffer.readPointerAtPosition(42, length); + QVERIFY(buf == 0); + QVERIFY(length == 0); +} + +void tst_QRingBuffer::readPointerAtPositionWithHead() +{ + QRingBuffer ringBuffer; + char *buf = ringBuffer.reserve(4); + memcpy (buf, "0123", 4); + ringBuffer.free(2); + + // ringBuffer should have stayed the same except + // its head it had moved to position 2 + qint64 length; + const char* buf2 = ringBuffer.readPointerAtPosition(0, length); + + QCOMPARE(length, qint64(2)); + QVERIFY(*buf2 == '2'); + QVERIFY(*(buf2+1) == '3'); + + // advance 2 more, ringBuffer should be empty then + ringBuffer.free(2); + buf2 = ringBuffer.readPointerAtPosition(0, length); + QCOMPARE(length, qint64(0)); + QVERIFY(buf2 == 0); +} + +void tst_QRingBuffer::readPointerAtPositionEmptyRead() +{ + QRingBuffer ringBuffer; + + qint64 length; + const char *buf = ringBuffer.readPointerAtPosition(0, length); + QVERIFY(buf == 0); + QVERIFY(length == 0); +} + +void tst_QRingBuffer::readPointerAtPositionWriteRead() +{ + //create some data + QBuffer inData; + inData.open(QIODevice::ReadWrite); + inData.putChar(0x42); + inData.putChar(0x23); + inData.write("Qt rocks!"); + for (int i = 0; i < 5000; i++) + inData.write(QString("Number %1").arg(i).toUtf8()); + inData.reset(); + QVERIFY(inData.size() > 0); + + //put the inData in the QRingBuffer + QRingBuffer ringBuffer; + qint64 remaining = inData.size(); + while (remaining > 0) { + // write in chunks of 50 bytes + // this ensures there will be multiple QByteArrays inside the QRingBuffer + // since QRingBuffer is then only using individual arrays of around 4000 bytes + qint64 thisWrite = qMin(remaining, qint64(50)); + char *pos = ringBuffer.reserve(thisWrite); + inData.read(pos, thisWrite); + remaining -= thisWrite; + } + // was data put into it? + QVERIFY(ringBuffer.size() > 0); + QCOMPARE(qint64(ringBuffer.size()), inData.size()); + + //read from the QRingBuffer in loop, put back into another QBuffer + QBuffer outData; + outData.open(QIODevice::ReadWrite); + remaining = ringBuffer.size(); + while (remaining > 0) { + qint64 thisRead; + // always try to read as much as possible + const char *buf = ringBuffer.readPointerAtPosition(ringBuffer.size() - remaining, thisRead); + outData.write(buf, thisRead); + remaining -= thisRead; + } + outData.reset(); + + QVERIFY(outData.size() > 0); + + // was the data read from the QRingBuffer the same as the one written into it? + QCOMPARE(outData.size(), inData.size()); + QVERIFY(outData.buffer().startsWith(inData.buffer())); +} + + +QTEST_APPLESS_MAIN(tst_QRingBuffer) +#include "tst_qringbuffer.moc" diff --git a/tests/auto/qsqlquery/tst_qsqlquery.cpp b/tests/auto/qsqlquery/tst_qsqlquery.cpp index 074f16f..7f97972 100644 --- a/tests/auto/qsqlquery/tst_qsqlquery.cpp +++ b/tests/auto/qsqlquery/tst_qsqlquery.cpp @@ -178,9 +178,11 @@ private slots: void task_217003_data() { generic_data(); } void task_217003(); #endif - void task_250026_data() { generic_data("QODBC"); } void task_250026(); + void task_205701_data() { generic_data("QMYSQL"); } + void task_205701(); + private: @@ -297,7 +299,7 @@ void tst_QSqlQuery::dropTestTables( QSqlDatabase db ) #ifdef NOT_READY_YET tablenames << qTableName( "Planet" ); #endif - tablenames << qTableName( "task_250026" ); + tablenames << qTableName( "task_250026" ); tst_Databases::safeDropTables( db, tablenames ); } @@ -2711,5 +2713,21 @@ void tst_QSqlQuery::task_250026() QCOMPARE( q.value( 0 ).toString().length(), data1026.length() ); } +void tst_QSqlQuery::task_205701() +{ + QSqlDatabase qsdb = QSqlDatabase::addDatabase("QMYSQL", "atest"); + qsdb.setHostName("test"); + qsdb.setDatabaseName("test"); + qsdb.setUserName("test"); + qsdb.setPassword("test"); + qsdb.open(); + +// { + QSqlQuery query(qsdb); +// } + QSqlDatabase::removeDatabase("atest"); +} + + QTEST_MAIN( tst_QSqlQuery ) #include "tst_qsqlquery.moc" diff --git a/tests/auto/qsslsocket/tst_qsslsocket.cpp b/tests/auto/qsslsocket/tst_qsslsocket.cpp index b9725fd..432092a 100644 --- a/tests/auto/qsslsocket/tst_qsslsocket.cpp +++ b/tests/auto/qsslsocket/tst_qsslsocket.cpp @@ -1286,6 +1286,8 @@ protected: // delayed start of encryption QTest::qSleep(100); QSslSocket *socket = server.socket; + Q_ASSERT(socket); + Q_ASSERT(socket->isValid()); socket->ignoreSslErrors(); socket->startServerEncryption(); if (!socket->waitForEncrypted(2000)) diff --git a/tests/auto/qtreewidget/tst_qtreewidget.cpp b/tests/auto/qtreewidget/tst_qtreewidget.cpp index c3595c2..906332c 100644 --- a/tests/auto/qtreewidget/tst_qtreewidget.cpp +++ b/tests/auto/qtreewidget/tst_qtreewidget.cpp @@ -136,6 +136,7 @@ private slots: void rootItemFlags(); void task218661_setHeaderData(); void task245280_sortChildren(); + void task253109_itemHeight(); // QTreeWidgetItem void itemOperatorLessThan(); @@ -2879,6 +2880,25 @@ void tst_QTreeWidget::task245280_sortChildren() QCOMPARE(top.child(i)->text(1), QString::number(i)); } +void tst_QTreeWidget::task253109_itemHeight() +{ + QTreeWidget treeWidget; + treeWidget.setColumnCount(1); + treeWidget.show(); + QTest::qWait(200); + + QTreeWidgetItem item(&treeWidget); + class MyWidget : public QWidget + { + virtual QSize sizeHint() const { return QSize(200,100); } + } w; + treeWidget.setItemWidget(&item, 0, &w); + + QTest::qWait(200); + QCOMPARE(w.geometry(), treeWidget.visualItemRect(&item)); + +} + void tst_QTreeWidget::task206367_duplication() { QTreeWidget treeWidget; |