From c498cd09d9558f0a441d884cee22bc99901f7c50 Mon Sep 17 00:00:00 2001 From: Tim Rupp Date: Fri, 13 Apr 2018 21:48:00 -0700 Subject: [PATCH 01/10] Fixes pycodestyle checks (#1424) Issues: Fixes #1423 Problem: Code checks were being suppressed Analysis: This fixes the offending checks Tests: (cherry picked from commit 3f39b43ff440f3d5861d4ce252bb2a4c8f1c46c0) --- f5/bigip/resource.py | 22 ++--- .../tm/gtm/test/functional/test_server.py | 29 +++--- .../tm/gtm/test/functional/test_topology.py | 88 +++++++++++-------- f5/bigip/tm/net/test/functional/test_trunk.py | 7 +- f5/bigip/tm/sys/performance.py | 6 +- f5/bigip/tm/sys/test/functional/test_snmp.py | 35 +++----- f5/utils/iapp_parser.py | 20 ++--- 7 files changed, 101 insertions(+), 106 deletions(-) diff --git a/f5/bigip/resource.py b/f5/bigip/resource.py index 6bdd03f10..d90ba2665 100644 --- a/f5/bigip/resource.py +++ b/f5/bigip/resource.py @@ -288,10 +288,10 @@ def _check_generation(self): response = session.get(self._meta_data['uri']) current_gen = response.json().get('generation', None) if current_gen is not None and current_gen != self.generation: - error_message = ("The generation of the object on the BigIP " + - "(" + str(current_gen) + ")" + - " does not match the current object" + - "(" + str(self.generation) + ")") + error_message = ("The generation of the object on the BigIP " + + "(" + str(current_gen) + ")" + + " does not match the current object" + + "(" + str(self.generation) + ")") raise GenerationMismatch(error_message) def _handle_requests_params(self, kwargs): @@ -974,7 +974,7 @@ def _create(self, **kwargs): return result def create(self, **kwargs): - """Create the resource on the BIG-IP®. + r"""Create the resource on the BIG-IP®. Uses HTTP POST to the `collection` URI to create a resource associated with a new unique URI on the device. @@ -1041,7 +1041,7 @@ def _load(self, **kwargs): return self._produce_instance(response) def load(self, **kwargs): - """Load an already configured service into this instance. + r"""Load an already configured service into this instance. This method uses HTTP GET to obtain a resource from the BIG-IP®. @@ -1081,7 +1081,7 @@ def _delete(self, **kwargs): self.__dict__ = {'deleted': True} def delete(self, **kwargs): - """Delete the resource on the BIG-IP®. + r"""Delete the resource on the BIG-IP®. Uses HTTP DELETE to delete the resource on the BIG-IP®. @@ -1103,7 +1103,7 @@ def delete(self, **kwargs): # Need to implement correct teardown here. def exists(self, **kwargs): - """Check for the existence of the named object on the BIG-IP + r"""Check for the existence of the named object on the BIG-IP Sends an HTTP GET to the URI of the named object and if it fails with a :exc:~requests.HTTPError` exception it checks the exception for @@ -1252,7 +1252,7 @@ def _load(self, **kwargs): return self._produce_instance(response) def load(self, **kwargs): - """Load an already configured service into this instance. + r"""Load an already configured service into this instance. This method uses HTTP GET to obtain a resource from the BIG-IP®. @@ -1303,7 +1303,7 @@ def delete(self, **kwargs): # Need to implement correct teardown here. def exists(self, **kwargs): - """Check for the existence of the ASM object on the BIG-IP + r"""Check for the existence of the ASM object on the BIG-IP Sends an HTTP GET to the URI of the ASM object and if it fails with a :exc:~requests.HTTPError` exception it checks the exception for @@ -1504,7 +1504,7 @@ def delete(self, **kwargs): # Need to implement correct teardown here. def exists(self, **kwargs): - """Check for the existence of the Task object on the BIG-IP + r"""Check for the existence of the Task object on the BIG-IP Sends an HTTP GET to the URI of the ASM object and if it fails with a :exc:~requests.HTTPError` exception it checks the exception for diff --git a/f5/bigip/tm/gtm/test/functional/test_server.py b/f5/bigip/tm/gtm/test/functional/test_server.py index 0c8664993..f02c6de9d 100644 --- a/f5/bigip/tm/gtm/test/functional/test_server.py +++ b/f5/bigip/tm/gtm/test/functional/test_server.py @@ -176,9 +176,10 @@ def test_load_no_object(self, mgmt_root): name='fake_serv1') assert err.value.response.status_code == 404 - @pytest.mark.skipif(LooseVersion(pytest.config.getoption('--release')) == - '11.5.4', - reason='Needs > v11.5.4 TMOS to pass') + @pytest.mark.skipif( + LooseVersion(pytest.config.getoption('--release')) == '11.5.4', + reason='Needs > v11.5.4 TMOS to pass' + ) def test_load(self, request, mgmt_root): setup_basic_test(request, mgmt_root, 'fake_serv1', 'Common') s1 = mgmt_root.tm.gtm.servers.server.load(name='fake_serv1') @@ -192,9 +193,9 @@ def test_load(self, request, mgmt_root): assert s2.disabled is True @pytest.mark.skipif( - LooseVersion(pytest.config.getoption('--release')) >= LooseVersion( - '11.6.0'), - reason='This test is for 11.5.4 or less.') + LooseVersion(pytest.config.getoption('--release')) >= LooseVersion('11.6.0'), + reason='This test is for 11.5.4 or less.' + ) def test_load_11_5_4_and_less(self, request, mgmt_root): setup_basic_test(request, mgmt_root, 'fake_serv1', 'Common') s1 = mgmt_root.tm.gtm.servers.server.load(name='fake_serv1') @@ -237,8 +238,7 @@ def test_delete(self, request, mgmt_root): class TestServerCollection(object): def test_server_collection(self, request, mgmt_root): s1 = setup_basic_test(request, mgmt_root, 'fake_serv1', 'Common') - if LooseVersion(pytest.config.getoption('--release')) >= \ - LooseVersion('12.1.0'): + if LooseVersion(pytest.config.getoption('--release')) >= LooseVersion('12.1.0'): link = 'https://localhost/mgmt/tm/gtm/server/~Common~fake_serv1' else: link = 'https://localhost/mgmt/tm/gtm/server/fake_serv1' @@ -259,8 +259,7 @@ def test_create_req_arg(self, request, mgmt_root): s1 = setup_basic_test(request, mgmt_root, 'fake_serv1', 'Common') vs = s1.virtual_servers_s vs1 = vs.virtual_server.create(name='vs1', destination='5.5.5.5:80') - if LooseVersion(pytest.config.getoption('--release')) >= \ - LooseVersion('12.1.0'): + if LooseVersion(pytest.config.getoption('--release')) >= LooseVersion('12.1.0'): link = 'https://localhost/mgmt/tm/gtm/server/~Common~fake_serv1' \ '/virtual-servers/vs' else: @@ -347,9 +346,10 @@ def test_modify(self, request, mgmt_root): elif k == limit: assert vs1.__dict__[k] == 'enabled' - @pytest.mark.skipif(pytest.config.getoption('--release') == '11.6.0', - reason='Due to a bug in 11.6.0 Final this test ' - 'fails') + @pytest.mark.skipif( + pytest.config.getoption('--release') == '11.6.0', + reason='Due to a bug in 11.6.0 Final this test fails' + ) def test_delete(self, request, mgmt_root): vs1 = setup_vs_basic_test(request, mgmt_root, 'vs2', '5.5.5.5:80') vs1.delete() @@ -361,8 +361,7 @@ def test_delete(self, request, mgmt_root): def test_virtual_server_collection(self, request, mgmt_root): vs1 = setup_vs_basic_test(request, mgmt_root, 'vs1', '5.5.5.5:80') - if LooseVersion(pytest.config.getoption('--release')) >= \ - LooseVersion('12.1.0'): + if LooseVersion(pytest.config.getoption('--release')) >= LooseVersion('12.1.0'): link = 'https://localhost/mgmt/tm/gtm/server/~Common~fake_serv1' \ '/virtual-servers/vs' else: diff --git a/f5/bigip/tm/gtm/test/functional/test_topology.py b/f5/bigip/tm/gtm/test/functional/test_topology.py index 16f7dfa26..4a56e61bd 100644 --- a/f5/bigip/tm/gtm/test/functional/test_topology.py +++ b/f5/bigip/tm/gtm/test/functional/test_topology.py @@ -24,6 +24,8 @@ from pytest import symbols from requests.exceptions import HTTPError +RELEASE_LOOSE_VERSION = LooseVersion(pytest.config.getoption('--release')) + pytestmark = pytest.mark.skipif( symbols and hasattr(symbols, 'modules') @@ -64,10 +66,10 @@ def teardown(): return top1 -@pytest.mark.skipif(LooseVersion(pytest.config.getoption('--release')) < - '12.1.0' or - LooseVersion(pytest.config.getoption('--release')) == - '12.0.0', reason='Needs > v12.1.0 TMOS to pass') +@pytest.mark.skipif( + RELEASE_LOOSE_VERSION < '12.1.0' or RELEASE_LOOSE_VERSION == '12.0.0', + reason='Needs > v12.1.0 TMOS to pass' +) class TestCreate(object): def test_create_no_args(self, mgmt_root): with pytest.raises(MissingRequiredCreationParameter): @@ -105,10 +107,10 @@ def test_create_duplicate(self, request, mgmt_root): assert err.value.response.status_code == 409 -@pytest.mark.skipif(LooseVersion(pytest.config.getoption('--release')) >= - '12.1.0' or - LooseVersion(pytest.config.getoption('--release')) == - '12.0.0', reason='Needs < v12.1.0 TMOS to pass') +@pytest.mark.skipif( + RELEASE_LOOSE_VERSION >= '12.1.0' or RELEASE_LOOSE_VERSION == '12.0.0', + reason='Needs < v12.1.0 TMOS to pass' +) class TestCreate_pre_12_1_0(object): def test_create_no_args(self, mgmt_root): with pytest.raises(MissingRequiredCreationParameter): @@ -146,18 +148,20 @@ def test_create_duplicate(self, request, mgmt_root): assert err.value.response.status_code == 409 -@pytest.mark.skipif(LooseVersion(pytest.config.getoption('--release')) == - '12.0.0', reason='Resource disabled for TMOS 12.0.0') +@pytest.mark.skipif( + RELEASE_LOOSE_VERSION == '12.0.0', + reason='Resource disabled for TMOS 12.0.0' +) class TestRefresh(object): def test_refresh_raises(self, mgmt_root): with pytest.raises(UnsupportedOperation): mgmt_root.tm.gtm.topology_s.topology.refresh() -@pytest.mark.skipif(LooseVersion(pytest.config.getoption('--release')) < - '12.1.0' or - LooseVersion(pytest.config.getoption('--release')) == - '12.0.0', reason='Needs > v12.1.0 TMOS to pass') +@pytest.mark.skipif( + RELEASE_LOOSE_VERSION < '12.1.0' or RELEASE_LOOSE_VERSION == '12.0.0', + reason='Needs > v12.1.0 TMOS to pass' +) class TestLoad(object): def test_load_no_object(self, mgmt_root): with pytest.raises(HTTPError) as err: @@ -174,10 +178,10 @@ def test_load(self, request, mgmt_root): assert t1.selfLink == t2.selfLink -@pytest.mark.skipif(LooseVersion(pytest.config.getoption('--release')) >= - '12.1.0' or - LooseVersion(pytest.config.getoption('--release')) == - '12.0.0', reason='Needs < v12.1.0 TMOS to pass') +@pytest.mark.skipif( + RELEASE_LOOSE_VERSION >= '12.1.0' or RELEASE_LOOSE_VERSION == '12.0.0', + reason='Needs < v12.1.0 TMOS to pass' +) class TestLoad_pre_12_1_0(object): def test_load_no_object(self, mgmt_root): with pytest.raises(HTTPError) as err: @@ -194,24 +198,30 @@ def test_load(self, request, mgmt_root): assert t1.selfLink == t2.selfLink -@pytest.mark.skipif(LooseVersion(pytest.config.getoption('--release')) == - '12.0.0', reason='Resource disabled for TMOS 12.0.0') +@pytest.mark.skipif( + RELEASE_LOOSE_VERSION == '12.0.0', + reason='Resource disabled for TMOS 12.0.0' +) class TestUpdate(object): def test_update_raises(self, mgmt_root): with pytest.raises(UnsupportedOperation): mgmt_root.tm.gtm.topology_s.topology.update() -@pytest.mark.skipif(LooseVersion(pytest.config.getoption('--release')) == - '12.0.0', reason='Resource disabled for TMOS 12.0.0') +@pytest.mark.skipif( + RELEASE_LOOSE_VERSION == '12.0.0', + reason='Resource disabled for TMOS 12.0.0' +) class TestModify(object): def test_modify_raises(self, mgmt_root): with pytest.raises(UnsupportedOperation): mgmt_root.tm.gtm.topology_s.topology.modify() -@pytest.mark.skipif(LooseVersion(pytest.config.getoption('--release')) < - '12.1.0', reason='Needs > v12.1.0 TMOS to pass') +@pytest.mark.skipif( + RELEASE_LOOSE_VERSION < '12.1.0', + reason='Needs > v12.1.0 TMOS to pass' +) class TestDelete(object): def test_delete(self, request, mgmt_root): r1 = setup_basic_test(request, mgmt_root, NAME) @@ -221,10 +231,10 @@ def test_delete(self, request, mgmt_root): assert err.value.response.status_code == 404 -@pytest.mark.skipif(LooseVersion(pytest.config.getoption('--release')) >= - '12.1.0' or - LooseVersion(pytest.config.getoption('--release')) == - '12.0.0', reason='Needs < v12.1.0 TMOS to pass') +@pytest.mark.skipif( + RELEASE_LOOSE_VERSION >= '12.1.0' or RELEASE_LOOSE_VERSION == '12.0.0', + reason='Needs < v12.1.0 TMOS to pass' +) class TestDelete_pre_12_1_0(object): def test_delete(self, request, mgmt_root): r1 = setup_basic_test(request, mgmt_root, NAME_SPACES) @@ -234,10 +244,10 @@ def test_delete(self, request, mgmt_root): assert err.value.response.status_code == 404 -@pytest.mark.skipif(LooseVersion(pytest.config.getoption('--release')) < - '12.1.0' or - LooseVersion(pytest.config.getoption('--release')) == - '12.0.0', reason='Needs > v12.1.0 TMOS to pass') +@pytest.mark.skipif( + RELEASE_LOOSE_VERSION < '12.1.0' or RELEASE_LOOSE_VERSION == '12.0.0', + reason='Needs > v12.1.0 TMOS to pass' +) class TestTopologyCollection(object): def test_region_collection(self, request, mgmt_root): setup_create_test(request, mgmt_root, NAME) @@ -257,10 +267,10 @@ def test_region_collection(self, request, mgmt_root): assert isinstance(rc[0], Topology) -@pytest.mark.skipif(LooseVersion(pytest.config.getoption('--release')) >= - '12.1.0' or - LooseVersion(pytest.config.getoption('--release')) == - '12.0.0', reason='Needs < v12.1.0 TMOS to pass') +@pytest.mark.skipif( + RELEASE_LOOSE_VERSION >= '12.1.0' or RELEASE_LOOSE_VERSION == '12.0.0', + reason='Needs < v12.1.0 TMOS to pass' +) class TestTopologyCollection_pre_12_1_0(object): def test_region_collection(self, request, mgmt_root): setup_create_test(request, mgmt_root, NAME_SPACES) @@ -280,8 +290,10 @@ def test_region_collection(self, request, mgmt_root): assert isinstance(rc[0], Topology) -@pytest.mark.skipif(LooseVersion(pytest.config.getoption('--release')) != - '12.0.0', reason='Only TMOS 12.0.0 test') +@pytest.mark.skipif( + RELEASE_LOOSE_VERSION != '12.0.0', + reason='Only TMOS 12.0.0 test' +) class TestTopology_12_0_0(object): def test_topology_raises(self, request, mgmt_root): with pytest.raises(UnsupportedTmosVersion): diff --git a/f5/bigip/tm/net/test/functional/test_trunk.py b/f5/bigip/tm/net/test/functional/test_trunk.py index 36cc59332..c26610f6c 100644 --- a/f5/bigip/tm/net/test/functional/test_trunk.py +++ b/f5/bigip/tm/net/test/functional/test_trunk.py @@ -22,9 +22,10 @@ pytestmark = pytest.mark.skipif( - not symbols or - symbols and not hasattr(symbols, 'run_hardware_tests') or - symbols and hasattr(symbols, 'run_hardware_tests') and symbols.modules['run_hardware_tests'] is False, + not symbols + or symbols and not hasattr(symbols, 'run_hardware_tests') + or symbols and hasattr(symbols, 'run_hardware_tests') + and symbols.modules['run_hardware_tests'] is False, reason='This series of tests requires a hardware BIG-IP be specified.' ) diff --git a/f5/bigip/tm/sys/performance.py b/f5/bigip/tm/sys/performance.py index 9d1d21f9b..5899af160 100644 --- a/f5/bigip/tm/sys/performance.py +++ b/f5/bigip/tm/sys/performance.py @@ -44,8 +44,7 @@ def get_collection(self): :raises: :exc:`~f5.BIG-IP.resource.UnsupportedOperation` ''' raise UnsupportedOperation( - "The iControl REST URI mgmt/sys/performance/ does not respond " + - "GET requests." + "The iControl REST URI mgmt/sys/performance/ does not respond GET requests." ) @@ -62,5 +61,4 @@ def update(self, **kwargs): :raises: :exc:`~f5.BIG-IP.resource.UnsupportedOperation` ''' - raise UnsupportedOperation( - 'Stats do not support create, only load and refresh') + raise UnsupportedOperation('Stats do not support create, only load and refresh') diff --git a/f5/bigip/tm/sys/test/functional/test_snmp.py b/f5/bigip/tm/sys/test/functional/test_snmp.py index 26989b7c0..5ba5aca5f 100644 --- a/f5/bigip/tm/sys/test/functional/test_snmp.py +++ b/f5/bigip/tm/sys/test/functional/test_snmp.py @@ -412,8 +412,7 @@ def test_community_modify(self, request, mgmt_root, setup_device_snapshot): class TestUser(object): @pytest.mark.skipif( - LooseVersion(pytest.config.getoption('--release')) > - LooseVersion('12.0.0'), + LooseVersion(pytest.config.getoption('--release')) > LooseVersion('12.0.0'), reason='Skip this test if v12.1.0 or above is set.' ) def test_user_create_refresh_update_delete_load( @@ -465,8 +464,7 @@ def test_user_create_refresh_update_delete_load( assert user2.selfLink == user1.selfLink @pytest.mark.skipif( - LooseVersion(pytest.config.getoption('--release')) < - LooseVersion('12.1.0'), + LooseVersion(pytest.config.getoption('--release')) < LooseVersion('12.1.0'), reason='Skip if the version is NOT 12.1.0 or above' ) def test_user_create_refresh_delete_load_12_1_0( @@ -529,13 +527,10 @@ def test_user_modify(self, request, mgmt_root, setup_device_snapshot): class TestTrap(object): @pytest.mark.skipif( - LooseVersion(pytest.config.getoption('--release')) > - LooseVersion('12.0.0'), + LooseVersion(pytest.config.getoption('--release')) > LooseVersion('12.0.0'), reason='Skip this test if v12.1.0 or above is set.' ) - def test_trap_create_refresh_update_delete_load( - self, request, mgmt_root, setup_device_snapshot - ): + def test_trap_create_refresh_update_delete_load(self, request, mgmt_root, setup_device_snapshot): trap1, t1 = setup_trap_test( request=request, mgmt_root=mgmt_root, @@ -577,12 +572,10 @@ def test_trap_create_refresh_update_delete_load( assert trap2.selfLink == trap1.selfLink @pytest.mark.skipif( - LooseVersion(pytest.config.getoption('--release')) < - LooseVersion('12.1.0'), + LooseVersion(pytest.config.getoption('--release')) < LooseVersion('12.1.0'), reason='Skip if the version is NOT 12.1.0 or above' ) - def test_trap_create_refresh_delete_load_12_1_0( - self, request, mgmt_root, setup_device_snapshot): + def test_trap_create_refresh_delete_load_12_1_0(self, request, mgmt_root, setup_device_snapshot): trap1, t1 = setup_trap_test( request=request, mgmt_root=mgmt_root, @@ -618,9 +611,7 @@ def test_trap_create_refresh_delete_load_12_1_0( assert trap1.selfLink.startswith(link1) assert trap2.selfLink.startswith(link2) - def test_trap_create_bad_version( - self, request, mgmt_root, setup_device_snapshot - ): + def test_trap_create_bad_version(self, request, mgmt_root, setup_device_snapshot): badVals = ['ads', 12, '12', '#^$%&#%', '', -1, '-1'] for badVal in badVals: with pytest.raises(iControlUnexpectedHTTPError) as err: @@ -635,9 +626,7 @@ def test_trap_create_bad_version( ) assert 'expected one of the following' in str(err.value) - def test_trap_create_bad_port( - self, request, mgmt_root, setup_device_snapshot - ): + def test_trap_create_bad_port(self, request, mgmt_root, setup_device_snapshot): """Test digit service ports The port can be a valid digit between 0 and 65,535. This matches @@ -663,9 +652,7 @@ def test_trap_create_bad_port( ) assert 'invalid or ambiguous service' in str(err.value) - def test_trap_create_named_port( - self, request, mgmt_root, setup_device_snapshot - ): + def test_trap_create_named_port(self, request, mgmt_root, setup_device_snapshot): """Test named service ports The port can be a valid service name instead of a digit. This differs @@ -689,9 +676,7 @@ def test_trap_create_named_port( version=version ) - def test_trap_create_named_port_v3( - self, request, mgmt_root, setup_device_snapshot - ): + def test_trap_create_named_port_v3(self, request, mgmt_root, setup_device_snapshot): """Test named service ports The port can be a valid service name instead of a digit. This differs diff --git a/f5/utils/iapp_parser.py b/f5/utils/iapp_parser.py index 8b5abfc3f..031b4bf45 100644 --- a/f5/utils/iapp_parser.py +++ b/f5/utils/iapp_parser.py @@ -27,8 +27,8 @@ class IappParser(object): 'role-acl' ] - tcl_list_for_attr_re = '{(\s*(\w+)?\s*)+}' - tcl_list_for_section_re = '(\s*\w+\s*)+' + tcl_list_for_attr_re = r'{(\s*(\w+)?\s*)+}' + tcl_list_for_section_re = r'(\s*\w+\s*)+' section_map = { 'html-help': 'htmlHelp', 'role-acl': 'roleAcl' @@ -136,7 +136,7 @@ def _get_section_start_index(self, section): :raises: NonextantSectionException ''' - sec_start_re = '%s\s*\{' % section + sec_start_re = r'%s\s*\{' % section found = re.search(sec_start_re, self.template_str) if found: @@ -153,9 +153,9 @@ def _get_template_name(self): :raises: NonextantTemplateNameException ''' - start_pattern = "sys application template\s+" \ - "(\/[\w\.\-]+\/)?" \ - "(?P[\w\.\-]+)\s*\{" + start_pattern = r"sys application template\s+" \ + r"(\/[\w\.\-]+\/)?" \ + r"(?P[\w\.\-]+)\s*\{" template_start = re.search(start_pattern, self.template_str) if template_start: @@ -170,7 +170,7 @@ def _get_template_attr(self, attr): :returns: string of attribute value ''' - attr_re = '%s\s+.*' % attr + attr_re = r'{0}\s+.*'.format(attr) attr_found = re.search(attr_re, self.template_str) if attr_found: @@ -200,9 +200,9 @@ def _add_sections(self): def _add_cli_scripts(self): '''Add the found external sections to the templ_dict.''' - pattern = "cli script\s+" \ - "(\/[\w\.\-]+\/)?" \ - "(?P[\w\.\-]+)\s*\{" + pattern = r"cli script\s+" \ + r"(\/[\w\.\-]+\/)?" \ + r"(?P[\w\.\-]+)\s*\{" sections = re.finditer(pattern, self.template_str) for section in sections: From 90bfccbee82be477f133832641df76ebdae3078e Mon Sep 17 00:00:00 2001 From: Qin Zhao Date: Wed, 9 Dec 2020 06:29:19 +0000 Subject: [PATCH 02/10] Fix pycodestyle errors --- f5/bigip/mixins.py | 2 +- f5/bigip/test/unit/test_mixins.py | 8 ++++---- f5/bigip/tm/gtm/test/unit/test_pool.py | 2 +- f5/bigip/tm/ltm/test/functional/test_pool.py | 2 +- .../tm/ltm/test/functional/test_virtual_address.py | 4 ++-- f5/utils/testutils/registrytools.py | 14 +++++++------- 6 files changed, 16 insertions(+), 16 deletions(-) diff --git a/f5/bigip/mixins.py b/f5/bigip/mixins.py index 731f84fa0..aad8eabc0 100644 --- a/f5/bigip/mixins.py +++ b/f5/bigip/mixins.py @@ -369,7 +369,7 @@ class AsmFileMixin(object): """ def _download_file(self, filepathname): - self._download(filepathname) + self._download(filepathname) def _download(self, filepathname): session = self._meta_data['icr_session'] diff --git a/f5/bigip/test/unit/test_mixins.py b/f5/bigip/test/unit/test_mixins.py index 90e7718ca..1374f3dfc 100644 --- a/f5/bigip/test/unit/test_mixins.py +++ b/f5/bigip/test/unit/test_mixins.py @@ -174,10 +174,10 @@ def fake_http_server(uri, **kwargs): class FakeAsmFileMixin(AsmFileMixin): - def __init__(self, uri, **kwargs): - session = fake_http_server(uri, **kwargs) - self._meta_data = {'icr_session': session} - self.file_bound_uri = uri + def __init__(self, uri, **kwargs): + session = fake_http_server(uri, **kwargs) + self._meta_data = {'icr_session': session} + self.file_bound_uri = uri class TestAsmFileMixin(object): diff --git a/f5/bigip/tm/gtm/test/unit/test_pool.py b/f5/bigip/tm/gtm/test/unit/test_pool.py index e5319ebc0..cfe0f9495 100644 --- a/f5/bigip/tm/gtm/test/unit/test_pool.py +++ b/f5/bigip/tm/gtm/test/unit/test_pool.py @@ -285,7 +285,7 @@ def test_non_404_response__v12_1(self, fakeicontrolsession_v12): session.post.side_effect = error memres._meta_data['bigip']._meta_data['icr_session'] = session with pytest.raises(HTTPError) as err: - memres.create(name='fake', partition='fakepart') + memres.create(name='fake', partition='fakepart') assert err.value.response.status_code == 500 def test_404_response_v12_1(self, fakeicontrolsession_v12): diff --git a/f5/bigip/tm/ltm/test/functional/test_pool.py b/f5/bigip/tm/ltm/test/functional/test_pool.py index 625a2f5aa..d3c1567bb 100644 --- a/f5/bigip/tm/ltm/test/functional/test_pool.py +++ b/f5/bigip/tm/ltm/test/functional/test_pool.py @@ -79,7 +79,7 @@ def test_get_collection(self, request, mgmt_root, opt_release): member1.refresh() except HTTPError as err: if err.response.status_code != 404: - raise + raise pre_del = set(iterkeys(pool1.__dict__)) pool1.refresh() post_del = set(iterkeys(pool1.__dict__)) diff --git a/f5/bigip/tm/ltm/test/functional/test_virtual_address.py b/f5/bigip/tm/ltm/test/functional/test_virtual_address.py index d83035904..29402db1f 100644 --- a/f5/bigip/tm/ltm/test/functional/test_virtual_address.py +++ b/f5/bigip/tm/ltm/test/functional/test_virtual_address.py @@ -26,8 +26,8 @@ def teardown(): def setup_virtual_address_test(request, mgmt_root, va_name, va_partition): vac = mgmt_root.tm.ltm.virtual_address_s if vac.virtual_address.exists(name=va_name, partition=va_partition): - vac.virtual_address.load( - name=va_name, partition=va_partition).delete() + vac.virtual_address.load( + name=va_name, partition=va_partition).delete() va = vac.virtual_address.create(name=va_name, partition=va_partition) request.addfinalizer(va.delete) return vac, va diff --git a/f5/utils/testutils/registrytools.py b/f5/utils/testutils/registrytools.py index b5879c17b..44ad5c541 100644 --- a/f5/utils/testutils/registrytools.py +++ b/f5/utils/testutils/registrytools.py @@ -76,13 +76,13 @@ def register_collection_atoms(collection): logging.debug(ex) return resource_registry for resource in resources: - try: - resource_registry[resource.selfLink] = resource - except KeyError as ex: - raise ex - except UnsupportedTmosVersion as ex: - logging.debug(ex) - continue + try: + resource_registry[resource.selfLink] = resource + except KeyError as ex: + raise ex + except UnsupportedTmosVersion as ex: + logging.debug(ex) + continue return resource_registry From cf819645ba4e9dbfb9e31c74ac147a7891e640fc Mon Sep 17 00:00:00 2001 From: Qin Zhao Date: Wed, 9 Dec 2020 08:04:46 +0000 Subject: [PATCH 03/10] Cap cryptography version (cherry picked from commit ebbd6d5047a32de9919696b438876e8d948fc3c0) --- requirements.test.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/requirements.test.txt b/requirements.test.txt index 3ed0917b6..abc86ff4d 100644 --- a/requirements.test.txt +++ b/requirements.test.txt @@ -7,6 +7,7 @@ pytest==3.2.1 pytest-cov>=2.2.1 git+https://github.com/F5Networks/pytest-symbols.git python-coveralls==2.7.0 +cryptography<3.3 pyOpenSSL==16.2.0 requests-mock==1.2.0 netaddr From c06483e3bc9bdc4bb3760b8a81e78fb72be9a7ba Mon Sep 17 00:00:00 2001 From: Qin Zhao Date: Wed, 9 Dec 2020 08:46:19 +0000 Subject: [PATCH 04/10] Remove pytest-xdist from requirement --- requirements.test.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/requirements.test.txt b/requirements.test.txt index abc86ff4d..55f5b477a 100644 --- a/requirements.test.txt +++ b/requirements.test.txt @@ -12,7 +12,6 @@ pyOpenSSL==16.2.0 requests-mock==1.2.0 netaddr q -pytest-xdist pycodestyle jinja2 tox From 6e31810d40bfd8f0d94dc3c395813e10119ab150 Mon Sep 17 00:00:00 2001 From: Qin Zhao Date: Wed, 9 Dec 2020 08:51:01 +0000 Subject: [PATCH 05/10] Cap pytest_cov version --- requirements.test.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.test.txt b/requirements.test.txt index 55f5b477a..23bd4b5d1 100644 --- a/requirements.test.txt +++ b/requirements.test.txt @@ -4,7 +4,7 @@ hacking==0.13.0 mock==2.0.0 pytest==3.2.1 -pytest-cov>=2.2.1 +pytest-cov==2.2.1 git+https://github.com/F5Networks/pytest-symbols.git python-coveralls==2.7.0 cryptography<3.3 From 2580c056ef2199c18c26594500feac223c943d99 Mon Sep 17 00:00:00 2001 From: Qin Zhao Date: Wed, 9 Dec 2020 09:06:56 +0000 Subject: [PATCH 06/10] Workaround for pip failures --- f5-sdk-dist/scripts/construct_setups.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/f5-sdk-dist/scripts/construct_setups.py b/f5-sdk-dist/scripts/construct_setups.py index 7ec9c00fe..c5010af0e 100644 --- a/f5-sdk-dist/scripts/construct_setups.py +++ b/f5-sdk-dist/scripts/construct_setups.py @@ -26,7 +26,11 @@ from collections import deque from collections import namedtuple -from pip.req import parse_requirements as p_reqs + +try: # for pip >= 10 + from pip._internal.req import parse_requirements as p_reqs +except ImportError: # for pip <= 9.0.3 + from pip.req import parse_requirements as p_reqs def construct_cfgs(**kargs): From b2da5da773245fbb01870f30df3b6cb4c1c3d15e Mon Sep 17 00:00:00 2001 From: Qin Zhao Date: Wed, 25 Nov 2020 09:47:23 +0000 Subject: [PATCH 07/10] Use lower version of pip to build package (cherry picked from commit e6ef02a5e79bdaea7184dad7b6e3940bd59f8468) --- requirements.test.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/requirements.test.txt b/requirements.test.txt index 23bd4b5d1..89f449e0d 100644 --- a/requirements.test.txt +++ b/requirements.test.txt @@ -1,6 +1,7 @@ # Install this directory (will use setup.py and therefore install_requires). -e . # Test Requirements +pip<=18.1 hacking==0.13.0 mock==2.0.0 pytest==3.2.1 From f5c458490e620ff258c4d7e84ec5f50cb588bad2 Mon Sep 17 00:00:00 2001 From: Qin Zhao Date: Wed, 25 Nov 2020 14:18:08 +0800 Subject: [PATCH 08/10] Support bandwidth controller policy (cherry picked from commit 1ac824aad5d4ca78aa113783e248f0c4bbf033e5) --- f5/bigip/tm/net/__init__.py | 2 + f5/bigip/tm/net/bwc.py | 59 +++++++++++++++++ f5/bigip/tm/net/test/functional/test_bwc.py | 71 +++++++++++++++++++++ f5/bigip/tm/net/test/unit/test_bwc.py | 40 ++++++++++++ 4 files changed, 172 insertions(+) create mode 100644 f5/bigip/tm/net/bwc.py create mode 100644 f5/bigip/tm/net/test/functional/test_bwc.py create mode 100644 f5/bigip/tm/net/test/unit/test_bwc.py diff --git a/f5/bigip/tm/net/__init__.py b/f5/bigip/tm/net/__init__.py index 504f276dc..4174fc92f 100644 --- a/f5/bigip/tm/net/__init__.py +++ b/f5/bigip/tm/net/__init__.py @@ -29,6 +29,7 @@ from f5.bigip.resource import OrganizingCollection from f5.bigip.tm.net.arp import Arps +from f5.bigip.tm.net.bwc import Bwc from f5.bigip.tm.net.dns_resolver import Dns_Resolvers from f5.bigip.tm.net.fdb import Fdb from f5.bigip.tm.net.interface import Interfaces @@ -47,6 +48,7 @@ def __init__(self, tm): super(Net, self).__init__(tm) self._meta_data['allowed_lazy_attributes'] = [ Arps, + Bwc, Dns_Resolvers, Fdb, Interfaces, diff --git a/f5/bigip/tm/net/bwc.py b/f5/bigip/tm/net/bwc.py new file mode 100644 index 000000000..cb6711365 --- /dev/null +++ b/f5/bigip/tm/net/bwc.py @@ -0,0 +1,59 @@ +# coding=utf-8 +# +# Copyright 2020 F5 Networks Inc. +# +# 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. +# + +"""BIG-IP® Network bwc module. + +REST URI + ``http://localhost/mgmt/tm/net/bwc`` + +GUI Path + ``Acceleration --> Bandwidth Controllers`` + +REST Kind + ``tm:net:bwc:*`` +""" + +from f5.bigip.resource import Collection +from f5.bigip.resource import OrganizingCollection +from f5.bigip.resource import Resource + + +class Bwc(OrganizingCollection): + """BIG-IP® network bwc collection""" + def __init__(self, net): + super(Bwc, self).__init__(net) + self._meta_data['allowed_lazy_attributes'] = [ + Policys, + ] + + +class Policys(Collection): + """BIG-IP® bwc policy sub-collection""" + def __init__(self, bwc): + super(Policys, self).__init__(bwc) + self._meta_data['allowed_lazy_attributes'] = [Policy] + self._meta_data['attribute_registry'] =\ + {'tm:net:bwc:policy:policystate': Policy} + + +class Policy(Resource): + """BIG-IP® bwc policy sub-collection resource""" + def __init__(self, policy_s): + super(Policy, self).__init__(policy_s) + self._meta_data['required_creation_parameters'].update(('partition',)) + self._meta_data['required_json_kind'] =\ + 'tm:net:bwc:policy:policystate' diff --git a/f5/bigip/tm/net/test/functional/test_bwc.py b/f5/bigip/tm/net/test/functional/test_bwc.py new file mode 100644 index 000000000..653a89a52 --- /dev/null +++ b/f5/bigip/tm/net/test/functional/test_bwc.py @@ -0,0 +1,71 @@ +# Copyright 2020 F5 Networks Inc. +# +# 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. +# + +from requests.exceptions import HTTPError + + +TEST_DESCR = "TEST DESCRIPTION" + + +def delete_resource(resource): + try: + resource.delete() + except HTTPError as err: + if err.response.status_code != 404: + raise + + +def setup_policy_test(request, mgmt_root, name, partition, maxRate): + def teardown(): + delete_resource(policy) + request.addfinalizer(teardown) + + policy = mgmt_root.tm.net.bwc.policys.policy.create( + name=name, partition=partition, maxRate=maxRate) + return policy + + +class TestPolicys(object): + def test_policy_list(self, mgmt_root): + policies = mgmt_root.tm.net.bwc.policys.get_collection() + assert len(policies) + for policy in policies: + assert policy.generation + + +class TestPolicy(object): + def test_policy_CURDL(self, request, mgmt_root): + # Create and Delete are tested by the setup/teardown + p1 = setup_policy_test( + request, mgmt_root, 'bwc-policy-test', 'Common', 1000000 + ) + + # Load + p2 = mgmt_root.tm.net.bwc.policys.policy.load( + name='bwc-policy-test', partition='Common') + assert p1.name == 'bwc-policy-test' + assert p1.name == p2.name + assert p1.generation == p2.generation + + # Update + p1.description = TEST_DESCR + p1.update() + assert p1.description == TEST_DESCR + assert p1.generation > p2.generation + + # Refresh + p2.refresh() + assert p2.description == TEST_DESCR + assert p1.generation == p2.generation diff --git a/f5/bigip/tm/net/test/unit/test_bwc.py b/f5/bigip/tm/net/test/unit/test_bwc.py new file mode 100644 index 000000000..d3b9d165d --- /dev/null +++ b/f5/bigip/tm/net/test/unit/test_bwc.py @@ -0,0 +1,40 @@ +# Copyright 2015 F5 Networks Inc. +# +# 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. +# + +import mock +import pytest + +from f5.bigip import ManagementRoot +from f5.bigip.tm.net.bwc import Policy +from f5.sdk_exception import MissingRequiredCreationParameter + + +@pytest.fixture +def FakePolicy(): + fake_policy_s = mock.MagicMock() + fake_policy = Policy(fake_policy_s) + return fake_policy + + +class TestCreate(object): + def test_create_two(self, fakeicontrolsession): + b = ManagementRoot('192.168.1.1', 'admin', 'admin') + p1 = b.tm.net.bwc.policys.policy + p2 = b.tm.net.bwc.policys.policy + assert p1 is not p2 + + def test_create_no_args(self, FakePolicy): + with pytest.raises(MissingRequiredCreationParameter): + FakePolicy.create() From 30ae18c8f16029a20dfed4b455e3eb1254868ad7 Mon Sep 17 00:00:00 2001 From: Qin Zhao Date: Wed, 9 Dec 2020 10:11:03 +0000 Subject: [PATCH 09/10] Fix a typo in deb deploy script (cherry picked from commit 518deec5361c53fd7ac2ef98a5d86944e8506c8b) --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 6e05c951e..2953efaa3 100644 --- a/.travis.yml +++ b/.travis.yml @@ -31,7 +31,7 @@ script: - sudo chown travis:travis ${DIST_REPO}/deb_dist/*.deb after_success: - md5sum ${PKG_RELEASE_EL7} > ${PKG_RELEASE_EL7}.md5 && md5sum --check ${PKG_RELEASE_EL7}.md5 - - md5sum ${PKG_RELEASE_1404} > ${PKG_RELEASE_1404}.md5 && md5sum --check ${PKG_RELASE_1404}.md5 + - md5sum ${PKG_RELEASE_1404} > ${PKG_RELEASE_1404}.md5 && md5sum --check ${PKG_RELEASE_1404}.md5 before_deploy: PKG_VERSION=$(python -c "import f5; print(f5.__version__)") deploy: From ad9e0d545add4b70cf3735d087428617d8de2e26 Mon Sep 17 00:00:00 2001 From: Qin Zhao Date: Wed, 9 Dec 2020 10:18:16 +0000 Subject: [PATCH 10/10] Bump version number to 3.0.11.1 --- f5/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/f5/__init__.py b/f5/__init__.py index 7bfc198dd..49137c0fb 100644 --- a/f5/__init__.py +++ b/f5/__init__.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = '3.0.11' +__version__ = '3.0.11.1'