Commit e226146e authored by Federico Sismondi's avatar Federico Sismondi
Browse files

Merge branch 'feat_lossy_packet_router' into 'develop'

Feat lossy packet router

See merge request !113
parents 1cb249eb b7263f23
......@@ -27,7 +27,6 @@ from messages import (MsgTestingToolTerminate, MsgSessionLog,
logger = logging.getLogger(__name__)
INTERACTIVE_SESSION = get_from_environment("INTERACTIVE_SESSION", True)
COAP_CLIENT_HOST = get_from_environment("COAP_CLIENT_HOST", 'bbbb::1')
COAP_SERVER_HOST = get_from_environment("COAP_SERVER_HOST", 'bbbb::2')
COAP_SERVER_PORT = get_from_environment("COAP_SERVER_PORT", '5683')
......
......@@ -318,11 +318,20 @@ def run_blocking_process(cmd: list, timeout=300):
if __name__ == '__main__':
help="""
This program drives an interop test suite by sending AMQP API messages to the event bus.
These typically are "testsuite.*" or "testingtool.*" type of messages.
It doesnt really run protocol implementations (implementations under test)
nor testing tool code (ioppytest testing tools) unless explicitly indicated by using options.
See optional arguments help for more information.
"""
MANIFEST_INTEROP_TESTS = 'automated_interop_tests.yaml'
DELIM = "*" * 70
# be careful with the order of the items as it's used along the main
parser = argparse.ArgumentParser()
parser = argparse.ArgumentParser(description=help)
parser.add_argument("--all-interops",
help="Runs all automated interop tests (requires local docker daemon to be running, "
......@@ -346,6 +355,7 @@ if __name__ == '__main__':
manif = yaml.load(stream)
for test in manif:
logging.info('\n{delim} \n'
'Starting interop test session: \n'
'\tinterop test: {interop_name} \n'
......
......@@ -38,7 +38,7 @@ import logging
from automation import COAP_SERVER_HOST, COAP_SERVER_PORT, COAP_CLIENT_HOST
from automation.automated_iut import AutomatedIUT, launch_short_automated_iut_process
default_coap_server_base_url = 'coap://[%s]:%s' % (COAP_SERVER_HOST, COAP_SERVER_PORT)
default_base_url = 'coap://[%s]:%s' % (COAP_SERVER_HOST, COAP_SERVER_PORT)
coap_host_address = COAP_CLIENT_HOST
BASE_CMD = ["aiocoap-client"]
......@@ -172,89 +172,111 @@ mollis sed dui. Ut sed. </large>"
stimuli_to_aiocoap_cli_call = {
# CoAP CORE test cases stimuli
"TD_COAP_CORE_01_step_01": (get, {"base_url": default_coap_server_base_url, "resource": "/test"}),
"TD_COAP_CORE_02_step_01": (delete, {"base_url": default_coap_server_base_url, "resource": "/test"}),
"TD_COAP_CORE_03_step_01": (
put, {"base_url": default_coap_server_base_url, "resource": "/test", "content_format": "text/plain"}),
"TD_COAP_CORE_04_step_01": (
post, {"base_url": default_coap_server_base_url, "resource": "/test", "content_format": "text/plain"}),
"TD_COAP_CORE_05_step_01": (
get, {"base_url": default_coap_server_base_url, "resource": "/test", "confirmable": False}),
"TD_COAP_CORE_06_step_01": (
delete, {"base_url": default_coap_server_base_url, "resource": "/test", "confirmable": False}),
"TD_COAP_CORE_07_step_01": (put, {"base_url": default_coap_server_base_url, "resource": "/test",
"content_format": "text/plain", "confirmable": False}),
"TD_COAP_CORE_08_step_01": (
post, {"base_url": default_coap_server_base_url, "resource": "/test", "content_format": "text/plain"}),
"TD_COAP_CORE_09_step_01": (get, {"base_url": default_coap_server_base_url, "resource": "/separate"}),
"TD_COAP_CORE_10_step_01": (get, {"base_url": default_coap_server_base_url, "resource": "/test"}),
"TD_COAP_CORE_11_step_01": (get, {"base_url": default_coap_server_base_url, "resource": "/separate"}),
"TD_COAP_CORE_12_step_01": (
get, {"base_url": default_coap_server_base_url, "resource": "/test", "use_token": False}),
"TD_COAP_CORE_13_step_01": (get, {"base_url": default_coap_server_base_url, "resource": "/seg1/seg2/seg3"}),
"TD_COAP_CORE_14_step_01": (
get, {"base_url": default_coap_server_base_url, "resource": "/query?first=1&second=2&third=3"}),
"TD_COAP_CORE_15_step_01": (get, {"base_url": default_coap_server_base_url, "resource": "/test"}),
"TD_COAP_CORE_16_step_01": (get, {"base_url": default_coap_server_base_url, "resource": "/separate"}),
"TD_COAP_CORE_17_step_01": (
get, {"base_url": default_coap_server_base_url, "resource": "/separate", "confirmable": False}),
"TD_COAP_CORE_18_step_01": (
post, {"base_url": default_coap_server_base_url, "resource": "/test", "content_format": "text/plain"}),
"TD_COAP_CORE_19_step_01": (
post, {"base_url": default_coap_server_base_url, "resource": "/location-query?first=1&second=2&third=3"}),
"TD_COAP_CORE_20_step_01": (
get, {"base_url": default_coap_server_base_url, "resource": "/multi-format", "accept_option": "text/plain"}),
"TD_COAP_CORE_20_step_05": (
get, {"base_url": default_coap_server_base_url, "resource": "/multi-format", "accept_option": "application/xml"}),
"TD_COAP_CORE_21_step_01": (get, {"base_url": default_coap_server_base_url, "resource": "/validate"}),
"TD_COAP_CORE_21_step_05": (get, {"base_url": default_coap_server_base_url, "resource": "/validate"}),
"TD_COAP_CORE_22_step_01": (get, {"base_url": default_coap_server_base_url, "resource": "/validate"}),
"TD_COAP_CORE_01_step_01":
(get, {"base_url": default_base_url, "resource": "/test"}),
"TD_COAP_CORE_02_step_01":
(delete, {"base_url": default_base_url, "resource": "/test"}),
"TD_COAP_CORE_03_step_01":
(put, {"base_url": default_base_url, "resource": "/test", "content_format": "text/plain"}),
"TD_COAP_CORE_04_step_01":
(post, {"base_url": default_base_url, "resource": "/test", "content_format": "text/plain"}),
"TD_COAP_CORE_05_step_01":
(get, {"base_url": default_base_url, "resource": "/test", "confirmable": False}),
"TD_COAP_CORE_06_step_01":
(delete, {"base_url": default_base_url, "resource": "/test", "confirmable": False}),
"TD_COAP_CORE_07_step_01":
(put, {"base_url": default_base_url, "resource": "/test", "content_format": "text/plain", "confirmable": False}),
"TD_COAP_CORE_08_step_01":
(post, {"base_url": default_base_url, "resource": "/test", "content_format": "text/plain"}),
"TD_COAP_CORE_09_step_01":
(get, {"base_url": default_base_url, "resource": "/separate"}),
"TD_COAP_CORE_10_step_01":
(get, {"base_url": default_base_url, "resource": "/test"}),
"TD_COAP_CORE_11_step_01":
(get, {"base_url": default_base_url, "resource": "/separate"}),
"TD_COAP_CORE_12_step_01":
(get, {"base_url": default_base_url, "resource": "/test", "use_token": False}),
"TD_COAP_CORE_13_step_01":
(get, {"base_url": default_base_url, "resource": "/seg1/seg2/seg3"}),
"TD_COAP_CORE_14_step_01":
(get, {"base_url": default_base_url, "resource": "/query?first=1&second=2&third=3"}),
"TD_COAP_CORE_15_step_01":
(get, {"base_url": default_base_url, "resource": "/test"}),
"TD_COAP_CORE_16_step_01":
(get, {"base_url": default_base_url, "resource": "/separate"}),
"TD_COAP_CORE_17_step_01":
(get, {"base_url": default_base_url, "resource": "/separate", "confirmable": False}),
"TD_COAP_CORE_18_step_01":
(post, {"base_url": default_base_url, "resource": "/test", "content_format": "text/plain"}),
"TD_COAP_CORE_19_step_01":
(post, {"base_url": default_base_url, "resource": "/location-query?first=1&second=2&third=3"}),
"TD_COAP_CORE_20_step_01":
(get, {"base_url": default_base_url, "resource": "/multi-format", "accept_option": "text/plain"}),
"TD_COAP_CORE_20_step_05":
(get, {"base_url": default_base_url, "resource": "/multi-format", "accept_option": "application/xml"}),
"TD_COAP_CORE_21_step_01":
(get, {"base_url": default_base_url, "resource": "/validate"}),
"TD_COAP_CORE_21_step_05":
(get, {"base_url": default_base_url, "resource": "/validate"}),
"TD_COAP_CORE_22_step_01":
(get, {"base_url": default_base_url, "resource": "/validate"}),
# "TD_COAP_CORE_22_step_04": "TD_COAP_CORE_22",
"TD_COAP_CORE_22_step_08": (put, {"base_url": default_coap_server_base_url, "resource": "/validate"}),
"TD_COAP_CORE_23_step_01": (put, {"base_url": default_coap_server_base_url, "resource": "/create1",
"content_format": "text/plain", "use_if_none_match": True}),
"TD_COAP_CORE_23_step_05": (put, {"base_url": default_coap_server_base_url, "resource": "/create1",
"content_format": "text/plain", "use_if_none_match": True}),
"TD_COAP_OBS_01_step_01": (observe, {"base_url": default_coap_server_base_url, "resource": "/obs"}),
"TD_COAP_OBS_02_step_01": (
observe, {"base_url": default_coap_server_base_url, "resource": "/obs-non", "confirmable": False}),
"TD_COAP_OBS_04_step_01": (observe, {"base_url": default_coap_server_base_url, "resource": "/obs"}),
"TD_COAP_OBS_05_step_01": (observe, {"base_url": default_coap_server_base_url, "resource": "/obs"}),
"TD_COAP_OBS_07_step_01": (observe, {"base_url": default_coap_server_base_url, "resource": "/obs", "duration": 20}),
"TD_COAP_OBS_08_step_01": (observe, {"base_url": default_coap_server_base_url, "resource": "/obs", "duration": 20}),
"TD_COAP_OBS_09_step_01": (observe, {"base_url": default_coap_server_base_url, "resource": "/obs", "duration": 20}),
"TD_COAP_OBS_10_step_01": (observe, {"base_url": default_coap_server_base_url, "resource": "/obs", "duration": 20}),
"TD_COAP_CORE_22_step_08":
(put, {"base_url": default_base_url, "resource": "/validate"}),
"TD_COAP_CORE_23_step_01":
(put, {"base_url": default_base_url, "resource": "/create1","content_format": "text/plain","use_if_none_match": True}),
"TD_COAP_CORE_23_step_05":
(put, {"base_url": default_base_url, "resource": "/create1","content_format": "text/plain","use_if_none_match": True}),
"TD_COAP_OBS_01_step_01":
(observe, {"base_url": default_base_url, "resource": "/obs"}),
"TD_COAP_OBS_02_step_01":
(observe, {"base_url": default_base_url, "resource": "/obs-non", "confirmable": False}),
"TD_COAP_OBS_04_step_01":
(observe, {"base_url": default_base_url, "resource": "/obs"}),
"TD_COAP_OBS_05_step_01":
(observe, {"base_url": default_base_url, "resource": "/obs"}),
"TD_COAP_OBS_07_step_01":
(observe, {"base_url": default_base_url, "resource": "/obs", "duration": 20}),
"TD_COAP_OBS_08_step_01":
(observe, {"base_url": default_base_url, "resource": "/obs", "duration": 20}),
"TD_COAP_OBS_09_step_01":
(observe, {"base_url": default_base_url, "resource": "/obs", "duration": 20}),
"TD_COAP_OBS_10_step_01":
(observe, {"base_url": default_base_url, "resource": "/obs", "duration": 20}),
# CoAP BLOCK test cases stimuli
"TD_COAP_BLOCK_01_step_01": (
get, {"base_url": default_coap_server_base_url, "resource": "/large", "use_block_option": True}),
"TD_COAP_BLOCK_02_step_01": (
get, {"base_url": default_coap_server_base_url, "resource": "/large", "use_block_option": False}),
"TD_COAP_BLOCK_03_step_01": (put, {"base_url": default_coap_server_base_url, "resource": "/large-update",
"use_block_option": True, "content_format": "text/plain",
"payload": large_payload}),
"TD_COAP_BLOCK_04_step_01": (post, {"base_url": default_coap_server_base_url, "resource": "/large-create",
"use_block_option": True, "content_format": "text/plain",
"payload": large_payload}),
"TD_COAP_BLOCK_05_step_01": (post, {"base_url": default_coap_server_base_url, "resource": "/large-post",
"use_block_option": True, "content_format": "text/plain",
"payload": large_payload}),
"TD_COAP_BLOCK_06_step_01": (
get, {"base_url": default_coap_server_base_url, "resource": "/large", "use_block_option": True, "block_size": 16}),
"TD_COAP_BLOCK_01_step_01":
(get, {"base_url": default_base_url, "resource": "/large", "use_block_option": True}),
"TD_COAP_BLOCK_02_step_01":
(get, {"base_url": default_base_url, "resource": "/large", "use_block_option": False}),
"TD_COAP_BLOCK_03_step_01":
(put, {"base_url": default_base_url, "resource": "/large-update","use_block_option": True, "content_format": "text/plain","payload": large_payload}),
"TD_COAP_BLOCK_04_step_01":
(post, {"base_url": default_base_url, "resource": "/large-create","use_block_option": True, "content_format": "text/plain","payload": large_payload}),
"TD_COAP_BLOCK_05_step_01":
(post, {"base_url": default_base_url, "resource": "/large-post","use_block_option": True, "content_format": "text/plain","payload": large_payload}),
"TD_COAP_BLOCK_06_step_01":
(get, {"base_url": default_base_url, "resource": "/large", "use_block_option": True, "block_size": 16}),
# CoAP LINK test cases stimuli
"TD_COAP_LINK_01_step_01": (get, {"base_url": default_coap_server_base_url, "resource": "/.well-known/core"}),
"TD_COAP_LINK_02_step_01": (
get, {"base_url": default_coap_server_base_url, "resource": "/.well-known/core?rt=Type1"}),
"TD_COAP_LINK_03_step_01": (get, {"base_url": default_coap_server_base_url, "resource": "/.well-known/core?rt=*"}),
"TD_COAP_LINK_04_step_01": (
get, {"base_url": default_coap_server_base_url, "resource": "/.well-known/core?rt=Type2"}),
"TD_COAP_LINK_05_step_01": (
get, {"base_url": default_coap_server_base_url, "resource": "/.well-known/core?if=If*"}),
"TD_COAP_LINK_06_step_01": (get, {"base_url": default_coap_server_base_url, "resource": "/.well-known/core?sz=*"}),
"TD_COAP_LINK_07_step_01": (
get, {"base_url": default_coap_server_base_url, "resource": "/.well-known/core?href=/link1"}),
"TD_COAP_LINK_08_step_01": (
get, {"base_url": default_coap_server_base_url, "resource": "/.well-known/core?href=/link*"}),
"TD_COAP_LINK_09_step_01": (get, {"base_url": default_coap_server_base_url, "resource": "/.well-known/core?ct=40"}),
"TD_COAP_LINK_01_step_01":
(get, {"base_url": default_base_url, "resource": "/.well-known/core"}),
"TD_COAP_LINK_02_step_01":
(get, {"base_url": default_base_url, "resource": "/.well-known/core?rt=Type1"}),
"TD_COAP_LINK_03_step_01":
(get, {"base_url": default_base_url, "resource": "/.well-known/core?rt=*"}),
"TD_COAP_LINK_04_step_01":
(get, {"base_url": default_base_url, "resource": "/.well-known/core?rt=Type2"}),
"TD_COAP_LINK_05_step_01":
(get, {"base_url": default_base_url, "resource": "/.well-known/core?if=If*"}),
"TD_COAP_LINK_06_step_01":
(get, {"base_url": default_base_url, "resource": "/.well-known/core?sz=*"}),
"TD_COAP_LINK_07_step_01":
(get, {"base_url": default_base_url, "resource": "/.well-known/core?href=/link1"}),
"TD_COAP_LINK_08_step_01":
(get, {"base_url": default_base_url, "resource": "/.well-known/core?href=/link*"}),
"TD_COAP_LINK_09_step_01":
(get, {"base_url": default_base_url, "resource": "/.well-known/core?ct=40"}),
}
......@@ -271,7 +293,7 @@ class AutomatedAiocoapClient(AutomatedIUT):
node = 'coap_client'
component_id = 'automated_iut-coap_client-aiocoap'
implemented_stimuli_list = list(stimuli_to_aiocoap_cli_call.keys())
default_coap_server_base_url = 'coap://[%s]:%s' % (COAP_SERVER_HOST, COAP_SERVER_PORT)
default_base_url = 'coap://[%s]:%s' % (COAP_SERVER_HOST, COAP_SERVER_PORT)
def __init__(self, target_base_url=None):
......@@ -280,7 +302,7 @@ class AutomatedAiocoapClient(AutomatedIUT):
if target_base_url:
self.base_url = target_base_url
else:
self.base_url = self.default_coap_server_base_url
self.base_url = self.default_base_url
self.log('Started successfully %s [ %s ]' % (self.node, self.component_id))
......
pika==0.11.0
art
pika
PyYAML==3.12
ioppytest-utils
......@@ -24,7 +24,6 @@ __all__ = [
'AMQP_URL',
'TEST_DESCRIPTIONS_DICT',
'TEST_DESCRIPTIONS_CONFIGS_DICT',
'INTERACTIVE_SESSION',
'LOGGER_FORMAT'
]
......@@ -143,9 +142,6 @@ AUTO_DISSECTION_FILE = os.path.join(project_dir, '/data/auto_dissection.json')
# # # # # # ENV variables # # # # # # # # # #
# INTERACTIVE_SESSION: if not an interactive session then user input is emulated
INTERACTIVE_SESSION = get_from_environment("INTERACTIVE_SESSION", True)
# AMQP ENV variables (either get them all from ENV or set them all as default)
try:
AMQP_EXCHANGE = str(os.environ['AMQP_EXCHANGE'])
......
# -*- coding: utf-8 -*-
# !/usr/bin/env python3
import argparse
import sys
import threading
import tabulate
import pika
import yaml
import pika
import tabulate
import argparse
import threading
from messages import *
from ioppytest import AMQP_URL, AMQP_EXCHANGE, LOG_LEVEL, TEST_DESCRIPTIONS_CONFIGS, LOGGER_FORMAT
......@@ -24,6 +24,10 @@ logging.getLogger('pika').setLevel(logging.WARNING)
class PacketRouter(threading.Thread):
DEFAULT_TOPICS = [
'routing.#',
] # this list is further extended on __init__ with the routing table
def __init__(self, amqp_url, amqp_exchange, routing_table):
assert routing_table
......@@ -41,9 +45,12 @@ class PacketRouter(threading.Thread):
self.logger = logging.getLogger(self.component_id)
self.logger.setLevel(LOG_LEVEL)
self.logger.info('routing table (rkey_src:[rkey_dst]) : {table}'.format(table=json.dumps(self.routing_table)))
self.logger.info('routing table (rkey_src:[rkey_dst]) : \n{table}'.format(
table=tabulate.tabulate([[k, list(v)] for k, v in self.routing_table.items()], tablefmt="grid")
))
self.message_count = 0
self.pending_number_of_packets_to_drop = 0
self._set_up_connection()
self._queues_init()
......@@ -52,7 +59,7 @@ class PacketRouter(threading.Thread):
)
publish_message(self.connection, msg)
self.logger.info('packet router waiting for new messages in the data plane..')
self.logger.info('Waiting for new messages in the data plane..')
def _set_up_connection(self):
......@@ -70,10 +77,23 @@ class PacketRouter(threading.Thread):
self.channel.basic_qos(prefetch_count=1)
except pika.exceptions.ConnectionClosed as cc:
self.logger.error(' AMQP cannot be established, is message broker up? \n More: %s' % cc)
self.logger.error(' AMQP connection cannot be established, is message broker up? \n More: %s' % cc)
sys.exit(1)
def _queues_init(self):
# declare a multi-purpose amqp queue for services provided by component
self.channel.queue_declare(queue='services_queue@%s' % COMPONENT_ID, auto_delete=True)
self.channel.queue_purge('services_queue@%s' % COMPONENT_ID)
for t in self.DEFAULT_TOPICS:
self.channel.queue_bind(exchange=self.exchange_name,
queue='services_queue@%s' % COMPONENT_ID,
routing_key=t)
self.channel.basic_qos(prefetch_count=1)
self.channel.basic_consume(self._on_request, queue='services_queue@%s' % COMPONENT_ID)
# handle subscriptions for routing table declarations
for src_rkey, dst_rkey_list in self.routing_table.items():
assert type(src_rkey) is str
assert type(dst_rkey_list) is list
......@@ -106,47 +126,73 @@ class PacketRouter(threading.Thread):
def _on_request(self, ch, method, props, body):
# TODO implement forced message drop mechanism
# obj hook so json.loads respects the order of the fields sent -just for visualization purposeses-
body_dict = json.loads(body.decode('utf-8'), object_pairs_hook=OrderedDict)
# ack message received
ch.basic_ack(delivery_tag=method.delivery_tag)
self.message_count += 1
# let's route the message to the right agent
self.logger.info('Identifying request with rkey: %s' % method.routing_key)
try:
m = MsgPacketInjectRaw(data=body_dict['data'],
timestamp=body_dict['timestamp'],
interface_name=body_dict['interface_name'])
except:
self.logger.error(
'wrong message format, <data> , <timestamp> and <interface_name> fields expected, got: {msg}'.
format(msg=json.dumps(body_dict))
)
msg_received = Message.load_from_pika(method, props, body)
print(msg_received.routing_key)
except Exception as e:
self.logger.info(str(e))
return
src_rkey = method.routing_key
if src_rkey in self.routing_table.keys():
list_dst_rkey = self.routing_table[src_rkey]
for dst_rkey in list_dst_rkey:
# forward to dst_rkey
self.channel.basic_publish(
body=m.to_json(),
routing_key=dst_rkey,
exchange=self.exchange_name,
properties=pika.BasicProperties(
content_type='application/json',
)
)
if isinstance(msg_received, MsgPacketSniffedRaw):
self.message_count += 1
if self.pending_number_of_packets_to_drop > 0:
self.pending_number_of_packets_to_drop -= 1
self.logger.info(
"Routing packet (%d) from topic: %s to topic: %s" % (self.message_count, src_rkey, dst_rkey))
'Dropping packet due to lossy link config. Pending packets to drop: %s' %
self.pending_number_of_packets_to_drop
)
return
# let's route the message to the right agent
try:
msg_to_send = MsgPacketInjectRaw(
data=msg_received.data,
timestamp=msg_received.timestamp,
interface_name=msg_received.interface_name
)
except:
self.logger.error(
'wrong message format, <data> , <timestamp> and <interface_name> fields expected, got: {msg}'.
format(msg=repr(msg_received))
)
return
src_rkey = msg_received.routing_key
json_to_send = msg_to_send.to_json()
if src_rkey in self.routing_table.keys():
list_dst_rkey = self.routing_table[src_rkey]
for dst_rkey in list_dst_rkey:
# forward to dst_rkey
self.channel.basic_publish(
body=json_to_send,
routing_key=dst_rkey,
exchange=self.exchange_name,
properties=pika.BasicProperties(
content_type='application/json',
)
)
self.logger.info(
"Routing packet (%d) from topic: %s to topic: %s" % (self.message_count, src_rkey, dst_rkey))
elif 'toAgent' in src_rkey:
pass # this is probably a message echo'ed from a message sent by this same component
elif 'toAgent' in src_rkey:
pass # echo of router message
else:
self.logger.warning('No known route for r_key source: {r_key}'.format(r_key=src_rkey))
return
elif isinstance(msg_received, MsgRoutingStartLossyLink):
self.pending_number_of_packets_to_drop = msg_received.number_of_packets_to_drop
self.logger.info("Packet router configured to drop %s packet(s)" % self.pending_number_of_packets_to_drop)
else:
self.logger.warning('No known route for r_key source: {r_key}'.format(r_key=src_rkey))
return
self.logger.warning("Message ignored %s" % repr(msg_received))
def _notify_component_shutdown(self):
......@@ -174,17 +220,17 @@ def generate_routing_table_from_test_configuration(testconfig: TestConfig):
"""
Builds routing table (not IP based, but using amqp topics), example for COAP_CFG_01
---------------------------------------------- ------------------------------------------------------------------------------------------------
---------------------------------------------- --------------------------------------------------------------------
data.serial.fromAgent.coap_client ['data.serial.toAgent.coap_server', 'data.serial.toAgent.agent_TT']
fromAgent.coap_client.802154.serial.packet.raw ['toAgent.coap_server.802154.serial.packet.raw', 'toAgent.agent_TT.802154.serial.packet.raw']
fromAgent.coap_client.ip.tun.packet.raw ['toAgent.coap_server.ip.tun.packet.raw', 'toAgent.agent_TT.ip.tun.packet.raw']
data.serial.fromAgent.coap_server ['data.serial.toAgent.coap_client', 'data.serial.toAgent.agent_TT']
fromAgent.coap_server.802154.serial.packet.raw ['toAgent.coap_client.802154.serial.packet.raw', 'toAgent.agent_TT.802154.serial.packet.raw']
fromAgent.coap_server.ip.tun.packet.raw ['toAgent.coap_client.ip.tun.packet.raw', 'toAgent.agent_TT.ip.tun.packet.raw']
data.serial.fromAgent.agent_TT ['data.serial.toAgent.coap_client', 'data.serial.toAgent.coap_server']
fromAgent.agent_TT.802154.serial.packet.raw ['toAgent.coap_client.802154.serial.packet.raw', 'toAgent.coap_server.802154.serial.packet.raw']
fromAgent.agent_TT.ip.tun.packet.raw ['toAgent.coap_client.ip.tun.packet.raw', 'toAgent.coap_server.ip.tun.packet.raw']
---------------------------------------------- ------------------------------------------------------------------------------------------------
fromAgent.coap_client.802154.serial.packet.raw ['toAgent.coap_server.802154.serial.packet.raw', 'toAgent.agent_...
fromAgent.coap_client.ip.tun.packet.raw ['toAgent.coap_server.ip.tun.packet.raw', 'toAgent.agent_TT.ip.t...
data.serial.fromAgent.coap_server ['data.serial.toAgent.coap_client', 'data.serial.toAgent.agent_T...
fromAgent.coap_server.802154.serial.packet.raw ['toAgent.coap_client.802154.serial.packet.raw', 'toAgent.agent_...
fromAgent.coap_server.ip.tun.packet.raw ['toAgent.coap_client.ip.tun.packet.raw', 'toAgent.agent_TT.ip.t...
data.serial.fromAgent.agent_TT ['data.serial.toAgent.coap_client', 'data.serial.toAgent.coap_se...
fromAgent.agent_TT.802154.serial.packet.raw ['toAgent.coap_client.802154.serial.packet.raw', 'toAgent.coap_s...
fromAgent.agent_TT.ip.tun.packet.raw ['toAgent.coap_client.ip.tun.packet.raw', 'toAgent.coap_server.i...
---------------------------------------------- --------------------------------------------------------------------
:param testconfig:
:return:
"""
......@@ -204,7 +250,6 @@ def generate_routing_table_from_test_configuration(testconfig: TestConfig):
nodes.append(agent_tt) # every single packet needs to be forwarded to agent TT
logging.info("Configuring routing tables for nodes: %s" % nodes)
# TODO deprecate old API from 802.15.4 based test suites like sixlowpan
table_entry_from_serial_v0 = "data.serial.fromAgent.{node}"
table_entry_to_serial_v0 = "data.serial.toAgent.{node}"
......@@ -232,13 +277,12 @@ def generate_routing_table_from_test_configuration(testconfig: TestConfig):
nodes if j != i]
routing_table.update(link_routes)
#print(tabulate.tabulate([*routing_table.items()]))
# print(tabulate.tabulate([*routing_table.items()]))
return routing_table
def main():
td_config = get_dict_of_all_test_cases_configurations()
assert len(td_config) > 0, 'No test case configuration files found!'
......
pika==0.11.0
pika
PyYAML==3.12
pytest==3.9.3
transitions==0.6.1
......
......@@ -9,7 +9,7 @@ import datetime
from transitions.core import MachineError
from ioppytest import AMQP_EXCHANGE, AMQP_URL, LOG_LEVEL
from ioppytest import RESULTS_DIR
from event_bus_utils import amqp_request, AmqpSynchCallTimeoutError
from event_bus_utils import amqp_request, publish_message, AmqpSynchCallTimeoutError
from event_bus_utils.rmq_handler import RabbitMQHandler, JsonFormatter
from ioppytest.exceptions import CoordinatorError
from messages import *
......@@ -166,6 +166,8 @@ class CoordinatorAmqpInterface:
Creates temporary channel on it's own
Connection must be a pika.BlockingConnection
"""
#publish_message(self.connection, message)
connection = None
channel = None
properties = pika.BasicProperties(**message.get_properties())
......@@ -486,3 +488,6 @@ class CoordinatorAmqpInterface:
return response
except AmqpSynchCallTimeoutError as e:
raise e # let caller handle it
def call_service_router_drop_packets(self, number_packets_to_drop=3):
self._publish_message(MsgRoutingStartLossyLink(number_of_packets_to_drop=number_packets_to_drop))
......@@ -19,12 +19,8 @@ from event_bus_utils import AmqpSynchCallTimeoutError
from event_bus_utils.rmq_handler import RabbitMQHandler, JsonFormatter
ANALYSIS_MODE = 'post_mortem' # either step_by_step or post_mortem # TODO test suite param?
# if left empty => packet_sniffer chooses the loopback
SNIFFER_FILTER_IF = 'tun0' # TODO test suite param?
# TODO 6lo FIX ME !
# - tun notify method -> execute only if test suite needs it (create a test suite param profiling)
SNIFFER_FILTER_IF = 'tun0' # TODO test suite param?, # if left empty packet_sniffer chooses the loopback
LOSSY_CONTEXT__NUMBER_OF_PACKETS_TO_DROP = 2 # TODO test suite param?
# component identification & bus params
COMPONENT_ID = '%s|%s' % ('test_coordinator', 'FSM')
......@@ -94,7 +90,7 @@ class Coordinator(CoordinatorAmqpInterface):
f.write(json.dumps(verdict_info))
def configure_agent_data_plane_interfaces(self, received_event):
# todo find a way of switching between different configuration requirements coming from each test suite
# ToDo find a way of switching between different configuration requirements coming from each test suite
# coap config is different from 6lowpan config
self.notify_tun_interfaces_start(received_event)
......@@ -347,12 +343,13 @@ class Coordinator(CoordinatorAmqpInterface):
gen_verdict, gen_description, report = current_tc.generate_testcases_verdict(partial_verd)
else:
error_msg += 'Response from Test Analyzer NOK: %s' % repr(tat_response)
error_msg += 'Error message: %s (err.code: %s)' % (tat_response.error_message,
tat_response.error_code)
logger.warning(error_msg)
# generate verdict and verdict description
try:
gen_description = tat_response.error_code
gen_description = error_msg
gen_verdict = 'inconclusive'
except AttributeError:
gen_description = error_msg
......@@ -415,7 +412,7 @@ class Coordinator(CoordinatorAmqpInterface):
def handle_testcase_select(self, received_event):
"""
this is more like a jump to function rather than select
this is more like a "jump to" function rather than select