@@ -69,14 +69,78 @@ class Filters:
6969 MODULE = 'Module filter'
7070 # in case of missing env. variable required for a platform
7171 ENVIRONMENT = 'Environment filter'
72-
73-
7472class TestLevel :
7573 name = None
7674 levels = []
7775 scenarios = []
76+ class TestConfiguration :
77+ tc_schema_path = os .path .join (
78+ ZEPHYR_BASE ,
79+ "scripts" ,
80+ "schemas" ,
81+ "twister" ,
82+ "test-config-schema.yaml"
83+ )
84+
85+ def __init__ (self , config_file ):
86+ self .test_config = None
87+ self .override_default_platforms = False
88+ self .increased_platform_scope = True
89+ self .default_platforms = []
90+ self .parse (config_file )
91+
92+ def parse (self , config_file ):
93+ if os .path .exists (config_file ):
94+ tc_schema = scl .yaml_load (self .tc_schema_path )
95+ self .test_config = scl .yaml_load_verify (config_file , tc_schema )
96+ else :
97+ raise TwisterRuntimeError (f"File { config_file } not found." )
98+
99+ platform_config = self .test_config .get ('platforms' , {})
100+
101+ self .override_default_platforms = platform_config .get ('override_default_platforms' , False )
102+ self .increased_platform_scope = platform_config .get ('increased_platform_scope' , True )
103+ self .default_platforms = platform_config .get ('default_platforms' , [])
104+
105+ self .options = self .test_config .get ('options' , {})
78106
79107
108+ @staticmethod
109+ def get_level (levels , name ):
110+ level = next ((lvl for lvl in levels if lvl .name == name ), None )
111+ return level
112+
113+ def get_levels (self , scenarios ):
114+ levels = []
115+ configured_levels = self .test_config .get ('levels' , [])
116+
117+ # Do first pass on levels to get initial data.
118+ for level in configured_levels :
119+ adds = []
120+ for s in level .get ('adds' , []):
121+ r = re .compile (s )
122+ adds .extend (list (filter (r .fullmatch , scenarios )))
123+
124+ test_level = TestLevel ()
125+ test_level .name = level ['name' ]
126+ test_level .scenarios = adds
127+ test_level .levels = level .get ('inherits' , [])
128+ levels .append (test_level )
129+
130+ # Go over levels again to resolve inheritance.
131+ for level in configured_levels :
132+ inherit = level .get ('inherits' , [])
133+ _level = self .get_level (levels , level ['name' ])
134+ if inherit :
135+ for inherted_level in inherit :
136+ _inherited = self .get_level (levels , inherted_level )
137+ assert _inherited , "Unknown inherited level {inherted_level}"
138+ _inherited_scenarios = _inherited .scenarios
139+ level_scenarios = _level .scenarios if _level else []
140+ level_scenarios .extend (_inherited_scenarios )
141+
142+ return levels
143+
80144class TestPlan :
81145 __test__ = False # for pytest to skip this class when collects tests
82146 config_re = re .compile ('(CONFIG_[A-Za-z0-9_]+)[=]\" ?([^\" ]*)\" ?$' )
@@ -89,14 +153,6 @@ class TestPlan:
89153 os .path .join (ZEPHYR_BASE ,
90154 "scripts" , "schemas" , "twister" , "quarantine-schema.yaml" ))
91155
92- tc_schema_path = os .path .join (
93- ZEPHYR_BASE ,
94- "scripts" ,
95- "schemas" ,
96- "twister" ,
97- "test-config-schema.yaml"
98- )
99-
100156 SAMPLE_FILENAME = 'sample.yaml'
101157 TESTSUITE_FILENAME = 'testcase.yaml'
102158
@@ -126,48 +182,10 @@ def __init__(self, env: Namespace):
126182
127183 self .run_individual_testsuite = []
128184 self .levels = []
129- self .test_config = {}
185+ self .test_config = None
130186
131187 self .name = "unnamed"
132188
133- def get_level (self , name ):
134- level = next ((lvl for lvl in self .levels if lvl .name == name ), None )
135- return level
136-
137- def parse_configuration (self , config_file ):
138- if os .path .exists (config_file ):
139- tc_schema = scl .yaml_load (self .tc_schema_path )
140- self .test_config = scl .yaml_load_verify (config_file , tc_schema )
141- else :
142- raise TwisterRuntimeError (f"File { config_file } not found." )
143-
144- levels = self .test_config .get ('levels' , [])
145-
146- # Do first pass on levels to get initial data.
147- for level in levels :
148- adds = []
149- for s in level .get ('adds' , []):
150- r = re .compile (s )
151- adds .extend (list (filter (r .fullmatch , self .scenarios )))
152-
153- tl = TestLevel ()
154- tl .name = level ['name' ]
155- tl .scenarios = adds
156- tl .levels = level .get ('inherits' , [])
157- self .levels .append (tl )
158-
159- # Go over levels again to resolve inheritance.
160- for level in levels :
161- inherit = level .get ('inherits' , [])
162- _level = self .get_level (level ['name' ])
163- if inherit :
164- for inherted_level in inherit :
165- _inherited = self .get_level (inherted_level )
166- assert _inherited , "Unknown inherited level {inherted_level}"
167- _inherited_scenarios = _inherited .scenarios
168- level_scenarios = _level .scenarios if _level else []
169- level_scenarios .extend (_inherited_scenarios )
170-
171189 def find_subtests (self ):
172190 sub_tests = self .options .sub_test
173191 if sub_tests :
@@ -188,6 +206,8 @@ def discover(self):
188206 if self .options .test :
189207 self .run_individual_testsuite = self .options .test
190208
209+ self .test_config = TestConfiguration (self .env .test_config )
210+
191211 self .add_configurations ()
192212 num = self .add_testsuites (testsuite_filter = self .run_individual_testsuite )
193213 if num == 0 :
@@ -203,7 +223,7 @@ def discover(self):
203223 self .scenarios .append (ts .id )
204224
205225 self .report_duplicates ()
206- self .parse_configuration ( config_file = self .env . test_config )
226+ self .levels = self .test_config . get_levels ( self . scenarios )
207227
208228 # handle quarantine
209229 ql = self .options .quarantine_list
@@ -220,6 +240,10 @@ def discover(self):
220240 logger .debug (f'Quarantine file { quarantine_file } is empty' )
221241 self .quarantine = Quarantine (ql )
222242
243+ def get_level (self , name ):
244+ level = next ((lvl for lvl in self .levels if lvl .name == name ), None )
245+ return level
246+
223247 def load (self ):
224248
225249 if self .options .report_suffix :
@@ -440,19 +464,16 @@ def add_configurations(self):
440464 soc_roots = self .env .soc_roots
441465 arch_roots = self .env .arch_roots
442466
443- platform_config = self .test_config .get ('platforms' , {})
444-
445467 for platform in generate_platforms (board_roots , soc_roots , arch_roots ):
446468 if not platform .twister :
447469 continue
448470 self .platforms .append (platform )
449471
450- if not platform_config . get ( ' override_default_platforms' , False ) :
472+ if not self . test_config . override_default_platforms :
451473 if platform .default :
452474 self .default_platforms .append (platform .name )
453- #logger.debug(f"adding {platform.name} to default platforms")
454475 continue
455- for pp in platform_config . get ( ' default_platforms' , []) :
476+ for pp in self . test_config . default_platforms :
456477 if pp in platform .aliases :
457478 logger .debug (f"adding { platform .name } to default platforms (override mode)" )
458479 self .default_platforms .append (platform .name )
@@ -767,9 +788,8 @@ def apply_filters(self, **kwargs):
767788 else :
768789 platforms = self .platforms
769790
770- platform_config = self .test_config .get ('platforms' , {})
771791 # test configuration options
772- test_config_options = self .test_config .get ( ' options' , {})
792+ test_config_options = self .test_config .options
773793 integration_mode_list = test_config_options .get ('integration_mode' , [])
774794
775795 logger .info ("Building initial testsuite list..." )
@@ -784,7 +804,7 @@ def apply_filters(self, **kwargs):
784804 _integration_platforms = []
785805
786806 if (ts .build_on_all and not platform_filter and
787- platform_config . get ( ' increased_platform_scope' , True ) ):
807+ self . test_config . increased_platform_scope ):
788808 # if build_on_all is set, we build on all platforms
789809 platform_scope = self .platforms
790810 elif ts .integration_platforms and self .options .integration :
@@ -808,7 +828,7 @@ def apply_filters(self, **kwargs):
808828 ts .platform_allow
809829 and not platform_filter
810830 and not integration
811- and platform_config . get ( ' increased_platform_scope' , True )
831+ and self . test_config . increased_platform_scope
812832 ):
813833 a = set (platform_scope )
814834 b = set (filter (lambda item : item .name in ts .platform_allow , self .platforms ))
0 commit comments