X-Git-Url: http://g0dil.de/git?a=blobdiff_plain;f=Packets%2FPacket.test.cc;h=18b8fe9ed174a8ee2b3453fe00b93299ca011622;hb=fd3a0e8ac95d1158e9ea661ddf9187b67c70169f;hp=bc565de79906fa813d59f1f0cdefb3c16a292a76;hpb=145f6a7d0f3a6aaa77b3625351c952d24cb0b8a1;p=senf.git diff --git a/Packets/Packet.test.cc b/Packets/Packet.test.cc index bc565de..18b8fe9 100644 --- a/Packets/Packet.test.cc +++ b/Packets/Packet.test.cc @@ -1,9 +1,9 @@ // $Id$ // -// Copyright (C) 2006 -// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS) -// Kompetenzzentrum fuer Satelitenkommunikation (SatCom) -// Stefan Bund +// Copyright (C) 2007 +// Fraunhofer Institute for Open Communication Systems (FOKUS) +// Competence Center NETwork research (NET), St. Augustin, GERMANY +// Stefan Bund // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -20,222 +20,299 @@ // Free Software Foundation, Inc., // 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -// Unit tests +/** \file + \brief Packet unit tests */ //#include "Packet.test.hh" //#include "Packet.test.ih" // Custom includes -#include "Packet.hh" -#include "DataPacket.hh" -#include "GenericPacket.hh" +#include +#include +#include "Packets.hh" -#include +#include "../Utils/auto_unit_test.hh" #include #define prefix_ ///////////////////////////////cc.p//////////////////////////////////////// -using namespace senf; - -// Since Packet is abstract, we can only test the Packet interface using -// a simple implementation: DataPacket and GenericPacket. - namespace { - Packet::byte data[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, - 10, 11, 12, 13, 14, 15, 16, 17, 18, 19 }; + struct RegTag { + typedef unsigned key_t; + }; - bool compare(Packet::iterator b, Packet::iterator e, unsigned o=0) + struct FooPacketType + : public senf::PacketTypeBase, + public senf::PacketTypeMixin + { + using senf::PacketTypeMixin::nextPacketRange; + using senf::PacketTypeMixin::initSize; + using senf::PacketTypeMixin::init; + static size_type initSize() + { return 4u; } + + // We need to implement initHeadSize() to force the mixin to switch into 'fixed-size' + // mode. Otherwise, mixin::nextPacketRange() would query the parser for it's size to find + // the header size. Since the parser is VoidPacketParser, the header size would therefore be + // 0 + static size_type initHeadSize() + { return initSize(); } + }; + typedef senf::ConcretePacket FooPacket; + + struct BarPacketParser : public senf::PacketParserBase + { +# include SENF_FIXED_PARSER() + + SENF_PARSER_FIELD( type, senf::UInt16Parser ); + SENF_PARSER_FIELD( length, senf::Int32Parser ); + SENF_PARSER_FIELD( reserved, senf::UInt16Parser ); + + SENF_PARSER_INIT() { + reserved() << 0xA0A0u; + } + + SENF_PARSER_FINALIZE(BarPacketParser); + }; + + struct BarPacketType + : public senf::PacketTypeBase, + public senf::PacketTypeMixin { - unsigned i (o); - for (; b!=e; ++b, ++i) - if (i>=sizeof(data) || *b != data[i]) - return false; - return true; + typedef senf::PacketTypeMixin mixin; + typedef senf::ConcretePacket packet; + typedef BarPacketParser parser; + using mixin::nextPacketRange; + using mixin::nextPacketType; + using mixin::initSize; + using mixin::init; + static void dump(packet p, std::ostream & os) { + os << "BarPacket:\n" + << "type: " << p->type() << "\n" + << "length: " << p->length() << "\n"; + } + static void finalize(packet p) { + if (p.next(senf::nothrow)) + p->type() = senf::PacketRegistry::key(p.next()); + else + p->type() = -1; + } + static key_t nextPacketKey(packet p) { + return p->type(); + } + }; + typedef BarPacketType::packet BarPacket; + + namespace reg { + senf::PacketRegistry::RegistrationProxy registerFoo(1u); + senf::PacketRegistry::RegistrationProxy registerBar(2u); } -} - -BOOST_AUTO_UNIT_TEST(Packet_DataPacket) -{ - Packet::ptr p (Packet::create(data, data+sizeof(data))); + struct IntAnnotation { + unsigned value; + }; + + struct LargeAnnotation { + char value[32]; + }; - BOOST_REQUIRE( p ); - BOOST_CHECK_EQUAL( p->size(), sizeof(data) ); - BOOST_CHECK( compare(p->begin(), p->end()) ); + struct ComplexAnnotation : senf::ComplexAnnotation + { + std::string s; + int i; + }; - *p->begin() = 20; - BOOST_CHECK( !compare(p->begin(), p->end()) ); - BOOST_CHECK_EQUAL( *p->begin(), 20 ); + struct ComplexEmptyAnnotation : senf::ComplexAnnotation + {}; - BOOST_CHECK( !p->next() ); - BOOST_CHECK( !p->prev() ); - BOOST_CHECK_EQUAL( p->head(), p ); - BOOST_CHECK_EQUAL( p->last(), p ); + struct InvalidAnnotation + { + std::string value; + }; - BOOST_CHECK( p->is() ); - BOOST_CHECK( p->as() ); } -BOOST_AUTO_UNIT_TEST(Packet_GenericPacket) +BOOST_AUTO_UNIT_TEST(packet) { - GenericPacket<4,6>::ptr p (Packet::create< GenericPacket<4,6> >(data, data+sizeof(data))); - - // check, that the packet was constructed corretly - BOOST_REQUIRE( p ); - BOOST_CHECK_EQUAL( p->size(), sizeof(data) ); - BOOST_CHECK( compare(p->begin(), p->end()) ); - BOOST_CHECK_EQUAL( p->header_len(), 4u ); - BOOST_CHECK( compare(p->begin_header(), p->end_header()) ); - BOOST_CHECK_EQUAL( p->trailer_len(), 6u ); - BOOST_CHECK( compare(p->begin_trailer(), p->end_trailer(), sizeof(data)-6) ); - - // check the first packet in the interpreter chain - BOOST_CHECK_EQUAL( p->head(), p ); - BOOST_CHECK( !p->prev() ); - BOOST_CHECK(( p->is< GenericPacket<4,6> >() )); - BOOST_CHECK( !p->is() ); - BOOST_CHECK(( !p->is< GenericPacket<4,4> >() )); - BOOST_CHECK(( p->as< GenericPacket<4,6> >() )); - BOOST_CHECK( !p->as() ); - - // check the next packet in the interpreter chain - BOOST_REQUIRE( p->next() ); - BOOST_CHECK( p->next()->is() ); - BOOST_CHECK(( !p->next()->is< GenericPacket<4,6> >() )); - - // check the contents of the second interpreter - BOOST_CHECK_EQUAL( p->next()->size(), sizeof(data)-10 ); - BOOST_CHECK( compare(p->next()->begin(), p->next()->end(), 4) ); - - // validate, that the two interpreters share the same data - // container - *p->next()->begin() = 20; - BOOST_CHECK( !compare(p->next()->begin(), p->next()->end(), 4) ); - BOOST_CHECK( *p->next()->begin() == 20 ); - BOOST_CHECK( !compare(p->begin(), p->end()) ); - BOOST_CHECK( *(p->begin()+4) == 20 ); - - // We need require here. If this fails, p->last() will probably - // run into an endless loop ... - BOOST_REQUIRE( !p->next()->next() ); - BOOST_CHECK_EQUAL( p->next(), p->last() ); + senf::Packet packet (FooPacket::create()); + BarPacket::createAfter(packet); + + BOOST_REQUIRE( packet ); + BOOST_CHECK( packet.next() ); + BOOST_CHECK( ! packet.next().next(senf::nothrow) ); + BOOST_CHECK( ! packet.prev(senf::nothrow) ); + BOOST_CHECK( packet.next().prev() == packet ); + BOOST_CHECK( packet.next() != packet ); + BOOST_CHECK_EQUAL( std::distance(packet.data().begin(), packet.next().data().begin()), 4 ); + BOOST_CHECK_EQUAL( std::distance(packet.data().begin(), packet.data().end()), 12 ); + BOOST_CHECK_EQUAL( std::distance(packet.next().data().begin(), packet.next().data().end()), 8 ); + BOOST_CHECK( packet.data().end() == packet.next().data().end() ); + BOOST_CHECK_EQUAL( packet.size(), 12u ); + BOOST_CHECK_EQUAL( packet.next().size(), 8u ); + BOOST_CHECK( packet.is() ); + BOOST_CHECK( packet.next().is() ); + BOOST_CHECK( packet.first() == packet ); + BOOST_CHECK( packet.last() == packet.next() ); + + senf::Packet p2 (packet.next()); + BOOST_CHECK( p2 ); + packet.parseNextAs(); + BOOST_CHECK_EQUAL( packet.size(), 12u ); + BOOST_CHECK_EQUAL( packet.next().size(), 8u ); + BOOST_CHECK( packet.next().is() ); + BOOST_CHECK( ! p2 ); + BOOST_CHECK( packet.next().as() ); + + p2 = packet.next().clone(); + BOOST_REQUIRE( p2 ); + packet.next().append( p2 ); + BOOST_REQUIRE( packet.next().next() ); + BOOST_CHECK( packet.next().next().next() ); + BOOST_CHECK( packet.next().next().next().is() ); + BOOST_CHECK_EQUAL( packet.size(), 16u ); + + // This calls and checks typeId() + BOOST_CHECK_EQUAL( senf::PacketRegistry::key(packet), 1u ); + packet.next().parseNextAs( senf::PacketRegistry::lookup(2u).factory() ); + BOOST_CHECK( packet.next().next().is() ); + + std::stringstream s; + packet.dump(s); + BOOST_CHECK_EQUAL( s.str(), "BarPacket:\ntype: 0\nlength: 0\n" ); + + packet.finalizeAll(); + BOOST_CHECK_EQUAL( packet.last().as()->type(), + BarPacket::Parser::type_t::value_type(-1) ); + packet.last().append(FooPacket::create()); + packet.finalizeThis(); + packet.finalizeTo(); + packet.finalizeTo(packet.find()); + packet.finalizeAll(); + BOOST_CHECK_EQUAL( packet.find()->type(), 1u ); + + BOOST_CHECK( packet.factory() == FooPacket::factory() ); + + senf::PacketData::byte data[] = { 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x81, 0x82, 0x83 }; + + BarPacket::createAfter(packet, data); + BOOST_REQUIRE( packet.next() ); + BOOST_REQUIRE( packet.next().is() ); + BOOST_CHECK( packet.last().is() ); + BOOST_CHECK_EQUAL( packet.last().rfind()->type(), 1u ); + BOOST_CHECK_EQUAL( packet.next().size(), 11u ); + BOOST_REQUIRE( packet.next().next() ); + BOOST_CHECK( packet.next().next().is() ); + BOOST_CHECK( ! packet.next().next().next(senf::nothrow) ); + BOOST_CHECK_EQUAL( packet.next().next().data()[0], 0x81u ); + + BOOST_CHECK( packet.first().find() == packet ); + BOOST_CHECK( packet.last().rfind() == packet.last().prev() ); + BOOST_CHECK( packet.find() == packet ); + BOOST_CHECK( packet.last().rfind() == packet.last() ); + BOOST_CHECK( packet.next() == packet.next() ); + BOOST_CHECK( packet.last().prev().prev() == packet ); + + senf::DataPacket::createAfter(packet); + BOOST_CHECK_THROW( packet.next().next().next().parseNextAs(), + senf::InvalidPacketChainException ); } -BOOST_AUTO_UNIT_TEST(Packet_Reinterpret) +BOOST_AUTO_UNIT_TEST(concretePacket) { - Packet::ptr p (Packet::create< GenericPacket<4,4> >(data, data+sizeof(data))); - - BOOST_CHECK( p->next()->is() ); - p->next()->reinterpret< GenericPacket<6> >(); - BOOST_CHECK( p->next()->is< GenericPacket<6> >() ); - BOOST_REQUIRE( p->next()->next() ); - BOOST_CHECK( p->next()->next()->is() ); - BOOST_CHECK( !p->next()->next()->next() ); - - BOOST_CHECK_EQUAL( p->next()->next()->size(), sizeof(data)-14 ); - BOOST_CHECK( compare(p->next()->next()->begin(), - p->next()->next()->end(), 10) ); - - p = p->reinterpret< GenericPacket<8,2> >(); - BOOST_REQUIRE( p->next() ); - BOOST_CHECK( p->next()->is() ); - - BOOST_CHECK_EQUAL( p->next()->size(), sizeof(data)-10 ); - BOOST_CHECK( compare(p->next()->begin(), p->next()->end(), 8) ); + senf::PacketData::byte data[] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06 }; + + BOOST_CHECK_EQUAL( FooPacket::create().size(), 4u ); + BOOST_CHECK_EQUAL( FooPacket::create(senf::noinit).size(), 0u ); + BOOST_CHECK_THROW( FooPacket::create(2u), senf::TruncatedPacketException ); + // No 'u' suffix here to check, that the disable_if works ... + BOOST_CHECK_EQUAL( FooPacket::create(10).size(), 10u ); + BOOST_CHECK_EQUAL( FooPacket::create(2u,senf::noinit).size(), 2u ); + BOOST_CHECK_EQUAL( FooPacket::create(data).size(), 6u ); + + senf::Packet packet (FooPacket::create()); + + BOOST_CHECK_EQUAL( FooPacket::createAfter(packet).size(), 4u ); + BOOST_CHECK_EQUAL( packet.size(), 8u ); + + BOOST_CHECK_EQUAL( FooPacket::createAfter(packet,senf::noinit).size(), 0u ); + BOOST_CHECK_EQUAL( packet.size(), 4u ); + + BOOST_CHECK_THROW( FooPacket::createAfter(packet,2u), senf::TruncatedPacketException ); + // No 'u' suffix here to check, that the disable_if works ... + BOOST_CHECK_EQUAL( FooPacket::createAfter(packet,10).size(), 10u ); + BOOST_CHECK_EQUAL( packet.size(), 14u ); + + BOOST_CHECK_EQUAL( FooPacket::createAfter(packet,2u,senf::noinit).size(), 2u ); + BOOST_CHECK_EQUAL( packet.size(), 6u ); + + BOOST_CHECK_EQUAL( FooPacket::createAfter(packet,data).size(), 6u ); + BOOST_CHECK_EQUAL( packet.size(), 10u ); + + BOOST_CHECK_EQUAL( FooPacket::createBefore(packet).size(), 14u ); + BOOST_CHECK_EQUAL( packet.size(), 10u ); + + BOOST_CHECK_EQUAL( FooPacket::createBefore(packet,senf::noinit).size(), 10u ); + BOOST_CHECK_EQUAL( packet.size(), 10u ); + + BOOST_CHECK( packet.clone() != packet ); + BOOST_CHECK_EQUAL( BarPacket::create()->reserved(), 0xA0A0u ); } -BOOST_AUTO_UNIT_TEST(Packet_InsertErase) +BOOST_AUTO_UNIT_TEST(packetAssign) { - Packet::ptr p (Packet::create< GenericPacket<7,3> >(data, data+sizeof(data))); - p->next()->reinterpret< GenericPacket<4> >(); - - BOOST_CHECK_EQUAL( p->size(), 20u ); - BOOST_CHECK_EQUAL( p->next()->size(), 10u ); - BOOST_CHECK_EQUAL( p->next()->next()->size(), 6u ); - - BOOST_CHECK_EQUAL( p->next()->next()->begin()[0], 11 ); - BOOST_CHECK_EQUAL( p->end()[-1], 19 ); - BOOST_CHECK_EQUAL( p->next()->end()[-1], 16 ); - BOOST_CHECK_EQUAL( p->next()->next()->end()[-1], 16 ); + BarPacket bar1 (BarPacket::create()); + BarPacket bar2 (BarPacket::create()); - p->next()->insert(p->next()->begin()+2, data, data+6); - - BOOST_CHECK_EQUAL( p->size(), 26u ); - BOOST_CHECK_EQUAL( p->next()->size(), 16u ); - BOOST_CHECK_EQUAL( p->next()->next()->size(), 6u ); - - BOOST_CHECK( compare(p->begin(), p->begin()+9) ); - BOOST_CHECK( compare(p->begin()+9, p->begin()+15) ); - BOOST_CHECK( compare(p->begin()+15, p->end(), 9) ); - BOOST_CHECK( compare(p->next()->begin(), p->next()->begin()+2, 7) ); - BOOST_CHECK( compare(p->next()->begin()+2, p->next()->begin()+8) ); - BOOST_CHECK( compare(p->next()->begin()+8, p->next()->end(), 9) ); - BOOST_CHECK( compare(p->next()->next()->begin(), p->next()->next()->end(), 11) ); - - p->next()->erase( p->next()->begin()+2, p->next()->begin()+8 ); - - BOOST_CHECK_EQUAL( p->size(), 20u ); - BOOST_CHECK_EQUAL( p->next()->size(), 10u ); - BOOST_CHECK_EQUAL( p->next()->next()->size(), 6u ); - - BOOST_CHECK( compare(p->begin(), p->end()) ); - BOOST_CHECK( compare(p->next()->begin(), p->next()->end(), 7) ); - BOOST_CHECK( compare(p->next()->next()->begin(), p->next()->next()->end(), 11) ); - - p->next()->insert(p->next()->begin()+4, data, data+2); - - BOOST_CHECK_EQUAL( p->size(), 22u ); - BOOST_CHECK_EQUAL( p->next()->size(), 12u ); - BOOST_CHECK_EQUAL( p->next()->next()->size(), 6u ); - - BOOST_CHECK( compare(p->next()->next()->begin(), p->next()->next()->end(), 11) ); + bar2->type() << 0x2A2Bu; + bar1.parser() << bar2; + + BOOST_CHECK_EQUAL( bar1->type(), 0x2A2Bu ); +} - p->next()->erase(p->next()->begin()+4, p->next()->begin()+6); +BOOST_AUTO_UNIT_TEST(packetAnnotation) +{ + senf::Packet packet (FooPacket::create()); + BarPacket::createAfter(packet); - BOOST_CHECK_EQUAL( p->size(), 20u ); - BOOST_CHECK_EQUAL( p->next()->size(), 10u ); - BOOST_CHECK_EQUAL( p->next()->next()->size(), 6u ); + ComplexAnnotation & ca (packet.annotation()); + ca.s = "dead beef"; + ca.i = 0x12345678; + SENF_CHECK_NO_THROW( packet.annotation().value = 0xDEADBEEF ); - BOOST_CHECK( compare(p->begin(), p->end()) ); - BOOST_CHECK( compare(p->next()->begin(), p->next()->end(), 7) ); - BOOST_CHECK( compare(p->next()->next()->begin(), p->next()->next()->end(), 11) ); + senf::Packet p2 (packet.next()); - p->next()->next()->insert(p->next()->begin()+5, data, data+4); + BOOST_CHECK_EQUAL( p2.annotation().value, 0xDEADBEEFu ); + BOOST_CHECK_EQUAL( p2.annotation().s, "dead beef" ); + BOOST_CHECK_EQUAL( p2.annotation().i, 0x12345678 ); - BOOST_CHECK_EQUAL( p->size(), 24u ); - BOOST_CHECK_EQUAL( p->next()->size(), 14u ); - BOOST_CHECK_EQUAL( p->next()->next()->size(), 10u ); + BOOST_CHECK( senf::detail::AnnotationIndexer::Small ); + BOOST_CHECK( ! senf::detail::AnnotationIndexer::Small ); + BOOST_CHECK( ! senf::detail::AnnotationIndexer::Small ); + BOOST_CHECK( ! senf::detail::AnnotationIndexer::Small ); +} - BOOST_CHECK( compare(p->next()->next()->begin(), p->next()->next()->begin()+1, 11) ); - BOOST_CHECK( compare(p->next()->next()->begin()+1, p->next()->next()->begin()+5) ); - BOOST_CHECK( compare(p->next()->next()->begin()+5, p->end(), 12) ); +#ifdef COMPILE_CHECK - p->next()->erase(p->next()->begin()+3, p->next()->begin()+9); +COMPILE_FAIL(invalidAnnotation) +{ +#if 0 // The traits check fails for user defined but trivial constructors so ... +# ifdef BOOST_HAS_TYPE_TRAITS_INTRINSICS - BOOST_CHECK_EQUAL( p->size(), 18u ); - BOOST_CHECK_EQUAL( p->next()->size(), 8u ); - BOOST_CHECK_EQUAL( p->next()->next()->size(), 5u ); + senf::Packet packet (FooPacket::create()); + (void) packet.annotation(); - BOOST_CHECK( compare(p->next()->next()->begin(), p->next()->next()->end(), 12) ); - BOOST_CHECK( compare(p->begin(), p->begin()+10) ); - BOOST_CHECK( compare(p->begin()+10, p->end(), 12) ); +# else +# endif +#endif - p->erase(p->begin()+5, p->end()); + invalid_annotation_check_disabled(); - BOOST_CHECK_EQUAL( p->size(), 5u ); - BOOST_CHECK_EQUAL( p->next()->size(), 0u ); - BOOST_CHECK_EQUAL( p->next()->next()->size(), 0u ); } -BOOST_AUTO_UNIT_TEST(Packet_new) -{ - Packet::ptr p (Packet::create< GenericPacket<10,4> >()); - BOOST_CHECK_EQUAL(p->size(), 14u); - Packet::ptr p2 (Packet::create< GenericPacket<2,2> >(p)); - BOOST_CHECK_EQUAL(p2->size(),18u); -} +#endif ///////////////////////////////cc.e//////////////////////////////////////// #undef prefix_