1Test::POE::Client::TCP(U3s)er Contributed Perl DocumentatTieosnt::POE::Client::TCP(3)
2
3
4
6 Test::POE::Client::TCP - A POE Component providing TCP client services
7 for test cases
8
10 version 1.26
11
13 use strict;
14 use Socket;
15 use Test::More tests => 15;
16 use POE qw(Wheel::SocketFactory Wheel::ReadWrite Filter::Line);
17 use Test::POE::Client::TCP;
18
19 my @data = (
20 'This is a test',
21 'This is another test',
22 'This is the last test',
23 );
24
25 POE::Session->create(
26 package_states => [
27 'main' => [qw(
28 _start
29 _accept
30 _failed
31 _sock_in
32 _sock_err
33 testc_registered
34 testc_connected
35 testc_disconnected
36 testc_input
37 testc_flushed
38 )],
39 ],
40 heap => { data => \@data, },
41 );
42
43 $poe_kernel->run();
44 exit 0;
45
46 sub _start {
47 my ($kernel,$heap) = @_[KERNEL,HEAP];
48 $heap->{listener} = POE::Wheel::SocketFactory->new(
49 BindAddress => '127.0.0.1',
50 SuccessEvent => '_accept',
51 FailureEvent => '_failed',
52 SocketDomain => AF_INET, # Sets the socket() domain
53 SocketType => SOCK_STREAM, # Sets the socket() type
54 SocketProtocol => 'tcp', # Sets the socket() protocol
55 Reuse => 'on', # Lets the port be reused
56 );
57 $heap->{testc} = Test::POE::Client::TCP->spawn();
58 return;
59 }
60
61 sub _accept {
62 my ($kernel,$heap,$socket) = @_[KERNEL,HEAP,ARG0];
63 my $wheel = POE::Wheel::ReadWrite->new(
64 Handle => $socket,
65 InputEvent => '_sock_in',
66 ErrorEvent => '_sock_err',
67 );
68 $heap->{wheels}->{ $wheel->ID } = $wheel;
69 return;
70 }
71
72 sub _failed {
73 my ($kernel,$heap,$operation,$errnum,$errstr,$wheel_id) = @_[KERNEL,HEAP,ARG0..ARG3];
74 die "Wheel $wheel_id generated $operation error $errnum: $errstr\n";
75 return;
76 }
77
78 sub _sock_in {
79 my ($heap,$input,$wheel_id) = @_[HEAP,ARG0,ARG1];
80 pass('Got input from client');
81 $heap->{wheels}->{ $wheel_id }->put( $input ) if $heap->{wheels}->{ $wheel_id };
82 return;
83 }
84
85 sub _sock_err {
86 my ($heap,$wheel_id) = @_[HEAP,ARG3];
87 pass('Client disconnected');
88 delete $heap->{wheels}->{ $wheel_id };
89 return;
90 }
91
92 sub testc_registered {
93 my ($kernel,$sender,$object) = @_[KERNEL,SENDER,ARG0];
94 pass($_[STATE]);
95 my $port = ( sockaddr_in( $_[HEAP]->{listener}->getsockname() ) )[0];
96 $kernel->post( $sender, 'connect', { address => '127.0.0.1', port => $port } );
97 return;
98 }
99
100 sub testc_connected {
101 my ($kernel,$heap,$sender) = @_[KERNEL,HEAP,SENDER];
102 pass($_[STATE]);
103 $kernel->post( $sender, 'send_to_server', $heap->{data}->[0] );
104 return;
105 }
106
107 sub testc_flushed {
108 pass($_[STATE]);
109 return;
110 }
111
112 sub testc_input {
113 my ($heap,$input) = @_[HEAP,ARG0];
114 pass('Got something back from the server');
115 my $data = shift @{ $heap->{data} };
116 ok( $input eq $data, "Data matched: '$input'" );
117 unless ( scalar @{ $heap->{data} } ) {
118 $heap->{testc}->terminate();
119 return;
120 }
121 $poe_kernel->post( $_[SENDER], 'send_to_server', $heap->{data}->[0] );
122 return;
123 }
124
125 sub testc_disconnected {
126 my ($heap,$state) = @_[HEAP,STATE];
127 pass($state);
128 delete $heap->{wheels};
129 delete $heap->{listener};
130 $heap->{testc}->shutdown();
131 return;
132 }
133
135 Test::POE::Client::TCP is a POE component that provides a TCP client
136 framework for inclusion in client component test cases, instead of
137 having to roll your own.
138
139 Once registered with the component, a session will receive events
140 related to connections made, disconnects, flushed output and input from
141 the specified server.
142
144 "spawn"
145 Takes a number of optional arguments:
146
147 'alias', set an alias on the component;
148 'address', the remote address to connect to;
149 'port', the remote port to connect to;
150 'options', a hashref of POE::Session options;
151 'filter', specify a POE::Filter to use for client connections, default is POE::Filter::Line;
152 'inputfilter', specify a POE::Filter for client input;
153 'outputfilter', specify a POE::Filter for output to clients;
154 'localaddr', specify that connections be made from a particular local address;
155 'localport', specify that connections be made from a particular port;
156 'autoconnect', set to a true value to make the poco connect immediately;
157 'prefix', specify an event prefix other than the default of 'testc';
158 'timeout', specify number of seconds to wait for socket timeouts;
159 'context', anything that can fit into a scalar, such as a ref, etc.
160 'usessl', enable SSL/TLS if POE::Component::SSLify is available;
161 'sslctx', set to a SSL Context to configure the SSL Connection;
162 'sslcert', set to a x509 Certificate(PEM encoded) to connect using a client cert;
163 'sslkey', set to a private Key(PEM encoded) to connect using a client cert;
164
165 The semantics for "filter", "inputfilter" and "outputfilter" are
166 the same as for POE::Component::Server::TCP in that one may provide
167 either a "SCALAR", "ARRAYREF" or an "OBJECT".
168
169 If the component is "spawn"ed within another session it will
170 automatically "register" the parent session to receive "all"
171 events.
172
173 "address" and "port" are optional within "spawn", but if they
174 aren't specified they must be provided to subsequent "connect"s. If
175 "autoconnect" is specified, "address" and "port" must also be
176 defined.
177
178 "usessl" is dependent on whether POE::Component::SSLify is
179 available.
180
182 "connect"
183 Initiates a connection to the given server. Takes a number of
184 parameters:
185
186 'address', the remote address to connect to;
187 'port', the remote port to connect to;
188 'localaddr', specify that connections be made from a particular local address, optional;
189 'localport', specify that connections be made from a particular port, optional;
190 'usessl', enable SSL/TLS if POE::Component::SSLify is available;
191
192 "address" and "port" are optional if they have been already
193 specified during "spawn".
194
195 "session_id"
196 Returns the POE::Session ID of the component.
197
198 "shutdown"
199 Terminates the component. It will terminate any pending connects or
200 connections.
201
202 "server_info"
203 Retrieves socket information about the current connection. In a
204 list context it returns a list consisting of, in order, the server
205 address, the server TCP port, our address and our TCP port. In a
206 scalar context it returns a HASHREF with the following keys:
207
208 'peeraddr', the server address;
209 'peerport', the server TCP port;
210 'sockaddr', our address;
211 'sockport', our TCP port;
212
213 "send_to_server"
214 Send some output to the connected server. The first parameter is a
215 string of text to send. This parameter may also be an arrayref of
216 items to send to the client. If the filter you have used requires
217 an arrayref as input, nest that arrayref within another arrayref.
218
219 "disconnect"
220 Places the server connection into pending disconnect state. Set
221 this, then send an applicable message to the server using
222 send_to_server() and the server connection will be terminated.
223
224 "terminate"
225 Immediately disconnects a server connection.
226
227 "wheel"
228 Returns the underlying POE::Wheel::ReadWrite object if we are
229 currently connected to a server, "undef" otherwise. You can use
230 this method to call methods on the wheel object to switch filters,
231 etc. Exercise caution.
232
233 "alias"
234 Returns the currently configured alias.
235
236 "context"
237 Returns whatever was provided as "context" when the component was
238 spawned. If nothing was provided then it returns nothing.
239
241 These are events that the component will accept:
242
243 "register"
244 Takes N arguments: a list of event names that your session wants to
245 listen for, minus the 'testc_' prefix.
246
247 Registering for 'all' will cause it to send all TESTC-related
248 events to you; this is the easiest way to handle it.
249
250 "unregister"
251 Takes N arguments: a list of event names which you don't want to
252 receive. If you've previously done a 'register' for a particular
253 event which you no longer care about, this event will tell the poco
254 to stop sending them to you. (If you haven't, it just ignores you.
255 No big deal).
256
257 "connect"
258 Initiates a connection to the given server. Takes a number of
259 parameters:
260
261 'address', the remote address to connect to;
262 'port', the remote port to connect to;
263 'localaddr', specify that connections be made from a particular local address, optional;
264 'localport', specify that connections be made from a particular port, optional;
265
266 "address" and "port" are optional if they have been already
267 specified during "spawn".
268
269 "shutdown"
270 Terminates the component. It will terminate any pending connects or
271 connections.
272
273 "send_to_server"
274 Send some output to the connected server. The first parameter is a
275 string of text to send. This parameter may also be an arrayref of
276 items to send to the client. If the filter you have used requires
277 an arrayref as input, nest that arrayref within another arrayref.
278
279 "disconnect"
280 Places the server connection into pending disconnect state. Set
281 this, then send an applicable message to the server using
282 send_to_server() and the server connection will be terminated.
283
284 "terminate"
285 Immediately disconnects a server connection.
286
288 The component sends the following events to registered sessions. If you
289 have changed the "prefix" option in "spawn" then substitute "testc"
290 with the event prefix that you specified.
291
292 "testc_registered"
293 This event is sent to a registering session. ARG0 is the
294 Test::POE::Client::TCP object.
295
296 "testc_socket_failed"
297 Generated if the component cannot make a socket connection. ARG0
298 contains the name of the operation that failed. ARG1 and ARG2 hold
299 numeric and string values for $!, respectively.
300
301 "testc_connected"
302 Generated whenever a connection is established. ARG0 is the
303 server's IP address, ARG1 is the server's TCP port. ARG3 is our IP
304 address and ARG4 is our socket port.
305
306 "testc_disconnected"
307 Generated whenever we disconnect from the server.
308
309 "testc_input"
310 Generated whenever the server sends us some traffic. ARG0 is the
311 data sent ( tokenised by whatever POE::Filter you specified ).
312
313 "testc_flushed"
314 Generated whenever anything we send to the server is actually
315 flushed down the 'line'.
316
318 Contains code borrowed from POE::Component::Server::TCP by Rocco
319 Caputo, Ann Barcomb and Jos Boumans.
320
322 POE
323
324 POE::Component::Server::TCP
325
327 Chris Williams <chris@bingosnet.co.uk>
328
330 This software is copyright (c) 2018 by Chris Williams, Rocco Caputo,
331 Ann Barcomb and Jos Boumans.
332
333 This is free software; you can redistribute it and/or modify it under
334 the same terms as the Perl 5 programming language system itself.
335
336
337
338perl v5.38.0 2023-07-21 Test::POE::Client::TCP(3)