messages.py 60.4 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
28
>>> m = MsgTestCaseSkip()
29
>>> m
30
MsgTestCaseSkip(_api_version = 0.1.40, _type = testcoordination.testcase.skip, node = someNode, testcase_id = TD_COAP_CORE_02_v01, )
31 32
>>> m.routing_key
'control.testcoordination'
33 34
>>> m.message_id # doctest: +SKIP
'802012eb-24e3-45c4-9dcc-dc293c584f63'
35 36
>>> m.testcase_id
'TD_COAP_CORE_02_v01'
37

38 39 40
# also we can modify some of the fields (rewrite the default ones)
>>> m = MsgTestCaseSkip(testcase_id = 'TD_COAP_CORE_03_v01')
>>> m
41
MsgTestCaseSkip(_api_version = 0.1.40, _type = testcoordination.testcase.skip, node = someNode, testcase_id = TD_COAP_CORE_03_v01, )
42 43
>>> m.testcase_id
'TD_COAP_CORE_03_v01'
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": "0.1.40", "_type": "testcoordination.testcase.skip", "node": "someNode", "testcase_id": "TD_COAP_CORE_03_v01"}'
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": "0.1.40", "_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 = 0.1.40, _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 = '0.1.40'
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)


95 96
class Message:
    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
        self._msg_data["_api_version"] = API_VERSION
121 122 123 124 125

        # add values as objects attributes
        for key in self._msg_data:
            setattr(self, key, self._msg_data[key])

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

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

136
        return OrderedDict(sorted(resp.items(), key=lambda t: t[0]))  # sorted by key
137 138 139 140

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

141
    def get_properties(self):
142 143 144 145
        resp = OrderedDict()
        for field in self._properties:
            resp[field] = getattr(self, field)
        return resp
146

147
    def __str__(self):
148 149 150 151 152 153 154
        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
155
        return s
156

157 158 159 160 161
    def update_properties(self, **kwargs):
        for key, value in kwargs.items():
            if key in self._properties:
                setattr(self, key, value)

162 163
    @classmethod
    def from_json(cls, body):
164 165 166 167 168 169 170 171 172 173
        """
        :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:
174
            message_dict = json.loads(body.decode("utf-8"))
175
        else:
176
            raise NonCompliantMessageFormatError("Not a Json")
177

178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193
        # 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

194
        # check fist if it's a response
195
        if "ok" in message_dict:
196
            # cannot build a complete reply message just from the json representation
197
            return
198

199
        message_type = message_dict["_type"]
200

201 202 203
        if message_type in message_types_dict:
            return message_types_dict[message_type](**message_dict)
        else:
204 205
            raise NonCompliantMessageFormatError("Cannot load json message: %s" % str(message_dict))

206
    def __repr__(self):
207
        ret = "%s(" % self.__class__.__name__
208
        for key, value in self.to_dict().items():
209 210
            ret += "%s = %s, " % (key, value)
        ret += ")"
211 212
        return ret

213

214 215 216 217 218
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
    """
219

220 221 222 223 224 225 226
    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)
227
        if not hasattr(self, "_msg_data_template"):
228
            self._msg_data_template = {
229
                "_type": request_message._type,
230
                "ok": True,
231 232
            }

233
        super(MsgReply, self).__init__(**kwargs)
234

235
        # overwrite correlation id template and attribute
236
        self._properties["correlation_id"] = request_message.correlation_id
237 238 239 240 241
        self.correlation_id = request_message.correlation_id


class MsgErrorReply(MsgReply):
    """
242
    see section "F-Interop conventions" on top
243
    """
244

245 246
    def __init__(self, request_message, **kwargs):
        assert request_message
247
        # msg_data_template doesnt include _type cause this class is generic, we can only get this at init from request
248
        # so, let's copy the _type from request and let the MsgReply handle the rest of the fields
249
        self._msg_data_template["_type"] = request_message._type
250
        super(MsgErrorReply, self).__init__(request_message, **kwargs)
251 252

    _msg_data_template = {
253
        "ok": False,
254
        "error_message": "Some error message TBD",
255
        "error_code": "Some error code TBD"
256 257
    }

258 259

# # # # # # AGENT MESSAGES # # # # # #
Federico Sismondi's avatar
Federico Sismondi committed
260 261 262

class MsgAgentTunStart(Message):
    """
263
    Requirements: Testing Tool MAY implement (if IP tun needed)
Federico Sismondi's avatar
Federico Sismondi committed
264

265
    Type: Event
Federico Sismondi's avatar
Federico Sismondi committed
266

267
    Pub/Sub: Testing Tool -> Agent
Federico Sismondi's avatar
Federico Sismondi committed
268

269
    Description: Message for triggering start IP tun interface in OS where the agent is running
Federico Sismondi's avatar
Federico Sismondi committed
270
    """
271
    routing_key = "control.tun.toAgent.agent_TT"
Federico Sismondi's avatar
Federico Sismondi committed
272 273

    _msg_data_template = {
274 275 276 277
        "_type": "tun.start",
        "name": "agent_TT",
        "ipv6_prefix": "bbbb",
        "ipv6_host": ":3",
278
        "ipv6_no_forwarding": False,
279 280 281
        "ipv4_host": None,
        "ipv4_network": None,
        "ipv4_netmask": None,
Federico Sismondi's avatar
Federico Sismondi committed
282 283 284
    }


285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305

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
306 307
class MsgAgentTunStarted(Message):
    """
308
    Description: Message for indicating that agent tun has been started
Federico Sismondi's avatar
Federico Sismondi committed
309

310
    Type: Event
Federico Sismondi's avatar
Federico Sismondi committed
311

312
    Pub/Sub: Agent -> Testing Tool
Federico Sismondi's avatar
Federico Sismondi committed
313

314
    Description: TBD
Federico Sismondi's avatar
Federico Sismondi committed
315
    """
316
    routing_key = "control.tun.from.tbd"
Federico Sismondi's avatar
Federico Sismondi committed
317 318

    _msg_data_template = {
319 320 321 322 323 324 325
        "_type": "tun.started",
        "name": "agent_TT",
        "ipv6_prefix": "bbbb",
        "ipv6_host": ":3",
        "ipv4_host": None,
        "ipv4_network": None,
        "ipv4_netmask": None,
326
        "ipv6_no_forwarding": False,
Federico Sismondi's avatar
Federico Sismondi committed
327 328
    }

329

330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350
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]}


351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369
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]}
370

371 372

# # # # # # SESSION MESSAGES # # # # # #
373

374
class MsgTestingToolTerminate(Message):
375
    """
376
    Requirements: Testing Tool MUST listen to event
Federico Sismondi's avatar
Federico Sismondi committed
377

378
    Type: Event
Federico Sismondi's avatar
Federico Sismondi committed
379

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

382
    Description: Testing tool should stop all it's processes gracefully.
383
    """
384
    routing_key = "control.session"
385 386

    _msg_data_template = {
387
        "_type": "testingtool.terminate",
388
        "description": "Event TERMINATE testing tool execution"
389 390 391 392 393
    }


class MsgTestingToolReady(Message):
    """
394
    Requirements: Testing Tool MUST publish event
Federico Sismondi's avatar
Federico Sismondi committed
395

396
    Type: Event
Federico Sismondi's avatar
Federico Sismondi committed
397

398
    Typcal_use: Testing Tool -> GUI
Federico Sismondi's avatar
Federico Sismondi committed
399

400
    Description: Used to indicate to the GUI that testing is ready to start the test suite
401
    """
402
    routing_key = "control.session"
403 404

    _msg_data_template = {
405 406
        "_type": "testingtool.ready",
        "description": "Event Testing tool READY to start test suite."
407 408 409 410 411
    }


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

414
    Type: Event
Federico Sismondi's avatar
Federico Sismondi committed
415

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

418
    Description: Once a testing tool's component is ready, it should publish a compoennt ready message
419
    """
420
    routing_key = "control.session"
421 422

    _msg_data_template = {
423
        "_type": "testingtool.component.ready",
424
        "component": "SomeComponent",
425
        "description": "Component READY to start test suite."
426 427 428
    }


429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469
class MsgSessionChat(Message):
    """
    Requirements: GUI should implement

    Type: Event

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

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

    _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",
        "component": "the_drummer",
        "description": "I've got blisters on my fingers!"
    }


# TODO delete "Interop" to generalize

