3
// +----------------------------------------------------------------------+
5
// +----------------------------------------------------------------------+
6
// | Copyright (c) 1997-2003 The PHP Group |
7
// +----------------------------------------------------------------------+
8
// | This source file is subject to version 2.02 of the PHP license, |
9
// | that is bundled with this package in the file LICENSE, and is |
10
// | available at through the world-wide-web at |
11
// | http://www.php.net/license/2_02.txt. |
12
// | If you did not receive a copy of the PHP license and are unable to |
13
// | obtain it through the world-wide-web, please send a note to |
14
// | license@php.net so we can mail you a copy immediately. |
15
// +----------------------------------------------------------------------+
16
// | Authors: Shane Caraveo <Shane@Caraveo.com> |
17
// +----------------------------------------------------------------------+
19
// $Id: client_round2_interop.php,v 1.15.2.2 2004/09/13 11:54:06 dmitry Exp $
21
require_once 'DB.php'; // PEAR/DB
22
require_once 'client_round2_params.php';
23
require_once 'test.utility.php';
24
require_once 'config.php';
26
error_reporting(E_ALL ^ E_NOTICE);
35
// our central interop server, where we can get the list of endpoints
36
var $interopServer = "http://www.whitemesa.net/wsdl/interopInfo.wsdl";
38
// our local endpoint, will always get added to the database for all tests
42
var $currentTest = 'base'; // see $tests above
43
var $paramType = 'php'; // 'php' or 'soapval'
44
var $useWSDL = 0; // 1= do wsdl tests
45
var $numServers = 0; // 0 = all
46
var $specificEndpoint = ''; // test only this endpoint
47
var $testMethod = ''; // test only this method
48
var $skipEndpointList = array(); // endpoints to skip
50
var $startAt = ''; // start in list at this endpoint
54
var $showFaults = 0; // used in result table output
58
var $totals = array();
59
var $tests = array('base','GroupB', 'GroupC');
60
var $paramTypes = array('php', 'soapval');
61
var $endpoints = array();
64
function Interop_Client() {
65
global $interopConfig;
66
$this->DSN = $interopConfig['DSN'];
67
$this->baseURL = $interopConfig['baseURL'];
68
//$this->baseURL = 'http://'.$_SERVER['HTTP_HOST'].dirname($_SERVER['PHP_SELF']);
69
// set up the database connection
70
$this->dbc = DB::connect($this->DSN, true);
71
// if it errors out, just ignore it and rely on regular methods
72
if (DB::isError($this->dbc)) {
73
echo $this->dbc->getMessage();
76
// set up local endpoint
77
$this->localEndpoint['base'] = (object)array(
78
'endpointName'=>'PHP ext/soap',
79
'endpointURL'=>$this->baseURL.'/server_round2_base.php',
80
'wsdlURL'=>$this->baseURL.'/interop.wsdl.php'
82
$this->localEndpoint['GroupB'] = (object)array(
83
'endpointName'=>'PHP ext/soap',
84
'endpointURL'=>$this->baseURL.'/server_round2_groupB.php',
85
'wsdlURL'=>$this->baseURL.'/interopB.wsdl.php'
87
$this->localEndpoint['GroupC'] = (object)array(
88
'endpointName'=>'PHP ext/soap',
89
'endpointURL'=>$this->baseURL.'/server_round2_groupC.php',
90
'wsdlURL'=>$this->baseURL.'/echoheadersvc.wsdl.php');
93
function _fetchEndpoints(&$soapclient, $test) {
94
$this->_getEndpoints($test, 1);
96
// retreive endpoints from the endpoint server
97
$endpointArray = $soapclient->__soapCall("GetEndpointInfo",array("groupName"=>$test),array('soapaction'=>"http://soapinterop.org/",'uri'=>"http://soapinterop.org/"));
98
if (is_soap_fault($endpointArray) || PEAR::isError($endpointArray)) {
99
if ($this->html) print "<pre>";
100
print $soapclient->wire."\n";
101
print_r($endpointArray);
102
if ($this->html) print "</pre>";
107
// add our local endpoint
108
if ($this->localEndpoint[$test]) {
109
array_push($endpointArray, $this->localEndpoint[$test]);
112
if (!$endpointArray) return;
114
// reset the status to zero
115
$res = $this->dbc->query("update endpoints set status = 0 where class='$test'");
116
if (DB::isError($res)) {
117
die ($res->getMessage());
119
if (is_object($res)) $res->free();
120
// save new endpoints into database
121
foreach($endpointArray as $k => $v){
122
if (array_key_exists($v->endpointName,$this->endpoints)) {
123
$res = $this->dbc->query("update endpoints set endpointURL='{$v->endpointURL}', wsdlURL='{$v->wsdlURL}', status=1 where id={$this->endpoints[$v->endpointName]['id']}");
125
$res = $this->dbc->query("insert into endpoints (endpointName,endpointURL,wsdlURL,class) values('{$v->endpointName}','{$v->endpointURL}','{$v->wsdlURL}','$test')");
127
if (DB::isError($res)) {
128
die ($res->getMessage());
130
if (is_object($res)) $res->free();
136
* retreive endpoints interop server
138
* @return boolean result
141
function fetchEndpoints($test = NULL) {
142
// fetch from the interop server
144
$soapclient = new SoapClient($this->interopServer);
146
$this->_fetchEndpoints($soapclient, $test);
148
foreach ($this->tests as $test) {
149
$this->_fetchEndpoints($soapclient, $test);
153
} catch (SoapFault $fault) {
155
echo "<pre>$fault</pre>\n";
161
// retreive all endpoints now
162
$this->currentTest = $test;
163
$x = $this->_getEndpoints($test);
169
* retreive endpoints from either database or interop server
171
* @param string base (see local var $tests)
172
* @param boolean all (if false, only get valid endpoints, status=1)
173
* @return boolean result
176
function getEndpoints($base = 'base', $all = 0) {
177
if (!$this->_getEndpoints($base, $all)) {
178
return $this->fetchEndpoints($base);
185
* retreive endpoints from database
187
* @param string base (see local var $tests)
188
* @param boolean all (if false, only get valid endpoints, status=1)
189
* @return boolean result
192
function _getEndpoints($base = "", $all = 0) {
193
$this->endpoints = array();
196
$sql = "select * from endpoints ";
198
$sql .= "where class='$base' ";
199
if (!$all) $sql .= "and status=1";
201
if (!$all) $sql .= "where status=1";
202
$sql .= " order by endpointName";
205
$db_ep = $this->dbc->getAll($sql,NULL, DB_FETCHMODE_ASSOC );
206
if (DB::isError($db_ep)) {
208
echo $db_ep->getMessage();
211
// rearange the array
212
foreach ($db_ep as $entry) {
213
$this->endpoints[$entry['endpointName']] = $entry;
216
if (count($this->endpoints) > 0) {
217
$this->currentTest = $base;
225
* retreive results from the database, stuff them into the endpoint array
229
function getResults($test = 'base', $type = 'php', $wsdl = 0) {
230
// be sure we have the right endpoints for this test result
231
$this->getEndpoints($test);
233
// retreive the results and put them into the endpoint info
234
$sql = "select * from results where class='$test' and type='$type' and wsdl=$wsdl";
235
$results = $this->dbc->getAll($sql,NULL, DB_FETCHMODE_ASSOC );
236
foreach ($results as $result) {
238
foreach ($this->endpoints as $epn => $epi) {
239
if ($epi['id'] == $result['endpoint']) {
241
$this->endpoints[$epn]['methods'][$result['function']] = $result;
250
* save the results of a method test into the database
254
function _saveResults($endpoint_id, &$soap_test) {
255
if ($this->nosave) return;
257
$result = $soap_test->result;
258
$wire = $result['wire'];
259
if ($result['success']) {
263
$success = $result['fault']->faultcode;
264
$pos = strpos($success,':');
265
if ($pos !== false) {
266
$success = substr($success,$pos+1);
268
$error = $result['fault']->faultstring;
269
if (!$wire) $wire= $result['fault']->detail;
272
$test_name = $soap_test->test_name;
274
$sql = "delete from results where endpoint=$endpoint_id ".
275
"and class='$this->currentTest' and type='$this->paramType' ".
276
"and wsdl=$this->useWSDL and function=".
277
$this->dbc->quote($test_name);
279
$res = $this->dbc->query($sql);
280
if (DB::isError($res)) {
281
die ($res->getMessage());
283
if (is_object($res)) $res->free();
285
$sql = "insert into results (endpoint,stamp,class,type,wsdl,function,result,error,wire) ".
286
"values($endpoint_id,".time().",'$this->currentTest',".
287
"'$this->paramType',$this->useWSDL,".
288
$this->dbc->quote($test_name).",".
289
$this->dbc->quote($success).",".
290
$this->dbc->quote($error).",".
291
($wire?$this->dbc->quote($wire):"''").")";
293
$res = $this->dbc->query($sql);
295
if (DB::isError($res)) {
296
die ($res->getMessage());
298
if (is_object($res)) $res->free();
303
* decodes a soap value to php type, used for test result comparisions
305
* @param SOAP_Value soapval
306
* @return mixed result
309
function decodeSoapval($soapval)
311
if (gettype($soapval) == "object" &&
312
(strcasecmp(get_class($soapval),"SoapParam") == 0 ||
313
strcasecmp(get_class($soapval),"SoapVar") == 0)) {
314
if (strcasecmp(get_class($soapval),"SoapParam") == 0)
315
$val = $soapval->param_data->enc_value;
317
$val = $soapval->enc_value;
321
if (is_array($val)) {
322
foreach($val as $k => $v) {
323
if (gettype($v) == "object" &&
324
(strcasecmp(get_class($soapval),"SoapParam") == 0 ||
325
strcasecmp(get_class($soapval),"SoapVar") == 0)) {
326
$val[$k] = $this->decodeSoapval($v);
335
* compare two php types for a match
337
* @param string expect
338
* @param string test_result
339
* @return boolean result
342
function compareResult($expect, $result, $type = NULL)
344
return compare($expect, $result);
350
* run a method on an endpoint and store it's results to the database
352
* @param array endpoint_info
353
* @param SOAP_Test test
354
* @return boolean result
357
function doEndpointMethod(&$endpoint_info, &$soap_test) {
360
// prepare a holder for the test results
361
$soap_test->result['class'] = $this->currentTest;
362
$soap_test->result['type'] = $this->paramType;
363
$soap_test->result['wsdl'] = $this->useWSDL;
365
if ($this->useWSDL) {
366
if (array_key_exists('wsdlURL',$endpoint_info)) {
367
if (!array_key_exists('client',$endpoint_info)) {
369
$endpoint_info['client'] = new SoapClient($endpoint_info['wsdlURL'], array("trace"=>1));
370
} catch (SoapFault $ex) {
371
$endpoint_info['client']->wsdl->fault = $ex;
374
$soap =& $endpoint_info['client'];
376
# XXX how do we determine a failure on retreiving/parsing wsdl?
377
if ($soap->wsdl->fault) {
378
$fault = $soap->wsdl->fault;
379
$soap_test->setResult(0,'WSDL',
380
$fault->faultstring."\n\n".$fault->detail,
387
$fault = new SoapFault('WSDL',"no WSDL defined for $endpoint");
388
$soap_test->setResult(0,'WSDL',
398
$namespace = $soapaction = 'http://soapinterop.org/';
399
// hack to make tests work with MS SoapToolkit
400
// it's the only one that uses this soapaction, and breaks if
401
// it isn't right. Can't wait for soapaction to be fully depricated
402
if ($this->currentTest == 'base' &&
403
strstr($endpoint_info['endpointName'],'MS SOAP ToolKit 2.0')) {
404
$soapaction = 'urn:soapinterop';
406
if (!array_key_exists('client',$endpoint_info)) {
407
$endpoint_info['client'] = new SoapClient(null,array('location'=>$endpoint_info['endpointURL'],'uri'=>$soapaction,'trace'=>1));
409
$soap = $endpoint_info['client'];
411
// // add headers to the test
412
// if ($soap_test->headers) {
413
// // $header is already a SOAP_Header class
414
// foreach ($soap_test->headers as $header) {
415
// $soap->addHeader($header);
418
// XXX no way to set encoding
419
// this lets us set UTF-8, US-ASCII or other
420
//$soap->setEncoding($soap_test->encoding);
422
if ($this->useWSDL && !$soap_test->headers && !$soap_test->headers_expect) {
424
foreach ($soap_test->method_params as $pname => $param) {
425
$arg = '$soap_test->method_params["'.$pname.'"]';
426
$args .= $args?','.$arg:$arg;
428
$return = eval('return $soap->'.$soap_test->method_name.'('.$args.');');
430
if ($soap_test->headers || $soap_test->headers_expect) {
431
$return = $soap->__soapCall($soap_test->method_name,$soap_test->method_params,array('soapaction'=>$soapaction,'uri'=>$namespace), $soap_test->headers, $result_headers);
433
$return = $soap->__soapCall($soap_test->method_name,$soap_test->method_params,array('soapaction'=>$soapaction,'uri'=>$namespace));
436
} catch (SoapFault $ex) {
440
if(!is_soap_fault($return)){
441
if ($soap_test->expect !== NULL) {
442
$sent = $soap_test->expect;
443
} else if (is_array($soap_test->method_params) && count($soap_test->method_params) == 1) {
444
reset($soap_test->method_params);
445
$sent = current($soap_test->method_params);
446
} else if (is_array($soap_test->method_params) && count($soap_test->method_params) == 0) {
449
$sent = $soap_test->method_params;
452
// compare header results
454
if ($soap_test->headers || $soap_test->headers_expect) {
455
$headers_ok = $this->compareResult($soap_test->headers_expect, $result_headers);
458
# we need to decode what we sent so we can compare!
459
$sent_d = $this->decodeSoapval($sent);
461
$soap_test->result['sent'] = $sent;
462
$soap_test->result['return'] = $return;
464
// compare the results with what we sent
466
if ($soap_test->cmp_func !== NULL) {
467
$cmp_func = $soap_test->cmp_func;
468
$ok = $cmp_func($sent_d,$return);
470
$ok = $this->compareResult($sent_d,$return, $sent->type);
471
if (!$ok && $soap_test->expect) {
472
$ok = $this->compareResult($soap_test->expect,$return);
477
$wire = "REQUEST:\n".str_replace('" ',"\" \n",str_replace('>',">\n",$soap->__getlastrequest()))."\n\n".
478
"RESPONSE:\n".str_replace('" ',"\" \n",str_replace('>',">\n",$soap->__getlastresponse()))."\n\n".
479
"EXPECTED:\n".var_dump_str($sent_d)."\n".
480
"RESULTL:\n".var_dump_str($return);
481
if ($soap_test->headers_expect) {
482
$wire .= "\nEXPECTED HEADERS:\n".var_dump_str($soap_test->headers_expect)."\n".
483
"RESULT HEADERS:\n".var_dump_str($result_headers);
485
#print "Wire:".htmlentities($wire);
489
$fault = new SoapFault('HEADER','The returned result did not match what we expected to receive');
490
$soap_test->setResult(0,$fault->faultcode,
496
$soap_test->setResult(1,'OK',$wire);
500
$fault = new SoapFault('RESULT','The returned result did not match what we expected to receive');
501
$soap_test->setResult(0,$fault->faultcode,
509
if ($soap_test->expect_fault) {
514
$res =$fault->faultcode;
515
$pos = strpos($res,':');
516
if ($pos !== false) {
517
$res = substr($res,$pos+1);
521
$wire = "REQUEST:\n".str_replace('" ',"\" \n",str_replace('>',">\n",$soap->__getlastrequest()))."\n\n".
522
"RESPONSE:\n".str_replace('" ',"\" \n",str_replace('>',">\n",$soap->__getlastresponse()))."\n".
523
"RESULTL:\n".var_dump_str($return);
524
#print "Wire:".htmlentities($wire);
526
$soap_test->setResult($ok,$res, $wire,$fault->faultstring, $fault);
535
* run a single round of tests
541
// get endpoints for this test
542
$this->getEndpoints($this->currentTest);
544
$this->totals = array();
547
foreach($this->endpoints as $endpoint => $endpoint_info){
549
// if we specify an endpoint, skip until we find it
550
if ($this->specificEndpoint && $endpoint != $this->specificEndpoint) continue;
551
if ($this->useWSDL && !$endpoint_info['endpointURL']) continue;
553
$skipendpoint = FALSE;
554
$this->totals['servers']++;
555
#$endpoint_info['tests'] = array();
558
print "Processing $endpoint at {$endpoint_info['endpointURL']}";
559
if ($this->html) print "<br>\n"; else print "\n";
562
foreach($soap_tests[$this->currentTest] as $soap_test) {
563
//foreach(array_keys($method_params[$this->currentTest][$this->paramType]) as $method)
565
// only run the type of test we're looking for (php or soapval)
566
if ($soap_test->type != $this->paramType) continue;
568
// if we haven't reached our startpoint, skip
569
if ($this->startAt && $this->startAt != $endpoint_info['endpointName']) continue;
572
// if this is in our skip list, skip it
573
if (in_array($endpoint, $this->skipEndpointList)) {
574
$skipendpoint = TRUE;
575
$skipfault = new SoapFault('SKIP','endpoint skipped');
576
$soap_test->setResult(0,$fault->faultcode, '',
577
$skipfault->faultstring,
580
#$endpoint_info['tests'][] = &$soap_test;
581
#$soap_test->showTestResult($this->debug, $this->html);
582
#$this->_saveResults($endpoint_info['id'], $soap_test->method_name);
583
$soap_test->result = NULL;
587
// if we're looking for a specific method, skip unless we have it
588
if ($this->testMethod && strcmp($this->testMethod,$soap_test->test_name) != 0) continue;
590
// if we are skipping the rest of the tests (due to error) note a fault
592
$soap_test->setResult(0,$fault->faultcode, '',
593
$skipfault->faultstring,
596
#$endpoint_info['tests'][] = &$soap_test;
597
$this->totals['fail']++;
599
// run the endpoint test
600
if ($this->doEndpointMethod($endpoint_info, $soap_test)) {
601
$this->totals['success']++;
603
$skipendpoint = $soap_test->result['fault']->faultcode=='HTTP'
604
&& strstr($soap_test->result['fault']->faultstring,'Connect Error');
605
$skipfault = $soap_test->result['fault'];
606
$this->totals['fail']++;
608
#$endpoint_info['tests'][] = &$soap_test;
610
$soap_test->showTestResult($this->debug, $this->html);
611
$this->_saveResults($endpoint_info['id'], $soap_test);
612
$soap_test->result = NULL;
613
$this->totals['calls']++;
615
if ($this->numservers && ++$i >= $this->numservers) break;
619
function doGroupTests() {
620
$dowsdl = array(0,1);
621
foreach($dowsdl as $usewsdl) {
622
$this->useWSDL = $usewsdl;
623
foreach($this->paramTypes as $ptype) {
624
// skip a pointless test
625
if ($usewsdl && $ptype == 'soapval') break;
626
$this->paramType = $ptype;
634
* go all out. This takes time.
639
// the mother of all interop tests
640
$dowsdl = array(0,1);
641
foreach($this->tests as $test) {
642
$this->currentTest = $test;
643
foreach($dowsdl as $usewsdl) {
644
$this->useWSDL = $usewsdl;
645
foreach($this->paramTypes as $ptype) {
646
// skip a pointless test
647
if ($usewsdl && $ptype == 'soapval') break;
648
$this->paramType = $ptype;
655
// ***********************************************************
660
* retreive results from the database, stuff them into the endpoint array
664
function getMethodList($test = 'base') {
665
// retreive the results and put them into the endpoint info
666
$sql = "select distinct(function) from results where class='$test' order by function";
667
$results = $this->dbc->getAll($sql);
669
foreach($results as $result) {
675
function outputTable()
677
$methods = $this->getMethodList($this->currentTest);
678
if (!$methods) return;
679
$this->getResults($this->currentTest,$this->paramType,$this->useWSDL);
681
echo "<b>Testing $this->currentTest ";
682
if ($this->useWSDL) echo "using WSDL ";
683
else echo "using Direct calls ";
684
echo "with $this->paramType values</b><br>\n";
686
// calculate totals for this table
687
$this->totals['success'] = 0;
688
$this->totals['fail'] = 0;
689
$this->totals['servers'] = 0; #count($this->endpoints);
690
foreach ($this->endpoints as $endpoint => $endpoint_info) {
691
if (count($endpoint_info['methods']) > 0) {
692
$this->totals['servers']++;
693
foreach ($methods as $method) {
694
$r = $endpoint_info['methods'][$method]['result'];
695
if ($r == 'OK') $this->totals['success']++;
696
else $this->totals['fail']++;
699
unset($this->endpoints[$endpoint]);
702
$this->totals['calls'] = count($methods) * $this->totals['servers'];
704
echo "\n\n<b>Servers: {$this->totals['servers']} Calls: {$this->totals['calls']} Success: {$this->totals['success']} Fail: {$this->totals['fail']}</b><br>\n";
706
echo "<table border=\"1\" cellspacing=\"0\" cellpadding=\"2\">\n";
707
echo "<tr><td class=\"BLANK\">Endpoint</td>\n";
708
foreach ($methods as $method) {
709
$info = split(':', $method);
710
echo "<td class='BLANK' valign='top'>";
711
foreach ($info as $m) {
713
echo '<b>'.$hi[0]."</b><br>\n";
714
if (count($hi) > 1) {
715
echo " Actor=".($hi[1]?'Target':'Not Target')."<br>\n";
716
echo " MustUnderstand=$hi[2]<br>\n";
724
foreach ($this->endpoints as $endpoint => $endpoint_info) {
725
if (array_key_exists('wsdlURL',$endpoint_info)) {
726
echo "<tr><td class=\"BLANK\"><a href=\"{$endpoint_info['wsdlURL']}\">$endpoint</a></td>\n";
728
echo "<tr><td class=\"BLANK\">$endpoint</td>\n";
730
foreach ($methods as $method) {
731
$id = $endpoint_info['methods'][$method]['id'];
732
$r = $endpoint_info['methods'][$method]['result'];
733
$e = $endpoint_info['methods'][$method]['error'];
738
echo "<td class='$r'><a href='$PHP_SELF?wire=$id'>$r</a></td>\n";
740
echo "<td class='untested'>untested</td>\n";
745
echo "</table><br>\n";
746
if ($this->showFaults && count($faults) > 0) {
747
echo "<b>ERROR Details:</b><br>\n<ul>\n";
748
# output more error detail
749
foreach ($faults as $fault) {
750
echo '<li>'.HTMLSpecialChars($fault)."</li>\n";
753
echo "</ul><br><br>\n";
756
function outputTables() {
757
// the mother of all interop tests
758
$dowsdl = array(0,1);
759
foreach($this->tests as $test) {
760
$this->currentTest = $test;
761
foreach($dowsdl as $usewsdl) {
762
$this->useWSDL = $usewsdl;
763
foreach($this->paramTypes as $ptype) {
764
// skip a pointless test
765
if ($usewsdl && $ptype == 'soapval') break;
766
$this->paramType = $ptype;
767
$this->outputTable();
773
function showWire($id) {
774
$results = $this->dbc->getAll("select * from results where id=$id",NULL, DB_FETCHMODE_ASSOC );
775
#$wire = preg_replace("/>/",">\n",$results[0]['wire']);
776
$wire = $results[0]['wire'];
777
if ($this->html) print "<pre>";
778
echo "\n".HTMLSpecialChars($wire);
779
if ($this->html) print "</pre>";
b'\\ No newline at end of file'