BinaryWriterTest.cpp

Go to the documentation of this file.
00001 /*
00002 
00003 Copyright (C) 2006-2007 by Peter Dimov.
00004 
00005 This file is part of Calitko (http://www.calitko.org).
00006 
00007 Calitko is free software; you can redistribute it and/or modify
00008 it under the terms of the GNU General Public License as published by
00009 the Free Software Foundation; either version 2 of the License, or
00010 (at your option) any later version.
00011 
00012 Calitko is distributed in the hope that it will be useful,
00013 but WITHOUT ANY WARRANTY; without even the implied warranty of
00014 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015 GNU General Public License for more details.
00016 
00017 You should have received a copy of the GNU General Public License
00018 along with Calitko; if not, write to the Free Software
00019 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
00020 
00021 */
00022 
00023 #include "Qt.h"
00024 #include "../BinaryWriter.h"
00025 #include "../BinaryReader.h"
00026 #include "../Extensions/QueryExtension.h"
00027 #include "../Extensions/QueryHitsExtension.h"
00028 #include "../Extensions/VendorCode.h"
00029 #include "Imports.cpp"
00030 
00031 namespace Protocols {
00032 namespace Gnutella {
00033 namespace Packets {
00034 namespace Testing {
00035 
00043 class BinaryWriterTest : public CppUnit::TestFixture
00044 {
00045     CPPUNIT_TEST_SUITE(BinaryWriterTest);
00046     CPPUNIT_TEST(testWriteGgepBlock);
00047     CPPUNIT_TEST(testWriteUuid);
00048     CPPUNIT_TEST(testWriteIPv4Address);
00049     CPPUNIT_TEST(testWriteQueryDataOneXml);
00050     CPPUNIT_TEST(testWriteQueryDataOneHuge);
00051     CPPUNIT_TEST(testWriteQueryDataOneUnknown);
00052     CPPUNIT_TEST(testWriteQueryDataOneGgepBlock);
00053     CPPUNIT_TEST(testWriteQueryDataMixed);
00054     CPPUNIT_TEST(testWriteMinSpeed);
00055     CPPUNIT_TEST(testWriteResultSetOneResultOneUrn);
00056     CPPUNIT_TEST(testWriteResultSetOneResultOneGgepBlock);
00057     CPPUNIT_TEST(testWriteResultSetOneResultOnePlainData);
00058     CPPUNIT_TEST(testWriteResultSetOneResultMixedData);
00059     CPPUNIT_TEST(testWriteResultSetTwoResults);
00060     CPPUNIT_TEST(testWriteQueryHitsDataCheckFlagsAllSet);
00061     CPPUNIT_TEST(testWriteQueryHitsDataCheckFlagsPushNotSet);
00062     CPPUNIT_TEST(testWriteQueryHitsDataCheckFlagsBusyNotSet);
00063     CPPUNIT_TEST(testWriteQueryHitsDataCheckFlagsUploadSpeedNotSet);
00064     CPPUNIT_TEST(testWriteQueryHitsDataCheckFlagsHaveUploadedNotSet);
00065     CPPUNIT_TEST(testWriteQueryHitsDataCheckFlagsGgepNotSet);
00066     CPPUNIT_TEST(testWriteQueryHitsDataCheckFlagsNoneSet);
00067     CPPUNIT_TEST(testWriteQueryHitsDataNoGgepBlockNoXmlData);
00068     CPPUNIT_TEST(testWriteQueryHitsDataXmlData);
00069     CPPUNIT_TEST(testWriteQueryHitsDataGgepBlock);
00070     CPPUNIT_TEST(testWriteQueryHitsDataGgepBlockXmlData);
00071     CPPUNIT_TEST(testWriteQueryHitsDataGgepBlockXmlDataOther);
00072     CPPUNIT_TEST_SUITE_END();
00073 
00074 public:
00075     void scenarioWriteUuid (uint l, ushort w1, ushort w2,
00076                             uchar b1, uchar b2, uchar b3, uchar b4,
00077                             uchar b5, uchar b6, uchar b7, uchar b8,
00078                             const QByteArray &rawUuid)
00079     {
00080         QUuid uuid (l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8 );
00081         BinaryWriter writer;
00082         writer.writeUuid (uuid);
00083         CPPUNIT_ASSERT (writer.buffer() == rawUuid);
00084         CPPUNIT_ASSERT (writer.hasWrittenAll() && !writer.hasWrittenPastEnd());
00085     }
00086 
00087     void testWriteUuid()
00088     {
00089         scenarioWriteUuid (0x67c8770b, 0x44f1, 0x410a,
00090                            0xab, 0x9a, 0xf9, 0xb5, 0x44, 0x6f, 0x13, 0xee,
00091                            QByteArray ("\x67\xc8\x77\x0b\x44\xf1\x41\x0a"
00092                                        "\xab\x9a\xf9\xb5\x44\x6f\x13\xee", 16));
00093         scenarioWriteUuid (0x00001111, 0xffff, 0xaaaa,
00094                            0xab, 0xab, 0xf9, 0xb5, 0x44, 0x00, 0xee, 0xff,
00095                            QByteArray ("\x00\x00\x11\x11\xff\xff\xaa\xaa"
00096                                        "\xab\xab\xf9\xb5\x44\x00\xee\xff", 16));
00097         scenarioWriteUuid (0x11111111, 0x3333, 0x5555,
00098                            0xee, 0xff, 0x22, 0x44, 0x66, 0x88, 0x00, 0xcc,
00099                            QByteArray ("\x11\x11\x11\x11\x33\x33\x55\x55"
00100                                        "\xee\xff\x22\x44\x66\x88\x00\xcc", 16));
00101     }
00102 
00103     // the logic is that BinaryReader is right .
00104     void scenarioWriteGgepBlock (QByteArray id, QByteArray rawData, int flags)
00105     {
00106         GgepBlock block;
00107         Ggeps::Unknown ggep (id, rawData, flags);
00108         // Write a block containing the same extension four times:
00109         for(int i = 0; i < 4; ++i)
00110             block.addExtension(ggep);
00111         BinaryWriter writer;
00112         writer.writeGgepBlock(block);
00113         BinaryReader reader (writer.buffer());
00114         GgepBlock readBlock = reader.readGgepBlock();
00115         CPPUNIT_ASSERT (readBlock == block);
00116         CPPUNIT_ASSERT (reader.hasReadAll() && !reader.hasReadPastEnd());
00117     }
00118 
00119     void testWriteGgepBlock()
00120     {
00121         scenarioWriteGgepBlock ("un", "fortest", 0x40);
00122         scenarioWriteGgepBlock ("unknown", "Hi , nice to meet you here^_^!", 0x80);
00123         scenarioWriteGgepBlock ("hehe", QByteArray(), 0x60);
00124     }
00125 
00126     void scenarioWriteIPv4Address (quint32 address)
00127     {
00128         BinaryWriter writer;
00129         QHostAddress qAddress (address);
00130         writer.writeIPv4Address (qAddress);
00131         BinaryReader reader (writer.buffer());
00132         CPPUNIT_ASSERT (reader.readIPv4Address().toIPv4Address() == address);
00133         CPPUNIT_ASSERT (reader.hasReadAll() && !reader.hasReadPastEnd());
00134     }
00135 
00136     void testWriteIPv4Address()
00137     {
00138         scenarioWriteIPv4Address (0x7f000001);  // 127.0.0.1
00139         scenarioWriteIPv4Address (0xc0a80148);  // 192.168.1.72
00140         scenarioWriteIPv4Address (0x55d63cb9);  // 85.214.60.185
00141         scenarioWriteIPv4Address (0x00000000);  // 0.0.0.0
00142     }
00143 
00144     void scenarioWriteQueryData (const QueryData &extension)
00145     {
00146         BinaryWriter    writer;
00147         writer.writeQueryData (extension);
00148         BinaryReader reader (writer.buffer());
00149         QueryData extension2 (reader.readQueryData());
00150         CPPUNIT_ASSERT (extension2.xmlList == extension.xmlList);
00151         CPPUNIT_ASSERT (extension2.urnList == extension.urnList);
00152         CPPUNIT_ASSERT (extension2.ggepBlock == extension.ggepBlock);
00153         CPPUNIT_ASSERT (extension2.unknownList == extension.unknownList);
00154         CPPUNIT_ASSERT (reader.hasReadAll() && !reader.hasReadPastEnd());
00155     }
00156 
00157     void testWriteQueryDataOneXml()
00158     {
00159         QueryData   extension;
00160         extension.xmlList += QByteArray ("{xmltest/}");
00161         scenarioWriteQueryData (extension);
00162     }
00163 
00164     void testWriteQueryDataOneHuge()
00165     {
00166         QueryData   extension;
00167         extension.urnList += QByteArray ("urn: fortest");
00168         scenarioWriteQueryData (extension);
00169     }
00170 
00171     void testWriteQueryDataOneUnknown()
00172     {
00173         QueryData   extension;
00174         extension.unknownList += QByteArray ("dunnotest");
00175         scenarioWriteQueryData (extension);
00176     }
00177 
00178     void testWriteQueryDataOneGgepBlock()
00179     {
00180         QueryData extension;
00181         extension.ggepBlock.addExtension (Ggeps::Unknown ("UNKN", "fortest"));
00182         scenarioWriteQueryData (extension);
00183     }
00184 
00185     void testWriteQueryDataMixed()
00186     {
00187         QueryData extension;
00188         extension.xmlList += QByteArray ("<xmltest/>");
00189         extension.xmlList += QByteArray ("{xmltest2/}");
00190         extension.urnList += QByteArray ("urn: hugetest");
00191         extension.unknownList += QByteArray ("dunnotest");
00192         extension.ggepBlock.addExtension (Ggeps::Unknown ("UNKN", "fortest"));
00193         scenarioWriteQueryData (extension);
00194     }
00195 
00196     void scenarioWriteMinSpeed(bool f1,bool f2,bool f3,bool f4,bool f5,bool f6,uchar byte)
00197     {
00198         MinSpeed speed(f1,f2,f3,f4,f5,f6,byte);
00199         BinaryWriter writer;
00200         writer.writeMinSpeed (speed);
00201         BinaryReader reader (writer.buffer());
00202         CPPUNIT_ASSERT (reader.readMinSpeed() == speed);
00203         CPPUNIT_ASSERT (reader.hasReadAll() && !reader.hasReadPastEnd());
00204     }
00205 
00206     void testWriteMinSpeed()
00207     {
00208         scenarioWriteMinSpeed (true, true, true, true, true, true, '\110');
00209         scenarioWriteMinSpeed (true, true, true, true, true, false, '\110');
00210         scenarioWriteMinSpeed (true, true, true, true, false, false, '\110');
00211         scenarioWriteMinSpeed (true, true, true, false, false, false, '\110');
00212         scenarioWriteMinSpeed (true, true, false, false, false, false, '\110');
00213         scenarioWriteMinSpeed (true, false, false, false, false, false, '\110');
00214     }
00215 
00216     void scenarioWriteResultSet(const ResultData &resultData, int number)
00217     {
00218         BinaryWriter writer;
00219         ResultSet rs;
00220         Result result;
00221         result.fileIndex = 0x44332211;
00222         result.fileSize = 0x66554433;
00223         result.fullFileName = "TAOCP";
00224         result.resultData = resultData;
00225         for(int i=0;i<number;++i)
00226             rs.append (result);
00227         writer.writeQueryHitsResultSet (rs);
00228         BinaryReader reader (writer.buffer());
00229         CPPUNIT_ASSERT (reader.readQueryHitsResultSet (number) == rs);
00230         CPPUNIT_ASSERT (reader.hasReadAll() && !reader.hasReadPastEnd());
00231     }
00232 
00233     void testWriteResultSetOneResultOneUrn()
00234     {
00235         ResultData resultData;
00236         resultData.urnList.append ("urn:test");
00237         scenarioWriteResultSet (resultData, 1);
00238     }
00239     void testWriteResultSetOneResultOneGgepBlock()
00240     {
00241         ResultData resultData;
00242         resultData.ggepBlock = GgepBlock().addExtension (Ggeps::Unknown ("UNKN", "fortest"));
00243         scenarioWriteResultSet (resultData, 1);
00244     }
00245 
00246     void testWriteResultSetOneResultOnePlainData()
00247     {
00248         ResultData resultData;
00249         resultData.unknownList.append ("plain:test");
00250         scenarioWriteResultSet (resultData, 1);
00251     }
00252 
00253     void testWriteResultSetOneResultMixedData()
00254     {
00255         ResultData resultData;
00256         resultData.unknownList.append ("plain:test");
00257         resultData.ggepBlock = GgepBlock().addExtension (Ggeps::Unknown ("UNKN", "fortest"));
00258         resultData.urnList.append ("urn:test");
00259         resultData.xmlList.append ("<book></book>");
00260         scenarioWriteResultSet (resultData, 1);
00261     }
00262 
00263     void testWriteResultSetTwoResults()
00264     {
00265         scenarioWriteResultSet (ResultData(),  2);
00266     }
00267 
00268     void scenarioWriteQueryHitsDataCheckFlags (bool ggep, bool uploadSpeed,
00269                                                bool haveUploaded, bool busy,
00270                                                bool push, const char flags[2])
00271     {
00272         QueryHitsData hitsData;
00273         if (ggep)
00274             hitsData.ggepBlock.addExtension (Ggeps::Unknown ("UNKN", "fortest"));
00275         hitsData.flagUploadSpeed = uploadSpeed;
00276         hitsData.flagHaveUploaded = haveUploaded;
00277         hitsData.flagBusy = busy;
00278         hitsData.flagPush = push;
00279 
00280         QByteArray rawBytes = hitsData.vendorCode.toBytes();
00281         rawBytes += "\x02"; // Only flags in open vendor area.
00282         rawBytes += flags; // The two bytes of flags.
00283         rawBytes += QByteArray (16, '\0'); // Null serventId.
00284 
00285         BinaryWriter writer;
00286         writer.writeQueryHitsData (hitsData);
00287         QByteArray writtenRawBytes = writer.buffer();
00288 
00289         CPPUNIT_ASSERT (writtenRawBytes.mid (5, 2) == QByteArray (flags));
00290     }
00291 
00292     void testWriteQueryHitsDataCheckFlagsAllSet()
00293     {
00294         scenarioWriteQueryHitsDataCheckFlags (true, true, true, true, true,
00295                                               "\x3d\x3d");
00296     }
00297 
00298     void testWriteQueryHitsDataCheckFlagsPushNotSet()
00299     {
00300         scenarioWriteQueryHitsDataCheckFlags (true, true, true, true, false,
00301                                               "\x3c\x3d");
00302     }
00303 
00304     void testWriteQueryHitsDataCheckFlagsBusyNotSet()
00305     {
00306         scenarioWriteQueryHitsDataCheckFlags (true, true, true, false, true,
00307                                               "\x3d\x39");
00308     }
00309 
00310     void testWriteQueryHitsDataCheckFlagsHaveUploadedNotSet()
00311     {
00312         scenarioWriteQueryHitsDataCheckFlags (true, true, false, true, true,
00313                                               "\x3d\x35");
00314     }
00315 
00316     void testWriteQueryHitsDataCheckFlagsUploadSpeedNotSet()
00317     {
00318         scenarioWriteQueryHitsDataCheckFlags (true, false, true, true, true,
00319                                               "\x3d\x2d");
00320     }
00321 
00322     void testWriteQueryHitsDataCheckFlagsGgepNotSet()
00323     {
00324         scenarioWriteQueryHitsDataCheckFlags (false, true, true, true, true,
00325                                               "\x3d\x1d");
00326     }
00327 
00328     void testWriteQueryHitsDataCheckFlagsNoneSet()
00329     {
00330         scenarioWriteQueryHitsDataCheckFlags (false, false, false, false, false,
00331                                               "\x3c\x01");
00332     }
00333 
00338     void scenarioWriteQueryHitsData(QueryHitsData &hitsData)
00339     {
00340         hitsData.flagUploadSpeed = false;
00341         hitsData.flagHaveUploaded = false;
00342         hitsData.flagBusy = false;
00343         hitsData.flagPush = false;
00344         hitsData.serventId  =   QUuid (0x11111111, 0x3333, 0x5555, 0xee, 0xff,
00345                                        0x22, 0x44, 0x66, 0x88, 0x00, 0xcc);
00346         BinaryWriter writer;
00347         writer.writeQueryHitsData (hitsData);
00348         BinaryReader reader (writer.buffer());
00349         QueryHitsData readHitsData = reader.readQueryHitsData();
00350         CPPUNIT_ASSERT (hitsData == readHitsData);
00351         CPPUNIT_ASSERT (reader.hasReadAll() && !reader.hasReadPastEnd());
00352     }
00353 
00354     void testWriteQueryHitsDataNoGgepBlockNoXmlData()
00355     {
00356         QueryHitsData hitsData;
00357         scenarioWriteQueryHitsData (hitsData);
00358     }
00359 
00360     void testWriteQueryHitsDataXmlData()
00361     {
00362         QueryHitsData hitsData;
00363         hitsData.xmlData = QByteArray("<xmltest/>");
00364         scenarioWriteQueryHitsData (hitsData);
00365     }
00366 
00367     void testWriteQueryHitsDataGgepBlock()
00368     {
00369         QueryHitsData hitsData;
00370         hitsData.ggepBlock = GgepBlock().addExtension (Ggeps::Unknown ("UNKN", "fortest"));
00371         scenarioWriteQueryHitsData (hitsData);
00372     }
00373 
00374     void testWriteQueryHitsDataGgepBlockXmlData()
00375     {
00376         QueryHitsData hitsData;
00377         hitsData.xmlData = QByteArray("<xmltest/>");
00378         hitsData.ggepBlock = GgepBlock().addExtension (Ggeps::Unknown ("UNKN", "fortest"));
00379         scenarioWriteQueryHitsData (hitsData);
00380     }
00381 
00382     void testWriteQueryHitsDataGgepBlockXmlDataOther()
00383     {
00384         QueryHitsData hitsData;
00385         hitsData.privateVendor.append(QByteArray("vendor1"));
00386         hitsData.privateVendor.append(QByteArray("vendor2"));
00387         hitsData.xmlData = QByteArray("<xmltest/>");
00388         hitsData.ggepBlock = GgepBlock().addExtension (Ggeps::Unknown ("UNKN", "fortest"));
00389         scenarioWriteQueryHitsData (hitsData);
00390     }
00391 };
00392 
00393 CPPUNIT_TEST_SUITE_REGISTRATION(BinaryWriterTest);
00394 
00395 } // namespace Testing
00396 } // namespace Packets
00397 } // namespace Gnutella
00398 } // namespace Protocols