fixed issues executing xml from gui, added more tests for testing message handling

This commit is contained in:
Blake Harnden 2019-06-24 15:49:12 -07:00
parent 588a0932d3
commit 4f4605163f
3 changed files with 344 additions and 92 deletions

View file

@ -1396,7 +1396,7 @@ class CoreHandler(socketserver.BaseRequestHandler):
open_file.write(data)
return ()
self.session.node_add_file(node_num, source_name, file_name, data)
self.session.add_node_file(node_num, source_name, file_name, data)
else:
raise NotImplementedError
@ -1639,10 +1639,10 @@ class CoreHandler(socketserver.BaseRequestHandler):
logging.info("request to connect to session %s", session_id)
# remove client from session broker and shutdown if needed
self.remove_session_handlers()
self.session.broker.session_clients.remove(self)
if not self.session.broker.session_clients and not self.session.is_active():
self.coreemu.delete_session(self.session.id)
self.remove_session_handlers()
# set session to join
self.session = session

View file

@ -628,6 +628,9 @@ class Session(object):
# clear out existing session
self.clear()
if start:
self.set_state(EventTypes.CONFIGURATION_STATE)
# write out xml file
CoreXmlReader(self).read(file_name)

View file

@ -1,104 +1,21 @@
"""
Unit tests for testing with a CORE switch.
Tests for testing tlv message handling.
"""
import os
import time
import mock
import pytest
from core.api.tlv import coreapi
from core.api.tlv.coreapi import CoreExecuteTlv
from core.emulator.enumerations import EventTlvs
from core.emulator.enumerations import EventTlvs, SessionTlvs, EventTypes, FileTlvs, RegisterTlvs
from core.emulator.enumerations import ExecuteTlvs
from core.emulator.enumerations import LinkTlvs
from core.emulator.enumerations import LinkTypes
from core.emulator.enumerations import MessageFlags
from core.emulator.enumerations import MessageTypes
from core.emulator.enumerations import NodeTypes, NodeTlvs
from core.nodes.ipaddress import Ipv4Prefix
def command_message(node, command):
"""
Create an execute command TLV message.
:param node: node to execute command for
:param command: command to execute
:return: packed execute message
"""
tlv_data = CoreExecuteTlv.pack(ExecuteTlvs.NODE.value, node.id)
tlv_data += CoreExecuteTlv.pack(ExecuteTlvs.NUMBER.value, 1)
tlv_data += CoreExecuteTlv.pack(ExecuteTlvs.COMMAND.value, command)
return coreapi.CoreExecMessage.pack(MessageFlags.STRING.value | MessageFlags.TEXT.value, tlv_data)
def state_message(state):
"""
Create a event TLV message for a new state.
:param core.enumerations.EventTypes state: state to create message for
:return: packed event message
"""
tlv_data = coreapi.CoreEventTlv.pack(EventTlvs.TYPE.value, state.value)
return coreapi.CoreEventMessage.pack(0, tlv_data)
def switch_link_message(switch, node, address, prefix_len):
"""
Create a link TLV message for node to a switch, with the provided address and prefix length.
:param switch: switch for link
:param node: node for link
:param address: address node on link
:param prefix_len: prefix length of address
:return: packed link message
"""
tlv_data = coreapi.CoreLinkTlv.pack(LinkTlvs.N1_NUMBER.value, switch.id)
tlv_data += coreapi.CoreLinkTlv.pack(LinkTlvs.N2_NUMBER.value, node.id)
tlv_data += coreapi.CoreLinkTlv.pack(LinkTlvs.TYPE.value, LinkTypes.WIRED.value)
tlv_data += coreapi.CoreLinkTlv.pack(LinkTlvs.INTERFACE2_NUMBER.value, 0)
tlv_data += coreapi.CoreLinkTlv.pack(LinkTlvs.INTERFACE2_IP4.value, address)
tlv_data += coreapi.CoreLinkTlv.pack(LinkTlvs.INTERFACE2_IP4_MASK.value, prefix_len)
return coreapi.CoreLinkMessage.pack(MessageFlags.ADD.value, tlv_data)
def run_cmd(node, exec_cmd):
"""
Convenience method for sending commands to a node using the legacy API.
:param node: The node the command should be issued too
:param exec_cmd: A string with the command to be run
:return: Returns the result of the command
"""
# Set up the command api message
# tlv_data = CoreExecuteTlv.pack(ExecuteTlvs.NODE.value, node.id)
# tlv_data += CoreExecuteTlv.pack(ExecuteTlvs.NUMBER.value, 1)
# tlv_data += CoreExecuteTlv.pack(ExecuteTlvs.COMMAND.value, exec_cmd)
# message = coreapi.CoreExecMessage.pack(MessageFlags.STRING.value | MessageFlags.TEXT.value, tlv_data)
message = command_message(node, exec_cmd)
node.session.broker.handlerawmsg(message)
# Now wait for the response
server = node.session.broker.servers["localhost"]
server.sock.settimeout(50.0)
# receive messages until we get our execute response
result = None
status = False
while True:
message_header = server.sock.recv(coreapi.CoreMessage.header_len)
message_type, message_flags, message_length = coreapi.CoreMessage.unpack_header(message_header)
message_data = server.sock.recv(message_length)
# If we get the right response return the results
print("received response message: %s" % message_type)
if message_type == MessageTypes.EXECUTE.value:
message = coreapi.CoreExecMessage(message_flags, message_header, message_data)
result = message.get_tlv(ExecuteTlvs.RESULT.value)
status = message.get_tlv(ExecuteTlvs.STATUS.value)
break
return result, status
class TestGui:
@pytest.mark.parametrize("node_type, model", [
(NodeTypes.DEFAULT, "PC"),
@ -154,14 +71,13 @@ class TestGui:
with pytest.raises(KeyError):
coreserver.session.get_node(node_id)
def test_link_add(self, coreserver):
def test_link_add_node_to_net(self, coreserver):
node_one = 1
coreserver.session.add_node(_id=node_one)
switch = 2
coreserver.session.add_node(_id=switch, _type=NodeTypes.SWITCH)
ip_prefix = Ipv4Prefix("10.0.0.0/24")
interface_one = ip_prefix.addr(node_one)
coreserver.session.add_link(node_one, switch, interface_one)
message = coreapi.CoreLinkMessage.create(MessageFlags.ADD.value, [
(LinkTlvs.N1_NUMBER, node_one),
(LinkTlvs.N2_NUMBER, switch),
@ -176,6 +92,54 @@ class TestGui:
all_links = switch_node.all_link_data(0)
assert len(all_links) == 1
def test_link_add_net_to_node(self, coreserver):
node_one = 1
coreserver.session.add_node(_id=node_one)
switch = 2
coreserver.session.add_node(_id=switch, _type=NodeTypes.SWITCH)
ip_prefix = Ipv4Prefix("10.0.0.0/24")
interface_one = ip_prefix.addr(node_one)
message = coreapi.CoreLinkMessage.create(MessageFlags.ADD.value, [
(LinkTlvs.N1_NUMBER, switch),
(LinkTlvs.N2_NUMBER, node_one),
(LinkTlvs.INTERFACE2_NUMBER, 0),
(LinkTlvs.INTERFACE2_IP4, interface_one),
(LinkTlvs.INTERFACE2_IP4_MASK, 24),
])
coreserver.request_handler.handle_message(message)
switch_node = coreserver.session.get_node(switch)
all_links = switch_node.all_link_data(0)
assert len(all_links) == 1
def test_link_add_node_to_node(self, coreserver):
node_one = 1
coreserver.session.add_node(_id=node_one)
node_two = 2
coreserver.session.add_node(_id=node_two)
ip_prefix = Ipv4Prefix("10.0.0.0/24")
interface_one = ip_prefix.addr(node_one)
interface_two = ip_prefix.addr(node_two)
message = coreapi.CoreLinkMessage.create(MessageFlags.ADD.value, [
(LinkTlvs.N1_NUMBER, node_one),
(LinkTlvs.N2_NUMBER, node_two),
(LinkTlvs.INTERFACE1_NUMBER, 0),
(LinkTlvs.INTERFACE1_IP4, interface_one),
(LinkTlvs.INTERFACE1_IP4_MASK, 24),
(LinkTlvs.INTERFACE2_NUMBER, 0),
(LinkTlvs.INTERFACE2_IP4, interface_two),
(LinkTlvs.INTERFACE2_IP4_MASK, 24),
])
coreserver.request_handler.handle_message(message)
all_links = []
for node_id in coreserver.session.nodes:
node = coreserver.session.nodes[node_id]
all_links += node.all_link_data(0)
assert len(all_links) == 1
def test_link_update(self, coreserver):
node_one = 1
coreserver.session.add_node(_id=node_one)
@ -309,3 +273,288 @@ class TestGui:
switch_node = coreserver.session.get_node(switch)
all_links = switch_node.all_link_data(0)
assert len(all_links) == 0
def test_session_update(self, coreserver):
session_id = coreserver.session.id
name = "test"
message = coreapi.CoreSessionMessage.create(0, [
(SessionTlvs.NUMBER, str(session_id)),
(SessionTlvs.NAME, name),
])
coreserver.request_handler.handle_message(message)
assert coreserver.session.name == name
def test_session_query(self, coreserver):
coreserver.request_handler.dispatch_replies = mock.MagicMock()
message = coreapi.CoreSessionMessage.create(MessageFlags.STRING.value, [])
coreserver.request_handler.handle_message(message)
args, _ = coreserver.request_handler.dispatch_replies.call_args
replies = args[0]
assert len(replies) == 1
def test_session_join(self, coreserver):
coreserver.request_handler.dispatch_replies = mock.MagicMock()
session_id = coreserver.session.id
message = coreapi.CoreSessionMessage.create(MessageFlags.ADD.value, [
(SessionTlvs.NUMBER, str(session_id)),
])
coreserver.request_handler.handle_message(message)
assert coreserver.request_handler.session.id == session_id
def test_session_delete(self, coreserver):
assert len(coreserver.server.coreemu.sessions) == 1
session_id = coreserver.session.id
message = coreapi.CoreSessionMessage.create(MessageFlags.DELETE.value, [
(SessionTlvs.NUMBER, str(session_id)),
])
coreserver.request_handler.handle_message(message)
assert len(coreserver.server.coreemu.sessions) == 0
def test_file_hook_add(self, coreserver):
state = EventTypes.DATACOLLECT_STATE.value
assert coreserver.session._hooks.get(state) is None
file_name = "test.sh"
file_data = "echo hello"
message = coreapi.CoreFileMessage.create(MessageFlags.ADD.value, [
(FileTlvs.TYPE, "hook:%s" % state),
(FileTlvs.NAME, file_name),
(FileTlvs.DATA, file_data),
])
coreserver.request_handler.handle_message(message)
hooks = coreserver.session._hooks.get(state)
assert len(hooks) == 1
name, data = hooks[0]
assert file_name == name
assert file_data == data
def test_file_service_file_set(self, coreserver):
node = coreserver.session.add_node()
service = "DefaultRoute"
file_name = "defaultroute.sh"
file_data = "echo hello"
message = coreapi.CoreFileMessage.create(MessageFlags.ADD.value, [
(FileTlvs.NODE, node.id),
(FileTlvs.TYPE, "service:%s" % service),
(FileTlvs.NAME, file_name),
(FileTlvs.DATA, file_data),
])
coreserver.request_handler.handle_message(message)
service_file = coreserver.session.services.get_service_file(node, service, file_name)
assert file_data == service_file.data
def test_file_node_file_copy(self, coreserver):
file_name = "/var/log/test/node.log"
node = coreserver.session.add_node()
node.makenodedir()
file_data = "echo hello"
message = coreapi.CoreFileMessage.create(MessageFlags.ADD.value, [
(FileTlvs.NODE, node.id),
(FileTlvs.NAME, file_name),
(FileTlvs.DATA, file_data),
])
coreserver.request_handler.handle_message(message)
directory, basename = os.path.split(file_name)
created_directory = directory[1:].replace("/", ".")
create_path = os.path.join(node.nodedir, created_directory, basename)
assert os.path.exists(create_path)
def test_exec_node_tty(self, coreserver):
coreserver.request_handler.dispatch_replies = mock.MagicMock()
node = coreserver.session.add_node()
node.startup()
message = coreapi.CoreExecMessage.create(MessageFlags.TTY.value, [
(ExecuteTlvs.NODE, node.id),
(ExecuteTlvs.NUMBER, 1),
(ExecuteTlvs.COMMAND, "bash")
])
coreserver.request_handler.handle_message(message)
args, _ = coreserver.request_handler.dispatch_replies.call_args
replies = args[0]
assert len(replies) == 1
def test_exec_local_command(self, coreserver):
coreserver.request_handler.dispatch_replies = mock.MagicMock()
node = coreserver.session.add_node()
node.startup()
message = coreapi.CoreExecMessage.create(
MessageFlags.TEXT.value | MessageFlags.LOCAL.value, [
(ExecuteTlvs.NODE, node.id),
(ExecuteTlvs.NUMBER, 1),
(ExecuteTlvs.COMMAND, "echo hello")
])
coreserver.request_handler.handle_message(message)
args, _ = coreserver.request_handler.dispatch_replies.call_args
replies = args[0]
assert len(replies) == 1
def test_exec_node_command(self, coreserver):
coreserver.request_handler.dispatch_replies = mock.MagicMock()
node = coreserver.session.add_node()
node.startup()
message = coreapi.CoreExecMessage.create(
MessageFlags.TEXT.value, [
(ExecuteTlvs.NODE, node.id),
(ExecuteTlvs.NUMBER, 1),
(ExecuteTlvs.COMMAND, "echo hello")
])
coreserver.request_handler.handle_message(message)
args, _ = coreserver.request_handler.dispatch_replies.call_args
replies = args[0]
assert len(replies) == 1
@pytest.mark.parametrize("state", [
EventTypes.SHUTDOWN_STATE,
EventTypes.RUNTIME_STATE,
EventTypes.DATACOLLECT_STATE,
EventTypes.CONFIGURATION_STATE,
EventTypes.DEFINITION_STATE
])
def test_event_state(self, coreserver, state):
message = coreapi.CoreEventMessage.create(0, [
(EventTlvs.TYPE, state.value),
])
coreserver.request_handler.handle_message(message)
assert coreserver.session.state == state.value
def test_event_schedule(self, coreserver):
coreserver.session.add_event = mock.MagicMock()
node = coreserver.session.add_node()
message = coreapi.CoreEventMessage.create(MessageFlags.ADD.value, [
(EventTlvs.TYPE, EventTypes.SCHEDULED.value),
(EventTlvs.TIME, str(time.time() + 100)),
(EventTlvs.NODE, node.id),
(EventTlvs.NAME, "event"),
(EventTlvs.DATA, "data"),
])
coreserver.request_handler.handle_message(message)
coreserver.session.add_event.assert_called_once()
def test_event_save_xml(self, coreserver, tmpdir):
xml_file = tmpdir.join("session.xml")
file_path = xml_file.strpath
coreserver.session.add_node()
message = coreapi.CoreEventMessage.create(0, [
(EventTlvs.TYPE, EventTypes.FILE_SAVE.value),
(EventTlvs.NAME, file_path),
])
coreserver.request_handler.handle_message(message)
assert os.path.exists(file_path)
def test_event_open_xml(self, coreserver, tmpdir):
xml_file = tmpdir.join("session.xml")
file_path = xml_file.strpath
node = coreserver.session.add_node()
coreserver.session.save_xml(file_path)
coreserver.session.delete_node(node.id)
message = coreapi.CoreEventMessage.create(0, [
(EventTlvs.TYPE, EventTypes.FILE_OPEN.value),
(EventTlvs.NAME, file_path),
])
coreserver.request_handler.handle_message(message)
assert coreserver.session.get_node(node.id)
@pytest.mark.parametrize("state", [
EventTypes.START,
EventTypes.STOP,
EventTypes.RESTART,
EventTypes.PAUSE,
EventTypes.RECONFIGURE
])
def test_event_service(self, coreserver, state):
coreserver.session.broadcast_event = mock.MagicMock()
node = coreserver.session.add_node()
node.startup()
message = coreapi.CoreEventMessage.create(0, [
(EventTlvs.TYPE, state.value),
(EventTlvs.NODE, node.id),
(EventTlvs.NAME, "service:DefaultRoute"),
])
coreserver.request_handler.handle_message(message)
coreserver.session.broadcast_event.assert_called_once()
@pytest.mark.parametrize("state", [
EventTypes.START,
EventTypes.STOP,
EventTypes.RESTART,
EventTypes.PAUSE,
EventTypes.RECONFIGURE
])
def test_event_mobility(self, coreserver, state):
coreserver.session.broadcast_event = mock.MagicMock()
message = coreapi.CoreEventMessage.create(0, [
(EventTlvs.TYPE, state.value),
(EventTlvs.NAME, "mobility:ns2script"),
])
coreserver.request_handler.handle_message(message)
def test_register_gui(self, coreserver):
coreserver.request_handler.master = False
message = coreapi.CoreRegMessage.create(0, [
(RegisterTlvs.GUI, "gui"),
])
coreserver.request_handler.handle_message(message)
assert coreserver.request_handler.master is True
def test_register_xml(self, coreserver, tmpdir):
xml_file = tmpdir.join("session.xml")
file_path = xml_file.strpath
node = coreserver.session.add_node()
coreserver.session.save_xml(file_path)
coreserver.session.delete_node(node.id)
message = coreapi.CoreRegMessage.create(0, [
(RegisterTlvs.EXECUTE_SERVER, file_path),
])
coreserver.session.instantiate()
coreserver.request_handler.handle_message(message)
assert coreserver.server.coreemu.sessions[2].get_node(node.id)
def test_register_python(self, coreserver, tmpdir):
xml_file = tmpdir.join("test.py")
file_path = xml_file.strpath
with open(file_path, "w") as f:
f.write("coreemu = globals()['coreemu']\n")
f.write("session = coreemu.sessions[1]\n")
f.write("session.add_node()\n")
message = coreapi.CoreRegMessage.create(0, [
(RegisterTlvs.EXECUTE_SERVER, file_path),
])
coreserver.session.instantiate()
coreserver.request_handler.handle_message(message)
assert len(coreserver.session.nodes) == 1