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