470
class MsgInteropSessionConfiguration(Message):
471
    """
472
    Requirements: Testing Tool MUST listen to event
Federico Sismondi's avatar
Federico Sismondi committed
473

474
    Type: Event
Federico Sismondi's avatar
Federico Sismondi committed
475

476
    Pub/Sub: Orchestrator -> Testing Tool
Federico Sismondi's avatar
Federico Sismondi committed
477

478
    Description: Testing tool MUST listen to this message and configure the testsuite correspondingly
479
    """
480
    routing_key = "control.session"
481 482

    _msg_data_template = {
483 484
        "_type": "session.interop.configuration",
        "session_id": "TBD",
485
        "testing_tools": "f-interop/interoperability-coap",
486
        "users": [
487 488 489
            "u1",
            "f-interop"
        ],
490
        "iuts": [
491
            {
492 493
                "id": "someImplementationFromAUser",
                "role": "coap_server",
494
                "execution_mode": "user-assisted",
495 496 497
                "location": "user-facilities",
                "owner": "someUserName",
                "version": "0.1"
498 499
            },
            {
500 501
                "id": "automated_iut-coap_client-coapthon-v0.1",
                "role": "coap_client",
502
                "execution_mode": "automated-iut",
503 504 505
                "location": "central-server-docker",
                "owner": "f-interop",
                "version": "0.1"
506 507
            }
        ],
508
        "tests": [
509 510
            {
                "testcase_ref": "http://doc.f-interop.eu/tests/TD_COAP_CORE_01_v01",
511
                "settings": {}
512 513 514
            },
            {
                "testcase_ref": "http://doc.f-interop.eu/tests/TD_COAP_CORE_02_v01",
515 516 517 518 519
                "settings": {}
            },
            {
                "testcase_ref": "http://doc.f-interop.eu/tests/TD_COAP_CORE_03_v01",
                "settings": {}
520 521 522 523 524
            }
        ]
    }


525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544
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'
    }


545 546
class MsgTestingToolConfigured(Message):
    """
547
    Requirements: Testing Tool MUST publish event
Federico Sismondi's avatar
Federico Sismondi committed
548

549
    Type: Event
Federico Sismondi's avatar
Federico Sismondi committed
550

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

553
    Description: The goal is to notify orchestrator and other components that the testing tool has been configured
554 555 556 557 558
    """

    routing_key = "control.session"

    _msg_data_template = {
559 560 561
        "_type": "testingtool.configured",
        "description": "Event Testing tool CONFIGURED",
        "session_id": "TBD",
562 563 564
        "testing_tools": "f-interop/interoperability-coap",
    }

565

566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586
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",
    }


587 588
class MsgTestingToolComponentShutdown(Message):
    """
589
    Requirements: Testing Tool SHOULD implement (other components should not subscribe to event)
Federico Sismondi's avatar
Federico Sismondi committed
590

591
    Type: Event
Federico Sismondi's avatar
Federico Sismondi committed
592

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

595 596
    Description: tbd
    """
597 598 599
    routing_key = "control.session"

    _msg_data_template = {
600
        "_type": "testingtool.component.shutdown",
601
        "component": "SomeComponent",
602
        "description": "Event Component SHUTDOWN. Bye!"
603 604
    }

605
    # # # # # # TEST COORDINATION MESSAGES # # # # # #
606

607 608 609

class MsgTestSuiteStart(Message):
    """
610
    Requirements: Testing Tool MUST listen to event
Federico Sismondi's avatar
Federico Sismondi committed
611

612
    Type: Event
Federico Sismondi's avatar
Federico Sismondi committed
613

614
    Pub/Sub: GUI -> Testing Tool
Federico Sismondi's avatar
Federico Sismondi committed
615

616
    Description: tbd
617 618
    """

619
    routing_key = "control.testcoordination"
620 621

    _msg_data_template = {
622
        "_type": "testcoordination.testsuite.start",
623
        "description": "Event test suite START"
624 625 626
    }


627 628
class MsgTestSuiteFinish(Message):
    """
629
    Requirements: Testing Tool MUST listen to event
Federico Sismondi's avatar
Federico Sismondi committed
630

631
    Type: Event
Federico Sismondi's avatar
Federico Sismondi committed
632

633
    Pub/Sub: GUI -> Testing Tool
Federico Sismondi's avatar
Federico Sismondi committed
634

635
    Description: tbd
636 637 638 639 640
    """

    routing_key = "control.testcoordination"

    _msg_data_template = {
641
        "_type": "testcoordination.testsuite.finish",
642
        "description": "Event test suite FINISH"
643 644
    }

645

646 647
class MsgTestCaseReady(Message):
    """
648
    Requirements: Testing Tool MUST publish event
Federico Sismondi's avatar
Federico Sismondi committed
649

650
    Type: Event
Federico Sismondi's avatar
Federico Sismondi committed
651

Federico Sismondi's avatar
Federico Sismondi committed
652
    Pub/Sub: Testing Tool -> GUI
Federico Sismondi's avatar
Federico Sismondi committed
653

654 655 656
    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)
657 658
    """

659
    routing_key = "control.testcoordination"
660 661

    _msg_data_template = {
662 663 664
        "_type": "testcoordination.testcase.ready",
        "description": "Next test case to be executed is TD_COAP_CORE_01_v01",
        "testcase_id": "TD_COAP_CORE_01_v01",
665
        "testcase_ref": "http://doc.f-interop.eu/tests/TD_COAP_CORE_01_v01",
666 667
        "objective": "Perform GET transaction(CON mode)",
        "state": None
668 669 670
    }


671 672
class MsgTestCaseStart(Message):
    """
673
    Requirements: Testing Tool MUST listen to event
Federico Sismondi's avatar
Federico Sismondi committed
674

675
    Type: Event
Federico Sismondi's avatar
Federico Sismondi committed
676

677
    Pub/Sub: GUI -> Testing Tool
Federico Sismondi's avatar
Federico Sismondi committed
678

679 680
    Description:
        - Message used for indicating the testing tool to start the test case (the one previously selected)
681 682
        - if testcase_id is Null then testing tool starts previously announced testcase in message
        "testcoordination.testcase.ready",
683
    """
684
    routing_key = "control.testcoordination"
685 686

    _msg_data_template = {
687
        "_type": "testcoordination.testcase.start",
688 689
        "description": "Event test case START",
        "testcase_id": "TBD",
690 691 692
    }


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

695 696
class MsgTestCaseConfiguration(Message):
    """
697
    Requirements: Testing Tool MAY publish event (if needed for executing the test case)
Federico Sismondi's avatar
Federico Sismondi committed
698

699
    Type: Event
Federico Sismondi's avatar
Federico Sismondi committed
700

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

703 704
    Description:
        - Message used to indicate GUI and/or automated-iut which configuration to use.
705 706 707 708
    """
    routing_key = "control.testcoordination"

    _msg_data_template = {
709
        "_type": "testcoordination.testcase.configuration",
710
        "configuration_id": "COAP_CFG_01_v01",
711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734
        "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"]
             ]
735 736 737
    }


738 739
class MsgTestCaseStop(Message):
    """
740
    Requirements: Testing Tool MUST listen to event
Federico Sismondi's avatar
Federico Sismondi committed
741

742
    Type: Event
Federico Sismondi's avatar
Federico Sismondi committed
743

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

746 747
    Description:
        - Message used for indicating the testing tool to stop the test case (the one running).
748 749
    """

750
    routing_key = "control.testcoordination"
751 752

    _msg_data_template = {
753
        "_type": "testcoordination.testcase.stop",
754
        "description": "Event test case STOP"
755 756 757 758 759
    }


class MsgTestCaseRestart(Message):
    """
760
    Requirements: Testing Tool MUST listen to event
Federico Sismondi's avatar
Federico Sismondi committed
761

762
    Type: Event
Federico Sismondi's avatar
Federico Sismondi committed
763

764
    Pub/Sub: GUI -> Testing Tool
Federico Sismondi's avatar
Federico Sismondi committed
765

766
    Description: Restart the running test cases.
767 768
    """

769
    routing_key = "control.testcoordination"
770 771

    _msg_data_template = {
772
        "_type": "testcoordination.testcase.restart",
773
        "description": "Event test case RESTART"
774 775
    }

776

777
class MsgStepStimuliExecute(Message):
778
    """
779
    Requirements: Testing Tool MUST publish event
780

781
    Type: Event
782

783
    Pub/Sub: Testing Tool -> GUI
784

785
    Description:
786 787
        - Used to indicate to the GUI (or automated-iut) which is the stimuli step to be executed by the user (or
        automated-IUT).
788 789
    """

790
    routing_key = "control.testcoordination"
