Skip to content

Commit

Permalink
device driver deprecation data: print nice error msg on malformed data
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
pirat89 committed Jan 22, 2024
1 parent 353cd03 commit 1412166
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 8 deletions.
Original file line number Diff line number Diff line change
@@ -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():
Expand All @@ -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})
Original file line number Diff line number Diff line change
@@ -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': [
Expand Down Expand Up @@ -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

0 comments on commit 1412166

Please sign in to comment.