async def test_browse_for_game_session(mock_game_session_window: AsyncMock, mock_game_session_browser: MagicMock, mock_execute_dialog: AsyncMock, skip_qtbot, default_main_window, mocker): # Setup mock_get_game_connection = mocker.patch( "randovania.gui.lib.common_qt_lib.get_game_connection", autospec=True) mocker.patch("randovania.gui.main_window.MainWindow._ensure_logged_in", new_callable=AsyncMock, return_value=True) mock_execute_dialog.return_value = mock_game_session_browser.return_value.Accepted mock_game_session_browser.return_value.refresh = AsyncMock() # Run await default_main_window._browse_for_game_session() # Assert mock_game_session_browser.assert_called_once_with( default_main_window.network_client) mock_game_session_browser.return_value.refresh.assert_awaited_once_with() mock_execute_dialog.assert_awaited_once_with( mock_game_session_browser.return_value) mock_game_session_window.assert_awaited_once_with( default_main_window.network_client, mock_get_game_connection.return_value, default_main_window.preset_manager, default_main_window, default_main_window._options, ) mock_game_session_window.return_value.show.assert_called_once_with()
async def test_browse_for_game_session(mock_execute_dialog: AsyncMock, skip_qtbot, default_online_interactions, mocker): # Setup mock_game_session_browser: MagicMock = mocker.patch( "randovania.gui.main_online_interaction.GameSessionBrowserDialog", autospec=True) mock_create_and_update: AsyncMock = mocker.patch( "randovania.gui.main_online_interaction.GameSessionWindow.create_and_update", new_callable=AsyncMock) mock_create_and_update.return_value = MagicMock() mock_get_game_connection = mocker.patch( "randovania.gui.lib.common_qt_lib.get_game_connection", autospec=True) default_online_interactions._ensure_logged_in = AsyncMock( return_value=True) mock_execute_dialog.return_value = mock_game_session_browser.return_value.Accepted mock_game_session_browser.return_value.refresh = AsyncMock() # Run await default_online_interactions._browse_for_game_session() # Assert mock_game_session_browser.assert_called_once_with( default_online_interactions.network_client) mock_game_session_browser.return_value.refresh.assert_awaited_once_with() mock_execute_dialog.assert_awaited_once_with( mock_game_session_browser.return_value) mock_create_and_update.assert_awaited_once_with( default_online_interactions.network_client, mock_get_game_connection.return_value, default_online_interactions.preset_manager, default_online_interactions.window_manager, default_online_interactions.options, ) mock_create_and_update.return_value.show.assert_called_once_with()
async def test_async_args(): coro = AsyncMock() f = WrappedFunction(coro, name='coro_mock') f.run('arg1', 'arg2', kw1='kw1') await asyncio.sleep(0.05) coro.assert_awaited_once_with('arg1', 'arg2', kw1='kw1')
def test_run_with_custom_assembly_and_missing_release_offset(self, load_group_config: AsyncMock, load_releases_config: AsyncMock): runtime = MagicMock(config={"build_config": {"ocp_build_data_url": "https://example.com/ocp-build-data.git"}}, working_dir=Path("/path/to/working"), dry_run=False) pipeline = PromotePipeline(runtime, group="openshift-4.10", assembly="art0001", release_offset=None, arches=["x86_64", "s390x"]) with self.assertRaisesRegex(ValueError, "release_offset is required"): asyncio.get_event_loop().run_until_complete(pipeline.run()) load_group_config.assert_awaited_once_with("openshift-4.10", "art0001", env=ANY) load_releases_config.assert_awaited_once_with(Path("/path/to/working/doozer-working/ocp-build-data"))
def test_build_release_image_from_image_stream( self, cmd_assert_async: AsyncMock): runtime = MagicMock(config={ "build_config": { "ocp_build_data_url": "https://example.com/ocp-build-data.git" } }, working_dir=Path("/path/to/working"), dry_run=False) pipeline = PromotePipeline( runtime, group="openshift-4.10", assembly="4.10.99", release_offset=None, arches=["x86_64", "s390x", "ppc64le", "aarch64"]) previous_list = ["4.10.98", "4.10.97", "4.9.99"] metadata = { "description": "whatever", "url": "https://access.redhat.com/errata/RHBA-2099:2222" } # test x86_64 reference_release = None dest_pullspec = "example.com/foo/release:4.10.99-x86_64" asyncio.get_event_loop().run_until_complete( pipeline.build_release_image("4.10.99", "x86_64", previous_list, metadata, dest_pullspec, reference_release)) expected_cmd = [ 'oc', 'adm', 'release', 'new', '-n', 'ocp', '--name=4.10.99', '--to-image=example.com/foo/release:4.10.99-x86_64', '--reference-mode=source', '--from-image-stream=4.10-art-assembly-4.10.99', '--previous=4.10.98,4.10.97,4.9.99', '--metadata', '{"description": "whatever", "url": "https://access.redhat.com/errata/RHBA-2099:2222"}' ] cmd_assert_async.assert_awaited_once_with(expected_cmd, env=ANY, stdout=ANY) # test aarch64 reference_release = None dest_pullspec = "example.com/foo/release:4.10.99-aarch64" cmd_assert_async.reset_mock() asyncio.get_event_loop().run_until_complete( pipeline.build_release_image("4.10.99", "aarch64", previous_list, metadata, dest_pullspec, reference_release)) expected_cmd = [ 'oc', 'adm', 'release', 'new', '-n', 'ocp-arm64', '--name=4.10.99', '--to-image=example.com/foo/release:4.10.99-aarch64', '--reference-mode=source', '--from-image-stream=4.10-art-assembly-4.10.99-arm64', '--previous=4.10.98,4.10.97,4.9.99', '--metadata', '{"description": "whatever", "url": "https://access.redhat.com/errata/RHBA-2099:2222"}' ] cmd_assert_async.assert_awaited_once_with(expected_cmd, env=ANY, stdout=ANY)
def test_run_with_standard_assembly_without_upgrade_edges(self, load_group_config: AsyncMock, load_releases_config: AsyncMock): runtime = MagicMock(config={"build_config": {"ocp_build_data_url": "https://example.com/ocp-build-data.git"}}, working_dir=Path("/path/to/working"), dry_run=False) pipeline = PromotePipeline(runtime, group="openshift-4.10", assembly="4.10.99", release_offset=None, arches=["x86_64", "s390x"]) pipeline._slack_client = AsyncMock() with self.assertRaisesRegex(ValueError, "missing the required `upgrades` field"): asyncio.get_event_loop().run_until_complete(pipeline.run()) load_group_config.assert_awaited_once_with("openshift-4.10", "4.10.99", env=ANY) load_releases_config.assert_awaited_once_with(Path("/path/to/working/doozer-working/ocp-build-data"))
def test_build_release_image_from_reference_release( self, cmd_assert_async: AsyncMock): runtime = MagicMock(config={ "build_config": { "ocp_build_data_url": "https://example.com/ocp-build-data.git" } }, working_dir=Path("/path/to/working"), dry_run=False) pipeline = PromotePipeline( runtime, group="openshift-4.10", assembly="4.10.99", release_offset=None, arches=["x86_64", "s390x", "ppc64le", "aarch64"]) previous_list = ["4.10.98", "4.10.97", "4.9.99"] metadata = { "description": "whatever", "url": "https://access.redhat.com/errata/RHBA-2099:2222" } # test x86_64 reference_release = "whatever-x86_64" dest_pullspec = "example.com/foo/release:4.10.99-x86_64" asyncio.get_event_loop().run_until_complete( pipeline.build_release_image("4.10.99", "x86_64", previous_list, metadata, dest_pullspec, reference_release)) expected_cmd = [ "oc", "adm", "release", "new", "-n", "ocp", "--name=4.10.99", "--to-image=example.com/foo/release:4.10.99-x86_64", "--from-release=registry.ci.openshift.org/ocp/release:whatever-x86_64", "--previous=4.10.98,4.10.97,4.9.99", "--metadata", "{\"description\": \"whatever\", \"url\": \"https://access.redhat.com/errata/RHBA-2099:2222\"}" ] cmd_assert_async.assert_awaited_once_with(expected_cmd, env=ANY, stdout=ANY) # test aarch64 reference_release = "whatever-aarch64" dest_pullspec = "example.com/foo/release:4.10.99-aarch64" cmd_assert_async.reset_mock() asyncio.get_event_loop().run_until_complete( pipeline.build_release_image("4.10.99", "aarch64", previous_list, metadata, dest_pullspec, reference_release)) expected_cmd = [ "oc", "adm", "release", "new", "-n", "ocp-arm64", "--name=4.10.99", "--to-image=example.com/foo/release:4.10.99-aarch64", "--from-release=registry.ci.openshift.org/ocp-arm64/release-arm64:whatever-aarch64", "--previous=4.10.98,4.10.97,4.9.99", "--metadata", "{\"description\": \"whatever\", \"url\": \"https://access.redhat.com/errata/RHBA-2099:2222\"}" ] cmd_assert_async.assert_awaited_once_with(expected_cmd, env=ANY, stdout=ANY)
def test_copy_to_rcm_guest(self, cmd_assert_async: AsyncMock): cmd_assert_async.return_value = (0, "whatever", "whatever") pipeline = TarballSourcesPipeline(MagicMock(dry_run=False), "fake-group-4.10", "fake-assembly", ["fake-component"], []) get_event_loop().run_until_complete( pipeline._copy_to_rcm_guest("fake-working/sources")) cmd_assert_async.assert_awaited_once_with([ "rsync", "-avz", "--no-perms", "--no-owner", "--no-group", "fake-working/sources", ANY ])
async def test_handle_network_errors_success(skip_qtbot, qapp): callee = AsyncMock() callee.return_value = MagicMock() data = MagicMock() # Run wrapped = qt_network_client.handle_network_errors(callee) result = await wrapped(qapp, "foo", data) # Assert callee.assert_awaited_once_with(qapp, "foo", data) assert result is callee.return_value
def test_run_with_custom_assembly(self, load_group_config: AsyncMock, load_releases_config: AsyncMock, get_release_image_info: AsyncMock, build_release_image: AsyncMock): runtime = MagicMock(config={"build_config": {"ocp_build_data_url": "https://example.com/ocp-build-data.git"}}, working_dir=Path("/path/to/working"), dry_run=False) pipeline = PromotePipeline(runtime, group="openshift-4.10", assembly="art0001", release_offset=99, arches=["x86_64", "s390x"]) pipeline._slack_client = AsyncMock() asyncio.get_event_loop().run_until_complete(pipeline.run()) load_group_config.assert_awaited_once_with("openshift-4.10", "art0001", env=ANY) load_releases_config.assert_awaited_once_with(Path("/path/to/working/doozer-working/ocp-build-data")) get_release_image_info.assert_any_await("quay.io/openshift-release-dev/ocp-release:4.10.99-assembly.art0001-x86_64", raise_if_not_found=ANY) get_release_image_info.assert_any_await("quay.io/openshift-release-dev/ocp-release:4.10.99-assembly.art0001-s390x", raise_if_not_found=ANY) build_release_image.assert_any_await("4.10.99-assembly.art0001", "x86_64", [], {}, "quay.io/openshift-release-dev/ocp-release:4.10.99-assembly.art0001-x86_64", None) build_release_image.assert_any_await("4.10.99-assembly.art0001", "s390x", [], {}, "quay.io/openshift-release-dev/ocp-release:4.10.99-assembly.art0001-s390x", None) pipeline._slack_client.bind_channel.assert_called_once_with("4.10.99-assembly.art0001")
async def test_auto_update(skip_qtbot, qapp): # Setup update_mock = AsyncMock() backend = MagicMock() game_connection = GameConnection(backend) game_connection._notify_status = MagicMock() game_connection.update = update_mock # Run await game_connection._auto_update() # Assert update_mock.assert_awaited_once_with(game_connection._dt) game_connection._notify_status.assert_called_once_with()
async def test_update(skip_qtbot, qapp): # Setup backend_update = AsyncMock() backend = MagicMock() backend.update = backend_update game_connection = GameConnection(backend) game_connection._notify_status = MagicMock() # Run await game_connection._update() # Assert backend_update.assert_awaited_once_with(game_connection._dt) game_connection._notify_status.assert_called_once_with()
async def test_handle_network_errors_exception(skip_qtbot, qapp, mocker, exception, title, message): mock_dialog = mocker.patch("randovania.gui.lib.async_dialog.warning", new_callable=AsyncMock) callee = AsyncMock() callee.side_effect = exception data = MagicMock() # Run wrapped = qt_network_client.handle_network_errors(callee) result = await wrapped(qapp, "foo", data) # Assert callee.assert_awaited_once_with(qapp, "foo", data) assert result is None mock_dialog.assert_awaited_once_with(qapp, title, message)
async def test_update(skip_qtbot, qapp): # Setup backend_update = AsyncMock() game_connection = GameConnection() game_connection._connection_status = ConnectionStatus.Disconnected game_connection.StatusUpdated = MagicMock() # game_connection.backend = MagicMock() game_connection.backend.update = backend_update game_connection.backend.current_status = ConnectionStatus.InGame # Run await game_connection._update() # Assert backend_update.assert_awaited_once_with(1.0) game_connection.StatusUpdated.emit.assert_called_once_with(ConnectionStatus.InGame)
def test_run_with_standard_assembly(self, load_group_config: AsyncMock, load_releases_config: AsyncMock, get_release_image_info: AsyncMock, build_release_image: AsyncMock): runtime = MagicMock(config={"build_config": {"ocp_build_data_url": "https://example.com/ocp-build-data.git"}}, working_dir=Path("/path/to/working"), dry_run=False) pipeline = PromotePipeline(runtime, group="openshift-4.10", assembly="4.10.99", release_offset=None, arches=["x86_64", "s390x", "ppc64le", "aarch64"]) pipeline._slack_client = AsyncMock() pipeline.check_blocker_bugs = AsyncMock() pipeline.attach_cve_flaws = AsyncMock() pipeline.get_advisory_info = AsyncMock(return_value={ "id": 2, "errata_id": 2222, "fulladvisory": "RHBA-2099:2222-02", "status": "QE", }) pipeline.verify_attached_bugs = AsyncMock(return_value=None) pipeline.get_image_stream_tag = AsyncMock(return_value=None) pipeline.tag_release = AsyncMock(return_value=None) pipeline.wait_for_stable = AsyncMock(return_value=None) pipeline.send_image_list_email = AsyncMock() asyncio.get_event_loop().run_until_complete(pipeline.run()) load_group_config.assert_awaited_once_with("openshift-4.10", "4.10.99", env=ANY) load_releases_config.assert_awaited_once_with(Path("/path/to/working/doozer-working/ocp-build-data")) pipeline.check_blocker_bugs.assert_awaited_once_with() for advisory in [1, 2, 3, 4]: pipeline.attach_cve_flaws.assert_any_await(advisory) pipeline.get_advisory_info.assert_awaited_once_with(2) pipeline.verify_attached_bugs.assert_awaited_once_with([1, 2, 3, 4]) get_release_image_info.assert_any_await("quay.io/openshift-release-dev/ocp-release:4.10.99-x86_64", raise_if_not_found=ANY) get_release_image_info.assert_any_await("quay.io/openshift-release-dev/ocp-release:4.10.99-s390x", raise_if_not_found=ANY) build_release_image.assert_any_await("4.10.99", "x86_64", ["4.10.98", "4.9.99"], {"description": "whatever", "url": "https://access.redhat.com/errata/RHBA-2099:2222"}, "quay.io/openshift-release-dev/ocp-release:4.10.99-x86_64", "nightly-x86_64") build_release_image.assert_any_await("4.10.99", "s390x", ["4.10.98", "4.9.99"], {"description": "whatever", "url": "https://access.redhat.com/errata/RHBA-2099:2222"}, "quay.io/openshift-release-dev/ocp-release:4.10.99-s390x", "nightly-s390x") build_release_image.assert_any_await("4.10.99", "ppc64le", ["4.10.98", "4.9.99"], {"description": "whatever", "url": "https://access.redhat.com/errata/RHBA-2099:2222"}, "quay.io/openshift-release-dev/ocp-release:4.10.99-ppc64le", "nightly-ppc64le") build_release_image.assert_any_await("4.10.99", "aarch64", ["4.10.98", "4.9.99"], {"description": "whatever", "url": "https://access.redhat.com/errata/RHBA-2099:2222"}, "quay.io/openshift-release-dev/ocp-release:4.10.99-aarch64", "nightly-aarch64") pipeline._slack_client.bind_channel.assert_called_once_with("4.10.99") pipeline.get_image_stream_tag.assert_any_await("ocp", "release:4.10.99") pipeline.tag_release.assert_any_await("quay.io/openshift-release-dev/ocp-release:4.10.99-x86_64", "ocp/release:4.10.99") pipeline.tag_release.assert_any_await("quay.io/openshift-release-dev/ocp-release:4.10.99-s390x", "ocp-s390x/release-s390x:4.10.99") pipeline.tag_release.assert_any_await("quay.io/openshift-release-dev/ocp-release:4.10.99-ppc64le", "ocp-ppc64le/release-ppc64le:4.10.99") pipeline.tag_release.assert_any_await("quay.io/openshift-release-dev/ocp-release:4.10.99-aarch64", "ocp-arm64/release-arm64:4.10.99") pipeline.wait_for_stable.assert_any_await("4.10.99", "x86_64", "4-stable") pipeline.wait_for_stable.assert_any_await("4.10.99", "s390x", "4-stable-s390x") pipeline.wait_for_stable.assert_any_await("4.10.99", "ppc64le", "4-stable-ppc64le") pipeline.wait_for_stable.assert_any_await("4.10.99", "aarch64", "4-stable-arm64") pipeline.send_image_list_email.assert_awaited_once_with("4.10.99", 2, ANY)
def test_run(self, load_group_config: AsyncMock): runtime = MagicMock(dry_run=False) load_group_config.return_value = { "advisories": { "extras": 10000, "image": 10001 } } pipeline = TarballSourcesPipeline(runtime, "fake-group-4.10", "fake-assembly", ["fake-component"], []) pipeline._create_tarball_sources = AsyncMock( return_value=["source-1.tar.gz", "source-2.tar.gz"]) pipeline._copy_to_rcm_guest = AsyncMock() pipeline._create_jira = MagicMock(return_value=MagicMock( key="FAKE-123")) get_event_loop().run_until_complete(pipeline.run()) load_group_config.assert_awaited_once_with("fake-group-4.10", "fake-assembly", ANY) pipeline._create_tarball_sources.assert_awaited_once_with( [10000, 10001], ANY) pipeline._copy_to_rcm_guest.assert_awaited_once_with(ANY) pipeline._create_jira.assert_called_once_with( [10000, 10001], ["source-1.tar.gz", "source-2.tar.gz"])
def test_associate_builds_with_cves_bz( self, fake_urils_associate_builds_with_cves: AsyncMock): errata_api = AsyncMock(spec=AsyncErrataAPI) advisory = Mock(errata_id=12345, errata_builds={ "Fake-Product-Version1": { "a-1.0.0-1.el8": {}, "b-1.0.0-1.el8": {}, "c-1.0.0-1.el8": {}, "d-1.0.0-1.el8": {}, }, "Fake-Product-Version2": { "a-1.0.0-1.el7": {}, "e-1.0.0-1.el7": {}, "f-1.0.0-1.el7": {}, } }) tracker_flaws = { 1: [101, 103], 2: [101, 103], 3: [102, 103], 4: [101, 103], 5: [102], } attached_tracker_bugs = [ BugzillaBug( Mock(id=1, keywords=["Security", "SecurityTracking"], whiteboard="component: a")), BugzillaBug( Mock(id=2, keywords=["Security", "SecurityTracking"], whiteboard="component: b")), BugzillaBug( Mock(id=3, keywords=["Security", "SecurityTracking"], whiteboard="component: c")), BugzillaBug( Mock(id=4, keywords=["Security", "SecurityTracking"], whiteboard="component: d")), BugzillaBug( Mock(id=5, keywords=["Security", "SecurityTracking"], whiteboard="component: e")), ] flaw_id_bugs = { 101: BugzillaBug( Mock(id=101, keywords=["Security"], alias=["CVE-2099-1"])), 102: BugzillaBug( Mock(id=102, keywords=["Security"], alias=["CVE-2099-2"])), 103: BugzillaBug( Mock(id=103, keywords=["Security"], alias=["CVE-2099-3"])), } actual = get_event_loop().run_until_complete( attach_cve_flaws_cli.associate_builds_with_cves( errata_api, advisory, attached_tracker_bugs, tracker_flaws, flaw_id_bugs, dry_run=False)) fake_urils_associate_builds_with_cves.assert_awaited_once_with( errata_api, 12345, [ 'a-1.0.0-1.el8', 'b-1.0.0-1.el8', 'c-1.0.0-1.el8', 'd-1.0.0-1.el8', 'a-1.0.0-1.el7', 'e-1.0.0-1.el7', 'f-1.0.0-1.el7' ], { 'CVE-2099-1': {'a', 'd', 'b'}, 'CVE-2099-3': {'a', 'd', 'b', 'c'}, 'CVE-2099-2': {'c', 'e'} }, dry_run=False) self.assertEqual(actual, None)
def test_promote_arch(self, get_release_image_info: AsyncMock, build_release_image: AsyncMock, get_image_stream_tag: AsyncMock, tag_release: AsyncMock): runtime = MagicMock(config={ "build_config": { "ocp_build_data_url": "https://example.com/ocp-build-data.git" } }, working_dir=Path("/path/to/working"), dry_run=False) pipeline = PromotePipeline( runtime, group="openshift-4.10", assembly="4.10.99", release_offset=None, arches=["x86_64", "s390x", "ppc64le", "aarch64"]) previous_list = ["4.10.98", "4.10.97", "4.9.99"] metadata = { "description": "whatever", "url": "https://access.redhat.com/errata/RHBA-2099:2222" } # test x86_64 reference_release = "whatever-x86_64" actual = asyncio.get_event_loop().run_until_complete( pipeline.promote_arch(release_name="4.10.99", arch="x86_64", previous_list=previous_list, metadata=metadata, reference_release=reference_release, tag_stable=True)) get_release_image_info.assert_any_await( "quay.io/openshift-release-dev/ocp-release:4.10.99-x86_64") build_release_image.assert_awaited_once_with( "4.10.99", "x86_64", previous_list, metadata, "quay.io/openshift-release-dev/ocp-release:4.10.99-x86_64", reference_release) get_image_stream_tag.assert_awaited_once_with("ocp", "release:4.10.99") tag_release.assert_awaited_once_with( "quay.io/openshift-release-dev/ocp-release:4.10.99-x86_64", "ocp/release:4.10.99") self.assertEqual( actual["image"], "quay.io/openshift-release-dev/ocp-release:4.10.99-x86_64") # test aarch64 reference_release = "whatever-aarch64" get_release_image_info.reset_mock() build_release_image.reset_mock() get_image_stream_tag.reset_mock() tag_release.reset_mock() actual = asyncio.get_event_loop().run_until_complete( pipeline.promote_arch(release_name="4.10.99", arch="aarch64", previous_list=previous_list, metadata=metadata, reference_release=reference_release, tag_stable=True)) get_release_image_info.assert_any_await( "quay.io/openshift-release-dev/ocp-release:4.10.99-aarch64") build_release_image.assert_awaited_once_with( "4.10.99", "aarch64", previous_list, metadata, "quay.io/openshift-release-dev/ocp-release:4.10.99-aarch64", reference_release) get_image_stream_tag.assert_awaited_once_with("ocp-arm64", "release-arm64:4.10.99") tag_release.assert_awaited_once_with( "quay.io/openshift-release-dev/ocp-release:4.10.99-aarch64", "ocp-arm64/release-arm64:4.10.99") self.assertEqual( actual["image"], "quay.io/openshift-release-dev/ocp-release:4.10.99-aarch64") # test release tag already exists but doesn't match the to-be-promoted release image get_image_stream_tag.return_value = { "image": { "dockerImageReference": "quay.io/openshift-release-dev/ocp-release@fake:foobar", } } reference_release = "whatever-aarch64" get_release_image_info.reset_mock() build_release_image.reset_mock() get_image_stream_tag.reset_mock() tag_release.reset_mock() with self.assertRaisesRegex( ValueError, "already exists, but it has a different digest"): asyncio.get_event_loop().run_until_complete( pipeline.promote_arch(release_name="4.10.99", arch="aarch64", previous_list=previous_list, metadata=metadata, reference_release=reference_release, tag_stable=True)) get_release_image_info.assert_any_await( "quay.io/openshift-release-dev/ocp-release:4.10.99-aarch64") build_release_image.assert_awaited_once_with( "4.10.99", "aarch64", previous_list, metadata, "quay.io/openshift-release-dev/ocp-release:4.10.99-aarch64", reference_release) get_image_stream_tag.assert_awaited_once_with("ocp-arm64", "release-arm64:4.10.99") tag_release.assert_not_awaited()
class AsyncMockAssert(unittest.TestCase): def setUp(self): self.mock = AsyncMock() async def _runnable_test(self, *args, **kwargs): await self.mock(*args, **kwargs) async def _await_coroutine(self, coroutine): return await coroutine def test_assert_called_but_not_awaited(self): mock = AsyncMock(AsyncClass) with assertNeverAwaited(self): mock.async_method() self.assertTrue(iscoroutinefunction(mock.async_method)) mock.async_method.assert_called() mock.async_method.assert_called_once() mock.async_method.assert_called_once_with() with self.assertRaises(AssertionError): mock.assert_awaited() with self.assertRaises(AssertionError): mock.async_method.assert_awaited() def test_assert_called_then_awaited(self): mock = AsyncMock(AsyncClass) mock_coroutine = mock.async_method() mock.async_method.assert_called() mock.async_method.assert_called_once() mock.async_method.assert_called_once_with() with self.assertRaises(AssertionError): mock.async_method.assert_awaited() run(self._await_coroutine(mock_coroutine)) # Assert we haven't re-called the function mock.async_method.assert_called_once() mock.async_method.assert_awaited() mock.async_method.assert_awaited_once() mock.async_method.assert_awaited_once_with() def test_assert_called_and_awaited_at_same_time(self): with self.assertRaises(AssertionError): self.mock.assert_awaited() with self.assertRaises(AssertionError): self.mock.assert_called() run(self._runnable_test()) self.mock.assert_called_once() self.mock.assert_awaited_once() def test_assert_called_twice_and_awaited_once(self): mock = AsyncMock(AsyncClass) coroutine = mock.async_method() # The first call will be awaited so no warning there # But this call will never get awaited, so it will warn here with assertNeverAwaited(self): mock.async_method() with self.assertRaises(AssertionError): mock.async_method.assert_awaited() mock.async_method.assert_called() run(self._await_coroutine(coroutine)) mock.async_method.assert_awaited() mock.async_method.assert_awaited_once() def test_assert_called_once_and_awaited_twice(self): mock = AsyncMock(AsyncClass) coroutine = mock.async_method() mock.async_method.assert_called_once() run(self._await_coroutine(coroutine)) with self.assertRaises(RuntimeError): # Cannot reuse already awaited coroutine run(self._await_coroutine(coroutine)) mock.async_method.assert_awaited() def test_assert_awaited_but_not_called(self): with self.assertRaises(AssertionError): self.mock.assert_awaited() with self.assertRaises(AssertionError): self.mock.assert_called() with self.assertRaises(TypeError): # You cannot await an AsyncMock, it must be a coroutine run(self._await_coroutine(self.mock)) with self.assertRaises(AssertionError): self.mock.assert_awaited() with self.assertRaises(AssertionError): self.mock.assert_called() def test_assert_has_calls_not_awaits(self): kalls = [call('foo')] with assertNeverAwaited(self): self.mock('foo') self.mock.assert_has_calls(kalls) with self.assertRaises(AssertionError): self.mock.assert_has_awaits(kalls) def test_assert_has_mock_calls_on_async_mock_no_spec(self): with assertNeverAwaited(self): self.mock() kalls_empty = [('', (), {})] self.assertEqual(self.mock.mock_calls, kalls_empty) with assertNeverAwaited(self): self.mock('foo') with assertNeverAwaited(self): self.mock('baz') mock_kalls = ([call(), call('foo'), call('baz')]) self.assertEqual(self.mock.mock_calls, mock_kalls) def test_assert_has_mock_calls_on_async_mock_with_spec(self): a_class_mock = AsyncMock(AsyncClass) with assertNeverAwaited(self): a_class_mock.async_method() kalls_empty = [('', (), {})] self.assertEqual(a_class_mock.async_method.mock_calls, kalls_empty) self.assertEqual(a_class_mock.mock_calls, [call.async_method()]) with assertNeverAwaited(self): a_class_mock.async_method(1, 2, 3, a=4, b=5) method_kalls = [call(), call(1, 2, 3, a=4, b=5)] mock_kalls = [ call.async_method(), call.async_method(1, 2, 3, a=4, b=5) ] self.assertEqual(a_class_mock.async_method.mock_calls, method_kalls) self.assertEqual(a_class_mock.mock_calls, mock_kalls) def test_async_method_calls_recorded(self): with assertNeverAwaited(self): self.mock.something(3, fish=None) with assertNeverAwaited(self): self.mock.something_else.something(6, cake=sentinel.Cake) self.assertEqual(self.mock.method_calls, [("something", (3, ), { 'fish': None }), ("something_else.something", (6, ), { 'cake': sentinel.Cake })], "method calls not recorded correctly") self.assertEqual(self.mock.something_else.method_calls, [("something", (6, ), { 'cake': sentinel.Cake })], "method calls not recorded correctly") def test_async_arg_lists(self): def assert_attrs(mock): names = ('call_args_list', 'method_calls', 'mock_calls') for name in names: attr = getattr(mock, name) self.assertIsInstance(attr, _CallList) self.assertIsInstance(attr, list) self.assertEqual(attr, []) assert_attrs(self.mock) with assertNeverAwaited(self): self.mock() with assertNeverAwaited(self): self.mock(1, 2) with assertNeverAwaited(self): self.mock(a=3) self.mock.reset_mock() assert_attrs(self.mock) a_mock = AsyncMock(AsyncClass) with assertNeverAwaited(self): a_mock.async_method() with assertNeverAwaited(self): a_mock.async_method(1, a=3) a_mock.reset_mock() assert_attrs(a_mock) def test_assert_awaited(self): with self.assertRaises(AssertionError): self.mock.assert_awaited() run(self._runnable_test()) self.mock.assert_awaited() def test_assert_awaited_once(self): with self.assertRaises(AssertionError): self.mock.assert_awaited_once() run(self._runnable_test()) self.mock.assert_awaited_once() run(self._runnable_test()) with self.assertRaises(AssertionError): self.mock.assert_awaited_once() def test_assert_awaited_with(self): msg = 'Not awaited' with self.assertRaisesRegex(AssertionError, msg): self.mock.assert_awaited_with('foo') run(self._runnable_test()) msg = 'expected await not found' with self.assertRaisesRegex(AssertionError, msg): self.mock.assert_awaited_with('foo') run(self._runnable_test('foo')) self.mock.assert_awaited_with('foo') run(self._runnable_test('SomethingElse')) with self.assertRaises(AssertionError): self.mock.assert_awaited_with('foo') def test_assert_awaited_once_with(self): with self.assertRaises(AssertionError): self.mock.assert_awaited_once_with('foo') run(self._runnable_test('foo')) self.mock.assert_awaited_once_with('foo') run(self._runnable_test('foo')) with self.assertRaises(AssertionError): self.mock.assert_awaited_once_with('foo') def test_assert_any_wait(self): with self.assertRaises(AssertionError): self.mock.assert_any_await('foo') run(self._runnable_test('baz')) with self.assertRaises(AssertionError): self.mock.assert_any_await('foo') run(self._runnable_test('foo')) self.mock.assert_any_await('foo') run(self._runnable_test('SomethingElse')) self.mock.assert_any_await('foo') def test_assert_has_awaits_no_order(self): calls = [call('foo'), call('baz')] with self.assertRaises(AssertionError) as cm: self.mock.assert_has_awaits(calls) self.assertEqual(len(cm.exception.args), 1) run(self._runnable_test('foo')) with self.assertRaises(AssertionError): self.mock.assert_has_awaits(calls) run(self._runnable_test('foo')) with self.assertRaises(AssertionError): self.mock.assert_has_awaits(calls) run(self._runnable_test('baz')) self.mock.assert_has_awaits(calls) run(self._runnable_test('SomethingElse')) self.mock.assert_has_awaits(calls) def test_awaits_asserts_with_any(self): class Foo: def __eq__(self, other): pass run(self._runnable_test(Foo(), 1)) self.mock.assert_has_awaits([call(ANY, 1)]) self.mock.assert_awaited_with(ANY, 1) self.mock.assert_any_await(ANY, 1) def test_awaits_asserts_with_spec_and_any(self): class Foo: def __eq__(self, other): pass mock_with_spec = AsyncMock(spec=Foo) async def _custom_mock_runnable_test(*args): await mock_with_spec(*args) run(_custom_mock_runnable_test(Foo(), 1)) mock_with_spec.assert_has_awaits([call(ANY, 1)]) mock_with_spec.assert_awaited_with(ANY, 1) mock_with_spec.assert_any_await(ANY, 1) def test_assert_has_awaits_ordered(self): calls = [call('foo'), call('baz')] with self.assertRaises(AssertionError): self.mock.assert_has_awaits(calls, any_order=True) run(self._runnable_test('baz')) with self.assertRaises(AssertionError): self.mock.assert_has_awaits(calls, any_order=True) run(self._runnable_test('bamf')) with self.assertRaises(AssertionError): self.mock.assert_has_awaits(calls, any_order=True) run(self._runnable_test('foo')) self.mock.assert_has_awaits(calls, any_order=True) run(self._runnable_test('qux')) self.mock.assert_has_awaits(calls, any_order=True) def test_assert_not_awaited(self): self.mock.assert_not_awaited() run(self._runnable_test()) with self.assertRaises(AssertionError): self.mock.assert_not_awaited() def test_assert_has_awaits_not_matching_spec_error(self): async def f(x=None): pass self.mock = AsyncMock(spec=f) run(self._runnable_test(1)) with self.assertRaisesRegex( AssertionError, '^{}$'.format( re.escape('Awaits not found.\n' 'Expected: [call()]\n' 'Actual: [call(1)]'))) as cm: self.mock.assert_has_awaits([call()]) self.assertIsNone(cm.exception.__cause__) with self.assertRaisesRegex( AssertionError, '^{}$'.format( re.escape('Error processing expected awaits.\n' "Errors: [None, TypeError('too many positional " "arguments')]\n" 'Expected: [call(), call(1, 2)]\n' 'Actual: [call(1)]').replace( "arguments\\'", "arguments\\',?"))) as cm: self.mock.assert_has_awaits([call(), call(1, 2)]) self.assertIsInstance(cm.exception.__cause__, TypeError)