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_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 printf("# 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 ::testing::Test
113 {
114 public:
115 }; // class ctors
116
TEST_F(ctors,ctors_001)117 TEST_F(ctors, ctors_001)
118 {
119 /// Socket constructor.
120 ::osl::DatagramSocket dsSocket;
121
122 ASSERT_TRUE(osl_Socket_TypeDgram == dsSocket.getType( ))
123 << "test for ctors_001 constructor function: check if the datagram socket was created successfully.";
124 }
125
126 /**thread do sendTo, refer to http://www.coding-zone.co.uk/cpp/articles/140101networkprogrammingv.shtml
127 */
128 class TalkerThread : public Thread
129 {
130 protected:
131 ::osl::SocketAddr saTargetSocketAddr;
132 ::osl::DatagramSocket dsSocket;
133
run()134 void SAL_CALL run( )
135 {
136 dsSocket.sendTo( saTargetSocketAddr, pTestString1, strlen( pTestString1 ) + 1 ); // "test socket"
137 dsSocket.shutdown();
138 }
139
onTerminated()140 void SAL_CALL onTerminated( )
141 {
142 }
143
144 public:
TalkerThread()145 TalkerThread( ):
146 saTargetSocketAddr( rtl::OUString::createFromAscii("127.0.0.1"), IP_PORT_MYPORT9 )
147 {
148 }
149
~TalkerThread()150 ~TalkerThread( )
151 {
152 if ( isRunning( ) )
153 printf("# error: TalkerThread not terminated normally.\n" );
154 }
155 };
156
157 /**thread do listen, refer to http://www.coding-zone.co.uk/cpp/articles/140101networkprogrammingv.shtml
158 */
159 class ListenerThread : public Thread
160 {
161 protected:
162 ::osl::SocketAddr saTargetSocketAddr;
163 ::osl::DatagramSocket dsSocket;
164
run()165 void SAL_CALL run( )
166 {
167 ::osl::SocketAddr saLocalSocketAddr( rtl::OUString::createFromAscii("127.0.0.1"), IP_PORT_MYPORT10 );
168 dsSocket.setOption( osl_Socket_OptionReuseAddr, 1 );
169 if ( dsSocket.bind( saLocalSocketAddr ) == sal_False )
170 {
171 printf("DatagramSocket bind failed \n");
172 return;
173 }
174 //blocking mode: default
175 sal_Int32 nRecv = dsSocket.recvFrom( pRecvBuffer, 30, &saTargetSocketAddr); //strlen( pTestString2 ) + 1
176 printf("After recvFrom, nRecv is %d\n", nRecv);
177 }
178
onTerminated()179 void SAL_CALL onTerminated( )
180 {
181 }
182
183 public:
184 sal_Char pRecvBuffer[30];
ListenerThread()185 ListenerThread( ):
186 saTargetSocketAddr( rtl::OUString::createFromAscii("127.0.0.1"), IP_PORT_MYPORT10 )
187 {
188 pRecvBuffer[0] = '\0';
189 }
190
~ListenerThread()191 ~ListenerThread( )
192 {
193 if ( isRunning( ) )
194 printf("# error: ListenerThread not terminated normally.\n" );
195 }
196
197 };
198
199 /** testing the methods:
200 inline sal_Int32 DatagramSocket::recvFrom(void* pBuffer, sal_uInt32 BufferSize,
201 SocketAddr* pSenderAddr, oslSocketMsgFlag Flag )
202 inline sal_Int32 DatagramSocket::sendTo( const SocketAddr& ReceiverAddr,
203 const void* pBuffer, sal_uInt32 BufferSize, oslSocketMsgFlag Flag )
204 */
205
206 class sendTo_recvFrom : public ::testing::Test
207 {
208 public:
209 }; // class sendTo_recvFrom
210
TEST_F(sendTo_recvFrom,sr_001)211 TEST_F(sendTo_recvFrom, sr_001)
212 {
213 ::osl::SocketAddr saLocalSocketAddr( rtl::OUString::createFromAscii("127.0.0.1"), IP_PORT_MYPORT9 );
214 ::osl::DatagramSocket dsSocket;
215 dsSocket.setOption( osl_Socket_OptionReuseAddr, 1 );
216 dsSocket.bind( saLocalSocketAddr );
217
218 sal_Char pReadBuffer[30];
219 TalkerThread myTalkThread;
220 myTalkThread.create();
221 sal_Int32 nRecv = dsSocket.recvFrom( pReadBuffer, 30, &saLocalSocketAddr);
222 myTalkThread.join();
223 //printf("#received buffer is %s# \n", pReadBuffer);
224
225 sal_Bool bOk = ( strcmp(pReadBuffer, pTestString1) == 0 );
226
227 ASSERT_TRUE(nRecv > 0 && bOk == sal_True )
228 << "test for sendTo/recvFrom function: create a talker thread and recvFrom in the main thread, check if the datagram socket can communicate successfully.";
229 }
230
TEST_F(sendTo_recvFrom,sr_002)231 TEST_F(sendTo_recvFrom, sr_002)
232 {
233 ::osl::SocketAddr saListenSocketAddr( rtl::OUString::createFromAscii("127.0.0.1"), IP_PORT_MYPORT10 );
234 ::osl::DatagramSocket dsSocket;
235
236 //listener thread construct a DatagramSocket, recvFrom waiting for data, then main thread sendto data
237 ListenerThread myListenThread;
238 myListenThread.create();
239 //to grantee the recvFrom is before sendTo
240 thread_sleep( 1 );
241
242 sal_Int32 nSend = dsSocket.sendTo( saListenSocketAddr, pTestString2, strlen( pTestString2 ) + 1 );
243
244 ASSERT_TRUE(nSend > 0) << "DatagramSocket sendTo failed: nSend <= 0.";
245
246 myListenThread.join();
247 //printf("#received buffer is %s# \n", myListenThread.pRecvBuffer);
248
249 sal_Bool bOk = ( strcmp( myListenThread.pRecvBuffer, pTestString2) == 0 );
250
251 ASSERT_TRUE( bOk == sal_True )
252 << "test for sendTo/recvFrom function: create a listener thread and sendTo in the main thread, check if the datagram socket can communicate successfully.";
253 }
254
255 //sendTo error, return -1; recvFrom error, return -1
TEST_F(sendTo_recvFrom,sr_003)256 TEST_F(sendTo_recvFrom, sr_003)
257 {
258 ::osl::SocketAddr saListenSocketAddr( rtl::OUString::createFromAscii("123.345.67.89"), IP_PORT_MYPORT10 );
259 ::osl::DatagramSocket dsSocket;
260 // Transport endpoint is not connected
261 sal_Int32 nSend = dsSocket.sendTo( saListenSocketAddr, pTestString2, strlen( pTestString2 ) + 1 );
262 ASSERT_TRUE(nSend == -1) << "DatagramSocket sendTo should fail: nSend <= 0.";
263 }
264
TEST_F(sendTo_recvFrom,sr_004)265 TEST_F(sendTo_recvFrom, sr_004)
266 {
267 ::osl::SocketAddr saListenSocketAddr1( rtl::OUString::createFromAscii("123.345.67.89"), IP_PORT_MYPORT10 );
268 ::osl::SocketAddr saListenSocketAddr2( rtl::OUString::createFromAscii("129.158.217.202"), IP_PORT_MYPORT10 );
269 ::osl::DatagramSocket dsSocket;
270
271 dsSocket.enableNonBlockingMode( sal_True );
272
273 sal_Char pReadBuffer[30];
274 //sal_Int32 nRecv1 = dsSocket.recvFrom( pReadBuffer, 30, &saListenSocketAddr1 );
275
276 // will block ?
277 CloseSocketThread myThread( dsSocket );
278 myThread.create();
279 sal_Int32 nRecv2 = dsSocket.recvFrom( pReadBuffer, 30, &saListenSocketAddr1 );
280 myThread.join();
281 //printf("#nRecv1 is %d nRecv2 is %d\n", nRecv1, nRecv2 );
282 ASSERT_TRUE(nRecv2 == -1) << "DatagramSocket sendTo should fail: nSend <= 0.";
283 }
284
285 } // namespace osl_DatagramSocket
286
main(int argc,char ** argv)287 int main(int argc, char **argv)
288 {
289 ::testing::InitGoogleTest(&argc, argv);
290 return RUN_ALL_TESTS();
291 }
292