3 * Benchmarking suite for the PHP-XMLRPC lib
4 * @author Gaetano Giunta
5 * @copyright (c) 2005-2014 G. Giunta
6 * @license code licensed under the BSD License: http://phpxmlrpc.sourceforge.net/license.txt
8 * @todo add a test for response ok in call testing
9 * @todo add support for --help option to give users the list of supported parameters
12 use PhpXmlRpc\PhpXmlRpc;
14 use PhpXmlRpc\Request;
16 use PhpXmlRpc\Response;
17 use PhpXmlRpc\Encoder;
19 include_once(__DIR__.'/../vendor/autoload.php');
21 include(__DIR__.'/parse_args.php');
22 $args = argParser::getArgs();
24 function begin_test($test_name, $test_case)
27 if (!isset($test_results[$test_name]))
28 $test_results[$test_name]=array();
29 $test_results[$test_name][$test_case] = array();
30 $test_results[$test_name][$test_case]['time'] = microtime(true);
33 function end_test($test_name, $test_case, $test_result)
36 $end = microtime(true);
37 if (!isset($test_results[$test_name][$test_case]))
38 trigger_error('ending test that was not started');
39 $test_results[$test_name][$test_case]['time'] = $end - $test_results[$test_name][$test_case]['time'];
40 $test_results[$test_name][$test_case]['result'] = $test_result;
46 // Set up PHP structures to be used in many tests
48 $data1 = array(1, 1.0, 'hello world', true, '20051021T23:43:00', -1, 11.0, '~!@#$%^&*()_+|', false, '20051021T23:43:00');
49 $data2 = array('zero' => $data1, 'one' => $data1, 'two' => $data1, 'three' => $data1, 'four' => $data1, 'five' => $data1, 'six' => $data1, 'seven' => $data1, 'eight' => $data1, 'nine' => $data1);
50 $data = array($data2, $data2, $data2, $data2, $data2, $data2, $data2, $data2, $data2, $data2);
51 $keys = array('zero', 'one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine');
55 $test_results=array();
56 $is_web = isset($_SERVER['REQUEST_METHOD']);
57 $xd = extension_loaded('xdebug') && ini_get('xdebug.profiler_enable');
63 $title = 'XML-RPC Benchmark Tests';
67 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<pre>\n";
76 echo "<h3>Using lib version: ".PhpXmlRpc::$xmlrpcVersion." on PHP version: ".phpversion()."</h3>\n";
77 if ($xd) echo "<h4>XDEBUG profiling enabled: skipping remote tests. Trace file is: ".htmlspecialchars(xdebug_get_profiler_filename())."</h4>\n";
83 echo "Using lib version: ".PhpXmlRpc::$xmlrpcVersion." on PHP version: ".phpversion()."\n";
84 if ($xd) echo "XDEBUG profiling enabled: skipping remote tests\nTrace file is: ".xdebug_get_profiler_filename()."\n";
87 // test 'old style' data encoding vs. 'automatic style' encoding
88 begin_test('Data encoding (large array)', 'manual encoding');
89 for ($i = 0; $i < $num_tests; $i++)
92 for ($j = 0; $j < 10; $j++)
95 foreach ($data[$j] as $key => $val)
98 $values[] = new Value($val[0], 'int');
99 $values[] = new Value($val[1], 'double');
100 $values[] = new Value($val[2], 'string');
101 $values[] = new Value($val[3], 'boolean');
102 $values[] = new Value($val[4], 'dateTime.iso8601');
103 $values[] = new Value($val[5], 'int');
104 $values[] = new Value($val[6], 'double');
105 $values[] = new Value($val[7], 'string');
106 $values[] = new Value($val[8], 'boolean');
107 $values[] = new Value($val[9], 'dateTime.iso8601');
108 $valarray[$key] = new Value($values, 'array');
110 $vals[] = new Value($valarray, 'struct');
112 $value = new Value($vals, 'array');
113 $out = $value->serialize();
115 end_test('Data encoding (large array)', 'manual encoding', $out);
117 begin_test('Data encoding (large array)', 'automatic encoding');
118 $encoder = new Encoder();
119 for ($i = 0; $i < $num_tests; $i++)
121 $value = $encoder->encode($data, array('auto_dates'));
122 $out = $value->serialize();
124 end_test('Data encoding (large array)', 'automatic encoding', $out);
126 if (function_exists('xmlrpc_set_type'))
128 begin_test('Data encoding (large array)', 'xmlrpc-epi encoding');
129 for ($i = 0; $i < $num_tests; $i++)
131 for ($j = 0; $j < 10; $j++)
132 foreach ($keys as $k)
134 xmlrpc_set_type($data[$j][$k][4], 'datetime');
135 xmlrpc_set_type($data[$j][$k][8], 'datetime');
137 $out = xmlrpc_encode($data);
139 end_test('Data encoding (large array)', 'xmlrpc-epi encoding', $out);
142 // test 'old style' data decoding vs. 'automatic style' decoding
143 $dummy = new Request('');
144 $out = new Response($value);
145 $in = '<?xml version="1.0" ?>'."\n".$out->serialize();
147 begin_test('Data decoding (large array)', 'manual decoding');
148 for ($i = 0; $i < $num_tests; $i++)
150 $response = $dummy->ParseResponse($in, true);
151 $value = $response->value();
153 for ($k = 0; $k < $value->arraysize(); $k++)
155 $val1 = $value->arraymem($k);
157 while (list($name, $val) = $val1->structeach())
159 $out[$name] = array();
160 for ($j = 0; $j < $val->arraysize(); $j++)
162 $data = $val->arraymem($j);
163 $out[$name][] = $data->scalarval();
169 end_test('Data decoding (large array)', 'manual decoding', $result);
171 begin_test('Data decoding (large array)', 'automatic decoding');
172 for ($i = 0; $i < $num_tests; $i++)
174 $response = $dummy->ParseResponse($in, true, 'phpvals');
175 $value = $response->value();
177 end_test('Data decoding (large array)', 'automatic decoding', $value);
179 if (function_exists('xmlrpc_decode'))
181 begin_test('Data decoding (large array)', 'xmlrpc-epi decoding');
182 for ($i = 0; $i < $num_tests; $i++)
184 $response = $dummy->ParseResponse($in, true, 'xml');
185 $value = xmlrpc_decode($response->value());
187 end_test('Data decoding (large array)', 'xmlrpc-epi decoding', $value);
193 /// test multicall vs. many calls vs. keep-alives
194 $encoder = new Encoder();
195 $value = $encoder->encode($data1, array('auto_dates'));
196 $req = new Request('interopEchoTests.echoValue', array($value));
198 for ($i = 0; $i < 25; $i++)
200 $server = explode(':', $args['LOCALSERVER']);
201 if(count($server) > 1)
203 $srv = $server[1] . '://' . $server[0] . $args['URI'];
204 $c = new Client($args['URI'], $server[0], $server[1]);
208 $srv = $args['LOCALSERVER'] . $args['URI'];
209 $c = new Client($args['URI'], $args['LOCALSERVER']);
211 // do not interfere with http compression
212 $c->accepted_compression = array();
215 $testName = "Repeated send (small array) to $srv";
217 if (function_exists('gzinflate')) {
218 $c->accepted_compression = null;
220 begin_test($testName, 'http 10');
222 for ($i = 0; $i < 25; $i++)
224 $resp = $c->send($req);
225 $response[] = $resp->value();
227 end_test($testName, 'http 10', $response);
229 if (function_exists('curl_init'))
231 begin_test($testName, 'http 11 w. keep-alive');
233 for ($i = 0; $i < 25; $i++)
235 $resp = $c->send($req, 10, 'http11');
236 $response[] = $resp->value();
238 end_test($testName, 'http 11 w. keep-alive', $response);
240 $c->keepalive = false;
241 begin_test($testName, 'http 11');
243 for ($i = 0; $i < 25; $i++)
245 $resp = $c->send($req, 10, 'http11');
246 $response[] = $resp->value();
248 end_test($testName, 'http 11', $response);
251 begin_test($testName, 'multicall');
252 $response = $c->send($reqs);
253 foreach ($response as $key =>& $val)
255 $val = $val->value();
257 end_test($testName, 'multicall', $response);
259 if (function_exists('gzinflate'))
261 $c->accepted_compression = array('gzip');
262 $c->request_compression = 'gzip';
264 begin_test($testName, 'http 10 w. compression');
266 for ($i = 0; $i < 25; $i++)
268 $resp = $c->send($req);
269 $response[] = $resp->value();
271 end_test($testName, 'http 10 w. compression', $response);
273 if (function_exists('curl_init'))
275 begin_test($testName, 'http 11 w. keep-alive and compression');
277 for ($i = 0; $i < 25; $i++)
279 $resp = $c->send($req, 10, 'http11');
280 $response[] = $resp->value();
282 end_test($testName, 'http 11 w. keep-alive and compression', $response);
284 $c->keepalive = false;
285 begin_test($testName, 'http 11 w. compression');
287 for ($i = 0; $i < 25; $i++)
289 $resp = $c->send($req, 10, 'http11');
290 $response[] = $resp->value();
292 end_test($testName, 'http 11 w. compression', $response);
295 begin_test($testName, 'multicall w. compression');
296 $response = $c->send($reqs);
297 foreach ($response as $key =>& $val)
299 $val = $val->value();
301 end_test($testName, 'multicall w. compression', $response);
304 } // end of 'if no xdebug profiling'
308 foreach($test_results as $test => $results)
310 echo "\nTEST: $test\n";
311 foreach ($results as $case => $data)
312 echo " $case: {$data['time']} secs - Output data CRC: ".crc32(serialize($data['result']))."\n";
318 echo "\n</pre>\n</body>\n</html>\n";