messages.py 72.8 KB
Newer Older
1 2 3
# -*- coding: utf-8 -*-

"""
4 5 6 7

About the library:
-----------------

8 9 10 11 12 13 14 15 16
This module provides the API message formats used in F-Interop.

The idea is to be able to have an
- organized and centralized way of dealing with the big amount of messages formats used in the platform;
- to be able to import (or just copy/paste) these messages formats from any component in the F-Interop platform,
- re-use this also for the integration testing;
- to have version control the messages e.g. messages_testcase_start API v1 and API v2;
- to have a direct way of exporting this as doc.

17 18 19 20 21 22 23 24

F-Interop conventions:
---------------------
- if event is a service request then the routing key (r_key) is control.someFunctionality.service
- a reply to a service will be on topic/r_key : control.someFunctionality.service.reply
- reply.correlation_id = request.correlation_id


25 26
Usage:
------
27
>>> from messages import * # doctest: +SKIP
Federico Sismondi's avatar
Federico Sismondi committed
28
>>> m = MsgTestCaseSkip(testcase_id = 'some_testcase_id')
29
>>> m
30
MsgTestCaseSkip(_api_version = 1.0.1, _type = testcoordination.testcase.skip, description = Skip testcase, node = someNode, testcase_id = some_testcase_id, )
31 32
>>> m.routing_key
'control.testcoordination'
33 34
>>> m.message_id # doctest: +SKIP
'802012eb-24e3-45c4-9dcc-dc293c584f63'
35
>>> m.testcase_id
Federico Sismondi's avatar
Federico Sismondi committed
36
'some_testcase_id'
37

38
# also we can modify some of the fields (rewrite the default ones)
Federico Sismondi's avatar
Federico Sismondi committed
39
>>> m = MsgTestCaseSkip(testcase_id = 'TD_COAP_CORE_03')
40
>>> m
41
MsgTestCaseSkip(_api_version = 1.0.1, _type = testcoordination.testcase.skip, description = Skip testcase, node = someNode, testcase_id = TD_COAP_CORE_03, )
42
>>> m.testcase_id
Federico Sismondi's avatar
Federico Sismondi committed
43
'TD_COAP_CORE_03'
44

45 46
# and even export the message in json format (for example for sending the message though the amqp event bus)
>>> m.to_json()
47
'{"_api_version": "1.0.1", "_type": "testcoordination.testcase.skip", "description": "Skip testcase", "node": "someNode", "testcase_id": "TD_COAP_CORE_03"}'
Federico Sismondi's avatar
Federico Sismondi committed
48

49
# We can use the Message class to import json into Message objects:
Federico Sismondi's avatar
Federico Sismondi committed
50 51
>>> m=MsgTestSuiteStart()
>>> m.to_json()
52
'{"_api_version": "1.0.1", "_type": "testcoordination.testsuite.start", "description": "Event test suite START"}'
Federico Sismondi's avatar
Federico Sismondi committed
53 54 55
>>> json_message = m.to_json()
>>> obj=Message.from_json(json_message)
>>> type(obj)
56
<class 'messages.MsgTestSuiteStart'>
57

58
# We can use the library for generating error responses:
59 60 61 62 63 64
# the request:
>>> m = MsgSniffingStart()
>>>
# the error reply (note that we pass the message of the request to build the reply):
>>> err = MsgErrorReply(m)
>>> err
65
MsgErrorReply(_api_version = 1.0.1, _type = sniffing.start, error_code = Some error code TBD, error_message = Some error message TBD, ok = False, )
66 67 68 69 70 71 72 73 74
>>> m.reply_to
'control.sniffing.service.reply'
>>> err.routing_key
'control.sniffing.service.reply'

>>> m.correlation_id # doctest: +SKIP
'360b0f67-4455-43e3-a00f-eca91f2e84da'
>>> err.correlation_id # doctest: +SKIP
'360b0f67-4455-43e3-a00f-eca91f2e84da'
Federico Sismondi's avatar
Federico Sismondi committed
75

76 77 78
"""

from collections import OrderedDict
79
import time
80 81 82
import json
import uuid

83
API_VERSION = '1.0.1'
84

85 86 87 88 89 90 91 92 93 94

# TODO use metaclasses instead?
class NonCompliantMessageFormatError(Exception):
    def __init__(self, value):
        self.value = value

    def __str__(self):
        return repr(self.value)


Federico Sismondi's avatar
Federico Sismondi committed
95
class Message(object):
96
    def __init__(self, **kwargs):
97 98 99
        global API_VERSION

        # hard copy the message template
100
        self._msg_data = {k: v for k, v in self._msg_data_template.items()}
101

102 103
        # init properties
        self._properties = dict(
104 105 106
            content_type="application/json",
            message_id=str(uuid.uuid4()),
            timestamp=int(time.time())
107 108
        )

109
        try:
110 111 112
            if self.routing_key.endswith(".service"):
                self._properties["reply_to"] = "%s.%s" % (self.routing_key, "reply")
                self._properties["correlation_id"] = self._properties["message_id"]
113
        except AttributeError:
114
            pass
115

116
        # rewrite default data fields with the passed args
117 118 119
        self._msg_data.update(kwargs)

        # add API's version
120
        if "_api_version" not in self._msg_data:
121
            self._msg_data["_api_version"] = API_VERSION
122

Federico Sismondi's avatar
Federico Sismondi committed
123
        # add values as object's attributes
124 125 126
        for key in self._msg_data:
            setattr(self, key, self._msg_data[key])

127 128 129 130
        # add props as objects attributes
        for key in self._properties:
            setattr(self, key, self._properties[key])

131 132
    def to_dict(self):
        resp = {}
133 134
        # let's use sorted so API returns items inside always in the same order
        for field in sorted(self._msg_data.keys()):
135
            resp[field] = getattr(self, field)
136

137 138 139 140 141 142 143 144
        return resp

    def to_odict(self):
        resp = {}
        # let's use sorted so API returns items inside always in the same order
        for field in sorted(self._msg_data.keys()):
            resp[field] = getattr(self, field)

145
        return OrderedDict(sorted(resp.items(), key=lambda t: t[0]))  # sorted by key
146 147 148 149

    def to_json(self):
        return json.dumps(self.to_dict())

150
    def get_properties(self):
151 152 153 154
        resp = OrderedDict()
        for field in self._properties:
            resp[field] = getattr(self, field)
        return resp
155

156
    def __str__(self):
157 158 159 160 161 162 163
        s = " - " * 20 + "\n"
        s += "Message routing key: %s" % self.routing_key
        s += "\n -  -  - \n"
        s += "Message properties: %s" % json.dumps(self.get_properties(), indent=4, )
        s += "\n -  -  - \n"
        s += "Message body: %s" % json.dumps(self.to_dict(), indent=4, )
        s += "\n" + " - " * 20
164
        return s
165

166 167 168 169 170
    def update_properties(self, **kwargs):
        for key, value in kwargs.items():
            if key in self._properties:
                setattr(self, key, value)

171 172
    @classmethod
    def from_json(cls, body):
173 174 175 176 177 178 179 180 181 182
        """
        :param body: json string or string encoded as utf-8
        :return:  Message object generated from the body
        :raises NonCompliantMessageFormatError: If the message cannot be build from the provided json
        """

        if type(body) is str:
            message_dict = json.loads(body)
        # Note: pika re-encodes json.dumps strings as utf-8 for some reason, the following line undoes this
        elif type(body) is bytes:
183
            message_dict = json.loads(body.decode("utf-8"))
184
        else:
185
            raise NonCompliantMessageFormatError("Not a Json")
186

187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202
        # check fist if it's a response
        if "ok" in message_dict:
            # cannot build a complete reply message just from the json representation
            return

        return cls.from_dict(message_dict)

    @classmethod
    def from_dict(cls, message_dict):
        """
        :param body: dict
        :return:  Message object generated from the body
        :raises NonCompliantMessageFormatError: If the message cannot be build from the provided json
        """
        assert type(message_dict) is dict

203
        # check fist if it's a response
204
        if "ok" in message_dict:
205
            # cannot build a complete reply message just from the json representation
206
            return
207

208
        message_type = message_dict["_type"]
209

210 211 212
        if message_type in message_types_dict:
            return message_types_dict[message_type](**message_dict)
        else:
213 214
            raise NonCompliantMessageFormatError("Cannot load json message: %s" % str(message_dict))

215
    def __repr__(self):
216
        ret = "%s(" % self.__class__.__name__
217
        for key, value in self.to_dict().items():
218 219
            ret += "%s = %s, " % (key, value)
        ret += ")"
220 221
        return ret

222

223 224 225 226 227
class MsgReply(Message):
    """
    Auxiliary class which creates replies messages with fields based on the request.
    Routing key, corr_id and _type are generated based on the request message
    """
228

229 230 231 232 233 234 235
    def __init__(self, request_message, **kwargs):
        assert request_message

        self.routing_key = request_message.routing_key + ".reply"

        # if not data template, then let's build one for a reply
        # (possible when creating a MsgReply directly and not by using subclass)
236
        if not hasattr(self, "_msg_data_template"):
237
            self._msg_data_template = {
238
                "_type": request_message._type,
239
                "ok": True,
240 241
            }

242
        super(MsgReply, self).__init__(**kwargs)
243

244
        # overwrite correlation id template and attribute
245
        self._properties["correlation_id"] = request_message.correlation_id
246 247 248 249 250
        self.correlation_id = request_message.correlation_id


class MsgErrorReply(MsgReply):
    """
251
    see section "F-Interop conventions" on top
252
    """
253

254 255
    def __init__(self, request_message, **kwargs):
        assert request_message
256
        # msg_data_template doesnt include _type cause this class is generic, we can only get this at init from request
257
        # so, let's copy the _type from request and let the MsgReply handle the rest of the fields
258
        self._msg_data_template["_type"] = request_message._type
259
        super(MsgErrorReply, self).__init__(request_message, **kwargs)
260 261

    _msg_data_template = {
262
        "ok": False,
263
        "error_message": "Some error message TBD",
264
        "error_code": "Some error code TBD"
265 266
    }

Federico Sismondi's avatar
Federico Sismondi committed
267

268
# # # # # # CORE API messages # # # # #
269 270

class MsgOrchestratorVersionReq(Message):
271 272 273 274 275 276 277 278 279
    """
    Requirements: ...

    Type: Event

    Pub/Sub: UI -> SO

    Description: Message for returning current version of SO
    """
Federico Sismondi's avatar
Federico Sismondi committed
280
    routing_key = "control.orchestrator.version.request.service"
281 282

    _msg_data_template = {
Federico Sismondi's avatar
Federico Sismondi committed
283
        "_type": "orchestrator.version.request"
284
    }
285

Federico Sismondi's avatar
Federico Sismondi committed
286

287 288 289 290 291 292 293 294 295 296
class MsgOrchestratorUsersList(Message):
    """
    Requirements: ...

    Type: Event

    Pub/Sub: UI -> SO

    Description: Message for returning user list of SO
    """
297
    routing_key = "control.orchestrator.users.list.request.service"
298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313

    _msg_data_template = {
        "_type": "orchestrator.users.list.request"
    }


class MsgOrchestratorUserAdd(Message):
    """
    Requirements: ...

    Type: Event

    Pub/Sub: UI -> SO

    Description: Message for adding a user to SO
    """
314 315

    routing_key = "control.orchestrator.users.add.request.service"
316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331

    _msg_data_template = {
        "_type": "orchestrator.users.add.request"
    }


class MsgOrchestratorUserDelete(Message):
    """
    Requirements: ...

    Type: Event

    Pub/Sub: UI -> SO

    Description: Message for deleting a user from SO
    """
332 333

    routing_key = "control.orchestrator.users.delete.request.service"
334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349

    _msg_data_template = {
        "_type": "orchestrator.users.delete.request"
    }


class MsgOrchestratorUserGet(Message):
    """
    Requirements: ...

    Type: Event

    Pub/Sub: UI -> SO

    Description: Message for getting a user from SO
    """
350 351

    routing_key = "control.orchestrator.users.get.request.service"
352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367

    _msg_data_template = {
        "_type": "orchestrator.users.get.request"
    }


class MsgOrchestratorSessionsList(Message):
    """
    Requirements: ...

    Type: Event

    Pub/Sub: UI -> SO

    Description: Message for listing sessions from SO
    """
368
    routing_key = "control.orchestrator.sessions.list.request.service"
369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384

    _msg_data_template = {
        "_type": "orchestrator.sessions.list.request"
    }


class MsgOrchestratorSessionsGet(Message):
    """
    Requirements: ...

    Type: Event

    Pub/Sub: UI -> SO

    Description: Message for getting a session from SO
    """
385
    routing_key = "control.orchestrator.sessions.get.request.service"
386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401

    _msg_data_template = {
        "_type": "orchestrator.sessions.get.request"
    }


class MsgOrchestratorSessionsAdd(Message):
    """
    Requirements: ...

    Type: Event

    Pub/Sub: UI -> SO

    Description: Message for adding a session to SO
    """
402
    routing_key = "control.orchestrator.sessions.add.request.service"
403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418

    _msg_data_template = {
        "_type": "orchestrator.sessions.add.request"
    }


class MsgOrchestratorSessionsDelete(Message):
    """
    Requirements: ...

    Type: Event

    Pub/Sub: UI -> SO

    Description: Message for deleting a session to SO
    """
419 420

    routing_key = "control.orchestrator.sessions.delete.request.service"
421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437

    _msg_data_template = {
        "_type": "orchestrator.sessions.delete.request"
    }


class MsgOrchestratorSessionsUpdate(Message):
    """
    Requirements: ...

    Type: Event

    Pub/Sub: UI -> SO

    Description: Message for updating a session from SO
    """

438
    routing_key = "control.orchestrator.sessions.update.request.service"
439 440 441 442 443 444 445 446 447 448 449 450 451 452 453
    _msg_data_template = {
        "_type": "orchestrator.sessions.update.request"
    }


class MsgOrchestratorTestsGet(Message):
    """
    Requirements: ...

    Type: Event

    Pub/Sub: UI -> SO

    Description: Message for getting tests from SO
    """
454
    routing_key = "control.orchestrator.tests.get.request.service"
455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470

    _msg_data_template = {
        "_type": "orchestrator.tests.get.request"
    }


class MsgOrchestratorTestsGetContributorName(Message):
    """
    Requirements: ...

    Type: Event

    Pub/Sub: UI -> SO

    Description: Message for getting tests from SO with contributor and name
    """
471
    routing_key = "control.orchestrator.tests.get_contributor_name.request.service"
472 473 474 475 476 477

    _msg_data_template = {
        "_type": "orchestrator.tests.get_contributor_name.request"
    }


478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499
# # # # # # UI API messages # # # # # # # #

class MsgUiRequestTextInput(Message):
    """
    Requirements: ...

    Type: Event

    Pub/Sub: TT -> UI

    Description: Message for requesting action or information to user
    """
    routing_key = "ui.any.request"

    _msg_data_template = {
        "_type": "ui.any.request.text.input",
        "fields": [
            {"name": "input_name",
             "type": "text"},
        ]
    }

500

501
# # # # # # AGENT MESSAGES # # # # # #
Federico Sismondi's avatar
Federico Sismondi committed
502

503

Federico Sismondi's avatar
Federico Sismondi committed
504 505
class MsgAgentTunStart(Message):
    """
506
    Requirements: Testing Tool MAY implement (if IP tun needed)
Federico Sismondi's avatar
Federico Sismondi committed
507

508
    Type: Event
Federico Sismondi's avatar
Federico Sismondi committed
509

510
    Pub/Sub: Testing Tool -> Agent
Federico Sismondi's avatar
Federico Sismondi committed
511

512
    Description: Message for triggering start IP tun interface in OS where the agent is running
Federico Sismondi's avatar
Federico Sismondi committed
513
    """
514
    routing_key = "control.tun.toAgent.agent_TT"
Federico Sismondi's avatar
Federico Sismondi committed
515 516

    _msg_data_template = {
517 518 519 520
        "_type": "tun.start",
        "name": "agent_TT",
        "ipv6_prefix": "bbbb",
        "ipv6_host": ":3",
521
        "ipv6_no_forwarding": False,
522 523 524
        "ipv4_host": None,
        "ipv4_network": None,
        "ipv4_netmask": None,
Federico Sismondi's avatar
Federico Sismondi committed
525 526 527
    }


528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547
class MsgAgentSerialStarted(Message):
    """
    Description: Message for indicating that agent serial interface has been started

    Type: Event

    Pub/Sub: Testing Tool -> Agent

    Description: TBD
    """
    routing_key = "control.serial.from.tbd"

    _msg_data_template = {
        "_type": "serial.started",
        "name": "tbd",
        "port": "tbd",
        "boudrate": "tbd",
    }


Federico Sismondi's avatar
Federico Sismondi committed
548 549
class MsgAgentTunStarted(Message):
    """
550
    Description: Message for indicating that agent tun has been started
Federico Sismondi's avatar
Federico Sismondi committed
551

552
    Type: Event
Federico Sismondi's avatar
Federico Sismondi committed
553

554
    Pub/Sub: Agent -> Testing Tool
Federico Sismondi's avatar
Federico Sismondi committed
555

556
    Description: TBD
Federico Sismondi's avatar
Federico Sismondi committed
557
    """
558
    routing_key = "control.tun.from.tbd"
Federico Sismondi's avatar
Federico Sismondi committed
559 560

    _msg_data_template = {
561 562 563 564 565 566 567
        "_type": "tun.started",
        "name": "agent_TT",
        "ipv6_prefix": "bbbb",
        "ipv6_host": ":3",
        "ipv4_host": None,
        "ipv4_network": None,
        "ipv4_netmask": None,
568
        "ipv6_no_forwarding": False,
Federico Sismondi's avatar
Federico Sismondi committed
569 570
    }

571

572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592
class MsgPacketInjectRaw(Message):
    """
    Description: Message to be captured by the agent an push into the correct embedded interface (e.g. tun, serial, etc..)

    Type: Event

    Pub/Sub: Testing Tool -> Agent

    Description: TBD
    """
    routing_key = None  # depends on the agent_id and the agent interface being used, re-write after creation

    _msg_data_template = {
        "_type": "packet.to_inject.raw",
        "timestamp": "1488586183.45",
        "interface_name": "tun0",
        "data": [96, 0, 0, 0, 0, 36, 0, 1, 254, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 255, 2, 0, 0, 0, 0, 0, 0,
                 0, 0, 0, 0, 0, 0, 0, 22, 58, 0, 5, 2, 0, 0, 1, 0, 143, 0, 112, 7, 0, 0, 0, 1, 4, 0, 0, 0, 255, 2, 0, 0,
                 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2]}


593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611
class MsgPacketSniffedRaw(Message):
    """
    Description: Message captured by the agent in one of its embedded interfaces (e.g. tun, serial, etc..)

    Type: Event

    Pub/Sub: Agent -> Testing Tool

    Description: TBD
    """
    routing_key = None  # depends on the agent_id and the agent interface being used, re-write after creation

    _msg_data_template = {
        "_type": "packet.sniffed.raw",
        "timestamp": "1488586183.45",
        "interface_name": "tun0",
        "data": [96, 0, 0, 0, 0, 36, 0, 1, 254, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 255, 2, 0, 0, 0, 0, 0, 0,
                 0, 0, 0, 0, 0, 0, 0, 22, 58, 0, 5, 2, 0, 0, 1, 0, 143, 0, 112, 7, 0, 0, 0, 1, 4, 0, 0, 0, 255, 2, 0, 0,
                 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2]}
612

613 614

# # # # # # SESSION MESSAGES # # # # # #
615

616
class MsgTestingToolTerminate(Message):
617
    """
618
    Requirements: TT MUST listen to event, and handle a gracefully termination of all it's processes
Federico Sismondi's avatar
Federico Sismondi committed
619

620
    Type: Event
Federico Sismondi's avatar
Federico Sismondi committed
621

622
    Pub/Sub: GUI, (or Orchestrator) -> Testing Tool
Federico Sismondi's avatar
Federico Sismondi committed
623

624
    Description: Testing tool should stop all it's processes gracefully.
625
    """
626
    routing_key = "control.session"
627 628

    _msg_data_template = {
629
        "_type": "testingtool.terminate",
630
        "description": "Event TERMINATE testing tool execution"
631 632 633 634 635
    }


class MsgTestingToolReady(Message):
    """
636
    Requirements: TT MUST publish event as soon as TT is up and listening on the event bus
Federico Sismondi's avatar
Federico Sismondi committed
637

638
    Type: Event
Federico Sismondi's avatar
Federico Sismondi committed
639

640
    Pub/Sub: Testing Tool -> GUI
Federico Sismondi's avatar
Federico Sismondi committed
641

642
    Description: Used to indicate to the GUI that testing is ready to start the test suite
643
    """
644
    routing_key = "control.session"
645 646

    _msg_data_template = {
647 648
        "_type": "testingtool.ready",
        "description": "Event Testing tool READY to start test suite."
649 650 651 652 653
    }


class MsgTestingToolComponentReady(Message):
    """
654
    Requirements: Testing Tool SHOULD implement (other components should not subscribe to event)
Federico Sismondi's avatar
Federico Sismondi committed
655

656
    Type: Event
Federico Sismondi's avatar
Federico Sismondi committed
657

658
    Pub/Sub: Any Testing tool's component -> Test Coordinator
Federico Sismondi's avatar
Federico Sismondi committed
659

660
    Description: Once a testing tool's component is ready, it should publish a compoennt ready message
661
    """
662
    routing_key = "control.session"
663 664

    _msg_data_template = {
665
        "_type": "testingtool.component.ready",
666
        "component": "SomeComponent",
667
        "description": "Component READY to start test suite."
668 669 670
    }


671 672 673 674 675 676 677 678 679 680
class MsgSessionChat(Message):
    """
    Requirements: GUI should implement

    Type: Event

    Pub/Sub: UI 1 (2) -> UI 2 (1)

    Description: Generic descriptor of chat messages
    """
681
    routing_key = "control.session"
682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704

    _msg_data_template = {
        "_type": "chat",
        "user_name": "Ringo",
        "iut_node": "tbd",
        "description": "I've got blisters on my fingers!"
    }


class MsgSessionLog(Message):
    """
    Requirements: Testing Tool SHOULD implement

    Type: Event

    Pub/Sub: Any Testing tool's component -> user/devs interfaces

    Description: Generic descriptor of log messages
    """
    routing_key = "log.warning.the_drummer"

    _msg_data_template = {
        "_type": "log",
Federico Sismondi's avatar
Federico Sismondi committed
705
        "component": "misc",
706
        "message": "I've got blisters on my fingers!"
707 708 709
    }


710 711
class MsgSessionConfiguration(Message):
    """
712
    Requirements: TT MUST listen to event, and configure accordingly
713 714 715 716 717

    Type: Event

    Pub/Sub: Orchestrator -> Testing Tool

718
    Description: TT MUST listen to this message and configure the testsuite correspondingly
719 720
    """
    routing_key = "control.session"
721

722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739
    _msg_data_template = {
        "_type": "session.configuration",
        "session_id": "666",
        "configuration": {
            'testsuite.testcases': [
                'someTestCaseId1',
                'someTestCaseId2'
            ]
        },
        "testing_tools": "f-interop/someTestToolId",
        "users": [
            "u1",
            "f-interop"
        ],
    }


# TODO deprecate this in favor of the generic MsgSessionConfiguration
740
class MsgInteropSessionConfiguration(Message):
741
    """
742
    Requirements: TT MUST listen to event
Federico Sismondi's avatar
Federico Sismondi committed
743

744
    Type: Event
Federico Sismondi's avatar
Federico Sismondi committed
745

746
    Pub/Sub: Orchestrator -> Testing Tool
Federico Sismondi's avatar
Federico Sismondi committed
747

748
    Description: TT MUST listen to this message and configure the testsuite correspondingly
749
    """
750
    routing_key = "control.session"
751 752

    _msg_data_template = {
753 754
        "_type": "session.interop.configuration",
        "session_id": "TBD",
755 756 757 758 759 760 761 762
        "configuration":
            {
                'testsuite.testcases': [
                    'http://doc.f-interop.eu/tests/TD_COAP_CORE_01',
                    'http://doc.f-interop.eu/tests/TD_COAP'
                ]
            },

763
        "testing_tools": "f-interop/interoperability-coap",
764
        "users": [
765 766 767
            "u1",
            "f-interop"
        ],
768
        "tests": [
769
            {
Federico Sismondi's avatar
Federico Sismondi committed
770
                "testcase_ref": "http://doc.f-interop.eu/tests/TD_COAP_CORE_01",
771
                "settings": {}
772 773
            },
            {
Federico Sismondi's avatar
Federico Sismondi committed
774
                "testcase_ref": "http://doc.f-interop.eu/tests/TD_COAP_CORE_02",
775 776 777
                "settings": {}
            },
            {
Federico Sismondi's avatar
Federico Sismondi committed
778
                "testcase_ref": "http://doc.f-interop.eu/tests/TD_COAP_CORE_03",
779
                "settings": {}
780 781 782 783 784
            }
        ]
    }


785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804
class MsgAgentConfigured(Message):
    """
    Requirements: Testing Tool SHOULD publish event

    Type: Event

    Pub/Sub: Testing Tool -> GUI

    Description: The goal is to notify GUI when agents are ready to start the session
    """

    routing_key = "control.session"

    _msg_data_template = {
        "_type": "agent.configured",
        "description": "Event agent successfully CONFIGURED",
        'name': 'agent_TT'
    }


805 806
class MsgTestingToolConfigured(Message):
    """
807
    Requirements: TT MUST publish event once session.configuration message has been processed.
Federico Sismondi's avatar
Federico Sismondi committed
808

809
    Type: Event
Federico Sismondi's avatar
Federico Sismondi committed
810

811
    Pub/Sub: Testing Tool -> Orchestrator, GUI
Federico Sismondi's avatar
Federico Sismondi committed
812

813
    Description: The goal is to notify orchestrator and other components that the testing tool has been configured
814 815 816 817 818
    """

    routing_key = "control.session"

    _msg_data_template = {
819 820 821
        "_type": "testingtool.configured",
        "description": "Event Testing tool CONFIGURED",
        "session_id": "TBD",
822 823 824
        "testing_tools": "f-interop/interoperability-coap",
    }

825

826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846
class MsgSessionCreated(Message):
    """
    Requirements: Session Orchestrator MUST publish message on common-services channel (on every session creation)

    Type: Event

    Pub/Sub: SO -> viz tools

    Description: The goal is to notify viz tools about new sessions
    """

    routing_key = "control.session.created"

    _msg_data_template = {
        "_type": "session.created",
        "description": "A new session has been created",
        "session_id": "TBD",
        "testing_tools": "TBD",
    }


847 848
class MsgTestingToolComponentShutdown(Message):
    """
849
    Requirements: Testing Tool SHOULD implement (other components should not subscribe to event)
Federico Sismondi's avatar
Federico Sismondi committed
850

851
    Type: Event
Federico Sismondi's avatar
Federico Sismondi committed
852

853
    Pub/Sub: Any Testing tool's component -> Test Coordinator
Federico Sismondi's avatar
Federico Sismondi committed
854

855 856
    Description: tbd
    """
857 858 859
    routing_key = "control.session"

    _msg_data_template = {
860
        "_type": "testingtool.component.shutdown",
861
        "component": "SomeComponent",
862
        "description": "Event Component SHUTDOWN. Bye!"
863 864
    }

865
    # # # # # # TEST COORDINATION MESSAGES # # # # # #
866

867 868 869

class MsgTestSuiteStart(Message):
    """
870
    Requirements: TT MUST listen to event and start the test suite right after reception. MsgTestSuiteStarted
Federico Sismondi's avatar
Federico Sismondi committed
871

872
    Type: Event
Federico Sismondi's avatar
Federico Sismondi committed
873

874
    Pub/Sub: GUI -> Testing Tool
Federico Sismondi's avatar
Federico Sismondi committed
875

876
    Description: tbd
877 878
    """

879
    # TODO change to control.testsuite
880
    routing_key = "control.testcoordination"
881 882

    _msg_data_template = {
883
        "_type": "testcoordination.testsuite.start",
884
        "description": "Event test suite START"
885 886
    }

887

Federico Sismondi's avatar
Federico Sismondi committed
888 889 890 891 892 893 894 895 896 897 898
class MsgTestSuiteStarted(Message):
    """
    Requirements: Testing Tool SHOULD publish to event

    Type: Event

    Pub/Sub: Testing Tool -> GUI

    Description: tbd
    """

899
    # TODO change to control.testsuite
Federico Sismondi's avatar
Federico Sismondi committed
900 901 902 903 904 905
    routing_key = "control.testcoordination"

    _msg_data_template = {
        "_type": "testcoordination.testsuite.started",
        "description": "Event test suite STARTED"
    }
906

907

908 909
class MsgTestSuiteFinish(Message):
    """
910
    Requirements: TT MUST listen to event
Federico Sismondi's avatar
Federico Sismondi committed
911

912
    Type: Event
Federico Sismondi's avatar
Federico Sismondi committed
913

914
    Pub/Sub: GUI -> Testing Tool
Federico Sismondi's avatar
Federico Sismondi committed
915

916
    Description: tbd
917 918
    """

919
    # TODO change to control.testsuite
920 921 922
    routing_key = "control.testcoordination"

    _msg_data_template = {
923
        "_type": "testcoordination.testsuite.finish",
924
        "description": "Event test suite FINISH"
925 926
    }

927

928 929
class MsgTestCaseReady(Message):
    """
930
    Requirements: TT MUST publish event
Federico Sismondi's avatar
Federico Sismondi committed
931

932
    Type: Event
Federico Sismondi's avatar
Federico Sismondi committed
933

Federico Sismondi's avatar
Federico Sismondi committed
934
    Pub/Sub: Testing Tool -> GUI
Federico Sismondi's avatar
Federico Sismondi committed
935

936 937 938
    Description:
        - Used to indicate to the GUI (or automated-iut) which is the next test case to be executed.
        - This message is normally followed by a MsgTestCaseStart (from GUI-> Testing Tool)
939 940
    """

941
    # TODO change to control.testsuite
942
    routing_key = "control.testcoordination"
943 944

    _msg_data_template = {
945
        "_type": "testcoordination.testcase.ready",
Federico Sismondi's avatar
Federico Sismondi committed
946 947 948
        "description": "Next test case to be executed is TD_COAP_CORE_01",
        "testcase_id": "TD_COAP_CORE_01",
        "testcase_ref": "http://doc.f-interop.eu/tests/TD_COAP_CORE_01",
949 950
        "objective": "Perform GET transaction(CON mode)",
        "state": None
951 952 953
    }


954 955
class MsgTestCaseStart(Message):
    """
956
    Requirements: TT MUST listen to event
Federico Sismondi's avatar
Federico Sismondi committed
957

958
    Type: Event
Federico Sismondi's avatar
Federico Sismondi committed
959

960
    Pub/Sub: GUI -> Testing Tool
Federico Sismondi's avatar
Federico Sismondi committed
961

962 963
    Description:
        - Message used for indicating the testing tool to start the test case (the one previously selected)
964 965
        - if testcase_id is Null then testing tool starts previously announced testcase in message
        "testcoordination.testcase.ready",
966
    """
967
    # TODO change to control.testsuite
968
    routing_key = "control.testcoordination"
969 970

    _msg_data_template = {
971
        "_type": "testcoordination.testcase.start",
972 973
        "description": "Event test case START",
        "testcase_id": "TBD",
974 975
    }

Federico Sismondi's avatar
Federico Sismondi committed
976

977 978 979 980 981 982 983 984 985 986 987
class MsgTestCaseStarted(Message):
    """
    Requirements: Testing Tool SHOULD publish event

    Type: Event

    Pub/Sub: Testing Tool -> GUI

    Description:
        - Message used for indicating that testcase has started
    """
988
    # TODO change to control.testsuite
989 990 991 992 993 994 995
    routing_key = "control.testcoordination"

    _msg_data_template = {
        "_type": "testcoordination.testcase.started",
        "description": "Event test case STARTED",
        "testcase_id": "TBD",
    }
996

Federico Sismondi's avatar
Federico Sismondi committed
997

998 999
# TODO MsgTestCaseNotes, see https://portal.etsi.org/cti/downloads/TestSpecifications/6LoWPAN_Plugtests_TestDescriptions_1.0.pdf

1000

1001 1002
class MsgTestCaseConfiguration(Message):
    """
1003
    Requirements: Testing Tool MAY publish event (if needed for executing the test case)
1004 1005 1006 1007 1008 1009
    Type: Event
    Pub/Sub: Testing Tool -> GUI & automated-iut
    Description:
        - Message used to indicate GUI and/or automated-iut which configuration to use.
        - IMPORTANT: deprecate this message in favor of MsgConfigurationExecute and MsgConfigurationExecuted
    """
1010 1011

    # TODO change to control.testsuite
1012 1013 1014
    routing_key = "control.testcoordination"
    _msg_data_template = {
        "_type": "testcoordination.testcase.configuration",
Federico Sismondi's avatar
Federico Sismondi committed
1015
        "configuration_id": "COAP_CFG_01",
1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045
        "node": "coap_server",
        "testcase_id": "TBD",
        "testcase_ref": "TBD",
        "description":
            ["CoAP servers running service at [bbbb::2]:5683",
             "CoAP servers are requested to offer the following resources",
             ["/test", "Default test resource", "Should not exceed 64bytes"],
             ["/seg1/seg2/seg3", "Long path ressource", "Should not exceed 64bytes"],
             ["/query", "Ressource accepting query parameters", "Should not exceed 64bytes"],
             ["/separate",
              "Ressource which cannot be served immediately and which cannot be "
              "acknowledged in a piggy-backed way",
              "Should not exceed 64bytes"],
             ["/large", "Large resource (>1024 bytes)", "shall not exceed 2048bytes"],
             ["/large_update",
              "Large resource that can be updated using PUT method (>1024 bytes)",
              "shall not exceed 2048bytes"],
             ["/large_create",
              "Large resource that can be  created using POST method (>1024 bytes)",
              "shall not exceed 2048bytes"],
             ["/obs", "Observable resource which changes every 5 seconds",
              "shall not exceed 2048bytes"],
             ["/.well-known/core", "CoRE Link Format", "may require usage of Block options"]
             ]
    }


class MsgConfigurationExecute(Message):
    """
    Requirements: Testing Tool MAY publish event (if needed for executing the test case)
Federico Sismondi's avatar
Federico Sismondi committed
1046

1047
    Type: Event
Federico Sismondi's avatar
Federico Sismondi committed
1048

1049
    Pub/Sub: Testing Tool -> GUI & automated-iut
Federico Sismondi's avatar
Federico Sismondi committed
1050

1051 1052
    Description:
        - Message used to indicate GUI and/or automated-iut which configuration to use.
1053
    """
