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 hashlib
import logging import logging
import os import os
import socket
import time import time
import urllib.request import urllib.request
import urllib.parse import urllib.parse
@ -403,8 +404,8 @@ class FirstTimeForm(QtGui.QWizard, UiFirstTimeWizard, RegistryProperties):
retries = 0 retries = 0
while True: while True:
try: try:
url_file = urllib.request.urlopen(url, timeout=CONNECTION_TIMEOUT)
filename = open(f_path, "wb") filename = open(f_path, "wb")
url_file = urllib.request.urlopen(url, timeout=CONNECTION_TIMEOUT)
if sha256: if sha256:
hasher = hashlib.sha256() hasher = hashlib.sha256()
# Download until finished or canceled. # 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)) log.error('sha256 sums did not match for file: {}'.format(f_path))
os.remove(f_path) os.remove(f_path)
return False return False
except urllib.error.URLError: except (urllib.error.URLError, socket.timeout) as err:
trace_error_handler(log) trace_error_handler(log)
filename.close() filename.close()
os.remove(f_path) os.remove(f_path)
@ -617,6 +618,7 @@ class FirstTimeForm(QtGui.QWizard, UiFirstTimeWizard, RegistryProperties):
songs_destination = os.path.join(gettempdir(), 'openlp') songs_destination = os.path.join(gettempdir(), 'openlp')
bibles_destination = AppLocation.get_section_data_path('bibles') bibles_destination = AppLocation.get_section_data_path('bibles')
themes_destination = AppLocation.get_section_data_path('themes') themes_destination = AppLocation.get_section_data_path('themes')
missed_files = []
# Download songs # Download songs
for i in range(self.songs_list_widget.count()): for i in range(self.songs_list_widget.count()):
item = self.songs_list_widget.item(i) item = self.songs_list_widget.item(i)
@ -626,7 +628,7 @@ class FirstTimeForm(QtGui.QWizard, UiFirstTimeWizard, RegistryProperties):
self.previous_size = 0 self.previous_size = 0
destination = os.path.join(songs_destination, str(filename)) destination = os.path.join(songs_destination, str(filename))
if not self.url_get_file('%s%s' % (self.songs_url, filename), destination, sha256): if not self.url_get_file('%s%s' % (self.songs_url, filename), destination, sha256):
return False missed_files.append('Song: {}'.format(filename))
# Download Bibles # Download Bibles
bibles_iterator = QtGui.QTreeWidgetItemIterator(self.bibles_tree_widget) bibles_iterator = QtGui.QTreeWidgetItemIterator(self.bibles_tree_widget)
while bibles_iterator.value(): while bibles_iterator.value():
@ -637,7 +639,7 @@ class FirstTimeForm(QtGui.QWizard, UiFirstTimeWizard, RegistryProperties):
self.previous_size = 0 self.previous_size = 0
if not self.url_get_file('%s%s' % (self.bibles_url, bible), os.path.join(bibles_destination, bible), if not self.url_get_file('%s%s' % (self.bibles_url, bible), os.path.join(bibles_destination, bible),
sha256): sha256):
return False missed_files.append('Bible: {}'.format(bible))
bibles_iterator += 1 bibles_iterator += 1
# Download themes # Download themes
for i in range(self.themes_list_widget.count()): for i in range(self.themes_list_widget.count()):
@ -648,7 +650,20 @@ class FirstTimeForm(QtGui.QWizard, UiFirstTimeWizard, RegistryProperties):
self.previous_size = 0 self.previous_size = 0
if not self.url_get_file('%s%s' % (self.themes_url, theme), os.path.join(themes_destination, theme), if not self.url_get_file('%s%s' % (self.themes_url, theme), os.path.join(themes_destination, theme),
sha256): 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 return True
def _set_plugin_status(self, field, tag): def _set_plugin_status(self, field, tag):

View File

@ -23,6 +23,8 @@
Package to test the openlp.core.ui.firsttimeform package. Package to test the openlp.core.ui.firsttimeform package.
""" """
import os import os
import socket
import tempfile
import urllib import urllib
from unittest import TestCase from unittest import TestCase
@ -70,6 +72,11 @@ class TestFirstTimeForm(TestCase, TestMixin):
self.app.process_events = lambda: None self.app.process_events = lambda: None
Registry.create() Registry.create()
Registry().register('application', self.app) 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): def initialise_test(self):
""" """
@ -229,3 +236,20 @@ class TestFirstTimeForm(TestCase, TestMixin):
# THEN: the critical_error_message_box should have been called # THEN: the critical_error_message_box should have been called
self.assertEquals(mocked_message_box.mock_calls[1][1][0], 'Network Error 407', self.assertEquals(mocked_message_box.mock_calls[1][1][0], 'Network Error 407',
'first_time_form should have caught Network Error') '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')