Packets/80221Bundle: more GenericTLVBase integration; removed GenericTLVPacket; some...
[senf.git] / senf / Packets / 80221Bundle / TLVParser.test.cc
1 // $Id$
2 //
3 // Copyright (C) 2007
4 // Fraunhofer Institute for Open Communication Systems (FOKUS)
5 // Competence Center NETwork research (NET), St. Augustin, GERMANY
6 //     Thorsten Horstmann <tho@berlios.de>
7 //
8 // This program is free software; you can redistribute it and/or modify
9 // it under the terms of the GNU General Public License as published by
10 // the Free Software Foundation; either version 2 of the License, or
11 // (at your option) any later version.
12 //
13 // This program is distributed in the hope that it will be useful,
14 // but WITHOUT ANY WARRANTY; without even the implied warranty of
15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 // GNU General Public License for more details.
17 //
18 // You should have received a copy of the GNU General Public License
19 // along with this program; if not, write to the
20 // Free Software Foundation, Inc.,
21 // 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
22
23 /** \file
24     \brief TLVParser unit tests */
25
26 //#include "TLVParser.test.hh"
27 //#include "TLVParser.test.ih"
28
29 // Custom includes
30 #include "TLVParser.hh"
31 #include <senf/Packets/DefaultBundle/EthernetPacket.hh>
32
33 #include <senf/Utils/auto_unit_test.hh>
34 #include <boost/test/test_tools.hpp>
35
36 #define prefix_
37 ///////////////////////////////cc.p////////////////////////////////////////
38
39 using namespace senf;
40
41 namespace {
42     struct VoidPacket : public PacketTypeBase
43     {};
44                            
45 #define CHECK_TLVParser(tlvParser, ptype, plength)                          \
46 {                                                                           \
47     BOOST_CHECK_EQUAL( tlvParser.type(),         ptype   );                 \
48     BOOST_CHECK_EQUAL( tlvParser.length(),       plength );                 \
49     BOOST_CHECK_EQUAL( tlvParser.value().size(), int(plength) );            \
50     senf::PacketData::iterator dataIterator (tlvParser.value().begin());    \
51     for (unsigned i=0; i<plength; i++) {                                    \
52         BOOST_CHECK_EQUAL( *dataIterator, i );                              \
53         dataIterator++;                                                     \
54     }                                                                       \
55 }
56 }
57
58
59 BOOST_AUTO_UNIT_TEST(MIHGenericTLVParser_parse_with_simple_length)
60 {
61     PacketInterpreterBase::byte data[] = {
62         0x01, // type
63         0x0A, // first bit not set, length=10
64         0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09 // value
65     };
66     PacketInterpreterBase::ptr p (PacketInterpreter<VoidPacket>::create(data));
67     MIHGenericTLVParser tlvParser( p->data().begin(), &p->data());
68     CHECK_TLVParser( tlvParser, 0x01, 0x0Au );
69 }
70
71
72 BOOST_AUTO_UNIT_TEST(MIHGenericTLVParser_parse_with_extended_length)
73 {
74     PacketInterpreterBase::byte data[] = {
75         0x01, // type
76         0x81, // first and last bit set => one byte length following
77         0x0A, // length (10 = 138 bytes value follows)
78         0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 
79         0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 
80         0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d,
81         0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 
82         0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 
83         0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b,
84         0x3c, 0x3d, 0x3e, 0x3f, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 
85         0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 
86         0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 
87         0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, 0x60, 0x61, 0x62, 0x63, 
88         0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d,
89         0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 
90         0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 0x80, 0x81, 
91         0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89
92     };
93     PacketInterpreterBase::ptr p (PacketInterpreter<VoidPacket>::create(data));
94     MIHGenericTLVParser tlvParser( p->data().begin(), &p->data());
95     CHECK_TLVParser( tlvParser, 0x01, 0x8au );
96 }
97
98
99 BOOST_AUTO_UNIT_TEST(MIHGenericTLVParser_create_with_simple_length)
100 {
101     PacketInterpreterBase::byte value[] = {
102            0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09
103     };
104     PacketInterpreterBase::ptr p (PacketInterpreter<VoidPacket>::create(2u));
105     MIHGenericTLVParser tlvParser( p->data().begin(), &p->data());
106     tlvParser.type() = 42u;
107     tlvParser.value( value);
108     tlvParser.finalizeLength();
109
110     CHECK_TLVParser( tlvParser, 42u, 0x0Au );
111
112     PacketInterpreterBase::byte data[] = {
113         0x2a, // type
114         0x0A, // first bit not set, length=10
115         0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09 // value
116     };
117     SENF_CHECK_EQUAL_COLLECTIONS( data, data+sizeof(data),
118             p->data().begin(), p->data().end() );
119 }
120
121
122 BOOST_AUTO_UNIT_TEST(MIHGenericTLVParser_create_with_extended_length)
123 {
124     PacketInterpreterBase::byte value[255];
125     for (unsigned i=0; i<sizeof(value); i++)
126         value[i] = i;
127     PacketInterpreterBase::ptr p (PacketInterpreter<VoidPacket>::create(2u));
128     MIHGenericTLVParser tlvParser( p->data().begin(), &p->data());
129     tlvParser.maxLengthValue( MIHTLVLengthParser::max_value);
130     tlvParser.type() = 42u;
131     tlvParser.value( value);
132     tlvParser.finalizeLength();
133
134     CHECK_TLVParser( tlvParser, 42u, sizeof(value) );
135
136     PacketInterpreterBase::byte data[] = {
137         0x2a, // type
138         0x81, // first and last bit set => one byte length following
139         0x7f, // length (127 = 255 bytes value)
140         0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09 // first bytes of value
141     };
142     SENF_CHECK_EQUAL_COLLECTIONS( data, data+sizeof(data),
143             p->data().begin(), boost::next( p->data().begin(), sizeof(data)) );
144 }
145
146
147 BOOST_AUTO_UNIT_TEST(MIHGenericTLVParser_create_invalid)
148 {
149     PacketInterpreterBase::ptr p (PacketInterpreter<VoidPacket>::create(2u));
150     MIHGenericTLVParser tlvParser( p->data().begin(), &p->data());
151     tlvParser.type() = 42u;
152     tlvParser.finalizeLength();
153
154     PacketInterpreterBase::byte value[255];
155     for (unsigned i=0; i<sizeof(value); i++)
156         value[i] = i;
157
158     BOOST_CHECK_THROW( tlvParser.value( value), MIHTLVLengthException);
159     tlvParser.maxLengthValue( sizeof(value));
160     tlvParser.value( value);
161     tlvParser.finalizeLength();
162     CHECK_TLVParser( tlvParser, 42u, sizeof(value) );
163 }
164
165
166 namespace {
167
168     struct TestMacAddressTLVPacketParser : public MIHBaseTLVParser
169     {
170     #   include SENF_PARSER()
171         SENF_PARSER_INHERIT ( MIHBaseTLVParser );
172         SENF_PARSER_VECTOR  ( value, bytes(length), senf::MACAddressParser );
173         SENF_PARSER_FINALIZE( TestMacAddressTLVPacketParser );
174     };
175
176     struct TestMacAddressTLVPacketType
177         : public PacketTypeBase,
178           public PacketTypeMixin<TestMacAddressTLVPacketType>
179     {
180         typedef PacketTypeMixin<TestMacAddressTLVPacketType> mixin;
181         typedef TestMacAddressTLVPacketParser parser;
182
183         using mixin::nextPacketRange;
184         using mixin::init;
185         using mixin::initSize;
186
187         static void finalize(ConcretePacket<TestMacAddressTLVPacketType> p) {
188             p->finalizeLength();
189         }
190     };
191     typedef ConcretePacket<TestMacAddressTLVPacketType> TestMacAddressTLVPacket;
192 }
193
194 BOOST_AUTO_UNIT_TEST(TestMacAddressTLVPacket_create)
195 {
196     TestMacAddressTLVPacket tlvPacket (TestMacAddressTLVPacket::create());
197     tlvPacket->type() = 42;
198     tlvPacket->value().push_back( senf::MACAddress::from_string("01:23:45:67:89:ab") );
199     tlvPacket->value().push_back( senf::MACAddress::from_string("cd:ef:01:23:45:67") );
200     tlvPacket.finalizeThis();
201
202     unsigned char data[] = {
203         0x2a, // type
204         0x0c, // length
205         0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0x01, 0x23, 0x45, 0x67  // value
206     };
207     BOOST_CHECK( equal( tlvPacket.data().begin(), tlvPacket.data().end(), data ));
208 }
209
210
211 ///////////////////////////////cc.e////////////////////////////////////////
212 #undef prefix_
213
214 \f
215 // Local Variables:
216 // mode: c++
217 // fill-column: 100
218 // c-file-style: "senf"
219 // indent-tabs-mode: nil
220 // ispell-local-dictionary: "american"
221 // compile-command: "scons -u test"
222 // comment-column: 40
223 // End: