Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
f-interop-contributors
ioppytest
Commits
e226146e
Commit
e226146e
authored
Dec 28, 2018
by
Federico Sismondi
Browse files
Merge branch 'feat_lossy_packet_router' into 'develop'
Feat lossy packet router See merge request
!113
parents
1cb249eb
b7263f23
Changes
15
Hide whitespace changes
Inline
Side-by-side
automation/__init__.py
View file @
e226146e
...
...
@@ -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'
)
...
...
automation/automated_interop.py
View file @
e226146e
...
...
@@ -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
'
'
\t
interop test: {interop_name}
\n
'
...
...
automation/coap_client_aiocoap/automated_iut.py
View file @
e226146e
...
...
@@ -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
))
...
...
automation/requirements.txt
View file @
e226146e
pika==0.11.0
art
pika
PyYAML==3.12
ioppytest-utils
ioppytest/__init__.py
View file @
e226146e
...
...
@@ -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'
])
...
...
ioppytest/packet_router/__main__.py
View file @
e226146e
# -*- 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 w
aiting for new messages in the data plane..'
)
self
.
logger
.
info
(
'
W
aiting 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.t
un.packet.raw']
data.serial.fromAgent.coap_server ['data.serial.toAgent.coap_client', 'data.serial.toAgent.agent_T
T']
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.t
un.packet.raw']
data.serial.fromAgent.agent_TT ['data.serial.toAgent.coap_client', 'data.serial.toAgent.coap_se
rver']
fromAgent.agent_TT.802154.serial.packet.raw ['toAgent.coap_client.802154.serial.packet.raw', 'toAgent.coap_s
erver.802154.serial.packet.raw']
fromAgent.agent_TT.ip.tun.packet.raw ['toAgent.coap_client.ip.tun.packet.raw', 'toAgent.coap_server.i
p.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!'
...
...
ioppytest/requirements.txt
View file @
e226146e
pika
==0.11.0
pika
PyYAML==3.12
pytest==3.9.3
transitions==0.6.1
...
...
ioppytest/test_coordinator/amqp_connector.py
View file @
e226146e
...
...
@@ -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
))
ioppytest/test_coordinator/coordinator.py
View file @
e226146e
...
...
@@ -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
):
#
tod
o find a way of switching between different configuration requirements coming from each test suite
#
ToD
o 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