59a9cb8c8bb0bda6cb206f237b3fbd2acc309364
[plcapi.git] / tests / benchmark.php
1 <?php
2 /**
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
7  *
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
10  **/
11
12 use PhpXmlRpc\PhpXmlRpc;
13 use PhpXmlRpc\Value;
14 use PhpXmlRpc\Request;
15 use PhpXmlRpc\Client;
16 use PhpXmlRpc\Response;
17 use PhpXmlRpc\Encoder;
18
19 include_once(__DIR__.'/../vendor/autoload.php');
20
21 include(__DIR__.'/parse_args.php');
22 $args = argParser::getArgs();
23
24 function begin_test($test_name, $test_case)
25 {
26     global $test_results;
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);
31 }
32
33 function end_test($test_name, $test_case, $test_result)
34 {
35     global $test_results;
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;
41     echo '.';
42     flush();
43     @ob_flush();
44 }
45
46 // Set up PHP structures to be used in many tests
47
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');
52
53 // Begin execution
54
55 $test_results=array();
56 $is_web = isset($_SERVER['REQUEST_METHOD']);
57 $xd = extension_loaded('xdebug') && ini_get('xdebug.profiler_enable');
58 if ($xd)
59     $num_tests = 1;
60 else
61     $num_tests = 10;
62
63 $title = 'XML-RPC Benchmark Tests';
64
65 if($is_web)
66 {
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";
68 }
69 else
70 {
71     echo "$title\n\n";
72 }
73
74 if($is_web)
75 {
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";
78     flush();
79     ob_flush();
80 }
81 else
82 {
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";
85 }
86
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++)
90 {
91     $vals = array();
92     for ($j = 0; $j < 10; $j++)
93     {
94         $valarray = array();
95         foreach ($data[$j] as $key => $val)
96         {
97             $values = array();
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');
109         }
110         $vals[] = new Value($valarray, 'struct');
111     }
112     $value = new Value($vals, 'array');
113     $out = $value->serialize();
114 }
115 end_test('Data encoding (large array)', 'manual encoding', $out);
116
117 begin_test('Data encoding (large array)', 'automatic encoding');
118 $encoder = new Encoder();
119 for ($i = 0; $i < $num_tests; $i++)
120 {
121     $value = $encoder->encode($data, array('auto_dates'));
122     $out = $value->serialize();
123 }
124 end_test('Data encoding (large array)', 'automatic encoding', $out);
125
126 if (function_exists('xmlrpc_set_type'))
127 {
128     begin_test('Data encoding (large array)', 'xmlrpc-epi encoding');
129     for ($i = 0; $i < $num_tests; $i++)
130     {
131         for ($j = 0; $j < 10; $j++)
132             foreach ($keys as $k)
133             {
134                 xmlrpc_set_type($data[$j][$k][4], 'datetime');
135                 xmlrpc_set_type($data[$j][$k][8], 'datetime');
136             }
137         $out = xmlrpc_encode($data);
138     }
139     end_test('Data encoding (large array)', 'xmlrpc-epi encoding', $out);
140 }
141
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();
146
147 begin_test('Data decoding (large array)', 'manual decoding');
148 for ($i = 0; $i < $num_tests; $i++)
149 {
150     $response = $dummy->ParseResponse($in, true);
151     $value = $response->value();
152     $result = array();
153     for ($k = 0; $k < $value->arraysize(); $k++)
154     {
155         $val1 = $value->arraymem($k);
156         $out = array();
157         while (list($name, $val) = $val1->structeach())
158         {
159             $out[$name] = array();
160             for ($j = 0; $j < $val->arraysize(); $j++)
161             {
162                 $data = $val->arraymem($j);
163                 $out[$name][] = $data->scalarval();
164             }
165         } // while
166         $result[] = $out;
167     }
168 }
169 end_test('Data decoding (large array)', 'manual decoding', $result);
170
171 begin_test('Data decoding (large array)', 'automatic decoding');
172 for ($i = 0; $i < $num_tests; $i++)
173 {
174     $response = $dummy->ParseResponse($in, true, 'phpvals');
175     $value = $response->value();
176 }
177 end_test('Data decoding (large array)', 'automatic decoding', $value);
178
179 if (function_exists('xmlrpc_decode'))
180 {
181     begin_test('Data decoding (large array)', 'xmlrpc-epi decoding');
182     for ($i = 0; $i < $num_tests; $i++)
183     {
184         $response = $dummy->ParseResponse($in, true, 'xml');
185         $value = xmlrpc_decode($response->value());
186     }
187     end_test('Data decoding (large array)', 'xmlrpc-epi decoding', $value);
188 }
189
190 if (!$xd)
191 {
192
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));
197     $reqs = array();
198     for ($i = 0; $i < 25; $i++)
199         $reqs[] = $req;
200     $server = explode(':', $args['LOCALSERVER']);
201     if(count($server) > 1)
202     {
203         $srv = $server[1] . '://' . $server[0] . $args['URI'];
204         $c = new Client($args['URI'], $server[0], $server[1]);
205     }
206     else
207     {
208         $srv = $args['LOCALSERVER'] . $args['URI'];
209         $c = new Client($args['URI'], $args['LOCALSERVER']);
210     }
211     // do not interfere with http compression
212     $c->accepted_compression = array();
213     //$c->debug=true;
214
215     $testName = "Repeated send (small array) to $srv";
216
217     if (function_exists('gzinflate')) {
218         $c->accepted_compression = null;
219     }
220     begin_test($testName, 'http 10');
221     $response = array();
222     for ($i = 0; $i < 25; $i++)
223     {
224         $resp = $c->send($req);
225         $response[] = $resp->value();
226     }
227     end_test($testName, 'http 10', $response);
228
229     if (function_exists('curl_init'))
230     {
231         begin_test($testName, 'http 11 w. keep-alive');
232         $response = array();
233         for ($i = 0; $i < 25; $i++)
234         {
235             $resp = $c->send($req, 10, 'http11');
236             $response[] = $resp->value();
237         }
238         end_test($testName, 'http 11 w. keep-alive', $response);
239
240         $c->keepalive = false;
241         begin_test($testName, 'http 11');
242         $response = array();
243         for ($i = 0; $i < 25; $i++)
244         {
245             $resp = $c->send($req, 10, 'http11');
246             $response[] = $resp->value();
247         }
248         end_test($testName, 'http 11', $response);
249     }
250
251     begin_test($testName, 'multicall');
252     $response = $c->send($reqs);
253     foreach ($response as $key =>& $val)
254     {
255         $val = $val->value();
256     }
257     end_test($testName, 'multicall', $response);
258
259     if (function_exists('gzinflate'))
260     {
261         $c->accepted_compression = array('gzip');
262         $c->request_compression = 'gzip';
263
264         begin_test($testName, 'http 10 w. compression');
265         $response = array();
266         for ($i = 0; $i < 25; $i++)
267         {
268             $resp = $c->send($req);
269             $response[] = $resp->value();
270         }
271         end_test($testName, 'http 10 w. compression', $response);
272
273         if (function_exists('curl_init'))
274         {
275             begin_test($testName, 'http 11 w. keep-alive and compression');
276             $response = array();
277             for ($i = 0; $i < 25; $i++)
278             {
279                 $resp = $c->send($req, 10, 'http11');
280                 $response[] = $resp->value();
281             }
282             end_test($testName, 'http 11 w. keep-alive and compression', $response);
283
284             $c->keepalive = false;
285             begin_test($testName, 'http 11 w. compression');
286             $response = array();
287             for ($i = 0; $i < 25; $i++)
288             {
289                 $resp = $c->send($req, 10, 'http11');
290                 $response[] = $resp->value();
291             }
292             end_test($testName, 'http 11 w. compression', $response);
293         }
294
295         begin_test($testName, 'multicall w. compression');
296         $response = $c->send($reqs);
297         foreach ($response as $key =>& $val)
298         {
299             $val = $val->value();
300         }
301         end_test($testName, 'multicall w. compression', $response);
302     }
303
304 } // end of 'if no xdebug profiling'
305
306
307 echo "\n";
308 foreach($test_results as $test => $results)
309 {
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";
313 }
314
315
316 if($is_web)
317 {
318     echo "\n</pre>\n</body>\n</html>\n";
319 }