PPI: Implement DebugEvent
[senf.git] / PPI / Route.test.cc
1 // $Id$
2 //
3 // Copyright (C) 2007 
4 // Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
5 // Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
6 //     Stefan Bund <g0dil@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 Route.test unit tests */
25
26 //#include "Route.test.hh"
27 //#include "Route.test.ih"
28
29 // Custom includes
30 #include "Route.hh"
31 #include "DebugEvent.hh"
32 #include "DebugModules.hh"
33 #include "Module.hh"
34 #include "Setup.hh"
35
36 #include <boost/test/auto_unit_test.hpp>
37 #include <boost/test/test_tools.hpp>
38
39 #define prefix_
40 ///////////////////////////////cc.p////////////////////////////////////////
41
42 namespace ppi = senf::ppi;
43 namespace connector = ppi::connector;
44 namespace module = ppi::module;
45 namespace debug = module::debug;
46
47 namespace {
48     class RouteTester : public module::Module
49     {
50     public:
51         connector::ActiveInput activeIn;
52         connector::PassiveInput passiveIn;
53
54         connector::ActiveOutput activeOut;
55         connector::PassiveOutput passiveOut;
56
57         ppi::DebugEvent event;
58
59         ppi::ForwardingRoute * rt;
60         
61         RouteTester() : events(0), throttles(0) {
62                    route( activeIn,  activeOut  );  // non-forwarding
63             rt = & route( activeIn,  passiveOut );  // forward throttling
64                    route( passiveIn, activeOut  );  // backward throttling
65                    route( passiveIn, passiveOut );  // non-forwarding
66                    route( event,     activeOut  );  // forward event throttling
67                    route( activeIn,  event      );  // backward event throttling
68
69             passiveIn.onRequest(&RouteTester::inputRequest);
70             passiveOut.onRequest(&RouteTester::outputRequest);
71             registerEvent(&RouteTester::onEvent, event);
72
73             activeIn.onThrottle(&RouteTester::throttleRequest);
74             activeIn.onUnthrottle(&RouteTester::unthrottleRequest);
75             activeOut.onThrottle(&RouteTester::throttleRequest);
76             activeOut.onUnthrottle(&RouteTester::unthrottleRequest);
77         }
78
79         void inputRequest() {
80             activeOut(passiveIn());
81         }
82
83         void outputRequest() {
84             passiveOut(activeIn());
85         }
86
87         void onEvent() {
88             ++ events;
89         }
90
91         void throttleRequest() {
92             ++ throttles;
93         }
94         
95         void unthrottleRequest() {
96             -- throttles;
97         }
98
99         unsigned events;
100         int throttles;
101     };
102 }
103
104 BOOST_AUTO_UNIT_TEST(route)
105 {
106     debug::PassivePacketSource passiveSource;
107     debug::ActivePacketSource activeSource;
108     debug::PassivePacketSink passiveSink;
109     debug::ActivePacketSink activeSink;
110     RouteTester tester;
111
112     ppi::connect(passiveSource.output, tester.activeIn);
113     ppi::connect(activeSource.output, tester.passiveIn);
114     ppi::connect(tester.activeOut, passiveSink.input);
115     ppi::connect(tester.passiveOut, activeSink.input);
116
117     ppi::init();
118
119     senf::Packet p1 (senf::DataPacket::create());
120     senf::Packet p2 (senf::DataPacket::create());
121
122     passiveSource.submit(p1);
123     activeSource.submit(p2);
124
125     BOOST_CHECK( p2 == passiveSink.front() );
126
127     // The passive source is not throttled at this point since it has packets in queue
128
129     passiveSink.input.throttle();
130     BOOST_CHECK( passiveSink.input.throttled() );
131     BOOST_CHECK( ! tester.activeOut );
132     BOOST_CHECK_EQUAL( tester.throttles, 1 );
133     BOOST_CHECK( tester.passiveIn.throttled() );
134     BOOST_CHECK( ! activeSource.output );
135     BOOST_CHECK( ! tester.event.enabled() );
136
137     passiveSink.input.unthrottle();
138     BOOST_CHECK( activeSource.output );
139     BOOST_CHECK( tester.event.enabled() );
140     
141
142     // Now throttle the passive source by exhausting the queue
143     
144     BOOST_CHECK( p1 == activeSink.request() );
145     BOOST_CHECK( passiveSource.output.throttled() );
146     BOOST_CHECK( ! tester.activeIn );
147     BOOST_CHECK_EQUAL( tester.throttles, 1 );
148     BOOST_CHECK( tester.passiveOut.throttled() );
149     BOOST_CHECK( ! activeSink.input );
150     BOOST_CHECK( ! tester.event.enabled() );
151     
152     passiveSource.submit(p1);
153     BOOST_CHECK( activeSink.input );
154     BOOST_CHECK( tester.event.enabled() );
155
156     tester.rt->autoThrottling(false);
157
158     BOOST_CHECK( p1 == activeSink.request() );
159     BOOST_CHECK( passiveSource.output.throttled() );
160     BOOST_CHECK( activeSink.input );
161 }
162
163 ///////////////////////////////cc.e////////////////////////////////////////
164 #undef prefix_
165
166 \f
167 // Local Variables:
168 // mode: c++
169 // fill-column: 100
170 // comment-column: 40
171 // c-file-style: "senf"
172 // indent-tabs-mode: nil
173 // ispell-local-dictionary: "american"
174 // compile-command: "scons -u test"
175 // End: