diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index 413e1fbda..11e229a72 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -135,7 +135,7 @@ jobs: architecture: x64 - name: Install Python build dependencies - run: python -m pip install setuptools wheel tox cffi + run: python -m pip install setuptools wheel cffi - name: Install Linux build dependencies run: | @@ -526,7 +526,7 @@ jobs: run: dnf install -y util-linux-core python3-devel python3-pip - name: Install Python build dependencies - run: python3 -m pip install setuptools wheel tox cffi + run: python3 -m pip install setuptools wheel cffi # https://cristianadam.eu/20200113/speeding-up-c-plus-plus-github-actions-using-ccache/ # https://docs.github.com/en/actions/using-workflows/workflow-commands-for-github-actions#environment-files @@ -740,9 +740,6 @@ jobs: cmake --build qpid-proton sudo cmake --install qpid-proton - - name: Install python-checker test dependencies - run: python3 -m pip install tox - - uses: actions/checkout@v3 - name: Create Build and Install directories @@ -835,7 +832,7 @@ jobs: dnf debuginfo-install -y python3 - name: Install Python build dependencies - run: python3 -m pip install setuptools wheel tox cffi + run: python3 -m pip install setuptools wheel cffi - name: Install Python runtime/test dependencies run: python3 -m pip install -r ${{github.workspace}}/skupper-router/requirements-dev.txt diff --git a/.gitignore b/.gitignore index 81c8ec0f2..f2f58bca5 100644 --- a/.gitignore +++ b/.gitignore @@ -19,7 +19,6 @@ tests/policy-1/policy-*.json .metadata .settings .history/ -.tox .vscode diff --git a/python/skupper_router_internal/management/agent.py b/python/skupper_router_internal/management/agent.py index e2b63731e..5fe807774 100644 --- a/python/skupper_router_internal/management/agent.py +++ b/python/skupper_router_internal/management/agent.py @@ -277,7 +277,7 @@ def __init__(self, agent, entity_type, attributes=None, validate=True): # This is for backward compatibility, we will remove this after a few releases. if attributes and attributes.get("enable") and "trace" in attributes.get("enable"): enabled = attributes.get("enable") - attributes["enable"] = enabled.replace("trace", "debug" ) + attributes["enable"] = enabled.replace("trace", "debug") # Special defaults for DEFAULT module. if attributes.get("module") == "DEFAULT": defaults = dict(enable="info+", includeTimestamp=True, includeSource=False, outputFile="stderr") diff --git a/requirements-dev.txt b/requirements-dev.txt index ad281f397..ebc38be8c 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -26,7 +26,6 @@ pre-commit setuptools virtualenv wheel -tox pytest pytest-cov @@ -41,3 +40,10 @@ quart selectors websockets>=9.1 psutil + +# For running the python-checker tests +hacking==4.1.0 +# hacking 4.1.0 requires flake8<3.9.0 and >=3.8.0 +flake8==3.8.4 +pylint==2.13.9 +mypy==0.950 diff --git a/scripts/auto_mesh.py b/scripts/auto_mesh.py index 6df721293..f43091ff3 100644 --- a/scripts/auto_mesh.py +++ b/scripts/auto_mesh.py @@ -89,7 +89,7 @@ def extract_ips(response, name): if js.get("items"): for pod in js['items']: # Filter non router pods - if('application' in pod['metadata']['labels'] and + if ('application' in pod['metadata']['labels'] and pod['metadata']['labels']['application'] == name): if 'podIP' not in pod['status']: print("Waiting for IP address...") diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 516261bc2..ae17088be 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -192,50 +192,17 @@ endforeach() # Place .coveragerc where coverage.py will find it when running system_tests configure_file(${CMAKE_CURRENT_SOURCE_DIR}/.coveragerc ${CMAKE_CURRENT_BINARY_DIR}/.coveragerc COPYONLY) -# Location of tox.ini determines the testroot directory for Pytest -configure_file(${CMAKE_CURRENT_SOURCE_DIR}/tox.ini.in ${CMAKE_CURRENT_BINARY_DIR}/tox.ini) -# Use tox to run the flake8 python linter tool on all the python -# sources. Highly recommended if you're hacking the python code. -# Unfortunately this can only be done for versions of tox >= 1.9.0 -# since that version allows us to skip the install step (we have -# no modules thus no setup.py) -# -find_program(TOX_EXE "tox") -if (TOX_EXE) - # the "skip_install" feature showed up in version 1.9.0 tox, - # which is used by our tox.ini script: - set(TOX_MIN_VERSION 1.9.0) - execute_process(COMMAND "${TOX_EXE}" "--version" - RESULT_VARIABLE TOX_STATUS - OUTPUT_VARIABLE TOX_VERSION) - if (TOX_STATUS EQUAL 0) - string(STRIP "${TOX_VERSION}" TOX_VERSION) - string(REGEX MATCH "^[0-9]+[.][0-9]+[.][0-9]+" TOX_VERSION "${TOX_VERSION}") - if (TOX_VERSION STRLESS TOX_MIN_VERSION) - message( STATUS "tox version ${TOX_VERSION} < required version ${TOX_MIN_VERSION} - skipping python-checker") - else (TOX_VERSION STRLESS TOX_MIN_VERSION) - add_test (NAME python-checker - COMMAND ${TOX_EXE} - WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) - # Once we move to tox >= v1.7.2 we can remove the next - # line. See tox.ini file for details - set_tests_properties(python-checker - PROPERTIES - PASS_REGULAR_EXPRESSION "commands succeeded" - FAIL_REGULAR_EXPRESSION "commands failed") - endif (TOX_VERSION STRLESS TOX_MIN_VERSION) - else (TOX_STATUS EQUAL 0) - message(STATUS "Cannot determine tox version - skipping python-checker") - endif (TOX_STATUS EQUAL 0) - -else (TOX_EXE) - message(STATUS "Could NOT find 'tox' tool - unable to validate python code") -endif () - - - +# Location of setup.cfg determines the testroot directory for Pytest +configure_file(${CMAKE_CURRENT_SOURCE_DIR}/setup.cfg.in ${CMAKE_CURRENT_BINARY_DIR}/setup.cfg) +#This python-checker shell script uses three tools - mypy, flake8 and pylint to validate python code +configure_file(${CMAKE_CURRENT_SOURCE_DIR}/python-checker.sh.in ${CMAKE_CURRENT_BINARY_DIR}/python-checker.sh) +find_program (BASH_PROGRAM bash) +add_test (NAME python-checker + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} + COMMAND ${BASH_PROGRAM} ${CMAKE_CURRENT_BINARY_DIR}/python-checker.sh) + # Additional files to install for running system tests. # NOTE: Don't install run.py. A system test of a dispatch installation should pick everything # up from standard install locations. diff --git a/tests/system_test.py b/tests/system_test.py index f51172da4..576546696 100755 --- a/tests/system_test.py +++ b/tests/system_test.py @@ -1054,7 +1054,7 @@ def is_edges_connected(edges=num_edges, meshes=num_meshes): for conn in out.results: if role == conn[role_index] and conn[dir_index] == "in": edges_num += 1 - if meshes != None: + if meshes is not None: meshid = conn[meshid_index] if meshid not in mesh_list: mesh_list.append(meshid) diff --git a/tests/system_tests_http2.py b/tests/system_tests_http2.py index 4536487b9..11d3e33bb 100644 --- a/tests/system_tests_http2.py +++ b/tests/system_tests_http2.py @@ -20,7 +20,6 @@ import os import sys import socket -import time import unittest from subprocess import PIPE from time import sleep @@ -28,7 +27,7 @@ import system_test from http1_tests import wait_http_listeners_up, HttpAdaptorListenerConnectTestBase, wait_tcp_listeners_up from system_test import TestCase, Qdrouterd, QdManager, Process, retry_assertion -from system_test import curl_available, nginx_available, TIMEOUT, skip_test_in_ci, Http2Server +from system_test import curl_available, nginx_available, TIMEOUT, Http2Server from system_test import get_digest h2hyper_installed = True @@ -182,8 +181,8 @@ def test_post_request(self): # @unittest.skipIf(skip_test(), "Python 3.7 or greater, Quart 0.13.0 or greater and curl needed to run http2 tests") # @unittest.skipIf(skip_test_in_ci('QPID_SYSTEM_TEST_SKIP_HTTP2_LARGE_IMAGE_UPLOAD_TEST'), skip_reason) # def test_post_upload_large_image_jpg(self): - # curl -X POST -H "Content-Type: multipart/form-data" -F "data=@/home/gmurthy/opensource/test.jpg" - # http://127.0.0.1:9000/upload --http2-prior-knowledge +# #curl -X POST -H "Content-Type: multipart/form-data" -F "data=@/home/gmurthy/opensource/test.jpg" +# http://127.0.0.1:9000/upload --http2-prior-knowledge # address = self.get_address() + "/upload" # _, out, _ = self.run_curl(address, args=self.get_all_curl_args(['-X', 'POST', '-H', # 'Content-Type: multipart/form-data', diff --git a/tests/system_tests_resend_released.py b/tests/system_tests_resend_released.py index 7b3f91332..64a4f9e1b 100644 --- a/tests/system_tests_resend_released.py +++ b/tests/system_tests_resend_released.py @@ -18,7 +18,6 @@ # from proton import Message, symbol, Data -from proton._events import Event from proton.handlers import MessagingHandler from proton.reactor import Container from proton import Delivery @@ -394,14 +393,14 @@ def on_link_opened(self, event): self.release_receivers.append(event.container.create_receiver(conn, self.addr)) for conn in self.accept_conns: self.accept_receivers.append(event.container.create_receiver(conn, self.addr)) - elif self.sender == None and event.receiver != None: + elif self.sender is None and event.receiver is not None: self.n_receivers += 1 if self.n_receivers == len(self.release_receivers) + len(self.accept_receivers): if self.wait_local > 0 or self.wait_remote > 0: self.query_stats() else: self.setup_sender(event) - elif self.sender != None and event.receiver != None: + elif self.sender is not None and event.receiver is not None: self.stream_receivers.append(event.receiver) def on_sendable(self, event): @@ -419,8 +418,8 @@ def find_stats(self, response): for record in response.results: if record.name == 'M' + self.addr: return (record.subscriberCount, record.remoteCount) - return (0,0) - + return (0, 0) + def setup_sender(self, event): self.sender = event.container.create_sender(self.sender_conn, self.addr) self.sender.target.capabilities.put_array(False, Data.SYMBOL) @@ -484,7 +483,7 @@ def on_released(self, event): self.fail("delivery released when there were available acceptors") elif len(self.release_receivers) != self.n_released: self.fail("delivery released after %d releases, had %d releasors" % (self.n_released, len(self.release_receivers))) - elif self.expected_releases != None and self.n_released != self.expected_releases: + elif self.expected_releases is not None and self.n_released != self.expected_releases: self.fail("delivery released: expected %d released, but got %d" % (self.expected_releases, self.n_released)) else: self.fail(None) @@ -494,7 +493,7 @@ def on_accepted(self, event): return if self.n_accepted != 1: self.fail("delivery accepted after %d acceptances. Expected 1" % self.n_accepted) - elif self.expected_releases != None and self.n_released != self.expected_releases: + elif self.expected_releases is not None and self.n_released != self.expected_releases: self.fail("delivery accepted: expected %d released, but got %d" % (self.expected_releases, self.n_released)) else: self.fail(None) diff --git a/tests/system_tests_streaming_deliveries.py b/tests/system_tests_streaming_deliveries.py index 96d34eb96..f229ed346 100644 --- a/tests/system_tests_streaming_deliveries.py +++ b/tests/system_tests_streaming_deliveries.py @@ -18,7 +18,6 @@ # from proton import Message, symbol -from proton._events import Event from proton.handlers import MessagingHandler from proton.reactor import Container @@ -185,7 +184,7 @@ def find_stats(self, response): for record in response.results: if record.name == 'M' + self.addr: return (record.subscriberCount, record.remoteCount) - return (0,0) + return (0, 0) def query_stats(self): if self.proxy: diff --git a/tests/system_tests_tcp_adaptor.py b/tests/system_tests_tcp_adaptor.py index 3a8beb35e..1738c2759 100644 --- a/tests/system_tests_tcp_adaptor.py +++ b/tests/system_tests_tcp_adaptor.py @@ -1344,6 +1344,7 @@ class TcpAdaptor(TcpAdaptorBase, CommonTcpTests): def setUpClass(cls): super(TcpAdaptor, cls).setUpClass(test_ssl=False) + class TcpAdaptorLite(TcpAdaptorBase, CommonTcpTests): @classmethod def setUpClass(cls): diff --git a/tests/system_tests_two_routers.py b/tests/system_tests_two_routers.py index 13f77742f..d3985debe 100644 --- a/tests/system_tests_two_routers.py +++ b/tests/system_tests_two_routers.py @@ -1617,9 +1617,6 @@ def router(name, extra): 'port': inter_router_port})]) cls.RouterB = cls.routers[-1] cls.RouterB.listener = cls.RouterB.addresses[0] - - - cls.RouterA.wait_router_connected('RouterB') cls.RouterB.wait_router_connected('RouterA') diff --git a/tests/tox.ini.in b/tests/tox.ini.in deleted file mode 100644 index f80a97058..000000000 --- a/tests/tox.ini.in +++ /dev/null @@ -1,288 +0,0 @@ -# -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you 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. -# - -[skrouter] -py_sources = - ${CMAKE_SOURCE_DIR}/python/skupper_router - ${CMAKE_SOURCE_DIR}/python/skupper_router_internal - ${CMAKE_SOURCE_DIR}/docs - ${CMAKE_SOURCE_DIR}/tests - ${CMAKE_SOURCE_DIR}/tools - ${CMAKE_SOURCE_DIR}/scripts - ${CMAKE_BINARY_DIR}/python/skupper_router_site.py - -[tox] -envlist = py36,py37,py38,py39,py310 -skipsdist = True -minversion = ${TOX_VERSION} -skip_missing_interpreters = True -skip_install = True - -[testenv] -commands = - flake8 --count --show-source {[skrouter]py_sources} ${CMAKE_SOURCE_DIR}/tools/skstat ${CMAKE_SOURCE_DIR}/tools/skmanage - - pylint --jobs 2 --rcfile ${CMAKE_BINARY_DIR}/tests/tox.ini --ignore friendship_pb2.py,friendship_pb2_grpc.py {[skrouter]py_sources} ${CMAKE_SOURCE_DIR}/tools/skstat ${CMAKE_SOURCE_DIR}/tools/skmanage - - mypy --config-file ${CMAKE_BINARY_DIR}/tests/tox.ini {[skrouter]py_sources} - -deps = - hacking==4.1.0 - # hacking 4.1.0 requires flake8<3.9.0 and >=3.8.0 - flake8==3.8.4 - pylint==2.13.9 - mypy==0.950 - -[testenv:py36] -basepython = python3.6 - -[testenv:py37] -basepython = python3.7 - -[testenv:py38] -basepython = python3.8 - -[testenv:py39] -basepython = python3.9 - -[testenv:py310] -basepython = python3.10 - -[flake8] -# TODO(DISPATCH-1974) decrease the limit -max-line-length = 464 - -# TODO(DISPATCH-1974) re-enable all these warnings -ignore = - # H238: old style class declaration, use new style (inherit from `object`) - H238, - # E704 multiple statements on one line (def) - E704, - # E241 multiple spaces after ',' - E241, - # E203 whitespace before ':' - E203, - # H101: Use TODO(NAME) - H101, - # H202: assertRaises Exception too broad - H202, - # H401: docstring should not start with a space - H401, - # H403: multi line docstrings should end on a new line - H403, - # H404: multi line docstring should start without a leading new line - H404, - # H405: multi line docstring summary not separated with an empty line - H405, - # E265 block comment should start with '# ' - E265, - # E266 too many leading '#' for block comment - E266, - # E221 multiple spaces before operator - E221, - # E222 multiple spaces after operator - E222, - # do not use bare 'except' - E722, - # H201: no 'except:' at least use 'except Exception:' - H201, - # H104: File contains nothing but comments - H104, - # H301: one import per line - H301, - # H306: imports not in alphabetical order - H306, - # F811 redefinition of unused 'Timeout' from line 29 - F811, - # E712 comparison to True should be 'if cond is not True:' or 'if not cond:' - # E712 comparison to False should be 'if cond is False:' or 'if not cond:' - E712, - # E402 module level import not at top of file - E402, - # may be undefined, or defined from star imports: datetime - F405, - # ambiguous variable name 'l' - E741, - # local variable 'int_nodes' is assigned to but never used - F841, - # TODO(DISPATCH-1974) decide which of these two warnings we want disabled - # _transport.py:908:21: W503 line break before binary operator - # _transport.py:907:56: W504 line break after binary operator - W503, - W504, - -# TODO(DISPATCH-1974) generated by gRPC tooling -exclude = friendship_pb2.py, friendship_pb2_grpc.py - -[pytest] -# https://github.com/pytest-dev/pytest/blob/main/src/_pytest/junitxml.py -# do not filter test file names -python_files = *.py -# dump all DEBUG+ python logs on test failure -# exclusions are configured in tests/__init__.py -log_level = DEBUG -# always show important logs -log_cli = true -log_cli_level = WARNING - -# pylint -[MESSAGE_CONTROL] -disable = - access-member-before-definition, - arguments-differ, - attribute-defined-outside-init, - bad-super-call, - bare-except, - broad-except, - consider-iterating-dictionary, - consider-using-dict-comprehension, - consider-using-dict-items, - consider-using-enumerate, - consider-using-f-string, - consider-using-with, - deprecated-module, - duplicate-code, - empty-docstring, - fatal, - fixme, - function-redefined, - global-statement, - import-error, - import-outside-toplevel, - inconsistent-return-statements, - invalid-name, - line-too-long, - method-hidden, - missing-docstring, - missing-function-docstring, - missing-module-docstring, - multiple-statements, - no-else-break, - no-else-raise, - no-else-return, - no-member, - no-name-in-module, - no-self-use, - parse-error, - protected-access, - raise-missing-from, - redefined-builtin, - redefined-outer-name, - redundant-unittest-assert, - singleton-comparison, - super-init-not-called, - super-with-arguments, - too-few-public-methods, - too-many-arguments, - too-many-branches, - too-many-instance-attributes, - too-many-lines, - too-many-locals, - too-many-nested-blocks, - too-many-public-methods, - too-many-return-statements, - too-many-statements, - unnecessary-pass, - unspecified-encoding, - unsubscriptable-object, - unused-argument, - unused-variable, - use-dict-literal, - use-list-literal, - useless-else-on-loop, - useless-super-delegation, - wrong-import-position, - -[mypy] -warn_redundant_casts = True -warn_unused_ignores = False - -# mypy cannot handle overridden attributes -# https://github.com/python/mypy/issues/7505 -allow_untyped_globals = True - -# https://mypy.readthedocs.io/en/stable/error_codes.html#displaying-error-codes -show_error_codes = True - -# tests is a source root, prevent importing as e.g. tests.system_test -namespace_packages = True -explicit_package_bases = True -mypy_path = ${CMAKE_SOURCE_DIR}/tests - -# this would print lots and lots of errors -# check_untyped_defs = True - -# ignore missing stub files for dependencies - -#[mypy-_ssl] -#ignore_missing_imports = True - -[mypy-proton.*] -ignore_missing_imports = True - -[mypy-cproton] -ignore_missing_imports = True - -[mypy-qpidtoollibs] -ignore_missing_imports = True - -[mypy-qpid_messaging] -ignore_missing_imports = True - -[mypy-pyprof2calltree] -ignore_missing_imports = True - -[mypy-quart.*] -ignore_missing_imports = True - -[mypy-hypercorn.*] -ignore_missing_imports = True - -[mypy-werkzeug.*] -ignore_missing_imports = True - -[mypy-selectors] -ignore_missing_imports = True - -[mypy-h2.*] -ignore_missing_imports = True - -[mypy-google.protobuf] -ignore_missing_imports = True - -[mypy-grpc] -ignore_missing_imports = True - -[mypy-grpcio] -ignore_missing_imports = True - -[mypy-protobuf] -ignore_missing_imports = True - -[mypy-websockets] -ignore_missing_imports = True - -[mypy-pytest] -ignore_missing_imports = True - -[mypy-pkg_resources] -ignore_missing_imports = True - -[mypy-psutil] -ignore_missing_imports = True