791 792

    _msg_data_template = {
793 794 795 796 797
        "_type": "testcoordination.step.stimuli.execute",
        "description": "Please execute TD_COAP_CORE_01_v01_step_01",
        "step_id": "TD_COAP_CORE_01_v01_step_01",
        "step_type": "stimuli",
        "step_info": [
798 799 800 801
            "Client is requested to send a GET request with",
            "Type = 0(CON)",
            "Code = 1(GET)"
        ],
802 803
        "step_state": "executing",
        "node": "coap_client",
804
        "node_execution_mode": "user_assisted",
805 806
        "testcase_id": "TBD",
        "testcase_ref": "TBD"
807 808
    }

809

810
class MsgStepStimuliExecuted(Message):
811
    """
812
    Requirements: Testing Tool MUST listen to event
Federico Sismondi's avatar
Federico Sismondi committed
813

814
    Type: Event
Federico Sismondi's avatar
Federico Sismondi committed
815

816
    Pub/Sub: GUI (or automated-IUT)-> Testing Tool
Federico Sismondi's avatar
Federico Sismondi committed
817

818 819
    Description:
        - Used to indicate stimuli has been executed by user (and it's user-assisted iut) or by automated-iut
820 821
    """

822
    routing_key = "control.testcoordination"
823 824

    _msg_data_template = {
825
        "_type": "testcoordination.step.stimuli.executed",
826 827 828
        "description": "Event step (stimuli) EXECUTED",
        "node": "coap_client",
        "node_execution_mode": "user_assisted",
829 830 831
    }


832
class MsgStepCheckExecute(Message):
833
    """
834
    Requirements: Testing Tool SHOULD publish event
Federico Sismondi's avatar
Federico Sismondi committed
835

836
    Type: Event
Federico Sismondi's avatar
Federico Sismondi committed
837

838
    Pub/Sub: Testing Tool -> Analysis
Federico Sismondi's avatar
Federico Sismondi committed
839

840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867
    Description:
        - Used to indicate to the GUI (or automated-iut) which is the stimuli step to be executed by the user (or
        automated-IUT).
    """

    routing_key = "control.testcoordination"

    _msg_data_template = {
        "_type": "testcoordination.step.check.execute",
        "description": "Please execute TD_COAP_CORE_01_v01_step_02",
        "step_id": "TD_COAP_CORE_01_v01_step_02",
        "step_type": "check",
        "step_info": [
            "The request sent by the client contains",
            "Type=0 and Code=1,"
            "Client-generated Message ID (➔ CMID)",
            "Client-generated Token (➔ CTOK)",
            "UTEST Uri-Path option test"
        ],
        "step_state": "executing",
        "testcase_id": "TBD",
        "testcase_ref": "TBD"
    }


class MsgStepCheckExecuted(Message):
    """
    Requirements: Testing Tool SHOULD implement
Federico Sismondi's avatar
Federico Sismondi committed
868

869
    Type: Event
Federico Sismondi's avatar
Federico Sismondi committed
870

871
    Pub/Sub: test coordination -> test analysis
Federico Sismondi's avatar
Federico Sismondi committed
872

873
    Description:
874 875
        - In the context of IUT to IUT test execution, this message is used for indicating that the previously
        executed
876 877
        messages (stimuli message and its reply) CHECK or comply to what is described in the Test Description.
        - Not used in CoAP testing Tool (analysis of traces is done post mortem)
878 879
    """

880
    routing_key = "control.testcoordination"
881

882
    _msg_data_template = {
883
        "_type": "testcoordination.step.check.executed",
884
        "partial_verdict": "pass",
885
        "description": "TAT says: step complies (checks) with specification",
886 887 888
    }


889
class MsgStepVerifyExecute(Message):
890
    """
891
    Requirements: Testing Tool MUST publish event
Federico Sismondi's avatar
Federico Sismondi committed
892

893
    Type: Event
Federico Sismondi's avatar
Federico Sismondi committed
894

895
    Pub/Sub: Testing Tool -> GUI (or automated-IUT)
Federico Sismondi's avatar
Federico Sismondi committed
896

897
    Description:
898 899
        - Used to indicate to the GUI (or automated-iut) which is the verify step to be executed by the user (or
        automated-IUT).
900 901
    """

902
    routing_key = "control.testcoordination"
