1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: pipetest.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_io.hxx"
34 #include <com/sun/star/test/XSimpleTest.hpp>
35 #include <com/sun/star/io/XInputStream.hpp>
36 #include <com/sun/star/io/XOutputStream.hpp>
37 #include <com/sun/star/io/XConnectable.hpp>
38 #include <com/sun/star/lang/IllegalArgumentException.hpp>
40 #include <com/sun/star/lang/XServiceInfo.hpp>
42 #include <cppuhelper/factory.hxx>
44 #include <cppuhelper/implbase1.hxx> // OWeakObject
46 #include <osl/conditn.hxx>
47 #include <osl/mutex.hxx>
48 #include <osl/thread.hxx>
52 using namespace ::rtl
;
53 using namespace ::osl
;
54 using namespace ::cppu
;
55 using namespace ::com::sun::star::uno
;
56 using namespace ::com::sun::star::io
;
57 using namespace ::com::sun::star::lang
;
58 using namespace ::com::sun::star::test
;
61 #include "testfactreg.hxx"
62 #define IMPLEMENTATION_NAME "test.com.sun.star.comp.extensions.stm.Pipe"
63 #define SERVICE_NAME "test.com.sun.star.io.Pipe"
66 class WriteToStreamThread
:
72 WriteToStreamThread( Reference
< XOutputStream
> xOutput
, int iMax
)
78 virtual ~WriteToStreamThread() {}
83 /// Working method which should be overridden.
84 virtual void SAL_CALL
run() {
85 for( int i
= 0 ; i
< m_iMax
; i
++ ) {
86 m_output
->writeBytes( createIntSeq(i
) );
88 m_output
->closeOutput();
91 /** Called when run() is done.
92 * You might want to override it to do some cleanup.
94 virtual void SAL_CALL
onTerminated()
102 Reference
< XOutputStream
> m_output
;
108 class OPipeTest
: public WeakImplHelper1
< XSimpleTest
>
111 OPipeTest( const Reference
< XMultiServiceFactory
> & rFactory
);
114 public: // implementation names
115 static Sequence
< OUString
> getSupportedServiceNames_Static(void) throw();
116 static OUString
getImplementationName_Static() throw();
119 virtual void SAL_CALL
testInvariant(const OUString
& TestName
, const Reference
< XInterface
>& TestObject
)
120 throw ( IllegalArgumentException
, RuntimeException
) ;
122 virtual sal_Int32 SAL_CALL
test( const OUString
& TestName
,
123 const Reference
< XInterface
>& TestObject
,
124 sal_Int32 hTestHandle
)
125 throw ( IllegalArgumentException
,
128 virtual sal_Bool SAL_CALL
testPassed(void) throw ( RuntimeException
) ;
129 virtual Sequence
< OUString
> SAL_CALL
getErrors(void) throw (RuntimeException
) ;
130 virtual Sequence
< Any
> SAL_CALL
getErrorExceptions(void) throw (RuntimeException
);
131 virtual Sequence
< OUString
> SAL_CALL
getWarnings(void) throw (RuntimeException
);
134 void testSimple( const Reference
< XInterface
> & );
135 void testBufferResizing( const Reference
< XInterface
> & );
136 void testMultithreading( const Reference
< XInterface
> & );
139 Sequence
<Any
> m_seqExceptions
;
140 Sequence
<OUString
> m_seqErrors
;
141 Sequence
<OUString
> m_seqWarnings
;
147 OPipeTest::OPipeTest( const Reference
< XMultiServiceFactory
> &rFactory
)
152 OPipeTest::~OPipeTest()
159 void OPipeTest::testInvariant( const OUString
& TestName
, const Reference
< XInterface
>& TestObject
)
160 throw ( IllegalArgumentException
,
163 Reference
< XServiceInfo
> info( TestObject
, UNO_QUERY
);
164 ERROR_ASSERT( info
.is() , "XServiceInfo not supported !" );
167 ERROR_ASSERT( info
->supportsService( TestName
), "XServiceInfo test failed" );
168 ERROR_ASSERT( ! info
->supportsService(
169 OUString( RTL_CONSTASCII_USTRINGPARAM("bla bluzb") ) ), "XServiceInfo test failed" );
175 sal_Int32
OPipeTest::test(
176 const OUString
& TestName
,
177 const Reference
< XInterface
>& TestObject
,
178 sal_Int32 hTestHandle
)
179 throw ( IllegalArgumentException
, RuntimeException
)
181 if( OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.io.Pipe") ) == TestName
) {
184 if( 0 == hTestHandle
) {
185 testInvariant( TestName
, TestObject
);
187 else if( 1 == hTestHandle
) {
188 testSimple( TestObject
);
190 else if( 2 == hTestHandle
) {
191 testBufferResizing( TestObject
);
193 else if( 3 == hTestHandle
) {
194 testMultithreading( TestObject
);
197 catch( Exception
& e
)
199 OString s
= OUStringToOString( e
.Message
, RTL_TEXTENCODING_ASCII_US
);
200 BUILD_ERROR( 0 , s
.getStr() );
204 BUILD_ERROR( 0 , "unknown exception (Exception is not base class)" );
209 if( 4 == hTestHandle
)
211 // all tests finished.
216 throw IllegalArgumentException();
223 sal_Bool
OPipeTest::testPassed(void) throw (RuntimeException
)
225 return m_seqErrors
.getLength() == 0;
229 Sequence
< OUString
> OPipeTest::getErrors(void) throw (RuntimeException
)
235 Sequence
< Any
> OPipeTest::getErrorExceptions(void) throw (RuntimeException
)
237 return m_seqExceptions
;
241 Sequence
< OUString
> OPipeTest::getWarnings(void) throw (RuntimeException
)
243 return m_seqWarnings
;
253 void OPipeTest::testSimple( const Reference
< XInterface
> &r
)
256 Reference
< XInputStream
> input( r
, UNO_QUERY
);
257 Reference
< XOutputStream
> output( r
, UNO_QUERY
);
259 ERROR_ASSERT( input
.is() , "queryInterface on XInputStream failed" );
260 ERROR_ASSERT( output
.is() , "queryInterface onXOutputStream failed" );
263 Sequence
<sal_Int8
> seqWrite
= createSeq( "Hallo, du Ei !" );
265 Sequence
<sal_Int8
> seqRead
;
266 for( int i
= 0 ; i
< 5000 ; i
++ ) {
267 output
->writeBytes( seqWrite
);
268 input
->readBytes( seqRead
, input
->available() );
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" );
275 // available shouldn't return a negative value
276 input
->skipBytes( seqWrite
.getLength() - 5 );
277 ERROR_ASSERT( 0 == input
->available() , "wrong available after skip" );
279 // 5 bytes should be available
280 output
->writeBytes( seqWrite
);
281 ERROR_ASSERT( 5 == input
->available() , "wrong available after skip/write " );
283 input
->readBytes( seqRead
, 5 );
284 ERROR_ASSERT( ! strcmp( (char*) seqRead
.getArray() ,
285 (char*) &( seqWrite
.getArray()[seqWrite
.getLength()-5] ) ),
286 "write/read mismatich" );
290 output
->writeBytes( seqWrite
);
291 ERROR_ASSERT( seqWrite
.getLength() == input
->available(), "wrong available() after write" );
293 ERROR_ASSERT( 10 == input
->readSomeBytes( seqRead
, 10 ) , "maximal number of bytes ignored" );
294 ERROR_ASSERT( seqWrite
.getLength() -10 == input
->readSomeBytes( seqRead
, 100 ) ,
295 "something wrong with readSomeBytes" );
298 output
->closeOutput();
300 output
->writeBytes( Sequence
<sal_Int8
> (100) );
301 ERROR_ASSERT( 0 , "writing on a closed stream does not cause an exception" );
303 catch (IOException
& )
307 ERROR_ASSERT(! input
->readBytes( seqRead
, 1 ), "eof not found !" );
312 input
->readBytes( seqRead
, 1 );
313 ERROR_ASSERT( 0 , "reading from a closed stream does not cause an exception" );
315 catch( IOException
& ) {
321 ERROR_ASSERT( 0 , "calling available from a closed stream should thrown an io exception" );
323 catch( IOException
& )
329 input
->skipBytes(42 );
330 ERROR_ASSERT( 0 , "calling available from a closed stream should thrown an io exception" );
332 catch( IOException
& )
338 void OPipeTest::testBufferResizing( const Reference
< XInterface
> &r
)
342 Reference
< XInputStream
> input( r
, UNO_QUERY
);
343 Reference
< XOutputStream
> output( r
, UNO_QUERY
);
345 ERROR_ASSERT( input
.is() , "queryInterface on XInputStream failed" );
346 ERROR_ASSERT( output
.is() , "queryInterface on XOutputStream failed" );
348 Sequence
<sal_Int8
> seqRead
;
350 // this is just to better check the
352 output
->writeBytes( Sequence
<sal_Int8
>(100) );
353 Sequence
< sal_Int8
> dummy
;
354 input
->readBytes( dummy
, 100);
356 for( i
= 0 ; i
< iMax
; i
++ ) {
357 output
->writeBytes( createIntSeq( i
) );
360 for( i
= 0 ; i
< iMax
; i
++ ) {
361 input
->readBytes( seqRead
, createIntSeq(i
).getLength() );
362 ERROR_ASSERT( ! strcmp( (char*) seqRead
.getArray() ,
363 (char*) createIntSeq(i
).getArray() ) ,
364 "written/read mismatch\n" );
367 output
->closeOutput();
368 ERROR_ASSERT( ! input
->readBytes( seqRead
, 1 ) , "eof not reached !" );
374 void OPipeTest::testMultithreading( const Reference
< XInterface
> &r
)
380 Reference
< XInputStream
> input( r
, UNO_QUERY
);
381 Reference
< XOutputStream
> output( r
, UNO_QUERY
);
383 ERROR_ASSERT( input
.is() , "queryInterface on XInputStream failed" );
384 ERROR_ASSERT( output
.is() , "queryInterface on XOutputStream failed" );
386 Sequence
<sal_Int8
> seqRead
;
389 Thread
*p
= new WriteToStreamThread( output
, iMax
);
391 ERROR_ASSERT( p
, "couldn't create thread for testing !\n" );
395 for( i
= 0 ; sal_True
; i
++ ) {
396 if( 0 == input
->readBytes( seqRead
, createIntSeq(i
).getLength() ) ) {
401 ERROR_ASSERT( ! strcmp( (char*) seqRead
.getArray() ,
402 (char*) createIntSeq(i
).getArray() ) ,
403 "written/read mismatch\n" );
406 ERROR_ASSERT( i
== iMax
, "less elements read than written !");
413 * for external binding
417 Reference
< XInterface
> SAL_CALL
OPipeTest_CreateInstance( const Reference
< XMultiServiceFactory
> & rSMgr
) throw (Exception
)
419 OPipeTest
*p
= new OPipeTest( rSMgr
);
420 Reference
< XInterface
> x ( SAL_STATIC_CAST( OWeakObject
* , p
) );
426 Sequence
<OUString
> OPipeTest_getSupportedServiceNames(void) throw()
428 Sequence
<OUString
> aRet(1);
429 aRet
.getArray()[0] = OPipeTest_getServiceName();
434 OUString
OPipeTest_getServiceName() throw()
436 return OUString( RTL_CONSTASCII_USTRINGPARAM( SERVICE_NAME
) );
439 OUString
OPipeTest_getImplementationName() throw()
441 return OUString( RTL_CONSTASCII_USTRINGPARAM( IMPLEMENTATION_NAME
) );