rudimentary framework/ui for testing network performance collab/phasefx/performance_testing
authorJason Etheridge <jason@esilibrary.com>
Wed, 13 Jul 2011 14:06:14 +0000 (10:06 -0400)
committerJason Etheridge <jason@esilibrary.com>
Mon, 12 Sep 2011 17:20:38 +0000 (13:20 -0400)
launchable from either inside the staff client (Admin->For Developers->server/main/test.html)
or a web browser (http://hostname/xul/server/main/test.html)

Signed-off-by: Jason Etheridge <jason@esilibrary.com>
Open-ILS/xul/staff_client/server/main/test.html [new file with mode: 0644]
Open-ILS/xul/staff_client/server/main/test.js [new file with mode: 0644]

diff --git a/Open-ILS/xul/staff_client/server/main/test.html b/Open-ILS/xul/staff_client/server/main/test.html
new file mode 100644 (file)
index 0000000..4b23c1f
--- /dev/null
@@ -0,0 +1,46 @@
+<html>
+    <head>
+        <title>Performance Tester</title>
+        <link rel='stylesheet' type='text/css'
+            href='/css/skin/default.css' />
+        <link rel='stylesheet' type='text/css'
+            href='/css/theme/default.css' />
+        <script type="text/javascript" src="test.js"></script>
+        <script type="text/javascript">
+            var djConfig = {
+                baseUrl : '/js/dojo/dojo/',
+                parseOnLoad: true,
+                isDebug:false
+            };
+        </script>
+        <script type="text/javascript" src="/js/dojo/dojo/dojo.js" />
+        <script type="text/javascript" src="/IDL2js" />
+        <script type="text/javascript">
+            try {
+                dojo.require('fieldmapper.AutoIDL');
+                dojo.require('dojo.date.locale');
+                dojo.require('dojo.date.stamp');
+                dojo.require('dijit.ProgressBar');
+                dojo.addOnLoad(my_init);
+            } catch(E) {
+                alert('Error in test.js, pre-onload: ' + E);
+            }
+        </script>
+        <style type="text/css">
+        </style>
+    </head>
+    <body class="tundra">
+        <h1>Performance Tester</h1>
+                <span id="progressmeter"
+                    dojoType="dijit.ProgressBar"
+                    style="width:300px"
+                    jsId="progressmeter"
+                    indeterminate="true"/>
+        <button id="submit">Go</button>
+        <table id="table" style="border: solid thin black">
+        </table>
+        <ol id="list">
+        </ol>
+    </body>
+</html>
+
diff --git a/Open-ILS/xul/staff_client/server/main/test.js b/Open-ILS/xul/staff_client/server/main/test.js
new file mode 100644 (file)
index 0000000..2945416
--- /dev/null
@@ -0,0 +1,274 @@
+var timers = {};
+var tests = [];
+var list;
+var ses;
+
+function xul_init() {
+    if (typeof xulG == 'object' && typeof xulG.set_tab_name == 'function') {
+        try {
+            xulG.set_tab_name('Performance Tester');
+        } catch(E) {
+            dump(E + '\n');
+        }
+    }
+}
+
+function my_init() {
+    try {
+
+        xul_init();
+        dojo.require('openils.PermaCrud');
+        dojo.require('dojo.cookie');
+        ses = dojo.cookie('ses');
+
+        list = dojo.byId('list');
+
+        // Generate some test definitions where the service can vary
+        dojo.forEach(
+            [
+                'open-ils.auth',
+                'open-ils.actor',
+                'open-ils.circ',
+                'open-ils.cat'
+            ],
+            function(service) {
+                generate_echo_test(service,true);
+                generate_echo_test(service,false);
+            }
+        );
+
+        // final "test" for UI cleanup
+        setup_final_test();
+
+        // Ready all defined tests so far and build summary grid
+        dojo.forEach(
+            tests,
+            function(t,idx) {
+                console.log('t.ready('+idx+')');
+                t.ready(idx);
+
+                var row;
+                if (dojo.byId('row_' + idx % 5)) {
+                    row = dojo.byId('row_' + idx % 5);
+                } else {
+                    row = document.createElement('tr');
+                    row.setAttribute('id', 'row_' + idx % 5);
+                    dojo.byId('table').appendChild(row);
+                }
+                var td = document.createElement('td');
+                if (idx != tests.length - 1) {
+                    td.innerHTML = '<b>Test #' + (idx+1) + '</b> : '
+                        + t.name;
+                } else {
+                    td.innerHTML = '<b>Complete Run</b>';
+                }
+                row.appendChild(td);
+                var td2 = document.createElement('td');
+                td2.setAttribute('id','td_' + idx);
+                td2.innerHTML = '&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;';
+                row.appendChild(td2);
+            }
+        );
+
+        // Arm the nuclear launch control
+        dojo.connect(
+            dojo.byId('submit'),
+            'onclick',
+            function(evt) {
+                timers['_main'] = { 'start' : new Date() };
+                evt.target.disabled = true;
+                dojo.publish('test_0',['run']);
+                openils.Util.show('progressmeter');
+            }
+        );
+        dojo.byId('submit').disabled = false;
+
+        // Nuclear progress meter
+        openils.Util.hide('progressmeter');
+
+    } catch(E) {
+        alert('Error in test.js, my_init(): ' + E);
+    }
+}
+
+function setup_final_test() {
+    tests.push(
+        {
+            'ready' : function(idx) {
+                var obj = this;
+                obj.current_test = idx;
+                dojo.subscribe(
+                    'test_' + idx,
+                    function(msg) {
+                        console.log('received ' + msg
+                            + ' request for test #' + (idx+1));
+                        obj[msg]();
+                    }
+                );
+            },
+            'run' : function() {
+                var obj = this;
+                timers['_main'].stop = new Date();
+                console.log('all done');
+                openils.Util.hide('progressmeter');
+                dojo.byId('submit').innerHTML = 'Done';
+                var td = dojo.byId('td_'+obj.current_test);
+                if (td) {
+                    var total_duration =
+                        timers['_main'].stop - timers['_main'].start
+                    td.innerHTML = '&nbsp;' + total_duration + 'ms&nbsp;';
+                }
+            }
+        }
+    );
+}
+
+function generate_echo_test(service,async) {
+    tests.push(
+        {
+            'name' : async
+                ? 'asynchronous echo test: ' + service
+                : 'synchronous echo test: ' + service,
+            'iterations' : 10,
+            'timeout' : 80000, // abort the test after this many milliseconds
+            'ready' : function(idx) {
+                var obj = this;
+                obj.node = dojo.create(
+                    'li',
+                    {
+                        innerHTML: '<p>' + obj.name + '</p>'
+                    },
+                    list
+                );
+                dojo.subscribe(
+                    'test_' + idx,
+                    function(msg) {
+                        console.log('received ' + msg
+                            + ' request for test #' + (idx+1));
+                        obj[msg]();
+                    }
+                );
+                obj.current_test = idx;
+                obj.next_test = idx + 1;
+                // FIXME - attempt to have it so you can run ready() to re-arm a
+                // test, but right now you can only run a test once
+                obj._result_count = 0;
+                obj._seen = {};
+                obj.aborted = false;
+            },
+            'run' : function() {
+                var obj = this;
+                if (timers[obj.name]) {
+                    return; // Defensive, thinking about aborted tests/timeouts
+                }
+                timers[obj.name] = { 'start' : new Date() };
+                obj.node.innerHTML += '<p>Sending '
+                    + obj.iterations + ' requests...</p>';
+                obj._timeout = setTimeout(
+                    function() {
+                        obj.aborted = true;
+                        obj.node.innerHTML += '<p>Giving up on this test '
+                            + 'after ' + (new Date() - timers[obj.name].start)
+                            + 'ms (though it may yet finish).  '
+                            + 'Starting next test.</p>';
+                        dojo.publish('test_'+obj.next_test,['run']);
+                    }, obj.timeout
+                );
+                for (var i = 0; i < obj.iterations; i++) {
+                    obj.request(i);
+                }
+            },
+            '_result_count' : 0,
+            '_seen' : {},
+            'finished?' : function(iteration) {
+                var obj = this;
+                if (! obj._seen[iteration]) {
+                    obj._seen[iteration] = true;
+                    obj._result_count++;
+                }
+                if (obj._result_count == obj.iterations) {
+                    timers[obj.name].stop = new Date();
+                    var total_duration =
+                        timers[obj.name].stop - timers[obj.name].start
+                    obj.node.innerHTML += '<p>Test complete, '
+                        + total_duration
+                        + 'ms'
+                        + '</p>';
+                    var td = dojo.byId('td_' + obj.current_test);
+                    if (td) {
+                        td.innerHTML = '&nbsp;' + total_duration + 'ms&nbsp;';
+                    }
+                    if (! obj.aborted) {
+                        clearTimeout(obj._timeout);
+                        dojo.publish('test_'+obj.next_test,['run']);
+                    }
+                }
+            },
+            'request' : function(iteration) {
+                var obj = this;
+                fieldmapper.standardRequest(
+                    [ service, 'opensrf.system.echo.atomic' ],
+                    {   async: async,
+                        params: ['echo ' + iteration],
+                        onresponse: function(r) {
+                            try {
+                                var result = openils.Util.readResponse(r);
+                                obj.node.innerHTML += '<span>['
+                                    + iteration + ': '
+                                    + (new Date() - timers[obj.name].start)
+                                    + 'ms, '
+                                    + 'onresponse = ' + result
+                                    + ']</span>';
+                            } catch(E) {
+                                obj.node.innerHTML += '<span>['
+                                    + iteration + ': '
+                                    + (new Date() - timers[obj.name].start)
+                                    + 'ms, '
+                                    + 'onresponse error = ' + result
+                                    + ']</span>';
+                            }
+                        },
+                        onerror: function(r) {
+                            try {
+                                var result = openils.Util.readResponse(r);
+                                obj.node.innerHTML += '<span>['
+                                    + iteration + ': '
+                                    + (new Date() - timers[obj.name].start)
+                                    + 'ms, '
+                                    + 'onerror = ' + result
+                                    + ']</span>';
+                            } catch(E) {
+                                obj.node.innerHTML += '<span>['
+                                    + iteration + ': '
+                                    + (new Date() - timers[obj.name].start)
+                                    + 'ms, '
+                                    + 'onerror error = ' + result
+                                    + ']</span>';
+                            }
+                        },
+                        oncomplete: function(r) {
+                            try {
+                                var result = openils.Util.readResponse(r);
+                                obj.node.innerHTML += '<span>['
+                                    + iteration + ': '
+                                    + (new Date() - timers[obj.name].start)
+                                    + 'ms, '
+                                    + 'oncomplete = ' + result
+                                    + ']</span>';
+                            } catch(E) {
+                                obj.node.innerHTML += '<span>['
+                                    + iteration + ': '
+                                    + (new Date() - timers[obj.name].start)
+                                    + 'ms, '
+                                    + 'oncomplete error = ' + result
+                                    + ']</span>';
+                            }
+                            obj['finished?'](iteration);
+                        }
+                    }
+                );
+            }
+        }
+    );
+}
+