unit test fix for last commit. hmpf.
[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->as<VoidPacket>() == pi2 );
70         BOOST_CHECK( pi2->parseNextAs(senf::PacketInterpreter<VoidPacket>::factory(), pi2->nextPacketRange()) );
71         BOOST_CHECK( pi2->typeId() == pi1->typeId() );
72
73         pi1->data().insert(pi1->data().begin(),2,0x01u);
74         BOOST_CHECK_EQUAL( pi1->data().size(), 3u );
75         BOOST_CHECK_EQUAL( pi2->data().size(), 1u );
76         BOOST_CHECK_EQUAL( pi3->data().size(), 1u );
77
78         senf::PacketInterpreter<VoidPacket>::ptr pi2b (pi2->clone());
79         BOOST_REQUIRE( pi2b->next() );
80         BOOST_CHECK( ! pi2b->next()->next() );
81         BOOST_CHECK( ! pi2b->prev() );
82
83         pi2b->data().insert(pi2b->data().begin(),0x03u);
84         BOOST_CHECK_EQUAL( pi2->data().size(), 1u );
85         BOOST_CHECK_EQUAL( pi2b->data().size(), 2u );
86
87         BOOST_CHECK_EQUAL( pi1->data().size(), unsigned(pi1->nextPacketRange()->size()) );
88         pi1->append(pi2b);
89         BOOST_CHECK_EQUAL( pi1->data().size(), 2u );
90         BOOST_REQUIRE( pi1->next() );
91         BOOST_REQUIRE( pi1->next()->next() );
92         BOOST_CHECK( ! pi1->next()->next()->next() );
93     }
94
95 }
96
97 namespace {
98     struct OtherPacket
99         : public senf::PacketTypeBase,
100           public senf::PacketTypeMixin<OtherPacket>
101     {
102         using senf::PacketTypeMixin<OtherPacket>::nextPacketRange;
103         typedef senf::ConcretePacket<OtherPacket> packet;
104         static size_type initSize()     { return 8u; }
105         static size_type initHeadSize() { return 6u; }
106         static void init(packet p)            { p.data()[0] = 0x01u; }
107     };
108 }
109
110 SENF_AUTO_UNIT_TEST(packetInterpreter)
111 {
112     typedef senf::PacketInterpreterBase::size_type size_type;
113     {
114         BOOST_CHECK_THROW( senf::PacketInterpreter<OtherPacket>::create(size_type(4u)),
115                            senf::TruncatedPacketException );
116         senf::PacketInterpreter<OtherPacket>::ptr p
117             (senf::PacketInterpreter<OtherPacket>::create(size_type(12u)));
118
119         BOOST_CHECK_EQUAL( p->data().size(), 12u );
120         BOOST_CHECK_EQUAL( std::distance(p->data().begin(),p->data().end()), 12 );
121         BOOST_CHECK_EQUAL( p->data()[0], 0x01u );
122
123         senf::PacketInterpreter<VoidPacket>::ptr p2
124             (p->parseNextAs<VoidPacket>());
125         BOOST_CHECK_EQUAL( p2->data().size(), 4u );
126         BOOST_CHECK_EQUAL( std::distance(p->data().begin(),p2->data().begin()), 6 );
127
128         senf::PacketInterpreter<OtherPacket>::ptr pc
129             (p->clone());
130         BOOST_CHECK_EQUAL( p->data().size(), 12u );
131         BOOST_CHECK( p->next() );
132         BOOST_CHECK( ! p->next()->next() );
133     }
134
135     {
136         SENF_CHECK_NO_THROW(
137             senf::PacketInterpreter<OtherPacket>::create(4u,senf::noinit));
138         senf::PacketInterpreter<OtherPacket>::ptr p
139             (senf::PacketInterpreter<OtherPacket>::create(senf::noinit));
140         BOOST_CHECK_EQUAL( p->data().size(), 0u );
141     }
142
143     {
144         senf::PacketInterpreter<VoidPacket>::byte data[] = { 0x01, 0x02, 0x03, 0x04 };
145         senf::PacketInterpreter<VoidPacket>::ptr p
146             (senf::PacketInterpreter<VoidPacket>::create(data));
147
148         BOOST_CHECK_EQUAL( p->data().size(), 4u );
149         BOOST_CHECK_EQUAL( std::distance(p->data().begin(),p->data().end()), 4 );
150         BOOST_CHECK( std::equal(p->data().begin(), p->data().end(), data) );
151     }
152
153     {
154         senf::PacketInterpreter<OtherPacket>::ptr p
155             (senf::PacketInterpreter<OtherPacket>::create(size_type(12u)));
156         senf::PacketInterpreter<VoidPacket>::ptr p2
157             (senf::PacketInterpreter<VoidPacket>::createAfter(p));
158         BOOST_CHECK_EQUAL( p2->data().size(), 0u );
159         BOOST_CHECK_EQUAL( p->data().size(), 8u );
160         p2->data().insert(p2->data().begin(),0x01u);
161         BOOST_CHECK_EQUAL( p->data()[6], 0x01u );
162         BOOST_CHECK_EQUAL( p->data().size(), 9u );
163     }
164
165     {
166         senf::PacketInterpreter<OtherPacket>::ptr p
167             (senf::PacketInterpreter<OtherPacket>::create(size_type(12u)));
168         senf::PacketInterpreter<OtherPacket>::ptr p2
169             (senf::PacketInterpreter<OtherPacket>::createAfter(
170                 p,senf::noinit));
171         BOOST_CHECK_EQUAL( p2->data().size(), 0u );
172         BOOST_CHECK_EQUAL( p->data().size(), 8u );
173     }
174
175     {
176         senf::PacketInterpreter<OtherPacket>::ptr p
177             (senf::PacketInterpreter<OtherPacket>::create(size_type(12u)));
178         senf::PacketInterpreter<OtherPacket>::ptr p2
179             (senf::PacketInterpreter<OtherPacket>::createAfter(p, size_type(10u)));
180         BOOST_CHECK_EQUAL( p2->data().size(), 10u );
181         BOOST_CHECK_EQUAL( p->data().size(), 18u );
182         BOOST_CHECK_EQUAL( p2->data()[0], 0x01u );
183         BOOST_CHECK_THROW( senf::PacketInterpreter<OtherPacket>::createAfter(p, size_type(4u)),
184                            senf::TruncatedPacketException );
185         SENF_CHECK_NO_THROW( senf::PacketInterpreter<OtherPacket>::createAfter(
186                                   p,4u,senf::noinit) );
187     }
188
189     {
190         senf::PacketInterpreter<OtherPacket>::ptr p
191             (senf::PacketInterpreter<OtherPacket>::create(size_type(10u)));
192         senf::PacketInterpreter<VoidPacket>::byte data[] = { 0x01, 0x02, 0x03, 0x04 };
193         senf::PacketInterpreter<OtherPacket>::ptr p2
194             (senf::PacketInterpreter<OtherPacket>::createAfter(p,data));
195         BOOST_CHECK_EQUAL( p2->data().size(), 4u );
196         BOOST_CHECK_EQUAL( p->data().size(), 12u );
197         BOOST_CHECK_EQUAL( p2->data()[1], 0x02u );
198         BOOST_CHECK_EQUAL( p->data()[8], 0x03u );
199     }
200
201     {
202         senf::PacketInterpreter<OtherPacket>::ptr p
203             (senf::PacketInterpreter<OtherPacket>::create(size_type(10u)));
204         senf::PacketInterpreter<OtherPacket>::ptr p2
205             (senf::PacketInterpreter<OtherPacket>::createBefore(p));
206
207         BOOST_CHECK_EQUAL( p2->data().size(), 18u );
208         BOOST_CHECK_EQUAL( p->data().size(), 10u );
209
210         senf::PacketInterpreter<OtherPacket>::ptr p3
211             (senf::PacketInterpreter<OtherPacket>::createBefore(
212                 p,senf::noinit));
213
214         BOOST_CHECK_EQUAL( p3->data().size(), 10u );
215
216         senf::PacketInterpreter<OtherPacket>::ptr p4
217             (senf::PacketInterpreter<OtherPacket>::createInsertBefore(p));
218
219         BOOST_CHECK_EQUAL( p->data().size(), 10u );
220         BOOST_CHECK_EQUAL( p4->data().size(), 18u );
221         BOOST_CHECK_EQUAL( p3->data().size(), 18u );
222     }
223
224 }
225
226 // fields() is tested in DefaultBundle/EthernetPacket.test.cc
227 // initSize() and initHeadSize() are already tested indirectly above
228
229 SENF_AUTO_UNIT_TEST(packetInterpreter_factory)
230 {
231     typedef senf::PacketInterpreterBase::size_type size_type;
232
233     senf::PacketInterpreterBase::byte data[] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06 };
234     senf::PacketInterpreterBase::factory_t factory (
235         senf::PacketInterpreter<OtherPacket>::factory());
236
237     BOOST_CHECK( ! senf::PacketInterpreterBase::no_factory() );
238     BOOST_REQUIRE( factory );
239
240     BOOST_CHECK_EQUAL( factory->create()->data().size(), 8u );
241     BOOST_CHECK_EQUAL( factory->create(senf::noinit)->data().size(), 0u );
242     BOOST_CHECK_EQUAL( factory->create(size_type(12u))->data().size(), 12u );
243     BOOST_CHECK_EQUAL(
244         factory->create(4u, senf::noinit)->data().size(), 4u );
245     BOOST_CHECK_EQUAL( factory->create(data)->data().size(), 6u );
246
247     {
248         senf::PacketInterpreter<VoidPacket>::ptr p
249             (senf::PacketInterpreter<VoidPacket>::create());
250
251         BOOST_CHECK_EQUAL( p->data().size(), 0u);
252         BOOST_CHECK( factory->createAfter(p) );
253         BOOST_REQUIRE( p->next() );
254         BOOST_CHECK( ! p->next()->next() );
255
256         BOOST_CHECK_EQUAL( factory->createAfter(p)->data().size(), 8u );
257         BOOST_CHECK_EQUAL( p->data().size(), 8u );
258         BOOST_CHECK( ! p->next()->next() );
259
260         BOOST_CHECK_EQUAL(
261             factory->createAfter(p, senf::noinit)->data().size(), 0u );
262         BOOST_CHECK_EQUAL( p->data().size(), 0u );
263         BOOST_CHECK( ! p->next()->next() );
264
265         BOOST_CHECK_EQUAL( factory->createAfter(p, size_type(12u))->data().size(), 12u );
266         BOOST_CHECK_EQUAL( p->data().size(), 12u );
267         BOOST_CHECK( ! p->next()->next() );
268
269         BOOST_CHECK_EQUAL(
270             factory->createAfter(p,4u, senf::noinit)->data().size(), 4u );
271         BOOST_CHECK_EQUAL( p->data().size(), 4u );
272         BOOST_CHECK( ! p->next()->next() );
273
274         BOOST_CHECK_EQUAL( factory->createAfter(p, data)->data().size(), 6u );
275         BOOST_CHECK_EQUAL( p->data().size(), 6u );
276         BOOST_CHECK( ! p->next()->next() );
277     }
278
279     {
280         senf::PacketInterpreter<VoidPacket>::ptr p
281             (senf::PacketInterpreter<VoidPacket>::create(size_type(4u)));
282
283         BOOST_CHECK_EQUAL( factory->createBefore(p)->data().size(), 12u );
284         BOOST_REQUIRE( p->prev() );
285         BOOST_CHECK( ! p->prev()->prev() );
286         BOOST_CHECK_EQUAL( p->prev()->data().size(), 12u );
287
288         BOOST_CHECK_EQUAL( factory->createBefore(p,senf::noinit)->data().size(), 4u );
289         BOOST_REQUIRE( p->prev() );
290         BOOST_CHECK( ! p->prev()->prev() );
291         BOOST_CHECK_EQUAL( p->prev()->data().size(), 4u );
292
293         BOOST_CHECK_EQUAL( factory->createInsertBefore(p,senf::noinit)->data().size(), 4u );
294         BOOST_REQUIRE( p->prev() );
295         BOOST_REQUIRE( p->prev()->prev() );
296         BOOST_CHECK( ! p->prev()->prev()->prev() );
297     }
298
299     {
300         senf::PacketInterpreter<VoidPacket>::ptr p
301             (senf::PacketInterpreter<VoidPacket>::create(size_type(12u)));
302
303         senf::PacketInterpreterBase::ptr p2 (p->parseNextAs(factory, p->nextPacketRange()));
304         BOOST_CHECK_EQUAL( unsigned(boost::size(*p2->nextPacketRange())), 4u );
305     }
306
307 }
308
309 //-/////////////////////////////////////////////////////////////////////////////////////////////////
310 #undef prefix_
311
312 \f
313 // Local Variables:
314 // mode: c++
315 // fill-column: 100
316 // c-file-style: "senf"
317 // indent-tabs-mode: nil
318 // ispell-local-dictionary: "american"
319 // compile-command: "scons -u test"
320 // comment-column: 40
321 // End: