messages.py 53.5 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.31, _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.31, _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.31", "_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.31", "_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 66
MsgErrorReply(_api_version = 0.1.31, _type = sniffing.start, error_code = Some error code TBD, error_message = Some
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.31'
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 266 267 268
    Requirements: Testing Tool MAY implement (if IP tun needed)
    Type: Event
    Typical_use: Testing Tool -> Agent
    Description: Message for triggering start IP tun interface in OS where the agent is running
Federico Sismondi's avatar
Federico Sismondi committed
269
    """
270
    routing_key = "control.tun.toAgent.agent_TT"
Federico Sismondi's avatar
Federico Sismondi committed
271 272

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


class MsgAgentTunStarted(Message):
    """
286 287 288 289
    Description: Message for indicating that agent tun has been started
    Type: Event
    Typical_use: Testing Tool -> Agent
    Description: TBD
Federico Sismondi's avatar
Federico Sismondi committed
290
    """
291
    routing_key = "control.tun.from.agent_TT"
Federico Sismondi's avatar
Federico Sismondi committed
292 293

    _msg_data_template = {
294 295 296 297 298 299 300
        "_type": "tun.started",
        "name": "agent_TT",
        "ipv6_prefix": "bbbb",
        "ipv6_host": ":3",
        "ipv4_host": None,
        "ipv4_network": None,
        "ipv4_netmask": None,
301
        "ipv6_no_forwarding": False,
Federico Sismondi's avatar
Federico Sismondi committed
302 303
    }

304

Federico Sismondi's avatar
Federico Sismondi committed
305 306 307 308
'''
TODO add packet.sniffed.raw
ROUTING_KEY: data.tun.fromAgent.coap_server_agent
 - - -
309 310
PROPS: {"delivery_mode": 2, "content_type": "application/json", "headers": {}, "priority": 0, "content_encoding": 
"utf-8"}
Federico Sismondi's avatar
Federico Sismondi committed
311
 - - -
312 313 314
BODY {"timestamp": "1488586183.45", "_type": "packet.sniffed.raw", "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]}
Federico Sismondi's avatar
Federico Sismondi committed
315
'''
316

317 318

# # # # # # SESSION MESSAGES # # # # # #
319

320
class MsgTestingToolTerminate(Message):
321
    """
322 323 324 325
    Requirements: Testing Tool MUST listen to event
    Type: Event
    Typical_use: GUI, (or Orchestrator) -> Testing Tool
    Description: Testing tool should stop all it's processes gracefully.
326
    """
327
    routing_key = "control.session"
328 329

    _msg_data_template = {
330
        "_type": "testingtool.terminate",
331
        "description": "Event TERMINATE testing tool execution"
332 333 334 335 336
    }


class MsgTestingToolReady(Message):
    """
337 338 339 340
    Requirements: Testing Tool MUST publish event
    Type: Event
    Typcal_use: Testing Tool -> GUI
    Description: Used to indicate to the GUI that testing is ready to start the test suite
341
    """
342
    routing_key = "control.session"
343 344

    _msg_data_template = {
345 346
        "_type": "testingtool.ready",
        "description": "Event Testing tool READY to start test suite."
347 348 349 350 351
    }


class MsgTestingToolComponentReady(Message):
    """
352 353 354 355
    Requirements: Testing Tool SHOULD implement (other components should not subscribe to event)
    Type: Event
    Typical_use: Any Testing tool's component -> Test Coordinator
    Description: Once a testing tool's component is ready, it should publish a compoennt ready message
356
    """
357
    routing_key = "control.session"
358 359

    _msg_data_template = {
360
        "_type": "testingtool.component.ready",
361
        "component": "SomeComponent",
362
        "description": "Component READY to start test suite."
363 364 365
    }


366
class MsgInteropSessionConfiguration(Message):
367
    """
368 369 370 371
    Requirements: Testing Tool MUST listen to event
    Type: Event
    Typical_use: Orchestrator -> Testing Tool
    Description: Testing tool MUST listen to this message and configure the testsuite correspondingly
372
    """
373
    routing_key = "control.session"
374 375

    _msg_data_template = {
376 377
        "_type": "session.interop.configuration",
        "session_id": "TBD",
378
        "testing_tools": "f-interop/interoperability-coap",
379
        "users": [
380 381 382
            "u1",
            "f-interop"
        ],
383
        "iuts": [
384
            {
385 386
                "id": "someImplementationFromAUser",
                "role": "coap_server",
387
                "execution_mode": "user-assisted",
388 389 390
                "location": "user-facilities",
                "owner": "someUserName",
                "version": "0.1"
391 392
            },
            {
393 394
                "id": "automated_iut-coap_client-coapthon-v0.1",
                "role": "coap_client",
395
                "execution_mode": "automated-iut",
396 397 398
                "location": "central-server-docker",
                "owner": "f-interop",
                "version": "0.1"
399 400
            }
        ],
401
        "tests": [
402 403
            {
                "testcase_ref": "http://doc.f-interop.eu/tests/TD_COAP_CORE_01_v01",
404
                "settings": {}
405 406 407
            },
            {
                "testcase_ref": "http://doc.f-interop.eu/tests/TD_COAP_CORE_02_v01",
408 409 410 411 412
                "settings": {}
            },
            {
                "testcase_ref": "http://doc.f-interop.eu/tests/TD_COAP_CORE_03_v01",
                "settings": {}
413 414 415 416 417 418 419
            }
        ]
    }


class MsgTestingToolConfigured(Message):
    """
420 421 422 423
    Requirements: Testing Tool MUST publish event
    Type: Event
    Typical_use: Testing Tool -> Orchestrator, GUI
    Description: The goal is to notify orchestrator and other components that the testing tool has been configured
424 425 426 427 428
    """

    routing_key = "control.session"

    _msg_data_template = {
429 430 431
        "_type": "testingtool.configured",
        "description": "Event Testing tool CONFIGURED",
        "session_id": "TBD",
432 433 434
        "testing_tools": "f-interop/interoperability-coap",
    }

435

436 437
class MsgTestingToolComponentShutdown(Message):
    """
438
    Requirements: Testing Tool SHOULD implement (other components should not subscribe to event)
439 440 441 442
    Type: Event
    Typical_use: Any Testing tool's component -> Test Coordinator
    Description: tbd
    """
443 444 445
    routing_key = "control.session"

    _msg_data_template = {
446
        "_type": "testingtool.component.shutdown",
447
        "component": "SomeComponent",
448
        "description": "Event Component SHUTDOWN. Bye!"
449 450
    }

451
    # # # # # # TEST COORDINATION MESSAGES # # # # # #
452

453 454 455

class MsgTestSuiteStart(Message):
    """
456 457 458 459
    Requirements: Testing Tool MUST listen to event
    Type: Event
    Typical_use: GUI -> Testing Tool
    Description: tbd
460 461
    """

462
    routing_key = "control.testcoordination"
463 464

    _msg_data_template = {
465
        "_type": "testcoordination.testsuite.start",
466
        "description": "Event test suite START"
467 468 469
    }


470 471
class MsgTestSuiteFinish(Message):
    """
472 473 474 475
    Requirements: Testing Tool MUST listen to event
    Type: Event
    Typical_use: GUI -> Testing Tool
    Description: tbd
476 477 478 479 480
    """

    routing_key = "control.testcoordination"

    _msg_data_template = {
481
        "_type": "testcoordination.testsuite.finish",
482
        "description": "Event test suite FINISH"
483 484
    }

485

486 487
class MsgTestCaseReady(Message):
    """
488 489 490 491 492 493
    Requirements: Testing Tool MUST publish event
    Type: Event
    Typical_use: GUI -> Testing Tool
    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)
494 495
    """

496
    routing_key = "control.testcoordination"
497 498

    _msg_data_template = {
499 500 501
        "_type": "testcoordination.testcase.ready",
        "description": "Next test case to be executed is TD_COAP_CORE_01_v01",
        "testcase_id": "TD_COAP_CORE_01_v01",
502
        "testcase_ref": "http://doc.f-interop.eu/tests/TD_COAP_CORE_01_v01",
503 504
        "objective": "Perform GET transaction(CON mode)",
        "state": None
505 506 507
    }


508 509
class MsgTestCaseStart(Message):
    """
510 511 512 513 514
    Requirements: Testing Tool MUST listen to event
    Type: Event
    Typical_use: GUI -> Testing Tool
    Description:
        - Message used for indicating the testing tool to start the test case (the one previously selected)
515
    """
516
    routing_key = "control.testcoordination"
517 518

    _msg_data_template = {
519
        "_type": "testcoordination.testcase.start",
520
        "description": "Event test case START"
521 522 523
    }


524 525
class MsgTestCaseConfiguration(Message):
    """
526 527 528 529 530
    Requirements: Testing Tool MAY publish event (if needed for executing the test case)
    Type: Event
    Typical_use: Testing Tool -> GUI & automated-iut
    Description:
        - Message used to indicate GUI and/or automated-iut which configuration to use.
531 532 533 534
    """
    routing_key = "control.testcoordination"

    _msg_data_template = {
535
        "_type": "testcoordination.testcase.configuration",
536
        "configuration_id": "COAP_CFG_01_v01",
537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560
        "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"]
             ]
561 562 563
    }


564 565
class MsgTestCaseStop(Message):
    """
566 567 568 569 570
    Requirements: Testing Tool MUST listen to event
    Type: Event
    Typical_use: GUI & automated-iut -> Testing Tool
    Description:
        - Message used for indicating the testing tool to stop the test case (the one running).
571 572
    """

573
    routing_key = "control.testcoordination"
574 575

    _msg_data_template = {
576
        "_type": "testcoordination.testcase.stop",
577
        "description": "Event test case STOP"
578 579 580 581 582
    }


class MsgTestCaseRestart(Message):
    """
583 584 585 586
    Requirements: Testing Tool MUST listen to event
    Type: Event
    Typical_use: GUI -> Testing Tool
    Description: Restart the running test cases.
587 588
    """

589
    routing_key = "control.testcoordination"
590 591

    _msg_data_template = {
592
        "_type": "testcoordination.testcase.restart",
593
        "description": "Event test case RESTART"
594 595
    }

596

597
class MsgStepStimuliExecute(Message):
598
    """
599
    Requirements: Testing Tool MUST publish event
600

601
    Type: Event
602

603
    Typical_use: Testing Tool -> GUI
604

605
    Description:
606 607
        - Used to indicate to the GUI (or automated-iut) which is the stimuli step to be executed by the user (or
        automated-IUT).
608 609
    """

610
    routing_key = "control.testcoordination"
611 612

    _msg_data_template = {
613 614 615 616 617
        "_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": [
618 619 620 621
            "Client is requested to send a GET request with",
            "Type = 0(CON)",
            "Code = 1(GET)"
        ],
622 623
        "step_state": "executing",
        "node": "coap_client",
624
        "node_execution_mode": "user_assisted",
625 626
        "testcase_id": "TBD",
        "testcase_ref": "TBD"
627 628
    }

629

630
class MsgStepStimuliExecuted(Message):
631
    """
632 633 634 635 636
    Requirements: Testing Tool MUST listen to event
    Type: Event
    Typical_use: GUI (or automated-IUT)-> Testing Tool
    Description:
        - Used to indicate stimuli has been executed by user (and it's user-assisted iut) or by automated-iut
637 638
    """

639
    routing_key = "control.testcoordination"
640 641

    _msg_data_template = {
642
        "_type": "testcoordination.step.stimuli.executed",
643 644 645
        "description": "Event step (stimuli) EXECUTED",
        "node": "coap_client",
        "node_execution_mode": "user_assisted",
646 647 648
    }


649
class MsgStepCheckExecute(Message):
650
    """
651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681
    Requirements: Testing Tool SHOULD publish event
    Type: Event
    Typical_use: Testing Tool -> Analysis
    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
682 683 684
    Type: Event
    Typical_use: test coordination -> test analysis
    Description:
685 686
        - In the context of IUT to IUT test execution, this message is used for indicating that the previously
        executed
687 688
        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)
689 690
    """

691
    routing_key = "control.testcoordination"
692

693
    _msg_data_template = {
694
        "_type": "testcoordination.step.check.executed",
695
        "partial_verdict": "pass",
696
        "description": "TAT says: step complies (checks) with specification",
697 698 699
    }


700
class MsgStepVerifyExecute(Message):
701
    """
702
    Requirements: Testing Tool MUST publish event
703
    Type: Event
704
    Typical_use: Testing Tool -> GUI (or automated-IUT)
705
    Description:
706 707
        - Used to indicate to the GUI (or automated-iut) which is the verify step to be executed by the user (or
        automated-IUT).
708 709
    """

710
    routing_key = "control.testcoordination"
711 712

    _msg_data_template = {
713 714 715 716 717 718 719 720 721 722 723 724 725 726
        "_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"

727 728
    }

729

730
class MsgStepVerifyExecuted(Message):
731
    """
732
    Requirements: Testing Tool MUST listen to event