1054 1055

    # TODO change to control.testsuite
1056 1057 1058
    routing_key = "control.testcoordination"

    _msg_data_template = {
1059
        "_type": "testcoordination.configuration.execute",
Federico Sismondi's avatar
Federico Sismondi committed
1060
        "configuration_id": "COAP_CFG_01",
1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084
        "node": "coap_server",
        "testcase_id": "TBD",
        "testcase_ref": "TBD",
        "description":
            ["CoAP servers running service at [bbbb::2]:5683",
             "CoAP servers are requested to offer the following resources",
             ["/test", "Default test resource", "Should not exceed 64bytes"],
             ["/seg1/seg2/seg3", "Long path ressource", "Should not exceed 64bytes"],
             ["/query", "Ressource accepting query parameters", "Should not exceed 64bytes"],
             ["/separate",
              "Ressource which cannot be served immediately and which cannot be "
              "acknowledged in a piggy-backed way",
              "Should not exceed 64bytes"],
             ["/large", "Large resource (>1024 bytes)", "shall not exceed 2048bytes"],
             ["/large_update",
              "Large resource that can be updated using PUT method (>1024 bytes)",
              "shall not exceed 2048bytes"],
             ["/large_create",
              "Large resource that can be  created using POST method (>1024 bytes)",
              "shall not exceed 2048bytes"],
             ["/obs", "Observable resource which changes every 5 seconds",
              "shall not exceed 2048bytes"],
             ["/.well-known/core", "CoRE Link Format", "may require usage of Block options"]
             ]
1085 1086 1087
    }


1088 1089 1090 1091 1092 1093 1094 1095 1096 1097
class MsgConfigurationExecuted(Message):
    """
    Requirements: Testing Tool SHOULD listen to event

    Type: Event

    Pub/Sub: GUI (automated-IUT) -> Testing Tool

    Description:
        - Message used for indicating that the IUT has been configured as requested
1098
        - pixit must be included in this message (pixit = Protocol Implementaiton eXtra Information for Testing)
1099
    """
1100 1101

    # TODO change to control.testsuite
1102 1103 1104 1105 1106
    routing_key = "control.testcoordination"

    _msg_data_template = {
        "_type": "testcoordination.configuration.executed",
        "description": "Event IUT has been configured",
1107
        "node": "coap_server",
Federico Sismondi's avatar
Federico Sismondi committed
1108
        "ipv6_address": "tbd"  # example of pixit
1109 1110 1111
    }


1112 1113
class MsgTestCaseStop(Message):
    """
1114
    Requirements: TT MUST listen to event
Federico Sismondi's avatar
Federico Sismondi committed
1115

1116
    Type: Event
Federico Sismondi's avatar
Federico Sismondi committed
1117

1118
    Pub/Sub: GUI & automated-iut -> Testing Tool
Federico Sismondi's avatar
Federico Sismondi committed
1119

1120 1121
    Description:
        - Message used for indicating the testing tool to stop the test case (the one running).
1122 1123
    """

1124
    # TODO change to control.testsuite
1125
    routing_key = "control.testcoordination"
1126 1127

    _msg_data_template = {
1128
        "_type": "testcoordination.testcase.stop",
1129
        "description": "Event test case STOP"
1130 1131 1132 1133 1134
    }


class MsgTestCaseRestart(Message):
    """
1135
    Requirements: TT MUST listen to event
Federico Sismondi's avatar
Federico Sismondi committed
1136

1137
    Type: Event
Federico Sismondi's avatar
Federico Sismondi committed
1138

1139
    Pub/Sub: GUI -> Testing Tool
Federico Sismondi's avatar
Federico Sismondi committed
1140

1141
    Description: Restart the running test cases.
1142 1143
    """

1144
    # TODO change to control.testsuite
1145
    routing_key = "control.testcoordination"
1146 1147

    _msg_data_template = {
1148
        "_type": "testcoordination.testcase.restart",
1149
        "description": "Event test case RESTART"
1150 1151
    }

1152

1153
class MsgStepStimuliExecute(Message):
1154
    """
1155
    Requirements: TT MUST publish event
1156

1157
    Type: Event
1158

1159
    Pub/Sub: Testing Tool -> GUI
1160

1161
    Description:
1162 1163
        - Used to indicate to the GUI (or automated-iut) which is the stimuli step to be executed by the user (or
        automated-IUT).
1164 1165
    """

1166
    # TODO change to control.testsuite
1167
    routing_key = "control.testcoordination"
1168 1169

    _msg_data_template = {
1170
        "_type": "testcoordination.step.stimuli.execute",
Federico Sismondi's avatar
Federico Sismondi committed
1171 1172
        "description": "Please execute TD_COAP_CORE_01_step_01",
        "step_id": "TD_COAP_CORE_01_step_01",
1173 1174
        "step_type": "stimuli",
        "step_info": [
1175 1176 1177 1178
            "Client is requested to send a GET request with",
            "Type = 0(CON)",
            "Code = 1(GET)"
        ],