Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

2048 american stout #928

Merged
merged 2 commits into from
Jul 8, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 16 additions & 1 deletion plugins/pulp_rpm/plugins/db/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -720,16 +720,31 @@ def update_needed(self, other):
date-time field. If we are not able to parse the `updated` field either in existing
erratum or in the new erratum, the metadata of existing erratum won't be updated.

When the other `updated` field is an empty string, False is returned. When the existing
`updated` field is an empty string, it is treated as the unix epoch. This allows erratum
published with an empty `updated` field to be updated later when the erratum is updated and
the `updated` field is set.

:param other: potentially a newer version of the erratum
:type other: pulp_rpm.plugins.db.models.Errata

:return: True if the other erratum is newer than the existing one
:rtype: bool

:raises ValueError: If either self or other `updated` fields is not an parseable datetime
format.
"""
if other.updated == "":
return False
if self.updated == "":
self_updated_field = '1970-01-01'
else:
self_updated_field = self.updated
err_msg = _('Fail to update the %(which)s erratum %(id)s.')
existing_err_msg = err_msg % {'which': 'existing', 'id': self.errata_id}
other_err_msg = err_msg % {'which': 'uploaded', 'id': self.errata_id}
existing_updated_dt = util.errata_format_to_datetime(self.updated, msg=existing_err_msg)
existing_updated_dt = util.errata_format_to_datetime(self_updated_field,
msg=existing_err_msg)
new_updated_dt = util.errata_format_to_datetime(other.updated, msg=other_err_msg)
return new_updated_dt > existing_updated_dt

Expand Down
20 changes: 19 additions & 1 deletion plugins/pulp_rpm/plugins/importers/yum/sync.py
Original file line number Diff line number Diff line change
Expand Up @@ -798,6 +798,7 @@ def save_fileless_units(self, file_handle, tag, process_func, mutable_type=False
package_info_generator = \
(model for model in all_packages if model.unit_key_as_named_tuple in to_save)

errata_could_not_be_merged_count = 0
for model in package_info_generator:
# Add repo_id to each collection of the pkglist of the new erratum
if isinstance(model, models.Errata):
Expand All @@ -808,13 +809,30 @@ def save_fileless_units(self, file_handle, tag, process_func, mutable_type=False
model.save()
else:
if additive_type:
model = self._concatenate_units(existing_unit, model)
try:
model = self._concatenate_units(existing_unit, model)
except ValueError:
# Sometimes Errata units cannot be merged and a ValueError is raised
# Count the errors and log them further down
if isinstance(model, models.Errata):
msg = _('The Errata "%(errata_id)s" could not be merged from the '
'remote repository. This is likely due to the existing or new '
'Errata not containing a valid `updated` field.')
_logger.debug(msg % {'errata_id': model.errata_id})
errata_could_not_be_merged_count += 1
continue
else:
raise
model.save()
else:
# make sure the associate_unit call gets the existing unit
model = existing_unit

repo_controller.associate_single_unit(self.repo, model)
if errata_could_not_be_merged_count != 0:
msg = _('There were %(count)d Errata units which could not be merged. This is likely '
'due to Errata in this repo not containing valid `updated` fields.')
_logger.warn(msg % {'count': errata_could_not_be_merged_count})

def _concatenate_units(self, existing_unit, new_unit):
"""
Expand Down
26 changes: 14 additions & 12 deletions plugins/pulp_rpm/yum_plugin/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,6 @@
import rpmUtils
from M2Crypto import X509

from pulp.server.exceptions import PulpCodedValidationException
from pulp_rpm.plugins import error_codes

_ = gettext.gettext

LOG_PREFIX_NAME = "pulp.plugins"
Expand Down Expand Up @@ -184,8 +181,9 @@ def errata_format_to_datetime(datetime_str, msg):
Convert known errata date-time formats to datetime object.

Expected formats are:
- '%Y-%m-%d %H:%M:%S'
- '%Y-%m-%d %H:%M:%S UTC'
- '%Y-%m-%d %H:%M:%S UTC'
- '%Y-%m-%d %H:%M:%S'
- '%Y-%m-%d'

