cli.py 31.9 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14
# -*- coding: utf-8 -*-
# !/usr/bin/env python3

"""
Command line interface

run as
`
cd f-interop-utils
python3 cli.py
`

"""

15
import six
16 17 18 19 20
import pika
import threading
import logging
import time
import json
21
from datetime import timedelta, datetime
22 23 24 25 26 27 28
import traceback
import uuid
from collections import OrderedDict
import os
import signal
from messages import *
from examples_pcap_base64 import *
29 30 31 32 33
from pure_pcapy import Dumper, Pkthdr, DLT_IEEE802_15_4, DLT_RAW

# globals
message_count = 0

34 35
print("THIS CLI IS NOT SUPPORTED ANY MORE")
logging.warning("THIS CLI IS NOT SUPPORTED ANY MORE")
36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88

def print_message(method, props, body):
    global message_count

    req_body_dict = json.loads(body.decode('utf-8'), object_pairs_hook=OrderedDict)
    logging.info("Message sniffed: %s, body: %s" % (json.dumps(req_body_dict), str(body)))
    message_count += 1

    props_dict = {
        'content_type': props.content_type,
        'content_encoding': props.content_encoding,
        'headers': props.headers,
        'delivery_mode': props.delivery_mode,
        'priority': props.priority,
        'correlation_id': props.correlation_id,
        'reply_to': props.reply_to,
        'expiration': props.expiration,
        'message_id': props.message_id,
        'timestamp': props.timestamp,
        'user_id': props.user_id,
        'app_id': props.app_id,
        'cluster_id': props.cluster_id,
    }
    # let's get rid of values which are empty
    props_dict_only_non_empty_values = {k: v for k, v in props_dict.items() if v is not None}

    print('\n* * * * * * MESSAGE SNIFFED (%s) * * * * * * *' % message_count)
    print("TIME: %s" % datetime.time(datetime.now()))
    print(" - - - ")
    print("ROUTING_KEY: %s" % method.routing_key)
    print(" - - - ")
    print("PROPS: %s" % json.dumps(props_dict_only_non_empty_values))
    print(" - - - ")
    print('BODY %s' % json.dumps(req_body_dict))
    print(" - - - ")
    # print("ERRORS: %s" % )
    print('* * * * * * * * * * * * * * * * * * * * * \n')


def validate_message_format(method, props, body):
    # obj hook so json.loads respects the order of the fields sent -just for visualization purposeses-
    req_body_dict = json.loads(body.decode('utf-8'), object_pairs_hook=OrderedDict)

    if props.content_type != "application/json":
        print('* * * * * * API VALIDATION WARNING * * * * * * * ')
        print("props.content_type : " + str(props.content_type))
        print("application/json was expected")
        print('* * * * * * * * * * * * * * * * * * * * *  \n')

    if '_type' not in req_body_dict.keys():
        print('* * * * * * API VALIDATION WARNING * * * * * * * ')
        print("no < _type > field found")
        print('* * * * * * * * * * * * * * * * * * * * *  \n')
89

90

91 92 93 94 95 96
class NullLogHandler(logging.Handler):
    def emit(self, record):
        pass


class AmqpSniffer(threading.Thread):
97
    COMPONENT_ID = 'amqp_sniffer_%s' % uuid.uuid1()
98
    DEFAULT_EXCHAGE = 'amq.topic'
99
    DEFAULT_URL = 'amqp://guest:guest@localhost'
100

101
    def __init__(self, url=None, exchange=None, topics=None):
102

103
        threading.Thread.__init__(self)
104

105 106 107
        self.exchange = exchange if exchange else self.DEFAULT_EXCHAGE

        self.url = url if url else self.DEFAULT_URL
108

109
        # queues & default exchange declaration
110
        self.connection = pika.BlockingConnection(pika.URLParameters(self.url))
111
        self.channel = self.connection.channel()
112 113 114 115
        self.services_queue_name = 'services_queue@%s' % self.COMPONENT_ID
        self.channel.queue_declare(queue=self.services_queue_name,
                                   auto_delete=True,
                                   arguments={'x-max-length': 200})
116

117
        if topics:  # subscribe only to passed list
118
            for t in topics:
119 120
                self.channel.queue_bind(exchange=self.exchange,
                                        queue=self.services_queue_name,
121 122 123
                                        routing_key=t)

        else:  # subscribe to all events
124 125
            self.channel.queue_bind(exchange=self.exchange,
                                    queue=self.services_queue_name,
126
                                    routing_key='#')
127 128
        # Hello world message
        self.channel.basic_publish(
129 130
            body=json.dumps({'_type': 'cli.info', 'value': 'CLI is up!'}),
            routing_key='control.cli.info',
131
            exchange=self.exchange,
132 133 134
            properties=pika.BasicProperties(
                content_type='application/json',
            )
135 136 137
        )

        self.channel.basic_qos(prefetch_count=1)
138
        self.channel.basic_consume(self.on_request, queue=self.services_queue_name)
139 140

    def stop(self):
141
        self.channel.queue_delete(self.services_queue_name)
142
        self.channel.stop_consuming()
143
        self.connection.close()
144 145 146

    def on_request(self, ch, method, props, body):
        # obj hook so json.loads respects the order of the fields sent -just for visualization purposeses-
147 148 149 150 151 152 153 154 155 156 157 158

        ch.basic_ack(delivery_tag=method.delivery_tag)

        print_message(method, props, body)
        validate_message_format(method, props, body)

    def run(self):
        print("Starting thread listening on the event bus")
        self.channel.start_consuming()
        print('Bye byes!')


159 160 161 162
class Cli(threading.Thread):
    """
    \brief Thread which handles CLI commands entered by the user.
    """
163
    COMPONENT_ID = 'finterop_CLI'
164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182
    CMD_LEVEL_USER = "user"
    CMD_LEVEL_SYSTEM = "system"
    CMD_LEVEL_ALL = [CMD_LEVEL_USER,
                     CMD_LEVEL_SYSTEM]

    def __init__(self, appName, quit_cb=None):
        # initialize parent class
        threading.Thread.__init__(self)

        # slot params
        self.appName = appName
        self.quit_cb = quit_cb

        # local variables
        self.commandLock = threading.Lock()
        self.commands = []
        self.goOn = True

        # logging
183
        self.log = logging.getLogger(self.COMPONENT_ID)
184 185 186 187
        self.log.setLevel(logging.DEBUG)
        self.log.addHandler(NullLogHandler())

        # give this thread a name
188
        self.name = self.COMPONENT_ID
189 190 191

        # register system commands (user commands registered by child object)
        self._registerCommand_internal(
192 193 194 195 196 197
            self.CMD_LEVEL_SYSTEM,
            'help',
            'h',
            'print this menu',
            [],
            self._handleHelp)
198
        self._registerCommand_internal(
199 200 201 202 203 204
            self.CMD_LEVEL_SYSTEM,
            'info',
            'i',
            'information about this application',
            [],
            self._handleInfo)
205
        self._registerCommand_internal(
206 207 208 209 210 211
            self.CMD_LEVEL_SYSTEM,
            'quit',
            'q',
            'quit this application',
            [],
            self._handleQuit)
212
        self._registerCommand_internal(
213 214 215 216 217 218
            self.CMD_LEVEL_SYSTEM,
            'uptime',
            'ut',
            'how long this application has been running',
            [],
            self._handleUptime)
219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314

        self.startTime = 0.0

    def stop(self):
        cli.goOn = False

    def run(self):
        print('{0} - (c) F-interop\n'.format(self.appName))

        self.startTime = time.time()

        try:
            while self.goOn:

                # CLI stops here each time a user needs to call a command
                params = input('> ')

                # log
                self.log.debug('Following command entered:' + params)

                params = params.split()
                if len(params) < 1:
                    continue

                if len(params) == 2 and params[1] == '?':
                    if not self._printUsageFromName(params[0]):
                        if not self._printUsageFromAlias(params[0]):
                            print(' unknown command or alias \'' + params[0] + '\'')
                    continue

                # find this command
                found = False
                self.commandLock.acquire()
                for command in self.commands:
                    if command['name'] == params[0] or command['alias'] == params[0]:
                        found = True
                        cmdParams = command['params']
                        cmdCallback = command['callback']
                        cmdDontCheckParamsLenth = command['dontCheckParamsLength']
                        break
                self.commandLock.release()

                # call its callback or print error message
                if found:
                    if cmdDontCheckParamsLenth or len(params[1:]) == len(cmdParams):
                        cmdCallback(params[1:])
                    else:
                        if not self._printUsageFromName(params[0]):
                            self._printUsageFromAlias(params[0])
                else:
                    print(' unknown command or alias \'' + params[0] + '\'')

        except Exception as err:
            output = []
            output += ['===== crash in thread {0} ====='.format(self.name)]
            output += ['\nerror:\n']
            output += [str(err)]
            output += ['\ncall stack:\n']
            output += [traceback.format_exc()]
            output = '\n'.join(output)
            print(output)
            self.log.critical(output)
            raise

    # ======================== public ==========================================

    def registerCommand(self, name, alias, description, params, callback, dontCheckParamsLength=False):

        self._registerCommand_internal(self.CMD_LEVEL_USER,
                                       name,
                                       alias,
                                       description,
                                       params,
                                       callback,
                                       dontCheckParamsLength)

    # ======================== private =========================================

    def _registerCommand_internal(self, cmdLevel, name, alias, description, params, callback,
                                  dontCheckParamsLength=False):

        assert cmdLevel in self.CMD_LEVEL_ALL
        assert isinstance(name, str)
        assert isinstance(alias, str)
        assert isinstance(description, str)
        assert isinstance(params, list)
        for p in params:
            assert isinstance(p, str)
        assert callable(callback)
        assert dontCheckParamsLength in [True, False]

        if self._doesCommandExist(name):
            raise SystemError("command {0} already exists".format(name))

        self.commandLock.acquire()
        self.commands.append({
315 316 317 318 319 320
            'cmdLevel': cmdLevel,
            'name': name,
            'alias': alias,
            'description': description,
            'params': params,
            'callback': callback,
321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406
            'dontCheckParamsLength': dontCheckParamsLength,
        })
        self.commandLock.release()

    def _printUsageFromName(self, commandname):
        return self._printUsage(commandname, 'name')

    def _printUsageFromAlias(self, commandalias):
        return self._printUsage(commandalias, 'alias')

    def _printUsage(self, name, paramType):

        usageString = None

        self.commandLock.acquire()
        for command in self.commands:
            if command[paramType] == name:
                usageString = []
                usageString += ['usage: {0}'.format(name)]
                usageString += [" <{0}>".format(p) for p in command['params']]
                usageString = ''.join(usageString)
        self.commandLock.release()

        if usageString:
            print(usageString)
            return True
        else:
            return False

    def _doesCommandExist(self, cmdName):

        returnVal = False

        self.commandLock.acquire()
        for cmd in self.commands:
            if cmd['name'] == cmdName:
                returnVal = True
        self.commandLock.release()

        return returnVal

    # === command handlers (system commands only, a child object creates more)

    def _handleHelp(self, params):
        output = []
        output += ['Available commands:']

        self.commandLock.acquire()
        for command in self.commands:
            output += [' - {0} ({1}): {2}'.format(command['name'],
                                                  command['alias'],
                                                  command['description'])]
        self.commandLock.release()

        print('\n'.join(output))

    def _handleInfo(self, params):
        output = []
        output += ['General status of the application']
        output += ['']
        output += ['current time: {0}'.format(time.ctime())]
        output += ['']
        output += ['{0} threads running:'.format(threading.activeCount())]
        threadNames = [t.getName() for t in threading.enumerate()]
        threadNames.sort()
        for t in threadNames:
            output += ['- {0}'.format(t)]
        output += ['']
        output += ['This is thread {0}.'.format(threading.currentThread().getName())]

        print('\n'.join(output))

    def _handleQuit(self, params):

        # call the quit callback
        if self.quit_cb:
            self.quit_cb()

        # kill this thread
        self.goOn = False

    def _handleUptime(self, params):

        upTime = timedelta(seconds=time.time() - self.startTime)

        print('Running since {0} ({1} ago)'.format(
407 408
            time.strftime("%m/%d/%Y %H:%M:%S", time.localtime(self.startTime)),
            upTime))
409 410 411 412 413 414 415 416 417 418 419 420 421 422 423


        # ======================== helpers =========================================


###############################################################################

if __name__ == '__main__':

    MESSAGE_UI_SELECTOR = 1

    logging.basicConfig(format='%(levelname)s:%(message)s', level=logging.WARNING)

    try:
        AMQP_EXCHANGE = str(os.environ['AMQP_EXCHANGE'])
424 425
        print('Imported AMQP_EXCHANGE env var: %s' % AMQP_EXCHANGE)

426
    except KeyError as e:
427
        AMQP_EXCHANGE = "amq.topic"
428
        print('Cannot retrieve environment variables for AMQP EXCHANGE. Loading default: %s' % AMQP_EXCHANGE)
429 430 431

    try:
        AMQP_URL = str(os.environ['AMQP_URL'])
432 433
        print('Imported AMQP_URL env var: %s' % AMQP_URL)

434
        p = six.moves.urllib_parse.urlparse(AMQP_URL)
435

436 437
        AMQP_USER = p.username
        AMQP_SERVER = p.hostname
438

439 440
        logging.info(
            "Env variables imported for AMQP connection, User: {0} @ Server: {1} ".format(AMQP_USER, AMQP_SERVER))
441

442
    except KeyError as e:
443

444 445 446 447 448 449 450 451 452 453 454 455
        print('Cannot retrieve environment variables for AMQP connection. Loading defaults..')
        # load default values
        AMQP_URL = "amqp://{0}:{1}@{2}/{3}".format("guest", "guest", "localhost", "/")

    connection = pika.BlockingConnection(pika.URLParameters(AMQP_URL))
    channel = connection.channel()
    logging.info("AMQP connection established")


    def quitCallback():
        print("quitting!")

456

457 458 459
    def echoCallback(params):
        print("echo {0}!".format(params))

460

461 462
    def forgeAmqpMessages(params):

463
        def publish_message(message):
464

465
            properties = pika.BasicProperties(**message.get_properties())
466 467

            channel.basic_publish(
468 469 470 471
                exchange=AMQP_EXCHANGE,
                routing_key=message.routing_key,
                properties=properties,
                body=message.to_json(),
472 473 474 475 476 477 478 479 480 481 482 483
            )

        # for a typical user input, for a user (coap client) vs automated-iut ( coap server) session type:
        # f 1
        # f 2
        # f 4.a
        # f 4.c
        # =-> there you should get an amqp message saying verdict inconclusive ( due to no traffic on the data plane)

        # re-write each message forged as a unittest? (if not this won't escalate very well)

        events_testcoordination = OrderedDict({
484
            '0': MsgTestingToolConfigured(),
485 486 487 488 489 490 491 492
            '1': MsgTestSuiteStart(),
            '2': MsgTestCaseStart(),
            '3': MsgTestCaseRestart(),
            '4.a': MsgStepStimuliExecuted(),
            '4.b': MsgStepCheckExecuted(),
            '4.c': MsgStepVerifyExecuted(),
            '4.d': MsgStepVerifyExecuted(verify_response=False, description='User indicates that IUT didnt behave '
                                                                            'as expected '),
493
            # TT should be able to know when the test case was finished based on stimuli, check and verify signals
494 495
            # '5':   MsgTestCaseFinish(),
            '6': MsgTestCaseSkip(testcase_id=None),
496 497
            '6.a': MsgTestCaseSkip(testcase_id='TD_COAP_CORE_01_v01'),
            '6.b': MsgTestCaseSkip(testcase_id='TD_COAP_CORE_02_v01'),
498 499
            '6.c': MsgTestCaseSkip(testcase_id='TD_COAP_CORE_03_v01'),
            '6.d': MsgTestCaseSkip(testcase_id='TD_COAP_CORE_04_v01'),
500
            '6.e': MsgTestCaseSkip(testcase_id='TD_COAP_CORE_05_v01'),
501 502
            '7': MsgTestCaseSelect(testcase_id='TD_COAP_CORE_02_v01'),
            '8': MsgTestSuiteAbort(),
503 504 505
            '100': MsgStepStimuliExecute(),
            '101': MsgStepVerifyExecute(),
            '102': MsgStepCheckExecute(),
506
            'orch': MsgOrchestratorVersionReq(),
507

508 509 510
        })
        events_orchestrator = OrderedDict({
            'term': MsgTestingToolTerminate(),
511
            'config': MsgInteropSessionConfiguration(),
512
            'config2': MsgInteropSessionConfiguration(
513 514 515 516 517 518
                tests=[
                    {
                        'testcase_ref': 'TD_COAP_CORE_01_v01',
                        'settings': {}
                    },
                ]
519 520 521

            ),
            'config3': MsgInteropSessionConfiguration(
522 523 524 525 526 527
                tests=[
                    {
                        'testcase_ref': 'someNoneExistantTestCase',
                        'settings': {}
                    },
                ]
528 529

            ),
530
        })
531

532
        service_testcoordination = OrderedDict({
533 534
            'stat0': MsgTestSuiteGetStatus(),
            'tclist': MsgTestSuiteGetTestCases(),
535
        })
536 537 538 539

        service_sniffing = OrderedDict({
            # start sniffing w/ certain parametrization
            'snif0': MsgSniffingStart(
540 541
                capture_id='TD_COAP_CORE_01',
                filter_if='tun0',
542
                filter_proto='udp'
543 544 545
            ),
            'snif1': MsgSniffingStop(),
            # get a particular capture file
546
            'snif2': MsgSniffingGetCapture(capture_id='TD_COAP_CORE_01'),
547 548
            # gets last capture
            'snif3': MsgSniffingGetCaptureLast()
549
        })
550 551

        service_tat = OrderedDict({
552 553 554
            'tat0': MsgInteropTestCaseAnalyze(
                protocol='coap',
            ),
555
            'tat1': MsgInteropTestCaseAnalyze(
556
                protocol='coap',
557
                testcase_id="TD_COAP_CORE_01",
558
                testcase_ref="http://doc.f-interop.eu/tests/TD_COAP_CORE_01_v01",
559 560 561
                file_enc="pcap_base64",
                filename="TD_COAP_CORE_01.pcap",
                value=PCAP_empty_base64,
562 563
            ),
            'tat2': MsgInteropTestCaseAnalyze(
564
                protocol='coap',
565
                testcase_id="TD_COAP_CORE_01",
566
                testcase_ref="http://doc.f-interop.eu/tests/TD_COAP_CORE_01_v01",
567 568 569
                file_enc="pcap_base64",
                filename="TD_COAP_CORE_01.pcap",
                value=PCAP_TC_COAP_01_base64,
570
            ),
571 572
            # 'tat3': MsgInteropTestCaseAnalyze(
            #     testcase_id="TD_COAP_CORE_04",
573
            #     testcase_ref="http://doc.f-interop.eu/tests/TD_COAP_CORE_04_v01",
574 575 576 577
            #     file_enc="pcap_base64",
            #     filename="TD_COAP_CORE_04.pcap",
            #     value=PCAP_COAP_TC4_OVER_TUN_INTERFACE_base64,
            # )
578 579 580 581 582 583 584 585
            'tat_onem2m': MsgInteropTestCaseAnalyze(
                protocol='onem2m',
                testcase_id="TD_M2M_NH_01",
                testcase_ref="http://doc.f-interop.eu/tests/TD_M2M_NH_01",
                file_enc="pcap_base64",
                filename="TD_M2M_NH_01.pcap",
                value=PCAP_ONEM2M_TD_M2M_NH_01,
            ),
586
        })
587

588
        service_dissection = OrderedDict({
589 590 591 592
            # dissection of empty pcap file
            'dis1': MsgDissectionDissectCapture(),
            # dissection of pcap only coap frames
            'dis2': MsgDissectionDissectCapture(
593 594 595 596
                file_enc="pcap_base64",
                filename="TD_COAP_CORE_01.pcap",
                protocol_selection='coap',
                value=PCAP_TC_COAP_01_base64,
597 598 599
            ),
            # complete dissection of pcap
            'dis3': MsgDissectionDissectCapture(
600 601 602
                file_enc="pcap_base64",
                filename="TD_COAP_CORE_01.pcap",
                value=PCAP_TC_COAP_01_base64,
603 604 605
            ),
            # complete dissection of pcap with extra TCP traffic
            'dis4': MsgDissectionDissectCapture(
606 607 608
                file_enc="pcap_base64",
                filename="TD_COAP_CORE_01.pcap",
                value=PCAP_TC_COAP_01_mingled_with_tcp_traffic_base64,
609 610 611
            ),
            # same as dis4 but filtering coap messages
            'dis5': MsgDissectionDissectCapture(
612 613 614 615
                file_enc="pcap_base64",
                filename="TD_COAP_CORE_01.pcap",
                protocol_selection='coap',
                value=PCAP_TC_COAP_01_mingled_with_tcp_traffic_base64,
616 617 618
            ),
            # pcap sniffed using AMQP based packet sniffer
            'dis6': MsgDissectionDissectCapture(
619 620 621
                file_enc="pcap_base64",
                filename="TD_COAP_CORE_01.pcap",
                value=PCAP_COAP_GET_OVER_TUN_INTERFACE_base64,
622
            ),
623 624 625 626 627 628
            # # pcap sniffed using AMQP based packet sniffer
            # 'dis7': MsgDissectionDissectCapture(
            #     file_enc="pcap_base64",
            #     filename="TD_COAP_CORE_04.pcap",
            #     value=PCAP_COAP_TC4_OVER_TUN_INTERFACE_base64,
            # ),
629 630
        })

631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666
        # testing_tool_emulation = OrderedDict({
        #     # testing tool is ready to start session
        #     'tt1': MsgTestingToolReady(),
        #
        #     # testcase coordination
        #     'tt10': MsgStepStimuliExecute(step_id="TD_COAP_CORE_01_v01_step_01"),
        #     # 'tt11': MsgStepCheckExecute(step_id="TD_COAP_CORE_01_v01_step_02"),
        #     # 'tt12': MsgStepCheckExecute(step_id="TD_COAP_CORE_01_v01_step_03"),
        #     'tt13': MsgStepVerifyExecute(step_id="TD_COAP_CORE_01_v01_step_04"),
        #     'ttver':MsgTestCaseVerdict(),
        #     'ttrepo': MsgTestSuiteReport(),
        #     # for 6LoWPAN TT tests
        #     's_hc_01': MsgStepStimuliExecute(step_id='TD_6LoWPAN_HC_01_step_01', node='eut1'),
        #     's_hc_02': MsgStepStimuliExecute(step_id='TD_6LoWPAN_HC_02_step_01', node='eut1'),
        #     's_hc_03': MsgStepStimuliExecute(step_id='TD_6LoWPAN_HC_03_step_01', node='eut1'),
        #     's_hc_04': MsgStepStimuliExecute(step_id='TD_6LoWPAN_HC_04_step_01', node='eut1'),
        #     's_hc_05': MsgStepStimuliExecute(step_id='TD_6LoWPAN_HC_05_step_01', node='eut1'),
        #     's_hc_06': MsgStepStimuliExecute(step_id='TD_6LoWPAN_HC_06_step_01', node='eut1'),
        #     's_hc_07': MsgStepStimuliExecute(step_id='TD_6LoWPAN_HC_07_step_01', node='eut1'),
        #     's_format_01': MsgStepStimuliExecute(step_id='TD_6LoWPAN_FORMAT_01_step_01', node='eut1'),
        #     's_format_03': MsgStepStimuliExecute(step_id='TD_6LoWPAN_FORMAT_03_step_01', node='eut1'),
        #     's_format_04': MsgStepStimuliExecute(step_id='TD_6LoWPAN_FORMAT_04_step_01', node='eut1'),
        #     's_format_06': MsgStepStimuliExecute(step_id='TD_6LoWPAN_FORMAT_06_step_01', node='eut1'),
        #     'tc_hc_01': MsgTestCaseReady(testcase_id='TD_6LoWPAN_HC_01'),
        #     'tc_hc_02': MsgTestCaseReady(testcase_id='TD_6LoWPAN_HC_02'),
        #     'tc_hc_03': MsgTestCaseReady(testcase_id='TD_6LoWPAN_HC_03'),
        #     'tc_hc_04': MsgTestCaseReady(testcase_id='TD_6LoWPAN_HC_04'),
        #     'tc_hc_05': MsgTestCaseReady(testcase_id='TD_6LoWPAN_HC_05'),
        #     'tc_hc_06': MsgTestCaseReady(testcase_id='TD_6LoWPAN_HC_06'),
        #     'tc_hc_07': MsgTestCaseReady(testcase_id='TD_6LoWPAN_HC_07'),
        #     'tc_format_01': MsgTestCaseReady(testcase_id='TD_6LoWPAN_FORMAT_01'),
        #     'tc_format_03': MsgTestCaseReady(testcase_id='TD_6LoWPAN_FORMAT_03'),
        #     'tc_format_04': MsgTestCaseReady(testcase_id='TD_6LoWPAN_FORMAT_04'),
        #     'tc_format_06': MsgTestCaseReady(testcase_id='TD_6LoWPAN_FORMAT_06'),
        # })

667 668 669 670
        testing_tool_emulation = OrderedDict({
            # testing tool is ready to start session
            'tt1': MsgTestingToolReady(),

671
            # testcase coordination
672 673 674 675
            'tt10': MsgStepStimuliExecute(step_id="TD_COAP_CORE_01_v01_step_01"),
            # 'tt11': MsgStepCheckExecute(step_id="TD_COAP_CORE_01_v01_step_02"),
            # 'tt12': MsgStepCheckExecute(step_id="TD_COAP_CORE_01_v01_step_03"),
            'tt13': MsgStepVerifyExecute(step_id="TD_COAP_CORE_01_v01_step_04"),
676
            'ttver': MsgTestCaseVerdict(),
677
            'ttrepo': MsgTestSuiteReport(),
678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694
            # for 6LoWPAN TT tests
            'conf_hc_01_eut1': MsgConfigurationExecute(testcase_id='TD_6LoWPAN_HC_01', node='eut1'),
            'conf_hc_01_eut2': MsgConfigurationExecute(testcase_id='TD_6LoWPAN_HC_01', node='eut2'),
            'conf_hc_03_eut1': MsgConfigurationExecute(testcase_id='TD_6LoWPAN_HC_03', node='eut1'),
            'conf_hc_03_eut2': MsgConfigurationExecute(testcase_id='TD_6LoWPAN_HC_03', node='eut2'),
            'conf_hc_05_eut1': MsgConfigurationExecute(testcase_id='TD_6LoWPAN_HC_05', node='eut1'),
            'conf_hc_05_eut2': MsgConfigurationExecute(testcase_id='TD_6LoWPAN_HC_05', node='eut2'),
            'conf_hc_07_eut1': MsgConfigurationExecute(testcase_id='TD_6LoWPAN_HC_07', node='eut1'),
            'conf_hc_07_eut2': MsgConfigurationExecute(testcase_id='TD_6LoWPAN_HC_07', node='eut2'),
            'conf_format_01_eut1': MsgConfigurationExecute(testcase_id='TD_6LoWPAN_FORMAT_01', node='eut1'),
            'conf_format_01_eut2': MsgConfigurationExecute(testcase_id='TD_6LoWPAN_FORMAT_01', node='eut2'),
            'conf_format_03_eut1': MsgConfigurationExecute(testcase_id='TD_6LoWPAN_FORMAT_03', node='eut1'),
            'conf_format_03_eut2': MsgConfigurationExecute(testcase_id='TD_6LoWPAN_FORMAT_03', node='eut2'),
            'conf_format_04_eut1': MsgConfigurationExecute(testcase_id='TD_6LoWPAN_FORMAT_04', node='eut1'),
            'conf_format_04_eut2': MsgConfigurationExecute(testcase_id='TD_6LoWPAN_FORMAT_04', node='eut2'),
            'conf_format_06_eut1': MsgConfigurationExecute(testcase_id='TD_6LoWPAN_FORMAT_06', node='eut1'),
            'conf_format_06_eut2': MsgConfigurationExecute(testcase_id='TD_6LoWPAN_FORMAT_06', node='eut2'),
695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715
            's_hc_01': MsgStepStimuliExecute(step_id='TD_6LoWPAN_HC_01', node='eut1',
                                             target_address="fe80:0000:0000:0000:0212:4b00:0615:a500"),
        # need to update the target_Address before sending the message!!
            's_hc_03': MsgStepStimuliExecute(step_id='TD_6LoWPAN_HC_03', node='eut1',
                                             target_address="fe80:0000:0000:0000:0212:4b00:0433:ed9c"),
            's_hc_05_step_01': MsgStepStimuliExecute(step_id='TD_6LoWPAN_HC_05', node='eut2',
                                                     target_address="fe80:0000:0000:0000:0212:4b00:0615:a500"),
            's_hc_05_step_02': MsgStepStimuliExecute(step_id='TD_6LoWPAN_HC_05', node='eut1',
                                                     target_address="fe80:0000:0000:0000:0212:4b00:0433:ed9c"),
            's_hc_07_step_01': MsgStepStimuliExecute(step_id='TD_6LoWPAN_HC_07', node='eut2',
                                                     target_address="fe80:0000:0000:0000:0212:4b00:0615:a500"),
            's_hc_07_step_02': MsgStepStimuliExecute(step_id='TD_6LoWPAN_HC_07', node='eut1',
                                                     target_address="fe80:0000:0000:0000:0212:4b00:0433:ed9c"),
            's_format_01': MsgStepStimuliExecute(step_id='TD_6LoWPAN_FORMAT_01', node='eut1',
                                                 target_address="fe80:0000:0000:0000:0212:4b00:060d:97f5"),
            's_format_03': MsgStepStimuliExecute(step_id='TD_6LoWPAN_FORMAT_03', node='eut1',
                                                 target_address="fe80:0000:0000:0000:0212:4b00:0433:ed9c"),
            's_format_04': MsgStepStimuliExecute(step_id='TD_6LoWPAN_FORMAT_04', node='eut1',
                                                 target_address="fe80:0000:0000:0000:0212:4b00:0433:ed9c"),
            's_format_06': MsgStepStimuliExecute(step_id='TD_6LoWPAN_FORMAT_06', node='eut1',
                                                 target_address="fe80:0000:0000:0000:0212:4b00:0433:ed9c"),
716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737
            # 'tc_hc_01': MsgTestCaseReady(testcase_id='TD_6LoWPAN_HC_01'), They have no effect on the iut controller
            # 'tc_hc_02': MsgTestCaseReady(testcase_id='TD_6LoWPAN_HC_02'),
            # 'tc_hc_03': MsgTestCaseReady(testcase_id='TD_6LoWPAN_HC_03'),
            # 'tc_hc_04': MsgTestCaseReady(testcase_id='TD_6LoWPAN_HC_04'),
            # 'tc_hc_05': MsgTestCaseReady(testcase_id='TD_6LoWPAN_HC_05'),
            # 'tc_hc_06': MsgTestCaseReady(testcase_id='TD_6LoWPAN_HC_06'),
            # 'tc_hc_07': MsgTestCaseReady(testcase_id='TD_6LoWPAN_HC_07'),
            # 'tc_format_01': MsgTestCaseReady(testcase_id='TD_6LoWPAN_FORMAT_01'),
            # 'tc_format_03': MsgTestCaseReady(testcase_id='TD_6LoWPAN_FORMAT_03'),
            # 'tc_format_04': MsgTestCaseReady(testcase_id='TD_6LoWPAN_FORMAT_04'),
            # 'tc_format_06': MsgTestCaseReady(testcase_id='TD_6LoWPAN_FORMAT_06'),

            # 'hc_07': MsgStepStimuliExecute(step_id='TD_6LoWPAN_HC_07', node='6lo_client',
            #                                target_address="fe80:0000:0000:0000:0212:4b00:0615:a500"),
            # 'format_01': MsgStepStimuliExecute(step_id='TD_6LoWPAN_Format_01', node='6lo_client',
            #                                    target_address="fe80:0000:0000:0000:0212:4b00:0615:a500"),
            # 'format_03': MsgStepStimuliExecute(step_id='TD_6LoWPAN_Format_03', node='6lo_client',
            #                                    target_address="fe80:0000:0000:0000:0212:4b00:0615:a500"),
            # 'format_04': MsgStepStimuliExecute(step_id='TD_6LoWPAN_Format_04', node='6lo_client',
            #                                    target_address="fe80:0000:0000:0000:0212:4b00:0615:a500"),
            # 'format_06': MsgStepStimuliExecute(step_id='TD_6LoWPAN_Format_06', node='6lo_client',
            #                                    target_address="fe80:0000:0000:0000:0212:4b00:0615:a500"),
738
        })
