Fix ftw socket.timeout bug 1422683

This commit is contained in:
Ken Roberts 2015-02-17 13:27:51 -08:00
parent f7cb420a31
commit 80055b7ec0
2 changed files with 44 additions and 5 deletions

View File

@ -25,6 +25,7 @@ This module contains the first time wizard.
import hashlib
import logging
import os
import socket
import time
import urllib.request
import urllib.parse
@ -403,8 +404,8 @@ class FirstTimeForm(QtGui.QWizard, UiFirstTimeWizard, RegistryProperties):
retries = 0
while True:
try:
url_file = urllib.request.urlopen(url, timeout=CONNECTION_TIMEOUT)
filename = open(f_path, "wb")
url_file = urllib.request.urlopen(url, timeout=CONNECTION_TIMEOUT)
if sha256:
hasher = hashlib.sha256()
# Download until finished or canceled.
@ -422,7 +423,7 @@ class FirstTimeForm(QtGui.QWizard, UiFirstTimeWizard, RegistryProperties):
log.error('sha256 sums did not match for file: {}'.format(f_path))
os.remove(f_path)
return False
except urllib.error.URLError:
except (urllib.error.URLError, socket.timeout) as err:
trace_error_handler(log)
filename.close()
os.remove(f_path)
@ -617,6 +618,7 @@ class FirstTimeForm(QtGui.QWizard, UiFirstTimeWizard, RegistryProperties):
songs_destination = os.path.join(gettempdir(), 'openlp')
bibles_destination = AppLocation.get_section_data_path('bibles')
themes_destination = AppLocation.get_section_data_path('themes')
missed_files = []
# Download songs
for i in range(self.songs_list_widget.count()):
item = self.songs_list_widget.item(i)
@ -626,7 +628,7 @@ class FirstTimeForm(QtGui.QWizard, UiFirstTimeWizard, RegistryProperties):
self.previous_size = 0
destination = os.path.join(songs_destination, str(filename))
if not self.url_get_file('%s%s' % (self.songs_url, filename), destination, sha256):
return False
missed_files.append('Song: {}'.format(filename))
# Download Bibles
bibles_iterator = QtGui.QTreeWidgetItemIterator(self.bibles_tree_widget)
while bibles_iterator.value():
@ -637,7 +639,7 @@ class FirstTimeForm(QtGui.QWizard, UiFirstTimeWizard, RegistryProperties):
self.previous_size = 0
if not self.url_get_file('%s%s' % (self.bibles_url, bible), os.path.join(bibles_destination, bible),
sha256):
return False
missed_files.append('Bible: {}'.format(bible))
bibles_iterator += 1
# Download themes
for i in range(self.themes_list_widget.count()):
@ -648,7 +650,20 @@ class FirstTimeForm(QtGui.QWizard, UiFirstTimeWizard, RegistryProperties):
self.previous_size = 0
if not self.url_get_file('%s%s' % (self.themes_url, theme), os.path.join(themes_destination, theme),
sha256):
return False
missed_files.append('Theme: {}'.format(theme))
if missed_files:
file_list = ''
for entry in missed_files:
file_list += '{}<br \>'.format(entry)
msg = QtGui.QMessageBox()
msg.setIcon(QtGui.QMessageBox.Warning)
msg.setWindowTitle(translate('OpenLP.FirstTimeWizard', 'Network Error'))
msg.setText(translate('OpenLP.FirstTimeWizard', 'Unable to download some files'))
msg.setInformativeText(translate('OpenLP.FirstTimeWizard',
'The following files were not able to be '
'downloaded:<br \>{}'.format(file_list)))
msg.setStandardButtons(msg.Ok)
ans = msg.exec_()
return True
def _set_plugin_status(self, field, tag):

View File

@ -23,6 +23,8 @@
Package to test the openlp.core.ui.firsttimeform package.
"""
import os
import socket
import tempfile
import urllib
from unittest import TestCase
@ -70,6 +72,11 @@ class TestFirstTimeForm(TestCase, TestMixin):
self.app.process_events = lambda: None
Registry.create()
Registry().register('application', self.app)
self.tempfile = os.path.join(tempfile.gettempdir(), 'testfile')
def tearDown(self):
if os.path.isfile(self.tempfile):
os.remove(self.tempfile)
def initialise_test(self):
"""
@ -229,3 +236,20 @@ class TestFirstTimeForm(TestCase, TestMixin):
# THEN: the critical_error_message_box should have been called
self.assertEquals(mocked_message_box.mock_calls[1][1][0], 'Network Error 407',
'first_time_form should have caught Network Error')
@patch('openlp.core.ui.firsttimeform.urllib.request.urlopen')
def socket_timeout_test(self, mocked_urlopen):
"""
Test socket timeout gets caught
"""
# GIVEN: Mocked urlopen to fake a network disconnect in the middle of a download
first_time_form = FirstTimeForm(None)
first_time_form.initialize(MagicMock())
mocked_urlopen.side_effect = socket.timeout()
# WHEN: Attempt to retrieve a file
first_time_form.url_get_file(url='http://localhost/test', f_path=self.tempfile)
# THEN: socket.timeout should have been caught
# NOTE: Test is if $tmpdir/tempfile is still there, then test fails since ftw deletes bad downloaded files
self.assertFalse(os.path.exists(self.tempfile), 'FTW url_get_file should have caught socket.timeout')