1396 lines
50 KiB
JavaScript
1396 lines
50 KiB
JavaScript
(function (context, $) {
|
|
|
|
"use strict";
|
|
|
|
context.JK = context.JK || {};
|
|
context.JK.NetworkTest = function (app) {
|
|
|
|
var NETWORK_TEST_TYPES = {
|
|
RestPhase: 0,
|
|
PktTest100NormalLatency: 1,
|
|
PktTest200MediumLatency: 2,
|
|
PktTest400LowLatency: 3,
|
|
PktTestRateSweep: 4,
|
|
RcvOnly: 5
|
|
}
|
|
var STARTING_NUM_CLIENTS_AUDIO = 4;
|
|
var STARTING_NUM_CLIENTS_VIDEO = 2;
|
|
var AUDIO_PAYLOAD_SIZE = gon.global.ftue_network_test_packet_size;
|
|
var VIDEO_PAYLOAD_SIZE = gon.global.ftue_network_test_packet_size_video;
|
|
var MINIMUM_ACCEPTABLE_SESSION_SIZE = 2;
|
|
var RETRY_THRESHOLD = 2;
|
|
|
|
var gearUtils = context.JK.GearUtils;
|
|
var rest = context.JK.Rest();
|
|
var logger = context.JK.logger;
|
|
var $step = null;
|
|
var TEST_SUCCESS_CALLBACK = 'JK.HandleNetworkTestSuccess';
|
|
var TEST_TIMEOUT_CALLBACK = 'JK.HandleNetworkTestTimeout';
|
|
|
|
var $startNetworkTestBtn = null;
|
|
var $foreverNetworkTestBtn = null;
|
|
var $testResults = null;
|
|
var $testScoreAudio = null;
|
|
var $testScoreVideo= null;
|
|
var $testText = null;
|
|
var $inProgressText = null;
|
|
var $audioResultText = null;
|
|
var $videoResultText = null;
|
|
var testedSuccessfully = false;
|
|
var $scoringBar = null;
|
|
var $goodMarker = null;
|
|
var $goodLine = null;
|
|
var $currentScore = null;
|
|
var $scoredClientsAudio = null;
|
|
var $scoredClientsVideo = null;
|
|
var $subscore = null;
|
|
var $watchVideo = null;
|
|
var $container = null;
|
|
var backendGuardTimeout = null;
|
|
var primeGuardTimeout = null;
|
|
var primeDeferred = null;
|
|
|
|
var serverClientId = '';
|
|
var audioScoring = false;
|
|
var videoScoring = false;
|
|
var numClientToTestAudio = STARTING_NUM_CLIENTS_AUDIO;
|
|
var numClientToTestVideo = STARTING_NUM_CLIENTS_VIDEO;
|
|
var testSummary = {audioAttempts: [], videoAttempts: [], final: null}
|
|
var $self = $(this);
|
|
var scoringZoneWidth = 100;//px
|
|
var inGearWizard = false;
|
|
var operatingSystem = null;
|
|
var PRIME_PUMP_TIME = 1;
|
|
|
|
var forever = false;
|
|
|
|
// these try to make it such that we only pass a NetworkTest Pass/Failed one time in a new user flow
|
|
var trackedPass = false;
|
|
var lastNetworkFailure = null;
|
|
var bandwidthSamples = [];
|
|
|
|
var NETWORK_TEST_START = 'network_test.start';
|
|
var NETWORK_TEST_DONE = 'network_test.done';
|
|
var NETWORK_TEST_FAIL = 'network_test.fail';
|
|
var NETWORK_TEST_CANCEL = 'network_test.cancel';
|
|
|
|
function createSuccessCallbackName(priming) {
|
|
if (priming) {
|
|
if (inGearWizard) {
|
|
return TEST_SUCCESS_CALLBACK + 'ForPumpPrimingGW';
|
|
}
|
|
else {
|
|
return TEST_SUCCESS_CALLBACK + 'ForPumpPrimingDialog';
|
|
}
|
|
}
|
|
else {
|
|
if (inGearWizard) {
|
|
return TEST_SUCCESS_CALLBACK + 'ForGearWizard';
|
|
}
|
|
else {
|
|
return TEST_SUCCESS_CALLBACK + 'ForDialog';
|
|
}
|
|
}
|
|
}
|
|
|
|
function createTimeoutCallbackName(priming) {
|
|
if (priming) {
|
|
if (inGearWizard) {
|
|
return TEST_TIMEOUT_CALLBACK + 'ForPumpPrimingGW';
|
|
}
|
|
else {
|
|
return TEST_TIMEOUT_CALLBACK + 'ForPumpPrimingDialog';
|
|
}
|
|
}
|
|
else {
|
|
if (inGearWizard) {
|
|
return TEST_TIMEOUT_CALLBACK + 'ForGearWizard';
|
|
}
|
|
else {
|
|
return TEST_TIMEOUT_CALLBACK + 'ForDialog';
|
|
}
|
|
}
|
|
}
|
|
|
|
// this averages bandwidthSamples; this method is meant just for GA data
|
|
function avgBandwidth(num_others) {
|
|
if (bandwidthSamples.length == 0) {
|
|
return 0;
|
|
}
|
|
else {
|
|
var total = 0;
|
|
context._.each(bandwidthSamples, function (sample) {
|
|
total += (sample * num_others * 400 * (100 + 28)); // sample is a percentage of 400. So sample * 400 gives us how many packets/sec. 100 is payload; 28 is UDP+ETHERNET overhead, to give us bandwidth
|
|
})
|
|
return total / bandwidthSamples.length;
|
|
}
|
|
}
|
|
|
|
function reset() {
|
|
trackedPass = false;
|
|
lastNetworkFailure = null;
|
|
resetTestState();
|
|
}
|
|
|
|
function resetTestState() {
|
|
serverClientId = '';
|
|
audioScoring = false;
|
|
videoScoring = false;
|
|
numClientToTestAudio = STARTING_NUM_CLIENTS_AUDIO;
|
|
numClientToTestVideo = STARTING_NUM_CLIENTS_VIDEO;
|
|
testSummary = {audioAttempts: [], videoAttempts:[]};
|
|
configureStartButton();
|
|
$scoredClientsAudio.empty();
|
|
$testResults.removeClass('good acceptable bad testing');
|
|
$testScoreAudio.removeClass('good acceptable bad testing');
|
|
$testScoreVideo.removeClass('good acceptable bad testing');
|
|
$scoredClientsAudio.text('-')
|
|
$scoredClientsVideo.text('-')
|
|
$inProgressText.empty();
|
|
$audioResultText.empty();
|
|
$audioResultText.hide();
|
|
$videoResultText.empty();
|
|
$videoResultText.hide();
|
|
$subscore.empty();
|
|
$currentScore.width(0);
|
|
bandwidthSamples = [];
|
|
|
|
}
|
|
|
|
function renderStartTestAudio() {
|
|
configureStartButton();
|
|
$testResults.addClass('testing');
|
|
$testScoreAudio.addClass('testing');
|
|
$goodLine.css('left', (gon.ftue_packet_rate_treshold * 100) + '%');
|
|
$goodMarker.css('left', (gon.ftue_packet_rate_treshold * 100) + '%');
|
|
}
|
|
|
|
function renderStartTestVideo() {
|
|
configureStartButton();
|
|
$testResults.addClass('testing');
|
|
$testScoreVideo.addClass('testing');
|
|
$goodLine.css('left', (gon.ftue_packet_rate_treshold * 100) + '%');
|
|
$goodMarker.css('left', (gon.ftue_packet_rate_treshold * 100) + '%');
|
|
}
|
|
|
|
function renderStopTestAudio(score, text) {
|
|
if(!score || score.length == 0) {
|
|
$scoredClientsAudio.html('0');
|
|
|
|
$inProgressText.text('The audio test did not pass. Video is not tested in this case.');
|
|
|
|
}
|
|
else {
|
|
$scoredClientsAudio.html(score);
|
|
}
|
|
|
|
if(text && text.length > 0) {
|
|
$audioResultText.text(text);
|
|
}
|
|
$testResults.removeClass('testing');
|
|
$testScoreAudio.removeClass('testing');
|
|
|
|
}
|
|
|
|
function renderStopTestVideo(score, text) {
|
|
logger.debug("renderStopTestVideo", score, text)
|
|
|
|
// don't show the audio result text until the test is over (it looks confusing otherwise).
|
|
if($audioResultText.text() && $audioResultText.text().length > 0) {
|
|
$audioResultText.show();
|
|
}
|
|
|
|
$inProgressText.text('Your router and Internet service will support:')
|
|
|
|
if(!score || score.length == 0) {
|
|
$scoredClientsVideo.html('-');
|
|
}
|
|
else {
|
|
|
|
if(score < 2) {
|
|
$scoredClientsVideo.html('0')
|
|
$videoResultText.html('No other players when in a video + audio session.').show();
|
|
$testScoreVideo.addClass('acceptable');
|
|
}
|
|
else {
|
|
$scoredClientsVideo.html(score);
|
|
|
|
var summary = "Video + audio sessions with up to " + score + " players";
|
|
|
|
if (text && text.length > 0) {
|
|
// presence of text means there was an error on the last test pass.
|
|
summary += '. Note that there was an error when testing for ' + (score + 1) + 'players. Support code=' + text
|
|
}
|
|
|
|
$videoResultText.html(summary).show();
|
|
}
|
|
}
|
|
|
|
$testResults.removeClass('testing');
|
|
$testScoreVideo.removeClass('testing');
|
|
}
|
|
|
|
function postDiagnostic() {
|
|
rest.createDiagnostic({
|
|
type: 'NETWORK_TEST_RESULT',
|
|
data: {client_type: context.JK.clientType(), client_id: context.JK.JamServer.clientID, summary: testSummary}
|
|
});
|
|
}
|
|
|
|
function appendContextualStatement() {
|
|
if (inGearWizard) {
|
|
return " You can skip this step for now."
|
|
}
|
|
else {
|
|
return '';
|
|
}
|
|
}
|
|
|
|
function getLastNetworkFailure() {
|
|
return lastNetworkFailure;
|
|
}
|
|
|
|
function haltScoring() {
|
|
context.jamClient.SetLatencyTestBlocked(true)
|
|
rest.updateNetworkTesting({client_id: app.clientId, is_network_testing: true})
|
|
.fail(function(jqXHR) {
|
|
|
|
if(jqXHR.status == 404) {
|
|
// assume connection is missing
|
|
app.notifyAlert("Not Connected", "You must be connected to the server to run the network test.")
|
|
}
|
|
else {
|
|
app.notifyServerError(jqXHR, "Unable to tell server that we are beginning the network test")
|
|
}
|
|
})
|
|
}
|
|
|
|
function resumeScoring() {
|
|
context.jamClient.SetLatencyTestBlocked(false)
|
|
rest.updateNetworkTesting({client_id: app.clientId, is_network_testing: false})
|
|
.fail(function(jqXHR) {
|
|
if(jqXHR.status == 404) {
|
|
// assume connection is missing
|
|
// do nothing in this case
|
|
}
|
|
else {
|
|
app.notifyServerError(jqXHR, "Unable to tell server that we are ending the network test")
|
|
}
|
|
})
|
|
}
|
|
|
|
function storeLastNetworkFailure(reason, data) {
|
|
if (!trackedPass) {
|
|
lastNetworkFailure = {reason: reason, data: data};
|
|
}
|
|
}
|
|
|
|
function testFinishedAudio() {
|
|
var attempt = getCurrentAttemptAudio();
|
|
|
|
if (!testSummary.final) {
|
|
testSummary.final = {reason: attempt.reason};
|
|
}
|
|
|
|
var reason = testSummary.final.reason;
|
|
var success = false;
|
|
|
|
if (reason == "success") {
|
|
renderStopTestAudio(attempt.num_clients, "Audio-only sessions with up to " + attempt.num_clients + " players")
|
|
testedSuccessfully = true;
|
|
if (!testSummary.final.num_clients) {
|
|
testSummary.final.num_clients = attempt.num_clients;
|
|
}
|
|
|
|
// context.jamClient.GetNetworkTestScore() == 0 is a rough approximation if the user has passed the FTUE before
|
|
if (inGearWizard || context.jamClient.GetNetworkTestScore() == 0) {
|
|
trackedPass = true;
|
|
lastNetworkFailure = null;
|
|
context.JK.GA.trackNetworkTest(context.JK.detectOS(), testSummary.final.num_clients);
|
|
}
|
|
|
|
context.jamClient.SetNetworkTestScore(attempt.num_clients);
|
|
if (testSummary.final.num_clients == 2) {
|
|
$testScoreAudio.addClass('acceptable');
|
|
}
|
|
else {
|
|
$testScoreAudio.addClass('good');
|
|
}
|
|
success = true;
|
|
}
|
|
else if (reason == "minimum_client_threshold") {
|
|
context.jamClient.SetNetworkTestScore(0);
|
|
renderStopTestAudio('', "We're sorry, but your router and Internet service will not effectively support JamKazam sessions. Please click the HELP button for more information.")
|
|
storeLastNetworkFailure(context.JK.GA.NetworkTestFailReasons.bandwidth, avgBandwidth(attempt.num_clients - 1));
|
|
}
|
|
else if (reason == "unreachable" || reason == "no-transmit") {
|
|
context.jamClient.SetNetworkTestScore(0);
|
|
// https://jamkazam.atlassian.net/browse/VRFS-2323
|
|
renderStopTestAudio('', "We're sorry, but your router will not support JamKazam in its current configuration. Please click <a rel='external' href='https://jamkazam.desk.com/customer/portal/articles/1716139-what-to-do-if-you-cannot-pass-the-network-test'>HERE</a> for more information.");
|
|
storeLastNetworkFailure(context.JK.GA.NetworkTestFailReasons.stun, attempt.num_clients);
|
|
}
|
|
else if (reason == "internal_error") {
|
|
context.JK.alertSupportedNeeded("The JamKazam client software had an unexpected problem while scoring your Internet connection.");
|
|
renderStopTestAudio('', '');
|
|
storeLastNetworkFailure(context.JK.GA.NetworkTestFailReasons.jamerror);
|
|
}
|
|
else if (reason == "remote_peer_cant_test") {
|
|
context.JK.alertSupportedNeeded("The JamKazam service is experiencing technical difficulties.");
|
|
renderStopTestAudio('', '');
|
|
storeLastNetworkFailure(context.JK.GA.NetworkTestFailReasons.jamerror);
|
|
}
|
|
else if (reason == "server_comm_timeout") {
|
|
gearUtils.skipNetworkTest();
|
|
context.JK.alertSupportedNeeded("Communication with the JamKazam network service has timed out." + appendContextualStatement());
|
|
renderStopTestAudio('', '');
|
|
storeLastNetworkFailure(context.JK.GA.NetworkTestFailReasons.jamerror);
|
|
}
|
|
else if (reason == 'backend_gone') {
|
|
context.JK.alertSupportedNeeded("The JamKazam client is experiencing technical difficulties.");
|
|
renderStopTestAudio('', '');
|
|
storeLastNetworkFailure(context.JK.GA.NetworkTestFailReasons.jamerror);
|
|
}
|
|
else if (reason == "invalid_response") {
|
|
gearUtils.skipNetworkTest();
|
|
context.JK.alertSupportedNeeded("The JamKazam client software had an unexpected problem while scoring your Internet connection.<br/><br/>Reason: " + attempt.backend_data.reason + '.');
|
|
renderStopTestAudio('', '');
|
|
storeLastNetworkFailure(context.JK.GA.NetworkTestFailReasons.jamerror);
|
|
}
|
|
else if (reason == 'no_servers') {
|
|
gearUtils.skipNetworkTest();
|
|
context.JK.Banner.showAlert("No network test servers are available." + appendContextualStatement());
|
|
renderStopTestAudio('', '');
|
|
testedSuccessfully = true;
|
|
storeLastNetworkFailure(context.JK.GA.NetworkTestFailReasons.jamerror);
|
|
}
|
|
else if (reason == 'no_network') {
|
|
context.JK.Banner.showAlert("Please try again later. Your network appears down.");
|
|
renderStopTestAudio('', '');
|
|
storeLastNetworkFailure(context.JK.GA.NetworkTestFailReasons.noNetwork);
|
|
}
|
|
else if (reason == "rest_api_error") {
|
|
gearUtils.skipNetworkTest();
|
|
context.JK.alertSupportedNeeded("Unable to acquire a network test server." + appendContextualStatement());
|
|
testedSuccessfully = true;
|
|
renderStopTestAudio('', '');
|
|
storeLastNetworkFailure(context.JK.GA.NetworkTestFailReasons.jamerror);
|
|
}
|
|
else if (reason == "timeout") {
|
|
gearUtils.skipNetworkTest();
|
|
context.JK.alertSupportedNeeded("Communication with the JamKazam network service timed out." + appendContextualStatement());
|
|
testedSuccessfully = true;
|
|
renderStopTestAudio('', '');
|
|
storeLastNetworkFailure(context.JK.GA.NetworkTestFailReasons.jamerror);
|
|
}
|
|
else {
|
|
gearUtils.skipNetworkTest();
|
|
context.JK.alertSupportedNeeded("The JamKazam client software had a logic error while scoring your Internet connection.");
|
|
renderStopTestAudio('', '');
|
|
storeLastNetworkFailure(context.JK.GA.NetworkTestFailReasons.jamerror);
|
|
}
|
|
|
|
numClientToTestAudio = STARTING_NUM_CLIENTS_AUDIO;
|
|
audioScoring = false;
|
|
postDiagnostic();
|
|
|
|
if (success) {
|
|
|
|
startVideoTest();
|
|
|
|
if(forever) {
|
|
prepareNetworkTest();
|
|
}
|
|
}
|
|
else {
|
|
configureStartButton();
|
|
|
|
$self.triggerHandler(NETWORK_TEST_FAIL)
|
|
}
|
|
}
|
|
|
|
function testFinishedVideo() {
|
|
|
|
var attempt = getCurrentAttemptVideo();
|
|
|
|
if (!testSummary.video_final) {
|
|
testSummary.video_final = {reason: attempt.reason};
|
|
}
|
|
|
|
// a score of '2' is a failure when we take error paths in this function. Because we alway decrement the num_clients by 1 (and < 2 is considered failure). Also , we start the testing at 2. so it's probably correct anyway
|
|
if (!testSummary.video_final.num_clients) {
|
|
testSummary.video_final.num_clients = 2;
|
|
}
|
|
|
|
var reason = testSummary.video_final.reason;
|
|
var success = false;
|
|
|
|
logger.debug("testFinishedVideo", testSummary)
|
|
|
|
if (reason == "success") {
|
|
renderStopTestVideo(attempt.num_clients, null)
|
|
//testedSuccessfully = true;
|
|
if (!testSummary.video_final.num_clients) {
|
|
testSummary.video_final.num_clients = attempt.num_clients;
|
|
}
|
|
|
|
// context.jamClient.GetNetworkTestScore() == 0 is a rough approximation if the user has passed the FTUE before
|
|
if (inGearWizard || context.jamClient.GetVideoNetworkTestScore() == 0) {
|
|
//trackedPass = true;
|
|
//lastNetworkFailure = null;
|
|
//context.JK.GA.trackNetworkTest(context.JK.detectOS(), testSummary.final.num_clients);
|
|
}
|
|
|
|
context.jamClient.SetVideoNetworkTestScore(attempt.num_clients);
|
|
if (!testSummary.video_final.num_clients) {
|
|
$testScoreVideo.addClass('acceptable');
|
|
}
|
|
else if (testSummary.video_final.num_clients >= 2) {
|
|
$testScoreVideo.addClass('good');
|
|
}
|
|
else {
|
|
$testScoreVideo.addClass('acceptable');
|
|
}
|
|
success = true;
|
|
}
|
|
else if (reason == "minimum_client_threshold") {
|
|
context.jamClient.SetVideoNetworkTestScore(testSummary.video_final.num_clients - 1);
|
|
renderStopTestVideo(testSummary.video_final.num_clients - 1, reason)
|
|
//storeLastNetworkFailure(context.JK.GA.NetworkTestFailReasons.bandwidth, avgBandwidth(attempt.num_clients - 1));
|
|
}
|
|
else if (reason == "unreachable" || reason == "no-transmit") {
|
|
context.jamClient.SetVideoNetworkTestScore(testSummary.video_final.num_clients - 1);
|
|
// https://jamkazam.atlassian.net/browse/VRFS-2323
|
|
renderStopTestVideo(testSummary.video_final.num_clients - 1, reason);
|
|
// storeLastNetworkFailure(context.JK.GA.NetworkTestFailReasons.stun, attempt.num_clients);
|
|
}
|
|
else if (reason == "internal_error") {
|
|
context.JK.alertSupportedNeeded("The JamKazam client software had an unexpected problem while scoring your Internet connection.");
|
|
renderStopTestVideo(testSummary.video_final.num_clients - 1, reason);
|
|
//storeLastNetworkFailure(context.JK.GA.NetworkTestFailReasons.jamerror);
|
|
}
|
|
else if (reason == "remote_peer_cant_test") {
|
|
context.JK.alertSupportedNeeded("The JamKazam service is experiencing technical difficulties.");
|
|
renderStopTestVideo(testSummary.video_final.num_clients - 1, reason);
|
|
//storeLastNetworkFailure(context.JK.GA.NetworkTestFailReasons.jamerror);
|
|
}
|
|
else if (reason == "server_comm_timeout") {
|
|
//gearUtils.skipNetworkTest();
|
|
context.JK.alertSupportedNeeded("Communication with the JamKazam network service has timed out." + appendContextualStatementVideo());
|
|
renderStopTestVideo(testSummary.video_final.num_clients - 1, reason);
|
|
//storeLastNetworkFailure(context.JK.GA.NetworkTestFailReasons.jamerror);
|
|
}
|
|
else if (reason == 'backend_gone') {
|
|
context.JK.alertSupportedNeeded("The JamKazam client is experiencing technical difficulties.");
|
|
renderStopTestVideo(testSummary.video_final.num_clients - 1, reason);
|
|
//storeLastNetworkFailure(context.JK.GA.NetworkTestFailReasons.jamerror);
|
|
}
|
|
else if (reason == "invalid_response") {
|
|
//gearUtils.skipNetworkTest();
|
|
context.JK.alertSupportedNeeded("The JamKazam client software had an unexpected problem while scoring your Internet connection.<br/><br/>Reason: " + attempt.backend_data.reason + '.');
|
|
renderStopTestVideo(testSummary.video_final.num_clients - 1, reason);
|
|
//storeLastNetworkFailure(context.JK.GA.NetworkTestFailReasons.jamerror);
|
|
}
|
|
else if (reason == 'no_servers') {
|
|
// gearUtils.skipNetworkTest();
|
|
context.JK.Banner.showAlert("No network test servers are available." + appendContextualStatement());
|
|
renderStopTestVideo(null, reason);
|
|
//testedSuccessfully = true;
|
|
//storeLastNetworkFailure(context.JK.GA.NetworkTestFailReasons.jamerror);
|
|
}
|
|
else if (reason == 'no_network') {
|
|
context.JK.Banner.showAlert("Please try again later. Your network appears down.");
|
|
renderStopTestVideo(testSummary.video_final.num_clients - 1, reason);
|
|
//storeLastNetworkFailure(context.JK.GA.NetworkTestFailReasons.noNetwork);
|
|
}
|
|
else if (reason == "rest_api_error") {
|
|
//gearUtils.skipNetworkTest();
|
|
context.JK.alertSupportedNeeded("Unable to acquire a network test server." + appendContextualStatement());
|
|
//testedSuccessfully = true;
|
|
renderStopTestVideo(null, reason);
|
|
//storeLastNetworkFailure(context.JK.GA.NetworkTestFailReasons.jamerror);
|
|
}
|
|
else if (reason == "timeout") {
|
|
//gearUtils.skipNetworkTest();
|
|
context.JK.alertSupportedNeeded("Communication with the JamKazam network service timed out." + appendContextualStatement());
|
|
//testedSuccessfully = true;
|
|
renderStopTestVideo(testSummary.video_final.num_clients - 1, reason);
|
|
//storeLastNetworkFailure(context.JK.GA.NetworkTestFailReasons.jamerror);
|
|
}
|
|
else {
|
|
//gearUtils.skipNetworkTest();
|
|
context.JK.alertSupportedNeeded("The JamKazam client software had a logic error while scoring your Internet connection.");
|
|
renderStopTestVideo(testSummary.video_final.num_clients - 1, reason);
|
|
//storeLastNetworkFailure(context.JK.GA.NetworkTestFailReasons.jamerror);
|
|
}
|
|
|
|
numClientToTestVideo = STARTING_NUM_CLIENTS_VIDEO;
|
|
videoScoring = false;
|
|
configureStartButton();
|
|
postDiagnostic();
|
|
|
|
$self.triggerHandler(NETWORK_TEST_DONE)
|
|
}
|
|
|
|
function startVideoTest() {
|
|
|
|
videoScoring = true;
|
|
|
|
renderStartTestVideo();
|
|
|
|
attemptTestPassVideo();
|
|
}
|
|
|
|
function getCurrentAttemptAudio() {
|
|
return testSummary.audioAttempts[testSummary.audioAttempts.length - 1];
|
|
}
|
|
function getCurrentAttemptVideo() {
|
|
return testSummary.videoAttempts[testSummary.videoAttempts.length - 1];
|
|
}
|
|
|
|
function isFirstAttemptAudio() {
|
|
return testSummary.audioAttempts.length == 0 || testSummary.audioAttempts.length == 1;
|
|
}
|
|
|
|
function isFirstAttemptVideo() {
|
|
return testSummary.videoAttempts.length == 0 || testSummary.videoAttempts.length == 1;
|
|
}
|
|
|
|
function hasGoneDown() {
|
|
var goneDown = false;
|
|
context._.each(testSummary.audioAttempts, function(attempt) {
|
|
if(attempt.num_clients == STARTING_NUM_CLIENTS_AUDIO - 1) {
|
|
goneDown = true
|
|
return false;
|
|
}
|
|
});
|
|
return goneDown;
|
|
}
|
|
|
|
// is this a retry attempt? If so, how many times now has it been.
|
|
// 0 = this is the 1st attempt
|
|
// > 0 indicates the number of retries.
|
|
function numRetryAttempts() {
|
|
// starting at the end of the attempts array, see how many have the same session count, which is implicitely
|
|
// indicative of a retry
|
|
var i = 0;
|
|
var testSessionSize = null;
|
|
var numSameSizeTests = 0;
|
|
|
|
for(i = testSummary.audioAttempts.length - 1; i >= 0; i--) {
|
|
var attempt = testSummary.audioAttempts[i];
|
|
|
|
if(testSessionSize === null) {
|
|
// this is the 1st loop through. just recording the testSessionSize
|
|
testSessionSize = attempt.num_clients;
|
|
}
|
|
else {
|
|
if(testSessionSize == attempt.num_clients) {
|
|
numSameSizeTests++;
|
|
}
|
|
else {
|
|
break; // different size session found, so we are digging back into non-retry territory. bail out
|
|
}
|
|
}
|
|
}
|
|
return numSameSizeTests;
|
|
}
|
|
|
|
function hasTooManyRetries() {
|
|
return numRetryAttempts() >= RETRY_THRESHOLD;
|
|
|
|
return false;
|
|
}
|
|
|
|
function primeTimedOut() {
|
|
logger.warn("backend never completed priming pump phase");
|
|
audioScoring = false;
|
|
primeDeferred.reject();
|
|
}
|
|
|
|
function backendTimedOut() {
|
|
|
|
if (audioScoring) {
|
|
testSummary.final = {reason: 'backend_gone'}
|
|
testFinishedAudio();
|
|
}
|
|
else {
|
|
testSummary.video_final = {reason: 'backend_gone'}
|
|
testFinishedVideo();
|
|
}
|
|
}
|
|
|
|
function cancel() {
|
|
|
|
}
|
|
|
|
function clearBackendGuard() {
|
|
if (backendGuardTimeout) {
|
|
clearTimeout(backendGuardTimeout);
|
|
backendGuardTimeout = null;
|
|
}
|
|
}
|
|
|
|
// we know we are attempting a pass if the backend or prime guard timeout is not null
|
|
function isAttemptingPass() {
|
|
return backendGuardTimeout != null || primeGuardTimeout != null;
|
|
}
|
|
|
|
function clearPrimeGuard() {
|
|
if (primeGuardTimeout) {
|
|
clearTimeout(primeGuardTimeout);
|
|
primeGuardTimeout = null;
|
|
}
|
|
}
|
|
|
|
function setPrimeGuard() {
|
|
clearPrimeGuard();
|
|
primeGuardTimeout = setTimeout(function () {
|
|
clearPrimeGuard();
|
|
primeTimedOut()
|
|
}, (PRIME_PUMP_TIME + 10) * 1000);
|
|
}
|
|
|
|
function setBackendGuard() {
|
|
clearBackendGuard();
|
|
backendGuardTimeout = setTimeout(function () {
|
|
clearBackendGuard();
|
|
backendTimedOut()
|
|
}, (gon.ftue_network_test_duration + 5) * 1000);
|
|
}
|
|
|
|
function attemptTestPassAudio() {
|
|
|
|
var attempt = {};
|
|
attempt.payload_size = AUDIO_PAYLOAD_SIZE;
|
|
attempt.duration = gon.ftue_network_test_duration;
|
|
attempt.test_type = 'PktTest400LowLatency';
|
|
attempt.num_clients = numClientToTestAudio;
|
|
attempt.server_client_id = serverClientId;
|
|
attempt.received_progress = false;
|
|
testSummary.audioAttempts.push(attempt);
|
|
|
|
$scoredClientsAudio.text(numClientToTestAudio);
|
|
|
|
//context.jamClient.StopNetworkTest('');
|
|
|
|
$inProgressText.text("Simulating the network traffic of a " + numClientToTestAudio + "-person audio session. Video will be tested next.");
|
|
|
|
updateProgress(0, false);
|
|
|
|
setBackendGuard();
|
|
|
|
audioScoring = true;
|
|
logger.debug("network test attempt: " + numClientToTestAudio + "-person audio session, 400 packets/s, " + AUDIO_PAYLOAD_SIZE + " byte payload")
|
|
context.jamClient.TestNetworkPktBwRate(serverClientId, createSuccessCallbackName(false), createTimeoutCallbackName(false),
|
|
NETWORK_TEST_TYPES.PktTest400LowLatency,
|
|
gon.ftue_network_test_duration,
|
|
numClientToTestAudio - 1,
|
|
AUDIO_PAYLOAD_SIZE, gon.global.ftue_network_test_backend_retries);
|
|
}
|
|
|
|
function attemptTestPassVideo() {
|
|
|
|
var attempt = {};
|
|
attempt.payload_size = VIDEO_PAYLOAD_SIZE;
|
|
attempt.duration = gon.ftue_network_test_duration;
|
|
attempt.test_type = 'PktTest400LowLatency';
|
|
attempt.num_clients = numClientToTestVideo;
|
|
attempt.server_client_id = serverClientId;
|
|
attempt.received_progress = false;
|
|
testSummary.videoAttempts.push(attempt);
|
|
|
|
$scoredClientsVideo.text(numClientToTestVideo);
|
|
//context.jamClient.StopNetworkTest('');
|
|
|
|
$inProgressText.text("Simulating the network traffic of a " + numClientToTestVideo + "-person video session.");
|
|
|
|
updateProgress(0, false);
|
|
|
|
setBackendGuard();
|
|
|
|
logger.debug("network test attempt: " + numClientToTestVideo + "-person video session, 400 packets/s, " + VIDEO_PAYLOAD_SIZE + " byte payload")
|
|
context.jamClient.TestNetworkPktBwRate(serverClientId, createSuccessCallbackName(false), createTimeoutCallbackName(false),
|
|
NETWORK_TEST_TYPES.PktTest400LowLatency,
|
|
gon.ftue_network_test_duration,
|
|
numClientToTestVideo - 1,
|
|
VIDEO_PAYLOAD_SIZE, gon.global.ftue_network_test_backend_retries);
|
|
}
|
|
|
|
// you have to score a little to 'prime' the logic to know whether it's on wireless or not
|
|
function primePump() {
|
|
audioScoring = true;
|
|
primeDeferred = new $.Deferred();
|
|
|
|
setPrimeGuard();
|
|
|
|
context.jamClient.TestNetworkPktBwRate(serverClientId, createSuccessCallbackName(true), createTimeoutCallbackName(true),
|
|
NETWORK_TEST_TYPES.PktTest400LowLatency,
|
|
PRIME_PUMP_TIME,
|
|
2,
|
|
AUDIO_PAYLOAD_SIZE, gon.global.ftue_network_test_backend_retries);
|
|
|
|
|
|
return primeDeferred;
|
|
}
|
|
|
|
function cancelTest() {
|
|
audioScoring = false;
|
|
configureStartButton();
|
|
renderStopTestAudio();
|
|
$self.triggerHandler(NETWORK_TEST_CANCEL)
|
|
}
|
|
|
|
function postPumpRun() {
|
|
// check if on Wifi 1st
|
|
var isWireless = context.jamClient.IsMyNetworkWireless();
|
|
if (isWireless == -1) {
|
|
logger.warn("unable to determine if the user is on wireless or not for network test. skipping prompt.")
|
|
}
|
|
|
|
if (isWireless == 1) {
|
|
context.JK.Banner.showAlert({buttons: [
|
|
{name: 'CANCEL', click: function () {
|
|
cancelTest();
|
|
}},
|
|
{name: 'RUN NETWORK TEST ANYWAY', click: function () {
|
|
attemptTestPassAudio();
|
|
;
|
|
}}
|
|
],
|
|
html: "<p>It appears that your computer is connected to your network using WiFi.</p>" +
|
|
"<p>We strongly advise against running the JamKazam application on a WiFi connection. " +
|
|
"We recommend using a wired Ethernet connection from your computer to your router. " +
|
|
"A WiFi connection is likely to cause significant issues in both latency and audio quality.</p>"})
|
|
}
|
|
else {
|
|
attemptTestPassAudio();
|
|
}
|
|
}
|
|
|
|
function pauseForRecentScoresTime() {
|
|
var lastScoreTimes = context.jamClient.GetLastLatencyTestTimes()
|
|
|
|
console.log(lastScoreTimes)
|
|
|
|
return 0;
|
|
|
|
var noPause = 0;
|
|
var longAgo = 1000000;
|
|
var initiated = lastScoreTimes.initiatied;
|
|
var requested = lastScoreTimes.requested;
|
|
|
|
if(initiated === null || initiated === undefined) {
|
|
logger.warn("lastScoreTimes.initiated is not set");
|
|
initiated = longAgo;
|
|
}
|
|
if(requested === null || requested === undefined) {
|
|
logger.warn("lastScoreTimes.requested is not set");
|
|
requested = longAgo;
|
|
}
|
|
|
|
if(initiated == 0) {
|
|
logger.debug("lastScoreTimes.initiated is zero");
|
|
initiated = longAgo;
|
|
}
|
|
if(requested == 0) {
|
|
logger.debug("lastScoreTimes.requested is zero");
|
|
requested = longAgo;
|
|
}
|
|
|
|
if(initiated < 0) {
|
|
logger.debug("lastScoreTimes.initiated is less than zero");
|
|
initiated = longAgo;
|
|
}
|
|
if(requested < 0) {
|
|
logger.debug("lastScoreTimes.requested is less than zero");
|
|
requested = longAgo;
|
|
}
|
|
|
|
var mostRecentValue = initiated < requested ? initiated : requested;
|
|
|
|
if(mostRecentValue > gon.globalftue_network_test_min_wait_since_last_score * 1000) {
|
|
return noPause; // our last score was past our min wait; so no delay necessary
|
|
}
|
|
else {
|
|
// pause for the remainder of the min wait threshold
|
|
var remainder = gon.globalftue_network_test_min_wait_since_last_score * 1000 - mostRecentValue;
|
|
|
|
if(remainder > 1500) {
|
|
// we need to update the UI because this is a long time for a mystery pause
|
|
$startNetworkTestBtn.text('SHORT QUIET PERIOD...')
|
|
}
|
|
|
|
return remainder;
|
|
}
|
|
}
|
|
function prepareNetworkTest() {
|
|
|
|
if (audioScoring || videoScoring) return false;
|
|
|
|
setTimeout(function() {
|
|
|
|
logger.info("starting network test");
|
|
resetTestState();
|
|
audioScoring = true;
|
|
$self.triggerHandler(NETWORK_TEST_START);
|
|
renderStartTestAudio();
|
|
rest.getLatencyTester()
|
|
.done(function (response) {
|
|
// ensure there are no tests ongoing
|
|
|
|
serverClientId = response.client_id;
|
|
|
|
testSummary.serverClientId = serverClientId;
|
|
|
|
logger.info("beginning network test against client_id: " + serverClientId);
|
|
|
|
primePump()
|
|
.done(function () {
|
|
postPumpRun();
|
|
})
|
|
.fail(function () {
|
|
logger.debug("unable to determine user's network type. primePump failed.")
|
|
context.JK.Banner.showAlert({
|
|
title: 'Unable to Determine Network Type',
|
|
buttons: [
|
|
{name: 'CANCEL', click: function () {
|
|
cancelTest();
|
|
}},
|
|
{name: 'RUN NETWORK TEST ANYWAY', click: function () {
|
|
attemptTestPassAudio();
|
|
;
|
|
}}
|
|
],
|
|
html: "<p>We are unable to determine if your computer is connected to your network using WiFi.</p>" +
|
|
"<p>We strongly advise against running the JamKazam application on a WiFi connection. " +
|
|
"We recommend using a wired Ethernet connection from your computer to your router. " +
|
|
"A WiFi connection is likely to cause significant issues in both latency and audio quality.</p>"})
|
|
});
|
|
})
|
|
.fail(function (jqXHR) {
|
|
if (jqXHR.status == 404) {
|
|
// means there are no network testers available.
|
|
// we have to skip this part of the UI
|
|
testSummary.final = {reason: 'no_servers'}
|
|
}
|
|
else {
|
|
if (context.JK.isNetworkError(arguments)) {
|
|
testSummary.final = {reason: 'no_network'}
|
|
}
|
|
else {
|
|
testSummary.final = {reason: 'rest_api_error'}
|
|
}
|
|
}
|
|
testFinishedAudio();
|
|
})
|
|
}, pauseForRecentScoresTime())
|
|
|
|
|
|
return false;
|
|
}
|
|
|
|
function updateProgress(throughput, showSubscore) {
|
|
|
|
var width = throughput * 100;
|
|
|
|
$currentScore.stop().data('showSubscore', showSubscore);
|
|
|
|
if (!showSubscore) {
|
|
$subscore.text('');
|
|
}
|
|
|
|
$currentScore.animate({
|
|
duration: 1000,
|
|
width: width + '%'
|
|
}, {
|
|
step: function (now, fx) {
|
|
if (showSubscore) {
|
|
var newWidth = ( 100 * parseFloat($currentScore.css('width')) / parseFloat($currentScore.parent().css('width')) );
|
|
$subscore.text((Math.round(newWidth * 10) / 10) + '%');
|
|
}
|
|
}
|
|
}).css('overflow', 'visible');
|
|
;
|
|
}
|
|
|
|
function primePumpTimeout(data) {
|
|
if(!isAttemptingPass()) {
|
|
logger.error("primePumpTimeout: already completed the test pass. indicates backend sent > 1 final event");
|
|
return;
|
|
}
|
|
clearPrimeGuard();
|
|
audioScoring = false;
|
|
logger.debug("the prime pump routine timed out")
|
|
primeDeferred.reject();
|
|
}
|
|
|
|
function primePumpComplete(data) {
|
|
if(!isAttemptingPass()) {
|
|
logger.error("primePumpComplete: already completed the test pass. indicates backend sent > 1 final event");
|
|
return;
|
|
}
|
|
|
|
if (data.progress === true) {
|
|
// waiting...
|
|
logger.debug("pump prime progress report");
|
|
setPrimeGuard();
|
|
}
|
|
else {
|
|
clearPrimeGuard();
|
|
// we could check for errors, but it's confusing to do so. we just want to let the backend figure out if
|
|
// the interface is wireless, or not
|
|
setTimeout(function () {
|
|
logger.debug("pump primed");
|
|
audioScoring = false;
|
|
primeDeferred.resolve();
|
|
}, 500); // give backend room to breath for timing/race issues
|
|
|
|
}
|
|
}
|
|
|
|
function networkTestCompleteAudio(data) {
|
|
if(!isAttemptingPass()) {
|
|
logger.error("networkTestComplete: already completed the test pass. indicates backend sent > 1 final event");
|
|
return;
|
|
}
|
|
|
|
var attempt = getCurrentAttemptAudio();
|
|
|
|
function refineTest(up) {
|
|
if (up === null) {
|
|
logger.debug("retrying test at size: " + numClientToTestAudio);
|
|
setTimeout(attemptTestPassAudio, 500); // wait a second to avoid race conditions with client/server comm
|
|
}
|
|
else if (up) {
|
|
if (numClientToTestAudio == gon.ftue_network_test_max_clients) {
|
|
attempt.reason = "success";
|
|
testFinishedAudio();
|
|
}
|
|
else if(hasGoneDown()) {
|
|
// this means we've gone up before... so don't go back down (i.e., creating a loop)
|
|
attempt.reason = "success";
|
|
testSummary.final = { reason: 'success', num_clients: numClientToTestAudio }
|
|
testFinishedAudio();
|
|
}
|
|
else {
|
|
numClientToTestAudio++;
|
|
logger.debug("increasing number of clients to " + numClientToTestAudio);
|
|
setTimeout(attemptTestPassAudio, 500); // wait a second to avoid race conditions with client/server comm
|
|
}
|
|
}
|
|
else {
|
|
// reduce numclients if we can
|
|
if (numClientToTestAudio == MINIMUM_ACCEPTABLE_SESSION_SIZE) {
|
|
// we are too low already. fail the user
|
|
attempt.reason = "minimum_client_threshold";
|
|
testFinishedAudio();
|
|
}
|
|
else if (numClientToTestAudio > STARTING_NUM_CLIENTS_AUDIO) {
|
|
// this means we've gone up before... so don't go back down (i.e., creating a loop)
|
|
attempt.reason = "success";
|
|
testSummary.final = { reason: 'success', num_clients: numClientToTestAudio - 1 }
|
|
testFinishedAudio();
|
|
}
|
|
else {
|
|
numClientToTestAudio--;
|
|
logger.debug("reducing number of clients to " + numClientToTestAudio);
|
|
setTimeout(attemptTestPassAudio, 500); // wait a second to avoid race conditions with client/server comm
|
|
}
|
|
}
|
|
}
|
|
|
|
attempt.backend_data = data;
|
|
|
|
if (data.progress === true) {
|
|
|
|
setBackendGuard();
|
|
|
|
var animate = true;
|
|
if (data.downthroughput && data.upthroughput) {
|
|
|
|
if (data.downthroughput > 0 || data.upthroughput > 0) {
|
|
attempt.received_progress = true;
|
|
animate = true;
|
|
}
|
|
|
|
if (attempt.received_progress) {
|
|
// take the lower
|
|
var throughput = data.downthroughput < data.upthroughput ? data.downthroughput : data.upthroughput;
|
|
|
|
bandwidthSamples.push(data.upthroughput);
|
|
|
|
updateProgress(throughput, true);
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
clearBackendGuard();
|
|
logger.debug("network test pass completed. data: ", data);
|
|
|
|
if (data.reason == "unreachable") {
|
|
logger.debug("network test: unreachable (STUN issue or similar)")
|
|
attempt.reason = data.reason;
|
|
testFinishedAudio();
|
|
}
|
|
else if (data.reason == "no-transmit") {
|
|
logger.debug("network test: no-transmit (STUN issue or similar)");
|
|
attempt.reason = data.reason;
|
|
testFinishedAudio();
|
|
}
|
|
else if (data.reason == "internal_error") {
|
|
// oops
|
|
logger.debug("network test: internal_error (client had a unexpected problem)");
|
|
attempt.reason = data.reason;
|
|
testFinishedAudio();
|
|
}
|
|
else if (data.reason == "remote_peer_cant_test") {
|
|
// old client
|
|
logger.debug("network test: remote_peer_cant_test (old client)")
|
|
attempt.reason = data.reason;
|
|
testFinishedAudio();
|
|
}
|
|
else if (data.reason == "server_comm_timeout") {
|
|
logger.debug("network test: server_comm_timeout (communication with server problem)")
|
|
attempt.reason = data.reason;
|
|
testFinishedAudio();
|
|
}
|
|
else {
|
|
if (!data.downthroughput || !data.upthroughput) {
|
|
// we have to assume this is bad. just not a reason we know about in code
|
|
logger.debug("network test: no test data (unknown issue? " + data.reason + ")")
|
|
attempt.reason = "invalid_response";
|
|
testFinishedAudio();
|
|
}
|
|
else {
|
|
// success... but we still have to verify if this data is within threshold
|
|
if (data.downthroughput < gon.ftue_packet_rate_treshold) {
|
|
logger.debug("network test: downthroughput too low. downthroughput: " + data.downthroughput + ", threshold: " + gon.ftue_packet_rate_treshold);
|
|
refineTest(false);
|
|
}
|
|
else if (data.upthroughput < gon.ftue_packet_rate_treshold) {
|
|
logger.debug("network test: upthroughput too low. upthroughput: " + data.upthroughput + ", threshold: " + gon.ftue_packet_rate_treshold);
|
|
refineTest(false);
|
|
}
|
|
else {
|
|
// true success. we can accept this score
|
|
logger.debug("network test: success")
|
|
refineTest(true);
|
|
}
|
|
}
|
|
}
|
|
|
|
// VRFS-1742
|
|
// context.jamClient.StopNetworkTest(serverClientId);
|
|
}
|
|
|
|
}
|
|
|
|
function networkTestCompleteVideo(data) {
|
|
if(!isAttemptingPass()) {
|
|
logger.error("networkTestCompleteVideo: already completed the test pass. indicates backend sent > 1 final event");
|
|
return;
|
|
}
|
|
|
|
var attempt = getCurrentAttemptVideo();
|
|
|
|
function refineTest(up) {
|
|
if (up === null) {
|
|
logger.debug("retrying video test at size: " + numClientToTestVideo);
|
|
setTimeout(attemptTestPassVideo, 500); // wait a second to avoid race conditions with client/server comm
|
|
}
|
|
else if (up) {
|
|
if (numClientToTestVideo == gon.ftue_network_test_max_clients) {
|
|
attempt.reason = "success";
|
|
testFinishedVideo();
|
|
}
|
|
else {
|
|
numClientToTestVideo++;
|
|
logger.debug("increasing number of clients to " + numClientToTestVideo);
|
|
setTimeout(attemptTestPassVideo, 500); // wait a second to avoid race conditions with client/server comm
|
|
}
|
|
}
|
|
else {
|
|
attempt.reason = "success";
|
|
testSummary.video_final = { reason: 'success', num_clients: numClientToTestVideo - 1 }
|
|
testFinishedVideo();
|
|
}
|
|
}
|
|
|
|
attempt.backend_data = data;
|
|
|
|
if (data.progress === true) {
|
|
|
|
setBackendGuard();
|
|
|
|
var animate = true;
|
|
if (data.downthroughput && data.upthroughput) {
|
|
|
|
if (data.downthroughput > 0 || data.upthroughput > 0) {
|
|
attempt.received_progress = true;
|
|
animate = true;
|
|
}
|
|
|
|
if (attempt.received_progress) {
|
|
// take the lower
|
|
var throughput = data.downthroughput < data.upthroughput ? data.downthroughput : data.upthroughput;
|
|
|
|
bandwidthSamples.push(data.upthroughput);
|
|
|
|
updateProgress(throughput, true);
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
clearBackendGuard();
|
|
logger.debug("network video test pass completed. data: ", data);
|
|
|
|
if (data.reason == "unreachable") {
|
|
logger.debug("video network test: unreachable (STUN issue or similar)")
|
|
attempt.reason = data.reason;
|
|
testFinishedVideo();
|
|
}
|
|
else if (data.reason == "no-transmit") {
|
|
logger.debug("video network test: no-transmit (STUN issue or similar)");
|
|
attempt.reason = data.reason;
|
|
testFinishedVideo();
|
|
}
|
|
else if (data.reason == "internal_error") {
|
|
// oops
|
|
logger.debug("video network test: internal_error (client had a unexpected problem)");
|
|
attempt.reason = data.reason;
|
|
testFinishedVideo();
|
|
}
|
|
else if (data.reason == "remote_peer_cant_test") {
|
|
// old client
|
|
logger.debug("video network test: remote_peer_cant_test (old client)")
|
|
attempt.reason = data.reason;
|
|
testFinishedVideo();
|
|
}
|
|
else if (data.reason == "server_comm_timeout") {
|
|
logger.debug("video network test: server_comm_timeout (communication with server problem)")
|
|
attempt.reason = data.reason;
|
|
testFinishedVideo();
|
|
}
|
|
else {
|
|
if (!data.downthroughput || !data.upthroughput) {
|
|
// we have to assume this is bad. just not a reason we know about in code
|
|
logger.debug("video network test: no test data (unknown issue? " + data.reason + ")")
|
|
attempt.reason = "invalid_response";
|
|
testFinishedVideo();
|
|
}
|
|
else {
|
|
// success... but we still have to verify if this data is within threshold
|
|
if (data.downthroughput < gon.ftue_packet_rate_treshold) {
|
|
logger.debug("video network test: downthroughput too low. downthroughput: " + data.downthroughput + ", threshold: " + gon.ftue_packet_rate_treshold);
|
|
refineTest(false);
|
|
}
|
|
else if (data.upthroughput < gon.ftue_packet_rate_treshold) {
|
|
logger.debug("video network test: upthroughput too low. upthroughput: " + data.upthroughput + ", threshold: " + gon.ftue_packet_rate_treshold);
|
|
refineTest(false);
|
|
}
|
|
else {
|
|
// true success. we can accept this score
|
|
logger.debug("vido network test: success")
|
|
refineTest(true);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
function networkTestTimeoutAudio(data) {
|
|
if(!isAttemptingPass()) {
|
|
logger.error("networkTestTimeout: already completed the audio test pass. indicates backend sent > 1 final event");
|
|
return;
|
|
}
|
|
|
|
clearBackendGuard();
|
|
|
|
logger.warn("network timeout when testing latency test: " + data);
|
|
|
|
var attempt = getCurrentAttemptAudio();
|
|
attempt.reason = 'timeout';
|
|
attempt.backend_data = data;
|
|
testFinishedAudio();
|
|
}
|
|
|
|
function networkTestTimeoutVideo(data) {
|
|
if(!isAttemptingPass()) {
|
|
logger.error("networkTestTimeout: already completed the video test pass. indicates backend sent > 1 final event");
|
|
return;
|
|
}
|
|
|
|
clearBackendGuard();
|
|
|
|
logger.warn("network timeout when testing latency test: " + data);
|
|
|
|
var attempt = getCurrentAttemptVideo();
|
|
attempt.reason = 'timeout';
|
|
attempt.backend_data = data;
|
|
testFinishedVideo();
|
|
}
|
|
|
|
function hasScoredNetworkSuccessfully() {
|
|
return testedSuccessfully;
|
|
}
|
|
|
|
function configureStartButton() {
|
|
if (audioScoring || videoScoring) {
|
|
$startNetworkTestBtn.text('NETWORK TEST RUNNING...').removeClass('button-orange').addClass('button-grey')
|
|
}
|
|
else {
|
|
$startNetworkTestBtn.text('START NETWORK TEST').removeClass('button-grey').addClass('button-orange');
|
|
}
|
|
}
|
|
|
|
function initializeNextButtonState() {
|
|
$dialog.setNextState(hasScoredNetworkSuccessfully() && !audioScoring && !videoScoring);
|
|
}
|
|
|
|
function initializeBackButtonState() {
|
|
$dialog.setBackState(!audioScoring && !videoScoring);
|
|
}
|
|
|
|
function beforeHide() {
|
|
|
|
}
|
|
|
|
function initializeVideoWatchButton() {
|
|
if (operatingSystem == "Win32") {
|
|
$watchVideo.attr('href', 'https://www.youtube.com/watch?v=rhAdCVuwhBc');
|
|
}
|
|
else {
|
|
$watchVideo.attr('href', 'https://www.youtube.com/watch?v=0r1py0AYJ4Y');
|
|
}
|
|
}
|
|
|
|
function initialize(_$step, _inGearWizard) {
|
|
$step = _$step;
|
|
inGearWizard = _inGearWizard;
|
|
|
|
$startNetworkTestBtn = $step.find('.start-network-test');
|
|
$foreverNetworkTestBtn = $step.find('.forever-network-test')
|
|
|
|
if ($startNetworkTestBtn.length == 0) throw 'no start network test button found in network-test'
|
|
|
|
$testResults = $step.find('.network-test-results');
|
|
$testScoreAudio = $step.find('.network-test-score-audio');
|
|
$scoredClientsAudio = $testScoreAudio.find('.scored-clients');
|
|
$testScoreVideo = $step.find('.network-test-score-video');
|
|
$scoredClientsVideo = $testScoreVideo.find('.scored-clients');
|
|
$testText = $step.find('.network-test-text');
|
|
$inProgressText = $step.find('.in-progress')
|
|
$audioResultText = $step.find('.audio-result')
|
|
$videoResultText = $step.find('.video-result')
|
|
$scoringBar = $step.find('.scoring-bar');
|
|
$goodMarker = $step.find('.good-marker');
|
|
$goodLine = $step.find('.good-line');
|
|
$currentScore = $step.find('.current-score');
|
|
|
|
$subscore = $step.find('.subscore');
|
|
$watchVideo = $step.find('.watch-video');
|
|
$container = $step.find('.network-test');
|
|
if(inGearWizard) {
|
|
$container.attr('data-mode', 'gear-wizard')
|
|
}
|
|
else {
|
|
$container.attr('data-mode', 'standalone')
|
|
}
|
|
$startNetworkTestBtn.on('click', function () {
|
|
forever = false;
|
|
prepareNetworkTest();
|
|
return false;
|
|
});
|
|
if(context.JK.currentUserAdmin) {
|
|
$foreverNetworkTestBtn.on('click', function() {
|
|
forever = true;
|
|
prepareNetworkTest();
|
|
return false;
|
|
}).show();
|
|
}
|
|
|
|
operatingSystem = context.JK.GetOSAsString();
|
|
|
|
initializeVideoWatchButton();
|
|
|
|
|
|
// if this network test is instantiated anywhere else than the gearWizard, or a dialog, then this will have to be expanded
|
|
if (inGearWizard) {
|
|
context.JK.HandleNetworkTestSuccessForPumpPrimingGW = function (data) {
|
|
primePumpComplete(data)
|
|
};
|
|
context.JK.HandleNetworkTestTimeoutForPumpPrimingGW = function (data) {
|
|
primePumpTimeout(data)
|
|
};
|
|
context.JK.HandleNetworkTestSuccessForGearWizard = function (data) {
|
|
if(audioScoring) {
|
|
networkTestCompleteAudio(data);
|
|
}
|
|
else if(videoScoring) {
|
|
networkTestCompleteVideo(data);
|
|
}
|
|
else {
|
|
logger.warn("unknown state in HandleNetworkTestSuccessForGearWizard");
|
|
}
|
|
|
|
}; // pin to global for bridge callback
|
|
context.JK.HandleNetworkTestTimeoutForGearWizard = function (data) {
|
|
if(audioScoring) {
|
|
networkTestTimeoutAudio(data);
|
|
}
|
|
else if(videoScoring) {
|
|
networkTestTimeoutVideo(data);
|
|
}
|
|
|
|
}; // pin to global for bridge callback
|
|
}
|
|
else {
|
|
context.JK.HandleNetworkTestSuccessForPumpPrimingDialog = function (data) {
|
|
primePumpComplete(data)
|
|
};
|
|
context.JK.HandleNetworkTestTimeoutForPumpPrimingDialog = function (data) {
|
|
primePumpTimeout(data)
|
|
};
|
|
context.JK.HandleNetworkTestSuccessForDialog = function (data) {
|
|
if(audioScoring) {
|
|
networkTestCompleteAudio(data);
|
|
}
|
|
else if(videoScoring) {
|
|
networkTestCompleteVideo(data);
|
|
}
|
|
else {
|
|
logger.warn("unknown state in HandleNetworkTestSuccessForDialog");
|
|
}
|
|
}; // pin to global for bridge callback
|
|
context.JK.HandleNetworkTestTimeoutForDialog = function (data) {
|
|
if(audioScoring) {
|
|
networkTestTimeoutAudio(data);
|
|
}
|
|
else if(videoScoring) {
|
|
networkTestTimeoutVideo(data);
|
|
}
|
|
}; // pin to global for bridge callback
|
|
}
|
|
|
|
}
|
|
|
|
this.isScoring = function () {
|
|
return audioScoring || videoScoring;
|
|
};
|
|
this.hasScoredNetworkSuccessfully = hasScoredNetworkSuccessfully;
|
|
this.initialize = initialize;
|
|
this.reset = reset;
|
|
this.cancel = cancel;
|
|
this.getLastNetworkFailure = getLastNetworkFailure;
|
|
this.haltScoring = haltScoring;
|
|
this.resumeScoring = resumeScoring;
|
|
|
|
this.NETWORK_TEST_START = NETWORK_TEST_START;
|
|
this.NETWORK_TEST_DONE = NETWORK_TEST_DONE;
|
|
this.NETWORK_TEST_FAIL = NETWORK_TEST_FAIL;
|
|
this.NETWORK_TEST_CANCEL = NETWORK_TEST_CANCEL;
|
|
|
|
return this;
|
|
}
|
|
})(window, jQuery); |