1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
21 #include <com/sun/star/test/XSimpleTest.hpp>
22 #include <com/sun/star/io/XInputStream.hpp>
23 #include <com/sun/star/io/XOutputStream.hpp>
24 #include <com/sun/star/io/XConnectable.hpp>
25 #include <com/sun/star/lang/IllegalArgumentException.hpp>
27 #include <com/sun/star/lang/XServiceInfo.hpp>
29 #include <cppuhelper/factory.hxx>
31 #include <cppuhelper/implbase.hxx>
33 #include <osl/conditn.hxx>
34 #include <osl/thread.hxx>
38 using namespace ::osl
;
39 using namespace ::cppu
;
40 using namespace ::com::sun::star::uno
;
41 using namespace ::com::sun::star::io
;
42 using namespace ::com::sun::star::lang
;
43 using namespace ::com::sun::star::test
;
46 #include "testfactreg.hxx"
49 class WriteToStreamThread
:
55 WriteToStreamThread( Reference
< XOutputStream
> xOutput
, int iMax
)
56 : m_output(xOutput
), m_iMax(iMax
)
60 virtual ~WriteToStreamThread() {}
65 /// Working method which should be overridden.
66 virtual void SAL_CALL
run() {
67 for( int i
= 0 ; i
< m_iMax
; i
++ ) {
68 m_output
->writeBytes( createIntSeq(i
) );
70 m_output
->closeOutput();
73 /** Called when run() is done.
74 * You might want to override it to do some cleanup.
76 virtual void SAL_CALL
onTerminated()
84 Reference
< XOutputStream
> m_output
;
89 class OPipeTest
: public WeakImplHelper
< XSimpleTest
>
92 explicit OPipeTest( const Reference
< XMultiServiceFactory
> & rFactory
);
95 public: // implementation names
96 static Sequence
< OUString
> getSupportedServiceNames_Static() throw();
97 static OUString
getImplementationName_Static() throw();
100 virtual void SAL_CALL
testInvariant(const OUString
& TestName
, const Reference
< XInterface
>& TestObject
)
101 throw ( IllegalArgumentException
, RuntimeException
) ;
103 virtual sal_Int32 SAL_CALL
test( const OUString
& TestName
,
104 const Reference
< XInterface
>& TestObject
,
105 sal_Int32 hTestHandle
)
106 throw ( IllegalArgumentException
,
109 virtual sal_Bool SAL_CALL
testPassed() throw ( RuntimeException
) ;
110 virtual Sequence
< OUString
> SAL_CALL
getErrors() throw (RuntimeException
) ;
111 virtual Sequence
< Any
> SAL_CALL
getErrorExceptions() throw (RuntimeException
);
112 virtual Sequence
< OUString
> SAL_CALL
getWarnings() throw (RuntimeException
);
115 void testSimple( const Reference
< XInterface
> & );
116 void testBufferResizing( const Reference
< XInterface
> & );
117 void testMultithreading( const Reference
< XInterface
> & );
120 Sequence
<Any
> m_seqExceptions
;
121 Sequence
<OUString
> m_seqErrors
;
122 Sequence
<OUString
> m_seqWarnings
;
127 OPipeTest::OPipeTest( const Reference
< XMultiServiceFactory
> &rFactory
)
132 OPipeTest::~OPipeTest()
138 void OPipeTest::testInvariant( const OUString
& TestName
, const Reference
< XInterface
>& TestObject
)
139 throw ( IllegalArgumentException
,
142 Reference
< XServiceInfo
> info( TestObject
, UNO_QUERY
);
143 ERROR_ASSERT( info
.is() , "XServiceInfo not supported !" );
146 ERROR_ASSERT( info
->supportsService( TestName
), "XServiceInfo test failed" );
147 ERROR_ASSERT( ! info
->supportsService(
148 OUString("bla bluzb") ), "XServiceInfo test failed" );
154 sal_Int32
OPipeTest::test(
155 const OUString
& TestName
,
156 const Reference
< XInterface
>& TestObject
,
157 sal_Int32 hTestHandle
)
158 throw ( IllegalArgumentException
, RuntimeException
)
160 if( OUString("com.sun.star.io.Pipe") == TestName
) {
163 if( 0 == hTestHandle
) {
164 testInvariant( TestName
, TestObject
);
166 else if( 1 == hTestHandle
) {
167 testSimple( TestObject
);
169 else if( 2 == hTestHandle
) {
170 testBufferResizing( TestObject
);
172 else if( 3 == hTestHandle
) {
173 testMultithreading( TestObject
);
176 catch( const Exception
& e
)
178 OString s
= OUStringToOString( e
.Message
, RTL_TEXTENCODING_ASCII_US
);
179 BUILD_ERROR( 0 , s
.getStr() );
183 BUILD_ERROR( 0 , "unknown exception (Exception is not base class)" );
188 if( 4 == hTestHandle
)
190 // all tests finished.
195 throw IllegalArgumentException();
201 sal_Bool
OPipeTest::testPassed() throw (RuntimeException
)
203 return m_seqErrors
.getLength() == 0;
207 Sequence
< OUString
> OPipeTest::getErrors() throw (RuntimeException
)
213 Sequence
< Any
> OPipeTest::getErrorExceptions() throw (RuntimeException
)
215 return m_seqExceptions
;
219 Sequence
< OUString
> OPipeTest::getWarnings() throw (RuntimeException
)
221 return m_seqWarnings
;
231 void OPipeTest::testSimple( const Reference
< XInterface
> &r
)
234 Reference
< XInputStream
> input( r
, UNO_QUERY
);
235 Reference
< XOutputStream
> output( r
, UNO_QUERY
);
237 ERROR_ASSERT( input
.is() , "queryInterface on XInputStream failed" );
238 ERROR_ASSERT( output
.is() , "queryInterface onXOutputStream failed" );
241 Sequence
<sal_Int8
> seqWrite
= createSeq( "Hallo, du Ei !" );
243 Sequence
<sal_Int8
> seqRead
;
244 for( int i
= 0 ; i
< 5000 ; i
++ ) {
245 output
->writeBytes( seqWrite
);
246 input
->readBytes( seqRead
, input
->available() );
248 ERROR_ASSERT( ! strcmp( (char *) seqWrite
.getArray() , (char * )seqRead
.getArray() ) ,
249 "error during read/write/skip" );
250 ERROR_ASSERT( 0 == input
->available() ,
251 "error during read/write/skip" );
253 // available shouldn't return a negative value
254 input
->skipBytes( seqWrite
.getLength() - 5 );
255 ERROR_ASSERT( 0 == input
->available() , "wrong available after skip" );
257 // 5 bytes should be available
258 output
->writeBytes( seqWrite
);
259 ERROR_ASSERT( 5 == input
->available() , "wrong available after skip/write " );
261 input
->readBytes( seqRead
, 5 );
262 ERROR_ASSERT( ! strcmp( (char*) seqRead
.getArray() ,
263 (char*) &( seqWrite
.getArray()[seqWrite
.getLength()-5] ) ),
264 "write/read mismatch" );
268 output
->writeBytes( seqWrite
);
269 ERROR_ASSERT( seqWrite
.getLength() == input
->available(), "wrong available() after write" );
271 ERROR_ASSERT( 10 == input
->readSomeBytes( seqRead
, 10 ) , "maximal number of bytes ignored" );
272 ERROR_ASSERT( seqWrite
.getLength() -10 == input
->readSomeBytes( seqRead
, 100 ) ,
273 "something wrong with readSomeBytes" );
276 output
->closeOutput();
278 output
->writeBytes( Sequence
<sal_Int8
> (100) );
279 ERROR_ASSERT( 0 , "writing on a closed stream does not cause an exception" );
281 catch (IOException
& )
285 ERROR_ASSERT(! input
->readBytes( seqRead
, 1 ), "eof not found !" );
290 input
->readBytes( seqRead
, 1 );
291 ERROR_ASSERT( 0 , "reading from a closed stream does not cause an exception" );
293 catch( IOException
& ) {
299 ERROR_ASSERT( 0 , "calling available from a closed stream should thrown an io exception" );
301 catch( IOException
& )
307 input
->skipBytes(42 );
308 ERROR_ASSERT( 0 , "calling available from a closed stream should thrown an io exception" );
310 catch( IOException
& )
316 void OPipeTest::testBufferResizing( const Reference
< XInterface
> &r
)
320 Reference
< XInputStream
> input( r
, UNO_QUERY
);
321 Reference
< XOutputStream
> output( r
, UNO_QUERY
);
323 ERROR_ASSERT( input
.is() , "queryInterface on XInputStream failed" );
324 ERROR_ASSERT( output
.is() , "queryInterface on XOutputStream failed" );
326 Sequence
<sal_Int8
> seqRead
;
328 // this is just to better check the
330 output
->writeBytes( Sequence
<sal_Int8
>(100) );
331 Sequence
< sal_Int8
> dummy
;
332 input
->readBytes( dummy
, 100);
334 for( i
= 0 ; i
< iMax
; i
++ ) {
335 output
->writeBytes( createIntSeq( i
) );
338 for( i
= 0 ; i
< iMax
; i
++ ) {
339 input
->readBytes( seqRead
, createIntSeq(i
).getLength() );
340 ERROR_ASSERT( ! strcmp( (char*) seqRead
.getArray() ,
341 (char*) createIntSeq(i
).getArray() ) ,
342 "written/read mismatch\n" );
345 output
->closeOutput();
346 ERROR_ASSERT( ! input
->readBytes( seqRead
, 1 ) , "eof not reached !" );
351 void OPipeTest::testMultithreading( const Reference
< XInterface
> &r
)
357 Reference
< XInputStream
> input( r
, UNO_QUERY
);
358 Reference
< XOutputStream
> output( r
, UNO_QUERY
);
360 ERROR_ASSERT( input
.is() , "queryInterface on XInputStream failed" );
361 ERROR_ASSERT( output
.is() , "queryInterface on XOutputStream failed" );
363 Sequence
<sal_Int8
> seqRead
;
366 Thread
*p
= new WriteToStreamThread( output
, iMax
);
368 ERROR_ASSERT( p
, "couldn't create thread for testing !\n" );
372 for( i
= 0 ; sal_True
; i
++ ) {
373 if( 0 == input
->readBytes( seqRead
, createIntSeq(i
).getLength() ) ) {
378 ERROR_ASSERT( ! strcmp( (char*) seqRead
.getArray() ,
379 (char*) createIntSeq(i
).getArray() ) ,
380 "written/read mismatch\n" );
383 ERROR_ASSERT( i
== iMax
, "less elements read than written !");
389 * for external binding
393 Reference
< XInterface
> SAL_CALL
OPipeTest_CreateInstance( const Reference
< XMultiServiceFactory
> & rSMgr
) throw (Exception
)
395 return getXWeak(new OPipeTest( rSMgr
));
399 Sequence
<OUString
> OPipeTest_getSupportedServiceNames() throw()
401 Sequence
<OUString
> aRet
{ OPipeTest_getServiceName() };
406 OUString
OPipeTest_getServiceName() throw()
408 return OUString( "test.com.sun.star.io.Pipe" );
411 OUString
OPipeTest_getImplementationName() throw()
413 return OUString( "test.com.sun.star.comp.extensions.stm.Pipe" );
416 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */