28736981e480c95f76f44373360071f675cf6d91
[plcapi.git] / test / testsuite.php
1 <?php
2         /* $Id$ */
3
4         include(getcwd().'/parse_args.php');
5
6         require_once('xmlrpc.inc');
7         require_once('xmlrpcs.inc');
8         require_once('xmlrpc_wrappers.inc');
9
10         require_once 'phpunit.php';
11         //require_once 'PHPUnit/TestDecorator.php';
12
13         // let testuite run for the needed time
14         if ((int)ini_get('max_execution_time') < 180)
15                 ini_set('max_execution_time', 180);
16
17         ini_set('max_execution_time', 180);
18
19         $suite = new PHPUnit_TestSuite();
20
21         // array with list of failed tests
22         $failed_tests = array();
23
24         class LocalhostTests extends PHPUnit_TestCase
25         {
26                 var $client = null;
27                 var $method = 'http';
28                 var $timeout = 10;
29                 var $request_compression = null;
30                 var $accepted_compression = '';
31
32                 function fail($message = '')
33                 {
34                         PHPUnit_TestCase::fail($message);
35                         // save in global var that this particular test has failed
36                         // (but only if not called from subclass objects / multitests)
37                         if (function_exists('debug_backtrace') && strtolower(get_class($this)) == 'localhosttests')
38                         {
39                                 global $failed_tests;
40                                 $trace = debug_backtrace();
41                                 for ($i = 0; $i < count($trace); $i++)
42                                 {
43                                         if (strpos($trace[$i]['function'], 'test') === 0)
44                                         {
45                                                 $failed_tests[$trace[$i]['function']] = true;
46                                                 break;
47                                         }
48                                 }
49                         }
50                 }
51
52                 function setUp()
53                 {
54                         global $DEBUG, $LOCALSERVER, $URI;
55                         $server = explode(':', $LOCALSERVER);
56                         if(count($server) > 1)
57                         {
58                                 $this->client=new xmlrpc_client($URI, $server[0], $server[1]);
59                         }
60                         else
61                         {
62                                 $this->client=new xmlrpc_client($URI, $LOCALSERVER);
63                         }
64                         if($DEBUG)
65                         {
66                                 $this->client->setDebug($DEBUG);
67                         }
68                         $this->client->request_compression = $this->request_compression;
69                         $this->client->accepted_compression = $this->accepted_compression;
70                 }
71
72                 function send($msg, $errrorcode=0, $return_response=false)
73                 {
74                         $r = $this->client->send($msg, $this->timeout, $this->method);
75                         // for multicall, return directly array of responses
76                         if(is_array($r))
77                         {
78                                 return $r;
79                         }
80                         $this->assertEquals($r->faultCode(), $errrorcode, 'Error '.$r->faultCode().' connecting to server: '.$r->faultString());
81                         if(!$r->faultCode())
82                         {
83                                 if($return_response)
84                                         return $r;
85                                 else
86                                         return $r->value();
87                         }
88                         else
89                         {
90                                 return null;
91                         }
92                 }
93
94                 function testString()
95                 {
96                         $sendstring="here are 3 \"entities\": < > &" .
97                                 "and here's a dollar sign: \$pretendvarname and a backslash too: " . chr(92) .
98                                 " - isn't that great? \\\"hackery\\\" at it's best " .
99                                 " also don't want to miss out on \$item[0]. ".
100                                 "The real weird stuff follows: CRLF here".chr(13).chr(10).
101                                 "a simple CR here".chr(13).
102                                 "a simple LF here".chr(10).
103                                 "and then LFCR".chr(10).chr(13).
104                                 "last but not least weird names: Günter, Elène, and an xml comment closing tag: -->";
105                         $f=new xmlrpcmsg('examples.stringecho', array(
106                                 new xmlrpcval($sendstring, 'string')
107                         ));
108                         $v=$this->send($f);
109                         if($v)
110                         {
111                                 // when sending/receiving non-US-ASCII encoded strings, XML says cr-lf can be normalized.
112                                 // so we relax our tests...
113                                 $l1 = strlen($sendstring);
114                                 $l2 = strlen($v->scalarval());
115                                 if ($l1 == $l2)
116                                         $this->assertEquals($sendstring, $v->scalarval());
117                                 else
118                                         $this->assertEquals(str_replace(array("\r\n", "\r"), array("\n", "\n"), $sendstring), $v->scalarval());
119                         }
120                 }
121
122                 function testAddingDoubles()
123                 {
124                         // note that rounding errors mean i
125                         // keep precision to sensible levels here ;-)
126                         $a=12.13; $b=-23.98;
127                         $f=new xmlrpcmsg('examples.addtwodouble',array(
128                                 new xmlrpcval($a, 'double'),
129                                 new xmlrpcval($b, 'double')
130                         ));
131                         $v=$this->send($f);
132                         if($v)
133                         {
134                                 $this->assertEquals($a+$b,$v->scalarval());
135                         }
136                 }
137
138                 function testAdding()
139                 {
140                         $f=new xmlrpcmsg('examples.addtwo',array(
141                                 new xmlrpcval(12, 'int'),
142                                 new xmlrpcval(-23, 'int')
143                         ));
144                         $v=$this->send($f);
145                         if($v)
146                         {
147                                 $this->assertEquals(12-23, $v->scalarval());
148                         }
149                 }
150
151                 function testInvalidNumber()
152                 {
153                         $f=new xmlrpcmsg('examples.addtwo',array(
154                                 new xmlrpcval('fred', 'int'),
155                                 new xmlrpcval("\"; exec('ls')", 'int')
156                         ));
157                         $v=$this->send($f);
158                         /// @todo a fault condition should be generated here
159                         /// by the server, which we pick up on
160                         if($v)
161                         {
162                                 $this->assertEquals(0, $v->scalarval());
163                         }
164                 }
165
166                 function testBoolean()
167                 {
168                         $f=new xmlrpcmsg('examples.invertBooleans', array(
169                                 new xmlrpcval(array(
170                                         new xmlrpcval(true, 'boolean'),
171                                         new xmlrpcval(false, 'boolean'),
172                                         new xmlrpcval(1, 'boolean'),
173                                         new xmlrpcval(0, 'boolean'),
174                                         //new xmlrpcval('true', 'boolean'),
175                                         //new xmlrpcval('false', 'boolean')
176                                 ),
177                                 'array'
178                         )));
179                         $answer='0101';
180                         $v=$this->send($f);
181                         if($v)
182                         {
183                                 $sz=$v->arraysize();
184                                 $got='';
185                                 for($i=0; $i<$sz; $i++)
186                                 {
187                                         $b=$v->arraymem($i);
188                                         if($b->scalarval())
189                                         {
190                                                 $got.='1';
191                                         }
192                                         else
193                                         {
194                                                 $got.='0';
195                                         }
196                                 }
197                                 $this->assertEquals($answer, $got);
198                         }
199                 }
200
201                 function testBase64()
202                 {
203                         $sendstring='Mary had a little lamb,
204 Whose fleece was white as snow,
205 And everywhere that Mary went
206 the lamb was sure to go.
207
208 Mary had a little lamb
209 She tied it to a pylon
210 Ten thousand volts went down its back
211 And turned it into nylon';
212                         $f=new xmlrpcmsg('examples.decode64',array(
213                                 new xmlrpcval($sendstring, 'base64')
214                         ));
215                         $v=$this->send($f);
216                         if($v)
217                         {
218                                 if (strlen($sendstring) == strlen($v->scalarval()))
219                                         $this->assertEquals($sendstring, $v->scalarval());
220                                 else
221                                         $this->assertEquals(str_replace(array("\r\n", "\r"), array("\n", "\n"), $sendstring), $v->scalarval());
222                         }
223                 }
224
225         function testDateTime()
226         {
227             $time = time();
228             $t1 = new xmlrpcval($time, 'dateTime.iso8601');
229             $t2 = new xmlrpcval(iso8601_encode($time), 'dateTime.iso8601');
230             $this->assertEquals($t1->serialize(), $t2->serialize());
231             if (class_exists('DateTime'))
232             {
233                 $datetime = new DateTime();
234                 $t3 = new xmlrpcval($datetime->setTimestamp($time), 'dateTime.iso8601');
235                 $this->assertEquals($t1->serialize(), $t3->serialize());
236             }
237         }
238
239                 function testCountEntities()
240                 {
241                         $sendstring = "h'fd>onc>>l>>rw&bpu>q>e<v&gxs<ytjzkami<";
242                         $f = new xmlrpcmsg('validator1.countTheEntities',array(
243                                 new xmlrpcval($sendstring, 'string')
244                         ));
245                         $v = $this->send($f);
246                         if($v)
247                         {
248                                 $got = '';
249                                 $expected = '37210';
250                                 $expect_array = array('ctLeftAngleBrackets','ctRightAngleBrackets','ctAmpersands','ctApostrophes','ctQuotes');
251                                 while(list(,$val) = each($expect_array))
252                                 {
253                                         $b = $v->structmem($val);
254                                         $got .= $b->me['int'];
255                                 }
256                                 $this->assertEquals($expected, $got);
257                         }
258                 }
259
260                 function _multicall_msg($method, $params)
261                 {
262                         $struct['methodName'] = new xmlrpcval($method, 'string');
263                         $struct['params'] = new xmlrpcval($params, 'array');
264                         return new xmlrpcval($struct, 'struct');
265                 }
266
267                 function testServerMulticall()
268                 {
269                         // We manually construct a system.multicall() call to ensure
270                         // that the server supports it.
271
272                         // NB: This test will NOT pass if server does not support system.multicall.
273
274                         // Based on http://xmlrpc-c.sourceforge.net/hacks/test_multicall.py
275                         $good1 = $this->_multicall_msg(
276                                 'system.methodHelp',
277                                 array(php_xmlrpc_encode('system.listMethods')));
278                         $bad = $this->_multicall_msg(
279                                 'test.nosuch',
280                                 array(php_xmlrpc_encode(1), php_xmlrpc_encode(2)));
281                         $recursive = $this->_multicall_msg(
282                                 'system.multicall',
283                                 array(new xmlrpcval(array(), 'array')));
284                         $good2 = $this->_multicall_msg(
285                                 'system.methodSignature',
286                                 array(php_xmlrpc_encode('system.listMethods')));
287                         $arg = new xmlrpcval(
288                                 array($good1, $bad, $recursive, $good2),
289                                 'array'
290                         );
291
292                         $f = new xmlrpcmsg('system.multicall', array($arg));
293                         $v = $this->send($f);
294                         if($v)
295                         {
296                                 //$this->assertTrue($r->faultCode() == 0, "fault from system.multicall");
297                                 $this->assertTrue($v->arraysize() == 4, "bad number of return values");
298
299                                 $r1 = $v->arraymem(0);
300                                 $this->assertTrue(
301                                         $r1->kindOf() == 'array' && $r1->arraysize() == 1,
302                                         "did not get array of size 1 from good1"
303                                 );
304
305                                 $r2 = $v->arraymem(1);
306                                 $this->assertTrue(
307                                         $r2->kindOf() == 'struct',
308                                         "no fault from bad"
309                                 );
310
311                                 $r3 = $v->arraymem(2);
312                                 $this->assertTrue(
313                                         $r3->kindOf() == 'struct',
314                                         "recursive system.multicall did not fail"
315                                 );
316
317                                 $r4 = $v->arraymem(3);
318                                 $this->assertTrue(
319                                         $r4->kindOf() == 'array' && $r4->arraysize() == 1,
320                                         "did not get array of size 1 from good2"
321                                 );
322                         }
323                 }
324
325                 function testClientMulticall1()
326                 {
327                         // NB: This test will NOT pass if server does not support system.multicall.
328
329                         $this->client->no_multicall = false;
330
331                         $good1 = new xmlrpcmsg('system.methodHelp',
332                                 array(php_xmlrpc_encode('system.listMethods')));
333                         $bad = new xmlrpcmsg('test.nosuch',
334                                 array(php_xmlrpc_encode(1), php_xmlrpc_encode(2)));
335                         $recursive = new xmlrpcmsg('system.multicall',
336                                 array(new xmlrpcval(array(), 'array')));
337                         $good2 = new xmlrpcmsg('system.methodSignature',
338                                 array(php_xmlrpc_encode('system.listMethods'))
339                         );
340
341                         $r = $this->send(array($good1, $bad, $recursive, $good2));
342                         if($r)
343                         {
344                                 $this->assertTrue(count($r) == 4, "wrong number of return values");
345                         }
346
347                         $this->assertTrue($r[0]->faultCode() == 0, "fault from good1");
348                         if(!$r[0]->faultCode())
349                         {
350                                 $val = $r[0]->value();
351                                 $this->assertTrue(
352                                         $val->kindOf() == 'scalar' && $val->scalartyp() == 'string',
353                                         "good1 did not return string"
354                                 );
355                         }
356                         $this->assertTrue($r[1]->faultCode() != 0, "no fault from bad");
357                         $this->assertTrue($r[2]->faultCode() != 0, "no fault from recursive system.multicall");
358                         $this->assertTrue($r[3]->faultCode() == 0, "fault from good2");
359                         if(!$r[3]->faultCode())
360                         {
361                                 $val = $r[3]->value();
362                                 $this->assertTrue($val->kindOf() == 'array', "good2 did not return array");
363                         }
364                         // This is the only assert in this test which should fail
365                         // if the test server does not support system.multicall.
366                         $this->assertTrue($this->client->no_multicall == false,
367                                 "server does not support system.multicall"
368                         );
369                 }
370
371                 function testClientMulticall2()
372                 {
373                         // NB: This test will NOT pass if server does not support system.multicall.
374
375                         $this->client->no_multicall = true;
376
377                         $good1 = new xmlrpcmsg('system.methodHelp',
378                                 array(php_xmlrpc_encode('system.listMethods')));
379                         $bad = new xmlrpcmsg('test.nosuch',
380                                 array(php_xmlrpc_encode(1), php_xmlrpc_encode(2)));
381                         $recursive = new xmlrpcmsg('system.multicall',
382                                 array(new xmlrpcval(array(), 'array')));
383                         $good2 = new xmlrpcmsg('system.methodSignature',
384                                 array(php_xmlrpc_encode('system.listMethods'))
385                         );
386
387                         $r = $this->send(array($good1, $bad, $recursive, $good2));
388                         if($r)
389                         {
390                                 $this->assertTrue(count($r) == 4, "wrong number of return values");
391                         }
392
393                         $this->assertTrue($r[0]->faultCode() == 0, "fault from good1");
394                         if(!$r[0]->faultCode())
395                         {
396                                 $val = $r[0]->value();
397                                 $this->assertTrue(
398                                         $val->kindOf() == 'scalar' && $val->scalartyp() == 'string',
399                                         "good1 did not return string");
400                         }
401                         $this->assertTrue($r[1]->faultCode() != 0, "no fault from bad");
402                         $this->assertTrue($r[2]->faultCode() == 0, "fault from (non recursive) system.multicall");
403                         $this->assertTrue($r[3]->faultCode() == 0, "fault from good2");
404                         if(!$r[3]->faultCode())
405                         {
406                                 $val = $r[3]->value();
407                                 $this->assertTrue($val->kindOf() == 'array', "good2 did not return array");
408                         }
409                 }
410
411                 function testClientMulticall3()
412                 {
413                         // NB: This test will NOT pass if server does not support system.multicall.
414
415                         $this->client->return_type = 'phpvals';
416                         $this->client->no_multicall = false;
417
418                         $good1 = new xmlrpcmsg('system.methodHelp',
419                                 array(php_xmlrpc_encode('system.listMethods')));
420                         $bad = new xmlrpcmsg('test.nosuch',
421                                 array(php_xmlrpc_encode(1), php_xmlrpc_encode(2)));
422                         $recursive = new xmlrpcmsg('system.multicall',
423                                 array(new xmlrpcval(array(), 'array')));
424                         $good2 = new xmlrpcmsg('system.methodSignature',
425                                 array(php_xmlrpc_encode('system.listMethods'))
426                         );
427
428                         $r = $this->send(array($good1, $bad, $recursive, $good2));
429                         if($r)
430                         {
431                                 $this->assertTrue(count($r) == 4, "wrong number of return values");
432                         }
433                         $this->assertTrue($r[0]->faultCode() == 0, "fault from good1");
434                         if(!$r[0]->faultCode())
435                         {
436                                 $val = $r[0]->value();
437                                 $this->assertTrue(
438                                         is_string($val) , "good1 did not return string");
439                         }
440                         $this->assertTrue($r[1]->faultCode() != 0, "no fault from bad");
441                         $this->assertTrue($r[2]->faultCode() != 0, "no fault from recursive system.multicall");
442                         $this->assertTrue($r[3]->faultCode() == 0, "fault from good2");
443                         if(!$r[3]->faultCode())
444                         {
445                                 $val = $r[3]->value();
446                                 $this->assertTrue(is_array($val), "good2 did not return array");
447                         }
448                         $this->client->return_type = 'xmlrpcvals';
449                 }
450
451                 function testCatchWarnings()
452                 {
453                         $f = new xmlrpcmsg('examples.generatePHPWarning', array(
454                                 new xmlrpcval('whatever', 'string')
455                         ));
456                         $v = $this->send($f);
457                         if($v)
458                         {
459                                 $this->assertEquals($v->scalarval(), true);
460                         }
461                 }
462
463                 function testZeroParams()
464                 {
465                         $f = new xmlrpcmsg('system.listMethods');
466                         $v = $this->send($f);
467                 }
468
469                 function testCodeInjectionServerSide()
470                 {
471                         $f = new xmlrpcmsg('system.MethodHelp');
472                         $f->payload = "<?xml version=\"1.0\"?><methodCall><methodName>validator1.echoStructTest</methodName><params><param><value><struct><member><name>','')); echo('gotcha!'); die(); //</name></member></struct></value></param></params></methodCall>";
473                         $v = $this->send($f);
474                         //$v = $r->faultCode();
475                         if ($v)
476                         {
477                                 $this->assertEquals(0, $v->structsize());
478                         }
479                 }
480
481                 function testAutoRegisteredFunction()
482                 {
483                         $f=new xmlrpcmsg('examples.php.getStateName',array(
484                                 new xmlrpcval(23, 'int')
485                         ));
486                         $v=$this->send($f);
487                         if($v)
488                         {
489                                 $this->assertEquals('Michigan', $v->scalarval());
490                         }
491                         else
492                         {
493                                 $this->fail('Note: server can only auto register functions if running with PHP 5.0.3 and up');
494                         }
495                 }
496
497                 function testAutoRegisteredClass()
498                 {
499                         $f=new xmlrpcmsg('examples.php2.getStateName',array(
500                                 new xmlrpcval(23, 'int')
501                         ));
502                         $v=$this->send($f);
503                         if($v)
504                         {
505                                 $this->assertEquals('Michigan', $v->scalarval());
506                         $f=new xmlrpcmsg('examples.php3.getStateName',array(
507                                 new xmlrpcval(23, 'int')
508                         ));
509                         $v=$this->send($f);
510                         if($v)
511                         {
512                                 $this->assertEquals('Michigan', $v->scalarval());
513                         }
514                 }
515                         else
516                         {
517                                 $this->fail('Note: server can only auto register class methods if running with PHP 5.0.3 and up');
518                         }
519                 }
520
521                 function testAutoRegisteredMethod()
522                 {
523                         $func=wrap_xmlrpc_method($this->client, 'examples.getStateName');
524                         if($func == '')
525                         {
526                                 $this->fail('Registration of examples.getStateName failed');
527                         }
528                         else
529                         {
530                                 $v=$func(23);
531                                 $this->assertEquals('Michigan', $v);
532                         }
533                 }
534
535                 function testGetCookies()
536                 {
537                         // let server set to us some cookies we tell it
538                         $cookies = array(
539                                 //'c1' => array(),
540                                 'c2' => array('value' => 'c2'),
541                                 'c3' => array('value' => 'c3', 'expires' => time()+60*60*24*30),
542                                 'c4' => array('value' => 'c4', 'expires' => time()+60*60*24*30, 'path' => '/'),
543                                 'c5' => array('value' => 'c5', 'expires' => time()+60*60*24*30, 'path' => '/', 'domain' => 'localhost'),
544                         );
545                         $cookiesval =& php_xmlrpc_encode($cookies);
546                         $f=new xmlrpcmsg('examples.setcookies',array($cookiesval));
547                         $r=$this->send($f, 0, true);
548                         if($r)
549                         {
550                                 $v = $r->value();
551                                 $this->assertEquals(1, $v->scalarval());
552                                 // now check if we decoded the cookies as we had set them
553                                 $rcookies = $r->cookies();
554                                 foreach($cookies as $c => $v)
555                                 // format for date string in cookies: 'Mon, 31 Oct 2005 13:50:56 GMT'
556                                 // but PHP versions differ on that, some use 'Mon, 31-Oct-2005 13:50:56 GMT'...
557                                         if(isset($v['expires']))
558                                         {
559                                                 if (isset($rcookies[$c]['expires']) && strpos($rcookies[$c]['expires'], '-'))
560                                                 {
561                                                         $cookies[$c]['expires'] = gmdate('D, d\-M\-Y H:i:s \G\M\T' ,$cookies[$c]['expires']);
562                                                 }
563                                                 else
564                                                 {
565                                                         $cookies[$c]['expires'] = gmdate('D, d M Y H:i:s \G\M\T' ,$cookies[$c]['expires']);
566                                                 }
567                                         }
568                                 $this->assertEquals($cookies, $rcookies);
569                         }
570                 }
571
572                 function testSetCookies()
573                 {
574                         // let server set to us some cookies we tell it
575                         $cookies = array(
576                                 'c0' => null,
577                                 'c1' => 1,
578                                 'c2' => '2 3',
579                                 'c3' => '!@#$%^&*()_+|}{":?><,./\';[]\\=-'
580                         );
581                         $f=new xmlrpcmsg('examples.getcookies',array());
582                         foreach ($cookies as $cookie => $val)
583                         {
584                                 $this->client->setCookie($cookie, $val);
585                                 $cookies[$cookie] = (string) $cookies[$cookie];
586                         }
587                         $r = $this->client->send($f, $this->timeout, $this->method);
588                         $this->assertEquals($r->faultCode(), 0, 'Error '.$r->faultCode().' connecting to server: '.$r->faultString());
589                         if(!$r->faultCode())
590                         {
591                                 $v = $r->value();
592                                 $v = php_xmlrpc_decode($v);
593                                 // on IIS and Apache getallheaders returns something slightly different...
594                                 $this->assertEquals($v, $cookies);
595                         }
596                 }
597
598                 function testSendTwiceSameMsg()
599                 {
600                         $f=new xmlrpcmsg('examples.stringecho', array(
601                                 new xmlrpcval('hello world', 'string')
602                         ));
603                         $v1 = $this->send($f);
604                         $v2 = $this->send($f);
605                         //$v = $r->faultCode();
606                         if ($v1 && $v2)
607                         {
608                                 $this->assertEquals($v2, $v1);
609                         }
610                 }
611         }
612
613         class LocalHostMultiTests extends LocalhostTests
614         {
615                 function _runtests()
616                 {
617                         global $failed_tests;
618                         foreach(get_class_methods('LocalhostTests') as $meth)
619                         {
620                                 if(strpos($meth, 'test') === 0 && $meth != 'testHttps')
621                                 {
622                                         if (!isset($failed_tests[$meth]))
623                                                 $this->$meth();
624                                 }
625                                 if ($this->_failed)
626                                 {
627                                         break;
628                                 }
629                         }
630                 }
631
632                 function testDeflate()
633                 {
634                         if(!function_exists('gzdeflate'))
635                         {
636                                 $this->fail('Zlib missing: cannot test deflate functionality');
637                                 return;
638                         }
639                         $this->client->accepted_compression = array('deflate');
640                         $this->client->request_compression = 'deflate';
641                         $this->_runtests();
642                 }
643
644                 function testGzip()
645                 {
646                         if(!function_exists('gzdeflate'))
647                         {
648                                 $this->fail('Zlib missing: cannot test gzip functionality');
649                                 return;
650                         }
651                         $this->client->accepted_compression = array('gzip');
652                         $this->client->request_compression = 'gzip';
653                         $this->_runtests();
654                 }
655
656                 function testKeepAlives()
657                 {
658                         if(!function_exists('curl_init'))
659                         {
660                                 $this->fail('CURL missing: cannot test http 1.1');
661                                 return;
662                         }
663                         $this->method = 'http11';
664                         $this->client->keepalive = true;
665                         $this->_runtests();
666                 }
667
668                 function testProxy()
669                 {
670                         global $PROXYSERVER, $PROXYPORT;
671             if ($PROXYSERVER)
672             {
673                                 $this->client->setProxy($PROXYSERVER, $PROXYPORT);
674                                 $this->_runtests();
675             }
676             else
677                 $this->fail('PROXY definition missing: cannot test proxy');
678                 }
679
680                 function testHttp11()
681                 {
682                         if(!function_exists('curl_init'))
683                         {
684                                 $this->fail('CURL missing: cannot test http 1.1');
685                                 return;
686                         }
687                         $this->method = 'http11'; // not an error the double assignment!
688                         $this->client->method = 'http11';
689                         //$this->client->verifyhost = 0;
690                         //$this->client->verifypeer = 0;
691                         $this->client->keepalive = false;
692                         $this->_runtests();
693                 }
694
695                 function testHttp11Gzip()
696                 {
697                         if(!function_exists('curl_init'))
698                         {
699                                 $this->fail('CURL missing: cannot test http 1.1');
700                                 return;
701                         }
702                         $this->method = 'http11'; // not an error the double assignment!
703                         $this->client->method = 'http11';
704                         $this->client->keepalive = false;
705                         $this->client->accepted_compression = array('gzip');
706                         $this->client->request_compression = 'gzip';
707                         $this->_runtests();
708                 }
709
710                 function testHttp11Deflate()
711                 {
712                         if(!function_exists('curl_init'))
713                         {
714                                 $this->fail('CURL missing: cannot test http 1.1');
715                                 return;
716                         }
717                         $this->method = 'http11'; // not an error the double assignment!
718                         $this->client->method = 'http11';
719                         $this->client->keepalive = false;
720                         $this->client->accepted_compression = array('deflate');
721                         $this->client->request_compression = 'deflate';
722                         $this->_runtests();
723                 }
724
725                 function testHttp11Proxy()
726                 {
727                         global $PROXYSERVER, $PROXYPORT;
728                         if(!function_exists('curl_init'))
729                         {
730                                 $this->fail('CURL missing: cannot test http 1.1 w. proxy');
731                                 return;
732                         }
733             else if ($PROXYSERVER == '')
734             {
735                 $this->fail('PROXY definition missing: cannot test proxy w. http 1.1');
736                 return;
737             }
738                         $this->method = 'http11'; // not an error the double assignment!
739                         $this->client->method = 'http11';
740             $this->client->setProxy($PROXYSERVER, $PROXYPORT);
741                         //$this->client->verifyhost = 0;
742                         //$this->client->verifypeer = 0;
743                         $this->client->keepalive = false;
744                         $this->_runtests();
745                 }
746
747                 function testHttps()
748                 {
749                         global $HTTPSSERVER, $HTTPSURI;
750                         if(!function_exists('curl_init'))
751                         {
752                                 $this->fail('CURL missing: cannot test https functionality');
753                                 return;
754                         }
755                         $this->client->server = $HTTPSSERVER;
756                         $this->method = 'https';
757                         $this->client->method = 'https';
758                         $this->client->path = $HTTPSURI;
759                         $this->_runtests();
760                 }
761
762                 function testHttpsProxy()
763                 {
764                         global $HTTPSSERVER, $HTTPSURI, $PROXYSERVER, $PROXYPORT;;
765                         if(!function_exists('curl_init'))
766                         {
767                                 $this->fail('CURL missing: cannot test https functionality');
768                                 return;
769                         }
770             else if ($PROXYSERVER == '')
771             {
772                 $this->fail('PROXY definition missing: cannot test proxy w. http 1.1');
773                 return;
774             }
775                         $this->client->server = $HTTPSSERVER;
776                         $this->method = 'https';
777                         $this->client->method = 'https';
778             $this->client->setProxy($PROXYSERVER, $PROXYPORT);
779                         $this->client->path = $HTTPSURI;
780                         $this->_runtests();
781                 }
782
783                 function testUTF8Responses()
784                 {
785                         global $URI;
786                         //$this->client->path = strpos($URI, '?') === null ? $URI.'?RESPONSE_ENCODING=UTF-8' : $URI.'&RESPONSE_ENCODING=UTF-8';
787                         $this->client->path = $URI.'?RESPONSE_ENCODING=UTF-8';
788                         $this->_runtests();
789                 }
790
791                 function testUTF8Requests()
792                 {
793                         $this->client->request_charset_encoding = 'UTF-8';
794                         $this->_runtests();
795                 }
796
797                 function testISOResponses()
798                 {
799                         global $URI;
800                         //$this->client->path = strpos($URI, '?') === null ? $URI.'?RESPONSE_ENCODING=UTF-8' : $URI.'&RESPONSE_ENCODING=UTF-8';
801                         $this->client->path = $URI.'?RESPONSE_ENCODING=ISO-8859-1';
802                         $this->_runtests();
803                 }
804
805                 function testISORequests()
806                 {
807                         $this->client->request_charset_encoding = 'ISO-8859-1';
808                         $this->_runtests();
809                 }
810         }
811
812         class ParsingBugsTests extends PHPUnit_TestCase
813         {
814                 function testMinusOneString()
815                 {
816                         $v=new xmlrpcval('-1');
817                         $u=new xmlrpcval('-1', 'string');
818                         $this->assertEquals($u->scalarval(), $v->scalarval());
819                 }
820
821                 function testUnicodeInMemberName(){
822                         $v = array('Günter, Elène' => new xmlrpcval(1));
823                         $r = new xmlrpcresp(new xmlrpcval($v, 'struct'));
824                         $r = $r->serialize();
825                         $m = new xmlrpcmsg('dummy');
826                         $r = $m->parseResponse($r);
827                         $v = $r->value();
828                         $this->assertEquals($v->structmemexists('Günter, Elène'), true);
829                 }
830
831                 function testUnicodeInErrorString()
832                 {
833                         $response = utf8_encode(
834 '<?xml version="1.0"?>
835 <!-- $Id -->
836 <!-- found by G. giunta, covers what happens when lib receives
837   UTF8 chars in reponse text and comments -->
838 <!-- àüè&#224;&#252;&#232; -->
839 <methodResponse>
840 <fault>
841 <value>
842 <struct>
843 <member>
844 <name>faultCode</name>
845 <value><int>888</int></value>
846 </member>
847 <member>
848 <name>faultString</name>
849 <value><string>àüè&#224;&#252;&#232;</string></value>
850 </member>
851 </struct>
852 </value>
853 </fault>
854 </methodResponse>');
855                         $m=new xmlrpcmsg('dummy');
856                         $r=$m->parseResponse($response);
857                         $v=$r->faultString();
858                         $this->assertEquals('àüèàüè', $v);
859                 }
860
861                 function testValidNumbers()
862                 {
863                         $m=new xmlrpcmsg('dummy');
864                         $fp=
865 '<?xml version="1.0"?>
866 <methodResponse>
867 <params>
868 <param>
869 <value>
870 <struct>
871 <member>
872 <name>integer1</name>
873 <value><int>01</int></value>
874 </member>
875 <member>
876 <name>float1</name>
877 <value><double>01.10</double></value>
878 </member>
879 <member>
880 <name>integer2</name>
881 <value><int>+1</int></value>
882 </member>
883 <member>
884 <name>float2</name>
885 <value><double>+1.10</double></value>
886 </member>
887 <member>
888 <name>float3</name>
889 <value><double>-1.10e2</double></value>
890 </member>
891 </struct>
892 </value>
893 </param>
894 </params>
895 </methodResponse>';
896                         $r=$m->parseResponse($fp);
897                         $v=$r->value();
898                         $s=$v->structmem('integer1');
899                         $t=$v->structmem('float1');
900                         $u=$v->structmem('integer2');
901                         $w=$v->structmem('float2');
902                         $x=$v->structmem('float3');
903                         $this->assertEquals(1, $s->scalarval());
904                         $this->assertEquals(1.1, $t->scalarval());
905                         $this->assertEquals(1, $u->scalarval());
906                         $this->assertEquals(1.1, $w->scalarval());
907                         $this->assertEquals(-110.0, $x->scalarval());
908                 }
909
910                 function testAddScalarToStruct()
911                 {
912                         $v=new xmlrpcval(array('a' => 'b'), 'struct');
913                         // use @ operator in case error_log gets on screen
914                         $r= @$v->addscalar('c');
915                         $this->assertEquals(0, $r);
916                 }
917
918                 function testAddStructToStruct()
919                 {
920                         $v=new xmlrpcval(array('a' => new xmlrpcval('b')), 'struct');
921                         $r=$v->addstruct(array('b' => new xmlrpcval('c')));
922                         $this->assertEquals(2, $v->structsize());
923                         $this->assertEquals(1, $r);
924                         $r=$v->addstruct(array('b' => new xmlrpcval('b')));
925                         $this->assertEquals(2, $v->structsize());
926                 }
927
928                 function testAddArrayToArray()
929                 {
930                         $v=new xmlrpcval(array(new xmlrpcval('a'), new xmlrpcval('b')), 'array');
931                         $r=$v->addarray(array(new xmlrpcval('b'), new xmlrpcval('c')));
932                         $this->assertEquals(4, $v->arraysize());
933                         $this->assertEquals(1, $r);
934                 }
935
936                 function testEncodeArray()
937                 {
938                         $r=range(1, 100);
939                         $v = php_xmlrpc_encode($r);
940                         $this->assertEquals('array', $v->kindof());
941                 }
942
943                 function testEncodeRecursive()
944                 {
945                         $v = php_xmlrpc_encode(php_xmlrpc_encode('a simple string'));
946                         $this->assertEquals('scalar', $v->kindof());
947                 }
948
949                 function testBrokenRequests()
950                 {
951                         $s = new xmlrpc_server();
952 // omitting the 'params' tag: not tolerated by the lib anymore
953 $f = '<?xml version="1.0"?>
954 <methodCall>
955 <methodName>system.methodHelp</methodName>
956 <param>
957 <value><string>system.methodHelp</string></value>
958 </param>
959 </methodCall>';
960                         $r = $s->parserequest($f);
961                         $this->assertEquals(15, $r->faultCode());
962 // omitting a 'param' tag
963 $f = '<?xml version="1.0"?>
964 <methodCall>
965 <methodName>system.methodHelp</methodName>
966 <params>
967 <value><string>system.methodHelp</string></value>
968 </params>
969 </methodCall>';
970                         $r = $s->parserequest($f);
971                         $this->assertEquals(15, $r->faultCode());
972 // omitting a 'value' tag
973 $f = '<?xml version="1.0"?>
974 <methodCall>
975 <methodName>system.methodHelp</methodName>
976 <params>
977 <param><string>system.methodHelp</string></param>
978 </params>
979 </methodCall>';
980                         $r = $s->parserequest($f);
981                         $this->assertEquals(15, $r->faultCode());
982                 }
983
984                 function testBrokenResponses()
985                 {
986                         $m=new xmlrpcmsg('dummy');
987                         //$m->debug = 1;
988 // omitting the 'params' tag: no more tolerated by the lib...
989 $f = '<?xml version="1.0"?>
990 <methodResponse>
991 <param>
992 <value><string>system.methodHelp</string></value>
993 </param>
994 </methodResponse>';
995                         $r = $m->parseResponse($f);
996                         $this->assertEquals(2, $r->faultCode());
997 // omitting the 'param' tag: no more tolerated by the lib...
998 $f = '<?xml version="1.0"?>
999 <methodResponse>
1000 <params>
1001 <value><string>system.methodHelp</string></value>
1002 </params>
1003 </methodResponse>';
1004                         $r = $m->parseResponse($f);
1005                         $this->assertEquals(2, $r->faultCode());
1006 // omitting a 'value' tag: KO
1007 $f = '<?xml version="1.0"?>
1008 <methodResponse>
1009 <params>
1010 <param><string>system.methodHelp</string></param>
1011 </params>
1012 </methodResponse>';
1013                         $r = $m->parseResponse($f);
1014                         $this->assertEquals(2, $r->faultCode());
1015                 }
1016
1017                 function testBuggyHttp()
1018                 {
1019                         $s = new xmlrpcmsg('dummy');
1020 $f = 'HTTP/1.1 100 Welcome to the jungle
1021
1022 HTTP/1.0 200 OK
1023 X-Content-Marx-Brothers: Harpo
1024                         Chico and Groucho
1025 Content-Length: who knows?
1026
1027
1028
1029 <?xml version="1.0"?>
1030 <!-- First of all, let\'s check out if the lib properly handles a commented </methodResponse> tag... -->
1031 <methodResponse><params><param><value><struct><member><name>userid</name><value>311127</value></member>
1032 <member><name>dateCreated</name><value><dateTime.iso8601>20011126T09:17:52</dateTime.iso8601></value></member><member><name>content</name><value>hello world. 2 newlines follow
1033
1034
1035 and there they were.</value></member><member><name>postid</name><value>7414222</value></member></struct></value></param></params></methodResponse>
1036 <script type="text\javascript">document.write(\'Hello, my name is added nag, I\\\'m happy to serve your content for free\');</script>
1037  ';
1038                         $r = $s->parseResponse($f);
1039                         $v = $r->value();
1040                         $s = $v->structmem('content');
1041                         $this->assertEquals("hello world. 2 newlines follow\n\n\nand there they were.", $s->scalarval());
1042                 }
1043
1044                 function testStringBug()
1045                 {
1046                         $s = new xmlrpcmsg('dummy');
1047 $f = '<?xml version="1.0"?>
1048 <!-- $Id -->
1049 <!-- found by 2z69xks7bpy001@sneakemail.com, amongst others
1050  covers what happens when there\'s character data after </string>
1051  and before </value> -->
1052 <methodResponse>
1053 <params>
1054 <param>
1055 <value>
1056 <struct>
1057 <member>
1058 <name>success</name>
1059 <value>
1060 <boolean>1</boolean>
1061 </value>
1062 </member>
1063 <member>
1064 <name>sessionID</name>
1065 <value>
1066 <string>S300510007I</string>
1067 </value>
1068 </member>
1069 </struct>
1070 </value>
1071 </param>
1072 </params>
1073 </methodResponse> ';
1074                         $r = $s->parseResponse($f);
1075                         $v = $r->value();
1076                         $s = $v->structmem('sessionID');
1077                         $this->assertEquals('S300510007I', $s->scalarval());
1078                 }
1079
1080                 function testWhiteSpace()
1081                 {
1082                         $s = new xmlrpcmsg('dummy');
1083 $f = '<?xml version="1.0"?><methodResponse><params><param><value><struct><member><name>userid</name><value>311127</value></member>
1084 <member><name>dateCreated</name><value><dateTime.iso8601>20011126T09:17:52</dateTime.iso8601></value></member><member><name>content</name><value>hello world. 2 newlines follow
1085
1086
1087 and there they were.</value></member><member><name>postid</name><value>7414222</value></member></struct></value></param></params></methodResponse>
1088 ';
1089                         $r = $s->parseResponse($f);
1090                         $v = $r->value();
1091                         $s = $v->structmem('content');
1092                         $this->assertEquals("hello world. 2 newlines follow\n\n\nand there they were.", $s->scalarval());
1093                 }
1094
1095                 function testDoubleDataInArrayTag()
1096                 {
1097                         $s = new xmlrpcmsg('dummy');
1098 $f = '<?xml version="1.0"?><methodResponse><params><param><value><array>
1099 <data></data>
1100 <data></data>
1101 </array></value></param></params></methodResponse>
1102 ';
1103                         $r = $s->parseResponse($f);
1104                         $v = $r->faultCode();
1105                         $this->assertEquals(2, $v);
1106 $f = '<?xml version="1.0"?><methodResponse><params><param><value><array>
1107 <data><value>Hello world</value></data>
1108 <data></data>
1109 </array></value></param></params></methodResponse>
1110 ';
1111                         $r = $s->parseResponse($f);
1112                         $v = $r->faultCode();
1113                         $this->assertEquals(2, $v);
1114                 }
1115
1116                 function testDoubleStuffInValueTag()
1117                 {
1118                         $s = new xmlrpcmsg('dummy');
1119 $f = '<?xml version="1.0"?><methodResponse><params><param><value>
1120 <string>hello world</string>
1121 <array><data></data></array>
1122 </value></param></params></methodResponse>
1123 ';
1124                         $r = $s->parseResponse($f);
1125                         $v = $r->faultCode();
1126                         $this->assertEquals(2, $v);
1127 $f = '<?xml version="1.0"?><methodResponse><params><param><value>
1128 <string>hello</string>
1129 <string>world</string>
1130 </value></param></params></methodResponse>
1131 ';
1132                         $r = $s->parseResponse($f);
1133                         $v = $r->faultCode();
1134                         $this->assertEquals(2, $v);
1135 $f = '<?xml version="1.0"?><methodResponse><params><param><value>
1136 <string>hello</string>
1137 <struct><member><name>hello><value>world</value></member></struct>
1138 </value></param></params></methodResponse>
1139 ';
1140                         $r = $s->parseResponse($f);
1141                         $v = $r->faultCode();
1142                         $this->assertEquals(2, $v);
1143                 }
1144
1145                 function testAutodecodeResponse()
1146                 {
1147                         $s = new xmlrpcmsg('dummy');
1148 $f = '<?xml version="1.0"?><methodResponse><params><param><value><struct><member><name>userid</name><value>311127</value></member>
1149 <member><name>dateCreated</name><value><dateTime.iso8601>20011126T09:17:52</dateTime.iso8601></value></member><member><name>content</name><value>hello world. 2 newlines follow
1150
1151
1152 and there they were.</value></member><member><name>postid</name><value>7414222</value></member></struct></value></param></params></methodResponse>
1153 ';
1154                         $r = $s->parseResponse($f, true, 'phpvals');
1155                         $v = $r->value();
1156                         $s = $v['content'];
1157                         $this->assertEquals("hello world. 2 newlines follow\n\n\nand there they were.", $s);
1158                 }
1159
1160                 function testNoDecodeResponse()
1161                 {
1162                         $s = new xmlrpcmsg('dummy');
1163 $f = '<?xml version="1.0"?><methodResponse><params><param><value><struct><member><name>userid</name><value>311127</value></member>
1164 <member><name>dateCreated</name><value><dateTime.iso8601>20011126T09:17:52</dateTime.iso8601></value></member><member><name>content</name><value>hello world. 2 newlines follow
1165
1166
1167 and there they were.</value></member><member><name>postid</name><value>7414222</value></member></struct></value></param></params></methodResponse>';
1168                         $r = $s->parseResponse($f, true, 'xml');
1169                         $v = $r->value();
1170                         $this->assertEquals($f, $v);
1171                 }
1172
1173                 function testAutoCoDec()
1174                 {
1175                         $data1 = array(1, 1.0, 'hello world', true, '20051021T23:43:00', -1, 11.0, '~!@#$%^&*()_+|', false, '20051021T23:43:00');
1176                         $data2 = array('zero' => $data1, 'one' => $data1, 'two' => $data1, 'three' => $data1, 'four' => $data1, 'five' => $data1, 'six' => $data1, 'seven' => $data1, 'eight' => $data1, 'nine' => $data1);
1177                         $data = array($data2, $data2, $data2, $data2, $data2, $data2, $data2, $data2, $data2, $data2);
1178                         //$keys = array('zero', 'one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine');
1179                         $v1 = php_xmlrpc_encode($data, array('auto_dates'));
1180                         $v2 = php_xmlrpc_decode_xml($v1->serialize());
1181                         $this->assertEquals($v1, $v2);
1182                         $r1 = new xmlrpcresp($v1);
1183                         $r2 = php_xmlrpc_decode_xml($r1->serialize());
1184                         $r2->serialize(); // needed to set internal member payload
1185                         $this->assertEquals($r1, $r2);
1186                         $m1 = new xmlrpcmsg('hello dolly', array($v1));
1187                         $m2 = php_xmlrpc_decode_xml($m1->serialize());
1188                         $m2->serialize(); // needed to set internal member payload
1189                         $this->assertEquals($m1, $m2);
1190                 }
1191
1192                 function testUTF8Request()
1193                 {
1194                         $sendstring='κόσμε'; // Greek word 'kosme'. NB: NOT a valid ISO8859 string!
1195                         $GLOBALS['xmlrpc_internalencoding'] = 'UTF-8';
1196                         $f = new xmlrpcval($sendstring, 'string');
1197                         $v=$f->serialize();
1198                         $this->assertEquals("<value><string>&#954;&#8057;&#963;&#956;&#949;</string></value>\n", $v);
1199                         $GLOBALS['xmlrpc_internalencoding'] = 'ISO-8859-1';
1200                 }
1201
1202                 function testUTF8Response()
1203                 {
1204                         $s = new xmlrpcmsg('dummy');
1205 $f = "HTTP/1.1 200 OK\r\nContent-type: text/xml; charset=UTF-8\r\n\r\n".'<?xml version="1.0"?><methodResponse><params><param><value><struct><member><name>userid</name><value>311127</value></member>
1206 <member><name>dateCreated</name><value><dateTime.iso8601>20011126T09:17:52</dateTime.iso8601></value></member><member><name>content</name><value>'.utf8_encode('àüèàüè').'</value></member><member><name>postid</name><value>7414222</value></member></struct></value></param></params></methodResponse>
1207 ';
1208                         $r = $s->parseResponse($f, false, 'phpvals');
1209                         $v = $r->value();
1210                         $v = $v['content'];
1211                         $this->assertEquals("àüèàüè", $v);
1212 $f = '<?xml version="1.0" encoding="utf-8"?><methodResponse><params><param><value><struct><member><name>userid</name><value>311127</value></member>
1213 <member><name>dateCreated</name><value><dateTime.iso8601>20011126T09:17:52</dateTime.iso8601></value></member><member><name>content</name><value>'.utf8_encode('àüèàüè').'</value></member><member><name>postid</name><value>7414222</value></member></struct></value></param></params></methodResponse>
1214 ';
1215                         $r = $s->parseResponse($f, false, 'phpvals');
1216                         $v = $r->value();
1217                         $v = $v['content'];
1218                         $this->assertEquals("àüèàüè", $v);
1219                 }
1220
1221                 function testUTF8IntString()
1222                 {
1223                         $v=new xmlrpcval(100, 'int');
1224                         $s=$v->serialize('UTF-8');
1225                         $this->assertequals("<value><int>100</int></value>\n", $s);
1226                 }
1227
1228                 function testStringInt()
1229                 {
1230                         $v=new xmlrpcval('hello world', 'int');
1231                         $s=$v->serialize();
1232                         $this->assertequals("<value><int>0</int></value>\n", $s);
1233                 }
1234
1235                 function testStructMemExists()
1236                 {
1237                         $v=php_xmlrpc_encode(array('hello' => 'world'));
1238                         $b=$v->structmemexists('hello');
1239                         $this->assertequals(true, $b);
1240                         $b=$v->structmemexists('world');
1241                         $this->assertequals(false, $b);
1242                 }
1243
1244                 function testNilvalue()
1245                 {
1246                         // default case: we do not accept nil values received
1247                         $v = new xmlrpcval('hello', 'null');
1248                         $r = new xmlrpcresp($v);
1249                         $s = $r->serialize();
1250                         $m = new xmlrpcmsg('dummy');
1251                         $r = $m->parseresponse($s);
1252                         $this->assertequals(2, $r->faultCode());
1253                         // enable reception of nil values
1254                         $GLOBALS['xmlrpc_null_extension'] = true;
1255                         $r = $m->parseresponse($s);
1256                         $v = $r->value();
1257                         $this->assertequals('null', $v->scalartyp());
1258                     // test with the apache version: EX:NIL
1259                     $GLOBALS['xmlrpc_null_apache_encoding'] = true;
1260                     // serialization
1261                     $v = new xmlrpcval('hello', 'null');
1262                     $s = $v->serialize();
1263                     $this->assertequals(1, preg_match( '#<value><ex:nil/></value>#', $s ));
1264                     // deserialization
1265             $r = new xmlrpcresp($v);
1266             $s = $r->serialize();
1267             $r = $m->parseresponse($s);
1268             $v = $r->value();
1269             $this->assertequals('null', $v->scalartyp());
1270                     $GLOBALS['xmlrpc_null_extension'] = false;
1271                     $r = $m->parseresponse($s);
1272                     $this->assertequals(2, $r->faultCode());
1273                 }
1274
1275                 function TestLocale()
1276         {
1277             $locale = setlocale(LC_NUMERIC,0);
1278             if ( setlocale(LC_NUMERIC,'deu', 'de_DE@euro', 'de_DE', 'de', 'ge') !== false )
1279             {
1280                         $v = new xmlrpcval(1.1,'double');
1281                         $r = $v->serialize();
1282                         $this->assertequals(false, strpos($r,','));
1283                         $this->assertequals(1, strpos($v->scalarval(),','));
1284                         setlocale(LC_NUMERIC,$locale);
1285                 }
1286                 }
1287         }
1288
1289         class InvalidHostTests extends PHPUnit_TestCase
1290         {
1291                 var $client = null;
1292
1293                 function setUp()
1294                 {
1295                         global $DEBUG,$LOCALSERVER;
1296                         $this->client=new xmlrpc_client('/NOTEXIST.php', $LOCALSERVER, 80);
1297                         if($DEBUG)
1298                         {
1299                                 $this->client->setDebug($DEBUG);
1300                         }
1301                 }
1302
1303                 function test404()
1304                 {
1305                         $f = new xmlrpcmsg('examples.echo',array(
1306                                 new xmlrpcval('hello', 'string')
1307                         ));
1308                         $r = $this->client->send($f, 5);
1309                         $this->assertEquals(5, $r->faultCode());
1310                 }
1311
1312                 function testSrvNotFound()
1313                 {
1314                         $f = new xmlrpcmsg('examples.echo',array(
1315                                 new xmlrpcval('hello', 'string')
1316                         ));
1317                         $this->client->server .= 'XXX';
1318                         $r = $this->client->send($f, 5);
1319                         $this->assertEquals(5, $r->faultCode());
1320                 }
1321
1322                 function testCurlKAErr()
1323                 {
1324                         global $LOCALSERVER, $URI;
1325                         if(!function_exists('curl_init'))
1326                         {
1327                                 $this->fail('CURL missing: cannot test curl keepalive errors');
1328                                 return;
1329                         }
1330                         $f = new xmlrpcmsg('examples.stringecho',array(
1331                                 new xmlrpcval('hello', 'string')
1332                         ));
1333                         // test 2 calls w. keepalive: 1st time connection ko, second time ok
1334                         $this->client->server .= 'XXX';
1335                         $this->client->keepalive = true;
1336                         $r = $this->client->send($f, 5, 'http11');
1337                         $this->assertEquals(8, $r->faultCode());
1338
1339                         // now test a successful connection
1340                         $server = explode(':', $LOCALSERVER);
1341                         if(count($server) > 1)
1342                         {
1343                                 $this->client->port = $server[1];
1344                         }
1345                         $this->client->server = $server[0];
1346                         $this->client->path = $URI;
1347
1348                         $r = $this->client->send($f, 5, 'http11');
1349                         $r = $r->value();
1350                         $this->assertEquals('hello', $r->scalarVal());
1351                 }
1352         }
1353
1354
1355         $suite->addTest(new LocalhostTests('testString'));
1356         $suite->addTest(new LocalhostTests('testAdding'));
1357         $suite->addTest(new LocalhostTests('testAddingDoubles'));
1358         $suite->addTest(new LocalhostTests('testInvalidNumber'));
1359         $suite->addTest(new LocalhostTests('testBoolean'));
1360         $suite->addTest(new LocalhostTests('testCountEntities'));
1361         $suite->addTest(new LocalhostTests('testBase64'));
1362         $suite->addTest(new LocalhostTests('testDateTime'));
1363         $suite->addTest(new LocalhostTests('testServerMulticall'));
1364         $suite->addTest(new LocalhostTests('testClientMulticall1'));
1365         $suite->addTest(new LocalhostTests('testClientMulticall2'));
1366         $suite->addTest(new LocalhostTests('testClientMulticall3'));
1367         $suite->addTest(new LocalhostTests('testCatchWarnings'));
1368         $suite->addTest(new LocalhostTests('testZeroParams'));
1369         $suite->addTest(new LocalhostTests('testCodeInjectionServerSide'));
1370         $suite->addTest(new LocalhostTests('testAutoRegisteredFunction'));
1371         $suite->addTest(new LocalhostTests('testAutoRegisteredMethod'));
1372         $suite->addTest(new LocalhostTests('testSetCookies'));
1373         $suite->addTest(new LocalhostTests('testGetCookies'));
1374         $suite->addTest(new LocalhostTests('testSendTwiceSameMsg'));
1375
1376         $suite->addTest(new LocalhostMultiTests('testUTF8Requests'));
1377         $suite->addTest(new LocalhostMultiTests('testUTF8Responses'));
1378         $suite->addTest(new LocalhostMultiTests('testISORequests'));
1379         $suite->addTest(new LocalhostMultiTests('testISOResponses'));
1380         $suite->addTest(new LocalhostMultiTests('testGzip'));
1381         $suite->addTest(new LocalhostMultiTests('testDeflate'));
1382         $suite->addTest(new LocalhostMultiTests('testProxy'));
1383         $suite->addTest(new LocalhostMultiTests('testHttp11'));
1384         $suite->addTest(new LocalhostMultiTests('testHttp11Gzip'));
1385         $suite->addTest(new LocalhostMultiTests('testHttp11Deflate'));
1386         $suite->addTest(new LocalhostMultiTests('testKeepAlives'));
1387         $suite->addTest(new LocalhostMultiTests('testHttp11Proxy'));
1388         $suite->addTest(new LocalhostMultiTests('testHttps'));
1389         $suite->addTest(new LocalhostMultiTests('testHttpsProxy'));
1390
1391         $suite->addTest(new InvalidHostTests('test404'));
1392         //$suite->addTest(new InvalidHostTests('testSrvNotFound'));
1393         $suite->addTest(new InvalidHostTests('testCurlKAErr'));
1394
1395         $suite->addTest(new ParsingBugsTests('testMinusOneString'));
1396         $suite->addTest(new ParsingBugsTests('testUnicodeInMemberName'));
1397         $suite->addTest(new ParsingBugsTests('testUnicodeInErrorString'));
1398         $suite->addTest(new ParsingBugsTests('testValidNumbers'));
1399         $suite->addTest(new ParsingBugsTests('testAddScalarToStruct'));
1400         $suite->addTest(new ParsingBugsTests('testAddStructToStruct'));
1401         $suite->addTest(new ParsingBugsTests('testAddArrayToArray'));
1402         $suite->addTest(new ParsingBugsTests('testEncodeArray'));
1403         $suite->addTest(new ParsingBugsTests('testEncodeRecursive'));
1404         $suite->addTest(new ParsingBugsTests('testBrokenrequests'));
1405         $suite->addTest(new ParsingBugsTests('testBrokenresponses'));
1406         $suite->addTest(new ParsingBugsTests('testBuggyHttp'));
1407         $suite->addTest(new ParsingBugsTests('testStringBug'));
1408         $suite->addTest(new ParsingBugsTests('testWhiteSpace'));
1409         $suite->addTest(new ParsingBugsTests('testAutodecodeResponse'));
1410         $suite->addTest(new ParsingBugsTests('testNoDecodeResponse'));
1411         $suite->addTest(new ParsingBugsTests('testAutoCoDec'));
1412         $suite->addTest(new ParsingBugsTests('testUTF8Response'));
1413         $suite->addTest(new ParsingBugsTests('testUTF8Request'));
1414         $suite->addTest(new ParsingBugsTests('testUTF8IntString'));
1415         $suite->addTest(new ParsingBugsTests('testStringInt'));
1416         $suite->addTest(new ParsingBugsTests('testStructMemExists'));
1417         $suite->addTest(new ParsingBugsTests('testDoubleDataInArrayTag'));
1418         $suite->addTest(new ParsingBugsTests('testDoubleStuffInValueTag'));
1419         $suite->addTest(new ParsingBugsTests('testNilValue'));
1420         $suite->addTest(new ParsingBugsTests('testLocale'));
1421
1422         $title = 'XML-RPC Unit Tests';
1423
1424         if(isset($only))
1425         {
1426                 $suite = new PHPUnit_TestSuite($only);
1427         }
1428
1429         if(isset($_SERVER['REQUEST_METHOD']))
1430         {
1431                 echo "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">\n<html xmlns=\"http://www.w3.org/1999/xhtml\" lang=\"en\" xml:lang=\"en\">\n<head>\n<title>$title</title>\n</head>\n<body>\n<h1>$title</h1>\n";
1432         }
1433         else
1434         {
1435                 echo "$title\n\n";
1436         }
1437
1438         if(isset($_SERVER['REQUEST_METHOD']))
1439         {
1440                 echo "<h3>Using lib version: $xmlrpcVersion on PHP version: ".phpversion()."</h3>\n";
1441                 echo '<h3>Running '.$suite->testCount().' tests (some of which are multiple) against servers: http://'.htmlspecialchars($LOCALSERVER.$URI).' and https://'.htmlspecialchars($HTTPSSERVER.$HTTPSURI)."\n ...</h3>\n";
1442                 flush();
1443             ob_flush();
1444         }
1445         else
1446         {
1447                 echo "Using lib version: $xmlrpcVersion on PHP version: ".phpversion()."\n";
1448                 echo 'Running '.$suite->testCount().' tests (some of which are multiple) against servers: http://'.$LOCALSERVER.$URI.' and https://'.$HTTPSSERVER.$HTTPSURI."\n\n";
1449         }
1450
1451         // do some basic timing measurement
1452         list($micro, $sec) = explode(' ', microtime());
1453         $start_time = $sec + $micro;
1454
1455         $PHPUnit = new PHPUnit;
1456         $result = $PHPUnit->run($suite, ($DEBUG == 0 ? '.' : '<hr/>'));
1457
1458         list($micro, $sec) = explode(' ', microtime());
1459         $end_time = $sec + $micro;
1460
1461         if(!isset($_SERVER['REQUEST_METHOD']))
1462         {
1463                 echo $result->toString()."\n";
1464         }
1465
1466         if(isset($_SERVER['REQUEST_METHOD']))
1467         {
1468                 echo '<h3>'.$result->failureCount()." test failures</h3>\n";
1469                 printf("Time spent: %.2f secs<br/>\n", $end_time - $start_time);
1470         }
1471         else
1472         {
1473                 echo $result->failureCount()." test failures\n";
1474                 printf("Time spent: %.2f secs\n", $end_time - $start_time);
1475         }
1476
1477         if($result->failureCount() && !$DEBUG)
1478         {
1479                 $target = strpos($_SERVER['PHP_SELF'], '?') ? $_SERVER['PHP_SELF'].'&amp;DEBUG=1' : $_SERVER['PHP_SELF'].'?DEBUG=1';
1480                 $t2 = strpos($_SERVER['PHP_SELF'], '?') ? $_SERVER['PHP_SELF'].'&amp;DEBUG=2' : $_SERVER['PHP_SELF'].'?DEBUG=2';
1481                 if(isset($_SERVER['REQUEST_METHOD']))
1482                 {
1483                         echo '<p>Run testsuite with <a href="'.$target.'">DEBUG=1</a> to have more detail about tests results. Or with <a href="'.$t2.'">DEBUG=2</a> for even more.</p>'."\n";
1484                 }
1485                 else
1486                 {
1487                         echo "Run testsuite with DEBUG=1 (or 2) to have more detail about tests results\n";
1488                 }
1489         }
1490
1491         if(isset($_SERVER['REQUEST_METHOD']))
1492         {
1493 ?>
1494 <a href="#" onclick="if (document.getElementById('opts').style.display == 'block') document.getElementById('opts').style.display = 'none'; else document.getElementById('opts').style.display = 'block';">More options...</a>
1495 <div id="opts" style="display: none;">
1496 <form method="GET" style="border: 1px solid silver; margin: 5px; padding: 5px; font-family: monospace;">
1497 HTTP Server:&nbsp;&nbsp;<input name="LOCALSERVER" size="30" value="<?php echo htmlspecialchars($LOCALSERVER); ?>"/> Path: <input name="URI"  size="30" value="<?php echo htmlspecialchars($URI); ?>"/><br/>
1498 HTTPS Server: <input name="HTTPSSERVER" size="30" value="<?php echo htmlspecialchars($HTTPSSERVER); ?>"/> Path: <input name="HTTPSURI"  size="30" value="<?php echo htmlspecialchars($HTTPSURI); ?>"/><br/>
1499 Proxy Server: <input name="PROXY" size="30" value="<?php echo isset($PROXY) ? htmlspecialchars($PROXY) : ''; ?>"/> <input type="submit" value="Run Testsuite"/>
1500 </form>
1501 </div>
1502 <?php
1503                 echo $result->toHTML()."\n</body>\n</html>\n";
1504         }
1505 ?>