Packets: Completely restructured #includes, introduced central Packets.hh file
[senf.git] / Packets / PacketInterpreter.test.cc
1 // Copyright (C) 2007 
2 // Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
3 // Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
4 //     Stefan Bund <g0dil@berlios.de>
5 //
6 // This program is free software; you can redistribute it and/or modify
7 // it under the terms of the GNU General Public License as published by
8 // the Free Software Foundation; either version 2 of the License, or
9 // (at your option) any later version.
10 //
11 // This program is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 // GNU General Public License for more details.
15 //
16 // You should have received a copy of the GNU General Public License
17 // along with this program; if not, write to the
18 // Free Software Foundation, Inc.,
19 // 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
20
21 /** \file
22     \brief PacketInterpreter.test unit tests */
23
24 //#include "PacketInterpreter.test.hh"
25 //#include "PacketInterpreter.test.ih"
26
27 // Custom includes
28 #include "Packets.hh"
29
30 #include <boost/test/auto_unit_test.hpp>
31 #include <boost/test/test_tools.hpp>
32
33 #define prefix_
34 ///////////////////////////////cc.p////////////////////////////////////////
35
36 namespace {
37     struct VoidPacket : public senf::PacketTypeBase {
38         typedef senf::ConcretePacket<VoidPacket> packet;
39         static optional_range nextPacketRange(packet p)
40             { return range(p.data().begin(), p.data().end()); }
41     };
42 }
43
44 BOOST_AUTO_UNIT_TEST(packetInterpreterBase)
45 {
46     {
47         senf::PacketInterpreter<VoidPacket>::ptr pi2 (senf::PacketInterpreter<VoidPacket>::create());
48         senf::PacketInterpreter<VoidPacket>::ptr pi1 (senf::PacketInterpreter<VoidPacket>::createBefore(pi2));
49   
50         pi2->data().insert(pi2->data().begin(),0x02);
51         BOOST_CHECK_EQUAL( pi1->data().size(), 1u );
52         BOOST_CHECK_EQUAL( pi2->data().size(), 1u );
53         
54         senf::PacketInterpreter<VoidPacket>::ptr pi3 (pi2->parseNextAs<VoidPacket>());
55         BOOST_REQUIRE( pi3 );
56         BOOST_CHECK( pi2 == pi1->next() );
57         BOOST_CHECK( pi3 == pi2->next() );
58         BOOST_CHECK( ! pi3->next() );
59         BOOST_CHECK( pi2 == pi3->prev() );
60         BOOST_CHECK( pi1 == pi2->prev() );
61         BOOST_CHECK( ! pi1->prev() );
62         BOOST_CHECK( pi2->is<VoidPacket>() );
63         BOOST_CHECK( pi2->as<VoidPacket>() == pi2 );
64         BOOST_CHECK( pi2->parseNextAs(senf::PacketInterpreter<VoidPacket>::factory()) );
65         BOOST_CHECK( pi2->typeId() == pi1->typeId() );
66         
67         pi1->data().insert(pi1->data().begin(),2,0x01u);
68         BOOST_CHECK_EQUAL( pi1->data().size(), 3u );
69         BOOST_CHECK_EQUAL( pi2->data().size(), 1u );
70         BOOST_CHECK_EQUAL( pi3->data().size(), 1u );
71
72         senf::PacketInterpreter<VoidPacket>::ptr pi2b (pi2->clone());
73         BOOST_REQUIRE( pi2b->next() );
74         BOOST_CHECK( ! pi2b->next()->next() );
75         BOOST_CHECK( ! pi2b->prev() );
76
77         pi2b->data().insert(pi2b->data().begin(),0x03u);
78         BOOST_CHECK_EQUAL( pi2->data().size(), 1u );
79         BOOST_CHECK_EQUAL( pi2b->data().size(), 2u );
80
81         BOOST_CHECK_EQUAL( pi1->data().size(), pi1->nextPacketRange()->size() );
82         pi1->append(pi2b);
83         BOOST_CHECK_EQUAL( pi1->data().size(), 2u );
84         BOOST_REQUIRE( pi1->next() );
85         BOOST_REQUIRE( pi1->next()->next() );
86         BOOST_CHECK( ! pi1->next()->next()->next() );
87     }
88
89 }
90
91 namespace {
92     struct OtherPacket 
93         : public senf::PacketTypeBase,
94           public senf::PacketTypeMixin<OtherPacket>
95     {
96         using senf::PacketTypeMixin<OtherPacket>::nextPacketRange;
97         typedef senf::ConcretePacket<OtherPacket> packet;
98         static size_type initSize()     { return 8u; }
99         static size_type initHeadSize() { return 6u; }
100         static void init(packet p)            { p.data()[0] = 0x01u; }
101     };
102 }
103
104 BOOST_AUTO_UNIT_TEST(packetInterpreter)
105 {
106     {
107         BOOST_CHECK_THROW( senf::PacketInterpreter<OtherPacket>::create(4u), 
108                            senf::TruncatedPacketException );
109         senf::PacketInterpreter<OtherPacket>::ptr p
110             (senf::PacketInterpreter<OtherPacket>::create(12u));
111         
112         BOOST_CHECK_EQUAL( p->data().size(), 12u );
113         BOOST_CHECK_EQUAL( std::distance(p->data().begin(),p->data().end()), 12 );
114         BOOST_CHECK_EQUAL( p->data()[0], 0x01u );
115         
116         senf::PacketInterpreter<VoidPacket>::ptr p2
117             (p->parseNextAs<VoidPacket>());
118         BOOST_CHECK_EQUAL( p2->data().size(), 4u );
119         BOOST_CHECK_EQUAL( std::distance(p->data().begin(),p2->data().begin()), 6 );
120
121         senf::PacketInterpreter<OtherPacket>::ptr pc
122             (p->clone());
123         BOOST_CHECK_EQUAL( p->data().size(), 12u );
124         BOOST_CHECK( p->next() );
125         BOOST_CHECK( ! p->next()->next() );
126     }
127
128     {
129         BOOST_CHECK_NO_THROW( 
130             senf::PacketInterpreter<OtherPacket>::create(4u,senf::PacketInterpreterBase::noinit));
131         senf::PacketInterpreter<OtherPacket>::ptr p
132             (senf::PacketInterpreter<OtherPacket>::create(senf::PacketInterpreterBase::noinit));
133         BOOST_CHECK_EQUAL( p->data().size(), 0u );
134     }
135
136     {
137         senf::PacketInterpreter<VoidPacket>::byte data[] = { 0x01, 0x02, 0x03, 0x04 };
138         senf::PacketInterpreter<VoidPacket>::ptr p
139             (senf::PacketInterpreter<VoidPacket>::create(data));
140
141         BOOST_CHECK_EQUAL( p->data().size(), 4u );
142         BOOST_CHECK_EQUAL( std::distance(p->data().begin(),p->data().end()), 4 );
143         BOOST_CHECK( std::equal(p->data().begin(), p->data().end(), data) );
144     }
145
146     {
147         senf::PacketInterpreter<OtherPacket>::ptr p
148             (senf::PacketInterpreter<OtherPacket>::create(12u));
149         senf::PacketInterpreter<VoidPacket>::ptr p2
150             (senf::PacketInterpreter<VoidPacket>::createAfter(p));
151         BOOST_CHECK_EQUAL( p2->data().size(), 0u );
152         BOOST_CHECK_EQUAL( p->data().size(), 8u );
153         p2->data().insert(p2->data().begin(),0x01u);
154         BOOST_CHECK_EQUAL( p->data()[6], 0x01u );
155         BOOST_CHECK_EQUAL( p->data().size(), 9u );
156     }
157
158     {
159         senf::PacketInterpreter<OtherPacket>::ptr p
160             (senf::PacketInterpreter<OtherPacket>::create(12u));
161         senf::PacketInterpreter<OtherPacket>::ptr p2
162             (senf::PacketInterpreter<OtherPacket>::createAfter(
163                 p,senf::PacketInterpreterBase::noinit));
164         BOOST_CHECK_EQUAL( p2->data().size(), 0u );
165         BOOST_CHECK_EQUAL( p->data().size(), 8u );
166     }
167  
168     {
169         senf::PacketInterpreter<OtherPacket>::ptr p
170             (senf::PacketInterpreter<OtherPacket>::create(12u));
171         senf::PacketInterpreter<OtherPacket>::ptr p2
172             (senf::PacketInterpreter<OtherPacket>::createAfter(p,10u));
173         BOOST_CHECK_EQUAL( p2->data().size(), 10u );
174         BOOST_CHECK_EQUAL( p->data().size(), 18u );
175         BOOST_CHECK_EQUAL( p2->data()[0], 0x01u );
176         BOOST_CHECK_THROW( senf::PacketInterpreter<OtherPacket>::createAfter(p,4u),
177                            senf::TruncatedPacketException );
178         BOOST_CHECK_NO_THROW( senf::PacketInterpreter<OtherPacket>::createAfter(
179                                   p,4u,senf::PacketInterpreterBase::noinit) );
180     }
181
182     {
183         senf::PacketInterpreter<OtherPacket>::ptr p
184             (senf::PacketInterpreter<OtherPacket>::create(10u));
185         senf::PacketInterpreter<VoidPacket>::byte data[] = { 0x01, 0x02, 0x03, 0x04 };
186         senf::PacketInterpreter<OtherPacket>::ptr p2
187             (senf::PacketInterpreter<OtherPacket>::createAfter(p,data));
188         BOOST_CHECK_EQUAL( p2->data().size(), 4u );
189         BOOST_CHECK_EQUAL( p->data().size(), 12u );
190         BOOST_CHECK_EQUAL( p2->data()[1], 0x02u );
191         BOOST_CHECK_EQUAL( p->data()[8], 0x03u );
192     }
193
194     {
195         senf::PacketInterpreter<OtherPacket>::ptr p
196             (senf::PacketInterpreter<OtherPacket>::create(10u));
197         senf::PacketInterpreter<OtherPacket>::ptr p2
198             (senf::PacketInterpreter<OtherPacket>::createBefore(p));
199
200         BOOST_CHECK_EQUAL( p2->data().size(), 18u );
201         BOOST_CHECK_EQUAL( p->data().size(), 10u );
202
203         senf::PacketInterpreter<OtherPacket>::ptr p3
204             (senf::PacketInterpreter<OtherPacket>::createBefore(
205                 p,senf::PacketInterpreterBase::noinit));
206         
207         BOOST_CHECK_EQUAL( p3->data().size(), 10u );
208     }
209     
210 }
211
212 // fields() ist tested in DefaultBundle/EthernetPacket.test.cc
213 // initSize() and initHeadSize() are already tested indirectly above
214
215 BOOST_AUTO_UNIT_TEST(packetInterpreter_factory)
216 {
217     senf::PacketInterpreterBase::byte data[] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06 };
218     senf::PacketInterpreterBase::factory_t factory (
219         senf::PacketInterpreter<OtherPacket>::factory());
220
221     BOOST_CHECK( ! senf::PacketInterpreterBase::no_factory() );
222     BOOST_REQUIRE( factory );
223
224     BOOST_CHECK( factory->create()->is<OtherPacket>() );
225     BOOST_CHECK_EQUAL( factory->create()->data().size(), 8u );
226     BOOST_CHECK_EQUAL( factory->create(senf::PacketInterpreterBase::noinit)->data().size(), 0u );
227     BOOST_CHECK_EQUAL( factory->create(12u)->data().size(), 12u );
228     BOOST_CHECK_EQUAL( 
229         factory->create(4u, senf::PacketInterpreterBase::noinit)->data().size(), 4u );
230     BOOST_CHECK_EQUAL( factory->create(data)->data().size(), 6u );
231
232     {
233         senf::PacketInterpreter<VoidPacket>::ptr p
234             (senf::PacketInterpreter<VoidPacket>::create());
235
236         BOOST_CHECK_EQUAL( p->data().size(), 0u);
237         BOOST_CHECK( factory->createAfter(p)->is<OtherPacket>() );
238         BOOST_REQUIRE( p->next() );
239         BOOST_CHECK( ! p->next()->next() );
240
241         BOOST_CHECK_EQUAL( factory->createAfter(p)->data().size(), 8u );
242         BOOST_CHECK_EQUAL( p->data().size(), 8u );
243         BOOST_CHECK( ! p->next()->next() );
244
245         BOOST_CHECK_EQUAL( 
246             factory->createAfter(p, senf::PacketInterpreterBase::noinit)->data().size(), 0u );
247         BOOST_CHECK_EQUAL( p->data().size(), 0u );
248         BOOST_CHECK( ! p->next()->next() );
249
250         BOOST_CHECK_EQUAL( factory->createAfter(p,12u)->data().size(), 12u );
251         BOOST_CHECK_EQUAL( p->data().size(), 12u );
252         BOOST_CHECK( ! p->next()->next() );
253
254         BOOST_CHECK_EQUAL( 
255             factory->createAfter(p,4u, senf::PacketInterpreterBase::noinit)->data().size(), 4u );
256         BOOST_CHECK_EQUAL( p->data().size(), 4u );
257         BOOST_CHECK( ! p->next()->next() );
258
259         BOOST_CHECK_EQUAL( factory->createAfter(p, data)->data().size(), 6u );
260         BOOST_CHECK_EQUAL( p->data().size(), 6u );
261         BOOST_CHECK( ! p->next()->next() );
262     }
263
264     {
265         senf::PacketInterpreter<VoidPacket>::ptr p
266             (senf::PacketInterpreter<VoidPacket>::create(4u));
267         
268         BOOST_CHECK_EQUAL( factory->createBefore(p)->data().size(), 12u );
269         BOOST_REQUIRE( p->prev() );
270         BOOST_CHECK( ! p->prev()->prev() );
271         BOOST_CHECK_EQUAL( p->prev()->data().size(), 12u );
272         
273         BOOST_CHECK_EQUAL( 
274             factory->createBefore(p,senf::PacketInterpreterBase::noinit)->data().size(), 4u );
275         BOOST_REQUIRE( p->prev() );
276         BOOST_CHECK( ! p->prev()->prev() );
277         BOOST_CHECK_EQUAL( p->prev()->data().size(), 4u );
278     }
279
280     {
281         senf::PacketInterpreter<VoidPacket>::ptr p
282             (senf::PacketInterpreter<VoidPacket>::create(12u));
283
284         senf::PacketInterpreterBase::ptr p2 (p->parseNextAs(factory));
285         BOOST_CHECK( p2->is<OtherPacket>() );
286         BOOST_CHECK( ! p2->is<VoidPacket>() );
287         BOOST_CHECK_EQUAL( boost::size(*p2->nextPacketRange()), 4u );
288     }
289
290 }
291
292 ///////////////////////////////cc.e////////////////////////////////////////
293 #undef prefix_
294
295 \f
296 // Local Variables:
297 // mode: c++
298 // fill-column: 100
299 // c-file-style: "senf"
300 // indent-tabs-mode: nil
301 // ispell-local-dictionary: "american"
302 // compile-command: "scons -u test"
303 // comment-column: 40
304 // End: