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 <QObject>
0008 #include <QtTest>
0009 #include <net/poll.h>
0010 #include <torrent/globals.h>
0011 #include <unistd.h>
0012 #include <util/bitset.h>
0013 #include <util/log.h>
0014 #include <utp/utpserver.h>
0015 #include <utp/utpsocket.h>
0016 
0017 using namespace utp;
0018 using namespace net;
0019 using namespace bt;
0020 
0021 #define NUM_SOCKETS 20
0022 
0023 class UTPPollTest : public QEventLoop
0024 {
0025 public:
0026     void accepted()
0027     {
0028         utp::Connection::Ptr conn = bt::Globals::instance().getUTPServer().acceptedConnection();
0029         incoming[num_accepted++] = new UTPSocket(conn);
0030         Out(SYS_UTP | LOG_DEBUG) << "Accepted " << num_accepted << endl;
0031         if (num_accepted >= NUM_SOCKETS)
0032             exit();
0033     }
0034 
0035     void doConnect()
0036     {
0037         for (int i = 0; i < NUM_SOCKETS; i++) {
0038             outgoing[i] = new UTPSocket();
0039             outgoing[i]->setBlocking(false);
0040             outgoing[i]->connectTo(net::Address("127.0.0.1", port));
0041         }
0042     }
0043 
0044     void endEventLoop()
0045     {
0046         exit();
0047     }
0048 
0049 private:
0050     void initTestCase()
0051     {
0052         bt::InitLog("utppolltest.log");
0053 
0054         port = 50000;
0055         while (port < 60000) {
0056             if (!bt::Globals::instance().initUTPServer(port))
0057                 port++;
0058             else
0059                 break;
0060         }
0061 
0062         bt::Globals::instance().getUTPServer().setCreateSockets(false);
0063         num_accepted = 0;
0064         for (int i = 0; i < NUM_SOCKETS; i++) {
0065             outgoing[i] = incoming[i] = nullptr;
0066         }
0067     }
0068 
0069     void cleanupTestCase()
0070     {
0071         bt::Globals::instance().shutdownUTPServer();
0072         for (int i = 0; i < NUM_SOCKETS; i++) {
0073             delete outgoing[i];
0074             delete incoming[i];
0075         }
0076     }
0077 
0078     void testPollConnect()
0079     {
0080         poller.reset();
0081         Out(SYS_UTP | LOG_DEBUG) << "testPollConnect " << endl;
0082         utp::UTPSocket s;
0083         s.setBlocking(false);
0084         s.connectTo(net::Address("127.0.0.1", port));
0085         s.prepare(&poller, Poll::OUTPUT);
0086         QVERIFY(poller.poll() > 0);
0087         QVERIFY(s.ready(&poller, Poll::OUTPUT));
0088         QVERIFY(s.connectSuccesFull());
0089         poller.reset();
0090 
0091         // Purge accepted connection
0092         utp::UTPServer &srv = bt::Globals::instance().getUTPServer();
0093         srv.acceptedConnection();
0094     }
0095 
0096     void testConnect()
0097     {
0098         Out(SYS_UTP | LOG_DEBUG) << "testConnect " << endl;
0099         utp::UTPServer &srv = bt::Globals::instance().getUTPServer();
0100         connect(&srv, &UTPServer::accepted, this, &UTPPollTest::accepted, Qt::QueuedConnection);
0101 
0102         QTimer::singleShot(0, this, &UTPPollTest::doConnect);
0103         QTimer::singleShot(5000, this, &UTPPollTest::endEventLoop); // use a 5 second timeout
0104         exec();
0105         QVERIFY(num_accepted == NUM_SOCKETS);
0106         for (int i = 0; i < num_accepted; i++) {
0107             Out(SYS_UTP | LOG_DEBUG) << "Check OK incoming " << i << endl;
0108             QVERIFY(incoming[i]->ok());
0109         }
0110     }
0111 
0112     void testPollInput()
0113     {
0114         Out(SYS_UTP | LOG_DEBUG) << "testPollInput " << endl;
0115         char test[] = "test\n";
0116 
0117         bt::BitSet bs(NUM_SOCKETS);
0118         poller.reset();
0119         while (!bs.allOn()) {
0120             for (int i = 0; i < NUM_SOCKETS; i++) {
0121                 if (!bs.get(i))
0122                     outgoing[i]->prepare(&poller, net::Poll::OUTPUT);
0123             }
0124 
0125             QVERIFY(poller.poll(1000) > 0);
0126             for (int i = 0; i < NUM_SOCKETS; i++) {
0127                 if (bs.get(i) || !outgoing[i]->ready(&poller, net::Poll::OUTPUT))
0128                     continue;
0129 
0130                 int ret = outgoing[i]->send((const bt::Uint8 *)test, strlen(test));
0131                 QVERIFY(ret == (int)strlen(test));
0132                 bs.set(i, true);
0133             }
0134         }
0135 
0136         bs.setAll(false);
0137 
0138         while (!bs.allOn()) {
0139             poller.reset();
0140             for (int i = 0; i < NUM_SOCKETS; i++)
0141                 if (!bs.get(i))
0142                     incoming[i]->prepare(&poller, Poll::INPUT);
0143 
0144             Out(SYS_GEN | LOG_DEBUG) << "Entering poll" << endl;
0145             QVERIFY(poller.poll(1000) > 0);
0146             for (int i = 0; i < NUM_SOCKETS; i++) {
0147                 if (!bs.get(i) && incoming[i]->ready(&poller, net::Poll::INPUT)) {
0148                     bt::Uint8 tmp[20];
0149                     QVERIFY(incoming[i]->recv(tmp, 20) == (int)strlen(test));
0150                     QVERIFY(memcmp(tmp, test, strlen(test)) == 0);
0151                     bs.set(i, true);
0152                 }
0153             }
0154         }
0155 
0156         poller.reset();
0157         QVERIFY(bs.allOn());
0158     }
0159 
0160     void testPollOutput()
0161     {
0162         poller.reset();
0163         Out(SYS_UTP | LOG_DEBUG) << "testPollOutput " << endl;
0164         for (int i = 0; i < NUM_SOCKETS; i++) {
0165             incoming[i]->prepare(&poller, Poll::OUTPUT);
0166         }
0167 
0168         QVERIFY(poller.poll(10000) > 0);
0169         for (int i = 0; i < NUM_SOCKETS; i++) {
0170             QVERIFY(incoming[i]->ready(&poller, Poll::OUTPUT));
0171         }
0172 
0173         poller.reset();
0174     }
0175 
0176     void testPollClose()
0177     {
0178         Out(SYS_UTP | LOG_DEBUG) << "testPollClose " << endl;
0179         for (int i = 0; i < NUM_SOCKETS; i++) {
0180             incoming[i]->close();
0181             outgoing[i]->prepare(&poller, net::Poll::INPUT);
0182         }
0183 
0184         QVERIFY(poller.poll() > 0);
0185         poller.reset();
0186     }
0187 
0188 private:
0189     int port;
0190     utp::UTPSocket *outgoing[NUM_SOCKETS];
0191     utp::UTPSocket *incoming[NUM_SOCKETS];
0192     int num_accepted;
0193     Poll poller;
0194 };
0195 
0196 QTEST_MAIN(UTPPollTest)