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