1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_sal.hxx"
30 
31 /**  test coder preface:
32 	1. the BSD socket function will meet "unresolved external symbol error" on Windows platform
33 	if you are not including ws2_32.lib in makefile.mk,  the including format will be like this:
34 
35 	.IF "$(GUI)" == "WNT"
36 	SHL1STDLIBS +=	$(SOLARLIBDIR)$/cppunit.lib
37 	SHL1STDLIBS +=  ws2_32.lib
38 	.ENDIF
39 
40 	likewise on Solaris platform.
41 	.IF "$(GUI)" == "UNX"
42 	SHL1STDLIBS+=$(SOLARLIBDIR)$/libcppunit$(DLLPOSTFIX).a
43 	SHL1STDLIBS += -lsocket -ldl -lnsl
44 	.ENDIF
45 
46 	2. since the Socket implementation of osl is only IPv4 oriented, our test are mainly focus on IPv4
47 	category.
48 
49 	3. some fragment of Socket source implementation are lack of comment so it is hard for testers
50 	guess what the exact functionality or usage of a member.  Hope the Socket section's comment
51 	will be added.
52 
53 	4. following functions are declared but not implemented:
54 	inline sal_Bool SAL_CALL operator== (const SocketAddr & Addr) const;
55  */
56 
57 //------------------------------------------------------------------------
58 // include files
59 //------------------------------------------------------------------------
60 
61 #include <testshl/simpleheader.hxx>
62 
63 #include "osl_Socket_Const.h"
64 #include "sockethelper.hxx"
65 
66 using namespace osl;
67 using namespace rtl;
68 
69 #define IP_PORT_MYPORT2 8883
70 #define IP_PORT_FTP     21
71 #define IP_PORT_MYPORT3 8884
72 
73 //------------------------------------------------------------------------
74 // helper functions
75 //------------------------------------------------------------------------
76 
77 class CloseSocketThread : public Thread
78 {
79 	::osl::Socket &m_sSocket;
80 protected:
81 	void SAL_CALL run( )
82 	{
83 		thread_sleep( 1 );
84 		m_sSocket.close( );
85 	}
86 public:
87 	CloseSocketThread(::osl::Socket & sSocket )
88 		: m_sSocket( sSocket )
89 	{
90 	}
91 
92 	~CloseSocketThread( )
93 	{
94 		if ( isRunning( ) )
95 		{
96 			t_print("# error: CloseSocketThread not terminated.\n" );
97 		}
98 	}
99 };
100 
101 namespace osl_ConnectorSocket
102 {
103 
104 	/** testing the method:
105 		ConnectorSocket(oslAddrFamily Family = osl_Socket_FamilyInet,
106 						oslProtocol	Protocol = osl_Socket_ProtocolIp,
107 						oslSocketType	Type = osl_Socket_TypeStream);
108 	*/
109 
110 	class ctors : public CppUnit::TestFixture
111 	{
112 	public:
113 		void ctors_001()
114 		{
115 			/// Socket constructor.
116 			::osl::ConnectorSocket csSocket( osl_Socket_FamilyInet, osl_Socket_ProtocolIp, osl_Socket_TypeStream );
117 
118 			CPPUNIT_ASSERT_MESSAGE( "test for ctors_001 constructor function: check if the connector socket was created successfully.",
119 									osl_Socket_TypeStream ==  csSocket.getType( ) );
120 		}
121 
122 		CPPUNIT_TEST_SUITE( ctors );
123 		CPPUNIT_TEST( ctors_001 );
124 		CPPUNIT_TEST_SUITE_END();
125 
126 	}; // class ctors
127 
128 	/** testing the method:
129 		oslSocketResult SAL_CALL connect(const SocketAddr& TargetHost, const TimeValue* pTimeout = 0);
130 	*/
131 
132 	class connect : public CppUnit::TestFixture
133 	{
134 	public:
135 		TimeValue *pTimeout;
136 		::osl::AcceptorSocket asAcceptorSocket;
137 		::osl::ConnectorSocket csConnectorSocket;
138 
139 
140 		// initialization
141 		void setUp( )
142 		{
143 			pTimeout  = ( TimeValue* )malloc( sizeof( TimeValue ) );
144 			pTimeout->Seconds = 3;
145 			pTimeout->Nanosec = 0;
146 		//	sHandle = osl_createSocket( osl_Socket_FamilyInet, osl_Socket_TypeStream, osl_Socket_ProtocolIp );
147 		}
148 
149 		void tearDown( )
150 		{
151 			free( pTimeout );
152 		//	sHandle = NULL;
153 			asAcceptorSocket.close( );
154 			csConnectorSocket.close( );
155 		}
156 
157 
158 		void connect_001()
159 		{
160 			::osl::SocketAddr saLocalSocketAddr( rtl::OUString::createFromAscii("127.0.0.1"), IP_PORT_MYPORT2 );
161 			::osl::SocketAddr saTargetSocketAddr( rtl::OUString::createFromAscii("127.0.0.1"), IP_PORT_MYPORT2 );
162 			::osl::SocketAddr saPeerSocketAddr( rtl::OUString::createFromAscii("129.158.217.202"), IP_PORT_FTP );
163 			::osl::StreamSocket ssConnection;
164 
165 			/// launch server socket
166 			asAcceptorSocket.setOption( osl_Socket_OptionReuseAddr, 1 ); //sal_True);
167 			sal_Bool bOK1 = asAcceptorSocket.bind( saLocalSocketAddr );
168 			CPPUNIT_ASSERT_MESSAGE( "AcceptorSocket bind address failed.", sal_True == bOK1 );
169 			sal_Bool bOK2 = asAcceptorSocket.listen( 1 );
170 			CPPUNIT_ASSERT_MESSAGE( "AcceptorSocket listen failed.",  sal_True == bOK2 );
171 
172 			//asAcceptorSocket.enableNonBlockingMode( sal_True );
173 			//oslSocketResult eResultAccept = asAcceptorSocket.acceptConnection(ssConnection); /// waiting for incoming connection...
174 			//CPPUNIT_ASSERT_MESSAGE( "accept failed.",  osl_Socket_Ok == eResultAccept );
175 			/// launch client socket
176 			oslSocketResult eResult = csConnectorSocket.connect( saTargetSocketAddr, pTimeout );   /// connecting to server...
177 			CPPUNIT_ASSERT_MESSAGE( "connect failed.",  osl_Socket_Ok == eResult );
178 
179 			/// get peer information
180 			csConnectorSocket.getPeerAddr( saPeerSocketAddr );/// connected.
181 
182 			CPPUNIT_ASSERT_MESSAGE( "test for connect function: try to create a connection with remote host. and check the setup address.",
183 									( sal_True == compareSocketAddr( saPeerSocketAddr, saLocalSocketAddr ) ) &&
184 									( osl_Socket_Ok == eResult ));
185 		}
186 		//non-blocking mode connect?
187 		void connect_002()
188 		{
189 			::osl::SocketAddr saLocalSocketAddr( rtl::OUString::createFromAscii("127.0.0.1"), IP_PORT_MYPORT3 );
190 			::osl::SocketAddr saTargetSocketAddr( rtl::OUString::createFromAscii("127.0.0.1"), IP_PORT_MYPORT3 );
191 			::osl::SocketAddr saPeerSocketAddr( rtl::OUString::createFromAscii("129.158.217.202"), IP_PORT_FTP );
192 
193 			asAcceptorSocket.setOption( osl_Socket_OptionReuseAddr, 1 ); //sal_True);
194 			asAcceptorSocket.enableNonBlockingMode( sal_True );
195 			sal_Bool bOK1 = asAcceptorSocket.bind( saLocalSocketAddr );
196 			CPPUNIT_ASSERT_MESSAGE( "AcceptorSocket bind address failed.", sal_True == bOK1 );
197 			sal_Bool bOK2 = asAcceptorSocket.listen( 1 );
198 			CPPUNIT_ASSERT_MESSAGE( "AcceptorSocket listen failed.",  sal_True == bOK2 );
199 
200 			csConnectorSocket.enableNonBlockingMode( sal_True );
201 
202 			oslSocketResult eResult = csConnectorSocket.connect( saTargetSocketAddr, pTimeout );   /// connecting to server...
203 			CPPUNIT_ASSERT_MESSAGE( "connect failed.",  osl_Socket_InProgress == eResult ||  osl_Socket_Ok == eResult );
204 
205 			/// get peer information
206 			csConnectorSocket.getPeerAddr( saPeerSocketAddr );
207 
208 			CPPUNIT_ASSERT_MESSAGE( "test for connect function: try to create a connection with remote host. and check the setup address.",
209 				sal_True == compareSocketAddr( saPeerSocketAddr, saLocalSocketAddr  )  ) ;
210 		}
211 		// really an error or just delayed
212 		// how to design senarios that will return osl_Socket_Interrupted, osl_Socket_TimedOut
213 		void connect_003()
214 		{
215 			::osl::SocketAddr saTargetSocketAddr1( rtl::OUString::createFromAscii("127.0.0.1"), IP_PORT_MYPORT3 );
216 			::osl::SocketAddr saTargetSocketAddr2( rtl::OUString::createFromAscii("123.345.67.89"), IP_PORT_MYPORT3 );
217 
218 			csConnectorSocket.enableNonBlockingMode( sal_False );
219 
220 			oslSocketResult eResult1 = csConnectorSocket.connect( saTargetSocketAddr1, pTimeout );
221 			oslSocketResult eResult2 = csConnectorSocket.connect( saTargetSocketAddr2, pTimeout );
222 			CloseSocketThread myCloseThread( csConnectorSocket );
223 			oslSocketResult eResult3 = csConnectorSocket.connect( saTargetSocketAddr2, pTimeout );
224 			myCloseThread.join();
225 			CPPUNIT_ASSERT_MESSAGE( "connect should failed.",  osl_Socket_Error == eResult1 &&
226 				osl_Socket_Error == eResult2 &&  osl_Socket_Error == eResult3 );
227 
228 		}
229 
230 		// really an error in non-blocking mode
231 		void connect_004()
232 		{
233 			::osl::SocketAddr saTargetSocketAddr( rtl::OUString::createFromAscii("123.345.67.89"), IP_PORT_MYPORT3 );
234 
235 			csConnectorSocket.enableNonBlockingMode( sal_True );
236 
237 			oslSocketResult eResult = csConnectorSocket.connect( saTargetSocketAddr, pTimeout );   /// connecting to server...
238 			CPPUNIT_ASSERT_MESSAGE( "connect should failed.",  osl_Socket_Error == eResult );
239 		}
240 		/** here need a case: immediate connection, say in non-blocking mode connect return osl_Socket_Ok
241 		*/
242 
243 		CPPUNIT_TEST_SUITE( connect );
244 		CPPUNIT_TEST( connect_001 );
245 		CPPUNIT_TEST( connect_002 );
246 		CPPUNIT_TEST( connect_003 );
247 		CPPUNIT_TEST( connect_004 );
248 		CPPUNIT_TEST_SUITE_END();
249 
250 	}; // class connect
251 
252 
253 // -----------------------------------------------------------------------------
254 
255 CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(osl_ConnectorSocket::ctors, "osl_ConnectorSocket");
256 CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(osl_ConnectorSocket::connect, "osl_ConnectorSocket");
257 
258 } // namespace osl_ConnectorSocket
259 
260 // -----------------------------------------------------------------------------
261 
262 // this macro creates an empty function, which will called by the RegisterAllFunctions()
263 // to let the user the possibility to also register some functions by hand.
264 NOADDITIONAL;
265