File indexing completed on 2025-01-05 04:37:31
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 <QObject> 0008 #include <QtTest> 0009 0010 #include <ctime> 0011 #include <unistd.h> 0012 #include <util/functions.h> 0013 #include <util/log.h> 0014 #include <utp/connection.h> 0015 #include <utp/utpserver.h> 0016 #include <utp/utpsocket.h> 0017 0018 #define PACKETS_TO_SEND 20 0019 #define TEST_DATA "This is the packet loss test\n" 0020 0021 using namespace utp; 0022 using namespace bt; 0023 0024 /** 0025 Server which simulates packet loss 0026 */ 0027 class CongestionTestServer : public UTPServer 0028 { 0029 Q_OBJECT 0030 public: 0031 CongestionTestServer(QObject *parent = nullptr) 0032 : UTPServer(parent) 0033 , congestion_delay(200) 0034 { 0035 } 0036 0037 virtual ~CongestionTestServer() 0038 { 0039 } 0040 0041 virtual bool sendTo(const QByteArray &data, const net::Address &addr) 0042 { 0043 } 0044 0045 virtual bool sendTo(const bt::Uint8 *data, const bt::Uint32 size, const net::Address &addr) 0046 { 0047 } 0048 0049 void setCongestionDelay(int cd) 0050 { 0051 congestion_delay = cd; 0052 } 0053 0054 public: 0055 void delayedSend() 0056 { 0057 } 0058 0059 private: 0060 int congestion_delay; 0061 }; 0062 0063 class SendThread : public QThread 0064 { 0065 public: 0066 SendThread(Connection::Ptr outgoing, QObject *parent = nullptr) 0067 : QThread(parent) 0068 , outgoing(outgoing) 0069 { 0070 } 0071 0072 virtual void run() 0073 { 0074 char test[] = TEST_DATA; 0075 int sent = 0; 0076 while (sent < PACKETS_TO_SEND) { 0077 int ret = outgoing->send((const bt::Uint8 *)test, strlen(test)); 0078 if (ret > 0) { 0079 sent++; 0080 } 0081 0082 msleep(200); 0083 } 0084 0085 while (!outgoing->allDataSent()) 0086 sleep(1); 0087 0088 Out(SYS_UTP | LOG_DEBUG) << "Transmitted " << sent << " packets " << endl; 0089 outgoing->dumpStats(); 0090 } 0091 0092 Connection::Ptr outgoing; 0093 }; 0094 0095 class CongestionTest : public QEventLoop 0096 { 0097 public: 0098 CongestionTest(QObject *parent = 0) 0099 : QEventLoop(parent) 0100 { 0101 } 0102 0103 public: 0104 void accepted() 0105 { 0106 incoming = srv.acceptedConnection().toStrongRef(); 0107 exit(); 0108 } 0109 0110 void endEventLoop() 0111 { 0112 exit(); 0113 } 0114 0115 private: 0116 void initTestCase() 0117 { 0118 bt::InitLog("congestiontest.log"); 0119 0120 incoming = outgoing = 0; 0121 port = 50000; 0122 while (port < 60000) { 0123 if (!srv.changePort(port)) 0124 port++; 0125 else 0126 break; 0127 } 0128 0129 srv.setCreateSockets(false); 0130 srv.start(); 0131 } 0132 0133 void cleanupTestCase() 0134 { 0135 srv.stop(); 0136 } 0137 0138 void testConnect() 0139 { 0140 net::Address addr("127.0.0.1", port); 0141 connect(&srv, &CongestionTestServer::accepted, this, &CongestionTest::accepted, Qt::QueuedConnection); 0142 outgoing = srv.connectTo(addr); 0143 QVERIFY(outgoing != 0); 0144 QTimer::singleShot(5000, this, &CongestionTest::endEventLoop); // use a 5 second timeout 0145 exec(); 0146 QVERIFY(incoming != 0); 0147 } 0148 0149 void testCongestionTest() 0150 { 0151 bt::Out(SYS_UTP | LOG_DEBUG) << "testCongestionTest" << bt::endl; 0152 if (outgoing->connectionState() != CS_CONNECTED || incoming->connectionState() != CS_CONNECTED) { 0153 QSKIP("Not Connected", SkipAll); 0154 return; 0155 } 0156 /* 0157 srv.setCongestionTestSimulation(true,0.1); // Drop 10 % of all packets 0158 SendThread st(outgoing); 0159 st.start(); // The thread will start sending a whole bunch of data 0160 int received = 0; 0161 QString received_data; 0162 while (!st.isFinished()) 0163 { 0164 bt::Uint32 ba = incoming->bytesAvailable(); 0165 if (ba > 0) 0166 { 0167 QByteArray data(ba,0); 0168 int ret = incoming->recv((bt::Uint8*)data.data(),ba); 0169 if (ret > 0) 0170 { 0171 received_data.append(data); 0172 received += ret; 0173 } 0174 } 0175 else 0176 { 0177 usleep(50000); 0178 } 0179 } 0180 0181 st.wait(); 0182 Out(SYS_UTP|LOG_DEBUG) << "Received " << received << " bytes:" << endl; 0183 Out(SYS_UTP|LOG_DEBUG) << received_data << endl; 0184 incoming->dumpStats(); 0185 QVERIFY(incoming->bytesAvailable() == 0); 0186 QVERIFY(received_data.count(TEST_DATA) == PACKETS_TO_SEND); 0187 QVERIFY(outgoing->allDataSent()); 0188 */ 0189 } 0190 0191 private: 0192 private: 0193 Connection::Ptr incoming; 0194 Connection::Ptr outgoing; 0195 CongestionTestServer srv; 0196 int port; 0197 }; 0198 0199 QTEST_MAIN(CongestionTest)