Merge ~sylvain-pineau/checkbox-ng:fail_valiadtion_on_missing_nested_parts into checkbox-ng:master

Proposed by Sylvain Pineau
Status: Work in progress
Proposed branch: ~sylvain-pineau/checkbox-ng:fail_valiadtion_on_missing_nested_parts
Merge into: checkbox-ng:master
Diff against target: 130 lines (+40/-10)
1 file modified
plainbox/impl/unit/testplan.py (+40/-10)
Reviewer Review Type Date Requested Status
Checkbox Developers Pending
Review via email: mp+412142@code.launchpad.net

Description of the change

This patch makes manage.py validate failing if one of the nested part is not found. The current behavior is just logging warnings.

To post a comment you must log in.
Revision history for this message
Sylvain Pineau (sylvain-pineau) wrote :

Does not play nicely with the sru provider and the missing pts testplan

Unmerged commits

44188d7... by Sylvain Pineau

Change: nested parts not found are now failing validation

test plan ids not found while performing a validation in context are now
causing the ./manage.py validate command to fail.
(instead of just logging warnings).

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1diff --git a/plainbox/impl/unit/testplan.py b/plainbox/impl/unit/testplan.py
2index 96b5c9a..f209ae9 100644
3--- a/plainbox/impl/unit/testplan.py
4+++ b/plainbox/impl/unit/testplan.py
5@@ -129,6 +129,26 @@ class NoBaseIncludeValidator(FieldValidatorBase):
6 raise NotImplementedError
7
8
9+class NestedPartReferenceValidator(FieldValidatorBase):
10+ """
11+ Validator that checks if nested parts identifiers are valid test plans
12+
13+ """
14+
15+ def check_in_context(self, parent, unit, field, context):
16+ id_map = context.compute_shared(
17+ "field_value_map[id]", compute_value_map, context, 'id')
18+ value_list, problems = unit.get_nested_part()
19+ for unit_id in problems:
20+ if unit_id not in id_map:
21+ yield parent.error(
22+ unit, field, Problem.bad_reference,
23+ self.message or _(
24+ "test plan {!a} is not available"
25+ ).format(unit_id))
26+ continue
27+
28+
29 class TestPlanUnit(UnitWithId):
30 """
31 Test plan class
32@@ -279,7 +299,8 @@ class TestPlanUnit(UnitWithId):
33 "unable to parse bootstrap_include: %s"), node.msg)
34
35 V().visit(WordList.parse(self.bootstrap_include))
36- for tp_unit in self.get_nested_part():
37+ tp_units, problems = self.get_nested_part()
38+ for tp_unit in tp_units:
39 job_ids.extend(tp_unit.get_bootstrap_job_ids())
40 return job_ids
41
42@@ -287,6 +308,7 @@ class TestPlanUnit(UnitWithId):
43 def get_nested_part(self):
44 """Compute and return a set of test plan ids from nested_part field."""
45 nested_parts = []
46+ problems = []
47 if self.nested_part is not None:
48 from plainbox.impl.session import SessionManager
49 with SessionManager.get_throwaway_manager(self.provider_list) as m:
50@@ -307,9 +329,8 @@ class TestPlanUnit(UnitWithId):
51 try:
52 nested_parts.append(context.get_unit(tp_id, 'test plan'))
53 except KeyError:
54- logger.warning(_(
55- "unable to find nested part: %s"), tp_id)
56- return nested_parts
57+ problems.append(tp_id)
58+ return nested_parts, problems
59
60 @instance_method_lru_cache(maxsize=None)
61 def get_qualifier(self):
62@@ -324,7 +345,8 @@ class TestPlanUnit(UnitWithId):
63 qual_list.extend(self._gen_qualifiers('include', self.include, True))
64 qual_list.extend(self._gen_qualifiers('exclude', self.exclude, False))
65 qual_list.extend([self.get_bootstrap_qualifier(excluding=True)])
66- for tp_unit in self.get_nested_part():
67+ tp_units, problems = self.get_nested_part()
68+ for tp_unit in tp_units:
69 qual_list.extend([tp_unit.get_qualifier()])
70 return CompositeQualifier(qual_list)
71
72@@ -340,7 +362,8 @@ class TestPlanUnit(UnitWithId):
73 qual_list = []
74 qual_list.extend(
75 self._gen_qualifiers('include', self.mandatory_include, True))
76- for tp_unit in self.get_nested_part():
77+ tp_units, problems = self.get_nested_part()
78+ for tp_unit in tp_units:
79 qual_list.extend([tp_unit.get_mandatory_qualifier()])
80 return CompositeQualifier(qual_list)
81
82@@ -356,7 +379,8 @@ class TestPlanUnit(UnitWithId):
83 qual_list = [FieldQualifier(
84 'id', OperatorMatcher(operator.eq, target_id), field_origin,
85 not excluding) for target_id in self.get_bootstrap_job_ids()]
86- for tp_unit in self.get_nested_part():
87+ tp_units, problems = self.get_nested_part()
88+ for tp_unit in tp_units:
89 qual_list.extend([tp_unit.get_bootstrap_qualifier(excluding)])
90 return CompositeQualifier(qual_list)
91
92@@ -577,6 +601,9 @@ class TestPlanUnit(UnitWithId):
93 fields.mandatory_include: [
94 NoBaseIncludeValidator(),
95 ],
96+ fields.nested_part: [
97+ NestedPartReferenceValidator(),
98+ ],
99 fields.bootstrap_include: [
100 concrete_validators.untranslatable,
101 NoBaseIncludeValidator(),
102@@ -784,7 +811,8 @@ PatternMatcher('^job-[x-z]$'), inclusive=False)])
103 override_list.append((pattern, 'category_id', category_id))
104
105 V().visit(OverrideFieldList.parse(testplan.category_overrides))
106- for tp_unit in testplan.get_nested_part():
107+ tp_units, problems = testplan.get_nested_part()
108+ for tp_unit in tp_units:
109 override_list.extend(self._get_category_overrides(tp_unit))
110 return override_list
111
112@@ -813,7 +841,8 @@ PatternMatcher('^job-[x-z]$'), inclusive=False)])
113
114 V().visit(OverrideFieldList.parse(
115 testplan.certification_status_overrides))
116- for tp_unit in testplan.get_nested_part():
117+ tp_units, problems = testplan.get_nested_part()
118+ for tp_unit in tp_units:
119 override_list.extend(self._get_blocker_status_overrides(tp_unit))
120 return override_list
121
122@@ -843,6 +872,7 @@ PatternMatcher('^job-[x-z]$'), inclusive=False)])
123 override_list.append((pattern, field_value_list))
124
125 V().visit(IncludeStmtList.parse(testplan.include))
126- for tp_unit in testplan.get_nested_part():
127+ tp_units, problems = testplan.get_nested_part()
128+ for tp_unit in tp_units:
129 override_list.extend(self._get_inline_overrides(tp_unit))
130 return override_list

Subscribers

People subscribed via source and target branches