File indexing completed on 2025-01-05 04:37:32
0001 /* 0002 SPDX-FileCopyrightText: 2010 Joris Guisson <joris.guisson@gmail.com> 0003 0004 SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 0007 #include <QFile> 0008 #include <QObject> 0009 #include <QTextStream> 0010 #include <QtTest> 0011 #include <unistd.h> 0012 #include <util/functions.h> 0013 #include <util/log.h> 0014 #include <util/sha1hash.h> 0015 #include <util/sha1hashgen.h> 0016 #include <utp/connection.h> 0017 #include <utp/utpserver.h> 0018 #include <utp/utpsocket.h> 0019 0020 #define BYTES_TO_SEND 100 * 1024 * 1024 0021 0022 using namespace utp; 0023 using namespace bt; 0024 0025 static QByteArray Generate(int size) 0026 { 0027 QByteArray ba(size, 0); 0028 /* for (int i = 0;i < size;i+=4) 0029 { 0030 ba[i] = 'A'; 0031 ba[i+1] = 'B'; 0032 ba[i+2] = 'C'; 0033 ba[i+3] = 'D'; 0034 } 0035 */ 0036 for (int i = 0; i < size; i++) { 0037 ba[i] = i % 256; 0038 } 0039 return ba; 0040 } 0041 /* 0042 static void Dump(const bt::Uint8* pkt, bt::Uint32 size,const QString & file) 0043 { 0044 QFile fptr(file); 0045 if (fptr.open(QIODevice::Text|QIODevice::WriteOnly)) 0046 { 0047 QTextStream out(&fptr); 0048 out << "Packet: " << size << ::endl; 0049 out << "Hash: " << bt::SHA1Hash::generate(pkt,size).toString() << ::endl; 0050 0051 for (bt::Uint32 i = 0;i < size;i+=4) 0052 { 0053 if (i > 0 && i % 32 == 0) 0054 out << ::endl; 0055 0056 out << QString("%1%2%3%4 ") 0057 .arg(pkt[i],2,16) 0058 .arg(pkt[i+1],2,16) 0059 .arg(pkt[i+2],2,16) 0060 .arg(pkt[i+3],2,16); 0061 } 0062 0063 out << ::endl << ::endl << ::endl; 0064 } 0065 } 0066 */ 0067 0068 class SendThread : public QThread 0069 { 0070 public: 0071 SendThread(Connection::Ptr outgoing, UTPServer &srv, QObject *parent = nullptr) 0072 : QThread(parent) 0073 , outgoing(outgoing) 0074 , srv(srv) 0075 { 0076 } 0077 0078 void run() override 0079 { 0080 int step = 64 * 1024; 0081 QByteArray data = Generate(step); 0082 bt::SHA1HashGen hgen; 0083 0084 bt::Int64 sent = 0; 0085 int off = 0; 0086 net::Poll poller; 0087 while (sent < BYTES_TO_SEND && outgoing->connectionState() != CS_CLOSED) { 0088 int to_send = step - off; 0089 int ret = outgoing->send((const bt::Uint8 *)data.data() + off, to_send); 0090 if (ret > 0) { 0091 hgen.update((const bt::Uint8 *)data.data() + off, ret); 0092 sent += ret; 0093 off += ret; 0094 off = off % step; 0095 // Out(SYS_UTP|LOG_DEBUG) << "Transmitted " << sent << endl; 0096 } else if (ret == 0) { 0097 srv.preparePolling(&poller, net::Poll::OUTPUT, outgoing); 0098 poller.poll(1000); 0099 } else { 0100 break; 0101 } 0102 } 0103 0104 sleep(2); 0105 Out(SYS_UTP | LOG_DEBUG) << "Transmitted " << sent << endl; 0106 outgoing->dumpStats(); 0107 outgoing->close(); 0108 hgen.end(); 0109 sent_hash = hgen.get(); 0110 } 0111 0112 Connection::Ptr outgoing; 0113 bt::SHA1Hash sent_hash; 0114 UTPServer &srv; 0115 }; 0116 0117 class TransmitTest : public QEventLoop 0118 { 0119 Q_OBJECT 0120 public: 0121 TransmitTest(QObject *parent = nullptr) 0122 : QEventLoop(parent) 0123 { 0124 } 0125 0126 void accepted() 0127 { 0128 incoming = srv.acceptedConnection().toStrongRef(); 0129 incoming->setBlocking(true); 0130 exit(); 0131 } 0132 0133 void startConnect() 0134 { 0135 net::Address addr("127.0.0.1", port); 0136 outgoing = srv.connectTo(addr); 0137 outgoing->setBlocking(true); 0138 } 0139 0140 void endEventLoop() 0141 { 0142 exit(); 0143 } 0144 0145 private Q_SLOTS: 0146 void initTestCase() 0147 { 0148 bt::InitLog("transmittest.log", false, true, false); 0149 0150 port = 50000; 0151 while (port < 60000) { 0152 if (!srv.changePort(port)) 0153 port++; 0154 else 0155 break; 0156 } 0157 0158 srv.setCreateSockets(false); 0159 srv.start(); 0160 } 0161 0162 void cleanupTestCase() 0163 { 0164 srv.stop(); 0165 } 0166 0167 void testConnect() 0168 { 0169 connect(&srv, &utp::UTPServer::accepted, this, &TransmitTest::accepted, Qt::QueuedConnection); 0170 QTimer::singleShot(0, this, &TransmitTest::startConnect); 0171 QTimer::singleShot(5000, this, &TransmitTest::endEventLoop); // use a 5 second timeout 0172 exec(); 0173 QVERIFY(outgoing); 0174 QVERIFY(incoming); 0175 QVERIFY(incoming->connectionState() == CS_CONNECTED); 0176 if (outgoing->connectionState() != CS_CONNECTED) 0177 QVERIFY(outgoing->waitUntilConnected()); 0178 QVERIFY(outgoing->connectionState() == CS_CONNECTED); 0179 } 0180 0181 void testThreaded() 0182 { 0183 bt::Out(SYS_UTP | LOG_DEBUG) << "testThreaded" << bt::endl; 0184 if (outgoing->connectionState() != CS_CONNECTED || incoming->connectionState() != CS_CONNECTED) { 0185 QSKIP("Not Connected", SkipAll); 0186 return; 0187 } 0188 0189 bt::SHA1HashGen hgen; 0190 0191 SendThread st(outgoing, srv); 0192 st.start(); // The thread will start sending a whole bunch of data 0193 bt::Int64 received = 0; 0194 // int failures = 0; 0195 incoming->setBlocking(true); 0196 while (received < BYTES_TO_SEND && incoming->connectionState() != CS_CLOSED) { 0197 bt::Uint32 ba = incoming->bytesAvailable(); 0198 if (ba > 0) { 0199 // failures = 0; 0200 QByteArray data(ba, 0); 0201 int to_read = ba; //;qMin<bt::Uint32>(1024,ba); 0202 int ret = incoming->recv((bt::Uint8 *)data.data(), to_read); 0203 QVERIFY(ret == to_read); 0204 if (ret > 0) { 0205 hgen.update((bt::Uint8 *)data.data(), ret); 0206 received += ret; 0207 // Out(SYS_UTP|LOG_DEBUG) << "Received " << received << endl; 0208 } 0209 } else if (incoming->connectionState() != CS_CLOSED) { 0210 incoming->waitForData(1000); 0211 } 0212 } 0213 0214 st.wait(); 0215 Out(SYS_UTP | LOG_DEBUG) << "Received " << received << endl; 0216 incoming->dumpStats(); 0217 QVERIFY(incoming->bytesAvailable() == 0); 0218 QVERIFY(outgoing->allDataSent()); 0219 QVERIFY(received >= BYTES_TO_SEND); 0220 0221 hgen.end(); 0222 SHA1Hash rhash = hgen.get(); 0223 Out(SYS_UTP | LOG_DEBUG) << "Received data hash: " << rhash.toString() << endl; 0224 Out(SYS_UTP | LOG_DEBUG) << "Sent data hash: " << st.sent_hash.toString() << endl; 0225 QVERIFY(rhash == st.sent_hash); 0226 } 0227 0228 private: 0229 Connection::Ptr incoming; 0230 Connection::Ptr outgoing; 0231 utp::UTPServer srv; 0232 int port; 0233 }; 0234 0235 QTEST_MAIN(TransmitTest) 0236 0237 #include "transmittest.moc"