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 #include <stdio.h>
27 #include <osl/time.h>
28
29 #include <osl/diagnose.h>
30 #include <com/sun/star/test/XSimpleTest.hpp>
31
32 #include <com/sun/star/io/XActiveDataSource.hpp>
33 #include <com/sun/star/io/XActiveDataSink.hpp>
34 #include <com/sun/star/io/XActiveDataControl.hpp>
35 #include <com/sun/star/io/XConnectable.hpp>
36 #include <com/sun/star/lang/XServiceInfo.hpp>
37 #include <com/sun/star/lang/XSingleServiceFactory.hpp>
38 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
39 #include <com/sun/star/registry/XRegistryKey.hpp>
40
41 #include <uno/dispatcher.h>
42 #include <uno/mapping.hxx>
43 #include <cppuhelper/implbase1.hxx>
44 #include <cppuhelper/factory.hxx>
45 #include <osl/mutex.hxx>
46 #include <osl/thread.h>
47 #include <list>
48
49
50
51
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;
59
60 #include "testfactreg.hxx"
61
mywait()62 static void mywait()
63 {
64 TimeValue a = { 0, 10000 };
65 osl_waitThread( &a );
66 osl_yieldThread();
67 osl_yieldThread();
68 }
69
70 class OPumpTest : public WeakImplHelper1 < XSimpleTest >
71 {
72 public:
73 OPumpTest( const Reference< XMultiServiceFactory > & rFactory );
74 ~OPumpTest();
75
76 public: // implementation names
77 static Sequence< OUString > getSupportedServiceNames_Static(void) throw();
78 static OUString getImplementationName_Static() throw();
79
80 public:
81 virtual void SAL_CALL testInvariant(const OUString& TestName, const Reference < XInterface >& TestObject)
82 throw ( IllegalArgumentException, RuntimeException) ;
83
84 virtual sal_Int32 SAL_CALL test( const OUString& TestName,
85 const Reference < XInterface >& TestObject,
86 sal_Int32 hTestHandle)
87 throw ( IllegalArgumentException,
88 RuntimeException);
89
90 virtual sal_Bool SAL_CALL testPassed(void) throw ( RuntimeException) ;
91 virtual Sequence< OUString > SAL_CALL getErrors(void) throw (RuntimeException) ;
92 virtual Sequence< Any > SAL_CALL getErrorExceptions(void) throw (RuntimeException);
93 virtual Sequence< OUString > SAL_CALL getWarnings(void) throw (RuntimeException);
94
95 private:
96 void testSimple( const Reference < XInterface > & );
97 void testWrongUsage( const Reference < XInterface > & );
98 void testClose( const Reference< XInterface >& );
99 void testTerminate( const Reference< XInterface >& );
100 void testFunction( const Reference< XInterface >& );
101 private:
102 Sequence<Any> m_seqExceptions;
103 Sequence<OUString> m_seqErrors;
104 Sequence<OUString> m_seqWarnings;
105 Reference< XMultiServiceFactory > m_rSmgr;
106
107 };
108
OPumpTest(const Reference<XMultiServiceFactory> & rFactory)109 OPumpTest::OPumpTest( const Reference< XMultiServiceFactory > &rFactory ) :
110 m_rSmgr( rFactory )
111 {
112
113 }
114
~OPumpTest()115 OPumpTest::~OPumpTest()
116 {
117
118 }
119
120
121
testInvariant(const OUString & TestName,const Reference<XInterface> & TestObject)122 void OPumpTest::testInvariant( const OUString& TestName, const Reference < XInterface >& TestObject )
123 throw ( IllegalArgumentException,
124 RuntimeException)
125 {
126 Reference< XServiceInfo > info( TestObject, UNO_QUERY );
127 ERROR_ASSERT( info.is() , "XServiceInfo not supported !" );
128 if( info.is() )
129 {
130 ERROR_ASSERT( info->supportsService( TestName ), "XServiceInfo test failed" );
131 ERROR_ASSERT( ! info->supportsService(
132 OUString( RTL_CONSTASCII_USTRINGPARAM("bla bluzb") ) ), "XServiceInfo test failed" );
133 }
134
135 Reference < XActiveDataSource > xActiveDataSource( TestObject, UNO_QUERY );
136 Reference < XActiveDataSink > xActiveDataSink( TestObject, UNO_QUERY );
137 Reference < XActiveDataControl > xActiveDataControl( TestObject , UNO_QUERY );
138 Reference < XConnectable > xConnectable( TestObject , UNO_QUERY );
139
140 ERROR_ASSERT( xActiveDataSource.is() && xActiveDataSink.is() && xActiveDataControl.is () &&
141 xConnectable.is(), "specified interface not supported" );
142 }
143
144
test(const OUString & TestName,const Reference<XInterface> & TestObject,sal_Int32 hTestHandle)145 sal_Int32 OPumpTest::test(
146 const OUString& TestName,
147 const Reference < XInterface >& TestObject,
148 sal_Int32 hTestHandle)
149 throw ( IllegalArgumentException, RuntimeException)
150 {
151 if( OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.io.Pump") ) == TestName ) {
152 try
153 {
154 if( 0 == hTestHandle ) {
155 testInvariant( TestName , TestObject );
156 }
157 else if ( 1 == hTestHandle )
158 {
159 testWrongUsage( TestObject);
160 }
161 else if ( 2 == hTestHandle )
162 {
163 testClose( TestObject);
164 }
165 else if ( 3 == hTestHandle )
166 {
167 testTerminate( TestObject );
168 }
169 else if ( 4 == hTestHandle )
170 {
171 testFunction( TestObject );
172 }
173 }
174 catch( Exception & e )
175 {
176 OString s = OUStringToOString( e.Message , RTL_TEXTENCODING_ASCII_US );
177 BUILD_ERROR( 0 , s.getStr() );
178 }
179 catch( ... )
180 {
181 BUILD_ERROR( 0 , "unknown exception (Exception is not base class)" );
182 }
183
184 hTestHandle ++;
185
186 if( 5 == hTestHandle )
187 {
188 // all tests finished.
189 hTestHandle = -1;
190 }
191 }
192 else {
193 throw IllegalArgumentException();
194 }
195 return hTestHandle;
196 }
197
198
199
testPassed(void)200 sal_Bool OPumpTest::testPassed(void) throw (RuntimeException)
201 {
202 return m_seqErrors.getLength() == 0;
203 }
204
205
getErrors(void)206 Sequence< OUString > OPumpTest::getErrors(void) throw (RuntimeException)
207 {
208 return m_seqErrors;
209 }
210
211
getErrorExceptions(void)212 Sequence< Any > OPumpTest::getErrorExceptions(void) throw (RuntimeException)
213 {
214 return m_seqExceptions;
215 }
216
217
getWarnings(void)218 Sequence< OUString > OPumpTest::getWarnings(void) throw (RuntimeException)
219 {
220 return m_seqWarnings;
221 }
222
223
224 /***
225 * the test methods
226 *
227 ****/
228
229
testSimple(const Reference<XInterface> & r)230 void OPumpTest::testSimple( const Reference < XInterface > &r )
231 {
232 // jbu todo: add sensible test
233
234 }
235
236 class TestListener: public WeakImplHelper1< XStreamListener >
237 {
238 public:
239 sal_Bool m_bStarted;
240 sal_Bool m_bClosed;
241 sal_Bool m_bTerminated;
242 sal_Bool m_bError;
243 sal_Bool m_bDisposed;
TestListener()244 TestListener() : m_bStarted (sal_False),
245 m_bClosed (sal_False),
246 m_bTerminated ( sal_False ),
247 m_bError( sal_False ),
248 m_bDisposed( sal_False )
249 {}
250
disposing(const EventObject & obj)251 virtual void SAL_CALL disposing( const EventObject &obj ) throw (::com::sun::star::uno::RuntimeException)
252 {
253 m_bDisposed = sal_True;
254 // printf( "disposing called\n");
255 }
256
started()257 virtual void SAL_CALL started( ) throw (::com::sun::star::uno::RuntimeException)
258 {
259 m_bStarted = sal_True;
260 // printf( "started called\n");
261 }
closed()262 virtual void SAL_CALL closed( ) throw (::com::sun::star::uno::RuntimeException)
263 {
264 m_bClosed = sal_True;
265 // printf( "closed called\n");
266 }
terminated()267 virtual void SAL_CALL terminated( ) throw (::com::sun::star::uno::RuntimeException)
268 {
269 m_bTerminated = sal_True;
270 // printf( "terminated called\n");
271 }
error(const::com::sun::star::uno::Any & aException)272 virtual void SAL_CALL error( const ::com::sun::star::uno::Any& aException )
273 throw (::com::sun::star::uno::RuntimeException)
274 {
275 m_bError = sal_True;
276 Exception e;
277 aException >>= e;
278 // printf( "error called %s\n", OUStringToOString( e.Message, RTL_TEXTENCODING_ASCII_US).getStr() );
279 }
280 };
281
282 class TestCase
283 {
284 public:
TestCase(const Reference<XMultiServiceFactory> & rSMgr,const Reference<XInterface> & r)285 TestCase( const Reference< XMultiServiceFactory > & rSMgr,
286 const Reference< XInterface > &r ) : m_rSmgr( rSMgr ), m_pTestListener( 0 )
287 {
288 m_rControl = Reference<XActiveDataControl>( r, UNO_QUERY );
289
290 Reference< XActiveDataSource > rSource ( r, UNO_QUERY );
291 Reference< XActiveDataSink > rSink( r , UNO_QUERY );
292
293 m_rOutSource = Reference< XOutputStream > ( createPipe() );
294 rSink->setInputStream(Reference< XInputStream> (m_rOutSource,UNO_QUERY));
295
296 Reference< XOutputStream > rOutSink( createPipe() );
297 m_rInSink = Reference< XInputStream > ( rOutSink, UNO_QUERY );
298 rSource->setOutputStream( rOutSink );
299
300 m_pTestListener = new TestListener();
301 m_pTestListener->acquire();
302 m_rControl->addListener( m_pTestListener );
303 }
304
~TestCase()305 ~TestCase()
306 {
307 if( m_pTestListener )
308 m_pTestListener->release();
309 }
310
311 TestListener *m_pTestListener;
312 Reference< XActiveDataControl > m_rControl;
313 Reference< XOutputStream > m_rOutSource;
314 Reference< XInputStream > m_rInSink;
315 Reference< XMultiServiceFactory > m_rSmgr;
316
317 private:
createPipe()318 Reference< XOutputStream > createPipe()
319 {
320 Reference< XOutputStream > rOut( m_rSmgr->createInstance(
321 OUString::createFromAscii( "com.sun.star.io.Pipe" )),UNO_QUERY);
322 return rOut;
323 }
324 };
325
326
327
testClose(const Reference<XInterface> & r)328 void OPumpTest::testClose( const Reference< XInterface > &r )
329 {
330 TestCase t( m_rSmgr, r );
331
332 ERROR_ASSERT( ! t.m_pTestListener->m_bStarted , "started too early" );
333 ERROR_ASSERT( ! t.m_pTestListener->m_bTerminated , "terminiation unexpected" );
334 ERROR_ASSERT( ! t.m_pTestListener->m_bError, "unexpected error" );
335 ERROR_ASSERT( ! t.m_pTestListener->m_bClosed, "unexpected clase" );
336
337 t.m_rControl->start();
338 mywait();
339
340 ERROR_ASSERT( t.m_pTestListener->m_bStarted , "should have been started already" );
341 ERROR_ASSERT( ! t.m_pTestListener->m_bTerminated , "terminiation unexpected" );
342 ERROR_ASSERT( ! t.m_pTestListener->m_bError, "unexpected error" );
343 ERROR_ASSERT( ! t.m_pTestListener->m_bClosed, "unexpected clase" );
344
345 Reference< XStreamListener > rListener( new TestListener() );
346 t.m_rControl->addListener( rListener );
347 t.m_rControl->removeListener( rListener );
348
349 t.m_rOutSource->closeOutput();
350 mywait();
351 ERROR_ASSERT( t.m_pTestListener->m_bStarted , "should have been started already" );
352 ERROR_ASSERT( ! t.m_pTestListener->m_bTerminated , "should be terminiated already" );
353 ERROR_ASSERT( ! t.m_pTestListener->m_bError, "unexpected error" );
354 ERROR_ASSERT( t.m_pTestListener->m_bClosed, "should be closed already" );
355 }
356
testTerminate(const Reference<XInterface> & r)357 void OPumpTest::testTerminate( const Reference< XInterface > &r )
358 {
359 TestCase t( m_rSmgr, r );
360
361 ERROR_ASSERT( ! t.m_pTestListener->m_bStarted , "started too early" );
362 ERROR_ASSERT( ! t.m_pTestListener->m_bTerminated , "terminiation unexpected" );
363 ERROR_ASSERT( ! t.m_pTestListener->m_bError, "unexpected error" );
364 ERROR_ASSERT( ! t.m_pTestListener->m_bClosed, "unexpected clase" );
365
366 t.m_rControl->start();
367 mywait();
368
369 ERROR_ASSERT( t.m_pTestListener->m_bStarted , "should have been started already" );
370 ERROR_ASSERT( ! t.m_pTestListener->m_bTerminated , "terminiation unexpected" );
371 ERROR_ASSERT( ! t.m_pTestListener->m_bError, "unexpected error" );
372 ERROR_ASSERT( ! t.m_pTestListener->m_bClosed, "unexpected clase" );
373
374 t.m_rControl->terminate();
375
376 mywait();
377 ERROR_ASSERT( t.m_pTestListener->m_bStarted , "should have been started already" );
378 ERROR_ASSERT( t.m_pTestListener->m_bTerminated , "should be terminiated already" );
379 // terminte leads to an error, that is no surprise, in fact
380 // one can't tell whether the error occurs because of the terminate
381 // call or for some other reason !
382 // ERROR_ASSERT( ! t.m_pTestListener->m_bError, "unexpected error" );
383 ERROR_ASSERT( t.m_pTestListener->m_bClosed, "should be closed already" );
384 }
385
testFunction(const Reference<XInterface> & r)386 void OPumpTest::testFunction( const Reference< XInterface > &r )
387 {
388 TestCase t( m_rSmgr, r );
389
390 t.m_rControl->start();
391
392 t.m_rOutSource->writeBytes( Sequence< sal_Int8 > ( 5 ) );
393
394 Sequence< sal_Int8 > dummy;
395 ERROR_ASSERT( 5 == t.m_rInSink->readBytes( dummy , 5 ), "couldn't read the expected number of bytes" );
396
397 t.m_rOutSource->closeOutput();
398 mywait();
399
400 ERROR_ASSERT( t.m_pTestListener->m_bStarted , "should have been started already" );
401 ERROR_ASSERT( ! t.m_pTestListener->m_bTerminated , "should be terminiated already" );
402 ERROR_ASSERT( ! t.m_pTestListener->m_bError, "unexpected error" );
403 ERROR_ASSERT( t.m_pTestListener->m_bClosed, "should be closed already" );
404 }
405
testWrongUsage(const Reference<XInterface> & r)406 void OPumpTest::testWrongUsage( const Reference< XInterface > &r )
407 {
408 Reference< XActiveDataSource > rSource ( r, UNO_QUERY );
409 Reference< XActiveDataSink > rSink( r , UNO_QUERY );
410 Reference< XActiveDataControl > rControl( r, UNO_QUERY );
411
412 Reference< XInputStream > rIn( m_rSmgr->createInstance(
413 OUString::createFromAscii( "com.sun.star.io.DataInputStream" )),UNO_QUERY);
414 Reference< XOutputStream > rOut( m_rSmgr->createInstance(
415 OUString::createFromAscii( "com.sun.star.io.DataOutputStream" )),UNO_QUERY);
416
417 rSink->setInputStream( rIn );
418 rSource->setOutputStream( rOut );
419
420 rControl->start();
421
422 mywait();
423 }
424
OPumpTest_CreateInstance(const Reference<XMultiServiceFactory> & rSMgr)425 Reference< XInterface > SAL_CALL OPumpTest_CreateInstance( const Reference< XMultiServiceFactory > & rSMgr ) throw( Exception )
426 {
427 return *new OPumpTest( rSMgr );
428 }
429
OPumpTest_getSupportedServiceNames(void)430 Sequence<OUString> OPumpTest_getSupportedServiceNames(void) throw()
431 {
432 OUString s = OPumpTest_getServiceName();
433 Sequence< OUString > seq( &s , 1 );
434 return seq;
435
436 }
OPumpTest_getServiceName()437 OUString OPumpTest_getServiceName() throw()
438 {
439 return OUString( RTL_CONSTASCII_USTRINGPARAM( "test.com.sun.star.io.Pump" ) );
440 }
441
OPumpTest_getImplementationName()442 OUString OPumpTest_getImplementationName() throw()
443 {
444 return OUString( RTL_CONSTASCII_USTRINGPARAM( "test.com.sun.star.comp.io.Pump") );
445 }
446