~ubuntu-branches/ubuntu/gutsy/poco/gutsy

« back to all changes in this revision

Viewing changes to Net/testsuite/src/SocketReactorTest.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Krzysztof Burghardt
  • Date: 2007-04-27 18:33:48 UTC
  • Revision ID: james.westby@ubuntu.com-20070427183348-xgnpct0qd6a2ip34
Tags: upstream-1.2.9
ImportĀ upstreamĀ versionĀ 1.2.9

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
//
 
2
// SocketReactorTest.cpp
 
3
//
 
4
// $Id: //poco/1.2/Net/testsuite/src/SocketReactorTest.cpp#1 $
 
5
//
 
6
// Copyright (c) 2005-2006, Applied Informatics Software Engineering GmbH.
 
7
// and Contributors.
 
8
//
 
9
// Permission is hereby granted, free of charge, to any person or organization
 
10
// obtaining a copy of the software and accompanying documentation covered by
 
11
// this license (the "Software") to use, reproduce, display, distribute,
 
12
// execute, and transmit the Software, and to prepare derivative works of the
 
13
// Software, and to permit third-parties to whom the Software is furnished to
 
14
// do so, all subject to the following:
 
15
// 
 
16
// The copyright notices in the Software and this entire statement, including
 
17
// the above license grant, this restriction and the following disclaimer,
 
18
// must be included in all copies of the Software, in whole or in part, and
 
19
// all derivative works of the Software, unless such copies or derivative
 
20
// works are solely in the form of machine-executable object code generated by
 
21
// a source language processor.
 
22
// 
 
23
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 
24
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 
25
// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
 
26
// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
 
27
// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
 
28
// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 
29
// DEALINGS IN THE SOFTWARE.
 
30
//
 
31
 
 
32
 
 
33
#include "SocketReactorTest.h"
 
34
#include "CppUnit/TestCaller.h"
 
35
#include "CppUnit/TestSuite.h"
 
36
#include "Poco/Net/SocketReactor.h"
 
37
#include "Poco/Net/SocketNotification.h"
 
38
#include "Poco/Net/SocketConnector.h"
 
39
#include "Poco/Net/SocketAcceptor.h"
 
40
#include "Poco/Net/StreamSocket.h"
 
41
#include "Poco/Net/ServerSocket.h"
 
42
#include "Poco/Net/SocketAddress.h"
 
43
#include "Poco/Observer.h"
 
44
#include <sstream>
 
45
 
 
46
 
 
47
using Poco::Net::SocketReactor;
 
48
using Poco::Net::SocketConnector;
 
49
using Poco::Net::SocketAcceptor;
 
50
using Poco::Net::StreamSocket;
 
51
using Poco::Net::ServerSocket;
 
52
using Poco::Net::SocketAddress;
 
53
using Poco::Net::SocketNotification;
 
54
using Poco::Net::ReadableNotification;
 
55
using Poco::Net::WritableNotification;
 
56
using Poco::Net::TimeoutNotification;
 
57
using Poco::Net::ShutdownNotification;
 
58
using Poco::Observer;
 
59
 
 
60
 
 
61
namespace
 
