messages.py 57.9 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.35, _type = testcoordination.testcase.skip, 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.35, _type = testcoordination.testcase.skip, 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.35", "_type": "testcoordination.testcase.skip", "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.35", "_type": "testcoordination.testsuite.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.35, _type = sniffing.start, error_code = Some error code TBD, error_message = Some
66
error message TBD, ok = False, )
67 68 69 70 71 72 73 74 75
>>> 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
76

77 78 79
"""

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

84
API_VERSION = '0.1.35'
85

86 87 88 89 90 91 92 93 94 95 96

# TODO use metaclasses instead?

class NonCompliantMessageFormatError(Exception):
    def __init__(self, value):
        self.value = value

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


97 98
class Message:
    def __init__(self, **kwargs):
99 100 101
        global API_VERSION

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

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

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

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

        # add API's version
122
        self._msg_data["_api_version"] = API_VERSION
123 124 125 126 127

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

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

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

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

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

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

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

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

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

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

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

201
        message_type = message_dict["_type"]
202

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

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

215

216 217 218 219 220
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
    """
221

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

235
        super(MsgReply, self).__init__(**kwargs)
236

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


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

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

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

260 261

# # # # # # AGENT MESSAGES # # # # # #
Federico Sismondi's avatar
Federico Sismondi committed
262 263 264

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

267
    Type: Event
Federico Sismondi's avatar
Federico Sismondi committed
268

269
    Pub/Sub: Testing Tool -> Agent
Federico Sismondi's avatar
Federico Sismondi committed
270

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

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


class MsgAgentTunStarted(Message):
    """
289
    Description: Message for indicating that agent tun has been started
Federico Sismondi's avatar
Federico Sismondi committed
290

291
    Type: Event
Federico Sismondi's avatar
Federico Sismondi committed
292

293
    Pub/Sub: Testing Tool -> Agent
Federico Sismondi's avatar
Federico Sismondi committed
294

295
    Description: TBD
Federico Sismondi's avatar
Federico Sismondi committed
296
    """
297
    routing_key = "control.tun.from.agent_TT"
Federico Sismondi's avatar
Federico Sismondi committed
298 299

    _msg_data_template = {
300 301 302 303 304 305 306
        "_type": "tun.started",
        "name": "agent_TT",
        "ipv6_prefix": "bbbb",
        "ipv6_host": ":3",
        "ipv4_host": None,
        "ipv4_network": None,
        "ipv4_netmask": None,
307
        "ipv6_no_forwarding": False,
Federico Sismondi's avatar
Federico Sismondi committed
308 309
    }

310

311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329
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]}
330

331 332

# # # # # # SESSION MESSAGES # # # # # #
333

334
class MsgTestingToolTerminate(Message):
335
    """
336
    Requirements: Testing Tool MUST listen to event
Federico Sismondi's avatar
Federico Sismondi committed
337

338
    Type: Event
Federico Sismondi's avatar
Federico Sismondi committed
339

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

342
    Description: Testing tool should stop all it's processes gracefully.
343
    """
344
    routing_key = "control.session"
345 346

    _msg_data_template = {
347
        "_type": "testingtool.terminate",
348
        "description": "Event TERMINATE testing tool execution"
349 350 351 352 353
    }


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

356
    Type: Event
Federico Sismondi's avatar
Federico Sismondi committed
357

358
    Typcal_use: Testing Tool -> GUI
Federico Sismondi's avatar
Federico Sismondi committed
359

360
    Description: Used to indicate to the GUI that testing is ready to start the test suite
361
    """
362
    routing_key = "control.session"
363 364

    _msg_data_template = {
365 366
        "_type": "testingtool.ready",
        "description": "Event Testing tool READY to start test suite."
367 368 369 370 371
    }


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

374
    Type: Event
Federico Sismondi's avatar
Federico Sismondi committed
375

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

378
    Description: Once a testing tool's component is ready, it should publish a compoennt ready message
379
    """
380
    routing_key = "control.session"
381 382

    _msg_data_template = {
383
        "_type": "testingtool.component.ready",
384
        "component": "SomeComponent",
385
        "description": "Component READY to start test suite."
386 387 388
    }


389
class MsgInteropSessionConfiguration(Message):
390
    """
391
    Requirements: Testing Tool MUST listen to event
Federico Sismondi's avatar
Federico Sismondi committed
392

393
    Type: Event
Federico Sismondi's avatar
Federico Sismondi committed
394

395
    Pub/Sub: Orchestrator -> Testing Tool
Federico Sismondi's avatar
Federico Sismondi committed
396

397
    Description: Testing tool MUST listen to this message and configure the testsuite correspondingly
398
    """
