PacketTest.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 "../Packet.h"
00025 #include "../Bye.h"
00026 #include "cppunit/extensions/HelperMacros.h"
00027 #include <memory>
00028 
00029 namespace Gnutella {
00030 namespace Packets {
00031 namespace Testing {
00032 
00033 class ByeConcretePacket : public Bye
00034 {
00035     public:
00036         typedef Packet::Data PacketData;
00037 
00038         ByeConcretePacket(  quint16 code,
00039                 const QByteArray &message )
00040             : Bye( code, message )
00041             {
00042             }
00043 
00044         ByeConcretePacket( const QByteArray &rawHeader,
00045                            const QByteArray &rawPayload )
00046             : Bye( rawHeader, rawPayload )
00047         {
00048         }
00049 
00050         PacketData* getPacketData()
00051         {
00052             return this->Packet::d;
00053         }
00054 
00055         void setHeaderAndPayload( QByteArray& header,
00056                 QByteArray& payload )
00057         {
00058             getPacketData()->rawHeader = header;
00059             getPacketData()->rawPayload = payload;
00060         }
00061 
00062         void invalidatePayload()
00063         {
00064             Packet::invalidatePayload();
00065         }
00066 };
00067 
00068 class TestPacket : public CppUnit::TestFixture
00069 {
00070     REFERENCE_OBJECT (TestPacket)
00071 
00072     CPPUNIT_TEST_SUITE(TestPacket);
00073     CPPUNIT_TEST(testDescriptorCtor);
00074     CPPUNIT_TEST(testAssign);
00075     CPPUNIT_TEST(testInvalidateHeader);
00076     CPPUNIT_TEST(testReadHeader);
00077     CPPUNIT_TEST(testParse);
00078     CPPUNIT_TEST(testInvalidatePayload);
00079     CPPUNIT_TEST(testWriteHeader);
00080     CPPUNIT_TEST(testHeaderPayloadCtor);
00081     CPPUNIT_TEST(testRawPayload);
00082     CPPUNIT_TEST(testRawHeader);
00083     CPPUNIT_TEST(testFromRawData);
00084     CPPUNIT_TEST_SUITE_END();
00085     ByeConcretePacket* m_p;
00086     QByteArray      m_header;
00087     QByteArray      m_payload;
00088     QUuid           m_uid;
00089     enum { PAYLOADLEN = 34567, TTL = 144, HOPS = 49,
00090            MSGLEN = 44, MSGFILLCHAR = 'X' };
00091 
00092 public:
00093 
00094     TestPacket() :
00095         m_p (0), m_header(), m_payload(),
00096         m_uid (0x67c8770b, 0x44f1, 0x410a, 0xab, 0x9a,
00097                0xf9, 0xb5, 0x44, 0x6f, 0x13, 0xee)
00098     {
00099     }
00100 
00101     void setUp()
00102     {
00103         createPacketStream( m_header, m_uid, ByeDescriptor, TTL, HOPS, PAYLOADLEN );
00104         m_payload.fill( ' ', PAYLOADLEN );
00105         QByteArray message( MSGLEN, MSGFILLCHAR );
00106         m_p = new ByeConcretePacket( 29, message );
00107     }
00108 
00109     void tearDown()
00110     {
00111         delete m_p;
00112     }
00113 
00114     void testDescriptorCtor()
00115     {
00116         ByeConcretePacket::PacketData* d = m_p->getPacketData();
00117         CPPUNIT_ASSERT( d->ref == 1 );
00118         CPPUNIT_ASSERT( d->descriptorId == m_p->descriptorId() );
00119         CPPUNIT_ASSERT( m_p->hops() == DefaultHops );
00120         CPPUNIT_ASSERT( m_p->ttl() == DefaultTtl );
00121         CPPUNIT_ASSERT( m_p->payloadDescriptor() == ByeDescriptor );
00122         CPPUNIT_ASSERT( d->payloadLength == 0 );
00123         CPPUNIT_ASSERT( d->rewriteHeader == true );
00124         CPPUNIT_ASSERT( d->rewritePayload == true );
00125         CPPUNIT_ASSERT( d->isValid );
00126         CPPUNIT_ASSERT( m_p->isValid() );
00127     }
00128 
00129     void testHeaderPayloadCtor()
00130     {
00131         const std::auto_ptr<ByeConcretePacket> p ( new ByeConcretePacket( m_header, m_payload ) );
00132         CPPUNIT_ASSERT( p->getPacketData()->ref == 1 );
00133         /* as the parse is done by now */
00134         CPPUNIT_ASSERT( p->isValid() == true );
00135         CPPUNIT_ASSERT( p->descriptorId() == m_uid );
00136         CPPUNIT_ASSERT( p->payloadDescriptor() == ByeDescriptor );
00137         CPPUNIT_ASSERT( p->ttl() == static_cast<uchar>(TTL) );
00138         CPPUNIT_ASSERT( p->hops() == static_cast<uchar>(HOPS) );
00139         CPPUNIT_ASSERT( p->getPacketData()->payloadLength ==
00140                 static_cast<quint32>(PAYLOADLEN) );
00141     }
00142 
00143     void testAssign()
00144     {
00145         QByteArray message( MSGLEN, MSGFILLCHAR );
00146         std::auto_ptr<ByeConcretePacket> p( new ByeConcretePacket( 29,
00147                 message ) );
00148         *p = *m_p;
00149         CPPUNIT_ASSERT( p->getPacketData() == m_p->getPacketData() );
00150         CPPUNIT_ASSERT( p->getPacketData()->ref == 2 );
00151         *m_p = *p;
00152         CPPUNIT_ASSERT( p->getPacketData() == m_p->getPacketData() );
00153         CPPUNIT_ASSERT( p->getPacketData()->ref == 2 );
00154         p->invalidateHeader();
00155         p.reset();
00156         CPPUNIT_ASSERT( m_p->getPacketData()->ref == 1 );
00157         ByeConcretePacket::PacketData* d = m_p->getPacketData();
00158         *m_p = *m_p;
00159         CPPUNIT_ASSERT( m_p->getPacketData() == d );
00160         CPPUNIT_ASSERT( m_p->getPacketData()->ref == 1 );
00161     }
00162 
00163     void testInvalidatePayload()
00164     {
00165         m_p->invalidatePayload();
00166         CPPUNIT_ASSERT( m_p->getPacketData()->rewritePayload == true );
00167         QByteArray message( MSGLEN, MSGFILLCHAR );
00168         std::auto_ptr<ByeConcretePacket> p( new ByeConcretePacket( 29, message ) );
00169         *p = *m_p;
00170         p->invalidatePayload();
00171         CPPUNIT_ASSERT( p->getPacketData() != m_p->getPacketData() );
00172         CPPUNIT_ASSERT( p->getPacketData()->ref == 1 );
00173         CPPUNIT_ASSERT( m_p->getPacketData()->ref == 1 );
00174         CPPUNIT_ASSERT( p->getPacketData()->rewritePayload == true );
00175         CPPUNIT_ASSERT( m_p->getPacketData()->rewritePayload == true );
00176     }
00177 
00178     void testInvalidateHeader()
00179     {
00180         ByeConcretePacket::PacketData* d = m_p->getPacketData();
00181         m_p->invalidateHeader();
00182         CPPUNIT_ASSERT( m_p->getPacketData() == d );
00183         CPPUNIT_ASSERT( m_p->getPacketData()->rewriteHeader == true );
00184         CPPUNIT_ASSERT( m_p->getPacketData()->ref == 1 );
00185         QByteArray message( MSGLEN, MSGFILLCHAR );
00186         std::auto_ptr<ByeConcretePacket> p( new ByeConcretePacket( 29, message ) );
00187         std::auto_ptr<ByeConcretePacket> q( new ByeConcretePacket( 29, message ) );
00188         *p = *m_p;
00189         *q = *m_p;
00190         d = m_p->getPacketData();
00191         p->invalidateHeader();
00192         CPPUNIT_ASSERT( q->getPacketData() == d );
00193         CPPUNIT_ASSERT( q->getPacketData()->ref == 2 );
00194         CPPUNIT_ASSERT( q->getPacketData() != p->getPacketData() );
00195         CPPUNIT_ASSERT( q->getPacketData()->rewriteHeader == true );
00196         CPPUNIT_ASSERT( p->getPacketData()->rewriteHeader == true );
00197     }
00198 
00199     void createPacketStream(QByteArray& arr,
00200                             QUuid& uid,
00201                             PayloadDescriptor desc,
00202                             uchar ttl,
00203                             uchar hops,
00204                             quint32 payloadLength)
00205     {
00206         QDataStream stream(&arr, QIODevice::WriteOnly);
00207         stream.setByteOrder (QDataStream::LittleEndian);
00208         stream << uid
00209             << desc
00210             << ttl
00211             << hops
00212             << payloadLength;
00213     }
00214 
00215     void testReadHeader()
00216     {
00217         QByteArray arr;
00218         createPacketStream( arr, m_uid, ByeDescriptor, TTL, HOPS, PAYLOADLEN );
00219         QDataStream stream( &arr, QIODevice::ReadOnly );
00220         stream.setByteOrder (QDataStream::LittleEndian);
00221         m_p->readHeader( stream );
00222         CPPUNIT_ASSERT( m_p->descriptorId() == m_uid );
00223         CPPUNIT_ASSERT( m_p->payloadDescriptor() == ByeDescriptor );
00224         CPPUNIT_ASSERT( m_p->ttl() == static_cast<uchar>(TTL) );
00225         CPPUNIT_ASSERT( m_p->hops() == static_cast<uchar>(HOPS) );
00226         CPPUNIT_ASSERT( m_p->getPacketData()->payloadLength ==
00227                 static_cast<quint32>(PAYLOADLEN) );
00228     }
00229 
00230     void testParse()
00231     {
00232         m_p->setHeaderAndPayload( m_header, m_payload );
00233         m_p->parse();
00234         CPPUNIT_ASSERT( m_p->descriptorId() == m_uid );
00235         CPPUNIT_ASSERT( m_p->isValid() == true );
00236     }
00237 
00238     void testWriteHeader()
00239     {
00240         m_p->setHeaderAndPayload( m_header, m_payload );
00241         m_p->parse();
00242         QByteArray arr;
00243         QBuffer buffer(&arr);
00244         buffer.open(QIODevice::ReadWrite);
00245         QDataStream stream( &buffer );
00246         m_p->writeHeader(stream);
00247         buffer.seek(0);
00248         QUuid uid;
00249         PayloadDescriptor desc;
00250         uchar ttl;
00251         uchar hops;
00252         quint32 payloadLength;
00253         stream >> uid >> desc >> ttl >> hops >> payloadLength;
00254         CPPUNIT_ASSERT( uid == m_uid );
00255         CPPUNIT_ASSERT( desc == ByeDescriptor );
00256         CPPUNIT_ASSERT( ttl == m_p->ttl() );
00257         CPPUNIT_ASSERT( hops == m_p->hops() );
00258         CPPUNIT_ASSERT( payloadLength == PAYLOADLEN );
00259     }
00260 
00261     void testRawPayload()
00262     {
00263         const std::auto_ptr<ByeConcretePacket> p ( new ByeConcretePacket( m_header, m_payload ) );
00264         QByteArray empty;
00265         p->setIsValid(false);
00266         CPPUNIT_ASSERT( p->rawPayload() == empty );
00267         p->setIsValid(true);
00268         QByteArray payload = p->rawPayload();
00269         CPPUNIT_ASSERT( payload != empty );
00270         CPPUNIT_ASSERT( static_cast <uint> (payload.length()) ==
00271                         p->getPacketData()->payloadLength );
00272         CPPUNIT_ASSERT( p->getPacketData()->rewritePayload == false );
00273     }
00274 
00275     void testRawHeader()
00276     {
00277         const std::auto_ptr<ByeConcretePacket> p ( new ByeConcretePacket( m_header, m_payload ) );
00278         QByteArray empty;
00279         p->setIsValid(false);
00280         CPPUNIT_ASSERT( p->rawHeader() == empty );
00281         p->setIsValid(true);
00282         QByteArray rawHeader = p->rawHeader();
00283         CPPUNIT_ASSERT( rawHeader != empty );
00284         CPPUNIT_ASSERT( rawHeader.length() ==
00285                 p->getPacketData()->rawHeader.length() );
00286         CPPUNIT_ASSERT( p->getPacketData()->rewriteHeader == false );
00287     }
00288 
00289     void testFromRawData()
00290     {
00291         auto_ptr <Packet> p (Packet::fromRawData(m_header, m_payload));
00292 //      CPPUNIT_ASSERT( p->payloadDescriptor() == ByeDescriptor );
00293     }
00294 };
00295 CPPUNIT_TEST_SUITE_REGISTRATION(TestPacket);
00296 
00297 } // namespace Testing
00298 } // namespace Packets
00299 } // namespace Gnutella