739

740 741 742 743
        event_type = params[0]
        print(event_type)

        # dict of all messages
Federico Sismondi's avatar
Federico Sismondi committed
744 745 746 747 748 749 750
        messages = events_orchestrator
        messages.update(events_testcoordination)
        messages.update(service_testcoordination)
        messages.update(service_sniffing)
        messages.update(service_tat)
        messages.update(service_dissection)
        messages.update(testing_tool_emulation)
751 752 753 754

        # send message
        if event_type in messages.keys():
            publish_message(messages[event_type])
755
            logging.info("Publishing in the bus: %s" % event_type)
756 757 758 759 760 761 762
        else:
            msgs_str = ''
            for k in sorted(messages):
                msgs_str += k + ': %s, %s \n' % (messages[k].__class__.__name__, messages[k].__doc__)

            logging.warning('Message type not known. '
                            'The valid ones are: \n %s'
763
                            % msgs_str
764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781
                            )


    cli = Cli("Standalone Sample App", quitCallback)
    cli.registerCommand('echo',
                        'e',
                        'echoes the first param',
                        ['string to echo'],
                        echoCallback)

    cli.registerCommand('forge',
                        'f',
                        'generates forged messages for testing the platform',
                        ['message type or number'],
                        forgeAmqpMessages)

    cli.start()

782
    amqp_listener = AmqpSniffer(AMQP_URL, AMQP_EXCHANGE, ['#'])  # if None subscribe to all messages
783 784
    amqp_listener.start()

785
    # interrumpted
786 787
    cli.join()
    amqp_listener.join()
788 789
    if connection:
        connection.close()