diff --git a/gso/__init__.py b/gso/__init__.py index 59c067be44c520a9034aeddc179b3a98ac65aaf7..bcf939dd8793126dac10ecde18c00d818cdb96b9 100644 --- a/gso/__init__.py +++ b/gso/__init__.py @@ -4,6 +4,7 @@ import typer from orchestrator import OrchestratorCore, app_settings from orchestrator.cli.main import app as cli_app +# noinspection PyUnresolvedReferences import gso.products import gso.workflows # noqa: F401 from gso.api import router as api_router diff --git a/gso/utils/helpers.py b/gso/utils/helpers.py index c2396a16833550f4ef49ce544f00152c95afd672..37ff1d87cf0121cc01a7393bc741f5fe1c8201ff 100644 --- a/gso/utils/helpers.py +++ b/gso/utils/helpers.py @@ -39,7 +39,12 @@ def set_isis_to_90000(subscription: Iptrunk, process_id: UUIDstr, callback_route old_isis_metric = subscription.iptrunk.iptrunk_isis_metric subscription.iptrunk.iptrunk_isis_metric = 90000 provisioning_proxy.provision_ip_trunk( - subscription, process_id, callback_route, tt_number, "isis_interface", dry_run=False, + subscription, + process_id, + callback_route, + tt_number, + "isis_interface", + dry_run=False, ) return { diff --git a/gso/workflows/iptrunk/create_iptrunk.py b/gso/workflows/iptrunk/create_iptrunk.py index d159f53106182deef7793e4e5f417d1effdafbce..c5bf342e1f7663545ede9c2a68e1074a754430c1 100644 --- a/gso/workflows/iptrunk/create_iptrunk.py +++ b/gso/workflows/iptrunk/create_iptrunk.py @@ -243,7 +243,12 @@ def provision_ip_trunk_iface_dry( ) -> State: """Perform a dry run of deploying configuration on both sides of the trunk.""" provisioning_proxy.provision_ip_trunk( - subscription, process_id, callback_route, tt_number, "trunk_interface", dry_run=True, + subscription, + process_id, + callback_route, + tt_number, + "trunk_interface", + dry_run=True, ) return {"subscription": subscription} @@ -258,7 +263,12 @@ def provision_ip_trunk_iface_real( ) -> State: """Deploy IP trunk configuration on both sides.""" provisioning_proxy.provision_ip_trunk( - subscription, process_id, callback_route, tt_number, "trunk_interface", dry_run=False, + subscription, + process_id, + callback_route, + tt_number, + "trunk_interface", + dry_run=False, ) return {"subscription": subscription} @@ -299,7 +309,12 @@ def provision_ip_trunk_isis_iface_real( ) -> State: """Deploy :term:`ISIS` configuration on both sides.""" provisioning_proxy.provision_ip_trunk( - subscription, process_id, callback_route, tt_number, "isis_interface", dry_run=False, + subscription, + process_id, + callback_route, + tt_number, + "isis_interface", + dry_run=False, ) return {"subscription": subscription} diff --git a/gso/workflows/iptrunk/migrate_iptrunk.py b/gso/workflows/iptrunk/migrate_iptrunk.py index 2d59934418a4853af39f5de031b2fbce942c835b..8f122fa26272b56eecaaa442247e14f35768fb85 100644 --- a/gso/workflows/iptrunk/migrate_iptrunk.py +++ b/gso/workflows/iptrunk/migrate_iptrunk.py @@ -296,13 +296,13 @@ def deploy_new_config_real( @inputstep("Wait for confirmation", assignee=Assignee.SYSTEM) def confirm_continue_move_fiber() -> FormGenerator: """Wait for confirmation from an operator that the physical fiber has been moved.""" + class ProvisioningResultPage(FormPage): class Config: title = "Please confirm before continuing" info_label: Label = ( - "New trunk interface has been deployed, " - "wait for the physical connection to be moved." # type: ignore[assignment] + "New trunk interface has been deployed, wait for the physical connection to be moved." # type: ignore[assignment] ) yield ProvisioningResultPage @@ -349,6 +349,7 @@ def deploy_new_isis( @inputstep("Wait for confirmation", assignee=Assignee.SYSTEM) def confirm_continue_restore_isis() -> FormGenerator: """Wait for an operator to confirm that the old :term:`ISIS` metric should be restored.""" + class ProvisioningResultPage(FormPage): class Config: title = "Please confirm before continuing" @@ -373,7 +374,12 @@ def restore_isis_metric( """Restore the :term:`ISIS` metric to its original value.""" subscription.iptrunk.iptrunk_isis_metric = old_isis_metric provisioning_proxy.provision_ip_trunk( - subscription, process_id, callback_route, tt_number, "isis_interface", dry_run=False, + subscription, + process_id, + callback_route, + tt_number, + "isis_interface", + dry_run=False, ) return {"subscription": subscription} diff --git a/gso/workflows/iptrunk/modify_isis_metric.py b/gso/workflows/iptrunk/modify_isis_metric.py index 266df247a206a7de27ffab333805c8c8afed81fd..3ae91edf1b94b5705560947616a8812afe548dc2 100644 --- a/gso/workflows/iptrunk/modify_isis_metric.py +++ b/gso/workflows/iptrunk/modify_isis_metric.py @@ -55,7 +55,12 @@ def provision_ip_trunk_isis_iface_real( ) -> State: """Deploy the new :term:`ISIS` metric on both sides of the trunk.""" provisioning_proxy.provision_ip_trunk( - subscription, process_id, callback_route, tt_number, "isis_interface", dry_run=False, + subscription, + process_id, + callback_route, + tt_number, + "isis_interface", + dry_run=False, ) return {"subscription": subscription} diff --git a/gso/workflows/iptrunk/terminate_iptrunk.py b/gso/workflows/iptrunk/terminate_iptrunk.py index f0a2d166e94674dac34444869bc3eb2894b723b0..b4eb75cbaa0b72bc7c0d4f9ccec4f14386a943bd 100644 --- a/gso/workflows/iptrunk/terminate_iptrunk.py +++ b/gso/workflows/iptrunk/terminate_iptrunk.py @@ -25,6 +25,7 @@ from gso.utils.helpers import set_isis_to_90000 def initial_input_form_generator() -> FormGenerator: """Ask the operator to confirm whether router configuration and/or IPAM resources should be deleted.""" + class TerminateForm(FormPage): termination_label: Label = ( "Please confirm whether configuration should get removed from the A and B sides of the trunk, and whether " @@ -50,7 +51,12 @@ def drain_traffic_from_ip_trunk( XXX: Should this not be done with the isis-90k-step? """ provisioning_proxy.provision_ip_trunk( - subscription, process_id, callback_route, tt_number, "isis_interface", dry_run=False, + subscription, + process_id, + callback_route, + tt_number, + "isis_interface", + dry_run=False, ) return {"subscription": subscription} diff --git a/gso/workflows/router/create_router.py b/gso/workflows/router/create_router.py index 62dc35584519c47a0ed758952d41ab0d594cee28..1ec7f8222cc59c6417b747c7bbfaf69cde398408 100644 --- a/gso/workflows/router/create_router.py +++ b/gso/workflows/router/create_router.py @@ -39,6 +39,7 @@ def _site_selector() -> Choice: def initial_input_form_generator(product_name: str) -> FormGenerator: """Gather information about the new router from the operator.""" + class CreateRouterForm(FormPage): class Config: title = product_name diff --git a/gso/workflows/site/create_site.py b/gso/workflows/site/create_site.py index 5a5f2ed4a96a928d18fe72ddd249e5f63a4d28db..ac4fbb7ed62dca473349fbe089ba637f2ddd4582 100644 --- a/gso/workflows/site/create_site.py +++ b/gso/workflows/site/create_site.py @@ -23,6 +23,7 @@ from gso.utils.helpers import ( def initial_input_form_generator(product_name: str) -> FormGenerator: """Get input from the operator about the new site subscription.""" + class CreateSiteForm(FormPage): class Config: title = product_name diff --git a/gso/workflows/tasks/import_router.py b/gso/workflows/tasks/import_router.py index 77c8de5f8a709741304d7e2bb7a0fd89d5ca40c7..7be387eb83f9163503c64bd614c8d0e64e621626 100644 --- a/gso/workflows/tasks/import_router.py +++ b/gso/workflows/tasks/import_router.py @@ -50,6 +50,7 @@ def create_subscription(customer: str) -> State: def initial_input_form_generator() -> FormGenerator: """Generate a form that is filled in using information passed through the :term:`API` endpoint.""" + class ImportRouter(FormPage): class Config: title = "Import Router" diff --git a/gso/workflows/tasks/import_site.py b/gso/workflows/tasks/import_site.py index e928861ff6899de199509ac875845c455de2df15..e0ea0cd7e8258c65241f705a4fa23e7e1d93bbbd 100644 --- a/gso/workflows/tasks/import_site.py +++ b/gso/workflows/tasks/import_site.py @@ -34,6 +34,7 @@ def create_subscription(customer: str) -> State: def generate_initial_input_form() -> FormGenerator: """Generate a form that is filled in using information passed through the :term:`API` endpoint.""" + class ImportSite(FormPage): class Config: title = "Import Site" diff --git a/test/conftest.py b/test/conftest.py index dd36e9f348991512c23fd9d906d8ca255320b348..0e546594174349c95bc31a39f9b4c9a110d3813a 100644 --- a/test/conftest.py +++ b/test/conftest.py @@ -214,14 +214,14 @@ def run_migrations(db_uri: str) -> None: version_locations = alembic_cfg.get_main_option("version_locations") alembic_cfg.set_main_option( "version_locations", - f"{version_locations} {os.path.dirname(orchestrator.__file__)}/migrations/versions/schema", + f"{version_locations} {Path(orchestrator.__file__).parent}/migrations/versions/schema", ) command.upgrade(alembic_cfg, "heads") @pytest.fixture(scope="session") -def database(db_uri): +def _database(db_uri): """Create database and run migrations and cleanup after wards. Args: @@ -257,13 +257,13 @@ def database(db_uri): conn.execute(text("COMMIT;")) # Terminate all connections to the database conn.execute( - text(f"SELECT pg_terminate_backend(pid) FROM pg_stat_activity WHERE datname='{db_to_create}';") # noqa + text(f"SELECT pg_terminate_backend(pid) FROM pg_stat_activity WHERE datname='{db_to_create}';"), # noqa: S608 ) conn.execute(text(f'DROP DATABASE IF EXISTS "{db_to_create}";')) @pytest.fixture(autouse=True) -def db_session(database): +def _db_session(_database): """Ensure that tests are executed within a transactional scope that automatically rolls back after completion. This fixture facilitates a pattern known as 'transactional tests'. At the start, it establishes a connection and @@ -286,7 +286,10 @@ def db_session(database): with contextlib.closing(db.wrapped_database.engine.connect()) as test_connection: # Create a new session factory for this context. session_factory = sessionmaker(bind=test_connection, **SESSION_ARGUMENTS) - scoped_session_instance = scoped_session(session_factory, scopefunc=db.wrapped_database._scopefunc) + scoped_session_instance = scoped_session( + session_factory, + scopefunc=db.wrapped_database._scopefunc, # noqa: SLF001 + ) # Point the database session to this new scoped session. db.wrapped_database.session_factory = session_factory diff --git a/test/fixtures.py b/test/fixtures.py index e7a8d7f9d7c2798c8e003716ed5361e4d59ff66a..86927813112733379d00ce55ab94cf7c27b217f2 100644 --- a/test/fixtures.py +++ b/test/fixtures.py @@ -90,7 +90,7 @@ def router_subscription_factory(site_subscription_factory, faker): router_vendor=RouterVendor.NOKIA, router_role=RouterRole.PE, router_site=None, - router_is_ias_connected=True, + router_is_ias_connected=True, # noqa: FBT002 status: SubscriptionLifecycle | None = None, ) -> UUIDstr: description = description or faker.text(max_nb_chars=30) diff --git a/test/imports/conftest.py b/test/imports/conftest.py index 4a3e9c07a0c70ef31069d0f624c7437553562a16..3583feca4c7bd28841198cf180161315811d3ff4 100644 --- a/test/imports/conftest.py +++ b/test/imports/conftest.py @@ -1,4 +1,4 @@ -from test.fixtures import ( # noqa +from test.fixtures import ( # noqa: F401 iptrunk_side_subscription_factory, iptrunk_subscription_factory, router_subscription_factory, diff --git a/test/schemas/test_types.py b/test/schemas/test_types.py index ea0f4688ed856c14f5d6660662a3b910d54f05ba..2e90123f3d96f3c0e5c86294780ba4539a9660c1 100644 --- a/test/schemas/test_types.py +++ b/test/schemas/test_types.py @@ -49,6 +49,5 @@ def test_longitude(input_value, is_valid): if is_valid: assert LongitudeCoordinate.validate(input_value) == input_value else: - with pytest.raises(ValueError) as excinfo: + with pytest.raises(ValueError, match="Invalid longitude coordinate"): LongitudeCoordinate.validate(input_value) - assert "Invalid longitude coordinate" in str(excinfo.value) diff --git a/test/services/test_netbox.py b/test/services/test_netbox.py index 69983297ea35f75b775b4b967db6d97979189662..7df6320a22bc73ac8aa6c8ae5b7a60d51954f2a1 100644 --- a/test/services/test_netbox.py +++ b/test/services/test_netbox.py @@ -158,9 +158,8 @@ def test_reserve_interface_exception(mock_api, device, interface, data_config_fi mock_api.return_value.dcim.interfaces.get.return_value = interface # Check exception - with pytest.raises(WorkflowStateError) as test_exception: + with pytest.raises(WorkflowStateError, match=exception_message): NetboxClient().reserve_interface(device.name, interface.name) - assert str(test_exception.value) == exception_message @patch("gso.services.netbox_client.pynetbox.api") @@ -207,9 +206,8 @@ def test_allocate_interface_exception(mock_api, device, interface, data_config_f mock_api.return_value.dcim.interfaces.get.return_value = interface # Check exception - with pytest.raises(WorkflowStateError) as test_exception: + with pytest.raises(WorkflowStateError, match=exception_message): NetboxClient().allocate_interface(device.name, interface.name) - assert str(test_exception.value) == exception_message @patch("gso.services.netbox_client.pynetbox.api") @@ -317,4 +315,4 @@ def test_free_interface(mock_api, device, interface): cleared_interface = netbox_client.free_interface(device_name, interface_name) assert cleared_interface.enabled is False assert cleared_interface.mark_connected is False - assert cleared_interface.description == "" + assert not cleared_interface.description diff --git a/test/subscriptions/conftest.py b/test/subscriptions/conftest.py index 425a0e627a4592241e2c3f81cce910255dd34a5e..59674dfa54304f2795f862ca02961b21b7f6163a 100644 --- a/test/subscriptions/conftest.py +++ b/test/subscriptions/conftest.py @@ -1 +1 @@ -from test.fixtures import router_subscription_factory, site_subscription_factory # noqa +from test.fixtures import router_subscription_factory, site_subscription_factory # noqa: F401 diff --git a/test/workflows/__init__.py b/test/workflows/__init__.py index 66b9bea12c4a6ce0a0a191102a965c1094cc2575..c4852e9dcffc3b3c0e286d3851481398d1731cf0 100644 --- a/test/workflows/__init__.py +++ b/test/workflows/__init__.py @@ -223,7 +223,7 @@ def resume_workflow( nr_of_steps_done = len(persistent) remaining_steps = process.workflow.steps[nr_of_steps_done:] - if step_log and step_log[-1][1].issuspend(): + if step_log and step_log[-1][1].issuspend(): # noqa: SIM114 _, current_state = step_log[-1] elif step_log and step_log[-1][1].isawaitingcallback(): _, current_state = step_log[-1] diff --git a/test/workflows/conftest.py b/test/workflows/conftest.py index a4b71a738da3818674500075dd7ce910e2c17382..a3d301f218536f760c41633cbd8d4be831c14b97 100644 --- a/test/workflows/conftest.py +++ b/test/workflows/conftest.py @@ -1,7 +1,7 @@ import pytest from urllib3_mock import Responses -from test.fixtures import ( # noqa +from test.fixtures import ( # noqa: F401 iptrunk_side_subscription_factory, iptrunk_subscription_factory, router_subscription_factory, @@ -14,7 +14,7 @@ def responses(): responses_mock = Responses("requests.packages.urllib3") def _find_request(call): - mock_url = responses_mock._find_match(call.request) + mock_url = responses_mock._find_match(call.request) # noqa: SLF001 if not mock_url: pytest.fail(f"Call not mocked: {call.request}") return mock_url @@ -25,7 +25,7 @@ def responses(): with responses_mock: yield responses_mock - mocked_urls = map(_to_tuple, responses_mock._urls) + mocked_urls = map(_to_tuple, responses_mock._urls) # noqa: SLF001 used_urls = map(_to_tuple, map(_find_request, responses_mock.calls)) not_used = set(mocked_urls) - set(used_urls) if not_used: diff --git a/test/workflows/iptrunk/test_create_iptrunk.py b/test/workflows/iptrunk/test_create_iptrunk.py index 527a05fc40bffc6dca62875629d663a47936fe71..336344d9ff0a3b31ba39e7cb25e8b6f154e2f94c 100644 --- a/test/workflows/iptrunk/test_create_iptrunk.py +++ b/test/workflows/iptrunk/test_create_iptrunk.py @@ -19,7 +19,7 @@ from test.workflows import ( @pytest.fixture() -def netbox_client_mock(): +def _netbox_client_mock(): # Mock NetboxClient methods with ( patch("gso.services.netbox_client.NetboxClient.get_device_by_name") as mock_get_device_by_name, @@ -90,6 +90,7 @@ def input_form_wizard_data(router_subscription_factory, faker): @pytest.mark.workflow() +@pytest.mark.usefixtures(_netbox_client_mock) @patch("gso.workflows.iptrunk.create_iptrunk.provisioning_proxy.check_ip_trunk") @patch("gso.workflows.iptrunk.create_iptrunk.provisioning_proxy.provision_ip_trunk") @patch("gso.workflows.iptrunk.create_iptrunk.infoblox.allocate_v6_network") @@ -103,7 +104,6 @@ def test_successful_iptrunk_creation_with_standard_lso_result( input_form_wizard_data, faker, data_config_filename: PathLike, - netbox_client_mock, test_client, ): mock_allocate_v4_network.return_value = faker.ipv4_network() @@ -129,6 +129,7 @@ def test_successful_iptrunk_creation_with_standard_lso_result( @pytest.mark.workflow() +@pytest.mark.usefixtures(_netbox_client_mock) @patch("gso.workflows.iptrunk.create_iptrunk.provisioning_proxy.check_ip_trunk") @patch("gso.workflows.iptrunk.create_iptrunk.provisioning_proxy.provision_ip_trunk") @patch("gso.workflows.iptrunk.create_iptrunk.infoblox.allocate_v6_network") @@ -141,7 +142,6 @@ def test_iptrunk_creation_fails_when_lso_return_code_is_one( responses, input_form_wizard_data, faker, - netbox_client_mock, data_config_filename: PathLike, ): mock_allocate_v4_network.return_value = faker.ipv4_network() @@ -156,3 +156,4 @@ def test_iptrunk_creation_fails_when_lso_return_code_is_one( assert_pp_interaction_failure(result, process_stat, step_log) assert mock_check_ip_trunk.call_count == 0 + assert mock_provision_ip_trunk.call_count == 1 diff --git a/test/workflows/site/test_create_site.py b/test/workflows/site/test_create_site.py index 531c02f7215e877ad9ebc1f029082b40ebb2cc04..c49a6d87d69c3926cf271a97fc39b8b6b2480083 100644 --- a/test/workflows/site/test_create_site.py +++ b/test/workflows/site/test_create_site.py @@ -70,6 +70,5 @@ def test_site_name_is_incorrect(responses, faker): }, ] - with pytest.raises(FormValidationError) as test_exception: - result, process, step_log = run_workflow("create_site", initial_site_data) - assert str(test_exception.value) == expected_exception_msg + with pytest.raises(FormValidationError, match=expected_exception_msg): + run_workflow("create_site", initial_site_data) diff --git a/test/workflows/site/test_modify_site.py b/test/workflows/site/test_modify_site.py index 2afac782ced138d9e67982d6402950e82ff5fca8..8465afcc0eb0b75ec0cec52bae4dc7b876d40114 100644 --- a/test/workflows/site/test_modify_site.py +++ b/test/workflows/site/test_modify_site.py @@ -39,6 +39,5 @@ def test_modify_site_with_invalid_data(responses, site_subscription_factory): }, ] - with pytest.raises(FormValidationError) as e: + with pytest.raises(FormValidationError, match="site_bgp_community_id must be unique"): run_workflow("modify_site", initial_site_data) - assert "site_bgp_community_id must be unique" in str(e.value)