messages.py 60.3 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.38, _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.38, _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.38", "_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.38", "_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.38, _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.38'
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 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307

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

312
    Type: Event
Federico Sismondi's avatar
Federico Sismondi committed
313

314
    Pub/Sub: Agent -> Testing Tool
Federico Sismondi's avatar
Federico Sismondi committed
315

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

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

331

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


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

373 374

# # # # # # SESSION MESSAGES # # # # # #
375

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

380
    Type: Event
Federico Sismondi's avatar
Federico Sismondi committed
381

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

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

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


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

398
    Type: Event
Federico Sismondi's avatar
Federico Sismondi committed
399

400
    Typcal_use: Testing Tool -> GUI
Federico Sismondi's avatar
Federico Sismondi committed
401

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

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


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

416
    Type: Event
Federico Sismondi's avatar
Federico Sismondi committed
417

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

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

    _msg_data_template = {
425
        "_type": "testingtool.component.ready",
426
        "component": "SomeComponent",
427
        "description": "Component READY to start test suite."
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 470 471
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

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

476
    Type: Event
Federico Sismondi's avatar
Federico Sismondi committed
477

478
    Pub/Sub: Orchestrator -> Testing Tool
Federico Sismondi's avatar
Federico Sismondi committed
479

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

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


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


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

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

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

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

    routing_key = "control.session"

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

567

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


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

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

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

597 598
    Description: tbd
    """
599 600 601
    routing_key = "control.session"

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

607
    # # # # # # TEST COORDINATION MESSAGES # # # # # #
608

609 610 611

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

614
    Type: Event
Federico Sismondi's avatar
Federico Sismondi committed
615

616
    Pub/Sub: GUI -> Testing Tool
Federico Sismondi's avatar
Federico Sismondi committed
617

618
    Description: tbd
619 620
    """

621
    routing_key = "control.testcoordination"
622 623

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


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

633
    Type: Event
Federico Sismondi's avatar
Federico Sismondi committed
634

635
    Pub/Sub: GUI -> Testing Tool
Federico Sismondi's avatar
Federico Sismondi committed
636

637
    Description: tbd
638 639 640 641 642
    """

    routing_key = "control.testcoordination"

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

647

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

652
    Type: Event
Federico Sismondi's avatar
Federico Sismondi committed
653

654
    Pub/Sub: GUI -> Testing Tool
Federico Sismondi's avatar
Federico Sismondi committed
655

656 657 658
    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)
659 660
    """

661
    routing_key = "control.testcoordination"
662 663

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


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

677
    Type: Event
Federico Sismondi's avatar
Federico Sismondi committed
678

679
    Pub/Sub: GUI -> Testing Tool
Federico Sismondi's avatar
Federico Sismondi committed
680

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

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


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

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

701
    Type: Event
Federico Sismondi's avatar
Federico Sismondi committed
702

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

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

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


740 741
class MsgTestCaseStop(Message):
    """
742
    Requirements: Testing Tool 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: GUI & automated-iut -> Testing Tool
Federico Sismondi's avatar
Federico Sismondi committed
747

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

752
    routing_key = "control.testcoordination"
753 754

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


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

764
    Type: Event
Federico Sismondi's avatar
Federico Sismondi committed
765

766
    Pub/Sub: GUI -> Testing Tool
Federico Sismondi's avatar
Federico Sismondi committed
767

768
    Description: Restart the running test cases.
769 770
    """

771
    routing_key = "control.testcoordination"
772 773

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

778

779
class MsgStepStimuliExecute(Message):
780
    """
781
    Requirements: Testing Tool MUST publish event
782

783
    Type: Event
784

785
    Pub/Sub: Testing Tool -> GUI
786

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

792
    routing_key = "control.testcoordination"
793 794

    _msg_data_template = {
795 796 797 798 799
        "_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": [
800 801 802 803
            "Client is requested to send a GET request with",
            "Type = 0(CON)",
            "Code = 1(GET)"
        ],
804 805
        "step_state": "executing",
        "node": "coap_client",
806
        "node_execution_mode": "user_assisted",
807 808
        "testcase_id": "TBD",
        "testcase_ref": "TBD"
809 810
    }

811

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

816
    Type: Event
Federico Sismondi's avatar
Federico Sismondi committed
817

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

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

824
    routing_key = "control.testcoordination"
825 826

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


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

838
    Type: Event
Federico Sismondi's avatar
Federico Sismondi committed
839

840
    Pub/Sub: Testing Tool -> Analysis
Federico Sismondi's avatar
Federico Sismondi committed
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 868 869
    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
870

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

873
    Pub/Sub: test coordination -> test analysis
Federico Sismondi's avatar
Federico Sismondi committed
874

875
    Description:
876 877
        - In the context of IUT to IUT test execution, this message is used for indicating that the previously
        executed
878 879
        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)
880 881
    """

882
    routing_key = "control.testcoordination"
883

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


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

895
    Type: Event
Federico Sismondi's avatar
Federico Sismondi committed
896

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

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

904
    routing_key = "control.testcoordination"
905 906

    _msg_data_template = {
907 908 909 910 911 912 913 914 915 916 917 918 919 920
        "_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"

921 922
    }

923

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

928
    Type: Event
Federico Sismondi's avatar
Federico Sismondi committed
929

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

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

936
    routing_key = "control.testcoordination"
937 938

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

947 948 949 950 951 952
    # class MsgTestCaseFinish(Message):
    #     """
    #     TODO: TBD if needed or not
    #
    #     Requirements: Testing Tool MAY listen to event
    #     Type: Event
953
    #     Pub/Sub: GUI (or automated-IUT)-> Testing Tool
954 955 956 957 958 959 960 961 962 963 964 965
    #     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",
    #     }

966

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

971
    Type: Event
Federico Sismondi's avatar
Federico Sismondi committed
972

973
    Pub/Sub: Testing Tool -> GUI
Federico Sismondi's avatar
Federico Sismondi committed
974

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

980
    routing_key = "control.testcoordination"
981 982

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

989

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

994
    Type: Event
Federico Sismondi's avatar
Federico Sismondi committed
995

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

998 999 1000
    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
1001
        - node (mandatory): node requesting to skip test case
1002 1003
    """

1004
    routing_key = "control.testcoordination"
1005 1006

    _msg_data_template = {
1007
        "_type": "testcoordination.testcase.skip",
1008
        "testcase_id": "TD_COAP_CORE_02_v01",
1009
        "node": "TBD",
1010 1011 1012 1013 1014
    }


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

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

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