mirror of
https://github.com/ansible/awx.git
synced 2026-03-06 03:01:06 -03:30
Adds network UI test framework
This adds a test framework to drive UI tests from the client instead of injecting events from the websocket. Tests consist of a pair of snapshots (before and after the test) and a list of UI events to process. Tests are run using a FSM in the client that controls the resetting of state to the snapshot, injecting the events into the UI, recording test coverage, and reporting tests to the server. * Adds design for event trace table * Adds design for a coverage tracking table * Adds models for EventTrace and Coverage * Adds trace_id to recording messages * Adds design for TopologySnapshot table * Adds order to TopologySnapshot table * Adds TopologySnapshot table * Adds Snapshot message when recordings are started and stoppped * Adds models for tracking test cases and test results * Adds designs for a test runner FSM * Updates test management commands with new schema * Adds download recording button * Adds models to track tests * Adds ui test runner * Adds id and client to TestResult design * Adds id and client to TestResult * Update message types * Stores test results and code coverage from the test runner * Adds tool to generate a test coverage report * Adds APIs for tests and code coverage * Adds per-test-case coverage reports * Breaks out coverage for loading the modules from the tests * Re-raises server-side errors * Captures errors during tests * Adds defaults for host name and host type * Disables test FSM trace storage * Adds support for sending server error message to the client * Resets the UI flags, history, and toolbox contents between tests * Adds istanbul instrumentation to network-ui
This commit is contained in:
@@ -176,23 +176,18 @@ function MultipleMessage(sender, messages) {
|
||||
}
|
||||
exports.MultipleMessage = MultipleMessage;
|
||||
|
||||
function Coverage(sender, coverage) {
|
||||
this.msg_type = "Coverage";
|
||||
this.sender = sender;
|
||||
this.coverage = coverage;
|
||||
}
|
||||
exports.Coverage = Coverage;
|
||||
|
||||
function MouseEvent(sender, x, y, type) {
|
||||
function MouseEvent(sender, x, y, type, trace_id) {
|
||||
this.msg_type = "MouseEvent";
|
||||
this.sender = sender;
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.type = type;
|
||||
this.trace_id = trace_id;
|
||||
}
|
||||
exports.MouseEvent = MouseEvent;
|
||||
|
||||
function MouseWheelEvent(sender, delta, deltaX, deltaY, type, metaKey) {
|
||||
function MouseWheelEvent(sender, delta, deltaX, deltaY, type, metaKey, trace_id) {
|
||||
this.msg_type = "MouseWheelEvent";
|
||||
this.sender = sender;
|
||||
this.delta = delta;
|
||||
@@ -200,10 +195,11 @@ function MouseWheelEvent(sender, delta, deltaX, deltaY, type, metaKey) {
|
||||
this.deltaY = deltaY;
|
||||
this.type = type;
|
||||
this.originalEvent = {metaKey: metaKey};
|
||||
this.trace_id = trace_id;
|
||||
}
|
||||
exports.MouseWheelEvent = MouseWheelEvent;
|
||||
|
||||
function KeyEvent(sender, key, keyCode, type, altKey, shiftKey, ctrlKey, metaKey) {
|
||||
function KeyEvent(sender, key, keyCode, type, altKey, shiftKey, ctrlKey, metaKey, trace_id) {
|
||||
this.msg_type = "KeyEvent";
|
||||
this.sender = sender;
|
||||
this.key = key;
|
||||
@@ -213,6 +209,7 @@ function KeyEvent(sender, key, keyCode, type, altKey, shiftKey, ctrlKey, metaKey
|
||||
this.shiftKey = shiftKey;
|
||||
this.ctrlKey = ctrlKey;
|
||||
this.metaKey = metaKey;
|
||||
this.trace_id = trace_id;
|
||||
}
|
||||
exports.KeyEvent = KeyEvent;
|
||||
|
||||
@@ -224,24 +221,27 @@ function TouchEvent(sender, type, touches) {
|
||||
}
|
||||
exports.TouchEvent = TouchEvent;
|
||||
|
||||
function StartRecording(sender) {
|
||||
function StartRecording(sender, trace_id) {
|
||||
this.msg_type = "StartRecording";
|
||||
this.sender = sender;
|
||||
this.trace_id = trace_id;
|
||||
}
|
||||
exports.StartRecording = StartRecording;
|
||||
|
||||
function StopRecording(sender) {
|
||||
function StopRecording(sender, trace_id) {
|
||||
this.msg_type = "StopRecording";
|
||||
this.sender = sender;
|
||||
this.trace_id = trace_id;
|
||||
}
|
||||
exports.StopRecording = StopRecording;
|
||||
|
||||
function ViewPort(sender, scale, panX, panY) {
|
||||
function ViewPort(sender, scale, panX, panY, trace_id) {
|
||||
this.msg_type = "ViewPort";
|
||||
this.sender = sender;
|
||||
this.scale = scale;
|
||||
this.panX = panX;
|
||||
this.panY = panY;
|
||||
this.trace_id = trace_id;
|
||||
}
|
||||
exports.ViewPort = ViewPort;
|
||||
|
||||
@@ -446,3 +446,54 @@ function ChannelTrace(from_fsm, to_fsm, sent_message_type) {
|
||||
this.sent_message_type = sent_message_type;
|
||||
}
|
||||
exports.ChannelTrace = ChannelTrace;
|
||||
|
||||
function Snapshot(sender, devices, links, groups, streams, order, trace_id) {
|
||||
this.msg_type = 'Snapshot';
|
||||
this.sender = 0;
|
||||
this.devices = devices;
|
||||
this.links = links;
|
||||
this.groups = groups;
|
||||
this.streams = streams;
|
||||
this.order = order;
|
||||
this.trace_id = trace_id;
|
||||
}
|
||||
exports.Snapshot = Snapshot;
|
||||
|
||||
function EnableTest() {
|
||||
this.msg_type = "EnableTest";
|
||||
}
|
||||
exports.EnableTest = EnableTest;
|
||||
|
||||
function DisableTest() {
|
||||
this.msg_type = "DisableTest";
|
||||
}
|
||||
exports.DisableTest = DisableTest;
|
||||
|
||||
function StartTest() {
|
||||
this.msg_type = "StartTest";
|
||||
}
|
||||
exports.StartTest = StartTest;
|
||||
|
||||
function TestCompleted() {
|
||||
this.msg_type = "TestCompleted";
|
||||
}
|
||||
exports.TestCompleted = TestCompleted;
|
||||
|
||||
function TestResult(sender, id, name, result, date, code_under_test) {
|
||||
this.msg_type = "TestResult";
|
||||
this.sender = sender;
|
||||
this.id = id;
|
||||
this.name = name;
|
||||
this.result = result;
|
||||
this.date = date;
|
||||
this.code_under_test = code_under_test;
|
||||
}
|
||||
exports.TestResult = TestResult;
|
||||
|
||||
function Coverage(sender, coverage, result_id) {
|
||||
this.msg_type = "Coverage";
|
||||
this.sender = sender;
|
||||
this.coverage = coverage;
|
||||
this.result_id = result_id;
|
||||
}
|
||||
exports.Coverage = Coverage;
|
||||
|
||||
@@ -36,8 +36,12 @@ Device.prototype.toJSON = function () {
|
||||
x: this.x,
|
||||
y: this.y,
|
||||
type: this.type,
|
||||
interfaces: this.interfaces,
|
||||
processes: this.processes};
|
||||
interfaces: this.interfaces.map(function (x) {
|
||||
return x.toJSON();
|
||||
}),
|
||||
processes: this.processes.map(function (x) {
|
||||
return x.toJSON();
|
||||
})};
|
||||
};
|
||||
|
||||
Device.prototype.is_selected = function (x, y) {
|
||||
@@ -726,6 +730,11 @@ function Process(id, name, type, x, y) {
|
||||
}
|
||||
exports.Process = Process;
|
||||
|
||||
Process.prototype.toJSON = function () {
|
||||
return {id: this.id,
|
||||
name: this.name};
|
||||
};
|
||||
|
||||
function Stream(id, from_device, to_device, label) {
|
||||
this.id = id;
|
||||
this.from_device = from_device;
|
||||
@@ -919,3 +928,21 @@ Stream.prototype.start_arc_angle_rad = function () {
|
||||
Stream.prototype.start_arc_angle = function () {
|
||||
return this.start_arc_angle_rad() * 180 / Math.PI;
|
||||
};
|
||||
|
||||
function Test(name, event_trace, fsm_trace, pre_test_snapshot, post_test_snapshot) {
|
||||
this.name = name;
|
||||
this.event_trace = event_trace;
|
||||
this.fsm_trace = fsm_trace;
|
||||
this.pre_test_snapshot = pre_test_snapshot;
|
||||
this.post_test_snapshot = post_test_snapshot;
|
||||
}
|
||||
exports.Test = Test;
|
||||
|
||||
function TestResult(id, name, result, date, code_under_test) {
|
||||
this.id = id;
|
||||
this.name = name;
|
||||
this.result = result;
|
||||
this.date = date;
|
||||
this.code_under_test = code_under_test;
|
||||
}
|
||||
exports.TestResult = TestResult;
|
||||
|
||||
@@ -33,6 +33,7 @@ var inventoryToolboxClipPath = require('./inventory.toolbox.clip.path.directive.
|
||||
var statusLight = require('./status.light.directive.js');
|
||||
var taskStatus = require('./task.status.directive.js');
|
||||
var debug = require('./debug.directive.js');
|
||||
var test_results = require('./test_results.directive.js');
|
||||
var awxNetworkUI = require('./network.ui.directive.js');
|
||||
|
||||
var networkUI = angular.module('networkUI', [
|
||||
@@ -70,6 +71,7 @@ var networkUI = angular.module('networkUI', [
|
||||
.directive('awxNetInventoryToolboxClipPath', inventoryToolboxClipPath.inventoryToolboxClipPath)
|
||||
.directive('awxNetStatusLight', statusLight.statusLight)
|
||||
.directive('awxNetTaskStatus', taskStatus.taskStatus)
|
||||
.directive('awxNetTestResults', test_results.test_results)
|
||||
.directive('awxNetworkUi', awxNetworkUI.awxNetworkUI);
|
||||
|
||||
exports.networkUI = networkUI;
|
||||
|
||||
@@ -15,6 +15,7 @@ var stream_fsm = require('./stream.fsm.js');
|
||||
var group = require('./group.js');
|
||||
var buttons = require('./buttons.js');
|
||||
var time = require('./time.js');
|
||||
var test_fsm = require('./test.fsm.js');
|
||||
var util = require('./util.js');
|
||||
var models = require('./models.js');
|
||||
var messages = require('./messages.js');
|
||||
@@ -22,7 +23,7 @@ var svg_crowbar = require('./svg-crowbar.js');
|
||||
var ReconnectingWebSocket = require('reconnectingwebsocket');
|
||||
|
||||
var NetworkUIController = function($scope, $document, $location, $window, $http,
|
||||
$q, $state, ProcessErrors) {
|
||||
$q, $state, ProcessErrors, ConfigService) {
|
||||
|
||||
window.scope = $scope;
|
||||
var i = 0;
|
||||
@@ -96,6 +97,7 @@ var NetworkUIController = function($scope, $document, $location, $window, $http,
|
||||
$scope.group_id_seq = util.natural_numbers(0);
|
||||
$scope.message_id_seq = util.natural_numbers(0);
|
||||
$scope.stream_id_seq = util.natural_numbers(0);
|
||||
$scope.test_result_id_seq = util.natural_numbers(0);
|
||||
$scope.overall_toolbox_collapsed = false;
|
||||
$scope.time_pointer = -1;
|
||||
$scope.frame = 0;
|
||||
@@ -108,6 +110,14 @@ var NetworkUIController = function($scope, $document, $location, $window, $http,
|
||||
$scope.groups = [];
|
||||
$scope.processes = [];
|
||||
$scope.configurations = [];
|
||||
$scope.tests = [];
|
||||
$scope.current_tests = [];
|
||||
$scope.current_test = null;
|
||||
$scope.testing = false;
|
||||
$scope.version = null;
|
||||
$scope.test_events = [];
|
||||
$scope.test_results = [];
|
||||
$scope.test_errors = [];
|
||||
$scope.streams = [];
|
||||
$scope.view_port = {'x': 0,
|
||||
'y': 0,
|
||||
@@ -118,7 +128,9 @@ var NetworkUIController = function($scope, $document, $location, $window, $http,
|
||||
$scope.trace_id = $scope.trace_id_seq();
|
||||
|
||||
$scope.send_trace_message = function (message) {
|
||||
console.log(message);
|
||||
if (!$scope.recording) {
|
||||
return;
|
||||
}
|
||||
message.sender = $scope.client_id;
|
||||
message.trace_id = $scope.trace_id;
|
||||
message.message_id = $scope.message_id_seq();
|
||||
@@ -148,6 +160,7 @@ var NetworkUIController = function($scope, $document, $location, $window, $http,
|
||||
$scope.site_controller = new fsm.FSMController($scope, "site_fsm", site_fsm.Disable, $scope);
|
||||
$scope.buttons_controller = new fsm.FSMController($scope, "buttons_fsm", buttons.Start, $scope);
|
||||
$scope.time_controller = new fsm.FSMController($scope, "time_fsm", time.Start, $scope);
|
||||
$scope.test_controller = new fsm.FSMController($scope, "test_fsm", test_fsm.Start, $scope);
|
||||
$scope.app_toolbox_controller = new fsm.FSMController($scope, "toolbox_fsm", toolbox_fsm.Start, $scope);
|
||||
|
||||
//App Toolbox Setup
|
||||
@@ -185,6 +198,12 @@ var NetworkUIController = function($scope, $document, $location, $window, $http,
|
||||
let host = hosts[i];
|
||||
console.log(host);
|
||||
host.data = jsyaml.safeLoad(host.variables);
|
||||
if (host.data.type == undefined) {
|
||||
host.data.type = 'unknown';
|
||||
}
|
||||
if (host.data.name == undefined) {
|
||||
host.data.name = host.name;
|
||||
}
|
||||
var device = new models.Device(0, host.data.name, 0, 0, host.data.type, host.id, host.variables);
|
||||
device.icon = true;
|
||||
$scope.inventory_toolbox.items.push(device);
|
||||
@@ -288,9 +307,13 @@ var NetworkUIController = function($scope, $document, $location, $window, $http,
|
||||
$scope.mode_controller.delegate_channel = new fsm.Channel($scope.mode_controller,
|
||||
$scope.time_controller,
|
||||
$scope);
|
||||
$scope.test_controller.delegate_channel = new fsm.Channel($scope.test_controller,
|
||||
$scope.mode_controller,
|
||||
$scope);
|
||||
|
||||
|
||||
$scope.first_channel = new fsm.Channel(null,
|
||||
$scope.mode_controller,
|
||||
$scope.test_controller,
|
||||
$scope);
|
||||
|
||||
var getMouseEventResult = function (mouseEvent) {
|
||||
@@ -464,7 +487,7 @@ var NetworkUIController = function($scope, $document, $location, $window, $http,
|
||||
$scope.onMouseDown = function ($event) {
|
||||
$scope.normalize_mouse_event($event);
|
||||
if ($scope.recording) {
|
||||
$scope.send_control_message(new messages.MouseEvent($scope.client_id, $event.x, $event.y, $event.type));
|
||||
$scope.send_control_message(new messages.MouseEvent($scope.client_id, $event.x, $event.y, $event.type, $scope.trace_id));
|
||||
}
|
||||
$scope.last_event = $event;
|
||||
$scope.first_channel.send('MouseDown', $event);
|
||||
@@ -475,7 +498,7 @@ var NetworkUIController = function($scope, $document, $location, $window, $http,
|
||||
$scope.onMouseUp = function ($event) {
|
||||
$scope.normalize_mouse_event($event);
|
||||
if ($scope.recording) {
|
||||
$scope.send_control_message(new messages.MouseEvent($scope.client_id, $event.x, $event.y, $event.type));
|
||||
$scope.send_control_message(new messages.MouseEvent($scope.client_id, $event.x, $event.y, $event.type, $scope.trace_id));
|
||||
}
|
||||
$scope.last_event = $event;
|
||||
$scope.first_channel.send('MouseUp', $event);
|
||||
@@ -486,7 +509,7 @@ var NetworkUIController = function($scope, $document, $location, $window, $http,
|
||||
$scope.onMouseLeave = function ($event) {
|
||||
$scope.normalize_mouse_event($event);
|
||||
if ($scope.recording) {
|
||||
$scope.send_control_message(new messages.MouseEvent($scope.client_id, $event.x, $event.y, $event.type));
|
||||
$scope.send_control_message(new messages.MouseEvent($scope.client_id, $event.x, $event.y, $event.type, $scope.trace_id));
|
||||
}
|
||||
$scope.onMouseLeaveResult = getMouseEventResult($event);
|
||||
$scope.cursor.hidden = true;
|
||||
@@ -496,7 +519,7 @@ var NetworkUIController = function($scope, $document, $location, $window, $http,
|
||||
$scope.onMouseMove = function ($event) {
|
||||
$scope.normalize_mouse_event($event);
|
||||
if ($scope.recording) {
|
||||
$scope.send_control_message(new messages.MouseEvent($scope.client_id, $event.x, $event.y, $event.type));
|
||||
$scope.send_control_message(new messages.MouseEvent($scope.client_id, $event.x, $event.y, $event.type, $scope.trace_id));
|
||||
}
|
||||
//var coords = getCrossBrowserElementCoords($event);
|
||||
$scope.cursor.hidden = false;
|
||||
@@ -513,7 +536,7 @@ var NetworkUIController = function($scope, $document, $location, $window, $http,
|
||||
$scope.onMouseOver = function ($event) {
|
||||
$scope.normalize_mouse_event($event);
|
||||
if ($scope.recording) {
|
||||
$scope.send_control_message(new messages.MouseEvent($scope.client_id, $event.x, $event.y, $event.type));
|
||||
$scope.send_control_message(new messages.MouseEvent($scope.client_id, $event.x, $event.y, $event.type, $scope.trace_id));
|
||||
}
|
||||
$scope.onMouseOverResult = getMouseEventResult($event);
|
||||
$scope.cursor.hidden = false;
|
||||
@@ -529,11 +552,11 @@ var NetworkUIController = function($scope, $document, $location, $window, $http,
|
||||
var deltaY = $event.deltaY;
|
||||
// console.log([$event, delta, deltaX, deltaY]);
|
||||
if ($scope.recording) {
|
||||
$scope.send_control_message(new messages.MouseWheelEvent($scope.client_id, delta, deltaX, deltaY, $event.type, $event.originalEvent.metaKey));
|
||||
$scope.send_control_message(new messages.MouseWheelEvent($scope.client_id, delta, deltaX, deltaY, $event.type, $event.originalEvent.metaKey, $scope.trace_id));
|
||||
}
|
||||
$scope.last_event = $event;
|
||||
$scope.first_channel.send('MouseWheel', [$event, delta, deltaX, deltaY]);
|
||||
event.preventDefault();
|
||||
$event.preventDefault();
|
||||
};
|
||||
|
||||
$scope.onKeyDown = function ($event) {
|
||||
@@ -545,7 +568,8 @@ var NetworkUIController = function($scope, $document, $location, $window, $http,
|
||||
$event.altKey,
|
||||
$event.shiftKey,
|
||||
$event.ctrlKey,
|
||||
$event.metaKey));
|
||||
$event.metaKey,
|
||||
$scope.trace_id));
|
||||
}
|
||||
$scope.last_event = $event;
|
||||
$scope.last_key = $event.key;
|
||||
@@ -653,6 +677,7 @@ var NetworkUIController = function($scope, $document, $location, $window, $http,
|
||||
};
|
||||
|
||||
$scope.onRenameContextButton = function (button) {
|
||||
console.log(button.name);
|
||||
$scope.context_menus[0].enabled = false;
|
||||
$scope.first_channel.send("LabelEdit", {});
|
||||
};
|
||||
@@ -690,14 +715,31 @@ var NetworkUIController = function($scope, $document, $location, $window, $http,
|
||||
console.log(button.name);
|
||||
$scope.recording = ! $scope.recording;
|
||||
if ($scope.recording) {
|
||||
$scope.trace_id = $scope.trace_id_seq();
|
||||
$scope.send_control_message(new messages.MultipleMessage($scope.client_id,
|
||||
[new messages.StartRecording($scope.client_id),
|
||||
[new messages.StartRecording($scope.client_id, $scope.trace_id),
|
||||
new messages.ViewPort($scope.client_id,
|
||||
$scope.current_scale,
|
||||
$scope.panX,
|
||||
$scope.panY)]));
|
||||
$scope.panY,
|
||||
$scope.trace_id),
|
||||
new messages.Snapshot($scope.client_id,
|
||||
$scope.devices,
|
||||
$scope.links,
|
||||
$scope.groups,
|
||||
$scope.streams,
|
||||
0,
|
||||
$scope.trace_id)]));
|
||||
} else {
|
||||
$scope.send_control_message(new messages.StopRecording($scope.client_id));
|
||||
$scope.send_control_message(new messages.MultipleMessage($scope.client_id,
|
||||
[new messages.Snapshot($scope.client_id,
|
||||
$scope.devices,
|
||||
$scope.links,
|
||||
$scope.groups,
|
||||
$scope.streams,
|
||||
1,
|
||||
$scope.trace_id),
|
||||
new messages.StopRecording($scope.client_id, $scope.trace_id)]));
|
||||
}
|
||||
};
|
||||
|
||||
@@ -789,6 +831,25 @@ var NetworkUIController = function($scope, $document, $location, $window, $http,
|
||||
console.log(button.label);
|
||||
window.open("/network_ui/download_trace?topology_id=" + $scope.topology_id + "&trace_id=" + $scope.trace_id + "&client_id=" + $scope.client_id);
|
||||
};
|
||||
|
||||
$scope.onDownloadRecordingButton = function (button) {
|
||||
console.log(button.label);
|
||||
window.open("/network_ui/download_recording?topology_id=" + $scope.topology_id + "&trace_id=" + $scope.trace_id + "&client_id=" + $scope.client_id);
|
||||
};
|
||||
|
||||
$scope.onUploadTestButton = function (button) {
|
||||
console.log(button.name);
|
||||
window.open("/network_ui/upload_test", "_top");
|
||||
};
|
||||
|
||||
$scope.onRunTestsButton = function (button) {
|
||||
console.log(button.name);
|
||||
|
||||
$scope.test_results = [];
|
||||
$scope.current_tests = $scope.tests.slice();
|
||||
$scope.first_channel.send("EnableTest", new messages.EnableTest());
|
||||
};
|
||||
|
||||
// Buttons
|
||||
var button_offset = 200;
|
||||
|
||||
@@ -802,6 +863,9 @@ var NetworkUIController = function($scope, $document, $location, $window, $http,
|
||||
new models.Button("CONFIGURE", button_offset + 520, 48, 90, 30, $scope.onConfigureButton, $scope),
|
||||
new models.Button("EXPORT YAML", button_offset + 620, 48, 120, 30, $scope.onExportYamlButton, $scope),
|
||||
new models.Button("DOWNLOAD TRACE", button_offset + 750, 48, 150, 30, $scope.onDownloadTraceButton, $scope),
|
||||
new models.Button("DOWNLOAD RECORDING", button_offset + 910, 48, 170, 30, $scope.onDownloadRecordingButton, $scope),
|
||||
new models.Button("UPLOAD TEST", button_offset + 10, 88, 100, 30, $scope.onUploadTestButton, $scope),
|
||||
new models.Button("RUN TESTS", button_offset + 120, 88, 100, 30, $scope.onRunTestsButton, $scope),
|
||||
];
|
||||
|
||||
var LAYERS_X = 160;
|
||||
@@ -1429,6 +1493,8 @@ var NetworkUIController = function($scope, $document, $location, $window, $http,
|
||||
//Erase the existing state
|
||||
$scope.devices = [];
|
||||
$scope.links = [];
|
||||
$scope.groups = [];
|
||||
$scope.streams = [];
|
||||
|
||||
var device_map = {};
|
||||
var device_interface_map = {};
|
||||
@@ -1634,12 +1700,6 @@ var NetworkUIController = function($scope, $document, $location, $window, $http,
|
||||
}
|
||||
};
|
||||
|
||||
$scope.send_coverage = function () {
|
||||
console.log("Sending coverage");
|
||||
if (typeof(window.__coverage__) !== "undefined" && window.__coverage__ !== null) {
|
||||
$scope.send_control_message(new messages.Coverage($scope.client_id, window.__coverage__));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
$scope.control_socket.onmessage = function(message) {
|
||||
@@ -1743,6 +1803,112 @@ var NetworkUIController = function($scope, $document, $location, $window, $http,
|
||||
map.set(key, stream.offset + 1);
|
||||
}
|
||||
};
|
||||
|
||||
setInterval( function () {
|
||||
var test_event = null;
|
||||
if ($scope.test_events.length > 0) {
|
||||
test_event = $scope.test_events.shift();
|
||||
console.log(test_event);
|
||||
test_event.sender = 0;
|
||||
try {
|
||||
$scope.first_channel.send(test_event.msg_type, test_event);
|
||||
} catch (err) {
|
||||
$scope.test_errors.push(err);
|
||||
}
|
||||
}
|
||||
$scope.$apply();
|
||||
}, 10);
|
||||
|
||||
ConfigService
|
||||
.getConfig()
|
||||
.then(function(config){
|
||||
$scope.version = config.version;
|
||||
});
|
||||
|
||||
$scope.reset_coverage = function() {
|
||||
var i = null;
|
||||
var coverage = null;
|
||||
var f = null;
|
||||
if (typeof(window.__coverage__) !== "undefined" && window.__coverage__ !== null) {
|
||||
for (f in window.__coverage__) {
|
||||
coverage = window.__coverage__[f];
|
||||
for (i in coverage.b) {
|
||||
coverage.b[i] = [0, 0];
|
||||
}
|
||||
for (i in coverage.f) {
|
||||
coverage.f[i] = 0;
|
||||
}
|
||||
for (i in coverage.s) {
|
||||
coverage.s[i] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
$scope.reset_flags = function () {
|
||||
$scope.debug = {'hidden': true};
|
||||
$scope.hide_buttons = false;
|
||||
$scope.hide_links = false;
|
||||
$scope.hide_interfaces = false;
|
||||
$scope.hide_groups = false;
|
||||
};
|
||||
|
||||
|
||||
$scope.reset_fsm_state = function () {
|
||||
$scope.null_controller.state = null_fsm.Start;
|
||||
$scope.null_controller.state.start($scope.null_controller);
|
||||
$scope.hotkeys_controller.state = hotkeys.Start;
|
||||
$scope.hotkeys_controller.state.start($scope.hotkeys_controller);
|
||||
$scope.view_controller.state = view.Start;
|
||||
$scope.view_controller.state.start($scope.view_controller);
|
||||
$scope.device_detail_controller.state = device_detail_fsm.Start;
|
||||
$scope.device_detail_controller.state.start($scope.device_detail_controller);
|
||||
$scope.move_controller.state = move.Start;
|
||||
$scope.move_controller.state.start($scope.move_controller);
|
||||
$scope.link_controller.state = link.Start;
|
||||
$scope.link_controller.state.start($scope.link_controller);
|
||||
$scope.stream_controller.state = stream_fsm.Start;
|
||||
$scope.stream_controller.state.start($scope.stream_controller);
|
||||
$scope.group_controller.state = group.Start;
|
||||
$scope.group_controller.state.start($scope.group_controller);
|
||||
$scope.rack_controller.state = rack_fsm.Disable;
|
||||
$scope.rack_controller.state.start($scope.rack_controller);
|
||||
$scope.site_controller.state = site_fsm.Disable;
|
||||
$scope.site_controller.state.start($scope.site_controller);
|
||||
$scope.buttons_controller.state = buttons.Start;
|
||||
$scope.buttons_controller.state.start($scope.buttons_controller);
|
||||
$scope.time_controller.state = time.Start;
|
||||
$scope.time_controller.state.start($scope.time_controller);
|
||||
$scope.app_toolbox_controller.state = toolbox_fsm.Start;
|
||||
$scope.app_toolbox_controller.state.start($scope.app_toolbox_controller);
|
||||
$scope.inventory_toolbox_controller.state = toolbox_fsm.Start;
|
||||
$scope.inventory_toolbox_controller.state.start($scope.inventory_toolbox_controller);
|
||||
$scope.rack_toolbox_controller.state = toolbox_fsm.Start;
|
||||
$scope.rack_toolbox_controller.state.start($scope.rack_toolbox_controller);
|
||||
$scope.site_toolbox_controller.state = toolbox_fsm.Start;
|
||||
$scope.site_toolbox_controller.state.start($scope.site_toolbox_controller);
|
||||
$scope.mode_controller.state = mode_fsm.Start;
|
||||
$scope.mode_controller.state.start($scope.mode_controller);
|
||||
};
|
||||
|
||||
$scope.reset_history = function () {
|
||||
$scope.history = [];
|
||||
};
|
||||
|
||||
$scope.reset_toolboxes = function () {
|
||||
$scope.app_toolbox.items = [];
|
||||
$scope.app_toolbox.items.push(new models.Process(0, 'BGP', 'process', 0, 0));
|
||||
$scope.app_toolbox.items.push(new models.Process(0, 'OSPF', 'process', 0, 0));
|
||||
$scope.app_toolbox.items.push(new models.Process(0, 'STP', 'process', 0, 0));
|
||||
$scope.app_toolbox.items.push(new models.Process(0, 'Zero Pipeline', 'process', 0, 0));
|
||||
|
||||
for(i = 0; i < $scope.app_toolbox.items.length; i++) {
|
||||
$scope.app_toolbox.items[i].icon = true;
|
||||
}
|
||||
$scope.inventory_toolbox.items = [];
|
||||
$scope.rack_toolbox.items = [];
|
||||
$scope.site_toolbox.items = [];
|
||||
};
|
||||
};
|
||||
|
||||
exports.NetworkUIController = NetworkUIController;
|
||||
|
||||
@@ -116,6 +116,7 @@
|
||||
ng-attr-transform="translate({{context_menus[0].x}}, {{context_menus[0].y}})">
|
||||
</g>
|
||||
<g awx-net-debug></g>
|
||||
<g awx-net-test-results></g>
|
||||
<g awx-net-cursor></g>
|
||||
<g ng-repeat="touch in touches">
|
||||
<g awx-net-touch></g>
|
||||
|
||||
@@ -766,3 +766,8 @@
|
||||
.NetworkUI__contextMenuButton-pressed{
|
||||
fill:@button-body-hover;
|
||||
}
|
||||
|
||||
.NetworkUI__test_results {
|
||||
fill: @light-background;
|
||||
stroke: @dark-widget-detail;
|
||||
}
|
||||
|
||||
160
awx/ui/client/src/network-ui/test.fsm.js
Normal file
160
awx/ui/client/src/network-ui/test.fsm.js
Normal file
@@ -0,0 +1,160 @@
|
||||
var inherits = require('inherits');
|
||||
var fsm = require('./fsm.js');
|
||||
var messages = require('./messages.js');
|
||||
var models = require('./models.js');
|
||||
|
||||
function _State () {
|
||||
}
|
||||
inherits(_State, fsm._State);
|
||||
|
||||
|
||||
function _Disabled () {
|
||||
this.name = 'Disabled';
|
||||
}
|
||||
inherits(_Disabled, _State);
|
||||
var Disabled = new _Disabled();
|
||||
exports.Disabled = Disabled;
|
||||
|
||||
function _Start () {
|
||||
this.name = 'Start';
|
||||
}
|
||||
inherits(_Start, _State);
|
||||
var Start = new _Start();
|
||||
exports.Start = Start;
|
||||
|
||||
function _Running () {
|
||||
this.name = 'Running';
|
||||
}
|
||||
inherits(_Running, _State);
|
||||
var Running = new _Running();
|
||||
exports.Running = Running;
|
||||
|
||||
function _Loading () {
|
||||
this.name = 'Loading';
|
||||
}
|
||||
inherits(_Loading, _State);
|
||||
var Loading = new _Loading();
|
||||
exports.Loading = Loading;
|
||||
|
||||
function _Ready () {
|
||||
this.name = 'Ready';
|
||||
}
|
||||
inherits(_Ready, _State);
|
||||
var Ready = new _Ready();
|
||||
exports.Ready = Ready;
|
||||
|
||||
function _Reporting () {
|
||||
this.name = 'Reporting';
|
||||
}
|
||||
inherits(_Reporting, _State);
|
||||
var Reporting = new _Reporting();
|
||||
exports.Reporting = Reporting;
|
||||
|
||||
|
||||
|
||||
|
||||
_Disabled.prototype.onEnableTest = function (controller) {
|
||||
|
||||
controller.changeState(Ready);
|
||||
};
|
||||
_Disabled.prototype.onEnableTest.transitions = ['Ready'];
|
||||
|
||||
|
||||
|
||||
_Start.prototype.start = function (controller) {
|
||||
|
||||
controller.changeState(Disabled);
|
||||
|
||||
};
|
||||
_Start.prototype.start.transitions = ['Disabled'];
|
||||
|
||||
|
||||
|
||||
_Running.prototype.onTestCompleted = function (controller) {
|
||||
|
||||
controller.changeState(Reporting);
|
||||
};
|
||||
_Running.prototype.onTestCompleted.transitions = ['Reporting'];
|
||||
|
||||
_Reporting.prototype.start = function (controller) {
|
||||
|
||||
var test_result = null;
|
||||
controller.scope.replay = false;
|
||||
controller.scope.disconnected = false;
|
||||
controller.scope.recording = false;
|
||||
var result = "passed";
|
||||
if (controller.scope.test_errors.length > 0) {
|
||||
result = "errored";
|
||||
}
|
||||
test_result = new models.TestResult(controller.scope.test_result_id_seq(),
|
||||
controller.scope.current_test.name,
|
||||
result,
|
||||
new Date().toISOString(),
|
||||
controller.scope.version);
|
||||
controller.scope.test_results.push(test_result);
|
||||
console.log(["Reporting test", test_result.name, test_result.id]);
|
||||
controller.scope.send_control_message(new messages.TestResult(controller.scope.client_id,
|
||||
test_result.id,
|
||||
test_result.name,
|
||||
test_result.result,
|
||||
test_result.date,
|
||||
test_result.code_under_test));
|
||||
if (typeof(window.__coverage__) !== "undefined" && window.__coverage__ !== null) {
|
||||
console.log(["Reporting coverage", test_result.name, test_result.id]);
|
||||
controller.scope.send_control_message(new messages.Coverage(controller.scope.client_id, window.__coverage__, test_result.id));
|
||||
}
|
||||
controller.changeState(Loading);
|
||||
};
|
||||
_Reporting.prototype.start.transitions = ['Loading'];
|
||||
|
||||
|
||||
_Loading.prototype.start = function (controller) {
|
||||
|
||||
if (controller.scope.current_tests.length === 0) {
|
||||
controller.changeState(Disabled);
|
||||
} else {
|
||||
console.log("Starting test");
|
||||
controller.scope.current_test = controller.scope.current_tests.shift();
|
||||
controller.scope.onSnapshot(controller.scope.current_test.pre_test_snapshot);
|
||||
controller.scope.replay = true;
|
||||
controller.scope.disconnected = true;
|
||||
controller.scope.test_errors = [];
|
||||
controller.scope.test_events = controller.scope.current_test.event_trace.slice();
|
||||
controller.scope.test_events.push(new messages.TestCompleted());
|
||||
controller.scope.reset_coverage();
|
||||
controller.scope.reset_flags();
|
||||
controller.scope.reset_fsm_state();
|
||||
controller.scope.reset_history();
|
||||
controller.scope.reset_toolboxes();
|
||||
controller.changeState(Running);
|
||||
}
|
||||
};
|
||||
_Loading.prototype.start.transitions = ['Running'];
|
||||
|
||||
|
||||
|
||||
_Ready.prototype.onDisableTest = function (controller) {
|
||||
|
||||
controller.changeState(Disabled);
|
||||
};
|
||||
_Ready.prototype.onDisableTest.transitions = ['Disabled'];
|
||||
|
||||
_Ready.prototype.start = function (controller) {
|
||||
|
||||
var load_id = controller.scope.test_result_id_seq();
|
||||
|
||||
console.log(["Reporting Load", load_id]);
|
||||
controller.scope.send_control_message(new messages.TestResult(controller.scope.client_id,
|
||||
load_id,
|
||||
"Load",
|
||||
"passed",
|
||||
new Date().toISOString(),
|
||||
controller.scope.version));
|
||||
if (typeof(window.__coverage__) !== "undefined" && window.__coverage__ !== null) {
|
||||
console.log(["Reporting Load Coverage", load_id]);
|
||||
controller.scope.send_control_message(new messages.Coverage(controller.scope.client_id, window.__coverage__, load_id));
|
||||
}
|
||||
|
||||
controller.changeState(Loading);
|
||||
};
|
||||
_Ready.prototype.start.transitions = ['Loading'];
|
||||
8
awx/ui/client/src/network-ui/test_results.directive.js
Normal file
8
awx/ui/client/src/network-ui/test_results.directive.js
Normal file
@@ -0,0 +1,8 @@
|
||||
/* Copyright (c) 2018 Red Hat, Inc. */
|
||||
|
||||
const templateUrl = require('~network-ui/test_results.partial.svg');
|
||||
|
||||
function test_results () {
|
||||
return { restrict: 'A', templateUrl};
|
||||
}
|
||||
exports.test_results = test_results;
|
||||
14
awx/ui/client/src/network-ui/test_results.partial.svg
Normal file
14
awx/ui/client/src/network-ui/test_results.partial.svg
Normal file
@@ -0,0 +1,14 @@
|
||||
<g ng-if="test_results.length > 0">
|
||||
<g ng-attr-transform="translate({{graph.width - 300}}, {{graph.height-500}})">
|
||||
<rect class="NetworkUI__test_results" width="280" height="480" x="0" y="0">
|
||||
</rect>
|
||||
<g transform="translate(20, 20)">
|
||||
<text class="NetworkUI__text">Test Results {{version}}</text>
|
||||
<g ng-repeat="result in test_results track by $index">
|
||||
<g ng-attr-transform="translate(0, {{$index * 20 + 20}})">
|
||||
<text class="NetworkUI__text">{{result.name}} - {{result.result}}</text>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
@@ -3,6 +3,7 @@ var inherits = require('inherits');
|
||||
var fsm = require('./fsm.js');
|
||||
var messages = require('./messages.js');
|
||||
var util = require('./util.js');
|
||||
var models = require('./models.js');
|
||||
|
||||
function _State () {
|
||||
}
|
||||
@@ -539,3 +540,23 @@ _Present.prototype.undo = function(controller) {
|
||||
controller.changeState(Past);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
_Present.prototype.onTestCase = function(controller, msg_type, message) {
|
||||
console.log([msg_type, message]);
|
||||
if ('runnable' in message[1]) {
|
||||
if (!message[1].runnable) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
controller.scope.tests.push(new models.Test(message[0],
|
||||
message[1].event_trace,
|
||||
[],
|
||||
message[1].snapshots[0],
|
||||
message[1].snapshots[1]));
|
||||
};
|
||||
|
||||
_Present.prototype.onError = function(controller, msg_type, message) {
|
||||
console.log(["onError", msg_type, message]);
|
||||
throw new Error("ServerError: " + message);
|
||||
};
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
var angular = require('angular');
|
||||
|
||||
var tower = angular.module('tower', ['tablesUI', 'networkUI', 'ui.router']);
|
||||
var tower = angular.module('tower', ['networkUI', 'ui.router']);
|
||||
|
||||
tower.config(function($stateProvider, $urlRouterProvider) {
|
||||
|
||||
|
||||
Reference in New Issue
Block a user