Skip to content

Commit fed3353

Browse files
pirat89abadger
andcommitted
device driver deprecation data: print nice error msg on malformed data
In case of malformed device_driver_deprecation_data.json user could originally see raw traceback without having too much information what it actually means or how to fix it. That usually happens only when the file is manually modified on the machine. So in this case we inform user what file is problematic and how to restore the original file installed by our package. In case of upstream development, this msg could be seen also when new data is provided if: * data file is malformed * data file has a new format of data (still json expected) * etc. These issues however will be discovered prior the merge as the running tests will fail, so such a problematic file should never get part of the upstream. From that point, we will be expect that user has malformed / customized data file. So no need to handle all possible errors differently in this case. Jira: OAMG-7549 Co-authored-by: Toshio Kuratomi <[email protected]>
1 parent 353cd03 commit fed3353

File tree

2 files changed

+56
-8
lines changed

2 files changed

+56
-8
lines changed

repos/system_upgrade/common/actors/loaddevicedriverdeprecationdata/libraries/deviceanddriverdeprecationdataload.py

Lines changed: 28 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
1+
from leapp.exceptions import StopActorExecutionError
12
from leapp.libraries.common import fetch
3+
from leapp.libraries.common.rpms import get_leapp_packages, LeappComponents
24
from leapp.libraries.stdlib import api
35
from leapp.models import DeviceDriverDeprecationData, DeviceDriverDeprecationEntry
6+
from leapp.models.fields import ModelViolationError
47

58

69
def process():
@@ -22,12 +25,29 @@ def process():
2225
docs_url='',
2326
docs_title='')
2427

25-
api.produce(
26-
DeviceDriverDeprecationData(
27-
entries=[
28-
DeviceDriverDeprecationEntry(**entry)
29-
for entry in deprecation_data['data']
30-
if entry.get('device_type') in supported_device_types
31-
]
28+
try:
29+
api.produce(
30+
DeviceDriverDeprecationData(
31+
entries=[
32+
DeviceDriverDeprecationEntry(**entry)
33+
for entry in deprecation_data['data']
34+
if entry.get('device_type') in supported_device_types
35+
]
36+
)
3237
)
33-
)
38+
except (ModelViolationError, ValueError, KeyError, AttributeError, TypeError) as err:
39+
# For the listed errors, we expect this to happen only when data is malformed
40+
# or manually updated. Corrupted data in the upstream is discovered
41+
# prior the merge thanks to testing. So just suggest the restoration
42+
# of the file.
43+
msg = 'Invalid device and driver deprecation data: {}'.format(err)
44+
hint = (
45+
'This issue is usually caused by manual update of the {lp} file.'
46+
' The data inside is either incorrect or old. To restore the original'
47+
' {lp} file, remove it and reinstall the following packages: {rpms}'
48+
.format(
49+
lp='/etc/leapp/file/device_driver_deprecation_data.json',
50+
rpms=', '.join(get_leapp_packages(component=LeappComponents.REPOSITORY))
51+
)
52+
)
53+
raise StopActorExecutionError(msg, details={'hint': hint})

repos/system_upgrade/common/actors/loaddevicedriverdeprecationdata/tests/test_ddddload.py

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
1+
import pytest
2+
3+
from leapp.exceptions import StopActorExecutionError
14
from leapp.libraries.actor import deviceanddriverdeprecationdataload as ddddload
25
from leapp.libraries.common import fetch
6+
from leapp.libraries.common.testutils import CurrentActorMocked
37

48
TEST_DATA = {
59
'data': [
@@ -57,3 +61,27 @@ def load_data_asset_mock(*args, **kwargs):
5761
assert produced
5862
assert len(produced[0].entries) == 3
5963
assert not any([e.device_type == 'unsupported' for e in produced[0].entries])
64+
65+
66+
@pytest.mark.parametrize('data', (
67+
{},
68+
{'foo': 'bar'},
69+
{'data': 1, 'foo': 'bar'},
70+
{'data': 'string', 'foo': 'bar'},
71+
{'data': {'foo': 1}, 'bar': 2},
72+
{'data': {'foo': 1, 'device_type': None}},
73+
{'data': {'foo': 1, 'device_type': 'cpu'}},
74+
{'data': {'driver_name': ['foo'], 'device_type': 'cpu'}},
75+
))
76+
def test_invalid_dddd_data(monkeypatch, data):
77+
produced = []
78+
79+
def load_data_asset_mock(*args, **kwargs):
80+
return data
81+
82+
monkeypatch.setattr(fetch, 'load_data_asset', load_data_asset_mock)
83+
monkeypatch.setattr(ddddload.api, 'current_actor', CurrentActorMocked())
84+
monkeypatch.setattr(ddddload.api, 'produce', lambda *v: produced.extend(v))
85+
with pytest.raises(StopActorExecutionError):
86+
ddddload.process()
87+
assert not produced

0 commit comments

Comments
 (0)