diff --git a/repos/system_upgrade/common/actors/loaddevicedriverdeprecationdata/libraries/deviceanddriverdeprecationdataload.py b/repos/system_upgrade/common/actors/loaddevicedriverdeprecationdata/libraries/deviceanddriverdeprecationdataload.py index f422c2c3b9..d4065a7232 100644 --- a/repos/system_upgrade/common/actors/loaddevicedriverdeprecationdata/libraries/deviceanddriverdeprecationdataload.py +++ b/repos/system_upgrade/common/actors/loaddevicedriverdeprecationdata/libraries/deviceanddriverdeprecationdataload.py @@ -1,6 +1,9 @@ +from leapp.exceptions import StopActorExecutionError from leapp.libraries.common import fetch +from leapp.libraries.common.rpms import get_leapp_packages, LeappComponents from leapp.libraries.stdlib import api from leapp.models import DeviceDriverDeprecationData, DeviceDriverDeprecationEntry +from leapp.models.fields import ModelViolationError def process(): @@ -22,12 +25,29 @@ def process(): docs_url='', docs_title='') - api.produce( - DeviceDriverDeprecationData( - entries=[ - DeviceDriverDeprecationEntry(**entry) - for entry in deprecation_data['data'] - if entry.get('device_type') in supported_device_types - ] + try: + api.produce( + DeviceDriverDeprecationData( + entries=[ + DeviceDriverDeprecationEntry(**entry) + for entry in deprecation_data['data'] + if entry.get('device_type') in supported_device_types + ] + ) ) - ) + except (ModelViolationError, ValueError, KeyError, AttributeError, TypeError) as err: + # All listed errors, we expect this to happen only when data is malformed + # or manually updated. Corrupted data in the upstream is discovered + # prior the merge thanks to the testing. So suggest just the restoration + # of the file. + msg = 'Invalid device and driver deprecation data: {}'.format(err) + hint = ( + 'This issue is usually caused by manual update of the {lp} file.' + ' The data inside is either incorrect or old. To restore the original' + ' {lp} file, remove it and reinstall the following packages: {rpms}' + .format( + lp='/etc/leapp/file/device_driver_deprecation_data.json', + rpms=', '.join(get_leapp_packages(component=LeappComponents.REPOSITORY)) + ) + ) + raise StopActorExecutionError(msg, details={'hint': hint}) diff --git a/repos/system_upgrade/common/actors/loaddevicedriverdeprecationdata/tests/test_ddddload.py b/repos/system_upgrade/common/actors/loaddevicedriverdeprecationdata/tests/test_ddddload.py index 69bcd09cfb..c3386745ae 100644 --- a/repos/system_upgrade/common/actors/loaddevicedriverdeprecationdata/tests/test_ddddload.py +++ b/repos/system_upgrade/common/actors/loaddevicedriverdeprecationdata/tests/test_ddddload.py @@ -1,5 +1,9 @@ +import pytest + +from leapp.exceptions import StopActorExecutionError from leapp.libraries.actor import deviceanddriverdeprecationdataload as ddddload from leapp.libraries.common import fetch +from leapp.libraries.common.testutils import CurrentActorMocked TEST_DATA = { 'data': [ @@ -57,3 +61,27 @@ def load_data_asset_mock(*args, **kwargs): assert produced assert len(produced[0].entries) == 3 assert not any([e.device_type == 'unsupported' for e in produced[0].entries]) + + +@pytest.mark.parametrize('data', ( + {}, + {'foo': 'bar'}, + {'data': 1, 'foo': 'bar'}, + {'data': 'string', 'foo': 'bar'}, + {'data': {'foo': 1}, 'bar': 2}, + {'data': {'foo': 1, 'device_type': None}}, + {'data': {'foo': 1, 'device_type': 'cpu'}}, + {'data': {'driver_name': ['foo'], 'device_type': 'cpu'}}, +)) +def test_invalid_dddd_data(monkeypatch, data): + produced = [] + + def load_data_asset_mock(*args, **kwargs): + return data + + monkeypatch.setattr(fetch, 'load_data_asset', load_data_asset_mock) + monkeypatch.setattr(ddddload.api, 'current_actor', CurrentActorMocked()) + monkeypatch.setattr(ddddload.api, 'produce', lambda *v: produced.extend(v)) + with pytest.raises(StopActorExecutionError): + ddddload.process() + assert not produced