switch to new MPL based Fraunhofer FOKUS Public License
[senf.git] / senf / Packets / PacketInterpreter.test.cc
1 // $Id$
2 //
3 // Copyright (C) 2007
4 // Fraunhofer Institute for Open Communication Systems (FOKUS)
5 //
6 // The contents of this file are subject to the Fraunhofer FOKUS Public License
7 // Version 1.0 (the "License"); you may not use this file except in compliance
8 // with the License. You may obtain a copy of the License at 
9 // http://senf.berlios.de/license.html
10 //
11 // The Fraunhofer FOKUS Public License Version 1.0 is based on, 
12 // but modifies the Mozilla Public License Version 1.1.
13 // See the full license text for the amendments.
14 //
15 // Software distributed under the License is distributed on an "AS IS" basis, 
16 // WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License 
17 // for the specific language governing rights and limitations under the License.
18 //
19 // The Original Code is Fraunhofer FOKUS code.
20 //
21 // The Initial Developer of the Original Code is Fraunhofer-Gesellschaft e.V. 
22 // (registered association), Hansastraße 27 c, 80686 Munich, Germany.
23 // All Rights Reserved.
24 //
25 // Contributor(s):
26 //   Stefan Bund <g0dil@berlios.de>
27
28 /** \file
29     \brief PacketInterpreter unit tests */
30
31 //#include "PacketInterpreter.test.hh"
32 //#include "PacketInterpreter.test.ih"
33
34 // Custom includes
35 #include "Packets.hh"
36
37 #include <senf/Utils/auto_unit_test.hh>
38 #include <boost/test/test_tools.hpp>
39
40 #define prefix_
41 //-/////////////////////////////////////////////////////////////////////////////////////////////////
42
43 namespace {
44     struct VoidPacket : public senf::PacketTypeBase {
45         typedef senf::ConcretePacket<VoidPacket> packet;
46         static optional_range nextPacketRange(packet p)
47             { return range(p.data().begin(), p.data().end()); }
48     };
49 }
50
51 SENF_AUTO_UNIT_TEST(packetInterpreterBase)
52 {
53     {
54         senf::PacketInterpreter<VoidPacket>::ptr pi2 (senf::PacketInterpreter<VoidPacket>::create());
55         senf::PacketInterpreter<VoidPacket>::ptr pi1 (senf::PacketInterpreter<VoidPacket>::createBefore(pi2));
56
57         pi2->data().insert(pi2->data().begin(),0x02);
58         BOOST_CHECK_EQUAL( pi1->data().size(), 1u );
59         BOOST_CHECK_EQUAL( pi2->data().size(), 1u );
60
61         senf::PacketInterpreter<VoidPacket>::ptr pi3 (pi2->parseNextAs<VoidPacket>());
62         BOOST_REQUIRE( pi3 );
63         BOOST_CHECK( pi2 == pi1->next() );
64         BOOST_CHECK( pi3 == pi2->next() );
65         BOOST_CHECK( ! pi3->next() );
66         BOOST_CHECK( pi2 == pi3->prev() );
67         BOOST_CHECK( pi1 == pi2->prev() );
68         BOOST_CHECK( ! pi1->prev() );
69         BOOST_CHECK( pi2->is<VoidPacket>() );
70         BOOST_CHECK( pi2->as<VoidPacket>() == pi2 );
71         BOOST_CHECK( pi2->parseNextAs(senf::PacketInterpreter<VoidPacket>::factory()) );
72         BOOST_CHECK( pi2->typeId() == pi1->typeId() );
73
74         pi1->data().insert(pi1->data().begin(),2,0x01u);
75         BOOST_CHECK_EQUAL( pi1->data().size(), 3u );
76         BOOST_CHECK_EQUAL( pi2->data().size(), 1u );
77         BOOST_CHECK_EQUAL( pi3->data().size(), 1u );
78
79         senf::PacketInterpreter<VoidPacket>::ptr pi2b (pi2->clone());
80         BOOST_REQUIRE( pi2b->next() );
81         BOOST_CHECK( ! pi2b->next()->next() );
82         BOOST_CHECK( ! pi2b->prev() );
83
84         pi2b->data().insert(pi2b->data().begin(),0x03u);
85         BOOST_CHECK_EQUAL( pi2->data().size(), 1u );
86         BOOST_CHECK_EQUAL( pi2b->data().size(), 2u );
87
88         BOOST_CHECK_EQUAL( pi1->data().size(), unsigned(pi1->nextPacketRange()->size()) );
89         pi1->append(pi2b);
90         BOOST_CHECK_EQUAL( pi1->data().size(), 2u );
91         BOOST_REQUIRE( pi1->next() );
92         BOOST_REQUIRE( pi1->next()->next() );
93         BOOST_CHECK( ! pi1->next()->next()->next() );
94     }
95
96 }
97
98 namespace {
99     struct OtherPacket
100         : public senf::PacketTypeBase,
101           public senf::PacketTypeMixin<OtherPacket>
102     {
103         using senf::PacketTypeMixin<OtherPacket>::nextPacketRange;
104         typedef senf::ConcretePacket<OtherPacket> packet;
105         static size_type initSize()     { return 8u; }
106         static size_type initHeadSize() { return 6u; }
107         static void init(packet p)            { p.data()[0] = 0x01u; }
108     };
109 }
110
111 SENF_AUTO_UNIT_TEST(packetInterpreter)
112 {
113     typedef senf::PacketInterpreterBase::size_type size_type;
114     {
115         BOOST_CHECK_THROW( senf::PacketInterpreter<OtherPacket>::create(size_type(4u)),
116                            senf::TruncatedPacketException );
117         senf::PacketInterpreter<OtherPacket>::ptr p
118             (senf::PacketInterpreter<OtherPacket>::create(size_type(12u)));
119
120         BOOST_CHECK_EQUAL( p->data().size(), 12u );
121         BOOST_CHECK_EQUAL( std::distance(p->data().begin(),p->data().end()), 12 );
122         BOOST_CHECK_EQUAL( p->data()[0], 0x01u );
123
124         senf::PacketInterpreter<VoidPacket>::ptr p2
125             (p->parseNextAs<VoidPacket>());
126         BOOST_CHECK_EQUAL( p2->data().size(), 4u );
127         BOOST_CHECK_EQUAL( std::distance(p->data().begin(),p2->data().begin()), 6 );
128
129         senf::PacketInterpreter<OtherPacket>::ptr pc
130             (p->clone());
131         BOOST_CHECK_EQUAL( p->data().size(), 12u );
132         BOOST_CHECK( p->next() );
133         BOOST_CHECK( ! p->next()->next() );
134     }
135
136     {
137         SENF_CHECK_NO_THROW(
138             senf::PacketInterpreter<OtherPacket>::create(4u,senf::noinit));
139         senf::PacketInterpreter<OtherPacket>::ptr p
140             (senf::PacketInterpreter<OtherPacket>::create(senf::noinit));
141         BOOST_CHECK_EQUAL( p->data().size(), 0u );
142     }
143
144     {
145         senf::PacketInterpreter<VoidPacket>::byte data[] = { 0x01, 0x02, 0x03, 0x04 };
146         senf::PacketInterpreter<VoidPacket>::ptr p
147             (senf::PacketInterpreter<VoidPacket>::create(data));
148
149         BOOST_CHECK_EQUAL( p->data().size(), 4u );
150         BOOST_CHECK_EQUAL( std::distance(p->data().begin(),p->data().end()), 4 );
151         BOOST_CHECK( std::equal(p->data().begin(), p->data().end(), data) );
152     }
153
154     {
155         senf::PacketInterpreter<OtherPacket>::ptr p
156             (senf::PacketInterpreter<OtherPacket>::create(size_type(12u)));
157         senf::PacketInterpreter<VoidPacket>::ptr p2
158             (senf::PacketInterpreter<VoidPacket>::createAfter(p));
159         BOOST_CHECK_EQUAL( p2->data().size(), 0u );
160         BOOST_CHECK_EQUAL( p->data().size(), 8u );
161         p2->data().insert(p2->data().begin(),0x01u);
162         BOOST_CHECK_EQUAL( p->data()[6], 0x01u );
163         BOOST_CHECK_EQUAL( p->data().size(), 9u );
164     }
165
166     {
167         senf::PacketInterpreter<OtherPacket>::ptr p
168             (senf::PacketInterpreter<OtherPacket>::create(size_type(12u)));
169         senf::PacketInterpreter<OtherPacket>::ptr p2
170             (senf::PacketInterpreter<OtherPacket>::createAfter(
171                 p,senf::noinit));
172         BOOST_CHECK_EQUAL( p2->data().size(), 0u );
173         BOOST_CHECK_EQUAL( p->data().size(), 8u );
174     }
175
176     {
177         senf::PacketInterpreter<OtherPacket>::ptr p
178             (senf::PacketInterpreter<OtherPacket>::create(size_type(12u)));
179         senf::PacketInterpreter<OtherPacket>::ptr p2
180             (senf::PacketInterpreter<OtherPacket>::createAfter(p, size_type(10u)));
181         BOOST_CHECK_EQUAL( p2->data().size(), 10u );
182         BOOST_CHECK_EQUAL( p->data().size(), 18u );
183         BOOST_CHECK_EQUAL( p2->data()[0], 0x01u );
184         BOOST_CHECK_THROW( senf::PacketInterpreter<OtherPacket>::createAfter(p, size_type(4u)),
185                            senf::TruncatedPacketException );
186         SENF_CHECK_NO_THROW( senf::PacketInterpreter<OtherPacket>::createAfter(
187                                   p,4u,senf::noinit) );
188     }
189
190     {
191         senf::PacketInterpreter<OtherPacket>::ptr p
192             (senf::PacketInterpreter<OtherPacket>::create(size_type(10u)));
193         senf::PacketInterpreter<VoidPacket>::byte data[] = { 0x01, 0x02, 0x03, 0x04 };
194         senf::PacketInterpreter<OtherPacket>::ptr p2
195             (senf::PacketInterpreter<OtherPacket>::createAfter(p,data));
196         BOOST_CHECK_EQUAL( p2->data().size(), 4u );
197         BOOST_CHECK_EQUAL( p->data().size(), 12u );
198         BOOST_CHECK_EQUAL( p2->data()[1], 0x02u );
199         BOOST_CHECK_EQUAL( p->data()[8], 0x03u );
200     }
201
202     {
203         senf::PacketInterpreter<OtherPacket>::ptr p
204             (senf::PacketInterpreter<OtherPacket>::create(size_type(10u)));
205         senf::PacketInterpreter<OtherPacket>::ptr p2
206             (senf::PacketInterpreter<OtherPacket>::createBefore(p));
207
208         BOOST_CHECK_EQUAL( p2->data().size(), 18u );
209         BOOST_CHECK_EQUAL( p->data().size(), 10u );
210
211         senf::PacketInterpreter<OtherPacket>::ptr p3
212             (senf::PacketInterpreter<OtherPacket>::createBefore(
213                 p,senf::noinit));
214
215         BOOST_CHECK_EQUAL( p3->data().size(), 10u );
216
217         senf::PacketInterpreter<OtherPacket>::ptr p4
218             (senf::PacketInterpreter<OtherPacket>::createInsertBefore(p));
219
220         BOOST_CHECK_EQUAL( p->data().size(), 10u );
221         BOOST_CHECK_EQUAL( p4->data().size(), 18u );
222         BOOST_CHECK_EQUAL( p3->data().size(), 18u );
223     }
224
225 }
226
227 // fields() is tested in DefaultBundle/EthernetPacket.test.cc
228 // initSize() and initHeadSize() are already tested indirectly above
229
230 SENF_AUTO_UNIT_TEST(packetInterpreter_factory)
231 {
232     typedef senf::PacketInterpreterBase::size_type size_type;
233
234     senf::PacketInterpreterBase::byte data[] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06 };
235     senf::PacketInterpreterBase::factory_t factory (
236         senf::PacketInterpreter<OtherPacket>::factory());
237
238     BOOST_CHECK( ! senf::PacketInterpreterBase::no_factory() );
239     BOOST_REQUIRE( factory );
240
241     BOOST_CHECK( factory->create()->is<OtherPacket>() );
242     BOOST_CHECK_EQUAL( factory->create()->data().size(), 8u );
243     BOOST_CHECK_EQUAL( factory->create(senf::noinit)->data().size(), 0u );
244     BOOST_CHECK_EQUAL( factory->create(size_type(12u))->data().size(), 12u );
245     BOOST_CHECK_EQUAL(
246         factory->create(4u, senf::noinit)->data().size(), 4u );
247     BOOST_CHECK_EQUAL( factory->create(data)->data().size(), 6u );
248
249     {
250         senf::PacketInterpreter<VoidPacket>::ptr p
251             (senf::PacketInterpreter<VoidPacket>::create());
252
253         BOOST_CHECK_EQUAL( p->data().size(), 0u);
254         BOOST_CHECK( factory->createAfter(p)->is<OtherPacket>() );
255         BOOST_REQUIRE( p->next() );
256         BOOST_CHECK( ! p->next()->next() );
257
258         BOOST_CHECK_EQUAL( factory->createAfter(p)->data().size(), 8u );
259         BOOST_CHECK_EQUAL( p->data().size(), 8u );
260         BOOST_CHECK( ! p->next()->next() );
261
262         BOOST_CHECK_EQUAL(
263             factory->createAfter(p, senf::noinit)->data().size(), 0u );
264         BOOST_CHECK_EQUAL( p->data().size(), 0u );
265         BOOST_CHECK( ! p->next()->next() );
266
267         BOOST_CHECK_EQUAL( factory->createAfter(p, size_type(12u))->data().size(), 12u );
268         BOOST_CHECK_EQUAL( p->data().size(), 12u );
269         BOOST_CHECK( ! p->next()->next() );
270
271         BOOST_CHECK_EQUAL(
272             factory->createAfter(p,4u, senf::noinit)->data().size(), 4u );
273         BOOST_CHECK_EQUAL( p->data().size(), 4u );
274         BOOST_CHECK( ! p->next()->next() );
275
276         BOOST_CHECK_EQUAL( factory->createAfter(p, data)->data().size(), 6u );
277         BOOST_CHECK_EQUAL( p->data().size(), 6u );
278         BOOST_CHECK( ! p->next()->next() );
279     }
280
281     {
282         senf::PacketInterpreter<VoidPacket>::ptr p
283             (senf::PacketInterpreter<VoidPacket>::create(size_type(4u)));
284
285         BOOST_CHECK_EQUAL( factory->createBefore(p)->data().size(), 12u );
286         BOOST_REQUIRE( p->prev() );
287         BOOST_CHECK( ! p->prev()->prev() );
288         BOOST_CHECK_EQUAL( p->prev()->data().size(), 12u );
289
290         BOOST_CHECK_EQUAL( factory->createBefore(p,senf::noinit)->data().size(), 4u );
291         BOOST_REQUIRE( p->prev() );
292         BOOST_CHECK( ! p->prev()->prev() );
293         BOOST_CHECK_EQUAL( p->prev()->data().size(), 4u );
294
295         BOOST_CHECK_EQUAL( factory->createInsertBefore(p,senf::noinit)->data().size(), 4u );
296         BOOST_REQUIRE( p->prev() );
297         BOOST_REQUIRE( p->prev()->prev() );
298         BOOST_CHECK( ! p->prev()->prev()->prev() );
299     }
300
301     {
302         senf::PacketInterpreter<VoidPacket>::ptr p
303             (senf::PacketInterpreter<VoidPacket>::create(size_type(12u)));
304
305         senf::PacketInterpreterBase::ptr p2 (p->parseNextAs(factory));
306         BOOST_CHECK( p2->is<OtherPacket>() );
307         BOOST_CHECK( ! p2->is<VoidPacket>() );
308         BOOST_CHECK_EQUAL( unsigned(boost::size(*p2->nextPacketRange())), 4u );
309     }
310
311 }
312
313 //-/////////////////////////////////////////////////////////////////////////////////////////////////
314 #undef prefix_
315
316 \f
317 // Local Variables:
318 // mode: c++
319 // fill-column: 100
320 // c-file-style: "senf"
321 // indent-tabs-mode: nil
322 // ispell-local-dictionary: "american"
323 // compile-command: "scons -u test"
324 // comment-column: 40
325 // End: