From cfa48db5d059b891aa53cb52e512504860863bed Mon Sep 17 00:00:00 2001 From: Bartosz Gardziejewski Date: Wed, 8 Apr 2020 09:47:06 +0200 Subject: Remove old PNF simulator Issue-ID: INT-1517 Signed-off-by: Bartosz Gardziejewski Change-Id: I235b0fdf12b265a256c371126e218826e74a9133 --- test/mocks/pnfsimulator/simulator-cli/.gitignore | 7 - test/mocks/pnfsimulator/simulator-cli/README.md | 304 ----------------- .../pnfsimulator/simulator-cli/cli/__init__.py | 19 -- .../simulator-cli/cli/client/__init__.py | 19 -- .../simulator-cli/cli/client/tailf_client.py | 59 ---- .../simulator-cli/cli/data/logging.ini | 20 -- .../simulator-cli/cli/netconf_simulator.py | 278 --------------- .../simulator-cli/cli/pnf_simulator.py | 374 --------------------- .../pnfsimulator/simulator-cli/requirements.txt | 23 -- test/mocks/pnfsimulator/simulator-cli/setup.py | 34 -- .../pnfsimulator/simulator-cli/tests/__init__.py | 19 -- .../tests/resources/notification.json | 17 - .../simulator-cli/tests/test_netconf_simulator.py | 165 --------- .../simulator-cli/tests/test_pnf_simulator.py | 270 --------------- .../simulator-cli/tests/test_tailf_client.py | 47 --- 15 files changed, 1655 deletions(-) delete mode 100644 test/mocks/pnfsimulator/simulator-cli/.gitignore delete mode 100644 test/mocks/pnfsimulator/simulator-cli/README.md delete mode 100644 test/mocks/pnfsimulator/simulator-cli/cli/__init__.py delete mode 100644 test/mocks/pnfsimulator/simulator-cli/cli/client/__init__.py delete mode 100644 test/mocks/pnfsimulator/simulator-cli/cli/client/tailf_client.py delete mode 100644 test/mocks/pnfsimulator/simulator-cli/cli/data/logging.ini delete mode 100755 test/mocks/pnfsimulator/simulator-cli/cli/netconf_simulator.py delete mode 100755 test/mocks/pnfsimulator/simulator-cli/cli/pnf_simulator.py delete mode 100644 test/mocks/pnfsimulator/simulator-cli/requirements.txt delete mode 100644 test/mocks/pnfsimulator/simulator-cli/setup.py delete mode 100644 test/mocks/pnfsimulator/simulator-cli/tests/__init__.py delete mode 100644 test/mocks/pnfsimulator/simulator-cli/tests/resources/notification.json delete mode 100644 test/mocks/pnfsimulator/simulator-cli/tests/test_netconf_simulator.py delete mode 100644 test/mocks/pnfsimulator/simulator-cli/tests/test_pnf_simulator.py delete mode 100644 test/mocks/pnfsimulator/simulator-cli/tests/test_tailf_client.py (limited to 'test/mocks/pnfsimulator/simulator-cli') diff --git a/test/mocks/pnfsimulator/simulator-cli/.gitignore b/test/mocks/pnfsimulator/simulator-cli/.gitignore deleted file mode 100644 index 96a29d6e2..000000000 --- a/test/mocks/pnfsimulator/simulator-cli/.gitignore +++ /dev/null @@ -1,7 +0,0 @@ -**/*.iml -**/.idea -**/target -**/__pycache__ -build/** -dist/** -pnf_simulator_cli.egg-info/** \ No newline at end of file diff --git a/test/mocks/pnfsimulator/simulator-cli/README.md b/test/mocks/pnfsimulator/simulator-cli/README.md deleted file mode 100644 index 5dc6f76b9..000000000 --- a/test/mocks/pnfsimulator/simulator-cli/README.md +++ /dev/null @@ -1,304 +0,0 @@ -## PNF/NETCONF SIMULATOR CLI - -### Overview -Anytime you want to see a basic usage of a tool, you can run fully descriptive help using command: -``` -./{tool_name}.py -h # --help argument is also acceptable -``` - -#### PNF Simulator CLI -PNF Simulator CLI provides command line interface to remotely interact with running PNF Simulator. - -Using the PNF Simulator CLI user is able to trigger events, retrieve simulator's configuration and change default VES url stored -inside simulator. - -#### Netconf Simulator CLI -Dedicated tool to help with management of the Netconf Server is also available. - -Using the Netconf Simulator CLI user is able to retrieve simulator's cm history stored inside simulator as well as open the live session to actively listen for new configuration changes. - -### Requirements and installation -Requirements -* Python > 3.5 - -Installation: -* Go to directory containing setup.py and invoke `python setup.py install` -* Go to cli directory -* Add executable privilege to pnf_simulator.py and netconf_simulator.py (for example `chmod +x `) - -### Pnf simulator -#### Usage -* [send](#send-action) -* [configure](#configure-action) -* [get-config](#get-config-action) -* [template](#template-action) -* [filter](#filter-templates-action) - - -#### Help -Invoke `pnf_simulator.py [send|configure|get-config] -h` to display help. - -##### Send Action -Send action allows user to trigger sending events from Simulator to VES Collector. - -*sending repeating events backed by template persisted in db -`usage: pnf_simulator.py send template [-h] --address ADDRESS --name NAME - [--patch PATCH] [--repeats REPEATS] - [--interval INTERVAL] - [--ves-server-url VES_SERVER_URL] [--verbose] -` - -Parameters -` --address ADDRESS` `IP address of simulator` -` --name NAME` `Name of template file which should be used as a base for event. - Cannot be used simultaneously with parameter: event.` -` --patch PATCH` `Json which should be merged into template to override parameters. - Acceptable format: valid json wrapped using single quotes (example:'{"abc":1}'). - Cannot be used simultaneously with parameter: event.` -` --repeats REPEATS` `Number of events to be send` -` --interval INTERVAL` `Interval between two consecutive events (in seconds)` -` --ves-server-url VES_SERVER_URL` `Well-formed URL which will override current VES endpoint stored in simulator's DB` -` --verbose` `Displays additional logs` - - -*sending event only once by passing path to file with complete event -`usage: pnf_simulator.py send event [-h] --address ADDRESS --filepath FILEPATH - [--ves-server-url VES_SERVER_URL] [--verbose] -` -Parameters -` --address ADDRESS` `IP address of simulator` -` --filepath FILEPATH` `Path to file with full, legitimate event that is to be send directly to VES only once. - This event is not associated with template and will not be persisted in db. - Cannot be used simultaneously with parameters: template and patch.` -` --ves-server-url VES_SERVER_URL` `Well-formed URL which will override current VES endpoint stored in simulator's DB` -` --verbose` `Displays additional logs` - -example content of file with complete event: -``` -{ - "commonEventHeader": { - "eventId": "#Timestamp", - "sourceName": "#Increment", - "version": 3.0 - } -} -``` - -##### Configure Action -Configure action allows user to change Simulator's configuration (VES Server URL) -`usage: pnf_simulator.py configure [-h] --address ADDRESS --ves-server-url - VES_SERVER_URL [--verbose] -` - -Parameters - -` --address ADDRESS` `IP address of simulator` -` --ves-server-url VES_SERVER_URL` `Well-formed URL which should be set as a default VES Server URL in simulator` -` --verbose` `Displays additional logs` - -##### Get Config Action -Get Config action allows user to retrieve actual Simulator's configuration -`usage: pnf_simulator.py get-config [-h] --address ADDRESS [--verbose] ` - -Parameters - -`--address ADDRESS` `IP address of simulator` -`--verbose` `Displays additional logs` - -##### Template Action -Template action allows user to: -* retrieve a single template by name -* list all available templates. -* upload template to PNF Simulator (can overwrite existing template) - -`usage: pnf_simulator.py template [-h] - (--list | --get-content NAME | --upload FILENAME) - [--override] --address ADDRESS [--verbose]` - -Parameters - -`--get-content NAME` `Gets the template by name` -`--list` `List all templates` -`--upload FILENAME [--override]` `Uploads the template given as FILENAME file. Optionally overrides any exisitng templates with matching filename` -`--address ADDRESS` `IP address of simulator` -`--verbose` `Displays additional logs` - -#### Filter Templates Action -Filter template action allows to search through templates in order to find names of those that satisfy given criteria. -Criteria are passed in JSON format, as key-values pairs. Relation between pairs with criteria is AND (all conditions must be satisfied by template to have it returned). -No searching for null values is supported. -Search expression must be valid JSON, thus no duplicate keys are allowed - user could specify the same parameter multiple times, but only last occurrence will be applied to query. - - -`usage: pnf_simulator.py filter [-h] - --criteria CRITERIA --address ADDRESS [--verbose]` - -Parameters -`--criteria CRITERIA` `Json with criteria as key-value pairs, where values can be one of following data types: string, integer, double, boolean. - Acceptable format: valid json wrapped using single quotes (example:'{"searchedInt":1}'). - Cannot be used simultaneously with parameter: event.` -`--address ADDRESS` `IP address of simulator` -`--verbose` `Displays additional logs` - - -### Netconf simulator -#### Usage -* [load-model](#load-model-action) -* [delete-model](#delete-model-action) -* [get-config](#get-config-action) -* [edit-config](#edit-config-action) -* [tailf](#tailf-action) -* [less](#less-action) -* [cm-history](#cm-history-action) - -#### Help -Invoke `netconf_simulator.py [tailf|less|cm-history] -h` to display help. - - -#### Load-model action -Loads to netconf server new YANG model that corresponds with schema passed as yang-model parameter, -assigns name specified in module-name and initializes model with startup configuration passed in config file. -`usage: netconf_simulator.py load-module [-h] --address ADDRESS ---module-name MODULE_NAME --yang-model YANG_MODEL_FILEPATH --config [--verbose]` - -example YANG schema (file content for YANG_MODEL) -``` -Response status: 200 -module pnf-simulator { - namespace "http://nokia.com/pnf-simulator"; - prefix config; - container config { - config true; - leaf itemValue1 {type uint32;} - leaf itemValue2 {type uint32;} - leaf itemValue3 {type uint32;} - leaf-list allow-user { - type string; - ordered-by user; - description "A sample list of user names."; - } - } -} -``` - -example startup configuration (file content of XML_CONFIG) -``` - - 100 - 200 - 300 - -``` - - -example output (without verbose flag): -``` -Response status: 200 -Successfully started -``` - -#### Delete-model action -Deletes a YANG model loaded in the netconf server. - -`usage: netconf_simulator.py delete-model [-h] --address ADDRESS --model-name - MODEL_NAME [--verbose]` - -Example output (without verbose flag): -``` -Response status: 200 -Successfully deleted -``` - -#### Get-config Action -Returns active running configurations. -By default it returns all running configurations. To retrieve one specific configuration (represented by _/'module_name':'container'_ ) user needs to pass module-name and container. -Example: -` -netconf_simulator.py get-config --address localhost --module-name pnf-simulator --container config -` - - -`usage: netconf_simulator.py get-config [-h] --address ADDRESS [--verbose] [--module-name MODULE-NAME] [--container CONTAINER]` - -example output (without verbose flag): -``` -Response status: 200 - - 2781 - 3782 - 3333 - -``` - -#### Edit-config Action -Modifies existing configuration (e.g. change parameter values, modify or remove parameter from model). -To edit configuration, netconf compliant XML file should be prepared and used as one of edit-config parameters. -`usage: netconf_simulator.py edit-config [-h] --address ADDRESS --config [--verbose]` - -example - parameter values modification -file content: -``` - - 1 - 2 - 3 - -``` - -example output (without verbose flag): -``` -Response status: 202 - - 1 - 2 - 3 - -``` - -##### Less Action -Less action allows user to watch historical configuration changes. -Size of the configuration changes list is limited to the 100 last cm events by default, but can be incresed/decresead using a 'limit' attribute. -`usage: netconf_simulator.py less [-h] --address ADDRESS [--limit LIMIT] [--verbose]` - -Output from the command can be easily piped into other tools like native less, more, etc. e.g.: -`netconf_simulator.py less --address 127.0.0.1 | less` - -Last known configuration is last printed to the output, so order of the printed configuration events complies with time when the configuration was stored inside the simulator. - -Parameters: - -`--address ADDRESS` - `IP address of simulator` - -`--limit LIMIT` - ` Number of configurations to print at output` - -`--verbose` - ` Displays additional logs` - -Single message is represented as a pair of timestamp in epoch format and suitable configuration entry. - -##### Tailf Action -Tailf action allows user to actively listen for new uploaded configuration changes. -Size of the historical configuration changes list is limited to the 10 last cm events. -`usage: netconf_simulator.py tailf [-h] --address ADDRESS [--verbose]` - -The listener can be easily terminated at anytime using `CTRL+C` shortcut. - -Parameters: - -`--address ADDRESS` - `IP address of simulator` - -`--verbose` - ` Displays additional logs` - -Single message is represented as a pair of timestamp in epoch format and suitable configuration entry. - -##### Cm-history Action -Cm-history action allows user to view list of all uploaded configuration changes. -`usage: netconf_simulator.py cm-history [-h] --address ADDRESS [--verbose]` - -Last known configuration is last printed to the output, so order of the printed configuration events complies with time when the configuration was stored inside the simulator. - -Parameters: - -`--address ADDRESS` - `IP address of simulator` - -`--verbose` - ` Displays additional logs` - -Single message is represented as a pair of timestamp in epoch format and suitable configuration entry. diff --git a/test/mocks/pnfsimulator/simulator-cli/cli/__init__.py b/test/mocks/pnfsimulator/simulator-cli/cli/__init__.py deleted file mode 100644 index aa8b4f995..000000000 --- a/test/mocks/pnfsimulator/simulator-cli/cli/__init__.py +++ /dev/null @@ -1,19 +0,0 @@ -### -# ============LICENSE_START======================================================= -# Simulator -# ================================================================================ -# Copyright (C) 2019 Nokia. All rights reserved. -# ================================================================================ -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# ============LICENSE_END========================================================= -### diff --git a/test/mocks/pnfsimulator/simulator-cli/cli/client/__init__.py b/test/mocks/pnfsimulator/simulator-cli/cli/client/__init__.py deleted file mode 100644 index aa8b4f995..000000000 --- a/test/mocks/pnfsimulator/simulator-cli/cli/client/__init__.py +++ /dev/null @@ -1,19 +0,0 @@ -### -# ============LICENSE_START======================================================= -# Simulator -# ================================================================================ -# Copyright (C) 2019 Nokia. All rights reserved. -# ================================================================================ -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# ============LICENSE_END========================================================= -### diff --git a/test/mocks/pnfsimulator/simulator-cli/cli/client/tailf_client.py b/test/mocks/pnfsimulator/simulator-cli/cli/client/tailf_client.py deleted file mode 100644 index d1cb60d97..000000000 --- a/test/mocks/pnfsimulator/simulator-cli/cli/client/tailf_client.py +++ /dev/null @@ -1,59 +0,0 @@ -### -# ============LICENSE_START======================================================= -# Simulator -# ================================================================================ -# Copyright (C) 2019 Nokia. All rights reserved. -# ================================================================================ -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# ============LICENSE_END========================================================= -### - -import logging - -import websockets -import asyncio -import signal -import sys - - -class TailfClient(object): - - def __init__(self, url: str, verbose: bool = False) -> None: - self._url = url - self._is_running = False - self._connection = None - self.logger = logging.getLogger() - self.logger.setLevel(logging.DEBUG if verbose else logging.INFO) - signal.signal(signal.SIGINT, self._handle_keyboard_interrupt) - - def tailf_messages(self): - self._is_running = True - self.logger.debug("Attempting to connect to websocket server on %s", self._url) - asyncio.get_event_loop().run_until_complete( - self._tailf_messages() - ) - - async def _tailf_messages(self): - try: - async with websockets.connect(self._url) as connection: - self.logger.debug("Connection with %s established", self._url) - self._connection = connection - while self._is_running: - print(await self._connection.recv(), "\n") - except ConnectionRefusedError: - self.logger.error("Cannot establish connection with %s", self._url) - - def _handle_keyboard_interrupt(self, sig, frame): - self.logger.warning("CTR-C pressed, interrupting.") - self._is_running = False - sys.exit(0) diff --git a/test/mocks/pnfsimulator/simulator-cli/cli/data/logging.ini b/test/mocks/pnfsimulator/simulator-cli/cli/data/logging.ini deleted file mode 100644 index 8b2b40285..000000000 --- a/test/mocks/pnfsimulator/simulator-cli/cli/data/logging.ini +++ /dev/null @@ -1,20 +0,0 @@ -[loggers] -keys=root - -[handlers] -keys=consoleHandler - -[formatters] -keys=simpleFormatter - -[logger_root] -level=DEBUG -handlers=consoleHandler - -[handler_consoleHandler] -class=StreamHandler -formatter=simpleFormatter -args=(sys.stdout,) - -[formatter_simpleFormatter] -format=%(message)s diff --git a/test/mocks/pnfsimulator/simulator-cli/cli/netconf_simulator.py b/test/mocks/pnfsimulator/simulator-cli/cli/netconf_simulator.py deleted file mode 100755 index a3b3bf1de..000000000 --- a/test/mocks/pnfsimulator/simulator-cli/cli/netconf_simulator.py +++ /dev/null @@ -1,278 +0,0 @@ -#!/usr/bin/env python3 -### -# ============LICENSE_START======================================================= -# Simulator -# ================================================================================ -# Copyright (C) 2019 Nokia. All rights reserved. -# ================================================================================ -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# ============LICENSE_END========================================================= -### - -import argparse -import logging -import logging.config -import requests -import os -import sys -from requests import Response - -from cli.client.tailf_client import TailfClient - -TAILF_FUNC_ENDPOINT = "ws://{}:9000/netconf" -LESS_FUNC_ENDPOINT = "/store/less" -CM_HISTORY_ENDPOINT = "/store/cm-history" -GET_CONFIG_ENDPOINT = "/netconf/get" -MODEL_ENDPOINT = "/netconf/model/{}" -EDIT_CONFIG_ENDPOINT = "/netconf/edit-config" -logging.basicConfig() - -DEFAULT_EXTERNAL_SIM_PORT = 8080 -DEFAULT_INTERNAL_SIM_PORT = 9000 - - -class NetconfSimulatorClient(object): - def __init__(self, ip: str, protocol: str = 'http', port: int = DEFAULT_EXTERNAL_SIM_PORT, verbose: bool = False) -> None: - self._ip = ip - self._protocol = protocol - self._port = port - self._configure_logger(verbose) - self._verbose=verbose - - def tailf_like_func(self) -> None: - url = TAILF_FUNC_ENDPOINT.format(self._ip) - client = TailfClient(url, self._verbose) - client.tailf_messages() - - def get_cm_history(self) -> None: - self.logger.info("Attempting to retrieve all netconf configuration changes") - simulator_address = "{}://{}:{}{}".format(self._protocol, self._ip, self._port, CM_HISTORY_ENDPOINT) - self.logger.debug("Simulator address: %s", simulator_address) - try: - response = requests.get(simulator_address) - self._log_json_response(response) - except requests.ConnectionError: - self.logger.error("Failed to establish connection with {}".format(simulator_address)) - - def less_like_func(self, limit: int) -> None: - self.logger.info("Attempting to run less on CM change") - simulator_address = "{}://{}:{}{}".format(self._protocol, self._ip, self._port, LESS_FUNC_ENDPOINT) - parameters = {"offset": limit} if limit else None - self.logger.debug("Simulator address: %s", simulator_address) - try: - response = requests.get(url = simulator_address, params = parameters) - self._log_json_response(response) - except requests.ConnectionError: - self.logger.error("Failed to establish connection with {}".format(simulator_address)) - - def get_config(self, module_name: str=None, container:str=None)-> None: - self.logger.info("Attempting to run get-config") - simulator_address = self._create_get_endpoint(module_name, container) - self.logger.debug("Simulator address: %s", simulator_address) - try: - response = requests.get(simulator_address) - self._log_string_response(response) - except requests.ConnectionError: - self.logger.error("Failed to establish connection with {}".format(simulator_address)) - - def load_yang_model(self, module_name: str, yang_model_path: str, config_path: str) -> None: - self.logger.info( - "Attempting to load new yang model with its initial configuration") - simulator_address = "{}://{}:{}{}".format(self._protocol, self._ip, self._port, MODEL_ENDPOINT.format(module_name)) - files = {"yangModel": open(yang_model_path, "rb"), - "initialConfig": open(config_path, "rb")} - self.logger.debug("Simulator address: %s", simulator_address) - - try: - response = requests.post(simulator_address, files=files) - self._log_string_response(response) - except requests.ConnectionError: - self.logger.error("Failed to establish connection with {}".format(simulator_address)) - - def delete_yang_model(self, model_name: str) -> None: - self.logger.info( - "Attempting to delete a yang model") - simulator_address = "{}://{}:{}{}".format(self._protocol, self._ip, self._port, MODEL_ENDPOINT.format(model_name)) - self.logger.debug("Simulator address: %s", simulator_address) - - try: - response = requests.delete(simulator_address) - self._log_string_response(response) - except requests.ConnectionError: - self.logger.error("Failed to establish connection with {}".format(simulator_address)) - - def edit_config(self, new_config_path: str): - self.logger.info("Attempting to apply new configuration") - simulator_address = "{}://{}:{}{}".format(self._protocol, self._ip, self._port, EDIT_CONFIG_ENDPOINT) - files = {"editConfigXml": open(new_config_path,"rb")} - self.logger.debug("Simulator address: %s", simulator_address) - - try: - response = requests.post(simulator_address, files=files) - self._log_string_response(response) - except requests.ConnectionError: - self.logger.error("Failed to establish connection with {}".format(simulator_address)) - - def _log_json_response(self, response: Response) ->None: - self.logger.info("Response status: %d", response.status_code) - self.logger.info(" ----- HEAD -----") - for message in response.json(): - self.logger.info("{}: {}".format(str(message['timestamp']), message['configuration'])) - self.logger.info(" ----- END ------") - self.logger.debug(response.headers) - - def _configure_logger(self, verbose): - logging_conf = os.path.join(sys.prefix, 'logging.ini') - if os.path.exists(logging_conf): - logging.config.fileConfig(logging_conf) - else: - print("Couldn't find logging.ini, using default logger config") - self.logger = logging.getLogger() - self.logger.setLevel(logging.DEBUG if verbose else logging.INFO) - - def _log_string_response(self, response: Response)->None: - self.logger.info("Response status: %d", response.status_code) - self.logger.info(response.text) - self.logger.debug(response.headers) - - def _create_get_endpoint(self, module_name: str, container: str): - endpoint = "{}://{}:{}{}".format(self._protocol, self._ip, self._port, - GET_CONFIG_ENDPOINT) - if module_name and container: - endpoint = endpoint + "/{}/{}".format(module_name, container) - elif (not module_name and container) or (module_name and not container): - raise AttributeError( - "Both module_name and container must be present or absent") - return endpoint - -def create_argument_parser(): - parser = argparse.ArgumentParser(description="Netconf Simulator Command Line Interface. ") - subparsers = parser.add_subparsers(title="Available actions") - tailf_parser = subparsers.add_parser("tailf", - description="Method which allows user to view N last lines of configuration changes") - - __configure_tailf_like_parser(tailf_parser) - less_parser = subparsers.add_parser("less", description="Method which allows user to traverse configuration changes") - __configure_less_like_parser(less_parser) - cm_history_parser = subparsers.add_parser("cm-history", - description="Method which allows user to view all configuration changes") - __configure_cm_history_parser(cm_history_parser) - - load_model_parser = subparsers.add_parser("load-model") - __configure_load_model_parser(load_model_parser) - - delete_model_parser = subparsers.add_parser("delete-model") - __configure_delete_model_parser(delete_model_parser) - - get_config_parser = subparsers.add_parser("get-config") - __configure_get_config_parser(get_config_parser) - edit_config_parser = subparsers.add_parser("edit-config") - __configure_edit_config_parser(edit_config_parser) - return parser - - -def run_tailf(args): - client = NetconfSimulatorClient(args.address, verbose=args.verbose) - client.tailf_like_func() - - -def run_get_cm_history(args): - client = NetconfSimulatorClient(args.address, verbose=args.verbose, port=DEFAULT_INTERNAL_SIM_PORT) - client.get_cm_history() - - -def run_less(args): - client = NetconfSimulatorClient(args.address, verbose=args.verbose, port=DEFAULT_INTERNAL_SIM_PORT) - client.less_like_func(args.limit) - - -def run_load_model(args): - client = NetconfSimulatorClient(args.address, verbose=args.verbose, - port=DEFAULT_INTERNAL_SIM_PORT) - client.load_yang_model(args.module_name, args.yang_model, args.config) - - -def run_delete_model(args): - client = NetconfSimulatorClient(args.address, verbose=args.verbose, - port=DEFAULT_INTERNAL_SIM_PORT) - client.delete_yang_model(args.model_name) - - -def run_get_config(args): - client = NetconfSimulatorClient(args.address, verbose=args.verbose, port=DEFAULT_INTERNAL_SIM_PORT) - client.get_config(args.module_name, args.container) - - -def run_edit_config(args): - client = NetconfSimulatorClient(args.address, verbose=args.verbose, port=DEFAULT_INTERNAL_SIM_PORT) - client.edit_config(args.config) - - -def __configure_tailf_like_parser(tailf_func_parser): - tailf_func_parser.add_argument("--address", required=True, help="IP address of simulator") - tailf_func_parser.add_argument("--verbose", action='store_true', - help="Displays additional logs") - tailf_func_parser.set_defaults(func=run_tailf) - - -def __configure_less_like_parser(less_func_parser): - less_func_parser.add_argument("--address", required=True, help="IP address of simulator") - less_func_parser.add_argument("--limit", help="Limit of configurations to retrieve") - less_func_parser.add_argument("--verbose", action='store_true', help="Displays additional logs") - less_func_parser.set_defaults(func=run_less) - - -def __configure_cm_history_parser(cm_history_parser): - cm_history_parser.add_argument("--address", required=True, help="IP address of simulator") - cm_history_parser.add_argument("--verbose", action='store_true', help="Displays additional logs") - cm_history_parser.set_defaults(func=run_get_cm_history) - - -def __configure_load_model_parser(load_model_parser): - load_model_parser.add_argument("--address", required=True, help="IP address of simulator") - load_model_parser.add_argument("--module-name", required=True, help="Module name corresponding to yang-model") - load_model_parser.add_argument("--verbose", action='store_true', help="Displays additional logs") - load_model_parser.add_argument("--yang-model", required=True, help="Path to file with yang model") - load_model_parser.add_argument("--config", required=True, help="Path to file with initial xml config") - load_model_parser.set_defaults(func=run_load_model) - - -def __configure_delete_model_parser(delete_model_parser): - delete_model_parser.add_argument("--address", required=True, help="IP address of simulator") - delete_model_parser.add_argument("--model-name", required=True, help="YANG model name to delete") - delete_model_parser.add_argument("--verbose", action='store_true', help="Displays additional logs") - delete_model_parser.set_defaults(func=run_delete_model) - - -def __configure_get_config_parser(get_config_parser): - get_config_parser.add_argument("--address", required=True, help="IP address of simulator") - get_config_parser.add_argument("--verbose", action='store_true',help="Displays additional logs") - get_config_parser.add_argument("--module-name", help="Module name corresponding to yang-model", default=None) - get_config_parser.add_argument("--container", help="Container name corresponding to module name", default=None) - get_config_parser.set_defaults(func=run_get_config) - - -def __configure_edit_config_parser(edit_config_parser): - edit_config_parser.add_argument("--address", required=True, help="IP address of simulator") - edit_config_parser.add_argument("--verbose", action='store_true', help="Displays additional logs") - edit_config_parser.add_argument("--config", required=True, help="Path to file with xml config to apply") - edit_config_parser.set_defaults(func=run_edit_config) - - -if __name__ == "__main__": - argument_parser = create_argument_parser() - result = argument_parser.parse_args() - if hasattr(result, 'func'): - result.func(result) - else: - argument_parser.parse_args(['-h']) diff --git a/test/mocks/pnfsimulator/simulator-cli/cli/pnf_simulator.py b/test/mocks/pnfsimulator/simulator-cli/cli/pnf_simulator.py deleted file mode 100755 index 9176fd8e0..000000000 --- a/test/mocks/pnfsimulator/simulator-cli/cli/pnf_simulator.py +++ /dev/null @@ -1,374 +0,0 @@ -#!/usr/bin/env python3 -### -# ============LICENSE_START======================================================= -# Simulator -# ================================================================================ -# Copyright (C) 2019 Nokia. All rights reserved. -# ================================================================================ -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# ============LICENSE_END========================================================= -### -import argparse -import http.client -import json -import logging -import ntpath -from typing import Dict - -SEND_PERIODIC_EVENT_ENDPOINT = "/simulator/start" -SEND_ONE_TIME_EVENT_ENDPOINT = "/simulator/event" -CONFIG_ENDPOINT = "/simulator/config" -LIST_TEMPLATES_ENDPOINT = "/template/list" -GET_TEMPLATE_BY_NAME_ENDPOINT = "/template/get" -UPLOAD_TEMPLATE_NOFORCE = "/template/upload" -UPLOAD_TEMPLATE_FORCE = "/template/upload?override=true" -FILTER_TEMPLATES_ENDPOINT = "/template/search" - -logging.basicConfig() - - -class Messages(object): - OVERRIDE_VALID_ONLY_WITH_UPLOAD = "--override is valid only with --upload parameter" - - -class SimulatorParams(object): - def __init__(self, repeats: int = 1, interval: int = 1, ves_server_url: str = None) -> None: - self.repeats_count = repeats - self.repeats_interval = interval - self.ves_server_url = ves_server_url - - def to_json(self) -> Dict: - to_return = {"repeatCount": self.repeats_count, - "repeatInterval": self.repeats_interval} - if self.ves_server_url: - to_return["vesServerUrl"] = self.ves_server_url - return to_return - - def __repr__(self) -> str: - return str(self.to_json()) - - -class PersistedEventRequest(object): - def __init__(self, simulator_params: SimulatorParams, template: str, patch: Dict = None) -> None: - self.params = simulator_params - self.template = template - self.patch = patch or {} - - def to_json(self) -> Dict: - return {"simulatorParams": self.params, "templateName": self.template, - "patch": self.patch} - - def __repr__(self) -> str: - return str(self.to_json()) - - -class FullEventRequest(object): - def __init__(self, event_body: Dict, ves_server_url: str = None) -> None: - self.event_body = event_body - self.ves_server_url = ves_server_url or "" - - def to_json(self) -> Dict: - return {"vesServerUrl": self.ves_server_url, "event": self.event_body} - - def __repr__(self) -> str: - return str(self.to_json()) - - -class TemplateUploadRequest(object): - def __init__(self, template_name: str, template_body: Dict) -> None: - self.template_name = template_name - self.template_body = template_body - - def to_json(self) -> Dict: - return {"name": self.template_name, "template": self.template_body} - - def __repr__(self) -> str: - return str(self.to_json()) - - -class SimulatorClient(object): - def __init__(self, ip: str, port: int = 5000, verbose: bool = False) -> None: - self._ip = ip - self._port = port - self.logger = logging.getLogger() - self.logger.setLevel(logging.DEBUG if verbose else logging.INFO) - - def send_event(self, request: PersistedEventRequest) -> None: - connection = http.client.HTTPConnection(self._ip, self._port) - self.logger.info("Attempting to send event") - self.logger.debug("Simulator address: ip %s, port %s, endpoint %s", self._ip, self._port, SEND_PERIODIC_EVENT_ENDPOINT) - self.logger.debug("REQUEST %s", request) - - connection.request("POST", SEND_PERIODIC_EVENT_ENDPOINT, body=json.dumps(request, cls=RequestSerializer), - headers={"Content-Type": "application/json"}) - - response = connection.getresponse() - - self._log_response(response) - connection.close() - - def send_one_time_event(self, request: FullEventRequest) -> None: - connection = http.client.HTTPConnection(self._ip, self._port) - self.logger.info("Attempting to send one time event") - self.logger.debug("Simulator address: ip %s, port %s, endpoint %s", self._ip, self._port, SEND_ONE_TIME_EVENT_ENDPOINT) - self.logger.debug("REQUEST %s", request.to_json()) - - connection.request("POST", SEND_ONE_TIME_EVENT_ENDPOINT, body=json.dumps(request.to_json()), - headers={"Content-Type": "application/json"}) - - response = connection.getresponse() - - self._log_response(response) - connection.close() - - def get_configuration(self) -> None: - connection = http.client.HTTPConnection(self._ip, self._port) - self.logger.info("Attempting to retrieve Simulator configuration") - self.logger.debug("Simulator address: ip %s, port %s, endpoint %s", self._ip, self._port, CONFIG_ENDPOINT) - connection.request("GET", CONFIG_ENDPOINT) - response = connection.getresponse() - - self._log_response(response) - connection.close() - - def edit_configuration(self, ves_server_url: str) -> None: - connection = http.client.HTTPConnection(self._ip, self._port) - self.logger.info("Attempting to update Simulator configuration") - self.logger.debug("Simulator address: ip %s, port %s, endpoint %s", self._ip, self._port, CONFIG_ENDPOINT) - request = {"vesServerUrl": ves_server_url} - self.logger.debug("REQUEST %s", request) - connection.request("PUT", CONFIG_ENDPOINT, body=json.dumps(request), - headers={"Content-Type": "application/json"}) - - response = connection.getresponse() - - self._log_response(response) - connection.close() - - def _log_response(self, response: http.client.HTTPResponse): - self.logger.info("Response status: %s ", response.status) - self.logger.info(response.read().decode()) - self.logger.debug(response.headers) - - def list_templates(self): - connection = http.client.HTTPConnection(self._ip, self._port) - self.logger.info("Attempting to retrieve all templates") - self.logger.debug("Simulator address: ip %s, port %s, endpoint %s", self._ip, self._port, LIST_TEMPLATES_ENDPOINT) - connection.request("GET", LIST_TEMPLATES_ENDPOINT) - response = connection.getresponse() - - self._log_response(response) - connection.close() - - def get_template_by_name(self, name): - connection = http.client.HTTPConnection(self._ip, self._port) - endpoint = GET_TEMPLATE_BY_NAME_ENDPOINT + "/" + name - self.logger.info("Attempting to retrieve template by name: '%s'", name) - self.logger.debug("Simulator address: ip %s, port %s, endpoint %s", self._ip, self._port, endpoint) - connection.request("GET", endpoint) - response = connection.getresponse() - - self._log_response(response) - connection.close() - - def upload_template(self, template_request, force): - connection = http.client.HTTPConnection(self._ip, self._port) - endpoint = UPLOAD_TEMPLATE_FORCE if force else UPLOAD_TEMPLATE_NOFORCE - self.logger.info("Attempting to upload template: '%s'", template_request) - self.logger.debug("Simulator address: ip %s, port %s, endpoint %s", self._ip, self._port, endpoint) - connection.request("POST", endpoint, - body=json.dumps(template_request.to_json()), - headers={"Content-Type": "application/json"}) - response = connection.getresponse() - - self._log_response(response) - connection.close() - - def search_for_templates(self, filter_criteria: str): - connection = http.client.HTTPConnection(self._ip, self._port) - self.logger.debug("Simulator address: ip %s, port %s, endpoint %s", self._ip, self._port, FILTER_TEMPLATES_ENDPOINT) - filter_request = {"searchExpr": json.loads(filter_criteria)} - self.logger.debug("Filter criteria: %s", str(filter_criteria)) - connection.request("POST", FILTER_TEMPLATES_ENDPOINT, - body=json.dumps(filter_request), - headers={"Content-Type": "application/json"}) - response = connection.getresponse() - - self._log_response(response) - connection.close() - - -class RequestSerializer(json.JSONEncoder): - def default(self, o): - return o.to_json() if (isinstance(o, SimulatorParams) or isinstance(o, PersistedEventRequest)) else o - - - -def create_argument_parser(): - parser = argparse.ArgumentParser(description="PNF Simulator Command Line Interface. ") - subparsers = parser.add_subparsers(title="Available actions") - send_parser = subparsers.add_parser("send", - description="Method which allows user to trigger simulator to start sending " - "events. Available options: [template, event]") - - send_subparsers = send_parser.add_subparsers() - one_time_send_event_parser = send_subparsers.add_parser("event", description="Option for direct, one-time event sending to VES. This option does not require having corresponging template.") - __configure_one_time_send_parser(one_time_send_event_parser) - persisted_send_event_parser = send_subparsers.add_parser("template") - __configure_persisted_send_parser(persisted_send_event_parser) - - configure_parser = subparsers.add_parser("configure", description="Method which allows user to set new default " - "value for VES Endpoint") - __configure_config_parser(configure_parser) - - get_config_parser = subparsers.add_parser("get-config", - description="Method which allows user to view simulator configuration") - __configure_get_config_parser(get_config_parser) - - template_config_parser = subparsers.add_parser("template", description="Template management operations") - __configure_template_parser(template_config_parser) - - template_filter_parser = subparsers.add_parser("filter", description="Method for searching through templates to find those satisfying given criteria") - __configure_template_filter_parser(template_filter_parser) - - return parser - - -def _perform_send_action(args): - if (not args.interval and args.repeats) or (args.interval and not args.repeats): - raise Exception("Either both repeats and interval must be present or missing") - - client = SimulatorClient(args.address, verbose=args.verbose) - client.send_event(_create_scheduled_event_request(args)) - - -def _perform_one_time_send_action(args): - client = SimulatorClient(args.address, verbose=args.verbose) - client.send_one_time_event(_create_one_time_event_request(args.filepath, args.ves_server_url)) - - -def get_configuration(args): - client = SimulatorClient(args.address, verbose=args.verbose) - client.get_configuration() - - -def edit_configuration(args): - client = SimulatorClient(args.address, verbose=args.verbose) - client.edit_configuration(args.ves_server_url) - - -def perform_template_action(args): - client = SimulatorClient(args.address, verbose=args.verbose) - if args.list: - client.list_templates() - elif args.get_content: - client.get_template_by_name(args.get_content) - elif args.upload: - client.upload_template(_create_upload_template_request(args.upload), args.override) - elif args.force: - raise Exception(Messages.OVERRIDE_VALID_ONLY_WITH_UPLOAD) - - -def list_all_templates(args): - client = SimulatorClient(args.address, verbose=args.verbose) - client.list_templates() - - -def filter_templates(args): - client = SimulatorClient(args.address, verbose=args.verbose) - client.search_for_templates(args.criteria) - - -def _create_upload_template_request(template_filename): - with open(template_filename) as json_template: - template_body = json.load(json_template) - return TemplateUploadRequest(path_leaf(template_filename), template_body) - - -def _create_scheduled_event_request(args): - simulator_params = SimulatorParams(args.repeats, args.interval, args.ves_server_url) - return PersistedEventRequest(simulator_params, args.name, json.loads(args.patch) if args.patch else {}) - - -def _create_one_time_event_request(event_filename, ves_server_url): - with open(event_filename) as json_event: - event_body = json.load(json_event) - return FullEventRequest(event_body, ves_server_url) - - -def __configure_persisted_send_parser(send_parser): - send_parser.add_argument("--address", required=True, help="IP address of simulator") - send_parser.add_argument("--name", required=True, help="Name of template file which should be used as a base for event") - send_parser.add_argument("--patch", help="Json which should be merged into template to override parameters") - send_parser.add_argument("--repeats", help="Number of events to be send", type=int) - send_parser.add_argument("--interval", help="Interval between two consecutive events (in seconds)", type=int) - send_parser.add_argument("--ves_server_url", - help="Well-formed URL which will override current VES endpoint stored in simulator's DB") - send_parser.add_argument("--verbose", action='store_true', help="Displays additional logs") - send_parser.set_defaults(func=_perform_send_action) - - -def __configure_one_time_send_parser(send_parser): - send_parser.add_argument("--address", required=True, help="IP address of simulator") - send_parser.add_argument("--filepath", required=True, help="Name of file with complete event for direct sending.") - send_parser.add_argument("--ves_server_url", - help="Well-formed URL which will override current VES endpoint stored in simulator's DB") - send_parser.add_argument("--verbose", action='store_true', help="Displays additional logs") - send_parser.set_defaults(func=_perform_one_time_send_action) - - -def __configure_config_parser(config_parser): - config_parser.add_argument("--address", required=True, help="IP address of simulator") - config_parser.add_argument("--ves-server-url", required=True, - help="Well-formed URL which should be set as a default VES Server URL in simulator") - config_parser.add_argument("--verbose", action='store_true', help="Displays additional logs") - config_parser.set_defaults(func=edit_configuration) - - -def __configure_get_config_parser(get_config_parser): - get_config_parser.add_argument("--address", required=True, help="IP address of simulator") - get_config_parser.add_argument("--verbose", action='store_true', help="Displays additional logs") - get_config_parser.set_defaults(func=get_configuration) - - -def __configure_template_parser(template_config_parser): - group = template_config_parser.add_mutually_exclusive_group(required=True) - group.add_argument("--list", action='store_true', help="List all templates") - group.add_argument("--get-content", help="Gets the template by name") - group.add_argument("--upload", help="Uploads the template given in parameter file.") - - template_config_parser.add_argument("--override", action='store_true', help="Overwrites the template in case it exists.") - template_config_parser.add_argument("--address", required=True, help="IP address of simulator") - template_config_parser.add_argument("--verbose", action='store_true', help="Displays additional logs") - template_config_parser.set_defaults(func=perform_template_action) - - -def __configure_template_filter_parser(template_filter_parser): - template_filter_parser.add_argument("--criteria", required=True, help="Json string with key-value search criteria") - template_filter_parser.add_argument("--address", required=True, help="IP address of simulator") - template_filter_parser.add_argument("--verbose", action='store_true', help="Displays additional logs") - template_filter_parser.set_defaults(func=filter_templates) - - -def path_leaf(path): - head, tail = ntpath.split(path) - return tail or ntpath.basename(head) - - -if __name__ == "__main__": - argument_parser = create_argument_parser() - result = argument_parser.parse_args() - if hasattr(result, 'func'): - result.func(result) - else: - argument_parser.parse_args(['-h']) diff --git a/test/mocks/pnfsimulator/simulator-cli/requirements.txt b/test/mocks/pnfsimulator/simulator-cli/requirements.txt deleted file mode 100644 index 4f962defb..000000000 --- a/test/mocks/pnfsimulator/simulator-cli/requirements.txt +++ /dev/null @@ -1,23 +0,0 @@ -### -# ============LICENSE_START======================================================= -# Simulator -# ================================================================================ -# Copyright (C) 2019 Nokia. All rights reserved. -# ================================================================================ -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# ============LICENSE_END========================================================= -### -requests==2.20.1 -websockets==7.0 -asynctest -mock diff --git a/test/mocks/pnfsimulator/simulator-cli/setup.py b/test/mocks/pnfsimulator/simulator-cli/setup.py deleted file mode 100644 index 26578a047..000000000 --- a/test/mocks/pnfsimulator/simulator-cli/setup.py +++ /dev/null @@ -1,34 +0,0 @@ -### -# ============LICENSE_START======================================================= -# Simulator -# ================================================================================ -# Copyright (C) 2019 Nokia. All rights reserved. -# ================================================================================ -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# ============LICENSE_END========================================================= -### - -import setuptools - -setuptools.setup( - name="pnf_simulator_cli", - version="5.0.0", - description="Command line interface which allows to communicate with PNF SIMULATOR", - packages=setuptools.find_packages(), - data_files=['cli/data/logging.ini'], - classifiers=["Programming Language :: Python :: 3"], - install_requires=[ - 'requests==2.20.1', - 'websockets==7.0' - ] -) diff --git a/test/mocks/pnfsimulator/simulator-cli/tests/__init__.py b/test/mocks/pnfsimulator/simulator-cli/tests/__init__.py deleted file mode 100644 index aa8b4f995..000000000 --- a/test/mocks/pnfsimulator/simulator-cli/tests/__init__.py +++ /dev/null @@ -1,19 +0,0 @@ -### -# ============LICENSE_START======================================================= -# Simulator -# ================================================================================ -# Copyright (C) 2019 Nokia. All rights reserved. -# ================================================================================ -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# ============LICENSE_END========================================================= -### diff --git a/test/mocks/pnfsimulator/simulator-cli/tests/resources/notification.json b/test/mocks/pnfsimulator/simulator-cli/tests/resources/notification.json deleted file mode 100644 index ca9641ec0..000000000 --- a/test/mocks/pnfsimulator/simulator-cli/tests/resources/notification.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "commonEventHeader": { - "domain": "notification", - "eventName": "#RandomString(20)", - "version": "4.0.1" - }, - "notificationFields": { - "arrayOfNamedHashMap": [ - { - "name": "A20161221.1031-1041.bin.gz", - "hashMap": { - "fileformatType": "org.3GPP.32.435#measCollec" - } - } - ] - } -} diff --git a/test/mocks/pnfsimulator/simulator-cli/tests/test_netconf_simulator.py b/test/mocks/pnfsimulator/simulator-cli/tests/test_netconf_simulator.py deleted file mode 100644 index 2b78a1bec..000000000 --- a/test/mocks/pnfsimulator/simulator-cli/tests/test_netconf_simulator.py +++ /dev/null @@ -1,165 +0,0 @@ -### -# ============LICENSE_START======================================================= -# Simulator -# ================================================================================ -# Copyright (C) 2019 Nokia. All rights reserved. -# ================================================================================ -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# ============LICENSE_END========================================================= -### -import logging -import unittest -import os -from mock import patch - -from cli.netconf_simulator import create_argument_parser, NetconfSimulatorClient - - -class TestArgumentParser(unittest.TestCase): - - def test_should_properly_parse_edit_config_with_all_params(self): - parser = create_argument_parser() - args = parser.parse_args( - ['edit-config', '--address', '127.0.0.1', '--config', 'sample_path', - "--verbose"] - ) - - self.assertEqual(args.address, '127.0.0.1') - self.assertEqual(args.config, 'sample_path') - self.assertTrue(args.verbose) - - def test_should_properly_parse_load_yang_model(self): - parser = create_argument_parser() - - args = parser.parse_args( - ['load-model', '--address', '127.0.0.1', '--module-name', - 'sample_name', '--yang-model', 'sample_model', '--config', - 'sample_config', - "--verbose"] - ) - - self.assertEqual(args.address, '127.0.0.1') - self.assertEqual(args.config, 'sample_config') - self.assertEqual(args.yang_model, 'sample_model') - self.assertEqual(args.module_name, 'sample_name') - self.assertTrue(args.verbose) - - def test_should_properly_parse_delete_yang_model(self): - parser = create_argument_parser() - - args = parser.parse_args( - ['delete-model', '--address', '127.0.0.1', '--model-name', - 'sample_name', "--verbose"] - ) - - self.assertEqual(args.address, '127.0.0.1') - self.assertEqual(args.model_name, 'sample_name') - self.assertTrue(args.verbose) - - def test_should_properly_parse_get_config(self): - parser = create_argument_parser() - args = parser.parse_args( - ['get-config', '--address', '127.0.0.1', '--verbose'] - ) - - self.assertEqual(args.address, '127.0.0.1') - self.assertTrue(args.verbose) - - -class TestNetconfSimulatorClient(unittest.TestCase): - - @classmethod - def setUpClass(cls): - with open("example", "w+") as f: - f.write("sampleContent") - - @classmethod - def tearDownClass(cls): - os.remove("example") - - @patch('cli.netconf_simulator.requests') - @patch('cli.netconf_simulator.NetconfSimulatorClient._configure_logger') - def test_should_properly_get_config(self, logger, requests): - client = NetconfSimulatorClient('localhost') - client.logger = logging.getLogger() - - client.get_config() - - requests.get.assert_called_with('http://localhost:8080/netconf/get') - - @patch('cli.netconf_simulator.requests') - @patch('cli.netconf_simulator.NetconfSimulatorClient._configure_logger') - def test_should_properly_get_config_for_given_module(self, logger, requests): - client = NetconfSimulatorClient('localhost') - client.logger = logging.getLogger() - - client.get_config("module", "container") - - requests.get.assert_called_with('http://localhost:8080/netconf/get/module/container') - - @patch('cli.netconf_simulator.NetconfSimulatorClient._configure_logger') - def test_should_raise_exception_when_module_is_present_and_container_is_absent(self, logger): - client = NetconfSimulatorClient('localhost') - client.logger = logging.getLogger() - - with self.assertRaises(AttributeError) as context: # pylint: disable=W0612 - client.get_config(module_name="test") - - @patch('cli.netconf_simulator.NetconfSimulatorClient._configure_logger') - def test_should_raise_exception_when_module_is_absent_and_container_is_present(self, logger): - client = NetconfSimulatorClient('localhost') - client.logger = logging.getLogger() - - with self.assertRaises(AttributeError) as context: # pylint: disable=W0612 - client.get_config(container="test") - - @patch('cli.netconf_simulator.requests') - @patch('cli.netconf_simulator.NetconfSimulatorClient._configure_logger') - def test_should_properly_load_yang_model(self, logger, requests): - client = NetconfSimulatorClient('localhost') - client.logger = logging.getLogger() - - client.load_yang_model('sample_module_name', 'example', 'example') - - requests.post.assert_called() - - @patch('cli.netconf_simulator.requests') - @patch('cli.netconf_simulator.NetconfSimulatorClient._configure_logger') - def test_should_properly_delete_yang_model(self, logger, requests): - client = NetconfSimulatorClient('localhost') - client.logger = logging.getLogger() - - client.delete_yang_model('sample_model_name') - - requests.delete.assert_called() - - @patch('cli.netconf_simulator.requests') - @patch('cli.netconf_simulator.NetconfSimulatorClient._configure_logger') - def test_should_properly_edit_config(self, logger, requests): - client = NetconfSimulatorClient('localhost') - client.logger = logging.getLogger() - - client.edit_config('example') - - requests.post.assert_called() - - @patch('cli.netconf_simulator.requests') - @patch('cli.netconf_simulator.NetconfSimulatorClient._configure_logger') - def test_should_properly_run_less_like_mode(self, logger, requests): - client = NetconfSimulatorClient('localhost') - client.logger = logging.getLogger() - - client.less_like_func(100) - - requests.get.assert_called_with( - params={"offset": 100}, url="http://localhost:8080/store/less") diff --git a/test/mocks/pnfsimulator/simulator-cli/tests/test_pnf_simulator.py b/test/mocks/pnfsimulator/simulator-cli/tests/test_pnf_simulator.py deleted file mode 100644 index 50f220038..000000000 --- a/test/mocks/pnfsimulator/simulator-cli/tests/test_pnf_simulator.py +++ /dev/null @@ -1,270 +0,0 @@ -### -# ============LICENSE_START======================================================= -# Simulator -# ================================================================================ -# Copyright (C) 2019 Nokia. All rights reserved. -# ================================================================================ -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# ============LICENSE_END========================================================= -### -import json -import os -import unittest -from http.client import HTTPResponse, HTTPConnection -from unittest import mock -from unittest.mock import patch, Mock - -from cli.pnf_simulator import SimulatorClient, FullEventRequest, Messages -from cli.pnf_simulator import create_argument_parser, SimulatorParams, PersistedEventRequest - - -class TestArgumentParser(unittest.TestCase): - - def test_should_properly_parse_send_template_action_with_all_params(self): - parser = create_argument_parser() - - result = parser.parse_args( - ['send', 'template', '--address', '127.0.0.1', "--name", 'sample_template', '--patch', '"{}"', '--repeats', '2', - "--interval", '5', '--verbose', '--ves_server_url', 'sample_url']) - - self.assertEqual(result.address, '127.0.0.1') - self.assertEqual(result.name, "sample_template") - self.assertEqual(result.patch, "\"{}\"") - self.assertEqual(result.repeats, 2) - self.assertEqual(result.interval, 5) - self.assertEqual(result.ves_server_url, 'sample_url') - self.assertTrue(result.verbose) - - def test_should_properly_parse_send_event_action_with_all_params(self): - parser = create_argument_parser() - - result = parser.parse_args( - ['send', 'event', '--address', '127.0.0.1', "--filepath", 'sample_filepath.json', '--verbose', '--ves_server_url', 'sample_url']) - - self.assertEqual(result.address, '127.0.0.1') - self.assertEqual(result.filepath, "sample_filepath.json") - self.assertEqual(result.ves_server_url, 'sample_url') - self.assertTrue(result.verbose) - - def test_should_properly_parse_configure_action_with_all_params(self): - parser = create_argument_parser() - result = parser.parse_args( - ['configure', '--address', '127.0.0.1', "--verbose", '--ves-server-url', 'sample_url'] - ) - - self.assertEqual(result.address, '127.0.0.1') - self.assertTrue(result.verbose) - self.assertEqual(result.ves_server_url, 'sample_url') - - def test_should_properly_parse_get_config_action_with_all_params(self): - parser = create_argument_parser() - result = parser.parse_args( - ['get-config', '--address', '127.0.0.1', '--verbose'] - ) - - self.assertEqual(result.address, '127.0.0.1') - self.assertTrue(result.verbose) - - def test_should_not_parse_arguments_when_mandatory_params_are_missing_for_template(self): - parser = create_argument_parser() - - with self.assertRaises(SystemExit) as context: - parser.parse_args(['send', 'template']) - self.assertTrue('the following arguments are required: --address, --name' in context.exception) - - def test_should_not_parse_arguments_when_mandatory_params_are_missing_for_event(self): - parser = create_argument_parser() - - with self.assertRaises(SystemExit) as context: - parser.parse_args(['send', 'event']) - self.assertTrue('the following arguments are required: --address, --filepath' in context.exception) - - def test_should_not_parse_arguments_when_mandatory_template_params_are_missing(self): - parser = create_argument_parser() - - with self.assertRaises(SystemExit) as context: - parser.parse_args(['template']) - self.assertTrue('one of the arguments --list --get-content is required' in context.exception) - - def test_should_not_parse_template_action_with_all_params(self): - parser = create_argument_parser() - with self.assertRaises(SystemExit) as context: - parser.parse_args( - ['template', '--address', '127.0.0.1', "--list", '--get-content', 'sample'] - ) - self.assertTrue('argument --get-content: not allowed with argument --list' in context.exception) - - def test_should_properly_parse_template_action_with_list_param(self): - parser = create_argument_parser() - result = parser.parse_args( - ['template', '--address', '127.0.0.1', "--list"] - ) - - self.assertTrue(result.list) - self.assertEqual(result.address, '127.0.0.1') - self.assertFalse(result.verbose) - - def test_should_properly_parse_template_action_with_get_content_param(self): - parser = create_argument_parser() - result = parser.parse_args( - ['template', '--address', '127.0.0.1', "--get-content", "sample"] - ) - - self.assertTrue(result.get_content) - self.assertEqual(result.address, '127.0.0.1') - self.assertFalse(result.verbose) - - def test_should_not_parse_template_action_with_empty_get_content_param(self): - parser = create_argument_parser() - with self.assertRaises(SystemExit) as context: - parser.parse_args( - ['template', '--address', '127.0.0.1', "--list", '--get-content'] - ) - self.assertTrue('argument --get-content: expected one argument' in context.exception) - - def test_should_not_parse_template_action_when_only_override_is_given(self): - parser = create_argument_parser() - with self.assertRaises(SystemExit) as context: - parser.parse_args( - ['template', '--address', '127.0.0.1', "--override"] - ) - self.assertTrue(Messages.OVERRIDE_VALID_ONLY_WITH_UPLOAD in context.exception) - - def test_should_parse_template_action_with_upload(self): - parser = create_argument_parser() - result = parser.parse_args( - ['template', '--address', '127.0.0.1', "--upload", "resources/notification.json"] - ) - - self.assertFalse(result.override) - self.assertEqual(result.upload, 'resources/notification.json') - - def test_should_parse_template_action_with_upload_and_override(self): - parser = create_argument_parser() - result = parser.parse_args( - ['template', '--address', '127.0.0.1', "--upload", "resources/notification.json", "--override"] - ) - - self.assertTrue(result.override) - self.assertEqual(result.upload, 'resources/notification.json') - - - def test_should_properly_parse_filter_templates_action_with_all_params(self): - parser = create_argument_parser() - - result = parser.parse_args( - ['filter', '--address', '127.0.0.1', '--criteria', '"{}"', '--verbose']) - - self.assertEqual(result.address, '127.0.0.1') - self.assertEqual(result.criteria, "\"{}\"") - self.assertTrue(result.verbose) - -class TestSimulatorClient(unittest.TestCase): - - @patch('cli.pnf_simulator.http.client.HTTPConnection') - def test_should_properly_send_event(self, http_connection): - request = self._create_request() - mocked_connection = Mock(HTTPConnection) - http_connection.return_value = mocked_connection - mocked_response = Mock(HTTPResponse) - mocked_connection.getresponse.return_value = mocked_response - mocked_response.status = '200' - mocked_response.headers = {} - - client = SimulatorClient('localhost') - client.send_event(request) - - mocked_connection.close.assert_called_with() - mocked_connection.request.assert_called_with('POST', '/simulator/start', - body=mock.ANY, - headers={'Content-Type': 'application/json'}) - - @patch('cli.pnf_simulator.http.client.HTTPConnection') - def test_should_properly_send_one_time_event(self, http_connection): - event_abs_filepath = os.path.join(os.path.dirname(os.path.abspath(__file__)),"resources/notification.json") - request = self._create_one_time_request(event_abs_filepath) - mocked_connection = Mock(HTTPConnection) - http_connection.return_value = mocked_connection - mocked_response = Mock(HTTPResponse) - mocked_connection.getresponse.return_value = mocked_response - mocked_response.status = '202' - mocked_response.headers = {} - - client = SimulatorClient('localhost') - client.send_one_time_event(request) - - mocked_connection.close.assert_called_with() - mocked_connection.request.assert_called_with('POST', '/simulator/event', - body=mock.ANY, - headers={'Content-Type': 'application/json'}) - - @patch('cli.pnf_simulator.http.client.HTTPConnection') - def test_should_properly_update_configuration(self, http_connection): - mocked_connection = Mock(HTTPConnection) - http_connection.return_value = mocked_connection - mocked_response = Mock(HTTPResponse) - mocked_connection.getresponse.return_value = mocked_response - mocked_response.status = '200' - mocked_response.headers = {} - - client = SimulatorClient('localhost') - client.edit_configuration("sample_url") - - mocked_connection.close.assert_called_with() - mocked_connection.request.assert_called_with('PUT', '/simulator/config', - body=json.dumps({"vesServerUrl": "sample_url"}), - headers={'Content-Type': 'application/json'}) - - @patch('cli.pnf_simulator.http.client.HTTPConnection') - def test_should_properly_retrieve_configuration(self, http_connection): - mocked_connection = Mock(HTTPConnection) - http_connection.return_value = mocked_connection - mocked_response = Mock(HTTPResponse) - mocked_connection.getresponse.return_value = mocked_response - mocked_response.status = '200' - mocked_response.headers = {} - - client = SimulatorClient('localhost') - client.get_configuration() - mocked_connection.close.assert_called_with() - mocked_connection.request.assert_called_with('GET', '/simulator/config') - - - @patch('cli.pnf_simulator.http.client.HTTPConnection') - def test_should_properly_trigger_filter_template_action(self, http_connection): - request = '{"sampleSearchString": "sampleSearchValue"}' - mocked_connection = Mock(HTTPConnection) - http_connection.return_value = mocked_connection - mocked_response = Mock(HTTPResponse) - mocked_connection.getresponse.return_value = mocked_response - mocked_response.status = '200' - mocked_response.headers = {} - - client = SimulatorClient('localhost') - client.search_for_templates(request) - - mocked_connection.close.assert_called_with() - mocked_connection.request.assert_called_with('POST', '/template/search', - body=json.dumps({"searchExpr": {"sampleSearchString": "sampleSearchValue"}}), - headers={'Content-Type': 'application/json'}) - - - @classmethod - def _create_request(cls): - return PersistedEventRequest(SimulatorParams(), 'sample_template') - - @classmethod - def _create_one_time_request(cls, event_filepath): - with open(event_filepath) as json_event: - event_body = json.load(json_event) - return FullEventRequest(event_body, 'sample_url') diff --git a/test/mocks/pnfsimulator/simulator-cli/tests/test_tailf_client.py b/test/mocks/pnfsimulator/simulator-cli/tests/test_tailf_client.py deleted file mode 100644 index da8bd624e..000000000 --- a/test/mocks/pnfsimulator/simulator-cli/tests/test_tailf_client.py +++ /dev/null @@ -1,47 +0,0 @@ -### -# ============LICENSE_START======================================================= -# Simulator -# ================================================================================ -# Copyright (C) 2019 Nokia. All rights reserved. -# ================================================================================ -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# ============LICENSE_END========================================================= -### -import unittest -import asynctest - -from cli.client.tailf_client import TailfClient - - -class TestTailfClient(unittest.TestCase): - - def __init__(self, methodName='runTest'): - super().__init__(methodName) - self._client = TailfClient('ws://localhost:9999') - - @asynctest.mock.patch('cli.client.tailf_client.websockets') - def test_should_connect_to_server_and_receive_message(self, websockets_mock): - recv_mock = asynctest.CoroutineMock(side_effect=self.interrupt) - aenter_mock = asynctest.MagicMock() - connection_mock = asynctest.MagicMock() - websockets_mock.connect.return_value = aenter_mock - aenter_mock.__aenter__.return_value = connection_mock - connection_mock.recv = recv_mock - - self._client.tailf_messages() - - recv_mock.assert_awaited_once() - - def interrupt(self): - self._client._is_running = False - return 'test' -- cgit 1.2.3-korg