399
    routing_key = "control.session"
400 401

    _msg_data_template = {
402 403
        "_type": "session.interop.configuration",
        "session_id": "TBD",
404
        "testing_tools": "f-interop/interoperability-coap",
405
        "users": [
406 407 408
            "u1",
            "f-interop"
        ],
409
        "iuts": [
410
            {
411 412
                "id": "someImplementationFromAUser",
                "role": "coap_server",
413
                "execution_mode": "user-assisted",
414 415 416
                "location": "user-facilities",
                "owner": "someUserName",
                "version": "0.1"
417 418
            },
            {
419 420
                "id": "automated_iut-coap_client-coapthon-v0.1",
                "role": "coap_client",
421
                "execution_mode": "automated-iut",
422 423 424
                "location": "central-server-docker",
                "owner": "f-interop",
                "version": "0.1"
425 426
            }
        ],
427
        "tests": [
428 429
            {
                "testcase_ref": "http://doc.f-interop.eu/tests/TD_COAP_CORE_01_v01",
430
                "settings": {}
431 432 433
            },
            {
                "testcase_ref": "http://doc.f-interop.eu/tests/TD_COAP_CORE_02_v01",
434 435 436 437 438
                "settings": {}
            },
            {
                "testcase_ref": "http://doc.f-interop.eu/tests/TD_COAP_CORE_03_v01",
                "settings": {}
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
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'
    }


464 465
class MsgTestingToolConfigured(Message):
    """
466
    Requirements: Testing Tool MUST publish event
Federico Sismondi's avatar
Federico Sismondi committed
467

468
    Type: Event
Federico Sismondi's avatar
Federico Sismondi committed
469

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

472
    Description: The goal is to notify orchestrator and other components that the testing tool has been configured
473 474 475 476 477
    """

    routing_key = "control.session"

    _msg_data_template = {
478 479 480
        "_type": "testingtool.configured",
        "description": "Event Testing tool CONFIGURED",
        "session_id": "TBD",
481 482 483
        "testing_tools": "f-interop/interoperability-coap",
    }

484

485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505
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",
    }


506 507
class MsgTestingToolComponentShutdown(Message):
    """
508
    Requirements: Testing Tool SHOULD implement (other components should not subscribe to event)
Federico Sismondi's avatar
Federico Sismondi committed
509

510
    Type: Event
Federico Sismondi's avatar
Federico Sismondi committed
511

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

514 515
    Description: tbd
    """
516 517 518
    routing_key = "control.session"

    _msg_data_template = {
519
        "_type": "testingtool.component.shutdown",
520
        "component": "SomeComponent",
521
        "description": "Event Component SHUTDOWN. Bye!"
522 523
    }

524
    # # # # # # TEST COORDINATION MESSAGES # # # # # #
525

526 527 528

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

531
    Type: Event
Federico Sismondi's avatar
Federico Sismondi committed
532

533
    Pub/Sub: GUI -> Testing Tool
Federico Sismondi's avatar
Federico Sismondi committed
534

535
    Description: tbd
536 537
    """

538
    routing_key = "control.testcoordination"
539 540

    _msg_data_template = {
541
        "_type": "testcoordination.testsuite.start",
542
        "description": "Event test suite START"
543 544 545
    }


546 547
class MsgTestSuiteFinish(Message):
    """
548
    Requirements: Testing Tool MUST listen to event
Federico Sismondi's avatar
Federico Sismondi committed
549

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

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

554
    Description: tbd
555 556 557 558 559
    """

    routing_key = "control.testcoordination"

    _msg_data_template = {
560
        "_type": "testcoordination.testsuite.finish",
561
        "description": "Event test suite FINISH"
562 563
    }

564

565 566
class MsgTestCaseReady(Message):
    """
567
    Requirements: Testing Tool MUST publish event
Federico Sismondi's avatar
Federico Sismondi committed
568

569
    Type: Event
Federico Sismondi's avatar
Federico Sismondi committed
570

571
    Pub/Sub: GUI -> Testing Tool
Federico Sismondi's avatar
Federico Sismondi committed
572

573 574 575
    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)
576 577
    """

578
    routing_key = "control.testcoordination"
579 580

    _msg_data_template = {
581 582 583
        "_type": "testcoordination.testcase.ready",
        "description": "Next test case to be executed is TD_COAP_CORE_01_v01",
        "testcase_id": "TD_COAP_CORE_01_v01",
584
        "testcase_ref": "http://doc.f-interop.eu/tests/TD_COAP_CORE_01_v01",
585 586
        "objective": "Perform GET transaction(CON mode)",
        "state": None
587 588 589
    }


590 591
class MsgTestCaseStart(Message):
    """
