1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_sal.hxx"
26 
27 /**  test coder preface:
28 	1. the BSD socket function will meet "unresolved external symbol error" on Windows platform
29 	if you are not including ws2_32.lib in makefile.mk,  the including format will be like this:
30 
31 	.IF "$(GUI)" == "WNT"
32 	SHL1STDLIBS +=	$(SOLARLIBDIR)$/cppunit.lib
33 	SHL1STDLIBS +=  ws2_32.lib
34 	.ENDIF
35 
36 	likewise on Solaris platform.
37 	.IF "$(GUI)" == "UNX"
38 	SHL1STDLIBS+=$(SOLARLIBDIR)$/libcppunit$(DLLPOSTFIX).a
39 	SHL1STDLIBS += -lsocket -ldl -lnsl
40 	.ENDIF
41 
42 	2. since the Socket implementation of osl is only IPv4 oriented, our test are mainly focus on IPv4
43 	category.
44 
45 	3. some fragment of Socket source implementation are lack of comment so it is hard for testers
46 	guess what the exact functionality or usage of a member.  Hope the Socket section's comment
47 	will be added.
48 
49 	4. following functions are declared but not implemented:
50 	inline sal_Bool SAL_CALL operator== (const SocketAddr & Addr) const;
51  */
52 
53 //------------------------------------------------------------------------
54 // include files
55 //------------------------------------------------------------------------
56 
57 #include "gtest/gtest.h"
58 
59 #include "osl_Socket_Const.h"
60 #include "sockethelper.hxx"
61 
62 using namespace osl;
63 using namespace rtl;
64 
65 #define IP_PORT_FTP     21
66 #define IP_PORT_MYPORT9 8897
67 #define IP_PORT_MYPORT4 8885
68 #define IP_PORT_MYPORT3 8884
69 
70 //------------------------------------------------------------------------
71 // helper functions
72 //------------------------------------------------------------------------
73 
74 // just used to test socket::close() when accepting
75 class AcceptorThread : public Thread
76 {
77 	::osl::AcceptorSocket asAcceptorSocket;
78 	::rtl::OUString aHostIP;
79 	sal_Bool bOK;
80 protected:
run()81 	void SAL_CALL run( )
82 	{
83 		::osl::SocketAddr saLocalSocketAddr( aHostIP, IP_PORT_MYPORT9 );
84 		::osl::StreamSocket ssStreamConnection;
85 
86 		asAcceptorSocket.setOption( osl_Socket_OptionReuseAddr, 1 ); //integer not sal_Bool : sal_True);
87 		sal_Bool bOK1 = asAcceptorSocket.bind( saLocalSocketAddr );
88 		if  ( sal_True != bOK1 )
89 		{
90 			printf("# AcceptorSocket bind address failed.\n" ) ;
91 			return;
92 		}
93 		sal_Bool bOK2 = asAcceptorSocket.listen( 1 );
94 		if  ( sal_True != bOK2 )
95 		{
96 			printf("# AcceptorSocket listen address failed.\n" ) ;
97 			return;
98 		}
99 
100 		asAcceptorSocket.enableNonBlockingMode( sal_False );
101 
102 		oslSocketResult eResult = asAcceptorSocket.acceptConnection( ssStreamConnection );
103 		if (eResult != osl_Socket_Ok )
104 		{
105 			bOK = sal_True;
106 			printf("AcceptorThread: acceptConnection failed! \n");
107 		}
108 	}
109 public:
AcceptorThread(::osl::AcceptorSocket & asSocket,::rtl::OUString const & aBindIP)110 	AcceptorThread(::osl::AcceptorSocket & asSocket, ::rtl::OUString const& aBindIP )
111 		: asAcceptorSocket( asSocket ), aHostIP( aBindIP )
112 	{
113 		bOK = sal_False;
114 	}
115 
isOK()116 	sal_Bool isOK() { return bOK; }
117 
~AcceptorThread()118 	~AcceptorThread( )
119 	{
120 		if ( isRunning( ) )
121 		{
122 			asAcceptorSocket.shutdown();
123 			printf("# error: Acceptor thread not terminated.\n" );
124 		}
125 	}
126 };
127 
128 namespace osl_AcceptorSocket
129 {
130 
131 	/** testing the methods:
132 		inline AcceptorSocket(oslAddrFamily Family = osl_Socket_FamilyInet,
133 							  oslProtocol	Protocol = osl_Socket_ProtocolIp,
134 							  oslSocketType	Type = osl_Socket_TypeStream);
135 	*/
136 
137 	class ctors : public ::testing::Test
138 	{
139 	public:
140 	}; // class ctors
141 
TEST_F(ctors,ctors_001)142     TEST_F(ctors, ctors_001)
143     {
144         /// Socket constructor.
145         ::osl::AcceptorSocket asSocket( osl_Socket_FamilyInet, osl_Socket_ProtocolIp, osl_Socket_TypeStream );
146 
147         ASSERT_TRUE(osl_Socket_TypeStream ==  asSocket.getType( )) << "test for ctors_001 constructor function: check if the acceptor socket was created successfully.";
148     }
149 
150 #if 0  /* OBSOLETE */
151 	class operator_assign : public ::testing::Test
152 	{
153 	public:
154 	}; // class operator_assign
155 
156     TEST_F(assign, assign_001)
157     {
158 #if defined(LINUX)
159         ::osl::AcceptorSocket asSocket( osl_Socket_FamilyInet, osl_Socket_ProtocolIp, osl_Socket_TypeStream );
160         ::osl::AcceptorSocket asSocketAssign( osl_Socket_FamilyInet, osl_Socket_ProtocolIp, osl_Socket_TypeStream );
161         asSocket.setOption( osl_Socket_OptionReuseAddr, 1);
162         ::osl::SocketAddr saSocketAddr( rtl::OUString::createFromAscii("127.0.0.1"), IP_PORT_MYPORT4 );
163         asSocket.bind( saSocketAddr );
164 
165         AcceptorThread myAcceptorThread( asSocketAssign, rtl::OUString::createFromAscii("127.0.0.1") );
166         myAcceptorThread.create();
167 
168         thread_sleep( 1 );
169         //when accepting, assign another socket to the socket, the thread will not be closed, so is blocking
170         asSocketAssign = asSocket;
171 
172         printf("#asSocketAssign port number is %d\n", asSocketAssign.getLocalPort() );
173 
174         asSocketAssign.shutdown();
175         myAcceptorThread.join();
176 
177         ASSERT_TRUE(myAcceptorThread.isOK() == sal_True) << "test for close when is accepting: the socket will quit accepting status.";
178 
179 
180 #endif /* LINUX */
181     }
182 #endif /* OBSOLETE */
183 
184 	/** testing the method:
185 		inline sal_Bool SAL_CALL listen(sal_Int32 MaxPendingConnections= -1);
186 		inline oslSocketResult SAL_CALL acceptConnection( StreamSocket& Connection);
187 		inline oslSocketResult SAL_CALL acceptConnection( StreamSocket&	Connection, SocketAddr & PeerAddr);
188 	*/
189 
190 	class listen_accept : public ::testing::Test
191 	{
192 	public:
193 		TimeValue *pTimeout;
194 		::osl::AcceptorSocket asAcceptorSocket;
195 		::osl::ConnectorSocket csConnectorSocket;
196 
197 
198 		// initialization
SetUp()199 		void SetUp( )
200 		{
201 			pTimeout  = ( TimeValue* )malloc( sizeof( TimeValue ) );
202 			pTimeout->Seconds = 3;
203 			pTimeout->Nanosec = 0;
204 			asAcceptorSocket.setOption( osl_Socket_OptionReuseAddr, 1);
205 		//	sHandle = osl_createSocket( osl_Socket_FamilyInet, osl_Socket_TypeStream, osl_Socket_ProtocolIp );
206 		}
207 
TearDown()208 		void TearDown( )
209 		{
210 			free( pTimeout );
211 		//	sHandle = NULL;
212 			asAcceptorSocket.close( );
213 			csConnectorSocket.close( );
214 		}
215 	}; // class listen_accept
216 
TEST_F(listen_accept,listen_accept_001)217     TEST_F(listen_accept, listen_accept_001)
218     {
219         ::osl::SocketAddr saLocalSocketAddr( rtl::OUString::createFromAscii("127.0.0.1"), IP_PORT_MYPORT3 );
220         ::osl::SocketAddr saTargetSocketAddr( rtl::OUString::createFromAscii("127.0.0.1"), IP_PORT_MYPORT3 );
221         ::osl::StreamSocket ssConnection;
222 
223         /// launch server socket
224         sal_Bool bOK1 = asAcceptorSocket.bind( saLocalSocketAddr );
225         ASSERT_TRUE(sal_True == bOK1) << "AcceptorSocket bind address failed.";
226         sal_Bool bOK2 = asAcceptorSocket.listen( 1 );
227         ASSERT_TRUE(sal_True == bOK2) << "AcceptorSocket listen failed.";
228         asAcceptorSocket.enableNonBlockingMode( sal_True );
229 
230         /// launch client socket
231         csConnectorSocket.connect( saTargetSocketAddr, pTimeout );   /// connecting to server...
232 
233         oslSocketResult eResult = asAcceptorSocket.acceptConnection(ssConnection); /// waiting for incoming connection...
234 
235         ASSERT_TRUE( ( osl_Socket_Ok == eResult ) )
236             << "test for listen_accept function: try to create a connection with remote host, using listen and accept.";
237     }
238 
TEST_F(listen_accept,listen_accept_002)239     TEST_F(listen_accept, listen_accept_002)
240     {
241         ::osl::SocketAddr saLocalSocketAddr( rtl::OUString::createFromAscii("127.0.0.1"), IP_PORT_MYPORT4 );
242         ::osl::SocketAddr saTargetSocketAddr( rtl::OUString::createFromAscii("127.0.0.1"), IP_PORT_MYPORT4 );
243         ::osl::SocketAddr saPeerSocketAddr( rtl::OUString::createFromAscii("129.158.217.202"), IP_PORT_FTP );
244         ::osl::StreamSocket ssConnection;
245 
246         /// launch server socket
247         sal_Bool bOK1 = asAcceptorSocket.bind( saLocalSocketAddr );
248         ASSERT_TRUE(sal_True == bOK1) << "AcceptorSocket bind address failed.";
249         sal_Bool bOK2 = asAcceptorSocket.listen( 1 );
250         ASSERT_TRUE(sal_True == bOK2) << "AcceptorSocket listen failed.";
251         asAcceptorSocket.enableNonBlockingMode( sal_True );
252 
253         /// launch client socket
254         csConnectorSocket.connect( saTargetSocketAddr, pTimeout );   /// connecting to server...
255 
256         oslSocketResult eResult = asAcceptorSocket.acceptConnection(ssConnection, saPeerSocketAddr); /// waiting for incoming connection...
257 
258         ASSERT_TRUE(
259                                 ( sal_True == bOK2 ) &&
260                                 ( osl_Socket_Ok == eResult ) &&
261                                 ( sal_True == compareSocketAddr( saPeerSocketAddr, saLocalSocketAddr ) ) )
262             << "test for listen_accept function: try to create a connection with remote host, using listen and accept, accept with peer address.";
263     }
264 
265 } // namespace osl_AcceptorSocket
266 
main(int argc,char ** argv)267 int main(int argc, char **argv)
268 {
269     ::testing::InitGoogleTest(&argc, argv);
270     return RUN_ALL_TESTS();
271 }
272