File indexing completed on 2025-01-05 04:37:09

0001 /*
0002     SPDX-FileCopyrightText: 2012 Joris Guisson <joris.guisson@gmail.com>
0003 
0004     SPDX-License-Identifier: GPL-2.0-or-later
0005 */
0006 
0007 #include <QtTest>
0008 #include <bcodec/bdecoder.h>
0009 #include <bcodec/bnode.h>
0010 #include <dht/errmsg.h>
0011 #include <dht/rpcmsg.h>
0012 #include <dht/rpcmsgfactory.h>
0013 #include <util/error.h>
0014 #include <util/log.h>
0015 
0016 class RPCMsgTest : public QObject, public dht::RPCMethodResolver
0017 {
0018     Q_OBJECT
0019 private:
0020     dht::Method findMethod(const QByteArray &mtid) override
0021     {
0022         Q_UNUSED(mtid);
0023         return current_method;
0024     }
0025 
0026 private Q_SLOTS:
0027     void initTestCase()
0028     {
0029         bt::InitLog("rpcmsgtest.log", false, true);
0030     }
0031 
0032     void cleanupTestCase()
0033     {
0034     }
0035 
0036     void testErrMsg()
0037     {
0038         const char *msg = "d1:eli201e23:A Generic Error Ocurrede1:t2:aa1:y1:ee";
0039 
0040         try {
0041             bt::BDecoder dec(QByteArray(msg), false);
0042 
0043             QScopedPointer<bt::BDictNode> dict(dec.decodeDict());
0044             dht::RPCMsg::Ptr msg = factory.build(dict.data(), nullptr);
0045 
0046             QVERIFY(msg->getType() == dht::ERR_MSG);
0047             dht::ErrMsg::Ptr err = msg.dynamicCast<dht::ErrMsg>();
0048             QVERIFY(err);
0049             QVERIFY(err->message() == "A Generic Error Ocurred");
0050             QVERIFY(err->getMTID() == QByteArray("aa"));
0051 
0052         } catch (bt::Error &e) {
0053             QFAIL(e.toString().toLocal8Bit().data());
0054         }
0055     }
0056 
0057     void testWrongErrMsg()
0058     {
0059         const char *msg[] = {"d1:t2:aa1:y1:ee", "d1:eli201e1:t2:aa1:y1:ee", nullptr};
0060 
0061         int idx = 0;
0062         while (msg[idx]) {
0063             bt::BDecoder dec(QByteArray(msg[idx]), false);
0064             QScopedPointer<bt::BDictNode> dict(dec.decodeDict());
0065             try {
0066                 dht::RPCMsg::Ptr msg = factory.build(dict.data(), this);
0067                 QFAIL("No exception thrown");
0068             } catch (bt::Error &) {
0069                 // OK
0070             }
0071             idx++;
0072         }
0073     }
0074 
0075     void testPing()
0076     {
0077         const char *msg[] = {"d1:ad2:id20:abcdefghij0123456789e1:q4:ping1:t2:aa1:y1:qe", "d1:rd2:id20:mnopqrstuvwxyz123456e1:t2:aa1:y1:re", nullptr};
0078         current_method = dht::PING;
0079 
0080         int idx = 0;
0081         while (msg[idx]) {
0082             bt::BDecoder dec(QByteArray(msg[idx]), false);
0083             QScopedPointer<bt::BDictNode> dict(dec.decodeDict());
0084             try {
0085                 dht::RPCMsg::Ptr msg = factory.build(dict.data(), this);
0086                 QVERIFY(msg);
0087                 QVERIFY(msg->getMTID() == QByteArray("aa"));
0088                 QVERIFY(msg->getMethod() == dht::PING);
0089             } catch (bt::Error &e) {
0090                 QFAIL(e.toString().toLocal8Bit().data());
0091             }
0092             idx++;
0093         }
0094     }
0095 
0096     void testFindNode()
0097     {
0098         const char *msg[] = {"d1:ad2:id20:abcdefghij01234567896:target20:mnopqrstuvwxyz123456e1:q9:find_node1:t2:aa1:y1:qe",
0099                              "d1:rd2:id20:0123456789abcdefghij5:nodes9:def456...e1:t2:aa1:y1:re",
0100                              nullptr};
0101 
0102         current_method = dht::FIND_NODE;
0103 
0104         int idx = 0;
0105         while (msg[idx]) {
0106             bt::BDecoder dec(QByteArray(msg[idx]), false);
0107             QScopedPointer<bt::BDictNode> dict(dec.decodeDict());
0108             try {
0109                 dht::RPCMsg::Ptr msg = factory.build(dict.data(), this);
0110                 QVERIFY(msg);
0111                 QVERIFY(msg->getMTID() == QByteArray("aa"));
0112                 QVERIFY(msg->getMethod() == dht::FIND_NODE);
0113             } catch (bt::Error &e) {
0114                 QFAIL(e.toString().toLocal8Bit().data());
0115             }
0116             idx++;
0117         }
0118     }
0119 
0120     void testGetPeers()
0121     {
0122         const char *msg[] = {"d1:ad2:id20:abcdefghij01234567899:info_hash20:mnopqrstuvwxyz123456e1:q9:get_peers1:t2:aa1:y1:qe",
0123                              "d1:rd2:id20:abcdefghij01234567895:token8:aoeusnth6:valuesl6:axje.u6:idhtnmee1:t2:aa1:y1:re",
0124                              "d1:rd2:id20:abcdefghij01234567895:nodes9:def456...5:token8:aoeusnthe1:t2:aa1:y1:re",
0125                              nullptr};
0126         current_method = dht::GET_PEERS;
0127 
0128         int idx = 0;
0129         while (msg[idx]) {
0130             bt::BDecoder dec(QByteArray(msg[idx]), false);
0131             QScopedPointer<bt::BDictNode> dict(dec.decodeDict());
0132             try {
0133                 dht::RPCMsg::Ptr msg = factory.build(dict.data(), this);
0134                 QVERIFY(msg);
0135                 QVERIFY(msg->getMTID() == QByteArray("aa"));
0136                 QVERIFY(msg->getMethod() == dht::GET_PEERS);
0137             } catch (bt::Error &e) {
0138                 QFAIL(e.toString().toLocal8Bit().data());
0139             }
0140             idx++;
0141         }
0142     }
0143 
0144     void testAnnounce()
0145     {
0146         const char *msg[] = {
0147             "d1:ad2:id20:abcdefghij01234567899:info_hash20:mnopqrstuvwxyz1234564:porti6881e5:token8:aoeusnthe1:q13:announce_peer1:t2:aa1:y1:qe",
0148             "d1:rd2:id20:mnopqrstuvwxyz123456e1:t2:aa1:y1:re",
0149             nullptr};
0150         current_method = dht::ANNOUNCE_PEER;
0151         int idx = 0;
0152         while (msg[idx]) {
0153             bt::BDecoder dec(QByteArray(msg[idx]), false);
0154             QScopedPointer<bt::BDictNode> dict(dec.decodeDict());
0155             try {
0156                 dht::RPCMsg::Ptr msg = factory.build(dict.data(), this);
0157                 QVERIFY(msg);
0158                 QVERIFY(msg->getMTID() == QByteArray("aa"));
0159                 QVERIFY(msg->getMethod() == dht::ANNOUNCE_PEER);
0160             } catch (bt::Error &e) {
0161                 QFAIL(e.toString().toLocal8Bit().data());
0162             }
0163             idx++;
0164         }
0165     }
0166 
0167 private:
0168     dht::RPCMsgFactory factory;
0169     dht::Method current_method;
0170 };
0171 
0172 QTEST_MAIN(RPCMsgTest)
0173 
0174 #include "rpcmsgtest.moc"