Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Handle IncompleteRead in the composer when on Python 3.
fixes #2758

Signed-off-by: Randy Barlow <randy@electronsweatshop.com>
  • Loading branch information
bowlofeggs committed Nov 21, 2018
1 parent 64ff871 commit 561a562
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 1 deletion.
7 changes: 6 additions & 1 deletion bodhi/server/consumers/masher.py
Expand Up @@ -34,6 +34,11 @@
import threading
import time
from datetime import datetime
try:
from http.client import IncompleteRead
except ImportError: # pragma: no cover
# Python 2 does not have this Exception.
IncompleteRead = None

import fedmsg.consumers
import jinja2
Expand Down Expand Up @@ -1320,7 +1325,7 @@ def _wait_for_sync(self):
try:
self.log.info('Polling %s' % master_repomd_url)
masterrepomd = urllib2.urlopen(master_repomd_url)
except (URLError, HTTPError):
except (IncompleteRead, URLError, HTTPError):
self.log.exception('Error fetching repomd.xml')
time.sleep(200)
continue
Expand Down
54 changes: 54 additions & 0 deletions bodhi/tests/server/consumers/test_masher.py
Expand Up @@ -25,6 +25,11 @@
import tempfile
import time
import unittest
try:
from http.client import IncompleteRead
except ImportError:
# Python 2 does not have this Exception.
IncompleteRead = None

from click import testing
import mock
Expand Down Expand Up @@ -3088,6 +3093,55 @@ def test_httperror(self, urlopen, sleep, publish, save):
sleep.assert_called_once_with(200)
save.assert_called_once_with(ComposeState.syncing_repo)

@unittest.skipIf(six.PY2, "Python 2 does not have the IncompleteRead Exception.")
@mock.patch.dict(
'bodhi.server.consumers.masher.config',
{'fedora_testing_master_repomd':
'http://example.com/pub/fedora/linux/updates/testing/%s/%s/repodata.repomd.xml'})
@mock.patch('bodhi.server.consumers.masher.PungiComposerThread.save_state')
@mock.patch('bodhi.server.consumers.masher.notifications.publish')
@mock.patch('bodhi.server.consumers.masher.time.sleep')
@mock.patch('bodhi.server.consumers.masher.urllib2.urlopen')
def test_incompleteread(self, urlopen, sleep, publish, save):
"""
Assert that an IncompleteRead is properly caught and logged, and that the code continues.
"""
fake_url = mock.MagicMock()
fake_url.read.return_value = b'---\nyaml: rules'
urlopen.side_effect = [IncompleteRead('some_data'), fake_url]
t = PungiComposerThread(self.semmock, self._make_msg()['body']['msg']['composes'][0],
'bowlofeggs', log, self.Session, self.tempdir)
t.compose = self.db.query(Compose).one()
t.id = 'f26-updates-testing'
t.log = mock.MagicMock()
t.path = os.path.join(self.tempdir, t.id + '-' + time.strftime("%y%m%d.%H%M"))
for arch in ['aarch64', 'x86_64']:
repodata = os.path.join(t.path, 'compose', 'Everything', arch, 'os', 'repodata')
os.makedirs(repodata)
with open(os.path.join(repodata, 'repomd.xml'), 'w') as repomd:
repomd.write('---\nyaml: rules')

t._wait_for_sync()

expected_calls = [
mock.call(topic='mashtask.sync.wait', msg={'repo': t.id, 'agent': 'bowlofeggs'},
force=True),
mock.call(topic='mashtask.sync.done', msg={'repo': t.id, 'agent': 'bowlofeggs'},
force=True)]
publish.assert_has_calls(expected_calls)
# Since os.listdir() isn't deterministic about the order of the items it returns, the test
# won't be deterministic about which of arch URL gets used. However, either one of them
# would be correct so we will just assert that the one that is used is used correctly.
arch = 'x86_64' if 'x86_64' in urlopen.mock_calls[0][1][0] else 'aarch64'
expected_calls = [
mock.call('http://example.com/pub/fedora/linux/updates/testing/17/'
'{}/repodata.repomd.xml'.format(arch))
for i in range(2)]
urlopen.assert_has_calls(expected_calls)
t.log.exception.assert_called_once_with('Error fetching repomd.xml')
sleep.assert_called_once_with(200)
save.assert_called_once_with(ComposeState.syncing_repo)

@mock.patch.dict(
'bodhi.server.consumers.masher.config',
{'fedora_testing_master_repomd': None})
Expand Down

0 comments on commit 561a562

Please sign in to comment.