mirror of
https://github.com/ansible/awx.git
synced 2026-01-17 20:51:21 -03:30
Refactors network_ui_test out of network_ui
* Separates test messages from application messages * Removes test runner and groups, processes, and streams from network_ui * Adds network_ui_test * Fixes routing for network_ui_test * Removes coverage_report tool from network_ui * Fixes network_ui_test test workflow * Sets width and height of the page during tests
This commit is contained in:
parent
b29a605800
commit
766bee3753
@ -1,4 +1,6 @@
|
||||
from channels.routing import route
|
||||
from awx.network_ui.routing import channel_routing as network_ui_routing
|
||||
from awx.network_ui_test.routing import channel_routing as network_ui_test_routing
|
||||
|
||||
|
||||
channel_routing = [
|
||||
@ -7,6 +9,6 @@ channel_routing = [
|
||||
route("websocket.receive", "awx.main.consumers.ws_receive", path=r'^/websocket/$'),
|
||||
]
|
||||
|
||||
from awx.network_ui.routing import channel_routing as network_routing
|
||||
|
||||
channel_routing += network_routing
|
||||
channel_routing += network_ui_routing
|
||||
channel_routing += network_ui_test_routing
|
||||
|
||||
@ -2,20 +2,12 @@
|
||||
# In consumers.py
|
||||
from channels import Group, Channel
|
||||
from channels.sessions import channel_session
|
||||
from awx.network_ui.models import Topology, Device, Link, Client, TopologyHistory, MessageType, Interface
|
||||
from awx.network_ui.models import Group as DeviceGroup
|
||||
from awx.network_ui.models import GroupDevice as GroupDeviceMap
|
||||
from awx.network_ui.models import Process, Stream
|
||||
from awx.network_ui.models import Toolbox, ToolboxItem
|
||||
from awx.network_ui.models import FSMTrace, EventTrace, Coverage, TopologySnapshot
|
||||
from awx.network_ui.models import Topology, Device, Link, Client, Interface
|
||||
from awx.network_ui.models import TopologyInventory
|
||||
from awx.network_ui.models import TestCase, TestResult, CodeUnderTest, Result
|
||||
import urlparse
|
||||
from django.core.exceptions import ObjectDoesNotExist
|
||||
from django.db.models import Q
|
||||
from collections import defaultdict
|
||||
import logging
|
||||
from django.utils.dateparse import parse_datetime
|
||||
|
||||
|
||||
from awx.network_ui.utils import transform_dict
|
||||
@ -71,16 +63,6 @@ class _Persistence(object):
|
||||
return
|
||||
message_type = data[0]
|
||||
message_value = data[1]
|
||||
try:
|
||||
message_type_id = MessageType.objects.get(name=message_type).pk
|
||||
except ObjectDoesNotExist:
|
||||
logger.warning("Unsupported message %s: no message type", message_type)
|
||||
return
|
||||
TopologyHistory(topology_id=topology_id,
|
||||
client_id=client_id,
|
||||
message_type_id=message_type_id,
|
||||
message_id=data[1].get('message_id', 0),
|
||||
message_data=message['text']).save()
|
||||
handler = self.get_handler(message_type)
|
||||
if handler is not None:
|
||||
try:
|
||||
@ -127,9 +109,6 @@ class _Persistence(object):
|
||||
def onDeviceInventoryUpdate(self, device, topology_id, client_id):
|
||||
Device.objects.filter(topology_id=topology_id, id=device['id']).update(host_id=device['host_id'])
|
||||
|
||||
def onGroupInventoryUpdate(self, group, topology_id, client_id):
|
||||
DeviceGroup.objects.filter(topology_id=topology_id, id=group['id']).update(inventory_group_id=group['group_id'])
|
||||
|
||||
def onDeviceLabelEdit(self, device, topology_id, client_id):
|
||||
Device.objects.filter(topology_id=topology_id, id=device['id']).update(name=device['name'])
|
||||
|
||||
@ -182,34 +161,6 @@ class _Persistence(object):
|
||||
to_interface_id=Interface.objects.get(device_id=device_map[link['to_device_id']],
|
||||
id=link['to_interface_id']).pk).delete()
|
||||
|
||||
def onProcessCreate(self, process, topology_id, client_id):
|
||||
Process.objects.get_or_create(device_id=Device.objects.get(id=process['device_id'],
|
||||
topology_id=topology_id).pk,
|
||||
id=process['id'],
|
||||
defaults=dict(name=process['name'], process_type=process['type']))
|
||||
(Device.objects
|
||||
.filter(id=process['device_id'],
|
||||
topology_id=topology_id,
|
||||
interface_id_seq__lt=process['id'])
|
||||
.update(interface_id_seq=process['id']))
|
||||
|
||||
def onStreamCreate(self, stream, topology_id, client_id):
|
||||
device_map = dict(Device.objects
|
||||
.filter(topology_id=topology_id, id__in=[stream['from_id'], stream['to_id']])
|
||||
.values_list('id', 'pk'))
|
||||
logger.info("onStreamCreate %s", stream)
|
||||
Stream.objects.get_or_create(id=stream['id'],
|
||||
label='',
|
||||
from_device_id=device_map[stream['from_id']],
|
||||
to_device_id=device_map[stream['to_id']])
|
||||
(Topology.objects
|
||||
.filter(topology_id=topology_id, stream_id_seq__lt=stream['id'])
|
||||
.update(stream_id_seq=stream['id']))
|
||||
|
||||
def onCopySite(self, site, topology_id, client_id):
|
||||
site_toolbox, _ = Toolbox.objects.get_or_create(name="Site")
|
||||
ToolboxItem(toolbox=site_toolbox, data=json.dumps(site['site'])).save()
|
||||
|
||||
def onDeviceSelected(self, message_value, topology_id, client_id):
|
||||
'Ignore DeviceSelected messages'
|
||||
pass
|
||||
@ -234,121 +185,6 @@ class _Persistence(object):
|
||||
else:
|
||||
logger.warning("Unsupported message %s", message['msg_type'])
|
||||
|
||||
def onCoverageRequest(self, coverage, topology_id, client_id):
|
||||
pass
|
||||
|
||||
def onTestResult(self, test_result, topology_id, client_id):
|
||||
xyz, _, rest = test_result['code_under_test'].partition('-')
|
||||
commits_since, _, commit_hash = rest.partition('-')
|
||||
commit_hash = commit_hash.strip('g')
|
||||
|
||||
x, y, z = [int(i) for i in xyz.split('.')]
|
||||
|
||||
code_under_test, _ = CodeUnderTest.objects.get_or_create(version_x=x,
|
||||
version_y=y,
|
||||
version_z=z,
|
||||
commits_since=int(commits_since),
|
||||
commit_hash=commit_hash)
|
||||
|
||||
tr = TestResult(id=test_result['id'],
|
||||
result_id=Result.objects.get(name=test_result['result']).pk,
|
||||
test_case_id=TestCase.objects.get(name=test_result['name']).pk,
|
||||
code_under_test_id=code_under_test.pk,
|
||||
client_id=client_id,
|
||||
time=parse_datetime(test_result['date']))
|
||||
tr.save()
|
||||
|
||||
|
||||
def onCoverage(self, coverage, topology_id, client_id):
|
||||
Coverage(test_result_id=TestResult.objects.get(id=coverage['result_id'], client_id=client_id).pk,
|
||||
coverage_data=json.dumps(coverage['coverage'])).save()
|
||||
|
||||
def onStartRecording(self, recording, topology_id, client_id):
|
||||
pass
|
||||
|
||||
def onStopRecording(self, recording, topology_id, client_id):
|
||||
pass
|
||||
|
||||
def write_event(self, event, topology_id, client_id):
|
||||
if event.get('save', True):
|
||||
EventTrace(trace_session_id=event['trace_id'],
|
||||
event_data=json.dumps(event),
|
||||
message_id=event['message_id'],
|
||||
client_id=client_id).save()
|
||||
|
||||
onViewPort = write_event
|
||||
onMouseEvent = write_event
|
||||
onTouchEvent = write_event
|
||||
onMouseWheelEvent = write_event
|
||||
onKeyEvent = write_event
|
||||
|
||||
def onGroupCreate(self, group, topology_id, client_id):
|
||||
logger.info("GroupCreate %s %s %s", group['id'], group['name'], group['type'])
|
||||
group = transform_dict(dict(x1='x1',
|
||||
y1='y1',
|
||||
x2='x2',
|
||||
y2='y2',
|
||||
name='name',
|
||||
id='id',
|
||||
type='group_type',
|
||||
group_id='inventory_group_id'), group)
|
||||
d, _ = DeviceGroup.objects.get_or_create(topology_id=topology_id, id=group['id'], defaults=group)
|
||||
d.x1 = group['x1']
|
||||
d.y1 = group['y1']
|
||||
d.x2 = group['x2']
|
||||
d.y2 = group['y2']
|
||||
d.group_type = group['group_type']
|
||||
d.save()
|
||||
(Topology.objects
|
||||
.filter(topology_id=topology_id, group_id_seq__lt=group['id'])
|
||||
.update(group_id_seq=group['id']))
|
||||
|
||||
def onGroupDestroy(self, group, topology_id, client_id):
|
||||
DeviceGroup.objects.filter(topology_id=topology_id, id=group['id']).delete()
|
||||
|
||||
def onGroupLabelEdit(self, group, topology_id, client_id):
|
||||
DeviceGroup.objects.filter(topology_id=topology_id, id=group['id']).update(name=group['name'])
|
||||
|
||||
def onGroupMove(self, group, topology_id, client_id):
|
||||
DeviceGroup.objects.filter(topology_id=topology_id, id=group['id']).update(x1=group['x1'],
|
||||
y1=group['y1'],
|
||||
x2=group['x2'],
|
||||
y2=group['y2'])
|
||||
|
||||
def onGroupMembership(self, group_membership, topology_id, client_id):
|
||||
members = set(group_membership['members'])
|
||||
group = DeviceGroup.objects.get(topology_id=topology_id, id=group_membership['id'])
|
||||
existing = set(GroupDeviceMap.objects.filter(group=group).values_list('device__id', flat=True))
|
||||
new = members - existing
|
||||
removed = existing - members
|
||||
|
||||
GroupDeviceMap.objects.filter(group__group_id=group.group_id,
|
||||
device__id__in=list(removed)).delete()
|
||||
|
||||
device_map = dict(Device.objects.filter(topology_id=topology_id, id__in=list(new)).values_list('id', 'device_id'))
|
||||
new_entries = []
|
||||
for i in new:
|
||||
new_entries.append(GroupDeviceMap(group=group,
|
||||
device_id=device_map[i]))
|
||||
if new_entries:
|
||||
GroupDeviceMap.objects.bulk_create(new_entries)
|
||||
|
||||
def onFSMTrace(self, message_value, diagram_id, client_id):
|
||||
FSMTrace(trace_session_id=message_value['trace_id'],
|
||||
fsm_name=message_value['fsm_name'],
|
||||
from_state=message_value['from_state'],
|
||||
to_state=message_value['to_state'],
|
||||
order=message_value['order'],
|
||||
client_id=client_id,
|
||||
message_type=message_value['recv_message_type'] or "none").save()
|
||||
|
||||
def onSnapshot(self, snapshot, topology_id, client_id):
|
||||
TopologySnapshot(trace_session_id=snapshot['trace_id'],
|
||||
snapshot_data=json.dumps(snapshot),
|
||||
order=snapshot['order'],
|
||||
client_id=client_id,
|
||||
topology_id=topology_id).save()
|
||||
|
||||
|
||||
persistence = _Persistence()
|
||||
|
||||
@ -385,45 +221,23 @@ def ws_connect(message):
|
||||
panY='panY',
|
||||
scale='scale',
|
||||
link_id_seq='link_id_seq',
|
||||
device_id_seq='device_id_seq',
|
||||
group_id_seq='group_id_seq'), topology.__dict__)
|
||||
device_id_seq='device_id_seq'), topology.__dict__)
|
||||
|
||||
message.reply_channel.send({"text": json.dumps(["Topology", topology_data])})
|
||||
send_snapshot(message.reply_channel, topology_id)
|
||||
send_history(message.reply_channel, topology_id)
|
||||
send_toolboxes(message.reply_channel)
|
||||
send_tests(message.reply_channel)
|
||||
|
||||
|
||||
def send_toolboxes(channel):
|
||||
for toolbox_item in ToolboxItem.objects.filter(toolbox__name__in=['Process', 'Device', 'Rack', 'Site']).values('toolbox__name', 'data'):
|
||||
item = dict(toolbox_name=toolbox_item['toolbox__name'],
|
||||
data=toolbox_item['data'])
|
||||
channel.send({"text": json.dumps(["ToolboxItem", item])})
|
||||
|
||||
|
||||
def send_tests(channel):
|
||||
for name, test_case_data in TestCase.objects.all().values_list('name', 'test_case_data'):
|
||||
channel.send({"text": json.dumps(["TestCase", [name, json.loads(test_case_data)]])})
|
||||
|
||||
|
||||
def send_snapshot(channel, topology_id):
|
||||
interfaces = defaultdict(list)
|
||||
processes = defaultdict(list)
|
||||
|
||||
for i in (Interface.objects
|
||||
.filter(device__topology_id=topology_id)
|
||||
.values()):
|
||||
interfaces[i['device_id']].append(i)
|
||||
for i in (Process.objects
|
||||
.filter(device__topology_id=topology_id)
|
||||
.values()):
|
||||
processes[i['device_id']].append(i)
|
||||
devices = list(Device.objects
|
||||
.filter(topology_id=topology_id).values())
|
||||
for device in devices:
|
||||
device['interfaces'] = interfaces[device['device_id']]
|
||||
device['processes'] = processes[device['device_id']]
|
||||
|
||||
links = [dict(id=x['id'],
|
||||
name=x['name'],
|
||||
@ -440,44 +254,12 @@ def send_snapshot(channel, topology_id):
|
||||
'to_device__id',
|
||||
'from_interface__id',
|
||||
'to_interface__id'))]
|
||||
groups = list(DeviceGroup.objects
|
||||
.filter(topology_id=topology_id).values())
|
||||
group_map = {g['id']: g for g in groups}
|
||||
for group_id, device_id in GroupDeviceMap.objects.filter(group__topology_id=topology_id).values_list('group__id', 'device__id'):
|
||||
if 'members' not in group_map[group_id]:
|
||||
group_map[group_id]['members'] = [device_id]
|
||||
else:
|
||||
group_map[group_id]['members'].append(device_id)
|
||||
|
||||
streams = [dict(id=x['id'],
|
||||
label=x['label'],
|
||||
from_id=x['from_device__id'],
|
||||
to_id=x['to_device__id'])
|
||||
for x in list(Stream.objects
|
||||
.filter(Q(from_device__topology_id=topology_id) |
|
||||
Q(to_device__topology_id=topology_id)).values('id',
|
||||
'label',
|
||||
'from_device__id',
|
||||
'to_device__id'))]
|
||||
|
||||
snapshot = dict(sender=0,
|
||||
devices=devices,
|
||||
links=links,
|
||||
groups=groups,
|
||||
streams=streams)
|
||||
links=links)
|
||||
channel.send({"text": json.dumps(["Snapshot", snapshot])})
|
||||
|
||||
|
||||
def send_history(channel, topology_id):
|
||||
history = list(TopologyHistory.objects
|
||||
.filter(topology_id=topology_id)
|
||||
.exclude(message_type__name__in=HISTORY_MESSAGE_IGNORE_TYPES)
|
||||
.exclude(undone=True)
|
||||
.order_by('pk')
|
||||
.values_list('message_data', flat=True)[:1000])
|
||||
channel.send({"text": json.dumps(["History", history])})
|
||||
|
||||
|
||||
@channel_session
|
||||
def ws_message(message):
|
||||
# Send to all clients editing the topology
|
||||
|
||||
147
awx/network_ui/migrations/0005_auto_20180306_1837.py
Normal file
147
awx/network_ui/migrations/0005_auto_20180306_1837.py
Normal file
@ -0,0 +1,147 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Generated by Django 1.11.7 on 2018-03-06 18:37
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import migrations
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('network_ui', '0004_auto_20180304_2122'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.RemoveField(
|
||||
model_name='coverage',
|
||||
name='test_result',
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name='eventtrace',
|
||||
name='client',
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name='fsmtrace',
|
||||
name='client',
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name='group',
|
||||
name='topology',
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name='groupdevice',
|
||||
name='device',
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name='groupdevice',
|
||||
name='group',
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name='process',
|
||||
name='device',
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name='stream',
|
||||
name='from_device',
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name='stream',
|
||||
name='to_device',
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name='testresult',
|
||||
name='client',
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name='testresult',
|
||||
name='code_under_test',
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name='testresult',
|
||||
name='result',
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name='testresult',
|
||||
name='test_case',
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name='toolboxitem',
|
||||
name='toolbox',
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name='topologyhistory',
|
||||
name='client',
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name='topologyhistory',
|
||||
name='message_type',
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name='topologyhistory',
|
||||
name='topology',
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name='topologysnapshot',
|
||||
name='client',
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name='device',
|
||||
name='process_id_seq',
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name='topology',
|
||||
name='group_id_seq',
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name='topology',
|
||||
name='stream_id_seq',
|
||||
),
|
||||
migrations.DeleteModel(
|
||||
name='CodeUnderTest',
|
||||
),
|
||||
migrations.DeleteModel(
|
||||
name='Coverage',
|
||||
),
|
||||
migrations.DeleteModel(
|
||||
name='EventTrace',
|
||||
),
|
||||
migrations.DeleteModel(
|
||||
name='FSMTrace',
|
||||
),
|
||||
migrations.DeleteModel(
|
||||
name='Group',
|
||||
),
|
||||
migrations.DeleteModel(
|
||||
name='GroupDevice',
|
||||
),
|
||||
migrations.DeleteModel(
|
||||
name='MessageType',
|
||||
),
|
||||
migrations.DeleteModel(
|
||||
name='Process',
|
||||
),
|
||||
migrations.DeleteModel(
|
||||
name='Result',
|
||||
),
|
||||
migrations.DeleteModel(
|
||||
name='Stream',
|
||||
),
|
||||
migrations.DeleteModel(
|
||||
name='TestCase',
|
||||
),
|
||||
migrations.DeleteModel(
|
||||
name='TestResult',
|
||||
),
|
||||
migrations.DeleteModel(
|
||||
name='Toolbox',
|
||||
),
|
||||
migrations.DeleteModel(
|
||||
name='ToolboxItem',
|
||||
),
|
||||
migrations.DeleteModel(
|
||||
name='TopologyHistory',
|
||||
),
|
||||
migrations.DeleteModel(
|
||||
name='TopologySnapshot',
|
||||
),
|
||||
]
|
||||
@ -11,7 +11,6 @@ class Device(models.Model):
|
||||
id = models.IntegerField()
|
||||
device_type = models.CharField(max_length=200, blank=True)
|
||||
interface_id_seq = models.IntegerField(default=0,)
|
||||
process_id_seq = models.IntegerField(default=0,)
|
||||
host_id = models.IntegerField(default=0,)
|
||||
|
||||
def __unicode__(self):
|
||||
@ -38,8 +37,6 @@ class Topology(models.Model):
|
||||
panY = models.FloatField()
|
||||
device_id_seq = models.IntegerField(default=0,)
|
||||
link_id_seq = models.IntegerField(default=0,)
|
||||
group_id_seq = models.IntegerField(default=0,)
|
||||
stream_id_seq = models.IntegerField(default=0,)
|
||||
|
||||
def __unicode__(self):
|
||||
return self.name
|
||||
@ -50,26 +47,6 @@ class Client(models.Model):
|
||||
client_id = models.AutoField(primary_key=True,)
|
||||
|
||||
|
||||
class TopologyHistory(models.Model):
|
||||
|
||||
topology_history_id = models.AutoField(primary_key=True,)
|
||||
topology = models.ForeignKey('Topology',)
|
||||
client = models.ForeignKey('Client',)
|
||||
message_type = models.ForeignKey('MessageType',)
|
||||
message_id = models.IntegerField()
|
||||
message_data = models.TextField()
|
||||
undone = models.BooleanField(default=False,)
|
||||
|
||||
|
||||
class MessageType(models.Model):
|
||||
|
||||
message_type_id = models.AutoField(primary_key=True,)
|
||||
name = models.CharField(max_length=200, blank=True)
|
||||
|
||||
def __unicode__(self):
|
||||
return self.name
|
||||
|
||||
|
||||
class Interface(models.Model):
|
||||
|
||||
interface_id = models.AutoField(primary_key=True,)
|
||||
@ -81,132 +58,8 @@ class Interface(models.Model):
|
||||
return self.name
|
||||
|
||||
|
||||
class Group(models.Model):
|
||||
|
||||
group_id = models.AutoField(primary_key=True,)
|
||||
id = models.IntegerField()
|
||||
name = models.CharField(max_length=200, blank=True)
|
||||
x1 = models.IntegerField()
|
||||
y1 = models.IntegerField()
|
||||
x2 = models.IntegerField()
|
||||
y2 = models.IntegerField()
|
||||
topology = models.ForeignKey('Topology',)
|
||||
group_type = models.CharField(max_length=200, blank=True)
|
||||
inventory_group_id = models.IntegerField(default=0,)
|
||||
|
||||
|
||||
class GroupDevice(models.Model):
|
||||
|
||||
group_device_id = models.AutoField(primary_key=True,)
|
||||
group = models.ForeignKey('Group',)
|
||||
device = models.ForeignKey('Device',)
|
||||
|
||||
|
||||
class Stream(models.Model):
|
||||
|
||||
stream_id = models.AutoField('Stream', primary_key=True,)
|
||||
from_device = models.ForeignKey('Device', related_name='from_stream',)
|
||||
to_device = models.ForeignKey('Device', related_name='to_stream',)
|
||||
label = models.CharField(max_length=200, blank=True)
|
||||
id = models.IntegerField(default=0,)
|
||||
|
||||
|
||||
class Process(models.Model):
|
||||
|
||||
process_id = models.AutoField(primary_key=True,)
|
||||
device = models.ForeignKey('Device',)
|
||||
name = models.CharField(max_length=200, blank=True)
|
||||
process_type = models.CharField(max_length=200, blank=True)
|
||||
id = models.IntegerField(default=0,)
|
||||
|
||||
|
||||
class Toolbox(models.Model):
|
||||
|
||||
toolbox_id = models.AutoField(primary_key=True,)
|
||||
name = models.CharField(max_length=200, blank=True)
|
||||
|
||||
|
||||
class ToolboxItem(models.Model):
|
||||
|
||||
toolbox_item_id = models.AutoField(primary_key=True,)
|
||||
toolbox = models.ForeignKey('Toolbox',)
|
||||
data = models.TextField()
|
||||
|
||||
|
||||
class FSMTrace(models.Model):
|
||||
|
||||
fsm_trace_id = models.AutoField(primary_key=True,)
|
||||
fsm_name = models.CharField(max_length=200, blank=True)
|
||||
from_state = models.CharField(max_length=200, blank=True)
|
||||
to_state = models.CharField(max_length=200, blank=True)
|
||||
message_type = models.CharField(max_length=200, blank=True)
|
||||
client = models.ForeignKey('Client',)
|
||||
trace_session_id = models.IntegerField(default=0,)
|
||||
order = models.IntegerField(default=0,)
|
||||
|
||||
|
||||
class TopologyInventory(models.Model):
|
||||
|
||||
topology_inventory_id = models.AutoField(primary_key=True,)
|
||||
topology = models.ForeignKey('Topology',)
|
||||
inventory_id = models.IntegerField()
|
||||
|
||||
|
||||
class EventTrace(models.Model):
|
||||
|
||||
event_trace_id = models.AutoField(primary_key=True,)
|
||||
client = models.ForeignKey('Client',)
|
||||
trace_session_id = models.IntegerField(default=0,)
|
||||
event_data = models.TextField()
|
||||
message_id = models.IntegerField()
|
||||
|
||||
|
||||
class Coverage(models.Model):
|
||||
|
||||
coverage_id = models.AutoField(primary_key=True,)
|
||||
coverage_data = models.TextField()
|
||||
test_result = models.ForeignKey('TestResult',)
|
||||
|
||||
|
||||
class TopologySnapshot(models.Model):
|
||||
|
||||
topology_snapshot_id = models.AutoField(primary_key=True,)
|
||||
client = models.ForeignKey('Client',)
|
||||
topology_id = models.IntegerField()
|
||||
trace_session_id = models.IntegerField()
|
||||
snapshot_data = models.TextField('TopologySnapshot',)
|
||||
order = models.IntegerField()
|
||||
|
||||
|
||||
class TestCase(models.Model):
|
||||
|
||||
test_case_id = models.AutoField(primary_key=True,)
|
||||
name = models.CharField('TestCase', max_length=200, blank=True)
|
||||
test_case_data = models.TextField()
|
||||
|
||||
|
||||
class Result(models.Model):
|
||||
|
||||
result_id = models.AutoField(primary_key=True,)
|
||||
name = models.CharField(max_length=20, blank=True)
|
||||
|
||||
|
||||
class CodeUnderTest(models.Model):
|
||||
|
||||
code_under_test_id = models.AutoField('CodeUnderTest', primary_key=True,)
|
||||
version_x = models.IntegerField()
|
||||
version_y = models.IntegerField()
|
||||
version_z = models.IntegerField()
|
||||
commits_since = models.IntegerField()
|
||||
commit_hash = models.CharField(max_length=40, blank=True)
|
||||
|
||||
|
||||
class TestResult(models.Model):
|
||||
|
||||
test_result_id = models.AutoField(primary_key=True,)
|
||||
test_case = models.ForeignKey('TestCase',)
|
||||
result = models.ForeignKey('Result',)
|
||||
code_under_test = models.ForeignKey('CodeUnderTest',)
|
||||
time = models.DateTimeField()
|
||||
id = models.IntegerField(default=0,)
|
||||
client = models.ForeignKey('Client',)
|
||||
|
||||
@ -1,10 +1,9 @@
|
||||
# Copyright (c) 2017 Red Hat, Inc
|
||||
|
||||
from awx.network_ui.models import Topology, Device, Link, Interface, Group, GroupDevice, Process, Stream
|
||||
from awx.network_ui.models import Topology, Device, Link, Interface
|
||||
from django.db.models import Q
|
||||
import yaml
|
||||
import json
|
||||
from collections import defaultdict
|
||||
|
||||
NetworkAnnotatedInterface = Interface.objects.values('name',
|
||||
'id',
|
||||
@ -19,36 +18,18 @@ NetworkAnnotatedInterface = Interface.objects.values('name',
|
||||
def topology_data(topology_id):
|
||||
|
||||
data = dict(devices=[],
|
||||
links=[],
|
||||
groups=[],
|
||||
streams=[])
|
||||
links=[])
|
||||
|
||||
topology = Topology.objects.get(pk=topology_id)
|
||||
|
||||
data['name'] = topology.name
|
||||
data['topology_id'] = topology_id
|
||||
|
||||
groups = list(Group.objects.filter(topology_id=topology_id).values())
|
||||
group_devices = GroupDevice.objects.filter(group__topology_id=topology_id).values('group_id', 'device_id', 'device__name', 'group__name')
|
||||
group_device_map = defaultdict(list)
|
||||
|
||||
for group_device in group_devices:
|
||||
group_device_map[group_device['group_id']].append(group_device)
|
||||
|
||||
device_group_map = defaultdict(list)
|
||||
for group_device in group_devices:
|
||||
device_group_map[group_device['device_id']].append(group_device)
|
||||
|
||||
for group in groups:
|
||||
group['members'] = [x['device__name'] for x in group_device_map[group['group_id']]]
|
||||
data['groups'] = groups
|
||||
|
||||
links = list(Link.objects
|
||||
.filter(Q(from_device__topology_id=topology_id) |
|
||||
Q(to_device__topology_id=topology_id)))
|
||||
|
||||
interfaces = Interface.objects.filter(device__topology_id=topology_id)
|
||||
processes = Process.objects.filter(device__topology_id=topology_id)
|
||||
|
||||
for device in Device.objects.filter(topology_id=topology_id).order_by('name'):
|
||||
interfaces = list(NetworkAnnotatedInterface.filter(device_id=device.pk).order_by('name'))
|
||||
@ -58,15 +39,12 @@ def topology_data(topology_id):
|
||||
remote_interface_name=x['from_link__to_interface__name'] or x['to_link__from_interface__name'],
|
||||
id=x['id'],
|
||||
) for x in interfaces]
|
||||
processes = list(Process.objects.filter(device_id=device.pk).values())
|
||||
data['devices'].append(dict(name=device.name,
|
||||
type=device.device_type,
|
||||
x=device.x,
|
||||
y=device.y,
|
||||
id=device.id,
|
||||
interfaces=interfaces,
|
||||
processes=processes,
|
||||
groups=[x['group__name'] for x in device_group_map[device.device_id]]))
|
||||
interfaces=interfaces))
|
||||
|
||||
for link in links:
|
||||
data['links'].append(dict(from_device=link.from_device.name,
|
||||
@ -80,18 +58,6 @@ def topology_data(topology_id):
|
||||
name=link.name,
|
||||
network=link.pk))
|
||||
|
||||
streams = list(Stream.objects
|
||||
.filter(Q(from_device__topology_id=topology_id) |
|
||||
Q(to_device__topology_id=topology_id)))
|
||||
|
||||
for stream in streams:
|
||||
data['streams'].append(dict(from_id=stream.from_device.id,
|
||||
to_id=stream.to_device.id,
|
||||
from_device=stream.from_device.name,
|
||||
to_device=stream.to_device.name,
|
||||
label=stream.label,
|
||||
id=stream.id))
|
||||
|
||||
return data
|
||||
|
||||
|
||||
|
||||
@ -5,11 +5,6 @@ from awx.network_ui import views
|
||||
|
||||
app_name = 'network_ui'
|
||||
urlpatterns = [
|
||||
url(r'^tests$', views.tests, name='tests'),
|
||||
url(r'^upload_test$', views.upload_test, name='upload_test'),
|
||||
url(r'^download_coverage/(?P<pk>[0-9]+)$', views.download_coverage, name='download_coverage'),
|
||||
url(r'^download_trace$', views.download_trace, name='download_trace'),
|
||||
url(r'^download_recording$', views.download_recording, name='download_recording'),
|
||||
url(r'^topology.json$', views.json_topology_data, name='json_topology_data'),
|
||||
url(r'^topology.yaml$', views.yaml_topology_data, name='json_topology_data'),
|
||||
]
|
||||
|
||||
@ -1,16 +1,12 @@
|
||||
# Copyright (c) 2017 Red Hat, Inc
|
||||
from django.shortcuts import render
|
||||
from django import forms
|
||||
from django.http import JsonResponse, HttpResponseBadRequest, HttpResponse, HttpResponseRedirect
|
||||
from django.core.exceptions import ObjectDoesNotExist
|
||||
from django.http import JsonResponse, HttpResponseBadRequest, HttpResponse
|
||||
from awx.network_ui.models import Topology
|
||||
import yaml
|
||||
|
||||
import json
|
||||
|
||||
|
||||
# Create your views here.
|
||||
from .models import Topology, FSMTrace, EventTrace, TopologySnapshot
|
||||
from .models import TestCase, TestResult, Coverage
|
||||
from .serializers import topology_data
|
||||
|
||||
|
||||
@ -39,100 +35,3 @@ def yaml_topology_data(request):
|
||||
else:
|
||||
return HttpResponseBadRequest(form.errors)
|
||||
|
||||
|
||||
class FSMTraceForm(forms.Form):
|
||||
topology_id = forms.IntegerField()
|
||||
trace_id = forms.IntegerField()
|
||||
client_id = forms.IntegerField()
|
||||
|
||||
|
||||
def download_trace(request):
|
||||
form = FSMTraceForm(request.GET)
|
||||
if form.is_valid():
|
||||
topology_id = form.cleaned_data['topology_id']
|
||||
trace_id = form.cleaned_data['trace_id']
|
||||
client_id = form.cleaned_data['client_id']
|
||||
data = list(FSMTrace.objects.filter(trace_session_id=trace_id,
|
||||
client_id=client_id).order_by('order').values())
|
||||
response = HttpResponse(yaml.safe_dump(data, default_flow_style=False),
|
||||
content_type="application/force-download")
|
||||
response['Content-Disposition'] = 'attachment; filename="trace_{0}_{1}_{2}.yml"'.format(topology_id, client_id, trace_id)
|
||||
return response
|
||||
else:
|
||||
return HttpResponse(form.errors)
|
||||
|
||||
|
||||
class RecordingForm(forms.Form):
|
||||
topology_id = forms.IntegerField()
|
||||
trace_id = forms.IntegerField()
|
||||
client_id = forms.IntegerField()
|
||||
|
||||
|
||||
def download_recording(request):
|
||||
form = RecordingForm(request.GET)
|
||||
if form.is_valid():
|
||||
topology_id = form.cleaned_data['topology_id']
|
||||
trace_id = form.cleaned_data['trace_id']
|
||||
client_id = form.cleaned_data['client_id']
|
||||
data = dict()
|
||||
data['event_trace'] = [json.loads(x) for x in EventTrace
|
||||
.objects.filter(trace_session_id=trace_id, client_id=client_id)
|
||||
.order_by('message_id')
|
||||
.values_list('event_data', flat=True)]
|
||||
data['fsm_trace'] = list(FSMTrace
|
||||
.objects
|
||||
.filter(trace_session_id=trace_id, client_id=client_id)
|
||||
.order_by('order')
|
||||
.values())
|
||||
data['snapshots'] = [json.loads(x) for x in TopologySnapshot
|
||||
.objects.filter(trace_session_id=trace_id, client_id=client_id)
|
||||
.order_by('order')
|
||||
.values_list('snapshot_data', flat=True)]
|
||||
response = HttpResponse(json.dumps(data, sort_keys=True, indent=4),
|
||||
content_type="application/force-download")
|
||||
response['Content-Disposition'] = 'attachment; filename="trace_{0}_{1}_{2}.yml"'.format(topology_id, client_id, trace_id)
|
||||
return response
|
||||
else:
|
||||
return HttpResponse(form.errors)
|
||||
|
||||
|
||||
def tests(request):
|
||||
tests = list(TestCase.objects.all().values('test_case_id', 'name'))
|
||||
for x in tests:
|
||||
x['coverage'] = "/network_ui/download_coverage/{0}".format(x['test_case_id'])
|
||||
return JsonResponse(dict(tests=tests))
|
||||
|
||||
|
||||
def create_test(name, data):
|
||||
try:
|
||||
test_case = TestCase.objects.get(name=name)
|
||||
test_case.test_case_data=json.dumps(data)
|
||||
test_case.save()
|
||||
except ObjectDoesNotExist:
|
||||
TestCase(name=name, test_case_data=json.dumps(data)).save()
|
||||
|
||||
|
||||
class UploadTestForm(forms.Form):
|
||||
name = forms.CharField()
|
||||
file = forms.FileField()
|
||||
|
||||
|
||||
def upload_test(request):
|
||||
if request.method == 'POST':
|
||||
form = UploadTestForm(request.POST, request.FILES)
|
||||
if form.is_valid():
|
||||
name = form.cleaned_data['name']
|
||||
data = json.loads(request.FILES['file'].read())
|
||||
create_test(name, data)
|
||||
return HttpResponseRedirect('/network_ui/tests')
|
||||
else:
|
||||
form = UploadTestForm()
|
||||
return render(request, 'network_ui/upload_test.html', {'form': form})
|
||||
|
||||
|
||||
def download_coverage(request, pk):
|
||||
latest_tr = TestResult.objects.filter(test_case_id=pk).order_by('-time')[0]
|
||||
coverage = Coverage.objects.get(test_result_id=latest_tr.pk)
|
||||
response = HttpResponse(coverage.coverage_data,
|
||||
content_type="application/json")
|
||||
return response
|
||||
|
||||
1
awx/network_ui_test/__init__.py
Normal file
1
awx/network_ui_test/__init__.py
Normal file
@ -0,0 +1 @@
|
||||
# Copyright (c) 2017 Red Hat, Inc
|
||||
205
awx/network_ui_test/consumers.py
Normal file
205
awx/network_ui_test/consumers.py
Normal file
@ -0,0 +1,205 @@
|
||||
# Copyright (c) 2018 Red Hat, Inc
|
||||
# In consumers.py
|
||||
from channels import Group, Channel
|
||||
from channels.sessions import channel_session
|
||||
from awx.network_ui.models import Topology, Client
|
||||
from awx.network_ui.models import TopologyInventory
|
||||
from awx.network_ui_test.models import FSMTrace, EventTrace, Coverage, TopologySnapshot
|
||||
from awx.network_ui_test.models import TestCase, TestResult, CodeUnderTest, Result
|
||||
import urlparse
|
||||
import logging
|
||||
from django.utils.dateparse import parse_datetime
|
||||
|
||||
|
||||
from pprint import pformat
|
||||
|
||||
import json
|
||||
# Connected to websocket.connect
|
||||
|
||||
HISTORY_MESSAGE_IGNORE_TYPES = ['DeviceSelected',
|
||||
'DeviceUnSelected',
|
||||
'LinkSelected',
|
||||
'LinkUnSelected',
|
||||
'MouseEvent',
|
||||
'MouseWheelEvent',
|
||||
'KeyEvent']
|
||||
|
||||
|
||||
logger = logging.getLogger("awx.network_ui_test.consumers")
|
||||
|
||||
|
||||
class NetworkUIException(Exception):
|
||||
|
||||
pass
|
||||
|
||||
|
||||
def parse_inventory_id(data):
|
||||
inventory_id = data.get('inventory_id', ['null'])
|
||||
try:
|
||||
inventory_id = int(inventory_id[0])
|
||||
except ValueError:
|
||||
inventory_id = None
|
||||
if not inventory_id:
|
||||
inventory_id = None
|
||||
return inventory_id
|
||||
|
||||
# TestPersistence
|
||||
|
||||
|
||||
class _TestPersistence(object):
|
||||
|
||||
def handle(self, message):
|
||||
topology_id = message.get('topology')
|
||||
assert topology_id is not None, "No topology_id"
|
||||
client_id = message.get('client')
|
||||
assert client_id is not None, "No client_id"
|
||||
data = json.loads(message['text'])
|
||||
if isinstance(data[1], list):
|
||||
logger.error("Message has no sender")
|
||||
return
|
||||
if isinstance(data[1], dict) and client_id != data[1].get('sender'):
|
||||
logger.error("client_id mismatch expected: %s actual %s", client_id, data[1].get('sender'))
|
||||
logger.error(pformat(data))
|
||||
return
|
||||
message_type = data[0]
|
||||
message_value = data[1]
|
||||
handler = self.get_handler(message_type)
|
||||
if handler is not None:
|
||||
try:
|
||||
handler(message_value, topology_id, client_id)
|
||||
except NetworkUIException, e:
|
||||
Group("client-%s" % client_id).send({"text": json.dumps(["Error", str(e)])})
|
||||
raise
|
||||
except Exception, e:
|
||||
Group("client-%s" % client_id).send({"text": json.dumps(["Error", "Server Error"])})
|
||||
raise
|
||||
except BaseException, e:
|
||||
Group("client-%s" % client_id).send({"text": json.dumps(["Error", "Server Error"])})
|
||||
raise
|
||||
else:
|
||||
logger.warning("Unsupported message %s: no handler", message_type)
|
||||
|
||||
def get_handler(self, message_type):
|
||||
return getattr(self, "on{0}".format(message_type), None)
|
||||
|
||||
def onMultipleMessage(self, message_value, topology_id, client_id):
|
||||
for message in message_value['messages']:
|
||||
handler = self.get_handler(message['msg_type'])
|
||||
if handler is not None:
|
||||
handler(message, topology_id, client_id)
|
||||
else:
|
||||
logger.warning("Unsupported message %s", message['msg_type'])
|
||||
|
||||
def onCoverageRequest(self, coverage, topology_id, client_id):
|
||||
pass
|
||||
|
||||
def onTestResult(self, test_result, topology_id, client_id):
|
||||
xyz, _, rest = test_result['code_under_test'].partition('-')
|
||||
commits_since, _, commit_hash = rest.partition('-')
|
||||
commit_hash = commit_hash.strip('g')
|
||||
|
||||
x, y, z = [int(i) for i in xyz.split('.')]
|
||||
|
||||
code_under_test, _ = CodeUnderTest.objects.get_or_create(version_x=x,
|
||||
version_y=y,
|
||||
version_z=z,
|
||||
commits_since=int(commits_since),
|
||||
commit_hash=commit_hash)
|
||||
|
||||
logger.error("TR: %s", test_result)
|
||||
tr = TestResult(id=test_result['id'],
|
||||
result_id=Result.objects.get(name=test_result['result']).pk,
|
||||
test_case_id=TestCase.objects.get(name=test_result['name']).pk,
|
||||
code_under_test_id=code_under_test.pk,
|
||||
client_id=client_id,
|
||||
time=parse_datetime(test_result['date']))
|
||||
tr.save()
|
||||
|
||||
|
||||
def onCoverage(self, coverage, topology_id, client_id):
|
||||
Coverage(test_result_id=TestResult.objects.get(id=coverage['result_id'], client_id=client_id).pk,
|
||||
coverage_data=json.dumps(coverage['coverage'])).save()
|
||||
|
||||
def onStartRecording(self, recording, topology_id, client_id):
|
||||
pass
|
||||
|
||||
def onStopRecording(self, recording, topology_id, client_id):
|
||||
pass
|
||||
|
||||
def write_event(self, event, topology_id, client_id):
|
||||
if event.get('save', True):
|
||||
EventTrace(trace_session_id=event['trace_id'],
|
||||
event_data=json.dumps(event),
|
||||
message_id=event['message_id'],
|
||||
client_id=client_id).save()
|
||||
|
||||
onViewPort = write_event
|
||||
onMouseEvent = write_event
|
||||
onTouchEvent = write_event
|
||||
onMouseWheelEvent = write_event
|
||||
onKeyEvent = write_event
|
||||
|
||||
def onFSMTrace(self, message_value, diagram_id, client_id):
|
||||
FSMTrace(trace_session_id=message_value['trace_id'],
|
||||
fsm_name=message_value['fsm_name'],
|
||||
from_state=message_value['from_state'],
|
||||
to_state=message_value['to_state'],
|
||||
order=message_value['order'],
|
||||
client_id=client_id,
|
||||
message_type=message_value['recv_message_type'] or "none").save()
|
||||
|
||||
def onSnapshot(self, snapshot, topology_id, client_id):
|
||||
TopologySnapshot(trace_session_id=snapshot['trace_id'],
|
||||
snapshot_data=json.dumps(snapshot),
|
||||
order=snapshot['order'],
|
||||
client_id=client_id,
|
||||
topology_id=topology_id).save()
|
||||
|
||||
|
||||
test_persistence = _TestPersistence()
|
||||
|
||||
|
||||
# UI Channel Events
|
||||
|
||||
@channel_session
|
||||
def ws_connect(message):
|
||||
# Accept connection
|
||||
data = urlparse.parse_qs(message.content['query_string'])
|
||||
inventory_id = parse_inventory_id(data)
|
||||
topology_ids = list(TopologyInventory.objects.filter(inventory_id=inventory_id).values_list('topology_id', flat=True))
|
||||
topology_id = 0
|
||||
if len(topology_ids) > 0:
|
||||
topology_id = topology_ids[0]
|
||||
if topology_id:
|
||||
topology = Topology.objects.get(topology_id=topology_id)
|
||||
else:
|
||||
topology = Topology(name="topology", scale=1.0, panX=0, panY=0)
|
||||
topology.save()
|
||||
TopologyInventory(inventory_id=inventory_id, topology_id=topology.topology_id).save()
|
||||
topology_id = topology.topology_id
|
||||
message.channel_session['topology_id'] = topology_id
|
||||
client = Client()
|
||||
client.save()
|
||||
message.channel_session['client_id'] = client.pk
|
||||
Group("client-%s" % client.pk).add(message.reply_channel)
|
||||
message.reply_channel.send({"text": json.dumps(["id", client.pk])})
|
||||
send_tests(message.reply_channel)
|
||||
|
||||
|
||||
def send_tests(channel):
|
||||
for name, test_case_data in TestCase.objects.all().values_list('name', 'test_case_data'):
|
||||
channel.send({"text": json.dumps(["TestCase", [name, json.loads(test_case_data)]])})
|
||||
|
||||
|
||||
@channel_session
|
||||
def ws_message(message):
|
||||
Channel('test_persistence').send({"text": message['text'],
|
||||
"topology": message.channel_session['topology_id'],
|
||||
"client": message.channel_session['client_id']})
|
||||
|
||||
|
||||
@channel_session
|
||||
def ws_disconnect(message):
|
||||
pass
|
||||
|
||||
|
||||
102
awx/network_ui_test/migrations/0001_initial.py
Normal file
102
awx/network_ui_test/migrations/0001_initial.py
Normal file
@ -0,0 +1,102 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Generated by Django 1.11.7 on 2018-03-06 18:40
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
initial = True
|
||||
|
||||
dependencies = [
|
||||
('network_ui', '0005_auto_20180306_1837'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='CodeUnderTest',
|
||||
fields=[
|
||||
('code_under_test_id', models.AutoField(primary_key=True, serialize=False, verbose_name=b'CodeUnderTest')),
|
||||
('version_x', models.IntegerField()),
|
||||
('version_y', models.IntegerField()),
|
||||
('version_z', models.IntegerField()),
|
||||
('commits_since', models.IntegerField()),
|
||||
('commit_hash', models.CharField(blank=True, max_length=40)),
|
||||
],
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='Coverage',
|
||||
fields=[
|
||||
('coverage_id', models.AutoField(primary_key=True, serialize=False)),
|
||||
('coverage_data', models.TextField()),
|
||||
],
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='EventTrace',
|
||||
fields=[
|
||||
('event_trace_id', models.AutoField(primary_key=True, serialize=False)),
|
||||
('trace_session_id', models.IntegerField(default=0)),
|
||||
('event_data', models.TextField()),
|
||||
('message_id', models.IntegerField()),
|
||||
('client', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='network_ui.Client')),
|
||||
],
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='FSMTrace',
|
||||
fields=[
|
||||
('fsm_trace_id', models.AutoField(primary_key=True, serialize=False)),
|
||||
('fsm_name', models.CharField(blank=True, max_length=200)),
|
||||
('from_state', models.CharField(blank=True, max_length=200)),
|
||||
('to_state', models.CharField(blank=True, max_length=200)),
|
||||
('message_type', models.CharField(blank=True, max_length=200)),
|
||||
('trace_session_id', models.IntegerField(default=0)),
|
||||
('order', models.IntegerField(default=0)),
|
||||
('client', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='network_ui.Client')),
|
||||
],
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='Result',
|
||||
fields=[
|
||||
('result_id', models.AutoField(primary_key=True, serialize=False)),
|
||||
('name', models.CharField(blank=True, max_length=20)),
|
||||
],
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='TestCase',
|
||||
fields=[
|
||||
('test_case_id', models.AutoField(primary_key=True, serialize=False)),
|
||||
('name', models.CharField(blank=True, max_length=200, verbose_name=b'TestCase')),
|
||||
('test_case_data', models.TextField()),
|
||||
],
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='TestResult',
|
||||
fields=[
|
||||
('test_result_id', models.AutoField(primary_key=True, serialize=False)),
|
||||
('time', models.DateTimeField()),
|
||||
('id', models.IntegerField(default=0)),
|
||||
('client', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='network_ui.Client')),
|
||||
('code_under_test', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='network_ui_test.CodeUnderTest')),
|
||||
('result', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='network_ui_test.Result')),
|
||||
('test_case', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='network_ui_test.TestCase')),
|
||||
],
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='TopologySnapshot',
|
||||
fields=[
|
||||
('topology_snapshot_id', models.AutoField(primary_key=True, serialize=False)),
|
||||
('topology_id', models.IntegerField()),
|
||||
('trace_session_id', models.IntegerField()),
|
||||
('snapshot_data', models.TextField(verbose_name=b'TopologySnapshot')),
|
||||
('order', models.IntegerField()),
|
||||
('client', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='network_ui.Client')),
|
||||
],
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='coverage',
|
||||
name='test_result',
|
||||
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='network_ui_test.TestResult'),
|
||||
),
|
||||
]
|
||||
34
awx/network_ui_test/migrations/0002_auto_20180306_2243.py
Normal file
34
awx/network_ui_test/migrations/0002_auto_20180306_2243.py
Normal file
@ -0,0 +1,34 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Generated by Django 1.11.7 on 2018-03-06 22:43
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import migrations
|
||||
|
||||
|
||||
results = ['passed',
|
||||
'failed',
|
||||
'errored',
|
||||
'skipped',
|
||||
'aborted',
|
||||
'not run',
|
||||
'blocked']
|
||||
|
||||
|
||||
def populate_result_types(apps, schema_editor):
|
||||
|
||||
Result = apps.get_model('network_ui_test', 'Result')
|
||||
for result in results:
|
||||
Result.objects.get_or_create(name=result)
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('network_ui_test', '0001_initial'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.RunPython(
|
||||
code=populate_result_types,
|
||||
),
|
||||
]
|
||||
26
awx/network_ui_test/migrations/0003_auto_20180306_2306.py
Normal file
26
awx/network_ui_test/migrations/0003_auto_20180306_2306.py
Normal file
@ -0,0 +1,26 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Generated by Django 1.11.7 on 2018-03-06 23:06
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import migrations
|
||||
|
||||
import json
|
||||
|
||||
|
||||
def add_load_test_case(apps, schema_editor):
|
||||
|
||||
TestCase = apps.get_model('network_ui_test', 'TestCase')
|
||||
TestCase.objects.get_or_create(name="Load", test_case_data=json.dumps(dict(runnable=False)))
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('network_ui_test', '0002_auto_20180306_2243'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.RunPython(
|
||||
code=add_load_test_case,
|
||||
),
|
||||
]
|
||||
0
awx/network_ui_test/migrations/__init__.py
Normal file
0
awx/network_ui_test/migrations/__init__.py
Normal file
73
awx/network_ui_test/models.py
Normal file
73
awx/network_ui_test/models.py
Normal file
@ -0,0 +1,73 @@
|
||||
from django.db import models
|
||||
|
||||
|
||||
class FSMTrace(models.Model):
|
||||
|
||||
fsm_trace_id = models.AutoField(primary_key=True,)
|
||||
fsm_name = models.CharField(max_length=200, blank=True)
|
||||
from_state = models.CharField(max_length=200, blank=True)
|
||||
to_state = models.CharField(max_length=200, blank=True)
|
||||
message_type = models.CharField(max_length=200, blank=True)
|
||||
client = models.ForeignKey('network_ui.Client',)
|
||||
trace_session_id = models.IntegerField(default=0,)
|
||||
order = models.IntegerField(default=0,)
|
||||
|
||||
|
||||
class EventTrace(models.Model):
|
||||
|
||||
event_trace_id = models.AutoField(primary_key=True,)
|
||||
client = models.ForeignKey('network_ui.Client',)
|
||||
trace_session_id = models.IntegerField(default=0,)
|
||||
event_data = models.TextField()
|
||||
message_id = models.IntegerField()
|
||||
|
||||
|
||||
class Coverage(models.Model):
|
||||
|
||||
coverage_id = models.AutoField(primary_key=True,)
|
||||
coverage_data = models.TextField()
|
||||
test_result = models.ForeignKey('TestResult',)
|
||||
|
||||
|
||||
class TopologySnapshot(models.Model):
|
||||
|
||||
topology_snapshot_id = models.AutoField(primary_key=True,)
|
||||
client = models.ForeignKey('network_ui.Client',)
|
||||
topology_id = models.IntegerField()
|
||||
trace_session_id = models.IntegerField()
|
||||
snapshot_data = models.TextField('TopologySnapshot',)
|
||||
order = models.IntegerField()
|
||||
|
||||
|
||||
class TestCase(models.Model):
|
||||
|
||||
test_case_id = models.AutoField(primary_key=True,)
|
||||
name = models.CharField('TestCase', max_length=200, blank=True)
|
||||
test_case_data = models.TextField()
|
||||
|
||||
|
||||
class Result(models.Model):
|
||||
|
||||
result_id = models.AutoField(primary_key=True,)
|
||||
name = models.CharField(max_length=20, blank=True)
|
||||
|
||||
|
||||
class CodeUnderTest(models.Model):
|
||||
|
||||
code_under_test_id = models.AutoField('CodeUnderTest', primary_key=True,)
|
||||
version_x = models.IntegerField()
|
||||
version_y = models.IntegerField()
|
||||
version_z = models.IntegerField()
|
||||
commits_since = models.IntegerField()
|
||||
commit_hash = models.CharField(max_length=40, blank=True)
|
||||
|
||||
|
||||
class TestResult(models.Model):
|
||||
|
||||
test_result_id = models.AutoField(primary_key=True,)
|
||||
test_case = models.ForeignKey('TestCase',)
|
||||
result = models.ForeignKey('Result',)
|
||||
code_under_test = models.ForeignKey('CodeUnderTest',)
|
||||
time = models.DateTimeField()
|
||||
id = models.IntegerField(default=0,)
|
||||
client = models.ForeignKey('network_ui.Client',)
|
||||
12
awx/network_ui_test/routing.py
Normal file
12
awx/network_ui_test/routing.py
Normal file
@ -0,0 +1,12 @@
|
||||
# Copyright (c) 2017 Red Hat, Inc
|
||||
from channels.routing import route
|
||||
from awx.network_ui_test.consumers import ws_connect, ws_message, ws_disconnect, test_persistence
|
||||
|
||||
|
||||
channel_routing = [
|
||||
route("websocket.connect", ws_connect, path=r"^/network_ui/test"),
|
||||
route("websocket.receive", ws_message, path=r"^/network_ui/test"),
|
||||
route("websocket.disconnect", ws_disconnect, path=r"^/network_ui/test"),
|
||||
route("test_persistence", test_persistence.handle),
|
||||
]
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
<form action="/network_ui/upload_test" method="post" enctype="multipart/form-data">
|
||||
<form action="/network_ui_test/upload_test" method="post" enctype="multipart/form-data">
|
||||
{% csrf_token %}
|
||||
{{form}}
|
||||
<button type="submit">Upload Test</button>
|
||||
13
awx/network_ui_test/tools/Makefile
Normal file
13
awx/network_ui_test/tools/Makefile
Normal file
@ -0,0 +1,13 @@
|
||||
|
||||
SERVER = "https://meganuke:8043"
|
||||
PORT = "9000"
|
||||
|
||||
.PHONY: clean coverage
|
||||
|
||||
clean:
|
||||
git clean -fdX .
|
||||
git clean -fd .
|
||||
|
||||
coverage:
|
||||
./coverage_report.py ${SERVER}
|
||||
python -m SimpleHTTPServer ${PORT}
|
||||
@ -18,7 +18,7 @@ import subprocess
|
||||
|
||||
logger = logging.getLogger('coverage_report')
|
||||
|
||||
TESTS_API = '/network_ui/tests'
|
||||
TESTS_API = '/network_ui_test/tests'
|
||||
|
||||
|
||||
|
||||
2
awx/network_ui_test/tools/requirements.txt
Normal file
2
awx/network_ui_test/tools/requirements.txt
Normal file
@ -0,0 +1,2 @@
|
||||
requests
|
||||
docopt
|
||||
14
awx/network_ui_test/urls.py
Normal file
14
awx/network_ui_test/urls.py
Normal file
@ -0,0 +1,14 @@
|
||||
# Copyright (c) 2017 Red Hat, Inc
|
||||
from django.conf.urls import url
|
||||
|
||||
from awx.network_ui_test import views
|
||||
|
||||
app_name = 'network_ui_test'
|
||||
urlpatterns = [
|
||||
url(r'^tests$', views.tests, name='tests'),
|
||||
url(r'^upload_test$', views.upload_test, name='upload_test'),
|
||||
url(r'^download_coverage/(?P<pk>[0-9]+)$', views.download_coverage, name='download_coverage'),
|
||||
url(r'^download_trace$', views.download_trace, name='download_trace'),
|
||||
url(r'^download_recording$', views.download_recording, name='download_recording'),
|
||||
]
|
||||
|
||||
112
awx/network_ui_test/views.py
Normal file
112
awx/network_ui_test/views.py
Normal file
@ -0,0 +1,112 @@
|
||||
# Copyright (c) 2017 Red Hat, Inc
|
||||
from django.shortcuts import render
|
||||
from django import forms
|
||||
from django.http import JsonResponse, HttpResponse, HttpResponseRedirect
|
||||
from django.core.exceptions import ObjectDoesNotExist
|
||||
import yaml
|
||||
|
||||
import json
|
||||
|
||||
|
||||
# Create your views here.
|
||||
from .models import FSMTrace, EventTrace, TopologySnapshot
|
||||
from .models import TestCase, TestResult, Coverage
|
||||
|
||||
|
||||
class FSMTraceForm(forms.Form):
|
||||
topology_id = forms.IntegerField()
|
||||
trace_id = forms.IntegerField()
|
||||
client_id = forms.IntegerField()
|
||||
|
||||
|
||||
def download_trace(request):
|
||||
form = FSMTraceForm(request.GET)
|
||||
if form.is_valid():
|
||||
topology_id = form.cleaned_data['topology_id']
|
||||
trace_id = form.cleaned_data['trace_id']
|
||||
client_id = form.cleaned_data['client_id']
|
||||
data = list(FSMTrace.objects.filter(trace_session_id=trace_id,
|
||||
client_id=client_id).order_by('order').values())
|
||||
response = HttpResponse(yaml.safe_dump(data, default_flow_style=False),
|
||||
content_type="application/force-download")
|
||||
response['Content-Disposition'] = 'attachment; filename="trace_{0}_{1}_{2}.yml"'.format(topology_id, client_id, trace_id)
|
||||
return response
|
||||
else:
|
||||
return HttpResponse(form.errors)
|
||||
|
||||
|
||||
class RecordingForm(forms.Form):
|
||||
topology_id = forms.IntegerField()
|
||||
trace_id = forms.IntegerField()
|
||||
client_id = forms.IntegerField()
|
||||
|
||||
|
||||
def download_recording(request):
|
||||
form = RecordingForm(request.GET)
|
||||
if form.is_valid():
|
||||
topology_id = form.cleaned_data['topology_id']
|
||||
trace_id = form.cleaned_data['trace_id']
|
||||
client_id = form.cleaned_data['client_id']
|
||||
data = dict()
|
||||
data['event_trace'] = [json.loads(x) for x in EventTrace
|
||||
.objects.filter(trace_session_id=trace_id, client_id=client_id)
|
||||
.order_by('message_id')
|
||||
.values_list('event_data', flat=True)]
|
||||
data['fsm_trace'] = list(FSMTrace
|
||||
.objects
|
||||
.filter(trace_session_id=trace_id, client_id=client_id)
|
||||
.order_by('order')
|
||||
.values())
|
||||
data['snapshots'] = [json.loads(x) for x in TopologySnapshot
|
||||
.objects.filter(trace_session_id=trace_id, client_id=client_id)
|
||||
.order_by('order')
|
||||
.values_list('snapshot_data', flat=True)]
|
||||
response = HttpResponse(json.dumps(data, sort_keys=True, indent=4),
|
||||
content_type="application/force-download")
|
||||
response['Content-Disposition'] = 'attachment; filename="trace_{0}_{1}_{2}.yml"'.format(topology_id, client_id, trace_id)
|
||||
return response
|
||||
else:
|
||||
return HttpResponse(form.errors)
|
||||
|
||||
|
||||
def tests(request):
|
||||
tests = list(TestCase.objects.all().values('test_case_id', 'name'))
|
||||
for x in tests:
|
||||
x['coverage'] = "/network_ui_test/download_coverage/{0}".format(x['test_case_id'])
|
||||
return JsonResponse(dict(tests=tests))
|
||||
|
||||
|
||||
def create_test(name, data):
|
||||
try:
|
||||
test_case = TestCase.objects.get(name=name)
|
||||
test_case.test_case_data=json.dumps(data)
|
||||
test_case.save()
|
||||
except ObjectDoesNotExist:
|
||||
TestCase(name=name, test_case_data=json.dumps(data)).save()
|
||||
|
||||
|
||||
class UploadTestForm(forms.Form):
|
||||
name = forms.CharField()
|
||||
file = forms.FileField()
|
||||
|
||||
|
||||
def upload_test(request):
|
||||
if request.method == 'POST':
|
||||
form = UploadTestForm(request.POST, request.FILES)
|
||||
if form.is_valid():
|
||||
name = form.cleaned_data['name']
|
||||
data = json.loads(request.FILES['file'].read())
|
||||
create_test(name, data)
|
||||
return HttpResponseRedirect('/network_ui_test/tests')
|
||||
else:
|
||||
form = UploadTestForm()
|
||||
return render(request, 'network_ui_test/upload_test.html', {'form': form})
|
||||
|
||||
|
||||
def download_coverage(request, pk):
|
||||
latest_tr = TestResult.objects.filter(test_case_id=pk).order_by('-time')[0]
|
||||
coverage = Coverage.objects.get(test_result_id=latest_tr.pk)
|
||||
response = HttpResponse(coverage.coverage_data,
|
||||
content_type="application/json")
|
||||
return response
|
||||
|
||||
@ -280,6 +280,7 @@ INSTALLED_APPS = (
|
||||
'awx.sso',
|
||||
'solo',
|
||||
'awx.network_ui',
|
||||
'awx.network_ui_test',
|
||||
)
|
||||
|
||||
INTERNAL_IPS = ('127.0.0.1',)
|
||||
|
||||
@ -196,12 +196,14 @@ function StopRecording(sender, trace_id) {
|
||||
}
|
||||
exports.StopRecording = StopRecording;
|
||||
|
||||
function ViewPort(sender, scale, panX, panY, trace_id) {
|
||||
function ViewPort(sender, scale, panX, panY, graph_width, graph_height, trace_id) {
|
||||
this.msg_type = "ViewPort";
|
||||
this.sender = sender;
|
||||
this.scale = scale;
|
||||
this.panX = panX;
|
||||
this.panY = panY;
|
||||
this.graph_width = graph_width;
|
||||
this.graph_height = graph_height;
|
||||
this.trace_id = trace_id;
|
||||
}
|
||||
exports.ViewPort = ViewPort;
|
||||
|
||||
@ -378,7 +378,6 @@ _Move.prototype.onMouseMove = function (controller) {
|
||||
var i = 0;
|
||||
var j = 0;
|
||||
var previous_x, previous_y;
|
||||
var membership_old_new;
|
||||
for (i = 0; i < devices.length; i++) {
|
||||
previous_x = devices[i].x;
|
||||
previous_y = devices[i].y;
|
||||
|
||||
@ -1,7 +1,6 @@
|
||||
/* Copyright (c) 2017 Red Hat, Inc. */
|
||||
var angular = require('angular');
|
||||
var fsm = require('./fsm.js');
|
||||
var null_fsm = require('./null.fsm.js');
|
||||
var mode_fsm = require('./mode.fsm.js');
|
||||
var hotkeys = require('./hotkeys.fsm.js');
|
||||
var toolbox_fsm = require('./toolbox.fsm.js');
|
||||
@ -57,6 +56,9 @@ var NetworkUIController = function($scope,
|
||||
$scope.control_socket = new ReconnectingWebSocket(protocol + "://" + window.location.host + "/network_ui/topology?inventory_id=" + $scope.inventory_id,
|
||||
null,
|
||||
{debug: false, reconnectInterval: 300});
|
||||
$scope.test_socket = new ReconnectingWebSocket(protocol + "://" + window.location.host + "/network_ui/test?inventory_id=" + $scope.inventory_id,
|
||||
null,
|
||||
{debug: false, reconnectInterval: 300});
|
||||
} else {
|
||||
$scope.control_socket = {
|
||||
on_message: util.noop
|
||||
@ -65,6 +67,7 @@ var NetworkUIController = function($scope,
|
||||
$scope.my_location = $location.protocol() + "://" + $location.host() + ':' + $location.port();
|
||||
$scope.history = [];
|
||||
$scope.client_id = 0;
|
||||
$scope.test_client_id = 0;
|
||||
$scope.onMouseDownResult = "";
|
||||
$scope.onMouseUpResult = "";
|
||||
$scope.onMouseEnterResult = "";
|
||||
@ -91,7 +94,6 @@ var NetworkUIController = function($scope,
|
||||
$scope.selected_items = [];
|
||||
$scope.new_link = null;
|
||||
$scope.new_stream = null;
|
||||
$scope.new_group_type = null;
|
||||
$scope.last_key = "";
|
||||
$scope.last_key_code = null;
|
||||
$scope.last_event = null;
|
||||
@ -108,9 +110,7 @@ var NetworkUIController = function($scope,
|
||||
$scope.MIN_ZOOM = 0.1;
|
||||
$scope.device_id_seq = util.natural_numbers(0);
|
||||
$scope.link_id_seq = util.natural_numbers(0);
|
||||
$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.animation_id_seq = util.natural_numbers(0);
|
||||
$scope.overall_toolbox_collapsed = false;
|
||||
@ -180,13 +180,13 @@ var NetworkUIController = function($scope,
|
||||
if (!$scope.recording) {
|
||||
return;
|
||||
}
|
||||
message.sender = $scope.client_id;
|
||||
message.sender = $scope.test_client_id;
|
||||
message.trace_id = $scope.trace_id;
|
||||
message.message_id = $scope.message_id_seq();
|
||||
var data = messages.serialize(message);
|
||||
if (!$scope.disconnected) {
|
||||
try {
|
||||
$scope.control_socket.send(data);
|
||||
$scope.test_socket.send(data);
|
||||
}
|
||||
catch(err) {
|
||||
$scope.initial_messages.push(message);
|
||||
@ -196,15 +196,15 @@ var NetworkUIController = function($scope,
|
||||
|
||||
$scope.onKeyDown = function ($event) {
|
||||
if ($scope.recording) {
|
||||
$scope.send_control_message(new messages.KeyEvent($scope.client_id,
|
||||
$event.key,
|
||||
$event.keyCode,
|
||||
$event.type,
|
||||
$event.altKey,
|
||||
$event.shiftKey,
|
||||
$event.ctrlKey,
|
||||
$event.metaKey,
|
||||
$scope.trace_id));
|
||||
$scope.send_test_message(new messages.KeyEvent($scope.test_client_id,
|
||||
$event.key,
|
||||
$event.keyCode,
|
||||
$event.type,
|
||||
$event.altKey,
|
||||
$event.shiftKey,
|
||||
$event.ctrlKey,
|
||||
$event.metaKey,
|
||||
$scope.trace_id));
|
||||
}
|
||||
$scope.last_event = $event;
|
||||
$scope.last_key = $event.key;
|
||||
@ -215,7 +215,6 @@ var NetworkUIController = function($scope,
|
||||
};
|
||||
|
||||
//Define the FSMs
|
||||
$scope.null_controller = new fsm.FSMController($scope, "null_fsm", null_fsm.Start, $scope);
|
||||
$scope.hotkeys_controller = new fsm.FSMController($scope, "hotkeys_fsm", hotkeys.Start, $scope);
|
||||
$scope.keybindings_controller = new fsm.FSMController($scope, "keybindings_fsm", keybindings.Start, $scope);
|
||||
$scope.view_controller = new fsm.FSMController($scope, "view_fsm", view.Start, $scope);
|
||||
@ -325,9 +324,13 @@ var NetworkUIController = function($scope,
|
||||
|
||||
|
||||
$scope.first_channel = new fsm.Channel(null,
|
||||
$scope.test_controller,
|
||||
$scope.mode_controller,
|
||||
$scope);
|
||||
|
||||
$scope.test_channel = new fsm.Channel(null,
|
||||
$scope.test_controller,
|
||||
$scope);
|
||||
|
||||
var getMouseEventResult = function (mouseEvent) {
|
||||
return "(" + mouseEvent.x + ", " + mouseEvent.y + ")";
|
||||
};
|
||||
@ -508,7 +511,7 @@ var NetworkUIController = function($scope,
|
||||
$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.trace_id));
|
||||
$scope.send_test_message(new messages.MouseEvent($scope.test_client_id, $event.x, $event.y, $event.type, $scope.trace_id));
|
||||
}
|
||||
$scope.last_event = $event;
|
||||
$scope.first_channel.send('MouseDown', $event);
|
||||
@ -519,7 +522,7 @@ var NetworkUIController = function($scope,
|
||||
$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.trace_id));
|
||||
$scope.send_test_message(new messages.MouseEvent($scope.test_client_id, $event.x, $event.y, $event.type, $scope.trace_id));
|
||||
}
|
||||
$scope.last_event = $event;
|
||||
$scope.first_channel.send('MouseUp', $event);
|
||||
@ -530,7 +533,7 @@ var NetworkUIController = function($scope,
|
||||
$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.trace_id));
|
||||
$scope.send_test_message(new messages.MouseEvent($scope.test_client_id, $event.x, $event.y, $event.type, $scope.trace_id));
|
||||
}
|
||||
$scope.onMouseLeaveResult = getMouseEventResult($event);
|
||||
$scope.cursor.hidden = true;
|
||||
@ -540,7 +543,7 @@ var NetworkUIController = function($scope,
|
||||
$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.trace_id));
|
||||
$scope.send_test_message(new messages.MouseEvent($scope.test_client_id, $event.x, $event.y, $event.type, $scope.trace_id));
|
||||
}
|
||||
//var coords = getCrossBrowserElementCoords($event);
|
||||
$scope.cursor.hidden = false;
|
||||
@ -557,7 +560,7 @@ var NetworkUIController = function($scope,
|
||||
$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.trace_id));
|
||||
$scope.send_test_message(new messages.MouseEvent($scope.test_client_id, $event.x, $event.y, $event.type, $scope.trace_id));
|
||||
}
|
||||
$scope.onMouseOverResult = getMouseEventResult($event);
|
||||
$scope.cursor.hidden = false;
|
||||
@ -572,7 +575,7 @@ var NetworkUIController = function($scope,
|
||||
var deltaX = $event.deltaX;
|
||||
var deltaY = $event.deltaY;
|
||||
if ($scope.recording) {
|
||||
$scope.send_control_message(new messages.MouseWheelEvent($scope.client_id, delta, deltaX, deltaY, $event.type, $event.originalEvent.metaKey, $scope.trace_id));
|
||||
$scope.send_test_message(new messages.MouseWheelEvent($scope.test_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]);
|
||||
@ -679,12 +682,12 @@ var NetworkUIController = function($scope,
|
||||
links[i].remote_selected = false;
|
||||
$scope.links.splice(index, 1);
|
||||
$scope.send_control_message(new messages.LinkDestroy($scope.client_id,
|
||||
links[i].id,
|
||||
links[i].from_device.id,
|
||||
links[i].to_device.id,
|
||||
links[i].from_interface.id,
|
||||
links[i].to_interface.id,
|
||||
links[i].name));
|
||||
links[i].id,
|
||||
links[i].from_device.id,
|
||||
links[i].to_device.id,
|
||||
links[i].from_interface.id,
|
||||
links[i].to_interface.id,
|
||||
links[i].name));
|
||||
}
|
||||
}
|
||||
for (i = 0; i < devices.length; i++) {
|
||||
@ -693,12 +696,12 @@ var NetworkUIController = function($scope,
|
||||
$scope.devices.splice(index, 1);
|
||||
$scope.$emit('removeSearchOption', devices[i]);
|
||||
$scope.send_control_message(new messages.DeviceDestroy($scope.client_id,
|
||||
devices[i].id,
|
||||
devices[i].x,
|
||||
devices[i].y,
|
||||
devices[i].name,
|
||||
devices[i].type,
|
||||
devices[i].host_id));
|
||||
devices[i].id,
|
||||
devices[i].x,
|
||||
devices[i].y,
|
||||
devices[i].name,
|
||||
devices[i].type,
|
||||
devices[i].host_id));
|
||||
}
|
||||
for (j = 0; j < all_links.length; j++) {
|
||||
if (all_links[j].to_device === devices[i] ||
|
||||
@ -823,38 +826,30 @@ var NetworkUIController = function($scope,
|
||||
$scope.jump_to_animation(v_center.x, v_center.y, scale, false);
|
||||
});
|
||||
|
||||
$scope.onDeployButton = function () {
|
||||
$scope.send_control_message(new messages.Deploy($scope.client_id));
|
||||
};
|
||||
|
||||
$scope.onDestroyButton = function () {
|
||||
$scope.send_control_message(new messages.Destroy($scope.client_id));
|
||||
};
|
||||
|
||||
$scope.onRecordButton = function () {
|
||||
$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, $scope.trace_id),
|
||||
new messages.ViewPort($scope.client_id,
|
||||
$scope.current_scale,
|
||||
$scope.panX,
|
||||
$scope.panY,
|
||||
$scope.trace_id),
|
||||
new messages.Snapshot($scope.client_id,
|
||||
$scope.devices,
|
||||
$scope.links,
|
||||
0,
|
||||
$scope.trace_id)]));
|
||||
$scope.send_test_message(new messages.MultipleMessage($scope.test_client_id,
|
||||
[new messages.StartRecording($scope.test_client_id, $scope.trace_id),
|
||||
new messages.ViewPort($scope.test_client_id,
|
||||
$scope.current_scale,
|
||||
$scope.panX,
|
||||
$scope.panY,
|
||||
$scope.trace_id),
|
||||
new messages.Snapshot($scope.test_client_id,
|
||||
$scope.devices,
|
||||
$scope.links,
|
||||
0,
|
||||
$scope.trace_id)]));
|
||||
} else {
|
||||
$scope.send_control_message(new messages.MultipleMessage($scope.client_id,
|
||||
[new messages.Snapshot($scope.client_id,
|
||||
$scope.devices,
|
||||
$scope.links,
|
||||
1,
|
||||
$scope.trace_id),
|
||||
new messages.StopRecording($scope.client_id, $scope.trace_id)]));
|
||||
$scope.send_test_message(new messages.MultipleMessage($scope.test_client_id,
|
||||
[new messages.Snapshot($scope.test_client_id,
|
||||
$scope.devices,
|
||||
$scope.links,
|
||||
1,
|
||||
$scope.trace_id),
|
||||
new messages.StopRecording($scope.test_client_id, $scope.trace_id)]));
|
||||
}
|
||||
};
|
||||
|
||||
@ -909,7 +904,7 @@ var NetworkUIController = function($scope,
|
||||
|
||||
$scope.test_results = [];
|
||||
$scope.current_tests = $scope.tests.slice();
|
||||
$scope.first_channel.send("EnableTest", new messages.EnableTest());
|
||||
$scope.test_channel.send("EnableTest", new messages.EnableTest());
|
||||
};
|
||||
|
||||
$scope.all_buttons = [];
|
||||
@ -961,35 +956,6 @@ var NetworkUIController = function($scope,
|
||||
$scope.devices.push(device);
|
||||
};
|
||||
|
||||
$scope.onGroupCreate = function(data) {
|
||||
$scope.create_group(data);
|
||||
};
|
||||
|
||||
$scope.create_group = function(data) {
|
||||
var group = new models.Group(data.id,
|
||||
data.name,
|
||||
data.type,
|
||||
data.x1,
|
||||
data.y1,
|
||||
data.x2,
|
||||
data.y2,
|
||||
false);
|
||||
$scope.group_id_seq = util.natural_numbers(data.id);
|
||||
$scope.groups.push(group);
|
||||
};
|
||||
|
||||
$scope.breadcrumbGroups = function(){
|
||||
let breadcrumbGroups = [];
|
||||
for(var i = 0; i < $scope.groups.length; i++){
|
||||
let group = $scope.groups[i];
|
||||
if(group.is_in_breadcrumb($scope.view_port)){
|
||||
group.distance = util.distance(group.x1, group.y1, group.x2, group.y2);
|
||||
breadcrumbGroups.push(group);
|
||||
}
|
||||
}
|
||||
return breadcrumbGroups;
|
||||
};
|
||||
|
||||
$scope.forDevice = function(device_id, data, fn) {
|
||||
var i = 0;
|
||||
for (i = 0; i < $scope.devices.length; i++) {
|
||||
@ -1025,16 +991,6 @@ var NetworkUIController = function($scope,
|
||||
}
|
||||
};
|
||||
|
||||
$scope.forGroup = function(group_id, data, fn) {
|
||||
var i = 0;
|
||||
for (i = 0; i < $scope.groups.length; i++) {
|
||||
if ($scope.groups[i].id === group_id) {
|
||||
fn($scope.groups[i], data);
|
||||
break;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
$scope.onDeviceLabelEdit = function(data) {
|
||||
$scope.edit_device_label(data);
|
||||
};
|
||||
@ -1201,88 +1157,6 @@ var NetworkUIController = function($scope,
|
||||
}
|
||||
};
|
||||
|
||||
$scope.onGroupLabelEdit = function(data) {
|
||||
$scope.edit_group_label(data);
|
||||
};
|
||||
|
||||
$scope.edit_group_label = function(data) {
|
||||
$scope.forGroup(data.id, data, function(group, data) {
|
||||
group.name = data.name;
|
||||
});
|
||||
};
|
||||
|
||||
$scope.redo = function(type_data) {
|
||||
var type = type_data[0];
|
||||
var data = type_data[1];
|
||||
|
||||
if (type === "DeviceMove") {
|
||||
$scope.move_device(data);
|
||||
}
|
||||
|
||||
if (type === "DeviceCreate") {
|
||||
$scope.create_device(data);
|
||||
}
|
||||
|
||||
if (type === "DeviceDestroy") {
|
||||
$scope.destroy_device(data);
|
||||
}
|
||||
|
||||
if (type === "DeviceLabelEdit") {
|
||||
$scope.edit_device_label(data);
|
||||
}
|
||||
|
||||
if (type === "LinkCreate") {
|
||||
$scope.create_link(data);
|
||||
}
|
||||
|
||||
if (type === "LinkDestroy") {
|
||||
$scope.destroy_link(data);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
$scope.undo = function(type_data) {
|
||||
var type = type_data[0];
|
||||
var data = type_data[1];
|
||||
var inverted_data;
|
||||
|
||||
if (type === "DeviceMove") {
|
||||
inverted_data = angular.copy(data);
|
||||
inverted_data.x = data.previous_x;
|
||||
inverted_data.y = data.previous_y;
|
||||
$scope.move_device(inverted_data);
|
||||
}
|
||||
|
||||
if (type === "DeviceCreate") {
|
||||
$scope.destroy_device(data);
|
||||
}
|
||||
|
||||
if (type === "DeviceDestroy") {
|
||||
inverted_data = new messages.DeviceCreate(data.sender,
|
||||
data.id,
|
||||
data.previous_x,
|
||||
data.previous_y,
|
||||
data.previous_name,
|
||||
data.previous_type,
|
||||
data.previous_host_id);
|
||||
$scope.create_device(inverted_data);
|
||||
}
|
||||
|
||||
if (type === "DeviceLabelEdit") {
|
||||
inverted_data = angular.copy(data);
|
||||
inverted_data.name = data.previous_name;
|
||||
$scope.edit_device_label(inverted_data);
|
||||
}
|
||||
|
||||
if (type === "LinkCreate") {
|
||||
$scope.destroy_link(data);
|
||||
}
|
||||
|
||||
if (type === "LinkDestroy") {
|
||||
$scope.create_link(data);
|
||||
}
|
||||
};
|
||||
|
||||
$scope.onClientId = function(data) {
|
||||
$scope.client_id = data;
|
||||
$scope.send_initial_messages();
|
||||
@ -1295,7 +1169,6 @@ var NetworkUIController = function($scope,
|
||||
$scope.current_scale = data.scale;
|
||||
$scope.$emit('awxNet-UpdateZoomWidget', $scope.current_scale, true);
|
||||
$scope.link_id_seq = util.natural_numbers(data.link_id_seq);
|
||||
$scope.group_id_seq = util.natural_numbers(data.group_id_seq);
|
||||
$scope.device_id_seq = util.natural_numbers(data.device_id_seq);
|
||||
};
|
||||
|
||||
@ -1326,99 +1199,11 @@ var NetworkUIController = function($scope,
|
||||
}
|
||||
};
|
||||
|
||||
$scope.onToolboxItem = function (data) {
|
||||
if (data.toolbox_name === "Site") {
|
||||
var site = util.parse_variables(data.data);
|
||||
var i = 0;
|
||||
var j = 0;
|
||||
var site_copy = new models.Group(site.id,
|
||||
site.name,
|
||||
site.type,
|
||||
site.x1,
|
||||
site.y1,
|
||||
site.x2,
|
||||
site.y2,
|
||||
false);
|
||||
var device, device_copy;
|
||||
var process, process_copy;
|
||||
var intf, intf_copy;
|
||||
var device_map = {};
|
||||
for (i = 0; i < site.devices.length; i++) {
|
||||
device = site.devices[i];
|
||||
device_copy = new models.Device(device.id,
|
||||
device.name,
|
||||
device.x,
|
||||
device.y,
|
||||
device.type);
|
||||
device_map[device.id] = device_copy;
|
||||
device_copy.interface_map = {};
|
||||
site_copy.devices.push(device_copy);
|
||||
for(j=0; j < device.interfaces.length; j++) {
|
||||
intf = device.interfaces[j];
|
||||
intf_copy = new models.Interface(intf.id, intf.name);
|
||||
intf_copy.device = device_copy;
|
||||
device_copy.interfaces.push(intf_copy);
|
||||
device_copy.interface_map[intf.id] = intf_copy;
|
||||
}
|
||||
for(j=0; j < device.processes.length; j++) {
|
||||
process = device.processes[j];
|
||||
process_copy = new models.Process(process.id,
|
||||
process.name,
|
||||
process.type,
|
||||
process.x,
|
||||
process.y);
|
||||
process_copy.device = device;
|
||||
device_copy.processes.push(process_copy);
|
||||
}
|
||||
}
|
||||
var group, group_copy;
|
||||
for (i = 0; i < site.groups.length; i++) {
|
||||
group = site.groups[i];
|
||||
group_copy = new models.Group(group.id,
|
||||
group.name,
|
||||
group.type,
|
||||
group.x1,
|
||||
group.y1,
|
||||
group.x2,
|
||||
group.y2,
|
||||
false);
|
||||
site_copy.groups.push(group_copy);
|
||||
}
|
||||
var link, link_copy;
|
||||
for (i = 0; i < site.links.length; i++) {
|
||||
link = site.links[i];
|
||||
link_copy = new models.Link(link.id,
|
||||
device_map[link.from_device_id],
|
||||
device_map[link.to_device_id],
|
||||
device_map[link.from_device_id].interface_map[link.from_interface_id],
|
||||
device_map[link.to_device_id].interface_map[link.to_interface_id]);
|
||||
link_copy.name = link.name;
|
||||
device_map[link.from_device_id].interface_map[link.from_interface_id].link = link_copy;
|
||||
device_map[link.to_device_id].interface_map[link.to_interface_id].link = link_copy;
|
||||
site_copy.links.push(link_copy);
|
||||
}
|
||||
|
||||
var stream, stream_copy;
|
||||
|
||||
for(i = 0; i < site.streams.length;i++) {
|
||||
stream = site.streams[i];
|
||||
stream_copy = new models.Stream(stream.id,
|
||||
device_map[stream.from_device],
|
||||
device_map[stream.to_device],
|
||||
stream.label);
|
||||
site_copy.streams.push(stream_copy);
|
||||
}
|
||||
$scope.site_toolbox.items.push(site_copy);
|
||||
}
|
||||
};
|
||||
|
||||
$scope.onSnapshot = function (data) {
|
||||
|
||||
//Erase the existing state
|
||||
$scope.devices = [];
|
||||
$scope.links = [];
|
||||
$scope.groups = [];
|
||||
$scope.streams = [];
|
||||
|
||||
var device_map = {};
|
||||
var device_interface_map = {};
|
||||
@ -1430,17 +1215,11 @@ var NetworkUIController = function($scope,
|
||||
var new_intf = null;
|
||||
var max_device_id = null;
|
||||
var max_link_id = null;
|
||||
var max_group_id = null;
|
||||
var max_stream_id = null;
|
||||
var min_x = null;
|
||||
var min_y = null;
|
||||
var max_x = null;
|
||||
var max_y = null;
|
||||
var new_link = null;
|
||||
var new_group = null;
|
||||
var process = null;
|
||||
var new_process = null;
|
||||
var new_stream = null;
|
||||
|
||||
//Build the devices
|
||||
for (i = 0; i < data.devices.length; i++) {
|
||||
@ -1478,16 +1257,6 @@ var NetworkUIController = function($scope,
|
||||
$scope.devices.push(new_device);
|
||||
device_map[device.id] = new_device;
|
||||
device_interface_map[device.id] = {};
|
||||
for (j = 0; j < device.processes.length; j++) {
|
||||
process = device.processes[j];
|
||||
new_process = (new models.Process(process.id,
|
||||
process.name,
|
||||
process.process_type,
|
||||
0,
|
||||
0));
|
||||
new_process.device = new_device;
|
||||
new_device.processes.push(new_process);
|
||||
}
|
||||
for (j = 0; j < device.interfaces.length; j++) {
|
||||
intf = device.interfaces[j];
|
||||
new_intf = (new models.Interface(intf.id,
|
||||
@ -1516,50 +1285,6 @@ var NetworkUIController = function($scope,
|
||||
device_interface_map[link.to_device_id][link.to_interface_id].link = new_link;
|
||||
}
|
||||
|
||||
//Build the streams
|
||||
var stream = null;
|
||||
for (i = 0; i < data.streams.length; i++) {
|
||||
stream = data.streams[i];
|
||||
if (max_stream_id === null || stream.id > max_stream_id) {
|
||||
max_stream_id = stream.id;
|
||||
}
|
||||
new_stream = new models.Stream(stream.id,
|
||||
device_map[stream.from_id],
|
||||
device_map[stream.to_id],
|
||||
stream.label);
|
||||
$scope.streams.push(new_stream);
|
||||
}
|
||||
|
||||
//Build the groups
|
||||
var group = null;
|
||||
for (i = 0; i < data.groups.length; i++) {
|
||||
group = data.groups[i];
|
||||
if (max_group_id === null || group.id > max_group_id) {
|
||||
max_group_id = group.id;
|
||||
}
|
||||
new_group = new models.Group(group.id,
|
||||
group.name,
|
||||
group.group_type,
|
||||
group.x1,
|
||||
group.y1,
|
||||
group.x2,
|
||||
group.y2,
|
||||
false);
|
||||
new_group.group_id = group.inventory_group_id;
|
||||
if (group.members !== undefined) {
|
||||
for (j=0; j < group.members.length; j++) {
|
||||
new_group.devices.push(device_map[group.members[j]]);
|
||||
}
|
||||
}
|
||||
$scope.groups.push(new_group);
|
||||
}
|
||||
|
||||
//Update group membership
|
||||
|
||||
for (i = 0; i < $scope.groups.length; i++) {
|
||||
$scope.groups[i].update_membership($scope.devices, $scope.groups);
|
||||
}
|
||||
|
||||
var diff_x;
|
||||
var diff_y;
|
||||
|
||||
@ -1592,18 +1317,9 @@ var NetworkUIController = function($scope,
|
||||
if (max_link_id !== null) {
|
||||
$scope.link_id_seq = util.natural_numbers(max_link_id);
|
||||
}
|
||||
//Update the stream_id_seq to be greater than all stream ids to prevent duplicate ids.
|
||||
if (max_stream_id !== null) {
|
||||
$scope.stream_id_seq = util.natural_numbers(max_stream_id);
|
||||
}
|
||||
//Update the group_id_seq to be greater than all group ids to prevent duplicate ids.
|
||||
if (max_group_id !== null) {
|
||||
$scope.group_id_seq = util.natural_numbers(max_group_id);
|
||||
}
|
||||
|
||||
$scope.updateInterfaceDots();
|
||||
$scope.$emit('instatiateSelect', $scope.devices);
|
||||
$scope.$emit('awxNet-breadcrumbGroups', $scope.breadcrumbGroups());
|
||||
$scope.update_device_variables();
|
||||
};
|
||||
|
||||
@ -1656,6 +1372,15 @@ var NetworkUIController = function($scope,
|
||||
//ignore
|
||||
};
|
||||
|
||||
$scope.test_socket.onmessage = function(message) {
|
||||
$scope.test_channel.send('Message', message);
|
||||
$scope.$apply();
|
||||
};
|
||||
|
||||
$scope.test_socket.onopen = function() {
|
||||
//ignore
|
||||
};
|
||||
|
||||
$scope.send_initial_messages = function() {
|
||||
var i = 0;
|
||||
var messages_to_send = $scope.initial_messages;
|
||||
@ -1664,9 +1389,9 @@ var NetworkUIController = function($scope,
|
||||
$scope.initial_messages = [];
|
||||
for(i = 0; i < messages_to_send.length; i++) {
|
||||
message = messages_to_send[i];
|
||||
message.sender = $scope.client_id;
|
||||
message.sender = $scope.test_client_id;
|
||||
data = messages.serialize(message);
|
||||
$scope.control_socket.send(data);
|
||||
$scope.test_socket.send(data);
|
||||
}
|
||||
};
|
||||
|
||||
@ -1674,6 +1399,25 @@ var NetworkUIController = function($scope,
|
||||
if ($scope.control_socket.readyState === WebSocket.OPEN) {
|
||||
$scope.control_socket.onopen();
|
||||
}
|
||||
// Call onopen directly if $scope.test_socket is already open
|
||||
if ($scope.test_socket.readyState === WebSocket.OPEN) {
|
||||
$scope.test_socket.onopen();
|
||||
}
|
||||
|
||||
$scope.send_test_message = function (message) {
|
||||
var i = 0;
|
||||
message.sender = $scope.test_client_id;
|
||||
message.message_id = $scope.message_id_seq();
|
||||
if (message.constructor.name === "MultipleMessage") {
|
||||
for (i=0; i < message.messages.length; i++) {
|
||||
message.messages[i].message_id = $scope.message_id_seq();
|
||||
}
|
||||
}
|
||||
var data = messages.serialize(message);
|
||||
if (!$scope.disconnected) {
|
||||
$scope.test_socket.send(data);
|
||||
}
|
||||
};
|
||||
|
||||
$scope.send_control_message = function (message) {
|
||||
var i = 0;
|
||||
@ -1811,13 +1555,10 @@ var NetworkUIController = function($scope,
|
||||
$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.keybindings_controller.state = keybindings.Start;
|
||||
|
||||
@ -1,36 +0,0 @@
|
||||
/* Copyright (c) 2017 Red Hat, Inc. */
|
||||
var inherits = require('inherits');
|
||||
var fsm = require('./fsm.js');
|
||||
|
||||
function _State () {
|
||||
}
|
||||
inherits(_State, fsm._State);
|
||||
|
||||
|
||||
function _Start () {
|
||||
this.name = 'Start';
|
||||
}
|
||||
inherits(_Start, _State);
|
||||
var Start = new _Start();
|
||||
exports.Start = Start;
|
||||
|
||||
function _Ready () {
|
||||
this.name = 'Ready';
|
||||
}
|
||||
inherits(_Ready, _State);
|
||||
var Ready = new _Ready();
|
||||
exports.Ready = Ready;
|
||||
|
||||
|
||||
|
||||
|
||||
_Start.prototype.start = function (controller) {
|
||||
|
||||
controller.changeState(Ready);
|
||||
|
||||
};
|
||||
_Start.prototype.start.transitions = ['Ready'];
|
||||
|
||||
|
||||
|
||||
|
||||
@ -51,7 +51,31 @@ var Reporting = new _Reporting();
|
||||
exports.Reporting = Reporting;
|
||||
|
||||
|
||||
_State.prototype.onMessage = function(controller, msg_type, message) {
|
||||
|
||||
var type_data = JSON.parse(message.data);
|
||||
var type = type_data[0];
|
||||
var data = type_data[1];
|
||||
|
||||
controller.handle_message(type, data);
|
||||
};
|
||||
|
||||
_State.prototype.onid = function(controller, msg_type, message) {
|
||||
controller.scope.test_client_id = message;
|
||||
};
|
||||
|
||||
_State.prototype.onTestCase = function(controller, 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]));
|
||||
};
|
||||
|
||||
_Disabled.prototype.onEnableTest = function (controller) {
|
||||
|
||||
@ -93,15 +117,15 @@ _Reporting.prototype.start = function (controller) {
|
||||
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));
|
||||
controller.scope.send_test_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.scope.send_test_message(new messages.Coverage(controller.scope.client_id, window.__coverage__, test_result.id));
|
||||
}
|
||||
controller.changeState(Loading);
|
||||
};
|
||||
@ -144,15 +168,15 @@ _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));
|
||||
controller.scope.send_test_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.scope.send_test_message(new messages.Coverage(controller.scope.client_id, window.__coverage__, load_id));
|
||||
}
|
||||
|
||||
controller.changeState(Loading);
|
||||
|
||||
@ -2,7 +2,6 @@
|
||||
var inherits = require('inherits');
|
||||
var fsm = require('./fsm.js');
|
||||
var util = require('./util.js');
|
||||
var models = require('./models.js');
|
||||
|
||||
function _State () {
|
||||
}
|
||||
@ -176,6 +175,13 @@ _Present.prototype.onViewPort = function(controller, msg_type, message) {
|
||||
controller.scope.current_scale = message.scale;
|
||||
controller.scope.panX = message.panX;
|
||||
controller.scope.panY = message.panY;
|
||||
if (message.graph_width !== undefined) {
|
||||
controller.scope.graph.width = message.graph_width;
|
||||
}
|
||||
if (message.graph_height !== undefined) {
|
||||
controller.scope.graph.height = message.graph_height;
|
||||
}
|
||||
controller.scope.update_toolbox_heights();
|
||||
controller.scope.updateScaledXY();
|
||||
controller.scope.updatePanAndScale();
|
||||
};
|
||||
@ -224,19 +230,36 @@ _Present.prototype.onMouseWheelEvent = function(controller, msg_type, message) {
|
||||
}
|
||||
};
|
||||
|
||||
_Present.prototype.onTestCase = function(controller, 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.onRecordButton = function(controller) {
|
||||
controller.scope.onRecordButton();
|
||||
};
|
||||
|
||||
_Present.prototype.onExportButton = function(controller) {
|
||||
controller.scope.onExportButton();
|
||||
};
|
||||
|
||||
_Present.prototype.onExportYamlButton = function(controller) {
|
||||
controller.scope.onExportYamlButton();
|
||||
};
|
||||
|
||||
_Present.prototype.onDownloadTraceButton = function(controller) {
|
||||
controller.scope.onDownloadTraceButton();
|
||||
};
|
||||
|
||||
_Present.prototype.onDownloadRecordingButton = function(controller) {
|
||||
controller.scope.onDownloadRecordingButton();
|
||||
};
|
||||
|
||||
_Present.prototype.onNoop = function(controller, msg_type, message) {
|
||||
|
||||
};
|
||||
|
||||
_Present.prototype.onTestCompleted = function(controller, msg_type, message) {
|
||||
|
||||
controller.scope.test_channel.send(msg_type, message);
|
||||
}
|
||||
|
||||
|
||||
_Present.prototype.onError = function(controller, msg_type, message) {
|
||||
throw new Error("ServerError: " + message);
|
||||
};
|
||||
|
||||
@ -85,7 +85,6 @@ _Scale.prototype.onMouseWheel = function (controller, msg_type, message) {
|
||||
var item = controller.scope.context_menus[0];
|
||||
item.enabled = false;
|
||||
controller.scope.$emit('awxNet-UpdateZoomWidget', controller.scope.current_scale, true);
|
||||
controller.scope.$emit('awxNet-breadcrumbGroups', controller.scope.breadcrumbGroups());
|
||||
controller.scope.updatePanAndScale();
|
||||
controller.changeState(Ready);
|
||||
};
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user