:param datetime_str: date and time in errata specific format
:type datetime_str: str
Expand All @@ -197,15 +195,19 @@ def errata_format_to_datetime(datetime_str, msg):
:rtype: datetime.datetime
:raises ValueError: if the date and time are in unknown format
"""
strptime_pattern = '%Y-%m-%d %H:%M:%S'
strptime_patterns = ['%Y-%m-%d %H:%M:%S',
'%Y-%m-%d']
datetime_str = datetime_str.strip()
if datetime_str.endswith(' UTC'):
datetime_str = datetime_str[:-4]

try:
datetime_obj = datetime.datetime.strptime(datetime_str, strptime_pattern)
except ValueError:
raise PulpCodedValidationException(error_code=error_codes.RPM1007, details=msg,
expected_format=strptime_pattern)

for strptime_pattern in strptime_patterns:
try:
datetime_obj = datetime.datetime.strptime(datetime_str, strptime_pattern)
except ValueError:
continue
else:
break
else:
raise ValueError(msg)
return datetime_obj
44 changes: 35 additions & 9 deletions plugins/test/unit/plugins/db/test_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
import mock

from pulp.common.compat import unittest
from pulp.server.exceptions import PulpCodedValidationException
from pulp_rpm.common import ids
from pulp_rpm.devel.skip import skip_broken
from pulp_rpm.plugins.db import models
Expand Down Expand Up @@ -202,29 +201,56 @@ def test_update_needed_older_erratum(self):
ret = existing_erratum.update_needed(uploaded_erratum)
self.assertFalse(ret)

def test_update_needed_different_supported_date_formats(self):
"""
Assert that the supported datetime format are handled correctly and without any warning
"""
existing_erratum, uploaded_erratum = models.Errata(), models.Errata()
existing_erratum.updated = '2015-01-01'
uploaded_erratum.updated = '2016-01-01 00:00:00'
ret = existing_erratum.update_needed(uploaded_erratum)
self.assertTrue(ret)

def test_update_needed_bad_date_existing(self):
"""
Assert that if the `updated` date of the existing erratum is in the unknown format, then
the PulpCodedValidationException is raised.
a ValueError is raised.
"""
existing_erratum, uploaded_erratum = models.Errata(), models.Errata()
existing_erratum.updated = 'Fri Jan 1 00:00:00 UTC 2016'
uploaded_erratum.updated = '2016-04-01 00:00:00 UTC'
with self.assertRaisesRegexp(PulpCodedValidationException, 'existing erratum') as cm:
existing_erratum.update_needed(uploaded_erratum)
self.assertEqual('RPM1007', cm.exception.error_code.code)
self.assertRaises(ValueError, existing_erratum.update_needed, uploaded_erratum)

def test_update_needed_bad_date_uploaded(self):
"""
Assert that if the `updated` date of the uploaded erratum is in the unknown format, then
the PulpCodedValidationException is raised.
a ValueError is raised.
"""
existing_erratum, uploaded_erratum = models.Errata(), models.Errata()
existing_erratum.updated = '2016-01-01 00:00:00 UTC'
uploaded_erratum.updated = 'Fri Apr 1 00:00:00 UTC 2016'
with self.assertRaisesRegexp(PulpCodedValidationException, 'uploaded erratum') as cm:
existing_erratum.update_needed(uploaded_erratum)
self.assertEqual('RPM1007', cm.exception.error_code.code)
self.assertRaises(ValueError, existing_erratum.update_needed, uploaded_erratum)

def test_update_needed_empty_date_existing(self):
"""
Test an empty existing `updated` erratum field.

Assert that an empty existing `updated` field is considered older than an uploaded
erratum with a valid `updated` field.
"""
existing_erratum, uploaded_erratum = models.Errata(), models.Errata()
existing_erratum.updated = ''
uploaded_erratum.updated = '2016-04-01 00:00:00 UTC'
self.assertEqual(True, existing_erratum.update_needed(uploaded_erratum))

def test_update_needed_empty_date_uploaded(self):
"""
Test that an empty uploaded erratum `updated` field returns False.
"""
existing_erratum, uploaded_erratum = models.Errata(), models.Errata()
existing_erratum.updated = '2016-01-01 00:00:00 UTC'
uploaded_erratum.updated = ''
self.assertEqual(False, existing_erratum.update_needed(uploaded_erratum))

@mock.patch('pulp_rpm.plugins.db.models.Errata.save')
def test_merge_pkglists_oldstyle_newstyle_same_collection(self, mock_save):
Expand Down