Permalink
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
454 lines (431 sloc) 14.7 KB
<!DOCTYPE html>
<html lang="en">
<head>
<script
src="/js/jquery-3.1.1.js"
crossorigin="anonymous"></script>
<meta charset="utf-8">
<style class="text/css">
table {
font-size: 12px;
border: 1px solid;
padding: 1px;
}
td {
border: 1px solid;
padding: 2px;
}
* {
box-sizing: border-box;
}
.row {
display: flex;
}
.column {
flex: 50%;
padding: 5px;
}
</style>
</head>
<body>
<audio id="alert-tone">
<source src="tester-alert.wav" type="audio/wav">
</audio>
<script>
var logIndex = 0;
var lastScenarioState = "";
var testerAlertTone = document.getElementById("alert-tone");
var alertPlayed = 0;
function result_to_string(r) {
if (r === undefined) {
return "Undefined";
}
else if (r["Fail"] !== undefined) {
return "Fail: " + r["Fail"];
}
else if (r["Pass"] !== undefined) {
return "Pass: " + r["Pass"];
}
else if (r === "Pending") {
return "Pending";
}
else if (r === "Running") {
return "Running";
}
else if (r["Skipped"] !== undefined) {
return "Skipped: " + r["Skipped"];
}
else {
return "Unknown";
}
}
function updateStuff(result) {
$("#serverid").html(result.server);
$("#jigid").html(result.jig);
$("#jigname").html(result.jig_name);
$("#jigdescription").html(result.jig_description);
$("#scenarioid").html(result.scenario);
$("#scenarioname").html(result.scenario_names[result.scenario]);
$("#scenariodescription").html(result.scenario_descriptions[result.scenario]);
$("#scenariostate").html(result.scenario_state);
if( result.scenario_state == "Running" ) {
$("#scenariostate")[0].style.backgroundColor = "yellow";
} else if( result.scenario_state == "Fail" ) {
$("#scenariostate")[0].style.backgroundColor = "red";
} else if( result.scenario_state == "Pass" ) {
$("#scenariostate")[0].style.backgroundColor = "green";
} else {
$("#scenariostate")[0].style.backgroundColor = "white";
}
// clear the status field
if( result.scenario_state == "Running" && lastScenarioState != "Running" ) {
$("#result_errcount").html( "Pending" );
$("#result_status").html( "Test Running" );
$("#result_status")[0].style.backgroundColor = "yellow";
test_errcount = 0;
alertPlayed = 0;
}
lastScenarioState = result.scenario_state;
var scenario_id = $('#scenarioselect').val() || result.scenario;
$("#scenarioselect").empty();
result.scenarios.forEach(function(e) {
$("#scenarioselect").append($('<option>', {
value: e,
selected: e === scenario_id
}).text(result.scenario_names[e]));
});
$('#tests').find('tbody').empty();
if (result.tests[scenario_id] !== undefined) {
result.tests[scenario_id].forEach(function(e) {
$('#tests').find('tbody')
.append($('<tr>')
.append($('<td>').text(e))
.append($('<td>').text(result.test_names[e]))
.append($('<td>').text(result.test_descriptions[e]))
.append($('<td>').text(result_to_string(result.test_results[e])))
);
});
}
}
function checksupply( supply_string, value ) {
var numregex = /[+-]?\d+(?:\.\d+)?/g;
if( supply_string.charAt(0) != 'I' ) {
nom_v = parseFloat(numregex.exec( supply_string )) * 1000.0;
if( supply_string.includes("1.2VE") ) { // special case the 1.2VE tolerance, it's an untrimmed LDO
if( (value > nom_v * 1.065) || (value < nom_v * 0.935) ) { // 6.5% tolerance
return "<p style=\"background-color:Red;\">FAIL</p>"
} else {
return "<p style=\"background-color:Green;\">PASS</p>"
}
} else if( nom_v != 12000 ) {
if( (value > nom_v * 1.045) || (value < nom_v * 0.955) ) { // 4.5% tolerance
return "<p style=\"background-color:Red;\">FAIL</p>"
} else {
return "<p style=\"background-color:Green;\">PASS</p>"
}
} else {
if( (value > nom_v * 1.10) || (value < nom_v * 0.90) ) { // 10% on adapter
return "<p style=\"background-color:Red;\">FAIL</p>"
} else {
return "<p style=\"background-color:Green;\">PASS</p>"
}
}
} else {
if( (value > 600) || (value < 8) ) { // amperage bounds in mA
return "<p style=\"background-color:Red;\">FAIL</p>"
} else {
return "<p style=\"background-color:Green;\">PASS</p>"
}
}
}
function parse_voltage(msg) {
var voltageNode = $("#voltage").find('tbody');
voltageNode.empty();
for( var supply in msg ) {
if( msg.hasOwnProperty( supply ) ) {
voltageNode
.append($('<tr>')
.append($('<td>').text(supply))
.append($('<td>').text( parseFloat(msg[supply]) / 1000 ))
.append($('<td>').html(checksupply( supply, msg[supply]) ))
);
}
}
}
function updateStatus(result) {
var statusNode = $("#status").find('tbody');
var devicedna;
var statusList = {};
var SUBMSG_CNT = 4;
var test_errcount = 0;
statusNode.empty(); // it's a full clean reparse every update...
result.forEach(function(e) {
d = new Date(0);
d.setUTCSeconds(e.timestamp.secs);
d.setMilliseconds(e.timestamp.nanos / 1000000);
var msg;
if( e.message[0] == '{' ) {
try {
msg = JSON.parse( e.message );
} catch(err) {
if( err == SyntaxError ) {
bar = 1;
}
}
if( msg.hasOwnProperty('start_time') ) {
// populate the jig ID fields and remember the DNA, always check on future records
$("#testerid_model").html(msg.model);
$("#testerid_rev").html(msg.rev);
$("#testerid_dna").html( parseInt(msg.dna).toString(16) );
$("#testerid_software").html( msg.tester_rev );
devicedna = parseInt(msg.dna);
$("#status_correctness").html( "No issues yet." );
$("#result_errcount").html( "Pending" );
$("#result_status").html( "Test Running" );
$("#result_status")[0].style.backgroundColor = "yellow";
can_update_errcount = 1;
} else if( msg.hasOwnProperty('end_time') ) {
test_errcount = test_errcount + msg.test_errcount;
$("#result_errcount").html( test_errcount );
if( test_errcount == 0 ) {
$("#result_status").html( "PASS" );
$("#result_status")[0].style.backgroundColor = "green";
} else {
$("#result_status").html( "FAIL" );
$("#result_status")[0].style.backgroundColor = "red";
}
} else {
if( msg.hasOwnProperty('subtest') ) {
if( parseInt(msg.dna) == devicedna ) {
dnastring = "Match"
} else if( parseInt(msg.dna) == -1 ) {
dnastring = "N/A"
} else {
dnastring = "Mismatch"
$("#status_correctness").html( "Inconsistent device DNA in logs " + msg.dna + " " + devicedna );
}
errcntobj = msg.msg[0];
var errcnt = -1;
if( errcntobj.hasOwnProperty('errcnt') ) {
errcnt = errcntobj.errcnt;
} else {
errcnt = -1;
}
if( !statusList.hasOwnProperty(msg.subtest) ) {
var submsg = [];
submsg.push(JSON.stringify(msg.msg));
if( msg.subtest == "LED" && !alertPlayed ) {
testerAlertTone.play();
alertPlayed = 1;
}
if( msg.subtest == "voltage" || msg.subtest == "power" ) {
parse_voltage(msg.msg[0]);
}
if( errcnt != -1 ) {
if( errcnt == 0 ) {
statusList[msg.subtest] = [dnastring, "PASS", submsg, d.toISOString()];
} else {
statusList[msg.subtest] = [dnastring, "FAIL", submsg, d.toISOString()];
}
} else {
statusList[msg.subtest] = [dnastring, "Running...", submsg, d.toISOString()];
}
} else {
if( errcnt != -1 ) {
if( errcnt == 0 ) {
statusList[msg.subtest][1] = "PASS";
} else {
statusList[msg.subtest][1] = "FAIL";
}
}
if( statusList[msg.subtest][2].length < SUBMSG_CNT ) {
statusList[msg.subtest][2].push( JSON.stringify(msg.msg) );
} else {
statusList[msg.subtest][2].shift();
statusList[msg.subtest][2].push( JSON.stringify(msg.msg) );
}
}
}
}
}
});
for( var key in statusList ) {
value = statusList[key];
var prettymsg = "";
value[2].forEach(function(e) {
prettymsg = prettymsg + "<br>" + e;
});
if( value[1] == "PASS" ) {
statusNode
.append($('<tr>')
.append($('<td>').text(key))
.append($('<td>').text(value[0]))
.append($('<td>').html("<p style=\"background-color:Green;\">" + value[1] + "</p>"))
.append($('<td>').html(prettymsg))
.append($('<td>').text(value[3]))
);
} else if( value[1] == "FAIL" ) {
statusNode
.append($('<tr>')
.append($('<td>').text(key))
.append($('<td>').text(value[0]))
.append($('<td>').html("<p style=\"background-color:Red;\">" + value[1] + "</p>"))
.append($('<td>').html(prettymsg))
.append($('<td>').text(value[3]))
);
} else {
statusNode
.append($('<tr>')
.append($('<td>').text(key))
.append($('<td>').text(value[0]))
.append($('<td>').html(value[1]))
.append($('<td>').html(prettymsg))
.append($('<td>').text(value[3]))
);
}
}
}
function updateLogs(result) {
var logNode = $("#logs").find('tbody');
result.forEach(function(e) {
d = new Date(0);
d.setUTCSeconds(e.timestamp.secs);
d.setMilliseconds(e.timestamp.nanos / 1000000);
logNode
.prepend($('<tr>')
.append($('<td>').text(e.message_class))
.append($('<td>').text(e.unit_type))
.append($('<td>').text(e.unit_id))
.append($('<td>').text(d))
.append($('<td>').text(e.message))
);
// When the next log request is made, don't include the recently-appended node.
logIndex++;
});
}
function queueUpdate(timeout) {
window.setTimeout(function() { fireUpdate(); }, timeout);
}
function fireUpdate() {
queueUpdate(500);
$.ajax({url: "/current.json", success: updateStuff});
$.ajax({url: "/log/current.json", success: updateStatus});
$.ajax({url: "/log.json?start=" + logIndex, success: updateLogs});
}
function changeScenario(e) {
var new_scenario_id = $('#scenarioselect').val();
$.ajax({url: "/scenario?" + new_scenario_id, success: function(){}});
return true;
}
$(document).ready(function() {
$('#scenarioselect').on("change", changeScenario);
$('#exit-button').on('click', function() {
$.ajax({
url: "/exit",
success: function(){}
});
});
$('#startstop-button').on('click', function() {
$.ajax({
url: "/start",
success: function(){}
});
});
fireUpdate();
})
</script>
<!-- HTML starts here -->
<div class="row">
<div class="column">
<div>Test state: <span id="scenariostate"></span></div>
<section id="testeridsection">
<div>Model: <span id="testerid_model"></span>, Rev: <span id="testerid_rev"></span>, Tester software rev: <span id="testerid_software"></span></div>
<div>DNA: <span id="testerid_dna"></span></div>
</section>
<table id="status">
<thead>
<tr>
<th>Subtest</th>
<th>DNA</th>
<th>Status</th>
<th>Message</th>
<th>Timestamp</th>
</tr>
</thead>
<tbody>
<tr></tr>
</tbody>
</table>
<table id="voltage">
<thead>
<tr>
<th>Supply</th>
<th>Measured</th>
<th>Status</th>
</tr>
</thead>
<tbody>
<tr></tr>
</tbody>
</table>
<section id="resultsection">
<div>Final error count: <span id="result_errcount"></span></div>
<div>Functional test status: <span id="result_status"></span></div>
</section>
<div>Test program correctness flag: <span id="status_correctness"></span></div>
<hr>
<section id="jigsection">
<div>Jig: <span id="jigid"></span></div>
<div>Jig name: <span id="jigname"></span></div>
<div>Jig description: <span id="jigdescription"></span></div>
</section>
<hr>
<section id="scenariolist"><label for="scenarioselect">Available Scenarios</label>
<select name="scenarioselect" id="scenarioselect" size="5">
</select>
</section>
<section id="scenariosection">
<div>Scenario: <span id="scenarioid"></span></div>
<div>Scenario name: <span id="scenarioname"></span></div>
<div>Scenario description: <span id="scenariodescription"></span></div>
</section>
<hr>
<div><input type="submit" id="exit-button" value="Quit Server"></div>
<hr>
</div>
<div class="column" style="background-color:#ddd;">
<div>Server ID: <span id="serverid"></span></div>
<div><input type="submit" id="startstop-button" value="Start Tests"></div>
<hr>
<table id="tests">
<thead>
<tr>
<th>Test ID</th>
<th>Name</th>
<th>Description</th>
<th>Result</th>
</tr>
</thead>
<tbody>
<tr>
</tr>
</tbody>
</table>
<hr>
<table id="logs">
<thead>
<tr>
<th>Class</th>
<th>Unit Type</th>
<th>Unit ID</th>
<th>Timestamp</th>
<th>Message</th>
</tr>
</thead>
<tbody>
<tr></tr>
</tbody>
</table>
</div>
</body>
</html>