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 <testshl/simpleheader.hxx>
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_MYPORT9  8897
66 #define IP_PORT_MYPORT10 8898
67 
68 const char * pTestString1 = "test socket";
69 const char * pTestString2 = " Passed#OK";
70 
71 //------------------------------------------------------------------------
72 // helper functions
73 //------------------------------------------------------------------------
74 
75 class CloseSocketThread : public Thread
76 {
77 	::osl::Socket m_sSocket;
78 protected:
run()79 	void SAL_CALL run( )
80 	{
81 		thread_sleep( 1 );
82 		m_sSocket.close( );
83 	}
84 public:
CloseSocketThread(::osl::Socket & sSocket)85 	CloseSocketThread(::osl::Socket & sSocket )
86 		: m_sSocket( sSocket )
87 	{
88 	}
89 
~CloseSocketThread()90 	~CloseSocketThread( )
91 	{
92 		if ( isRunning( ) )
93 		{
94 			t_print("# error: CloseSocketThread not terminated.\n" );
95 		}
96 	}
97 };
98 
99 //------------------------------------------------------------------------
100 // tests cases begins here
101 //------------------------------------------------------------------------
102 
103 namespace osl_DatagramSocket
104 {
105 
106 	/** testing the methods:
107 		inline DatagramSocket(oslAddrFamily Family= osl_Socket_FamilyInet,
108 							  oslProtocol	Protocol= osl_Socket_ProtocolIp,
109 							  oslSocketType	Type= osl_Socket_TypeDgram);
110 	*/
111 
112 	class ctors : public CppUnit::TestFixture
113 	{
114 	public:
115 
ctors_001()116 		void ctors_001()
117 		{
118 			/// Socket constructor.
119 			::osl::DatagramSocket dsSocket;
120 
121 			CPPUNIT_ASSERT_MESSAGE( "test for ctors_001 constructor function: check if the datagram socket was created successfully.",
122 									osl_Socket_TypeDgram ==  dsSocket.getType( ) );
123 		}
124 
125 
126 		CPPUNIT_TEST_SUITE( ctors );
127 		CPPUNIT_TEST( ctors_001 );
128 		CPPUNIT_TEST_SUITE_END();
129 
130 	}; // class ctors
131 
132 /**thread do sendTo, refer to http://www.coding-zone.co.uk/cpp/articles/140101networkprogrammingv.shtml
133 */
134 class TalkerThread : public Thread
135 {
136 protected:
137 	::osl::SocketAddr saTargetSocketAddr;
138 	::osl::DatagramSocket dsSocket;
139 
run()140 	void SAL_CALL run( )
141 	{
142 		dsSocket.sendTo( saTargetSocketAddr, pTestString1, strlen( pTestString1 ) + 1 ); // "test socket"
143 		dsSocket.shutdown();
144 	}
145 
onTerminated()146 	void SAL_CALL onTerminated( )
147 	{
148 	}
149 
150 public:
TalkerThread()151 	TalkerThread( ):
152 		saTargetSocketAddr( rtl::OUString::createFromAscii("127.0.0.1"), IP_PORT_MYPORT9 )
153 	{
154 	}
155 
~TalkerThread()156 	~TalkerThread( )
157 	{
158 		if ( isRunning( ) )
159 			t_print("# error: TalkerThread not terminated normally.\n" );
160 	}
161 };
162 
163 /**thread do listen, refer to http://www.coding-zone.co.uk/cpp/articles/140101networkprogrammingv.shtml
164 */
165 class ListenerThread : public Thread
166 {
167 protected:
168 	::osl::SocketAddr saTargetSocketAddr;
169 	::osl::DatagramSocket dsSocket;
170 
run()171 	void SAL_CALL run( )
172 	{
173 		::osl::SocketAddr saLocalSocketAddr( rtl::OUString::createFromAscii("127.0.0.1"), IP_PORT_MYPORT10 );
174 		dsSocket.setOption( osl_Socket_OptionReuseAddr, 1 );
175 		if ( dsSocket.bind( saLocalSocketAddr ) == sal_False )
176 		{
177 			t_print("DatagramSocket bind failed \n");
178 			return;
179 		}
180 		//blocking mode: default
181 		sal_Int32 nRecv = dsSocket.recvFrom( pRecvBuffer, 30, &saTargetSocketAddr); //strlen( pTestString2 ) + 1
182 		t_print("After recvFrom, nRecv is %d\n", nRecv);
183 	}
184 
onTerminated()185 	void SAL_CALL onTerminated( )
186 	{
187 	}
188 
189 public:
190 	sal_Char pRecvBuffer[30];
ListenerThread()191 	ListenerThread( ):
192 		saTargetSocketAddr( rtl::OUString::createFromAscii("127.0.0.1"), IP_PORT_MYPORT10 )
193 	{
194 		pRecvBuffer[0] = '\0';
195 	}
196 
~ListenerThread()197 	~ListenerThread( )
198 	{
199 		if ( isRunning( ) )
200 			t_print("# error: ListenerThread not terminated normally.\n" );
201 	}
202 
203 };
204 
205 	/** testing the methods:
206 		inline sal_Int32 DatagramSocket::recvFrom(void*  pBuffer, sal_uInt32 BufferSize,
207 			  SocketAddr* pSenderAddr, oslSocketMsgFlag Flag )
208 		inline sal_Int32  DatagramSocket::sendTo( const SocketAddr& ReceiverAddr,
209 			  const void* pBuffer, sal_uInt32 BufferSize, oslSocketMsgFlag Flag )
210 	*/
211 
212 	class sendTo_recvFrom : public CppUnit::TestFixture
213 	{
214 	public:
215 
sr_001()216 		void sr_001()
217 		{
218 			::osl::SocketAddr saLocalSocketAddr( rtl::OUString::createFromAscii("127.0.0.1"), IP_PORT_MYPORT9 );
219 			::osl::DatagramSocket dsSocket;
220 			dsSocket.setOption( osl_Socket_OptionReuseAddr, 1 );
221 			dsSocket.bind( saLocalSocketAddr );
222 
223 			sal_Char pReadBuffer[30];
224 			TalkerThread myTalkThread;
225 			myTalkThread.create();
226 			sal_Int32 nRecv = dsSocket.recvFrom( pReadBuffer, 30, &saLocalSocketAddr);
227 			myTalkThread.join();
228 			//t_print("#received buffer is %s# \n", pReadBuffer);
229 
230 			sal_Bool bOk = ( strcmp(pReadBuffer, pTestString1) == 0 );
231 
232 			CPPUNIT_ASSERT_MESSAGE( "test for sendTo/recvFrom function: create a talker thread and recvFrom in the main thread, check if the datagram socket can communicate successfully.",
233 									nRecv > 0 && bOk == sal_True );
234 		}
235 
sr_002()236 		void sr_002()
237 		{
238 			::osl::SocketAddr saListenSocketAddr( rtl::OUString::createFromAscii("127.0.0.1"), IP_PORT_MYPORT10 );
239 			::osl::DatagramSocket dsSocket;
240 
241 			//listener thread construct a DatagramSocket, recvFrom waiting for data, then main thread sendto data
242 			ListenerThread myListenThread;
243 			myListenThread.create();
244 			//to grantee the recvFrom is before sendTo
245 			thread_sleep( 1 );
246 
247 			sal_Int32 nSend = dsSocket.sendTo( saListenSocketAddr, pTestString2, strlen( pTestString2 ) + 1 );
248 
249 			CPPUNIT_ASSERT_MESSAGE( "DatagramSocket sendTo failed: nSend <= 0.", nSend > 0);
250 
251 			myListenThread.join();
252 			//t_print("#received buffer is %s# \n", myListenThread.pRecvBuffer);
253 
254 			sal_Bool bOk = ( strcmp( myListenThread.pRecvBuffer, pTestString2) == 0 );
255 
256 			CPPUNIT_ASSERT_MESSAGE( "test for sendTo/recvFrom function: create a listener thread and sendTo in the main thread, check if the datagram socket can communicate successfully.",
257 									bOk == sal_True );
258 		}
259 
260 		//sendTo error, return -1; recvFrom error, return -1
sr_003()261 		void sr_003()
262 		{
263 			::osl::SocketAddr saListenSocketAddr( rtl::OUString::createFromAscii("123.345.67.89"), IP_PORT_MYPORT10 );
264 			::osl::DatagramSocket dsSocket;
265 			// Transport endpoint is not connected
266 			sal_Int32 nSend = dsSocket.sendTo( saListenSocketAddr, pTestString2, strlen( pTestString2 ) + 1 );
267 			CPPUNIT_ASSERT_MESSAGE( "DatagramSocket sendTo should fail: nSend <= 0.",
268 				nSend == -1 );
269 		}
270 
sr_004()271 		void sr_004()
272 		{
273 			::osl::SocketAddr saListenSocketAddr1( rtl::OUString::createFromAscii("123.345.67.89"), IP_PORT_MYPORT10 );
274 			::osl::SocketAddr saListenSocketAddr2( rtl::OUString::createFromAscii("129.158.217.202"), IP_PORT_MYPORT10 );
275 			::osl::DatagramSocket dsSocket;
276 
277 			dsSocket.enableNonBlockingMode( sal_True );
278 
279 			sal_Char pReadBuffer[30];
280 			//sal_Int32 nRecv1 = dsSocket.recvFrom( pReadBuffer, 30, &saListenSocketAddr1 );
281 
282 			// will block ?
283 			CloseSocketThread myThread( dsSocket );
284 			myThread.create();
285 			sal_Int32 nRecv2 = dsSocket.recvFrom( pReadBuffer, 30, &saListenSocketAddr1 );
286 			myThread.join();
287 			//t_print("#nRecv1 is %d nRecv2 is %d\n", nRecv1, nRecv2 );
288 			CPPUNIT_ASSERT_MESSAGE( "DatagramSocket sendTo should fail: nSend <= 0.",
289 				 nRecv2 == -1 );
290 		}
291 
292 		CPPUNIT_TEST_SUITE( sendTo_recvFrom );
293 		CPPUNIT_TEST( sr_001 );
294 		CPPUNIT_TEST( sr_002 );
295 		CPPUNIT_TEST( sr_003 );
296 		CPPUNIT_TEST( sr_004 );
297 		CPPUNIT_TEST_SUITE_END();
298 
299 	}; // class sendTo_recvFrom
300 
301 // -----------------------------------------------------------------------------
302 
303 CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(osl_DatagramSocket::ctors, "osl_DatagramSocket");
304 CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(osl_DatagramSocket::sendTo_recvFrom, "osl_DatagramSocket");
305 
306 } // namespace osl_DatagramSocket
307 
308 // -----------------------------------------------------------------------------
309 
310 // this macro creates an empty function, which will called by the RegisterAllFunctions()
311 // to let the user the possibility to also register some functions by hand.
312 NOADDITIONAL;
313