// $Id$ // // Copyright (C) 2007 // Fraunhofer Institute for Open Communication Systems (FOKUS) // Competence Center NETwork research (NET), St. Augustin, GERMANY // Thorsten Horstmann <tho@berlios.de> // // 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 // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the // Free Software Foundation, Inc., // 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. /** \file \brief TLVPacket unit tests */ //#include "TLVPacket.test.hh" //#include "TLVPacket.test.ih" // Custom includes #include "TLVPacket.hh" #include "../DefaultBundle/EthernetPacket.hh" #include "../../Utils/auto_unit_test.hh" #include <boost/test/test_tools.hpp> #define prefix_ ///////////////////////////////cc.p//////////////////////////////////////// using namespace senf; namespace { void check_TLVPacket(GenericTLVPacket &tlvPacket, boost::uint8_t type, boost::uint32_t length) { BOOST_CHECK_EQUAL( tlvPacket->type(), type ); BOOST_CHECK_EQUAL( tlvPacket->length(), length ); BOOST_CHECK_EQUAL( tlvPacket->value().size(), int(length) ); std::ostringstream oss (std::ostringstream::out); SENF_CHECK_NO_THROW( tlvPacket.dump( oss)); senf::PacketData::iterator dataIterator (tlvPacket->value().begin()); for (unsigned i=0; i<length; i++) { BOOST_CHECK_EQUAL( *dataIterator, i ); dataIterator++; } } } BOOST_AUTO_UNIT_TEST(GenericTLVPacket_parse_packet_with_simple_length) { unsigned char data[] = { 0x01, // type 0x0A, // first bit not set, length=10 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09 // value }; GenericTLVPacket tlvPacket (GenericTLVPacket::create(data)); check_TLVPacket( tlvPacket, 0x01, 0x0Au ); } BOOST_AUTO_UNIT_TEST(GenericTLVPacket_parse_packet_with_extended_length) { unsigned char data[] = { 0x01, // type 0x81, // first and last bit set => one byte length following 0x0A, // length (10 bytes value) 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09 // value }; GenericTLVPacket tlvPacket (GenericTLVPacket::create(data)); check_TLVPacket( tlvPacket, 0x01, 0x0Au ); } BOOST_AUTO_UNIT_TEST(GenericTLVPacket_create_packet_with_simple_length) { unsigned char value[] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09 }; GenericTLVPacket tlvPacket (GenericTLVPacket::create()); tlvPacket->type() = 42u; tlvPacket->value( value); tlvPacket.finalizeThis(); check_TLVPacket( tlvPacket, 42u, 0x0Au ); unsigned char data[] = { 0x2a, // type 0x0A, // first bit not set, length=10 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09 // value }; BOOST_CHECK( equal( tlvPacket.data().begin(), tlvPacket.data().end(), data )); } BOOST_AUTO_UNIT_TEST(GenericTLVPacket_create_packet_with_extended_length) { unsigned char value[255]; for (unsigned i=0; i<sizeof(value); i++) value[i] = i; GenericTLVPacket tlvPacket (GenericTLVPacket::create()); tlvPacket->maxLengthValue( DynamicTLVLengthParser::max_value); tlvPacket->type() = 42u; tlvPacket->value( value); tlvPacket.finalizeThis(); check_TLVPacket( tlvPacket, 42u, sizeof(value) ); unsigned char data[] = { 0x2a, // type 0x81, // first and last bit set => one byte length following 0xff, // length (255 bytes value) 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09 // first bytes of value }; BOOST_CHECK( equal( tlvPacket.data().begin(), boost::next( tlvPacket.data().begin(), sizeof(data)), data )); } BOOST_AUTO_UNIT_TEST(GenericTLVPacket_create_invalid_packet) { GenericTLVPacket tlvPacket (GenericTLVPacket::create()); tlvPacket->type() = 42u; tlvPacket.finalizeThis(); unsigned char value[255]; for (unsigned i=0; i<sizeof(value); i++) value[i] = i; BOOST_CHECK_THROW( tlvPacket->value( value), TLVLengthException); tlvPacket->maxLengthValue( sizeof(value)); tlvPacket->value( value); tlvPacket.finalizeThis(); check_TLVPacket( tlvPacket, 42u, sizeof(value) ); } namespace { struct TestMacAddressTLVPacketParser : public BaseTLVPacketParser { # include SENF_PARSER() SENF_PARSER_INHERIT ( BaseTLVPacketParser ); SENF_PARSER_VECTOR ( value, bytes(length), senf::MACAddressParser ); SENF_PARSER_FINALIZE( TestMacAddressTLVPacketParser ); }; struct TestMacAddressTLVPacketType : public PacketTypeBase, public PacketTypeMixin<TestMacAddressTLVPacketType> { typedef PacketTypeMixin<TestMacAddressTLVPacketType> mixin; typedef TestMacAddressTLVPacketParser parser; using mixin::nextPacketRange; using mixin::init; using mixin::initSize; static void finalize(ConcretePacket<TestMacAddressTLVPacketType> p) { p->shrinkLength(); } }; typedef ConcretePacket<TestMacAddressTLVPacketType> TestMacAddressTLVPacket; } BOOST_AUTO_UNIT_TEST(TestMacAddressTLVPacket_create) { TestMacAddressTLVPacket tlvPacket (TestMacAddressTLVPacket::create()); tlvPacket->type() = 42; tlvPacket->value().push_back( senf::MACAddress::from_string("01:23:45:67:89:ab") ); tlvPacket->value().push_back( senf::MACAddress::from_string("cd:ef:01:23:45:67") ); tlvPacket.finalizeThis(); unsigned char data[] = { 0x2a, // type 0x0c, // length 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0x01, 0x23, 0x45, 0x67 // value }; BOOST_CHECK( equal( tlvPacket.data().begin(), tlvPacket.data().end(), data )); } ///////////////////////////////cc.e//////////////////////////////////////// #undef prefix_ // Local Variables: // mode: c++ // fill-column: 100 // c-file-style: "senf" // indent-tabs-mode: nil // ispell-local-dictionary: "american" // compile-command: "scons -u test" // comment-column: 40 // End: