1 /*******************************************************************************
2
3 Unit tests for SelectListener.
4
5 Copyright:
6 Copyright (c) 2009-2016 dunnhumby Germany GmbH.
7 All rights reserved.
8
9 License:
10 Boost Software License Version 1.0. See LICENSE_BOOST.txt for details.
11 Alternatively, this file may be distributed under the terms of the Tango
12 3-Clause BSD License (see LICENSE_BSD.txt for details).
13
14 *******************************************************************************/
15
16 module ocean.net.server.SelectListener_slowtest;
17
18
19 import ocean.meta.types.Qualifiers;
20
21 import ocean.net.server.SelectListener;
22 import ocean.net.server.connection.IConnectionHandler;
23 import ocean.io.select.protocol.generic.ErrnoIOException: SocketError;
24 import ocean.util.log.Logger;
25
26 import ocean.core.Test;
27 import ocean.sys.socket.AddressIPSocket;
28 import ocean.sys.socket.UnixSocket;
29 import ocean.sys.socket.InetAddress;
30 import core.sys.posix.unistd: unlink;
31 import ocean.stdc.posix.sys.un;
32 import core.sys.posix.sys.socket;
33
34
35 /*******************************************************************************
36
37 Static module logger
38
39 *******************************************************************************/
40
41 static private Logger log;
42 static this ( )
43 {
44 log = Log.lookup("ocean.net.server.SelectListener_slowtest");
45 }
46
47 /*******************************************************************************
48
49 IP unit tests
50
51 *******************************************************************************/
52
53 class DummyConHandler : IConnectionHandler
54 {
55 this ( scope void delegate ( IConnectionHandler instance ) )
56 {
57 super(new AddressIPSocket!(), null, null);
58 }
59 override protected bool io_error() { return true; }
60 override public void handleConnection () {}
61 override public void unregisterSocket() {}
62 }
63
64 ushort testPort ( ushort port )
65 {
66 InetAddress!(false) addr;
67
68 auto socket = new AddressIPSocket!();
69
70 auto listener = new SelectListener!(DummyConHandler)(
71 addr(port), socket);
72
73 scope (exit) listener.shutdown();
74
75 test(!socket.updateAddress(), "socket.updateAddress() failed.");
76
77 test(socket.port() != 0, "Did not correctly query bounded port from OS");
78
79 test(port == 0 || socket.port() == port,
80 "Didn't bind to expected port!");
81
82 return socket.port();
83 }
84
85 unittest
86 {
87 auto port = testPort(0);
88
89 port++;
90
91 // If the port we're testing happens to be taken, try the next one
92 // give up after 10 tries
93 for ( size_t i = 0; i < 10; ++i ) try
94 {
95 port = testPort(port);
96 return;
97 }
98 catch ( SocketError e )
99 {
100 port += i;
101 }
102
103 log.warn("FLAKEY: Failed to perform test of binding to a "
104 ~ "specific port after 10 tries");
105 }
106
107 /*******************************************************************************
108
109 UNIX socket unit tests
110
111 *******************************************************************************/
112
113 class DummyConHandlerUnix : IConnectionHandler
114 {
115 this ( scope void delegate ( IConnectionHandler instance ) )
116 {
117 super(new UnixSocket, null, null);
118 }
119 override protected bool io_error() { return true; }
120 override public void handleConnection () {}
121 override public void unregisterSocket() {}
122 }
123
124 void test_unix (istring path)
125 {
126 // The following test will fail:
127 // 1) during the socket creation if the socket file can not be created.
128 // 2) during the socket termination, if the socket file can not be deleted.
129
130 auto local_address = sockaddr_un.create(path);
131 auto unix_socket = new UnixSocket;
132
133 auto listener = new SelectListener!(DummyConHandlerUnix)(
134 cast(sockaddr*)&local_address, unix_socket);
135
136 test(unix_socket.error ==0, "Something wrong happened");
137
138 scope (exit)
139 {
140 listener.shutdown();
141
142 if ( (local_address.sun_path[0] != '\0')
143 && unlink(local_address.sun_path.ptr) == -1 )
144 {
145 test(false, "Socket file '" ~ local_address.sun_path ~
146 "' could not be unlinked (it may not exist or "
147 ~ "the executable lacks permissions).");
148 }
149 }
150 }
151
152 unittest
153 {
154 test_unix("\0ocean-unixsocket-test");
155 test_unix("/tmp/ocean-unixsocket-test");
156 }