3 * Benchmarking suite for the PHP-XMLRPC lib.
5 * @author Gaetano Giunta
6 * @copyright (c) 2005-2015 G. Giunta
7 * @license code licensed under the BSD License: see file license.txt
9 * @todo add a test for response ok in call testing
10 * @todo add support for --help option to give users the list of supported parameters
13 use PhpXmlRpc\PhpXmlRpc;
15 use PhpXmlRpc\Request;
17 use PhpXmlRpc\Response;
18 use PhpXmlRpc\Encoder;
20 include_once __DIR__ . '/../vendor/autoload.php';
22 include __DIR__ . '/parse_args.php';
23 $args = argParser::getArgs();
25 function begin_test($test_name, $test_case)
28 if (!isset($test_results[$test_name])) {
29 $test_results[$test_name] = array();
31 $test_results[$test_name][$test_case] = array();
32 $test_results[$test_name][$test_case]['time'] = microtime(true);
35 function end_test($test_name, $test_case, $test_result)
38 $end = microtime(true);
39 if (!isset($test_results[$test_name][$test_case])) {
40 trigger_error('ending test that was not started');
42 $test_results[$test_name][$test_case]['time'] = $end - $test_results[$test_name][$test_case]['time'];
43 $test_results[$test_name][$test_case]['result'] = $test_result;
49 // Set up PHP structures to be used in many tests
51 $data1 = array(1, 1.0, 'hello world', true, '20051021T23:43:00', -1, 11.0, '~!@#$%^&*()_+|', false, '20051021T23:43:00');
52 $data2 = array('zero' => $data1, 'one' => $data1, 'two' => $data1, 'three' => $data1, 'four' => $data1, 'five' => $data1, 'six' => $data1, 'seven' => $data1, 'eight' => $data1, 'nine' => $data1);
53 $data = array($data2, $data2, $data2, $data2, $data2, $data2, $data2, $data2, $data2, $data2);
54 $keys = array('zero', 'one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine');
58 $test_results = array();
59 $is_web = isset($_SERVER['REQUEST_METHOD']);
60 $xd = extension_loaded('xdebug') && ini_get('xdebug.profiler_enable');
67 $title = 'XML-RPC Benchmark Tests';
70 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";
78 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";
85 echo "XDEBUG profiling enabled: skipping remote tests\nTrace file is: " . xdebug_get_profiler_filename() . "\n";
89 // test 'old style' data encoding vs. 'automatic style' encoding
90 begin_test('Data encoding (large array)', 'manual encoding');
91 for ($i = 0; $i < $num_tests; $i++) {
93 for ($j = 0; $j < 10; $j++) {
95 foreach ($data[$j] as $key => $val) {
97 $values[] = new Value($val[0], 'int');
98 $values[] = new Value($val[1], 'double');
99 $values[] = new Value($val[2], 'string');
100 $values[] = new Value($val[3], 'boolean');
101 $values[] = new Value($val[4], 'dateTime.iso8601');
102 $values[] = new Value($val[5], 'int');
103 $values[] = new Value($val[6], 'double');
104 $values[] = new Value($val[7], 'string');
105 $values[] = new Value($val[8], 'boolean');
106 $values[] = new Value($val[9], 'dateTime.iso8601');
107 $valarray[$key] = new Value($values, 'array');
109 $vals[] = new Value($valarray, 'struct');
111 $value = new Value($vals, 'array');
112 $out = $value->serialize();
114 end_test('Data encoding (large array)', 'manual encoding', $out);
116 begin_test('Data encoding (large array)', 'automatic encoding');
117 $encoder = new Encoder();
118 for ($i = 0; $i < $num_tests; $i++) {
119 $value = $encoder->encode($data, array('auto_dates'));
120 $out = $value->serialize();
122 end_test('Data encoding (large array)', 'automatic encoding', $out);
124 if (function_exists('xmlrpc_set_type')) {
125 begin_test('Data encoding (large array)', 'xmlrpc-epi encoding');
126 for ($i = 0; $i < $num_tests; $i++) {
127 for ($j = 0; $j < 10; $j++) {
128 foreach ($keys as $k) {
129 xmlrpc_set_type($data[$j][$k][4], 'datetime');
130 xmlrpc_set_type($data[$j][$k][8], 'datetime');
133 $out = xmlrpc_encode($data);
135 end_test('Data encoding (large array)', 'xmlrpc-epi encoding', $out);
138 // test 'old style' data decoding vs. 'automatic style' decoding
139 $dummy = new Request('');
140 $out = new Response($value);
141 $in = '<?xml version="1.0" ?>' . "\n" . $out->serialize();
143 begin_test('Data decoding (large array)', 'manual decoding');
144 for ($i = 0; $i < $num_tests; $i++) {
145 $response = $dummy->ParseResponse($in, true);
146 $value = $response->value();
148 for ($k = 0; $k < $value->arraysize(); $k++) {
149 $val1 = $value->arraymem($k);
151 while (list($name, $val) = $val1->structeach()) {
152 $out[$name] = array();
153 for ($j = 0; $j < $val->arraysize(); $j++) {
154 $data = $val->arraymem($j);
155 $out[$name][] = $data->scalarval();
161 end_test('Data decoding (large array)', 'manual decoding', $result);
163 begin_test('Data decoding (large array)', 'automatic decoding');
164 for ($i = 0; $i < $num_tests; $i++) {
165 $response = $dummy->ParseResponse($in, true, 'phpvals');
166 $value = $response->value();
168 end_test('Data decoding (large array)', 'automatic decoding', $value);
170 if (function_exists('xmlrpc_decode')) {
171 begin_test('Data decoding (large array)', 'xmlrpc-epi decoding');
172 for ($i = 0; $i < $num_tests; $i++) {
173 $response = $dummy->ParseResponse($in, true, 'xml');
174 $value = xmlrpc_decode($response->value());
176 end_test('Data decoding (large array)', 'xmlrpc-epi decoding', $value);
181 /// test multicall vs. many calls vs. keep-alives
182 $encoder = new Encoder();
183 $value = $encoder->encode($data1, array('auto_dates'));
184 $req = new Request('interopEchoTests.echoValue', array($value));
186 for ($i = 0; $i < 25; $i++) {
189 $server = explode(':', $args['LOCALSERVER']);
190 if (count($server) > 1) {
191 $srv = $server[1] . '://' . $server[0] . $args['URI'];
192 $c = new Client($args['URI'], $server[0], $server[1]);
194 $srv = $args['LOCALSERVER'] . $args['URI'];
195 $c = new Client($args['URI'], $args['LOCALSERVER']);
197 // do not interfere with http compression
198 $c->accepted_compression = array();
201 $testName = "Repeated send (small array) to $srv";
203 if (function_exists('gzinflate')) {
204 $c->accepted_compression = null;
206 begin_test($testName, 'http 10');
208 for ($i = 0; $i < 25; $i++) {
209 $resp = $c->send($req);
210 $response[] = $resp->value();
212 end_test($testName, 'http 10', $response);
214 if (function_exists('curl_init')) {
215 begin_test($testName, 'http 11 w. keep-alive');
217 for ($i = 0; $i < 25; $i++) {
218 $resp = $c->send($req, 10, 'http11');
219 $response[] = $resp->value();
221 end_test($testName, 'http 11 w. keep-alive', $response);
223 $c->keepalive = false;
224 begin_test($testName, 'http 11');
226 for ($i = 0; $i < 25; $i++) {
227 $resp = $c->send($req, 10, 'http11');
228 $response[] = $resp->value();
230 end_test($testName, 'http 11', $response);
233 begin_test($testName, 'multicall');
234 $response = $c->send($reqs);
235 foreach ($response as $key => & $val) {
236 $val = $val->value();
238 end_test($testName, 'multicall', $response);
240 if (function_exists('gzinflate')) {
241 $c->accepted_compression = array('gzip');
242 $c->request_compression = 'gzip';
244 begin_test($testName, 'http 10 w. compression');
246 for ($i = 0; $i < 25; $i++) {
247 $resp = $c->send($req);
248 $response[] = $resp->value();
250 end_test($testName, 'http 10 w. compression', $response);
252 if (function_exists('curl_init')) {
253 begin_test($testName, 'http 11 w. keep-alive and compression');
255 for ($i = 0; $i < 25; $i++) {
256 $resp = $c->send($req, 10, 'http11');
257 $response[] = $resp->value();
259 end_test($testName, 'http 11 w. keep-alive and compression', $response);
261 $c->keepalive = false;
262 begin_test($testName, 'http 11 w. compression');
264 for ($i = 0; $i < 25; $i++) {
265 $resp = $c->send($req, 10, 'http11');
266 $response[] = $resp->value();
268 end_test($testName, 'http 11 w. compression', $response);
271 begin_test($testName, 'multicall w. compression');
272 $response = $c->send($reqs);
273 foreach ($response as $key => & $val) {
274 $val = $val->value();
276 end_test($testName, 'multicall w. compression', $response);
278 } // end of 'if no xdebug profiling'
282 foreach ($test_results as $test => $results) {
283 echo "\nTEST: $test\n";
284 foreach ($results as $case => $data) {
285 echo " $case: {$data['time']} secs - Output data CRC: " . crc32(serialize($data['result'])) . "\n";
290 echo "\n</pre>\n</body>\n</html>\n";