def test_validate_is_called_first(monkeypatch): torrent = torf.Torrent() mock_validate = mock.Mock(side_effect=torf.MetainfoError('Mock error')) monkeypatch.setattr(torrent, 'validate', mock_validate) with pytest.raises(torf.MetainfoError) as excinfo: torrent.verify('some/path') assert str(excinfo.value) == 'Invalid metainfo: Mock error' mock_validate.assert_called_once_with()
def test_validate_is_called_first(monkeypatch): torrent = torf.Torrent() mock_validate = mock.MagicMock(side_effect=torf.MetainfoError('Mock error')) monkeypatch.setattr(torrent, 'validate', mock_validate) with pytest.raises(torf.MetainfoError) as excinfo: torrent.verify_filesize('some/path') assert excinfo.match(f'^Invalid metainfo: Mock error$') mock_validate.assert_called_once_with()
def test_callback_cancels_when_handling(cancel_condition, exp_callback_calls_count, existing_torrents, create_file): # Create and prepare existing torrents existing_torrents = existing_torrents( readable1=( ('a', 'foo', { 'creation_date': 123 }), ('b', 'bar', { 'creation_date': 456 }), ('c', 'baz', { 'creation_date': 789 }), ), # Unreadable directory unreadable=(), readable2=( ('d', 'hey', { 'private': True }), ('e', 'ho', { 'comment': 'yo' }), ('f', 'oh', { 'comment': 'oy' }), ('g', 'ohh', { 'comment': 'oyy' }), ('h', 'ohy', { 'comment': 'hoyo' }), ), ) # ReadError (directory) existing_torrents.locations['unreadable'].chmod(0o300) # ReadError (torrent file) existing_torrents.readable2[1].torrent_path.chmod(0o300) # BdecodeError data = bytearray(existing_torrents.readable2[2].torrent_path.read_bytes()) data[0] = ord('x') existing_torrents.readable2[2].torrent_path.write_bytes(data) # MetainfoError del existing_torrents.readable2[3].torrent.metainfo['info']['piece length'] existing_torrents.readable2[3].torrent.write( existing_torrents.readable2[3].torrent_path, validate=False, overwrite=True, ) # Create and prepare the torrent we want to generate new_content = existing_torrents.readable2[4].content_path new_torrent = torf.Torrent(path=new_content) exp_joined_metainfo = copy.deepcopy(new_torrent.metainfo) def callback(torrent, torrent_path, done, total, is_match, exception): if cancel_condition(torrent_path, is_match): return 'cancel' callback_wrapper = Mock(side_effect=callback) # Reuse existing torrent return_value = new_torrent.reuse(existing_torrents.location_paths, callback=callback_wrapper) # Confirm everything happened as expected assert return_value is False assert new_torrent.metainfo == exp_joined_metainfo all_callback_calls = [ call(new_torrent, str(existing_torrents.readable1[0].torrent_path), 1, 8, False, None), call(new_torrent, str(existing_torrents.readable1[1].torrent_path), 2, 8, False, None), call(new_torrent, str(existing_torrents.readable1[2].torrent_path), 3, 8, False, None), call( new_torrent, None, 3, 8, False, ComparableException( torf.ReadError( errno.EACCES, str(existing_torrents.locations['unreadable'])), ), ), call(new_torrent, str(existing_torrents.readable2[0].torrent_path), 4, 8, False, None), call( new_torrent, str(existing_torrents.readable2[1].torrent_path), 5, 8, False, ComparableException( torf.ReadError( errno.EACCES, str(existing_torrents.readable2[1].torrent_path)), ), ), call( new_torrent, str(existing_torrents.readable2[2].torrent_path), 6, 8, False, ComparableException( torf.BdecodeError( str(existing_torrents.readable2[2].torrent_path)), ), ), call( new_torrent, str(existing_torrents.readable2[3].torrent_path), 7, 8, False, ComparableException( torf.MetainfoError("Missing 'piece length' in ['info']"), ), ), call(new_torrent, str(existing_torrents.readable2[4].torrent_path), 8, 8, None, None), call(new_torrent, str(existing_torrents.readable2[4].torrent_path), 8, 8, False, None), ] assert callback_wrapper.call_args_list == all_callback_calls[: exp_callback_calls_count]