733 734 735
    Type: Event
    Typical_use: GUI (or automated-IUT)-> Testing Tool
    Description:
736
        - Message generated by user (GUI or automated-IUT) declaring if the IUT VERIFY verifies the expected behaviour.
737 738
    """

739
    routing_key = "control.testcoordination"
740 741

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

750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768
    # class MsgTestCaseFinish(Message):
    #     """
    #     TODO: TBD if needed or not
    #
    #     Requirements: Testing Tool MAY listen to event
    #     Type: Event
    #     Typical_use: GUI (or automated-IUT)-> Testing Tool
    #     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",
    #     }

769

770 771
class MsgTestCaseFinished(Message):
    """
772 773 774 775 776 777
    Requirements: Testing Tool MUST publish event
    Type: Event
    Typical_use: Testing Tool -> GUI
    Description:
        - Used for indicating to subscribers that the test cases has finished.
        - This message is followed by a verdict.
778 779
    """

780
    routing_key = "control.testcoordination"
781 782

    _msg_data_template = {
783 784
        "_type": "testcoordination.testcase.finished",
        "testcase_id": "TD_COAP_CORE_01",
785
        "testcase_ref": "TBD",
786
        "description": "Testcase finished"
787 788
    }

789

790 791
class MsgTestCaseSkip(Message):
    """
792 793 794 795 796 797
    Requirements: Testing Tool MUST listen to event
    Type: Event
    Typical_use: GUI (or automated-IUT)-> Testing Tool
    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
798
        - node (mandatory): node requesting to skip test case
799 800
    """

801
    routing_key = "control.testcoordination"
802 803

    _msg_data_template = {
804
        "_type": "testcoordination.testcase.skip",
805
        "testcase_id": "TD_COAP_CORE_02_v01",
806
        "node": "TBD",
807 808 809 810 811
    }


class MsgTestCaseSelect(Message):
    """
812 813 814 815 816
    Requirements: Testing Tool MUST listen to event
    Type: Event
    Typical_use: GUI (or automated-IUT)-> Testing Tool
    Description: tbd

817 818
    """

819
    routing_key = "control.testcoordination"
820 821

    _msg_data_template = {
822
        "_type": "testcoordination.testcase.select",
823
        "testcase_id": "TD_COAP_CORE_03_v01",
824 825
    }

826

827 828
class MsgTestSuiteAbort(Message):
    """
829 830 831
    Requirements: Testing Tool MUST listen to event
    Type: Event
    Typical_use: GUI (or automated-IUT)-> Testing Tool
832
    Description: Event test suite ABORT
833 834
    """

835
    routing_key = "control.testcoordination"
836 837

    _msg_data_template = {
838
        "_type": "testcoordination.testsuite.abort",
839
        "description": "Event test suite ABORT"
840 841
    }

842

843 844
class MsgTestSuiteGetStatus(Message):
    """
845 846 847 848 849 850
    Requirements: Testing Tool SHOULD implement (other components should not subscribe to event)
    Type: Request (service)
    Typical_use: GUI -> Testing Tool
    Description:
        - Describes current state of the test suite.
        - Format for the response not standardised.
851 852
    """

853
    routing_key = "control.testcoordination.service"
854 855

    _msg_data_template = {
856
        "_type": "testcoordination.testsuite.getstatus",
857 858
    }

859

860
class MsgTestSuiteGetStatusReply(MsgReply):
861
    """
862 863 864 865 866 867
    Requirements: Testing Tool SHOULD implement (other components should not subscribe to event)
    Type: Reply (service)
    Typical_use: Testing Tool -> GUI
    Description:
        - Describes current state of the test suite.
        - Format for the response not standardised.
868 869
    """

870
    routing_key = "control.testcoordination.service.reply"
871 872

    _msg_data_template = {
873 874 875 876
        "_type": "testcoordination.testsuite.getstatus.reply",
        "ok": True,
        "started": True,
        "testcase_id": "TD_COAP_CORE_01_v01",
877
        "testcase_state": "executing",
878
        "step_id": "TD_COAP_CORE_01_v01_step_01"
879

880 881
    }

882

883 884
class MsgTestSuiteGetTestCases(Message):
    """
885 886 887 888
    Requirements: Testing Tool SHOULD (MUST?) implement (other components should not subscribe to event)
    Type: Request (service)
    Typical_use: GUI -> Testing Tool
    Description: TBD
889 890
    """