62
{
 
63
        class EchoServiceHandler
 
64
        {
 
65
        public:
 
66
                EchoServiceHandler(StreamSocket& socket, SocketReactor& reactor):
 
67
                        _socket(socket),
 
68
                        _reactor(reactor)
 
69
                {
 
70
                        _reactor.addEventHandler(_socket, Observer<EchoServiceHandler, ReadableNotification>(*this, &EchoServiceHandler::onReadable));
 
71
                }
 
72
                
 
73
                ~EchoServiceHandler()
 
74
                {
 
75
                        _reactor.removeEventHandler(_socket, Observer<EchoServiceHandler, ReadableNotification>(*this, &EchoServiceHandler::onReadable));
 
76
                }
 
77
                
 
78
                void onReadable(ReadableNotification* pNf)
 
79
                {
 
80
                        pNf->release();
 
81
                        char buffer[8];
 
82
                        int n = _socket.receiveBytes(buffer, sizeof(buffer));
 
83
                        if (n > 0)
 
84
                        {
 
85
                                _socket.sendBytes(buffer, n);
 
86
                        }
 
87
                        else
 
88
                        {
 
89
                                _socket.shutdownSend();
 
90
                                delete this;
 
91
                        }
 
92
                }
 
93
                
 
94
        private:
 
95
                StreamSocket   _socket;
 
96
                SocketReactor& _reactor;
 
97
        };
 
98
        
 
99
        class ClientServiceHandler
 
100
        {
 
101
        public:
 
102
                ClientServiceHandler(StreamSocket& socket, SocketReactor& reactor):
 
103
                        _socket(socket),
 
104
                        _reactor(reactor)
 
105
                {
 
106
                        _timeout = false;
 
107
                        _reactor.addEventHandler(_socket, Observer<ClientServiceHandler, ReadableNotification>(*this, &ClientServiceHandler::onReadable));
 
108
                        _reactor.addEventHandler(_socket, Observer<ClientServiceHandler, WritableNotification>(*this, &ClientServiceHandler::onWritable));
 
109
                        _reactor.addEventHandler(_socket, Observer<ClientServiceHandler, TimeoutNotification>(*this, &ClientServiceHandler::onTimeout));
 
110
                }
 
111
                
 
112
                ~ClientServiceHandler()
 
113
                {
 
114
                }
 
115
                
 
116
                void onReadable(ReadableNotification* pNf)
 
117
                {
 
118
                        pNf->release();
 
119
                        char buffer[32];
 
120
                        int n = _socket.receiveBytes(buffer, sizeof(buffer));
 
121
                        if (n > 0)
 
122
                        {
 
123
                                _str.write(buffer, n);
 
124
                        }
 
125
                        else
 
126
                        {
 
127
                                _reactor.removeEventHandler(_socket, Observer<ClientServiceHandler, ReadableNotification>(*this, &ClientServiceHandler::onReadable));
 
128
                                _reactor.stop();
 
129
                                _data = _str.str();
 
130
                                delete this;
 
131
                        }
 
132
                }
 
133
                
 
134
                void onWritable(WritableNotification* pNf)
 
135
                {
 
136
                        pNf->release();
 
137
                        _reactor.removeEventHandler(_socket, Observer<ClientServiceHandler, WritableNotification>(*this, &ClientServiceHandler::onWritable));
 
138
                        std::string data(1024, 'x');
 
139
                        _socket.sendBytes(data.data(), (int) data.length());
 
140
                        _socket.shutdownSend();
 
141
                }
 
142
                
 
143
                void onTimeout(TimeoutNotification* pNf)
 
144
                {
 
145
                        pNf->release();
 
146
                        _timeout = true;
 
147
                        if (_closeOnTimeout) 
 
148
                        {
 
149
                                _reactor.stop();
 
150
                                delete this;
 
151
                        }
 
152
                }
 
153
                
 
154
                static std::string data()
 
155
                {
 
156
                        return _data;
 
157
                }
 
158
                
 
159
                static bool timeout()
 
160
                {
 
161
                        return _timeout;
 
162
                }
 
163
 
 
164
                static bool getCloseOnTimeout()
 
165
                {
 
166
                        return _closeOnTimeout;
 
167
                }
 
168
                
 
169
                static void setCloseOnTimeout(bool flag)
 
170
                {
 
171
                        _closeOnTimeout = flag;
 
172
                }
 
173
                
 
174
        private:
 
175
                StreamSocket       _socket;
 
176
                SocketReactor&     _reactor;
 
177
                std::stringstream  _str;
 
178
                static std::string _data;
 
179
                static bool        _timeout;
 
180
                static bool        _closeOnTimeout;
 
181
        };
 
182
        
 
183
        
 
184
        std::string ClientServiceHandler::_data;
 
185
        bool ClientServiceHandler::_timeout = false;
 
186
        bool ClientServiceHandler::_closeOnTimeout = false;
 
187
        
 
188
        
 
189
        class FailConnector: public SocketConnector<ClientServiceHandler>
 
190
        {
 
191
        public:
 
192
                FailConnector(SocketAddress& address, SocketReactor& reactor):
 
193
                        SocketConnector<ClientServiceHandler>(address, reactor),
 
194
                        _failed(false),
 
195
                        _shutdown(false)
 
196
                {
 
197
                        reactor.addEventHandler(socket(), Observer<FailConnector, ShutdownNotification>(*this, &FailConnector::onShutdown));
 
198
                }
 
199
                
 
200
                void onShutdown(ShutdownNotification* pNf)
 
201
                {
 
202
                        pNf->release();
 
203
                        _shutdown = true;
 
204
                }
 
205
                
 
206
                void onError(int error)
 
207
                {
 
208
                        _failed = true;
 
209
                        reactor()->stop();
 
210
                }
 
211
                
 
212
                bool failed() const
 
213
                {
 
214
                        return _failed;
 
215
                }
 
216
 
 
217
                bool shutdown() const
 
218
                {
 
219
                        return _shutdown;
 
220
                }
 
221
                
 
222
        private:
 
223
                bool _failed;
 
224
                bool _shutdown;
 
225
        };
 
226
}
 
