summaryrefslogtreecommitdiffstats
path: root/BaseTools/Plugin/DebugMacroCheck/tests/MacroTest.py
diff options
context:
space:
mode:
authorMichael Kubacki <michael.kubacki@microsoft.com>2023-08-10 17:24:55 -0400
committermergify[bot] <37929162+mergify[bot]@users.noreply.github.com>2023-09-19 01:20:27 +0000
commitcbcf0428e83bbe8314de47207072b3b4f1557dc6 (patch)
tree543f63271cb41eb0e5188f06e6ef574e88093e6a /BaseTools/Plugin/DebugMacroCheck/tests/MacroTest.py
parent97d367f37e1d44efd126efb0c5145240af9d7afb (diff)
downloadedk2-cbcf0428e83bbe8314de47207072b3b4f1557dc6.tar.gz
edk2-cbcf0428e83bbe8314de47207072b3b4f1557dc6.tar.bz2
edk2-cbcf0428e83bbe8314de47207072b3b4f1557dc6.zip
BaseTools/Plugin: Add DebugMacroCheck
Adds a plugin that finds debug macro formatting issues. These errors often creep into debug prints in error conditions not frequently executed and make debug more difficult when they are encountered. The code can be as a standalone script which is useful to find problems in a large codebase that has not been checked before or as a build plugin that notifies a developer of an error right away. The script was already used to find numerous issues in edk2 in the past so there's not many code fixes in this change. More details are available in the readme file: .pytool\Plugin\DebugMacroCheck\Readme.md Cc: Sean Brogan <sean.brogan@microsoft.com> Cc: Michael D Kinney <michael.d.kinney@intel.com> Cc: Liming Gao <gaoliming@byosoft.com.cn> Cc: Rebecca Cran <rebecca@bsdio.com> Cc: Liming Gao <gaoliming@byosoft.com.cn> Cc: Bob Feng <bob.c.feng@intel.com> Cc: Yuwei Chen <yuwei.chen@intel.com> Signed-off-by: Michael Kubacki <michael.kubacki@microsoft.com> Reviewed-by: Michael D Kinney <michael.d.kinney@intel.com>
Diffstat (limited to 'BaseTools/Plugin/DebugMacroCheck/tests/MacroTest.py')
-rw-r--r--BaseTools/Plugin/DebugMacroCheck/tests/MacroTest.py131
1 files changed, 131 insertions, 0 deletions
diff --git a/BaseTools/Plugin/DebugMacroCheck/tests/MacroTest.py b/BaseTools/Plugin/DebugMacroCheck/tests/MacroTest.py
new file mode 100644
index 0000000000..3b966d31ff
--- /dev/null
+++ b/BaseTools/Plugin/DebugMacroCheck/tests/MacroTest.py
@@ -0,0 +1,131 @@
+# @file MacroTest.py
+#
+# Contains the data classes that are used to compose debug macro tests.
+#
+# All data classes inherit from a single abstract base class that expects
+# the subclass to define the category of test it represents.
+#
+# Copyright (c) Microsoft Corporation. All rights reserved.
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+##
+
+from dataclasses import dataclass, field
+from os import linesep
+from typing import Tuple
+
+import abc
+
+
+@dataclass(frozen=True)
+class MacroTest(abc.ABC):
+ """Abstract base class for an individual macro test case."""
+
+ macro: str
+ result: Tuple[int, int, int]
+ description: str = field(default='')
+
+ @property
+ @abc.abstractmethod
+ def category(self) -> str:
+ """Returns the test class category identifier.
+
+ Example: 'equal_specifier_equal_argument_macro_test'
+
+ This string is used to bind test objects against this class.
+
+ Returns:
+ str: Test category identifier string.
+ """
+ pass
+
+ @property
+ def category_description(self) -> str:
+ """Returns the test class category description.
+
+ Example: 'Test case with equal count of print specifiers to arguments.'
+
+ This string is a human readable description of the test category.
+
+ Returns:
+ str: String describing the test category.
+ """
+ return self.__doc__
+
+ def __str__(self):
+ """Returns a macro test case description string."""
+
+ s = [
+ f"{linesep}",
+ "=" * 80,
+ f"Macro Test Type: {self.category_description}",
+ f"{linesep}Macro: {self.macro}",
+ f"{linesep}Expected Result: {self.result}"
+ ]
+
+ if self.description:
+ s.insert(3, f"Test Description: {self.description}")
+
+ return f'{linesep}'.join(s)
+
+
+@dataclass(frozen=True)
+class NoSpecifierNoArgumentMacroTest(MacroTest):
+ """Test case with no print specifier and no arguments."""
+
+ @property
+ def category(self) -> str:
+ return "no_specifier_no_argument_macro_test"
+
+
+@dataclass(frozen=True)
+class EqualSpecifierEqualArgumentMacroTest(MacroTest):
+ """Test case with equal count of print specifiers to arguments."""
+
+ @property
+ def category(self) -> str:
+ return "equal_specifier_equal_argument_macro_test"
+
+
+@dataclass(frozen=True)
+class MoreSpecifiersThanArgumentsMacroTest(MacroTest):
+ """Test case with more print specifiers than arguments."""
+
+ @property
+ def category(self) -> str:
+ return "more_specifiers_than_arguments_macro_test"
+
+
+@dataclass(frozen=True)
+class LessSpecifiersThanArgumentsMacroTest(MacroTest):
+ """Test case with less print specifiers than arguments."""
+
+ @property
+ def category(self) -> str:
+ return "less_specifiers_than_arguments_macro_test"
+
+
+@dataclass(frozen=True)
+class IgnoredSpecifiersMacroTest(MacroTest):
+ """Test case to test ignored print specifiers."""
+
+ @property
+ def category(self) -> str:
+ return "ignored_specifiers_macro_test"
+
+
+@dataclass(frozen=True)
+class SpecialParsingMacroTest(MacroTest):
+ """Test case with special (complicated) parsing scenarios."""
+
+ @property
+ def category(self) -> str:
+ return "special_parsing_macro_test"
+
+
+@dataclass(frozen=True)
+class CodeSnippetMacroTest(MacroTest):
+ """Test case within a larger code snippet."""
+
+ @property
+ def category(self) -> str:
+ return "code_snippet_macro_test"