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