1313
1414if TYPE_CHECKING :
1515 import tmt .base .core
16- from tmt .base .core import Dependency , Run , _RawAdjustRule , _RawLinks
16+ from tmt .base .core import Dependency , Run , _RawAdjustRule
1717 from tmt .base .plan import Plan
1818
1919
@@ -27,14 +27,6 @@ def _unserialize_dependency(
2727 return dependency_factory (serialized )
2828
2929
30- # This needs to be a stand-alone function because of the import of `tmt.base`.
31- # It cannot be imported on module level because of circular dependency.
32- def _unserialize_links (serialized : Optional ['_RawLinks' ]) -> Optional ['tmt.base.core.Links' ]:
33- from tmt .base .core import Links
34-
35- return Links (data = serialized )
36-
37-
3830@container
3931class _RecipeTest (SerializableContainer ):
4032 name : str
@@ -58,18 +50,16 @@ class _RecipeTest(SerializableContainer):
5850 restart_max_count : int
5951 restart_with_reboot : bool
6052 serial_number : int
61- discover_phase : str
6253 link : Optional ['tmt.base.core.Links' ] = field (
6354 serialize = lambda value : value .to_spec () if value else [],
64- unserialize = lambda value : _unserialize_links (value ),
6555 )
6656 test : ShellScript = field (
6757 serialize = lambda value : str (value ),
6858 unserialize = lambda value : ShellScript (value ),
6959 )
70- path : Optional [ Path ] = field (
71- serialize = lambda value : str (value ) if value else None ,
72- unserialize = lambda value : Path (value ) if value else None ,
60+ path : Path = field (
61+ serialize = lambda value : str (value ),
62+ unserialize = lambda value : Path (value ),
7363 )
7464 require : list ['Dependency' ] = field (
7565 serialize = lambda value : [dependency .to_minimal_spec () for dependency in value ],
@@ -89,9 +79,17 @@ class _RecipeTest(SerializableContainer):
8979 )
9080 check : list [Check ] = field (
9181 serialize = lambda checks : [check .to_spec () for check in checks ],
92- unserialize = lambda serialized : [Check .from_spec (** check ) for check in serialized ],
9382 )
9483
84+ # ignore[override]: does not match the signature on purpose, we need to pass logger
85+ @classmethod
86+ def from_serialized (cls , serialized : dict [str , Any ], logger : Logger ) -> '_RecipeTest' : # type: ignore[override]
87+ raw_checks = serialized .pop ('check' , [])
88+ serialized ['check' ] = []
89+ recipe_test = super ().from_serialized (serialized )
90+ recipe_test .check = [Check .from_spec (check , logger ) for check in raw_checks ]
91+ return recipe_test
92+
9593 @classmethod
9694 def from_test_origin (cls , test_origin : 'TestOrigin' ) -> '_RecipeTest' :
9795 return _RecipeTest (
@@ -109,7 +107,7 @@ def from_test_origin(cls, test_origin: 'TestOrigin') -> '_RecipeTest':
109107 link = test_origin .test .link ,
110108 component = test_origin .test .component ,
111109 test = test_origin .test .test or ShellScript ('' ),
112- path = test_origin .test .path ,
110+ path = test_origin .test .path or Path ( '/' ) ,
113111 framework = test_origin .test .framework ,
114112 manual = test_origin .test .manual ,
115113 tty = test_origin .test .tty ,
@@ -124,7 +122,6 @@ def from_test_origin(cls, test_origin: 'TestOrigin') -> '_RecipeTest':
124122 restart_max_count = test_origin .test .restart_max_count ,
125123 restart_with_reboot = test_origin .test .restart_with_reboot ,
126124 serial_number = test_origin .test .serial_number ,
127- discover_phase = test_origin .phase ,
128125 )
129126
130127 def to_minimal_spec (self ) -> dict [str , Any ]:
@@ -134,7 +131,6 @@ def to_minimal_spec(self) -> dict[str, Any]:
134131 if value not in (None , [], {})
135132 }
136133 data .pop ('__class__' )
137- data .pop ('discover-phase' )
138134 return data
139135
140136 def to_test (self , logger : Logger ) -> 'tmt.base.core.Test' :
@@ -202,7 +198,9 @@ def from_serialized(cls, serialized: dict[str, Any], logger: Logger) -> '_Recipe
202198 phases = [StepData .unserialize (phase , logger ) for phase in serialized .get ('phases' , [])]
203199 if enabled
204200 else [],
205- tests = [_RecipeTest .from_serialized (test ) for test in serialized .get ('tests' , [])],
201+ tests = [
202+ _RecipeTest .from_serialized (test , logger ) for test in serialized .get ('tests' , [])
203+ ],
206204 )
207205
208206 @classmethod
@@ -305,7 +303,7 @@ def from_serialized(cls, serialized: dict[str, Any], logger: Logger) -> '_Recipe
305303 tag = serialized .get ('tag' , []),
306304 tier = serialized .get ('tier' ),
307305 adjust = serialized .get ('adjust' ),
308- link = _unserialize_links ( serialized .get ('link' ) ),
306+ link = serialized .get ('link' ),
309307 environment_from_fmf = Environment .from_fmf_spec (
310308 serialized .get ('environment-from-fmf' , {})
311309 ),
@@ -358,8 +356,27 @@ def from_plan(cls, plan: 'Plan') -> '_RecipePlan':
358356 )
359357
360358 def to_spec (self ) -> dict [str , Any ]:
361- # TODO: For now, only return the discover step.
362- return {'discover' : self .discover .to_spec ()}
359+ spec = self .to_dict ()
360+
361+ for e in [
362+ 'environment_from_fmf' ,
363+ 'environment_from_importing' ,
364+ 'environment_from_cli' ,
365+ 'environment_from_intrinsics' ,
366+ ]:
367+ spec .pop (e )
368+
369+ spec ['environment' ] = self .environment_from_fmf .to_fmf_spec ()
370+ spec ['context' ] = self .context .to_spec ()
371+
372+ spec ['discover' ] = self .discover .to_spec ()
373+ spec ['provision' ] = self .provision .to_spec ()
374+ spec ['prepare' ] = self .prepare .to_spec ()
375+ spec ['execute' ] = self .execute .to_spec ()
376+ spec ['report' ] = self .report .to_spec ()
377+ spec ['finish' ] = self .finish .to_spec ()
378+ spec ['cleanup' ] = self .cleanup .to_spec ()
379+ return spec
363380
364381
365382@container
@@ -425,7 +442,7 @@ def tests(self, recipe: Recipe, plan_name: str) -> list[TestOrigin]:
425442 if plan .name == plan_name :
426443 return [
427444 TestOrigin (
428- phase = test .discover_phase ,
445+ phase = test .path . unrooted (). parts [ 0 ] ,
429446 test = test .to_test (self ._logger ),
430447 )
431448 for test in plan .discover .tests
@@ -438,4 +455,5 @@ def update_tree(recipe: Recipe, tree: fmf.Tree) -> None:
438455 """
439456 Load the plans from the recipe and update the given fmf tree with their specifications.
440457 """
458+ tree .children .clear ()
441459 tree .update ({plan .name : plan .to_spec () for plan in recipe .plans })
0 commit comments