227
 
 
228
 
 
229
SocketReactorTest::SocketReactorTest(const std::string& name): CppUnit::TestCase(name)
 
230
{
 
231
}
 
232
 
 
233
 
 
234
SocketReactorTest::~SocketReactorTest()
 
235
{
 
236
}
 
237
 
 
238
 
 
239
void SocketReactorTest::testSocketReactor()
 
240
{
 
241
        SocketAddress ssa;
 
242
        ServerSocket ss(ssa);
 
243
        SocketReactor reactor;
 
244
        SocketAcceptor<EchoServiceHandler> acceptor(ss, reactor);
 
245
        SocketAddress sa("localhost", ss.address().port());
 
246
        SocketConnector<ClientServiceHandler> connector(sa, reactor);
 
247
        reactor.run();
 
248
        std::string data(ClientServiceHandler::data());
 
249
        assert (data.size() == 1024);
 
250
}
 
251
 
 
252
 
 
253
void SocketReactorTest::testSocketConnectorFail()
 
254
{
 
255
        SocketReactor reactor;
 
256
        SocketAddress sa("192.168.168.192", 12345);
 
257
        FailConnector connector(sa, reactor);
 
258
        assert (!connector.failed());
 
259
        assert (!connector.shutdown());
 
260
        reactor.run();
 
261
        assert (connector.failed());
 
262
        assert (connector.shutdown());
 
263
}
 
264
 
 
265
 
 
266
void SocketReactorTest::testSocketConnectorTimeout()
 
267
{
 
268
        ClientServiceHandler::setCloseOnTimeout(true);
 
269
        
 
270
        SocketAddress ssa;
 
271
        ServerSocket ss(ssa);
 
272
        SocketReactor reactor;
 
273
        SocketAddress sa("localhost", ss.address().port());
 
274
        SocketConnector<ClientServiceHandler> connector(sa, reactor);
 
275
        reactor.run();
 
276
        assert (ClientServiceHandler::timeout());
 
277
}
 
278
 
 
279
 
 
280
void SocketReactorTest::setUp()
 
281
{
 
282
        ClientServiceHandler::setCloseOnTimeout(false);
 
283
}
 
284
 
 
285
 
 
286
void SocketReactorTest::tearDown()
 
287
{
 
288
}
 
289
 
 
290
 
 
291
CppUnit::Test* SocketReactorTest::suite()
 
292
{
 
293
        CppUnit::TestSuite* pSuite = new CppUnit::TestSuite("SocketReactorTest");
 
294
 
 
295
        CppUnit_addTest(pSuite, SocketReactorTest, testSocketReactor);
 
296
        CppUnit_addTest(pSuite, SocketReactorTest, testSocketConnectorFail);
 
297
        CppUnit_addTest(pSuite, SocketReactorTest, testSocketConnectorTimeout);
 
298
 
 
299
        return pSuite;
 
300
}