592
    Requirements: Testing Tool MUST listen to event
Federico Sismondi's avatar
Federico Sismondi committed
593

594
    Type: Event
Federico Sismondi's avatar
Federico Sismondi committed
595

596
    Pub/Sub: GUI -> Testing Tool
Federico Sismondi's avatar
Federico Sismondi committed
597

598 599
    Description:
        - Message used for indicating the testing tool to start the test case (the one previously selected)
600 601
        - if testcase_id is Null then testing tool starts previously announced testcase in message
        "testcoordination.testcase.ready",
602
    """
603
    routing_key = "control.testcoordination"
604 605

    _msg_data_template = {
606
        "_type": "testcoordination.testcase.start",
607 608
        "description": "Event test case START",
        "testcase_id": "TBD",
609 610 611
    }


612 613
class MsgTestCaseConfiguration(Message):
    """
614
    Requirements: Testing Tool MAY publish event (if needed for executing the test case)
Federico Sismondi's avatar
Federico Sismondi committed
615

616
    Type: Event
Federico Sismondi's avatar
Federico Sismondi committed
617

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

620 621
    Description:
        - Message used to indicate GUI and/or automated-iut which configuration to use.
622 623 624 625
    """
    routing_key = "control.testcoordination"

    _msg_data_template = {
626
        "_type": "testcoordination.testcase.configuration",
627
        "configuration_id": "COAP_CFG_01_v01",
628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651
        "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"]
             ]
652 653 654
    }


655 656
class MsgTestCaseStop(Message):
    """
657
    Requirements: Testing Tool MUST listen to event
Federico Sismondi's avatar
Federico Sismondi committed
658

659
    Type: Event
Federico Sismondi's avatar
Federico Sismondi committed
660

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

663 664
    Description:
        - Message used for indicating the testing tool to stop the test case (the one running).
665 666
    """

667
    routing_key = "control.testcoordination"
668 669

    _msg_data_template = {
670
        "_type": "testcoordination.testcase.stop",
671
        "description": "Event test case STOP"
672 673 674 675 676
    }


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

679
    Type: Event
Federico Sismondi's avatar
Federico Sismondi committed
680

681
    Pub/Sub: GUI -> Testing Tool
Federico Sismondi's avatar
Federico Sismondi committed
682

683
    Description: Restart the running test cases.
684 685
    """

686
    routing_key = "control.testcoordination"
687 688

    _msg_data_template = {
689
        "_type": "testcoordination.testcase.restart",
690
        "description": "Event test case RESTART"
691 692
    }

693

694
class MsgStepStimuliExecute(Message):
695
    """
696
    Requirements: Testing Tool MUST publish event
697

698
    Type: Event
699

700
    Pub/Sub: Testing Tool -> GUI
701

702
    Description:
703 704
        - Used to indicate to the GUI (or automated-iut) which is the stimuli step to be executed by the user (or
        automated-IUT).
705 706
    """

707
    routing_key = "control.testcoordination"
708 709

    _msg_data_template = {
710 711 712 713 714
        "_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": [
715 716 717 718
            "Client is requested to send a GET request with",
            "Type = 0(CON)",
            "Code = 1(GET)"
        ],
719 720
        "step_state": "executing",
        "node": "coap_client",
721
        "node_execution_mode": "user_assisted",
722 723
        "testcase_id": "TBD",
        "testcase_ref": "TBD"
724 725
    }

726

727
class MsgStepStimuliExecuted(Message):
728
    """
729
    Requirements: Testing Tool MUST listen to event
Federico Sismondi's avatar
Federico Sismondi committed
730

731
    Type: Event
Federico Sismondi's avatar
Federico Sismondi committed
732

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

735 736
    Description:
        - Used to indicate stimuli has been executed by user (and it's user-assisted iut) or by automated-iut
737 738
    """

739
    routing_key = "control.testcoordination"
740 741

    _msg_data_template = {
742
        "_type": "testcoordination.step.stimuli.executed",
743 744 745
        "description": "Event step (stimuli) EXECUTED",
        "node": "coap_client",
        "node_execution_mode": "user_assisted",
746 747 748
    }


