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"