twister: testplan: Handle unknown test level

Fail a test run gracefully when an unknown test level
is requested to execute with the current test plan.

Signed-off-by: Dmitrii Golovanov <dmitrii.golovanov@intel.com>
diff --git a/scripts/pylib/twister/twisterlib/testplan.py b/scripts/pylib/twister/twisterlib/testplan.py
index 2d24ca9..1ef5dce 100755
--- a/scripts/pylib/twister/twisterlib/testplan.py
+++ b/scripts/pylib/twister/twisterlib/testplan.py
@@ -740,9 +740,12 @@
 
                 if self.options.level:
                     tl = self.get_level(self.options.level)
-                    planned_scenarios = tl.scenarios
-                    if ts.id not in planned_scenarios and not set(ts.levels).intersection(set(tl.levels)):
-                        instance.add_filter("Not part of requested test plan", Filters.TESTPLAN)
+                    if tl is None:
+                        instance.add_filter(f"Unknown test level '{self.options.level}'", Filters.TESTPLAN)
+                    else:
+                        planned_scenarios = tl.scenarios
+                        if ts.id not in planned_scenarios and not set(ts.levels).intersection(set(tl.levels)):
+                            instance.add_filter("Not part of requested test plan", Filters.TESTPLAN)
 
                 if runnable and not instance.run:
                     instance.add_filter("Not runnable on device", Filters.CMD_LINE)
diff --git a/scripts/tests/twister/test_testplan.py b/scripts/tests/twister/test_testplan.py
index 02eae84..a069c89 100644
--- a/scripts/tests/twister/test_testplan.py
+++ b/scripts/tests/twister/test_testplan.py
@@ -109,6 +109,7 @@
     ("min_ram", "500", "ram", "256", "Not enough RAM"),
     ("None", "None", "env", ['BSIM_OUT_PATH', 'demo_env'], "Environment (BSIM_OUT_PATH, demo_env) not satisfied"),
     ("build_on_all", True, None, None, "Platform is excluded on command line."),
+    ("build_on_all", True, "level", "foobar", "Unknown test level 'foobar'"),
     (None, None, "supported_toolchains", ['gcc'], "Not supported by the toolchain"),
 ]
 
@@ -162,6 +163,9 @@
         if tc_attribute == "min_ram":
             testcase.min_ram = tc_value
 
+    if plat_attribute == "level":
+        plan.options.level = plat_value
+
     if tc_attribute == "build_on_all":
         for _, testcase in plan.testsuites.items():
             testcase.build_on_all = tc_value
@@ -417,6 +421,11 @@
     res = testplan.get_level(name)
     assert res == lvl1
 
+    lvl_missed = mock.Mock()
+    lvl_missed.name = 'missed lvl'
+    res = testplan.get_level('missed_lvl')
+    assert res is None
+
     testplan.levels.remove(lvl1)
     testplan.levels.remove(lvl2)