749
class MsgStepCheckExecute(Message):
750
    """
751
    Requirements: Testing Tool SHOULD publish event
Federico Sismondi's avatar
Federico Sismondi committed
752

753
    Type: Event
Federico Sismondi's avatar
Federico Sismondi committed
754

755
    Pub/Sub: Testing Tool -> Analysis
Federico Sismondi's avatar
Federico Sismondi committed
756

757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784
    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
785

786
    Type: Event
Federico Sismondi's avatar
Federico Sismondi committed
787

788
    Pub/Sub: test coordination -> test analysis
Federico Sismondi's avatar
Federico Sismondi committed
789

790
    Description:
791 792
        - In the context of IUT to IUT test execution, this message is used for indicating that the previously
        executed
793 794
        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)
795 796
    """

797
    routing_key = "control.testcoordination"
798

799
    _msg_data_template = {
800
        "_type": "testcoordination.step.check.executed",
801
        "partial_verdict": "pass",
802
        "description": "TAT says: step complies (checks) with specification",
803 804 805
    }


806
class MsgStepVerifyExecute(Message):
807
    """
808
    Requirements: Testing Tool MUST publish event
Federico Sismondi's avatar
Federico Sismondi committed
809

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

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

814
    Description:
815 816
        - Used to indicate to the GUI (or automated-iut) which is the verify step to be executed by the user (or
        automated-IUT).
817 818
    """

819
    routing_key = "control.testcoordination"
820 821

    _msg_data_template = {
822 823 824 825 826 827 828 829 830 831 832 833 834 835
        "_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"

836 837
    }

838

839
class MsgStepVerifyExecuted(Message):
840
    """
841
    Requirements: Testing Tool MUST listen to event
Federico Sismondi's avatar
Federico Sismondi committed
842

843
    Type: Event
Federico Sismondi's avatar
Federico Sismondi committed
844

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

847
    Description:
848
        - Message generated by user (GUI or automated-IUT) declaring if the IUT VERIFY verifies the expected behaviour.
849 850
    """

851
    routing_key = "control.testcoordination"
852 853

    _msg_data_template = {
854 855 856 857 858 859
        "_type": "testcoordination.step.verify.executed",
        "description": "Event step (verify) EXECUTED",
        "response_type": "bool",
        "verify_response": True,
        "node": "coap_client",
        "node_execution_mode": "user_assisted",
860 861
    }

862 863 864 865 866 867
    # class MsgTestCaseFinish(Message):
    #     """
    #     TODO: TBD if needed or not
    #
    #     Requirements: Testing Tool MAY listen to event
    #     Type: Event
868
    #     Pub/Sub: GUI (or automated-IUT)-> Testing Tool
869 870 871 872 873 874 875 876 877 878 879 880
    #     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",
    #     }

881

882 883
class MsgTestCaseFinished(Message):
    """
884
    Requirements: Testing Tool MUST publish event
Federico Sismondi's avatar
Federico Sismondi committed
885

886
    Type: Event
Federico Sismondi's avatar
Federico Sismondi committed
887

888
    Pub/Sub: Testing Tool -> GUI
Federico Sismondi's avatar
Federico Sismondi committed
889

890 891 892
    Description:
        - Used for indicating to subscribers that the test cases has finished.
        - This message is followed by a verdict.
893 894
    """

895
    routing_key = "control.testcoordination"
896 897

    _msg_data_template = {
898 899
        "_type": "testcoordination.testcase.finished",
        "testcase_id": "TD_COAP_CORE_01",
900
        "testcase_ref": "TBD",
901
        "description": "Testcase finished"
902 903
    }

904

905 906
class MsgTestCaseSkip(Message):
    """
907
    Requirements: Testing Tool MUST listen to event
Federico Sismondi's avatar
Federico Sismondi committed
908

909
    Type: Event
Federico Sismondi's avatar
Federico Sismondi committed
910

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

913 914 915
    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
916
        - node (mandatory): node requesting to skip test case
917 918
    """

919
    routing_key = "control.testcoordination"
920 921

    _msg_data_template = {
922
        "_type": "testcoordination.testcase.skip",
923
        "testcase_id": "TD_COAP_CORE_02_v01",
924
        "node": "TBD",
925 926 927 928 929
    }


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

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

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

936 937
    Description: tbd

938 939
    """

940
    routing_key = "control.testcoordination"
941 942

    _msg_data_template = {
943
        "_type": "testcoordination.testcase.select",
944
        "testcase_id": "TD_COAP_CORE_03_v01",
945 946
    }

947

948 949
class MsgTestSuiteAbort(Message):
    """
950
    Requirements: Testing Tool MUST listen to event
Federico Sismondi's avatar
Federico Sismondi committed
951

952
    Type: Event
Federico Sismondi's avatar
Federico Sismondi committed
953

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

956
    Description: Event test suite ABORT
957 958
    """

959
    routing_key = "control.testcoordination"