Skip to content

Instantly share code, notes, and snippets.

@luketn
Created November 18, 2022 04:18
Show Gist options
  • Save luketn/db0b0a09f711875cecfda4c91125a1be to your computer and use it in GitHub Desktop.
Save luketn/db0b0a09f711875cecfda4c91125a1be to your computer and use it in GitHub Desktop.
CDN Test Script
var API_PREFIX = '/api/v1';
var stats = [];
var TEST_CDN = '';
function recordStat(url, cdnName, statName, timeInMillis) {
stats.push({
"name": statName,
"cdn": cdnName,
"timeTakenMillis": timeInMillis
});
}
function measureImageSpeed(imageAddr, success, error) {
setTimeout(function() {
var startTime, endTime;
var download = new Image();
download.onload = function () {
endTime = (new Date()).getTime();
var duration = (endTime - startTime);
success(imageAddr, duration);
}
download.onerror = function (err, msg) {
error(imageAddr, err, msg);
}
startTime = (new Date()).getTime();
var cacheBuster = "?nnn=" + startTime;
download.src = imageAddr + cacheBuster;
}, 500)
}
function getCookie(name) {
var value = "; " + document.cookie;
var parts = value.split("; " + name + "=");
if (parts.length == 2) return parts.pop().split(";").shift();
}
function loadAndTime(url, statName, testType, cdnName) {
var start = new Date().getTime();
if (testType == 'api') {
var requestDetails = {
type: "GET",
url: API_PREFIX + url,
cache: false,
headers: {
Authorization: getCookie('Authorization')
},
success: function(data) {
if (data) {
var end = new Date().getTime();
recordStat(url, TEST_CDN, statName, (end-start));
} else {
recordStat(url, TEST_CDN, statName, -1); // Failure!
}
runNext();
},
error: function() {
recordStat(url, TEST_CDN, statName, -1); // Failure!
runNext();
},
dataType: null
};
$.ajax(requestDetails);
} else if (testType == 'apiAbsolute') {
var requestDetails = {
type: "GET",
url: url,
cache: false,
headers: {
Authorization: getCookie('Authorization')
},
success: function(data, textStatus, request) {
if (data) {
var end = new Date().getTime();
recordStat(url, cdnName, statName, (end-start));
} else {
recordStat(url, cdnName, statName, -1); // Failure!
}
runNext();
},
error: function(request, textStatus, err) {
recordStat(url, cdnName, statName, -1); // Failure!
runNext();
},
dataType: null
};
$.ajax(requestDetails);
} else if (testType == 'image') {
measureImageSpeed(url, function(url, duration) {
recordStat(url, cdnName, statName, duration);
runNext();
},
function(url, err, msg) {
recordStat(url, cdnName, statName, -1); // Failure!
runNext();
})
} else if (testType == 'measured') {
var measuredCdnName = TEST_CDN;
var measuredTimeTaken = -1;
if (url) {
var measures = url.split('|');
if (measures.length == 2) {
var begin = window[measures[0]];
var end = window[measures[1]];
if (begin && end) {
measuredTimeTaken = end - begin;
}
}
}
recordStat(url, measuredCdnName, statName, measuredTimeTaken);
setTimeout(function(){
runNext();
}, 10);
} else {
setTimeout(function(){
runNext();
}, 10);
}
}
function getCdnName(request) {
var cdnName;
if (isCloudFrontRequest(request)) {
cdnName = 'CloudFront';
} else if (isAliCloudRequest(request)){
cdnName = 'AliCloud';
} else {
cdnName = 'Unknown';
}
return cdnName;
}
function isCloudFrontRequest(request) {
if (request.getResponseHeader('x-amz-cf-id')) {
return true;
} else {
return false;
}
}
function isAliCloudRequest(request) {
if (request.getResponseHeader('X-Swift-CacheTime')) {
return true;
} else {
return false;
}
}
function postStats() {
var result = {
"stats": stats
};
$.ajax({
type: "POST",
url: API_PREFIX + '/statscollector/save',
data: JSON.stringify(result),
headers: {
"Content-Type": "application/json",
"Accept": "application/json",
"Authorization": getCookie('Authorization')
},
success: function(data) {
//if (console && console.log) console.log("Test complete: " + cdn);
},
dataType: null
});
}
var tests = []; //{url: '' (relative to API_PREFIX for 'api' testType, absolute for all others), name: 'Xyz' (e.g. img-large, json-small), testType: 'api|image|apiAbsolute', cdnName: 'CloudFront|Akamai|AliCloud' (determined from response header for 'api' testType)}
var nextIndex = 0;
function runNext(){
if (nextIndex < tests.length) {
loadAndTime(tests[nextIndex].url, tests[nextIndex].name, tests[nextIndex].testType, tests[nextIndex].cdnName)
nextIndex++;
} else {
postStats();
}
}
function loadAndRunTests() {
$.ajax({
type: "GET",
url: API_PREFIX + '/statscollector/getTests.json',
headers: {
"Content-Type": "application/json",
"Accept": "application/json",
"Authorization": getCookie('Authorization')
},
success: function(data, textStatus, request) {
TEST_CDN = getCdnName(request);
if (data && data.tests) {
tests = data.tests;
//if (console && console.log) console.log("Running tests: " + JSON.stringify(data));
} else {
//console.log('Received invalid test data.')
}
runNext();
},
error: function() {
//console.log('Failed to load tests.')
}
});
}
$( document ).ready(function() {
setTimeout(function() {
loadAndRunTests();
}, 3000)
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment