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