scale service save progress increments to thousandths

(Progress bar size == 1000 rather than a potential int overflow using the file size)
This commit is contained in:
Daniel 2020-07-01 16:10:28 +00:00 committed by Tim Bentley
parent 14aa717272
commit f6b4f8229e
2 changed files with 40 additions and 3 deletions

View File

@ -646,17 +646,17 @@ class ServiceManager(QtWidgets.QWidget, RegistryBase, Ui_ServiceManager, LogMixi
for local_file_item, zip_file_item in write_list: for local_file_item, zip_file_item in write_list:
total_size += local_file_item.stat().st_size total_size += local_file_item.stat().st_size
self.log_debug('ServiceManager.save_file - ZIP contents size is %i bytes' % total_size) self.log_debug('ServiceManager.save_file - ZIP contents size is %i bytes' % total_size)
self.main_window.display_progress_bar(total_size) self.main_window.display_progress_bar(1000)
try: try:
with NamedTemporaryFile(dir=str(file_path.parent), prefix='.') as temp_file, \ with NamedTemporaryFile(dir=str(file_path.parent), prefix='.') as temp_file, \
zipfile.ZipFile(temp_file, 'w') as zip_file: zipfile.ZipFile(temp_file, 'w') as zip_file:
# First we add service contents.. # First we add service contents..
zip_file.writestr('service_data.osj', service_content) zip_file.writestr('service_data.osj', service_content)
self.main_window.increment_progress_bar(service_content_size) self.main_window.increment_progress_bar(service_content_size / total_size * 1000)
# Finally add all the listed media files. # Finally add all the listed media files.
for local_file_item, zip_file_item in write_list: for local_file_item, zip_file_item in write_list:
zip_file.write(str(local_file_item), str(zip_file_item)) zip_file.write(str(local_file_item), str(zip_file_item))
self.main_window.increment_progress_bar(local_file_item.stat().st_size) self.main_window.increment_progress_bar(local_file_item.stat().st_size / total_size * 1000)
with suppress(FileNotFoundError): with suppress(FileNotFoundError):
file_path.unlink() file_path.unlink()
os.link(temp_file.name, file_path) os.link(temp_file.name, file_path)

View File

@ -655,6 +655,43 @@ def test_save_file_raises_permission_error(mocked_os, mocked_save_file_as, mocke
mocked_save_file_as.assert_called_with() mocked_save_file_as.assert_called_with()
@patch('openlp.core.ui.servicemanager.zipfile')
@patch('openlp.core.ui.servicemanager.ServiceManager.save_file_as')
@patch('openlp.core.ui.servicemanager.os')
@patch('openlp.core.ui.servicemanager.len')
def test_save_file_large_file(mocked_len, mocked_os, mocked_save_file_as, mocked_zipfile, registry):
"""
Test that when a file size size larger than a 32bit signed int is attempted to save, the progress bar
should be provided a value that fits in a 32bit int (because it's passed to C++ as a 32bit unsigned int)
"""
# GIVEN: A service manager, a service to save, and len() returns a huge value (file size)
def check_for_i32_overflow(val):
if val > 2147483647:
raise OverflowError
mocked_main_window = MagicMock()
mocked_main_window.display_progress_bar.side_effect = check_for_i32_overflow
Registry().register('main_window', mocked_main_window)
Registry().register('application', MagicMock())
mocked_settings = MagicMock()
Registry().register('settings', mocked_settings)
service_manager = ServiceManager(None)
service_manager._service_path = MagicMock()
service_manager._save_lite = False
service_manager.service_items = []
service_manager.service_theme = 'Default'
service_manager.service_manager_list = MagicMock()
mocked_save_file_as.return_value = True
mocked_zipfile.ZipFile.return_value = MagicMock()
mocked_len.return_value = 10000000000000
# WHEN: The service is saved and no error is raised
result = service_manager.save_file()
# THEN: The "save_as" method is called to save the service
assert result is True
mocked_save_file_as.assert_called_with()
@patch('openlp.core.ui.servicemanager.ServiceManager.regenerate_service_items') @patch('openlp.core.ui.servicemanager.ServiceManager.regenerate_service_items')
def test_theme_change_global(mocked_regenerate_service_items, registry): def test_theme_change_global(mocked_regenerate_service_items, registry):
""" """