891
    routing_key = "control.testcoordination.service"
892 893

    _msg_data_template = {
894
        "_type": "testcoordination.testsuite.gettestcases",
895 896
    }

897 898 899

class MsgTestSuiteGetTestCasesReply(MsgReply):
    """
900 901 902 903
    Requirements: Testing Tool SHOULD (MUST?) implement (other components should not subscribe to event)
    Type: Reply (service)
    Typical_use: Testing Tool -> GUI
    Description: TBD
904 905
    """

906
    routing_key = "control.testcoordination.service.reply"
907 908

    _msg_data_template = {
909 910
        "_type": "testcoordination.testsuite.gettestcases.reply",
        "ok": True,
911 912
        "tc_list": [
            {
913
                "testcase_id": "TD_COAP_CORE_01_v01",
914
                "testcase_ref": "http://doc.f-interop.eu/tests/TD_COAP_CORE_01_v01",
915 916
                "objective": "Perform GET transaction(CON mode)",
                "state": None
917 918
            },
            {
919
                "testcase_id": "TD_COAP_CORE_02_v01",
920
                "testcase_ref": "http://doc.f-interop.eu/tests/TD_COAP_CORE_02_v01",
921 922
                "objective": "Perform DELETE transaction (CON mode)",
                "state": None
923 924
            },
            {
925
                "testcase_id": "TD_COAP_CORE_03_v01",
926
                "testcase_ref": "http://doc.f-interop.eu/tests/TD_COAP_CORE_03_v01",
927 928
                "objective": "Perform PUT transaction (CON mode)",
                "state": None
929 930 931 932 933 934 935
            }
        ]
    }


class MsgTestCaseVerdict(Message):
    """
936 937 938 939
    Requirements: Testing Tool MUST publish event
    Type: Event
    Typical_use: Testing Tool -> GUI
    Description: Used to indicate to the GUI (or automated-iut) which is the final verdict of the testcase.
940 941
    """

942
    routing_key = "control.testcoordination"
943 944

    _msg_data_template = {
945 946 947
        "_type": "testcoordination.testcase.verdict",
        "verdict": "pass",
        "description": "No interoperability error was detected,",
948 949 950 951 952 953 954 955
        "partial_verdicts": [
            ["TD_COAP_CORE_01_v01_step_02", None, "CHECK postponed", ""],
            ["TD_COAP_CORE_01_v01_step_03", None, "CHECK postponed", ""],
            ["TD_COAP_CORE_01_v01_step_04", "pass",
             "VERIFY step: User informed that the information was displayed correclty on his/her IUT", ""],
            ["CHECK_1_post_mortem_analysis", "pass",
             "<Frame   3: [bbbb::1 -> bbbb::2] CoAP [CON 43211] GET /test> Match: CoAP(type=0, code=1)"],
            ["CHECK_2_post_mortem_analysis", "pass",
956 957
             "<Frame   4: [bbbb::2 -> bbbb::1] CoAP [ACK 43211] 2.05 Content > Match: CoAP(code=69, "
             "mid=0xa8cb, tok=b'', pl=Not(b''))"],
958
            ["CHECK_3_post_mortem_analysis", "pass",
959 960 961 962 963
             "<Frame   4: [bbbb::2 -> bbbb::1] CoAP [ACK 43211] 2.05 Content > Match: CoAP(opt=Opt("
             "CoAPOptionContentFormat()))"]],
        "testcase_id": "TD_COAP_CORE_01_v01",
        "testcase_ref": "http://f-interop.paris.inria.fr/tests/TD_COAP_CORE_01_v01",
        "objective": "Perform GET transaction(CON mode)", "state": "finished"
964 965 966 967 968
    }


class MsgTestSuiteReport(Message):
    """
969 970 971 972
    Requirements: Testing Tool MUST publish event
    Type: Event
    Typical_use: Testing Tool -> GUI
    Description: Used to indicate to the GUI (or automated-iut) the final results of the test session.
973 974
    """

975
    routing_key = "control.testcoordination"
