diff --git a/README.md b/README.md index d065a3552a..ec997c59bb 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,5 @@ [![Build Status](https://travis-ci.org/networktocode/ntc-templates.svg?branch=master)](https://travis-ci.org/networktocode/ntc-templates) +[![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/ambv/black) NTC TEMPLATES ============= diff --git a/lib/ntc_templates/parse.py b/lib/ntc_templates/parse.py index b504b649f7..77dc89db6d 100644 --- a/lib/ntc_templates/parse.py +++ b/lib/ntc_templates/parse.py @@ -32,17 +32,16 @@ def _clitable_to_dict(cli_table): def parse_output(platform=None, command=None, data=None): """Return the structured data based on the output from a network device.""" template_dir = _get_template_dir() - cli_table = clitable.CliTable('index', template_dir) + cli_table = clitable.CliTable("index", template_dir) - attrs = dict( - Command=command, - Platform=platform - ) + attrs = {"Command": command, "Platform": platform} try: cli_table.ParseCmd(data, attrs) structured_data = _clitable_to_dict(cli_table) except clitable.CliTableError as e: - raise Exception('Unable to parse command "%s" on platform %s - %s' % (command, platform, str(e))) + raise Exception( + 'Unable to parse command "{0}" on platform {1} - {2}'.format(command, platform, str(e)) + ) # Invalid or Missing template # module.fail_json(msg='parsing error', error=str(e)) # rather than fail, fallback to return raw text diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000000..48a67fddef --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,19 @@ +[tool.black] +line-length = 100 +target-version = ['py36'] +include = '\.pyi?$' +exclude = ''' +/( + \.eggs + | \.git + | \.hg + | \.mypy_cache + | \.tox + | \.venv + | _build + | buck-out + | build + | dist +)/ +| test-templates\.py +''' \ No newline at end of file diff --git a/setup.py b/setup.py index d5c84e9ea3..cb5727ad73 100644 --- a/setup.py +++ b/setup.py @@ -2,43 +2,40 @@ from codecs import open from setuptools import setup, find_packages -version = '' -with open('lib/ntc_templates/__init__.py', 'r') as fd: - version = re.search(r'^__version__\s*=\s*[\'"]([^\'"]*)[\'"]', - fd.read(), re.MULTILINE).group(1) +with open("lib/ntc_templates/__init__.py", "r") as fd: + version = re.search(r'^__version__\s*=\s*[\'"]([^\'"]*)[\'"]', fd.read(), re.MULTILINE).group(1) if not version: - raise RuntimeError('Cannot find version information') + raise RuntimeError("Cannot find version information") -with open('README.md', 'r', 'utf-8') as f: +with open("README.md", "r", "utf-8") as f: readme = f.read() -with open('CHANGELOG', 'r', 'utf-8') as f: +with open("CHANGELOG", "r", "utf-8") as f: history = f.read() -long_description = readme + '\n\n' + history +long_description = readme + "\n\n" + history config = { - 'name': 'ntc_templates', - 'package_dir': {'': 'lib'}, - 'packages': find_packages('lib'), - 'version': version, - 'package_data': {'ntc_templates': ['templates/*']}, - 'description': 'Package to return structured data from the output of network devices.', - 'long_description': long_description, - 'long_description_content_type': 'text/markdown', - 'author': 'network.toCode()', - 'author_email': 'info@networktocode.com', - 'url': 'https://github.com/networktocode/ntc-templates', - 'install_requires': [ - 'textfsm', - 'terminal', + "name": "ntc_templates", + "package_dir": {"": "lib"}, + "packages": find_packages("lib"), + "version": version, + "package_data": {"ntc_templates": ["templates/*"]}, + "description": "Package to return structured data from the output of network devices.", + "long_description": long_description, + "long_description_content_type": "text/markdown", + "author": "network.toCode()", + "author_email": "info@networktocode.com", + "url": "https://github.com/networktocode/ntc-templates", + "install_requires": ["textfsm", "terminal"], + "classifiers": [ + "Development Status :: 4 - Beta", + "Intended Audience :: Developers", + "Intended Audience :: System Administrators", + "Programming Language :: Python :: 3", ], - 'classifiers': ['Development Status :: 4 - Beta', - 'Intended Audience :: Developers', - 'Intended Audience :: System Administrators', - 'Programming Language :: Python :: 3'], - 'zip_safe': False + "zip_safe": False, } setup(**config) diff --git a/tests/__init__.py b/tests/__init__.py index 875ee2be5d..5a62df4906 100644 --- a/tests/__init__.py +++ b/tests/__init__.py @@ -9,9 +9,9 @@ def load_index_data(): """Load data from index file.""" index_data = [] - with open('%s%sindex' % (_get_template_dir(), os.sep)) as indexfs: + with open("{0}{1}index".format(_get_template_dir(), os.sep)) as indexfs: data = csv.reader(indexfs) for row in data: - if len(row) > 2 and row[0] != 'Template': + if len(row) > 2 and row[0] != "Template": index_data.append(row) return index_data diff --git a/tests/test_index_order.py b/tests/test_index_order.py index 40c300ad3d..cab9d9e04d 100644 --- a/tests/test_index_order.py +++ b/tests/test_index_order.py @@ -17,53 +17,89 @@ def check_order(current_os, prior_os, cmd_len, prior_len, os_choices, used_os, c add_os_check.append(current_os) if used_os != sorted(used_os): - msg = "OS's are not in alpabetical order, current order: '{}'".format(used_os) + msg = "OS's are not in alpabetical order, current order: '{0}'".format(used_os) return False, msg elif add_os_check != sorted(add_os_check): - msg = "OS's are not in alpabetical order, current order: '{}'".format(add_os_check) + msg = "OS's are not in alpabetical order, current order: '{0}'".format(add_os_check) return False, msg if current_os not in os_choices: - msg = "'{}' is not one of the valid options '{}'".format(current_os, used_os) + msg = "'{0}' is not one of the valid options '{1}'".format(current_os, used_os) return False, msg if not prior_os and prior_len == 0: # Starting Point - return True, '' + return True, "" elif current_os == prior_os and cmd_len == prior_len and cmd == min(prior_cmd, cmd): msg = ( "OS is the same and command same length, " - "please set {} before {} to be in alphabetical order".format(cmd, prior_cmd) + "please set {0} before {1} to be in alphabetical order".format(cmd, prior_cmd) ) return False, msg elif current_os == prior_os and cmd_len <= prior_len: # OS is the same as previous, and cmd_len is smaller or equal to prior so good - return True, '' + return True, "" elif current_os != prior_os and current_os not in used_os: # prior OS has changed, do not need to check for length yet - return True, '' + return True, "" elif current_os == prior_os and cmd_len > prior_len: - msg = "Current Command len '{}' larger then previous '{}', for command '{}'".format( + msg = "Current Command len '{0}' larger then previous '{1}', for command '{2}'".format( cmd_len, prior_len, cmd ) return False, msg elif current_os != prior_os and current_os in used_os: - msg = "'{}' OS was already used in list on command '{}'".format(current_os, cmd) + msg = "'{0}' OS was already used in list on command '{1}'".format(current_os, cmd) return False, msg else: msg = "Failed for unknown reason" return False, msg + def test_index_ordering(): os_choices = [ - 'a10', 'alcatel_aos', 'alcatel_sros', 'arista_eos', 'aruba_os', 'avaya_ers', 'avaya_vsp', - 'brocade_fastiron', 'brocade_netiron', 'brocade_nos', 'brocade_vdx', 'brocade_vyos', - 'checkpoint_gaia', 'ciena_6x', 'cisco_asa', 'cisco_ios', 'cisco_nxos', 'cisco_s300', - 'cisco_wlc', 'cisco_xe', 'cisco_xr', 'dell_force10', 'enterasys', 'extreme', 'f5_ltm', - 'fortinet_fortios', 'hp_comware', 'hp_procurve', 'huawei_vrp', 'juniper', 'juniper_junos', - 'juniper_screenos', 'linux', 'ovs_linux', 'paloalto_panos', 'quanta_mesh','ruckus_fastiron', - 'ubiquiti_edgeswitch', 'vmware_nsxv', 'vyatta_vyos', 'vyos', 'watchguard_firebox', + "a10", + "alcatel_aos", + "alcatel_sros", + "arista_eos", + "aruba_os", + "avaya_ers", + "avaya_vsp", + "brocade_fastiron", + "brocade_netiron", + "brocade_nos", + "brocade_vdx", + "brocade_vyos", + "checkpoint_gaia", + "ciena_6x", + "cisco_asa", + "cisco_ios", + "cisco_nxos", + "cisco_s300", + "cisco_wlc", + "cisco_xe", + "cisco_xr", + "dell_force10", + "enterasys", + "extreme", + "f5_ltm", + "fortinet_fortios", + "hp_comware", + "hp_procurve", + "huawei_vrp", + "juniper", + "juniper_junos", + "juniper_screenos", + "linux", + "ovs_linux", + "paloalto_panos", + "quanta_mesh", + "ruckus_fastiron", + "ubiquiti_edgeswitch", + "vmware_nsxv", + "vyatta_vyos", + "vyos", + "watchguard_firebox", ] prior_os = "" @@ -74,16 +110,16 @@ def test_index_ordering(): index = load_index_data() for row in index: template = row[0].strip() - os = '_'.join(template.split('_')[:2]) - cmd = '_'.join(template.split('_')[2:]) + os = "_".join(template.split("_")[:2]) + cmd = "_".join(template.split("_")[2:]) cmd_len = len(cmd) check_val, check_msg = check_order( os, prior_os, cmd_len, prior_len, os_choices, used_os, cmd, prior_cmd ) if not check_val: - #assertFalse(check_val, msg=check_msg) - print("Error on line: {}".format(row)) - print("Error Message: {}".format(check_msg)) + # assertFalse(check_val, msg=check_msg) + print("Error on line: {0}".format(row)) + print("Error Message: {0}".format(check_msg)) assert check_val if os not in used_os: used_os.append(os) diff --git a/tests/test_structured_data_against_parsed_reference_files.py b/tests/test_structured_data_against_parsed_reference_files.py index f4708c2101..a241b0c219 100644 --- a/tests/test_structured_data_against_parsed_reference_files.py +++ b/tests/test_structured_data_against_parsed_reference_files.py @@ -11,15 +11,15 @@ def return_test_files(): """Return a list of all the *.raw files to run tests against.""" - platform_dirs = glob.glob('tests/*') - platforms = (glob.glob('%s/*' % platform) for platform in platform_dirs) + platform_dirs = glob.glob("tests/*") + platforms = (glob.glob("{0}/*".format(platform)) for platform in platform_dirs) template_dirs = (item for sublist in platforms for item in sublist) - test_commands = (glob.glob('%s/*.raw' % template_dir) for template_dir in template_dirs) + test_commands = (glob.glob("{0}/*.raw".format(template_dir)) for template_dir in template_dirs) return (item for sublist in test_commands for item in sublist) -@pytest.fixture(scope='function', params=return_test_files()) +@pytest.fixture(scope="function", params=return_test_files()) def load_template_test(request): """Return each *.raw file to run tests on.""" return request.param @@ -27,17 +27,17 @@ def load_template_test(request): def raw_template_test(raw_file): """Return structured data along with reference data.""" - parsed_file = '%s.parsed' % raw_file[:-4] - parts = raw_file.split('/') + parsed_file = "{0}.parsed".format(raw_file[:-4]) + parts = raw_file.split("/") platform = parts[1] - command = ' '.join(parts[2].split('_')) - with open(raw_file, 'r') as data: + command = " ".join(parts[2].split("_")) + with open(raw_file, "r") as data: rawoutput = data.read() structured = parse_output(platform=platform, command=command, data=rawoutput) - with open(parsed_file, 'r') as data: + with open(parsed_file, "r") as data: parsed_data = yaml.safe_load(data.read()) - return structured, parsed_data['parsed_sample'] + return structured, parsed_data["parsed_sample"] def test_raw_data_against_mock(load_template_test): diff --git a/tests/test_testcases_exists.py b/tests/test_testcases_exists.py index e4201c54d3..ae661ca75f 100644 --- a/tests/test_testcases_exists.py +++ b/tests/test_testcases_exists.py @@ -7,10 +7,10 @@ KNOWN_MISSING_TESTS = { - 'cisco_ios_show_vlan', - 'cisco_nxos_show_interface_brief', - 'cisco_nxos_show_ip_ospf_neighbor_vrf', - 'cisco_xr_show_controllers', + "cisco_ios_show_vlan", + "cisco_nxos_show_interface_brief", + "cisco_nxos_show_ip_ospf_neighbor_vrf", + "cisco_xr_show_controllers", } @@ -25,7 +25,7 @@ def test_verify_parsed_and_reference_data_exists(): index = sorted(load_index_data()) for row in index: template = row[0].strip() - template_short = template.split('.template')[0] + template_short = template.split(".template")[0] platform = row[2].strip() for directory in os.listdir("tests"): if re.match(platform, directory): @@ -34,6 +34,6 @@ def test_verify_parsed_and_reference_data_exists(): cut = len(platform_directory) + 1 command = template_short[cut:] if template_short not in KNOWN_MISSING_TESTS: - cases = 'tests/%s/%s/*.raw' % (platform_directory, command) + cases = "tests/{0}/{1}/*.raw".format(platform_directory, command) test_list = glob.glob(cases) - assert len(test_list) != 0, 'Could not find tests for %s' % template + assert len(test_list) != 0, "Could not find tests for {0}".format(template) diff --git a/tox.ini b/tox.ini index d1fe915d53..c739aaffb5 100644 --- a/tox.ini +++ b/tox.ini @@ -5,10 +5,13 @@ envlist = py36 deps = pytest PyYAML + black whitelist_externals = git rm -commands = pytest -vv +commands = + pytest -vv + black ./ --diff --check