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_extensions.hxx" 30 #include <smart/com/sun/star/test/XSimpleTest.hxx> 31 #include <smart/com/sun/star/io/XOutputStream.hxx> 32 #include <smart/com/sun/star/io/XInputStream.hxx> 33 34 #include <smart/com/sun/star/lang/XServiceInfo.hxx> 35 36 #include <usr/factoryhlp.hxx> 37 38 #include <usr/reflserv.hxx> // for EXTERN_SERVICE_CALLTYPE 39 #include <usr/weak.hxx> // OWeakObject 40 41 #include <vos/conditn.hxx> 42 #include <vos/mutex.hxx> 43 #include <vos/thread.hxx> 44 45 #include <string.h> 46 47 #include "testfactreg.hxx" 48 #define IMPLEMENTATION_NAME L"test.com.sun.star.comp.extensions.stm.Pipe" 49 #define SERVICE_NAME L"test.com.sun.star.io.Pipe" 50 51 using namespace vos; 52 using namespace usr; 53 54 class WriteToStreamThread : 55 public OThread 56 { 57 58 public: 59 60 WriteToStreamThread( XOutputStreamRef xOutput , int iMax ) 61 { 62 m_output = xOutput; 63 m_iMax = iMax; 64 } 65 66 virtual ~WriteToStreamThread() {} 67 68 69 protected: 70 71 /// Working method which should be overridden. 72 virtual void run() { 73 for( int i = 0 ; i < m_iMax ; i ++ ) { 74 m_output->writeBytes( createIntSeq(i) ); 75 } 76 m_output->closeOutput(); 77 } 78 79 /** Called when run() is done. 80 * You might want to override it to do some cleanup. 81 */ 82 virtual void onTerminated() 83 { 84 delete this; 85 } 86 87 88 private: 89 90 XOutputStreamRef m_output; 91 int m_iMax; 92 }; 93 94 95 96 class OPipeTest : 97 public XSimpleTest, 98 public OWeakObject 99 { 100 public: 101 OPipeTest( const XMultiServiceFactoryRef & rFactory ); 102 ~OPipeTest(); 103 104 public: // refcounting 105 BOOL queryInterface( Uik aUik, XInterfaceRef & rOut ); 106 void acquire() { OWeakObject::acquire(); } 107 void release() { OWeakObject::release(); } 108 void* getImplementation(Reflection *p) { return OWeakObject::getImplementation(p); } 109 110 public: // implementation names 111 static Sequence< UString > getSupportedServiceNames_Static(void) THROWS( () ); 112 static UString getImplementationName_Static() THROWS( () ); 113 114 public: 115 virtual void testInvariant(const UString& TestName, const XInterfaceRef& TestObject) 116 THROWS( ( IllegalArgumentException, 117 UsrSystemException) ); 118 119 virtual INT32 test( const UString& TestName, 120 const XInterfaceRef& TestObject, 121 INT32 hTestHandle) THROWS( ( IllegalArgumentException, 122 UsrSystemException) ); 123 124 virtual BOOL testPassed(void) THROWS( ( UsrSystemException) ); 125 virtual Sequence< UString > getErrors(void) THROWS( (UsrSystemException) ); 126 virtual Sequence< UsrAny > getErrorExceptions(void) THROWS( (UsrSystemException) ); 127 virtual Sequence< UString > getWarnings(void) THROWS( (UsrSystemException) ); 128 129 private: 130 void testSimple( const XInterfaceRef & ); 131 void testBufferResizing( const XInterfaceRef & ); 132 void testMultithreading( const XInterfaceRef & ); 133 134 private: 135 Sequence<UsrAny> m_seqExceptions; 136 Sequence<UString> m_seqErrors; 137 Sequence<UString> m_seqWarnings; 138 139 }; 140 141 142 143 OPipeTest::OPipeTest( const XMultiServiceFactoryRef &rFactory ) 144 { 145 146 } 147 148 OPipeTest::~OPipeTest() 149 { 150 151 } 152 153 154 BOOL OPipeTest::queryInterface( Uik uik , XInterfaceRef &rOut ) 155 { 156 if( XSimpleTest::getSmartUik() == uik ) { 157 rOut = (XSimpleTest *) this; 158 } 159 else { 160 return OWeakObject::queryInterface( uik , rOut ); 161 } 162 return TRUE; 163 } 164 165 166 void OPipeTest::testInvariant( const UString& TestName, const XInterfaceRef& TestObject ) 167 THROWS( ( IllegalArgumentException, 168 UsrSystemException) ) 169 { 170 XServiceInfoRef info( TestObject, USR_QUERY ); 171 ERROR_ASSERT( info.is() , "XServiceInfo not supported !" ); 172 if( info.is() ) 173 { 174 ERROR_ASSERT( info->supportsService( TestName ), "XServiceInfo test failed" ); 175 ERROR_ASSERT( ! info->supportsService( L"bla bluzb" ) , "XServiceInfo test failed" ); 176 } 177 178 } 179 180 181 INT32 OPipeTest::test( const UString& TestName, 182 const XInterfaceRef& TestObject, 183 INT32 hTestHandle) THROWS( ( IllegalArgumentException, 184 UsrSystemException) ) 185 { 186 if( L"com.sun.star.io.Pipe" == TestName ) { 187 try { 188 if( 0 == hTestHandle ) { 189 testInvariant( TestName , TestObject ); 190 } 191 else if( 1 == hTestHandle ) { 192 testSimple( TestObject ); 193 } 194 else if( 2 == hTestHandle ) { 195 testBufferResizing( TestObject ); 196 } 197 else if( 3 == hTestHandle ) { 198 testMultithreading( TestObject ); 199 } 200 } 201 catch( Exception& e ) { 202 BUILD_ERROR( 0 , UStringToString( e.getName() , CHARSET_SYSTEM ).GetCharStr() ); 203 } 204 catch(...) { 205 BUILD_ERROR( 0 , "unknown exception (Exception is not base class)" ); 206 } 207 208 hTestHandle ++; 209 210 if( 4 == hTestHandle ) { 211 // all tests finished. 212 hTestHandle = -1; 213 } 214 } 215 else { 216 THROW( IllegalArgumentException() ); 217 } 218 return hTestHandle; 219 } 220 221 222 223 BOOL OPipeTest::testPassed(void) THROWS( (UsrSystemException) ) 224 { 225 return m_seqErrors.getLen() == 0; 226 } 227 228 229 Sequence< UString > OPipeTest::getErrors(void) THROWS( (UsrSystemException) ) 230 { 231 return m_seqErrors; 232 } 233 234 235 Sequence< UsrAny > OPipeTest::getErrorExceptions(void) THROWS( (UsrSystemException) ) 236 { 237 return m_seqExceptions; 238 } 239 240 241 Sequence< UString > OPipeTest::getWarnings(void) THROWS( (UsrSystemException) ) 242 { 243 return m_seqWarnings; 244 } 245 246 247 /*** 248 * the test methods 249 * 250 ****/ 251 252 253 void OPipeTest::testSimple( const XInterfaceRef &r ) 254 { 255 256 XInputStreamRef input( r , USR_QUERY ); 257 XOutputStreamRef output( r , USR_QUERY ); 258 259 ERROR_ASSERT( input.is() , "queryInterface on XInputStream failed" ); 260 ERROR_ASSERT( output.is() , "queryInterface onXOutputStream failed" ); 261 262 // basic read/write 263 Sequence<BYTE> seqWrite = createSeq( "Hallo, du Ei !" ); 264 265 Sequence<BYTE> seqRead; 266 for( int i = 0 ; i < 5000 ; i ++ ) { 267 output->writeBytes( seqWrite ); 268 input->readBytes( seqRead , input->available() ); 269 270 ERROR_ASSERT( ! strcmp( (char *) seqWrite.getArray() , (char * )seqRead.getArray() ) , 271 "error during read/write/skip" ); 272 ERROR_ASSERT( 0 == input->available() , 273 "error during read/write/skip" ); 274 275 // available shouldn't return a negative value 276 input->skipBytes( seqWrite.getLen() - 5 ); 277 ERROR_ASSERT( 0 == input->available() , "wrong available after skip" ); 278 279 // 5 bytes should be available 280 output->writeBytes( seqWrite ); 281 ERROR_ASSERT( 5 == input->available() , "wrong available after skip/write " ); 282 283 input->readBytes( seqRead , 5 ); 284 ERROR_ASSERT( ! strcmp( (char*) seqRead.getArray() , 285 (char*) &( seqWrite.getArray()[seqWrite.getLen()-5] ) ), 286 "write/read mismatich" ); 287 288 } 289 290 output->writeBytes( seqWrite ); 291 ERROR_ASSERT( seqWrite.getLen() == input->available(), "wrong available() after write" ); 292 293 ERROR_ASSERT( 10 == input->readSomeBytes( seqRead , 10 ) , "maximal number of bytes ignored" ); 294 ERROR_ASSERT( seqWrite.getLen() -10 == input->readSomeBytes( seqRead , 100 ) , 295 "something wrong with readSomeBytes" ); 296 297 298 output->closeOutput(); 299 try { 300 output->writeBytes( Sequence<BYTE> (100) ); 301 ERROR_ASSERT( 0 , "writing on a closed stream does not cause an exception" ); 302 } 303 catch (IOException& e ) { 304 e; // just to suppress warning during compile 305 } 306 307 ERROR_ASSERT(! input->readBytes( seqRead , 1 ), "eof not found !" ); 308 309 input->closeInput(); 310 try { 311 input->readBytes( seqRead , 1 ); 312 ERROR_ASSERT( 0 , "reading from a closed stream does not cause an exception" ); 313 } 314 catch( IOException& e ) { 315 e; // just to suppress warning during compile 316 } 317 318 } 319 320 void OPipeTest::testBufferResizing( const XInterfaceRef &r ) 321 { 322 323 int iMax = 20000; 324 XInputStreamRef input( r , USR_QUERY ); 325 XOutputStreamRef output( r , USR_QUERY ); 326 327 ERROR_ASSERT( input.is() , "queryInterface on XInputStream failed" ); 328 ERROR_ASSERT( output.is() , "queryInterface on XOutputStream failed" ); 329 330 Sequence<BYTE> seqRead; 331 332 // this is just to better check the 333 // internal buffers 334 output->writeBytes( Sequence<BYTE>(100) ); 335 input->readBytes( Sequence<BYTE>() , 100); 336 337 for( int i = 0 ; i < iMax ; i ++ ) { 338 output->writeBytes( createIntSeq( i ) ); 339 } 340 341 for( i = 0 ; i < iMax ; i ++ ) { 342 input->readBytes( seqRead, createIntSeq(i).getLen() ); 343 ERROR_ASSERT( ! strcmp( (char*) seqRead.getArray() , 344 (char*) createIntSeq(i).getArray() ) , 345 "written/read mismatch\n" ); 346 } 347 348 output->closeOutput(); 349 ERROR_ASSERT( ! input->readBytes( seqRead , 1 ) , "eof not reached !" ); 350 input->closeInput(); 351 } 352 353 354 355 void OPipeTest::testMultithreading( const XInterfaceRef &r ) 356 { 357 358 359 int iMax = 30000; 360 361 XInputStreamRef input( r , USR_QUERY ); 362 XOutputStreamRef output( r , USR_QUERY ); 363 364 ERROR_ASSERT( input.is() , "queryInterface on XInputStream failed" ); 365 ERROR_ASSERT( output.is() , "queryInterface on XOutputStream failed" ); 366 367 Sequence<BYTE> seqRead; 368 369 // deletes itself 370 OThread *p = new WriteToStreamThread( output, iMax ); 371 372 ERROR_ASSERT( p , "couldn't create thread for testing !\n" ); 373 374 p->create(); 375 376 for(int i = 0 ; TRUE ; i ++ ) { 377 if( 0 == input->readBytes( seqRead, createIntSeq(i).getLen() ) ) { 378 // eof reached ! 379 break; 380 } 381 382 ERROR_ASSERT( ! strcmp( (char*) seqRead.getArray() , 383 (char*) createIntSeq(i).getArray() ) , 384 "written/read mismatch\n" ); 385 } 386 387 ERROR_ASSERT( i == iMax , "less elements read than written !"); 388 input->closeInput(); 389 } 390 391 /* { 392 try { 393 XInterfaceRef x = xSMgr->createInstance( strService ); 394 395 XInputStreamRef input( x , USR_QUERY ); 396 XOutputStreamRef output( x , USR_QUERY ); 397 398 OSL_ASSERT( output.is() ); 399 while( TRUE ) { 400 // basic read/write 401 Sequence<BYTE> seqWrite( 500 ); 402 output->writeBytes( seqWrite ); 403 404 } 405 } 406 catch( IOException& e ) { 407 printf( "%s %s\n" , UStringToString( e.getName() , CHARSET_SYSTEM ).GetCharStr() , 408 UStringToString( e.Message , CHARSET_SYSTEM ).GetCharStr() ); 409 } 410 } 411 */ 412 413 414 415 416 /** 417 * for external binding 418 * 419 * 420 **/ 421 XInterfaceRef OPipeTest_CreateInstance( const XMultiServiceFactoryRef & rSMgr ) THROWS((Exception)) 422 { 423 OPipeTest *p = new OPipeTest( rSMgr ); 424 XInterfaceRef xService = *p; 425 return xService; 426 } 427 428 429 430 Sequence<UString> OPipeTest_getSupportedServiceNames(void) THROWS( () ) 431 { 432 Sequence<UString> aRet(1); 433 aRet.getArray()[0] = OPipeTest_getImplementationName(); 434 435 return aRet; 436 } 437 438 UString OPipeTest_getServiceName() THROWS( () ) 439 { 440 return SERVICE_NAME; 441 } 442 443 UString OPipeTest_getImplementationName() THROWS( () ) 444 { 445 return IMPLEMENTATION_NAME; 446 } 447