591 lines
15 KiB
JavaScript
591 lines
15 KiB
JavaScript
/**
|
|
* Forge XmlHttpRequest Test
|
|
*
|
|
* @author Dave Longley
|
|
* @author David I. Lehn <dlehn@digitalbazaar.com>
|
|
*
|
|
* Copyright (c) 2009-2010 Digital Bazaar, Inc. All rights reserved.
|
|
*/
|
|
(function($)
|
|
{
|
|
// load flash socket pool
|
|
window.forge.socketPool = {};
|
|
window.forge.socketPool.ready = function()
|
|
{
|
|
// init forge xhr
|
|
forge.xhr.init({
|
|
flashId: 'socketPool',
|
|
policyPort: 19945,
|
|
msie: $.browser.msie,
|
|
connections: 10,
|
|
caCerts: [],
|
|
verify: function(c, verified, depth, certs)
|
|
{
|
|
// don't care about cert verification for test
|
|
return true;
|
|
}
|
|
});
|
|
};
|
|
swfobject.embedSWF(
|
|
'forge/SocketPool.swf', 'socketPool', '0', '0', '9.0.0',
|
|
false, {}, {allowscriptaccess: 'always'}, {});
|
|
})(jQuery);
|
|
|
|
jQuery(function($)
|
|
{
|
|
var cat = 'forge.tests.xhr';
|
|
|
|
var tests = [];
|
|
var passed = 0;
|
|
var failed = 0;
|
|
|
|
var init = function() {
|
|
passed = failed = 0;
|
|
$('.ready,.testing,.pass,.fail')
|
|
.removeClass('ready testing pass fail');
|
|
$('#status')
|
|
.text('Ready.')
|
|
.addClass('ready');
|
|
$('#total').text(tests.length);
|
|
$('#pass').text(passed);
|
|
$('#fail').text(failed);
|
|
$('.expect').empty();
|
|
$('.result').empty();
|
|
$('.time').empty();
|
|
$('.timePer').empty();
|
|
$('#start').removeAttr('disabled');
|
|
};
|
|
|
|
var start = function()
|
|
{
|
|
$('#start').attr('disabled', 'disabled');
|
|
// meta! use tasks to run the task tests
|
|
forge.task.start({
|
|
type: 'test',
|
|
run: function(task) {
|
|
task.next('starting', function(task) {
|
|
forge.log.debug(cat, 'start');
|
|
$('#status')
|
|
.text('Testing...')
|
|
.addClass('testing')
|
|
.removeClass('idle');
|
|
});
|
|
$.each(tests, function(i, test) {
|
|
task.next('test', function(task) {
|
|
var title = $('li:first', test.container);
|
|
if($('#scroll:checked').length === 1)
|
|
{
|
|
$('html,body').animate({scrollTop: title.offset().top});
|
|
}
|
|
title.addClass('testing');
|
|
test.run(task, test);
|
|
});
|
|
task.next('test', function(task) {
|
|
$('li:first', test.container).removeClass('testing');
|
|
});
|
|
});
|
|
task.next('success', function(task) {
|
|
forge.log.debug(cat, 'done');
|
|
if(failed === 0) {
|
|
$('#status')
|
|
.text('PASS')
|
|
.addClass('pass')
|
|
.removeClass('testing');
|
|
} else {
|
|
// FIXME: should just be hitting failure() below
|
|
$('#status')
|
|
.text('FAIL')
|
|
.addClass('fail')
|
|
.removeClass('testing');
|
|
}
|
|
});
|
|
},
|
|
failure: function() {
|
|
$('#status')
|
|
.text('FAIL')
|
|
.addClass('fail')
|
|
.removeClass('testing');
|
|
}
|
|
});
|
|
};
|
|
|
|
$('#start').click(function() {
|
|
start();
|
|
});
|
|
|
|
$('#reset').click(function() {
|
|
init();
|
|
});
|
|
|
|
var stressStats =
|
|
{
|
|
sent: 0,
|
|
success: 0,
|
|
error: 0
|
|
};
|
|
var stressStatsMessage = function()
|
|
{
|
|
return 'received:' + (stressStats.success + stressStats.error) + '/' +
|
|
stressStats.sent + ' errors:' + stressStats.error;
|
|
};
|
|
|
|
$('#stress').click(function() {
|
|
for(var i = 1; i <= 100; ++i)
|
|
{
|
|
(function(seqnum)
|
|
{
|
|
setTimeout(function()
|
|
{
|
|
$.ajax(
|
|
{
|
|
type: 'GET',
|
|
url: '/result.txt?seq=' + seqnum,
|
|
beforeSend: function(xhr)
|
|
{
|
|
++stressStats.sent;
|
|
xhr.setRequestHeader('Connection', 'close');
|
|
},
|
|
success: function(data, textStatus, xhr)
|
|
{
|
|
++stressStats.success;
|
|
forge.log.debug(cat, 'xhr connection completed' +
|
|
' seq:' + seqnum +
|
|
' datalen:' + data.length + ' ' +
|
|
stressStatsMessage());
|
|
},
|
|
error: function(xhr, textStatus, errorThrown)
|
|
{
|
|
++stressStats.error;
|
|
forge.log.error(cat, 'xhr connection failed' +
|
|
' seq:' + seqnum + ' ' +
|
|
stressStatsMessage(), arguments);
|
|
},
|
|
xhr: forge.xhr.create
|
|
});
|
|
}, 0);
|
|
})(i);
|
|
}
|
|
return false;
|
|
});
|
|
|
|
/**
|
|
* Creates a simple XMLHttpRequest wrapper. For testing.
|
|
*/
|
|
var createWrapper = function()
|
|
{
|
|
var UNSENT = 0;
|
|
var OPENED = 1;
|
|
var HEADERS_RECEIVED = 2;
|
|
var LOADING = 3;
|
|
var DONE = 4;
|
|
|
|
var toWrap = new XMLHttpRequest();
|
|
|
|
// create xhr wrapper object
|
|
var xhr =
|
|
{
|
|
// FIXME: an EventListener
|
|
onreadystatechange: null,
|
|
// FIXME: readonly
|
|
readyState: UNSENT,
|
|
// FIXME: a string
|
|
responseText: null,
|
|
// FIXME: a document
|
|
responseXML: null,
|
|
// FIXME: readonly, returns the HTTP status code
|
|
status: 0,
|
|
// FIXME: readonly, returns the HTTP status message
|
|
statusText: null,
|
|
|
|
// FIXME: async, user, and password are optional
|
|
open: function(method, url, async, user, password)
|
|
{
|
|
toWrap.open(method, url, async, user, password);
|
|
},
|
|
|
|
setRequestHeader: function(header, value)
|
|
{
|
|
toWrap.setRequestHeader(header, value);
|
|
},
|
|
|
|
// FIXME: data can be a string or a document
|
|
send: function(data)
|
|
{
|
|
toWrap.send(data);
|
|
},
|
|
|
|
abort: function()
|
|
{
|
|
toWrap.abort();
|
|
toWrap.onreadystatechange = null;
|
|
toWrap = null;
|
|
},
|
|
|
|
// FIXME: return all response headers as a string
|
|
getAllResponseHeaders: function()
|
|
{
|
|
return toWrap.getAllResponseHeaders();
|
|
},
|
|
|
|
// FIXME: return header field value
|
|
getResponseHeader: function(header)
|
|
{
|
|
return toWrap.getResponseHeader(header);
|
|
}
|
|
};
|
|
|
|
toWrap.onreadystatechange = function()
|
|
{
|
|
// copy attributes
|
|
xhr.readyState = toWrap.readyState;
|
|
xhr.responseText = toWrap.responseText;
|
|
xhr.responseXML = toWrap.responseXML;
|
|
|
|
if(toWrap.readyState == HEADERS_RECEIVED)
|
|
{
|
|
xhr.status = toWrap.status;
|
|
xhr.statusText = toWrap.statusText;
|
|
}
|
|
|
|
if(xhr.onreadystatechange)
|
|
{
|
|
//forge.log.debug(cat, 'wrapper orsc', toWrap);
|
|
xhr.onreadystatechange();
|
|
}
|
|
};
|
|
|
|
return xhr;
|
|
};
|
|
|
|
var addTest = function(name, run)
|
|
{
|
|
var container = $('<ul><li>Test ' + name + '</li><ul/></ul>');
|
|
var expect = $('<li>Expect: <span class="expect"/></li>');
|
|
var result = $('<li>Result: <span class="result"/></li>');
|
|
var time = $('<li>Time: <span class="time"/></li>');
|
|
var timePer = $('<li>Time Per Iteration: <span class="timePer"/></li>');
|
|
$('ul', container)
|
|
.append(expect)
|
|
.append(result)
|
|
.append(time)
|
|
.append(timePer);
|
|
$('#tests').append(container);
|
|
var test = {
|
|
container: container,
|
|
startTime: null,
|
|
run: function(task, test) {
|
|
test.startTime = new Date();
|
|
run(task, test);
|
|
},
|
|
expect: $('span', expect),
|
|
result: $('span', result),
|
|
check: function() {
|
|
var e = test.expect.text();
|
|
var r = test.result.text();
|
|
(e == r) ? test.pass() : test.fail();
|
|
},
|
|
pass: function(iterations) {
|
|
var dt = new Date() - test.startTime;
|
|
if(!iterations)
|
|
{
|
|
iterations = 1;
|
|
}
|
|
var dti = (dt / iterations);
|
|
passed += 1;
|
|
$('#pass').text(passed);
|
|
$('li:first', container).addClass('pass');
|
|
$('span.time', container).html(dt + 'ms');
|
|
$('span.timePer', container).html(dti + 'ms');
|
|
},
|
|
fail: function(iterations) {
|
|
var dt = new Date() - test.startTime;
|
|
if(!iterations)
|
|
{
|
|
iterations = 1;
|
|
}
|
|
var dti = (dt / iterations);
|
|
failed += 1;
|
|
$('#fail').text(failed);
|
|
$('li:first', container).addClass('fail');
|
|
$('span.time', container).html(dt + 'ms');
|
|
$('span.timePer', container).html(dti + 'ms');
|
|
}
|
|
};
|
|
tests.push(test);
|
|
};
|
|
|
|
addTest('builtin xhr', function(task, test)
|
|
{
|
|
task.block();
|
|
|
|
$.ajax(
|
|
{
|
|
type: 'GET',
|
|
url: '/result.txt',
|
|
success: function(data)
|
|
{
|
|
test.expect.html('expected result');
|
|
test.result.html(data);
|
|
task.unblock();
|
|
},
|
|
error: function()
|
|
{
|
|
task.fail();
|
|
}
|
|
});
|
|
|
|
task.next(function(task)
|
|
{
|
|
test.pass();
|
|
});
|
|
});
|
|
|
|
addTest('builtin xhr (10 serial)', function(task, test)
|
|
{
|
|
var N = 10;
|
|
for(var i = 0; i < N; i++)
|
|
{
|
|
task.next(function(task)
|
|
{
|
|
task.parent.block();
|
|
|
|
$.ajax(
|
|
{
|
|
type: 'GET',
|
|
url: '/result.txt',
|
|
success: function(data, textStatus)
|
|
{
|
|
test.result.append('.');
|
|
task.parent.unblock();
|
|
},
|
|
error: function(xhr, textStatus, errorThrown)
|
|
{
|
|
task.fail(N);
|
|
}
|
|
});
|
|
});
|
|
}
|
|
|
|
task.next(function(task)
|
|
{
|
|
test.pass(N);
|
|
});
|
|
});
|
|
|
|
addTest('builtin xhr (10 parallel)', function(task, test)
|
|
{
|
|
var N = 10;
|
|
task.block(N);
|
|
for(var i = 0; i < N; i++)
|
|
{
|
|
$.ajax(
|
|
{
|
|
type: 'GET',
|
|
url: '/result.txt',
|
|
success: function(data, textStatus)
|
|
{
|
|
test.result.append('.');
|
|
task.unblock();
|
|
},
|
|
error: function(xhr, textStatus, errorThrown)
|
|
{
|
|
task.fail(N);
|
|
}
|
|
});
|
|
}
|
|
|
|
task.next(function(task)
|
|
{
|
|
test.pass(N);
|
|
});
|
|
});
|
|
|
|
// test only works with non-IE
|
|
if(!$.browser.msie)
|
|
{
|
|
addTest('generic wrapper xhr', function(task, test)
|
|
{
|
|
task.block();
|
|
|
|
$.ajax(
|
|
{
|
|
type: 'GET',
|
|
url: '/result.txt',
|
|
success: function(data)
|
|
{
|
|
test.expect.html('expected result');
|
|
test.result.html(data);
|
|
task.unblock();
|
|
},
|
|
error: function()
|
|
{
|
|
task.fail();
|
|
},
|
|
xhr: createWrapper
|
|
});
|
|
|
|
task.next(function(task)
|
|
{
|
|
test.pass();
|
|
});
|
|
});
|
|
|
|
addTest('generic wrapper xhr (10 serial)', function(task, test)
|
|
{
|
|
var N = 10;
|
|
for(var i = 0; i < N; i++)
|
|
{
|
|
task.next(function(task)
|
|
{
|
|
task.parent.block();
|
|
|
|
$.ajax(
|
|
{
|
|
type: 'GET',
|
|
url: '/result.txt',
|
|
success: function(data, textStatus)
|
|
{
|
|
test.result.append('.');
|
|
task.parent.unblock();
|
|
},
|
|
error: function(xhr, textStatus, errorThrown)
|
|
{
|
|
task.fail(N);
|
|
},
|
|
xhr: createWrapper
|
|
});
|
|
});
|
|
}
|
|
|
|
task.next(function(task)
|
|
{
|
|
test.pass(N);
|
|
});
|
|
});
|
|
|
|
addTest('generic wrapper xhr (10 parallel)', function(task, test)
|
|
{
|
|
var N = 10;
|
|
task.block(N);
|
|
for(var i = 0; i < N; i++)
|
|
{
|
|
$.ajax(
|
|
{
|
|
type: 'GET',
|
|
url: '/result.txt',
|
|
success: function(data, textStatus)
|
|
{
|
|
test.result.append('.');
|
|
task.unblock();
|
|
},
|
|
error: function(xhr, textStatus, errorThrown)
|
|
{
|
|
task.fail(N);
|
|
},
|
|
xhr: createWrapper
|
|
});
|
|
}
|
|
|
|
task.next(function(task)
|
|
{
|
|
test.pass(N);
|
|
});
|
|
});
|
|
}
|
|
|
|
for(var i = 0; i < 3; i++) {
|
|
addTest('TLS xhr ' + i, function(task, test)
|
|
{
|
|
task.block();
|
|
|
|
$.ajax(
|
|
{
|
|
type: 'GET',
|
|
url: '/result.txt',
|
|
success: function(data, textStatus, xhr)
|
|
{
|
|
test.expect.html('expected result');
|
|
test.result.html(data);
|
|
task.unblock();
|
|
},
|
|
error: function(xhr, textStatus, errorThrown)
|
|
{
|
|
task.fail();
|
|
},
|
|
xhr: forge.xhr.create
|
|
});
|
|
|
|
task.next(function(task)
|
|
{
|
|
test.pass();
|
|
});
|
|
});
|
|
}
|
|
|
|
addTest('TLS xhr (10 serial)', function(task, test)
|
|
{
|
|
var N = 10;
|
|
for(var i = 0; i < N; i++)
|
|
{
|
|
task.next(function(task)
|
|
{
|
|
task.parent.block();
|
|
|
|
$.ajax(
|
|
{
|
|
type: 'GET',
|
|
url: '/result.txt',
|
|
success: function(data, textStatus, xhr)
|
|
{
|
|
test.result.append('.');
|
|
task.parent.unblock();
|
|
},
|
|
error: function(xhr, textStatus, errorThrown)
|
|
{
|
|
task.fail(N);
|
|
},
|
|
xhr: forge.xhr.create
|
|
});
|
|
});
|
|
}
|
|
|
|
task.next(function(task)
|
|
{
|
|
test.pass(N);
|
|
});
|
|
});
|
|
|
|
addTest('TLS xhr (10 parallel) ' +
|
|
'(hit "Reset" then "Start" to speed up - uses SSL session cache)',
|
|
function(task, test)
|
|
{
|
|
var N = 10;
|
|
task.block(N);
|
|
for(var i = 0; i < N; i++)
|
|
{
|
|
$.ajax(
|
|
{
|
|
type: 'GET',
|
|
url: '/result.txt',
|
|
success: function(data, textStatus, xhr)
|
|
{
|
|
test.result.append('.');
|
|
task.unblock();
|
|
},
|
|
error: function(xhr, textStatus, errorThrown)
|
|
{
|
|
task.fail(N);
|
|
},
|
|
xhr: forge.xhr.create
|
|
});
|
|
}
|
|
|
|
task.next(function(task)
|
|
{
|
|
test.pass(N);
|
|
});
|
|
});
|
|
|
|
init();
|
|
});
|