976 977

    _msg_data_template = {
978
        "_type": "testcoordination.testsuite.report",
979
        "TD_COAP_CORE_01_v01":
980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003
            {
                "verdict": "pass",
                "description": "No interoperability error was detected,",
                "partial_verdicts":
                    [
                        ["TD_COAP_CORE_01_v01_step_02", None, "CHECK postponed", ""],
                        ["TD_COAP_CORE_01_v01_step_03", None, "CHECK postponed", ""],
                        ["TD_COAP_CORE_01_v01_step_04", "pass",
                         "VERIFY step: User informed that the information was displayed "
                         "correclty on his/her IUT",
                         ""],
                        ["CHECK_1_post_mortem_analysis", "pass",
                         "<Frame   3: [bbbb::1 -> bbbb::2] CoAP [CON 43211] GET /test> Match: "
                         "CoAP(type=0, code=1)"],
                        ["CHECK_2_post_mortem_analysis", "pass",
                         "<Frame   4: [bbbb::2 -> bbbb::1] CoAP [ACK 43211] 2.05 Content > "
                         "Match: CoAP(code=69, mid=0xa8cb, tok=b'', pl=Not(b''))"],
                        [
                            "CHECK_3_post_mortem_analysis",
                            "pass",
                            "<Frame   4: [bbbb::2 -> bbbb::1] CoAP [ACK 43211] 2.05 Content > "
                            "Match: CoAP(opt=Opt(CoAPOptionContentFormat()))"]
                    ]
            },
1004 1005

        "TD_COAP_CORE_02_v01":
1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021
            {
                "verdict": "pass",
                "description": "No interoperability error was detected,",
                "partial_verdicts": [
                    ["TD_COAP_CORE_02_v01_step_02", None, "CHECK postponed", ""],
                    ["TD_COAP_CORE_02_v01_step_03", None, "CHECK postponed", ""],
                    ["TD_COAP_CORE_02_v01_step_04", "pass",
                     "VERIFY step: User informed that the information was displayed correclty on his/her "
                     "IUT",
                     ""], ["CHECK_1_post_mortem_analysis", "pass",
                           "<Frame   3: [bbbb::1 -> bbbb::2] CoAP [CON 43213] DELETE /test> Match: CoAP(type=0, "
                           "code=4)"],
                    ["CHECK_2_post_mortem_analysis", "pass",
                     "<Frame   4: [bbbb::2 -> bbbb::1] CoAP [ACK 43213] 2.02 Deleted > Match: CoAP("
                     "code=66, mid=0xa8cd, tok=b'')"]]
            }
1022 1023
    }

1024
    # # # # # # SNIFFING SERVICES REQUEST MESSAGES # # # # # #
1025

1026 1027 1028

class MsgSniffingStart(Message):
    """
1029
    Requirements: Testing Tool SHOULD implement (other components should not subscribe to event)
1030 1031 1032
    Type: Request (service)
    Typical_use: coordination -> sniffing
    Description: tbd
1033 1034
    """

1035
    routing_key = "control.sniffing.service"
1036 1037

    _msg_data_template = {
1038 1039 1040
        "_type": "sniffing.start",
        "capture_id": "TD_COAP_CORE_01",
        "filter_if": "tun0",
1041
        "filter_proto": "udp port 5683"
1042 1043
    }

1044

1045 1046
class MsgSniffingStartReply(MsgReply):
    """
1047 1048 1049 1050
    Requirements: Testing Tool SHOULD implement (other components should not subscribe to event)
    Type: Reply (service)
    Typical_use: sniffing -> coordination
    Description: tbd
1051 1052
    """

1053
    routing_key = "control.sniffing.service.reply"
1054 1055

    _msg_data_template = {
1056
        "_type": "sniffing.start.reply",
1057
        "ok": True
1058 1059
    }

1060

1061 1062
class MsgSniffingStop(Message):
    """
1063 1064 1065 1066
    Requirements: Testing Tool SHOULD implement (other components should not subscribe to event)
    Type: Request (service)
    Typical_use: coordination -> sniffing
    Description: tbd
1067 1068
    """

1069
    routing_key = "control.sniffing.service"
1070 1071

    _msg_data_template = {
1072
        "_type": "sniffing.stop",
1073 1074
    }

1075

1076 1077
class MsgSniffingStoptReply(MsgReply):
    """
1078 1079 1080 1081
    Requirements: Testing Tool SHOULD implement (other components should not subscribe to event)
    Type: Reply (service)
    Typical_use: sniffing -> coordination
    Description: tbd
1082 1083
    """

1084
    routing_key = "control.sniffing.service.reply"
1085 1086

    _msg_data_template = {
1087
        "_type": "sniffing.stop.reply",
1088
        "ok": True
1089 1090
    }

1091

1092 1093
class MsgSniffingGetCapture(Message):
    """
109