async def test_pull_file_from_remote( ftpserver: ProcessFTPServer, tmp_path: Path, faker: Faker, mocked_log_publishing_cb: mock.AsyncMock, ): ftp_server = cast(dict, ftpserver.get_login_data()) ftp_server["password"] = ftp_server["passwd"] del ftp_server["passwd"] ftp_server["username"] = ftp_server["user"] del ftp_server["user"] # put some file on the remote fs = fsspec.filesystem("ftp", **ftp_server) TEXT_IN_FILE = faker.text() file_name = faker.file_name() with fs.open(file_name, mode="wt") as fp: fp.write(TEXT_IN_FILE) ftp_server_url_login_data = ftpserver.get_login_data(style="url") src_url = parse_obj_as(AnyUrl, f"{ftp_server_url_login_data}/{file_name}") dst_path = tmp_path / faker.file_name() await pull_file_from_remote(src_url, dst_path, mocked_log_publishing_cb) assert dst_path.exists() assert dst_path.read_text() == TEXT_IN_FILE mocked_log_publishing_cb.assert_called()
async def test_parse_error(disconnecting_foldingathomecontroller, patched_error_prepared_open_connection): """Test that parsing a pyon message works.""" with patch("asyncio.open_connection", return_value=patched_error_prepared_open_connection): callback = MagicMock() disconnecting_foldingathomecontroller.register_callback(callback) with pytest.raises(FoldingAtHomeControlAuthenticationRequired): await disconnecting_foldingathomecontroller.start() callback.assert_called()
async def test_binary_sensor_unload_will_unsubscribe( hass: HomeAssistant) -> None: """Verify entity unique_id(s).""" mock_unsubscribe = AsyncMock() with patch("custom_components.frigate.async_unsubscribe_topics", new=mock_unsubscribe): config_entry = await setup_mock_frigate_config_entry(hass) await hass.config_entries.async_unload(config_entry.entry_id) await hass.async_block_till_done() mock_unsubscribe.assert_called()
async def test_parse_pyon_options( disconnecting_foldingathomecontroller, patched_pyon_options_prepared_open_connection): """Test that parsing a pyon message works.""" with patch( "asyncio.open_connection", return_value=patched_pyon_options_prepared_open_connection, ): callback = MagicMock() disconnecting_foldingathomecontroller.register_callback(callback) await disconnecting_foldingathomecontroller.start() callback.assert_called()
async def test_pull_compressed_zip_file_from_remote( ftpserver: ProcessFTPServer, tmp_path: Path, faker: Faker, mocked_log_publishing_cb: mock.AsyncMock, ): ftp_server = cast(dict, ftpserver.get_login_data()) ftp_server["password"] = ftp_server["passwd"] del ftp_server["passwd"] ftp_server["username"] = ftp_server["user"] del ftp_server["user"] # put some zip file on the remote local_zip_file_path = tmp_path / f"{faker.file_name()}.zip" local_test_file = tmp_path / faker.file_name() local_test_file.write_text(faker.text()) assert local_test_file.exists() with zipfile.ZipFile(local_zip_file_path, compression=zipfile.ZIP_DEFLATED, mode="w") as zfp: zfp.write(local_test_file, local_test_file.name) ftp_zip_file_path = f"{faker.file_name()}.zip" fs = fsspec.filesystem("ftp", **ftp_server) fs.put_file(local_zip_file_path, ftp_zip_file_path) assert fs.exists(ftp_zip_file_path) # USE-CASE 1: if destination is a zip then no decompression is done ftp_server_url_login_data = ftpserver.get_login_data(style="url") src_url = parse_obj_as(AnyUrl, f"{ftp_server_url_login_data}/{ftp_zip_file_path}") download_folder = tmp_path / "download" download_folder.mkdir(parents=True, exist_ok=True) assert download_folder.exists() dst_path = download_folder / f"{faker.file_name()}.zip" await pull_file_from_remote(src_url, dst_path, mocked_log_publishing_cb) assert dst_path.exists() dst_path.unlink() mocked_log_publishing_cb.assert_called() mocked_log_publishing_cb.reset_mock() # USE-CASE 2: if destination is not a zip, then we decompress assert download_folder.exists() dst_path = download_folder / faker.file_name() await pull_file_from_remote(src_url, dst_path, mocked_log_publishing_cb) assert not dst_path.exists() expected_download_file_path = download_folder / local_test_file.name assert expected_download_file_path.exists() mocked_log_publishing_cb.assert_called()
async def test_controller_calls_on_disconnect_on_IncompleteReadError( disconnecting_foldingathomecontroller, patched_open_connection): """Test that a IncompleteReadError is caught and calls on_disconnect().""" callback = MagicMock() with patch("asyncio.open_connection", return_value=patched_open_connection): await disconnecting_foldingathomecontroller.try_connect_async(timeout=5 ) stream_reader, _ = await asyncio.open_connection("localhost") stream_reader.readuntil.side_effect = IncompleteReadError([None], 5) disconnecting_foldingathomecontroller.on_disconnect(callback) await disconnecting_foldingathomecontroller.start(connect=False, subscribe=False) assert not disconnecting_foldingathomecontroller.is_connected callback.assert_called()
async def test_fixup(coresys: CoreSys): """Test fixup.""" create_full_snapshot = FixupCreateFullSnapshot(coresys) assert not create_full_snapshot.auto coresys.resolution.suggestions = Suggestion( SuggestionType.CREATE_FULL_SNAPSHOT, ContextType.SYSTEM) mock_snapshots = AsyncMock() coresys.snapshots.do_snapshot_full = mock_snapshots await create_full_snapshot() mock_snapshots.assert_called() assert len(coresys.resolution.suggestions) == 0
async def test_fixup(coresys: CoreSys): """Test fixup.""" create_full_backup = FixupSystemCreateFullBackup(coresys) assert not create_full_backup.auto coresys.resolution.suggestions = Suggestion( SuggestionType.CREATE_FULL_BACKUP, ContextType.SYSTEM) mock_backups = AsyncMock() coresys.backups.do_backup_full = mock_backups await create_full_backup() mock_backups.assert_called() assert len(coresys.resolution.suggestions) == 0
async def test_copy_file_to_remote( ftpserver: ProcessFTPServer, tmp_path: Path, faker: Faker, mocked_log_publishing_cb: mock.AsyncMock, ): ftp_server_base_url = ftpserver.get_login_data(style="url") file_on_remote = f"{ftp_server_base_url}/{faker.file_name()}" destination_url = parse_obj_as(AnyUrl, file_on_remote) src_path = tmp_path / faker.file_name() TEXT_IN_FILE = faker.text() src_path.write_text(TEXT_IN_FILE) assert src_path.exists() await push_file_to_remote(src_path, destination_url, mocked_log_publishing_cb) open_file = fsspec.open(destination_url, mode="rt") with open_file as fp: assert fp.read() == TEXT_IN_FILE mocked_log_publishing_cb.assert_called()
async def test_handle_push(monkeypatch): relay_push_discord = AsyncMock(return_value=True) relay_push = AsyncMock(return_value=True) monkeypatch.setattr("chitanda.modules.github_relay._relay_push_discord", relay_push_discord) monkeypatch.setattr("chitanda.modules.github_relay._relay_push", relay_push) await handle_push( Mock(), payload={ "ref": "refs/heads/master", "before": "abcdefghi", "repository": { "name": "chitanda" }, }, cfg={ "branches": ["master"], "channel": "hi" }, ) relay_push_discord.assert_not_called() relay_push.assert_called()
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 self.assertWarns(RuntimeWarning): # Will raise a warning because never awaited mock.async_method() self.assertTrue(asyncio.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() asyncio.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() asyncio.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() with self.assertWarns(RuntimeWarning): # The first call will be awaited so no warning there # But this call will never get awaited, so it will warn here mock.async_method() with self.assertRaises(AssertionError): mock.async_method.assert_awaited() mock.async_method.assert_called() asyncio.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() asyncio.run(self._await_coroutine(coroutine)) with self.assertRaises(RuntimeError): # Cannot reuse already awaited coroutine asyncio.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 asyncio.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 self.assertWarns(RuntimeWarning): # Will raise a warning because never awaited 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 self.assertWarns(RuntimeWarning): # Will raise a warning because never awaited self.mock() kalls_empty = [('', (), {})] self.assertEqual(self.mock.mock_calls, kalls_empty) with self.assertWarns(RuntimeWarning): # Will raise a warning because never awaited self.mock('foo') 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 self.assertWarns(RuntimeWarning): # Will raise a warning because never awaited 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 self.assertWarns(RuntimeWarning): # Will raise a warning because never awaited 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 self.assertWarns(RuntimeWarning): # Will raise warnings because never awaited self.mock.something(3, fish=None) 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 self.assertWarns(RuntimeWarning): # Will raise warnings because never awaited self.mock() self.mock(1, 2) self.mock(a=3) self.mock.reset_mock() assert_attrs(self.mock) a_mock = AsyncMock(AsyncClass) with self.assertWarns(RuntimeWarning): # Will raise warnings because never awaited a_mock.async_method() 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() asyncio.run(self._runnable_test()) self.mock.assert_awaited() def test_assert_awaited_once(self): with self.assertRaises(AssertionError): self.mock.assert_awaited_once() asyncio.run(self._runnable_test()) self.mock.assert_awaited_once() asyncio.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') asyncio.run(self._runnable_test()) msg = 'expected await not found' with self.assertRaisesRegex(AssertionError, msg): self.mock.assert_awaited_with('foo') asyncio.run(self._runnable_test('foo')) self.mock.assert_awaited_with('foo') asyncio.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') asyncio.run(self._runnable_test('foo')) self.mock.assert_awaited_once_with('foo') asyncio.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') asyncio.run(self._runnable_test('baz')) with self.assertRaises(AssertionError): self.mock.assert_any_await('foo') asyncio.run(self._runnable_test('foo')) self.mock.assert_any_await('foo') asyncio.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) asyncio.run(self._runnable_test('foo')) with self.assertRaises(AssertionError): self.mock.assert_has_awaits(calls) asyncio.run(self._runnable_test('foo')) with self.assertRaises(AssertionError): self.mock.assert_has_awaits(calls) asyncio.run(self._runnable_test('baz')) self.mock.assert_has_awaits(calls) asyncio.run(self._runnable_test('SomethingElse')) self.mock.assert_has_awaits(calls) 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) asyncio.run(self._runnable_test('baz')) with self.assertRaises(AssertionError): self.mock.assert_has_awaits(calls, any_order=True) asyncio.run(self._runnable_test('bamf')) with self.assertRaises(AssertionError): self.mock.assert_has_awaits(calls, any_order=True) asyncio.run(self._runnable_test('foo')) self.mock.assert_has_awaits(calls, any_order=True) asyncio.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() asyncio.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) asyncio.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)]'))) as cm: self.mock.assert_has_awaits([call(), call(1, 2)]) self.assertIsInstance(cm.exception.__cause__, TypeError)