903 904

    _msg_data_template = {
905 906 907 908 909 910 911 912 913 914 915 916 917 918
        "_type": "testcoordination.step.verify.execute",
        "response_type": "bool",
        "description": "Please execute TD_COAP_CORE_01_v01_step_04",
        "step_id": "TD_COAP_CORE_01_v01_step_04",
        "step_type": "verify",
        "step_info": [
            "Client displays the received information"
        ],
        "node": "coap_client",
        "node_execution_mode": "user_assisted",
        "step_state": "executing",
        "testcase_id": "TBD",
        "testcase_ref": "TBD"

919 920
    }

921

922
class MsgStepVerifyExecuted(Message):
923
    """
924
    Requirements: Testing Tool MUST listen to event
Federico Sismondi's avatar
Federico Sismondi committed
925

926
    Type: Event
Federico Sismondi's avatar
Federico Sismondi committed
927

928
    Pub/Sub: GUI (or automated-IUT)-> Testing Tool
Federico Sismondi's avatar
Federico Sismondi committed
929

930
    Description:
931
        - Message generated by user (GUI or automated-IUT) declaring if the IUT VERIFY verifies the expected behaviour.
932 933
    """

934
    routing_key = "control.testcoordination"
935 936

    _msg_data_template = {
937 938 939 940 941 942
        "_type": "testcoordination.step.verify.executed",
        "description": "Event step (verify) EXECUTED",
        "response_type": "bool",
        "verify_response": True,
        "node": "coap_client",
        "node_execution_mode": "user_assisted",
943 944
    }

945 946 947 948 949 950
    # class MsgTestCaseFinish(Message):
    #     """
    #     TODO: TBD if needed or not
    #
    #     Requirements: Testing Tool MAY listen to event
    #     Type: Event
951
    #     Pub/Sub: GUI (or automated-IUT)-> Testing Tool
952 953 954 955 956 957 958 959 960 961 962 963
    #     Description:
    #         - Used for indicating that the test case has finished.
    #         - Test coordinator deduces it automatically by using the testcase's step sequence
    #         - Not used in CoAP Testing Tool.
    #     """
    #
    #     routing_key = "control.testcoordination"
    #
    #     _msg_data_template = {
    #         "_type": "testcoordination.testcase.finish",
    #     }

964

965 966
class MsgTestCaseFinished(Message):
    """
967
    Requirements: Testing Tool MUST publish event
Federico Sismondi's avatar
Federico Sismondi committed
968

969
    Type: Event
Federico Sismondi's avatar
Federico Sismondi committed
970

971
    Pub/Sub: Testing Tool -> GUI
Federico Sismondi's avatar
Federico Sismondi committed
972

973 974 975
    Description:
        - Used for indicating to subscribers that the test cases has finished.
        - This message is followed by a verdict.
976 977
    """

978
    routing_key = "control.testcoordination"
979 980

    _msg_data_template = {
981 982
        "_type": "testcoordination.testcase.finished",
        "testcase_id": "TD_COAP_CORE_01",
983
        "testcase_ref": "TBD",
984
        "description": "Testcase finished"
985 986
    }

987

988 989
class MsgTestCaseSkip(Message):
    """
990
    Requirements: Testing Tool MUST listen to event
Federico Sismondi's avatar
Federico Sismondi committed
991

992
    Type: Event
Federico Sismondi's avatar
Federico Sismondi committed
993

994
    Pub/Sub: GUI (or automated-IUT)-> Testing Tool
Federico Sismondi's avatar
Federico Sismondi committed
995

996 997 998
    Description:
        - Used for skipping a test cases event when was previusly selected to be executed.
        - testcase_id (optional) : if not provided then current tc is skipped
999
        - node (mandatory): node requesting to skip test case
1000 1001
    """

1002
    routing_key = "control.testcoordination"
1003 1004

    _msg_data_template = {
1005
        "_type": "testcoordination.testcase.skip",
1006 1007 1008
        "description": "Skip testcase",
        "testcase_id": None,
        "node": "someNode",
1009 1010 1011 1012 1013
    }


class MsgTestCaseSelect(Message):
    """
1014
    Requirements: Testing Tool MUST listen to event
Federico Sismondi's avatar
Federico Sismondi committed
1015

1016
    Type: Event
Federico Sismondi's avatar
Federico Sismondi committed
1017

1018
    Pub/Sub: GUI (or automated-IUT)-> Testing Tool
Federico Sismondi's avatar
Federico Sismondi committed
1019

1020 1021
    Description: tbd