scripts: twister: snippet roots from modules

Automatically populate the snippet roots from Zephyr modules, instead of
only looking in `ZEPHYR_BASE`.

Signed-off-by: Jordan Yates <jordan.yates@data61.csiro.au>
diff --git a/scripts/pylib/twister/twisterlib/environment.py b/scripts/pylib/twister/twisterlib/environment.py
index 7e9c7de..42e48b6 100644
--- a/scripts/pylib/twister/twisterlib/environment.py
+++ b/scripts/pylib/twister/twisterlib/environment.py
@@ -863,6 +863,13 @@
             self.board_roots = None
             self.outdir = None
 
+        self.snippet_roots = [Path(ZEPHYR_BASE)]
+        modules = zephyr_module.parse_modules(ZEPHYR_BASE)
+        for module in modules:
+            snippet_root = module.meta.get("build", {}).get("settings", {}).get("snippet_root")
+            if snippet_root:
+                self.snippet_roots.append(Path(module.project) / snippet_root)
+
         self.hwm = None
 
         self.test_config = options.test_config if options else None
diff --git a/scripts/pylib/twister/twisterlib/testplan.py b/scripts/pylib/twister/twisterlib/testplan.py
index e813f03..4ce4a8c 100755
--- a/scripts/pylib/twister/twisterlib/testplan.py
+++ b/scripts/pylib/twister/twisterlib/testplan.py
@@ -806,7 +806,7 @@
                 if ts.required_snippets:
                     missing_snippet = False
                     snippet_args = {"snippets": ts.required_snippets}
-                    found_snippets = snippets.find_snippets_in_roots(snippet_args, [Path(ZEPHYR_BASE), Path(ts.source_dir)])
+                    found_snippets = snippets.find_snippets_in_roots(snippet_args, [*self.env.snippet_roots, Path(ts.source_dir)])
 
                     # Search and check that all required snippet files are found
                     for this_snippet in snippet_args['snippets']: