"FmpDevicePkg",\r
"ShellPkg",\r
"FatPkg",\r
- "CryptoPkg"\r
+ "CryptoPkg",\r
+ "UnitTestFrameworkPkg"\r
)\r
\r
def GetArchitecturesSupported(self):\r
\r
def GetActiveScopes(self):\r
''' return tuple containing scopes that should be active for this process '''\r
- scopes = ("cibuild","edk2-build")\r
+ scopes = ("cibuild", "edk2-build", "host-based-test")\r
\r
self.ActualToolChainTag = shell_environment.GetBuildVars().GetValue("TOOL_CHAIN_TAG", "")\r
\r
+ if GetHostInfo().os.upper() == "WINDOWS":\r
+ scopes += ('host-test-win',)\r
+\r
if GetHostInfo().os.upper() == "LINUX" and self.ActualToolChainTag.upper().startswith("GCC"):\r
if "AARCH64" in self.ActualArchitectures:\r
scopes += ("gcc_aarch64_linux",)\r
''' return iterable containing RequiredSubmodule objects.\r
If no RequiredSubmodules return an empty iterable\r
'''\r
- rs=[]\r
+ rs = []\r
rs.append(RequiredSubmodule(\r
"ArmPkg/Library/ArmSoftFloatLib/berkeley-softfloat-3", False))\r
rs.append(RequiredSubmodule(\r
"CryptoPkg/Library/OpensslLib/openssl", False))\r
+ rs.append(RequiredSubmodule(\r
+ "UnitTestFrameworkPkg/Library/CmockaLib/cmocka", False))\r
return rs\r
\r
def GetName(self):\r
return "Edk2"\r
\r
def GetDependencies(self):\r
- return []\r
+ return [\r
+ ]\r
\r
def GetPackagesPath(self):\r
return ()\r
\r
def FilterPackagesToTest(self, changedFilesList: list, potentialPackagesList: list) -> list:\r
''' Filter potential packages to test based on changed files. '''\r
- build_these_packages=[]\r
- possible_packages=potentialPackagesList.copy()\r
+ build_these_packages = []\r
+ possible_packages = potentialPackagesList.copy()\r
for f in changedFilesList:\r
- nodes=f.split("/") # split each part of path for comparison later\r
+ # split each part of path for comparison later\r
+ nodes = f.split("/")\r
\r
# python file change in .pytool folder causes building all\r
if f.endswith(".py") and ".pytool" in nodes:\r
overall_status += 1\r
\r
tc.LogStdOut("Tested Encoding on {0} files".format(files_tested))\r
- if overall_status is not 0:\r
+ if overall_status != 0:\r
tc.SetFailed("CharEncoding {0} Failed. Errors {1}".format(packagename, overall_status), "CHAR_ENCODING_CHECK_FAILED")\r
else:\r
tc.SetSuccess()\r
-# @file HostUnitTestCompiler_plugin.py\r
+# @file CompilerPlugin.py\r
##\r
# Copyright (c) Microsoft Corporation.\r
# SPDX-License-Identifier: BSD-2-Clause-Patent\r
return ["DEBUG", "RELEASE"]\r
\r
##\r
- # External function of plugin. This function is used to perform the task of the MuBuild Plugin\r
+ # External function of plugin. This function is used to perform the task of the ICiBuildPlugin Plugin\r
#\r
# - package is the edk2 path to package. This means workspace/packagepath relative.\r
# - edk2path object configured with workspace and packages path\r
overall_status += 1\r
\r
# If XML object exists, add results\r
- if overall_status is not 0:\r
+ if overall_status != 0:\r
tc.SetFailed("Failed with {0} errors".format(overall_status), "DEPENDENCYCHECK_FAILED")\r
else:\r
tc.SetSuccess()\r
# Parse the config for required DscPath element\r
if "DscPath" not in pkgconfig:\r
tc.SetSkipped()\r
- tc.LogStdError("DscPath not found in config file. Nothing to check.")\r
+ tc.LogStdError(\r
+ "DscPath not found in config file. Nothing to check.")\r
return -1\r
\r
- abs_pkg_path = Edk2pathObj.GetAbsolutePathOnThisSytemFromEdk2RelativePath(packagename)\r
+ abs_pkg_path = Edk2pathObj.GetAbsolutePathOnThisSytemFromEdk2RelativePath(\r
+ packagename)\r
abs_dsc_path = os.path.join(abs_pkg_path, pkgconfig["DscPath"].strip())\r
- wsr_dsc_path = Edk2pathObj.GetEdk2RelativePathFromAbsolutePath(abs_dsc_path)\r
+ wsr_dsc_path = Edk2pathObj.GetEdk2RelativePathFromAbsolutePath(\r
+ abs_dsc_path)\r
\r
if abs_dsc_path is None or wsr_dsc_path == "" or not os.path.isfile(abs_dsc_path):\r
tc.SetSkipped()\r
\r
# Get INF Files\r
INFFiles = self.WalkDirectoryForExtension([".inf"], abs_pkg_path)\r
- INFFiles = [Edk2pathObj.GetEdk2RelativePathFromAbsolutePath(x) for x in INFFiles] # make edk2relative path so can compare with DSC\r
+ INFFiles = [Edk2pathObj.GetEdk2RelativePathFromAbsolutePath(\r
+ x) for x in INFFiles] # make edk2relative path so can compare with DSC\r
\r
# remove ignores\r
\r
tc.LogStdOut("Ignoring INF {0}".format(a))\r
INFFiles.remove(a)\r
except:\r
- tc.LogStdError("DscCompleteCheck.IgnoreInf -> {0} not found in filesystem. Invalid ignore file".format(a))\r
- logging.info("DscCompleteCheck.IgnoreInf -> {0} not found in filesystem. Invalid ignore file".format(a))\r
+ tc.LogStdError(\r
+ "DscCompleteCheck.IgnoreInf -> {0} not found in filesystem. Invalid ignore file".format(a))\r
+ logging.info(\r
+ "DscCompleteCheck.IgnoreInf -> {0} not found in filesystem. Invalid ignore file".format(a))\r
\r
# DSC Parser\r
dp = DscParser()\r
infp.SetPackagePaths(Edk2pathObj.PackagePathList)\r
infp.ParseFile(INF)\r
if("MODULE_TYPE" not in infp.Dict):\r
- tc.LogStdOut("Ignoring INF. Missing key for MODULE_TYPE {0}".format(INF))\r
+ tc.LogStdOut(\r
+ "Ignoring INF. Missing key for MODULE_TYPE {0}".format(INF))\r
continue\r
\r
if(infp.Dict["MODULE_TYPE"] == "HOST_APPLICATION"):\r
- tc.LogStdOut("Ignoring INF. Module type is HOST_APPLICATION {0}".format(INF))\r
+ tc.LogStdOut(\r
+ "Ignoring INF. Module type is HOST_APPLICATION {0}".format(INF))\r
+ continue\r
+\r
+ if len(infp.SupportedPhases) == 1 and \\r
+ "HOST_APPLICATION" in infp.SupportedPhases:\r
+ tc.LogStdOut(\r
+ "Ignoring Library INF due to only supporting type HOST_APPLICATION {0}".format(INF))\r
continue\r
\r
logging.critical(INF + " not in " + wsr_dsc_path)\r
overall_status = overall_status + 1\r
\r
# If XML object exists, add result\r
- if overall_status is not 0:\r
- tc.SetFailed("DscCompleteCheck {0} Failed. Errors {1}".format(wsr_dsc_path, overall_status), "CHECK_FAILED")\r
+ if overall_status != 0:\r
+ tc.SetFailed("DscCompleteCheck {0} Failed. Errors {1}".format(\r
+ wsr_dsc_path, overall_status), "CHECK_FAILED")\r
else:\r
tc.SetSuccess()\r
return overall_status\r
much of the CI infrastructure assumes that all modules will be listed in the DSC\r
and compiled.\r
\r
+This test will ignore INFs in the following cases:\r
+\r
+1. When MODULE_TYPE = HOST_APPLICATION\r
+2. When a Library instance **only** supports the HOST_APPLICATION environment\r
+\r
## Configuration\r
\r
The plugin has a few configuration options to support the UEFI codebase.\r
``` yaml\r
"DscCompleteCheck": {\r
"DscPath": "", # Path to dsc from root of package\r
- "IgnoreInf": [] # Ignore INF if found in filesystem by not dsc\r
+ "IgnoreInf": [] # Ignore INF if found in filesystem but not dsc\r
}\r
```\r
\r
\r
# add result to test case\r
overall_status = len(Errors)\r
- if overall_status is not 0:\r
+ if overall_status != 0:\r
tc.SetFailed("GuidCheck {0} Failed. Errors {1}".format(\r
packagename, overall_status), "CHECK_FAILED")\r
else:\r
--- /dev/null
+# @file HostUnitTestCompilerPlugin.py\r
+##\r
+# Copyright (c) Microsoft Corporation.\r
+# SPDX-License-Identifier: BSD-2-Clause-Patent\r
+##\r
+\r
+import logging\r
+import os\r
+import re\r
+from edk2toollib.uefi.edk2.parsers.dsc_parser import DscParser\r
+from edk2toolext.environment.plugintypes.ci_build_plugin import ICiBuildPlugin\r
+from edk2toolext.environment.uefi_build import UefiBuilder\r
+from edk2toolext import edk2_logging\r
+from edk2toolext.environment.var_dict import VarDict\r
+from edk2toollib.utility_functions import GetHostInfo\r
+\r
+\r
+class HostUnitTestCompilerPlugin(ICiBuildPlugin):\r
+ """\r
+ A CiBuildPlugin that compiles the dsc for host based unit test apps.\r
+ An IUefiBuildPlugin may be attached to this plugin that will run the\r
+ unit tests and collect the results after successful compilation.\r
+\r
+ Configuration options:\r
+ "HostUnitTestCompilerPlugin": {\r
+ "DscPath": "<path to dsc from root of pkg>"\r
+ }\r
+ """\r
+\r
+ def GetTestName(self, packagename: str, environment: VarDict) -> tuple:\r
+ """ Provide the testcase name and classname for use in reporting\r
+ testclassname: a descriptive string for the testcase can include whitespace\r
+ classname: should be patterned <packagename>.<plugin>.<optionally any unique condition>\r
+\r
+ Args:\r
+ packagename: string containing name of package to build\r
+ environment: The VarDict for the test to run in\r
+ Returns:\r
+ a tuple containing the testcase name and the classname\r
+ (testcasename, classname)\r
+ """\r
+ num,types = self.__GetHostUnitTestArch(environment)\r
+ types = types.replace(" ", "_")\r
+\r
+ return ("Compile and Run Host-Based UnitTests for " + packagename + " on arch " + types,\r
+ packagename + ".HostUnitTestCompiler." + types)\r
+\r
+ def RunsOnTargetList(self):\r
+ return ["NOOPT"]\r
+\r
+ #\r
+ # Find the intersection of application types that can run on this host\r
+ # and the TARGET_ARCH being build in this request.\r
+ #\r
+ # return tuple with (number of UEFI arch types, space separated string)\r
+ def __GetHostUnitTestArch(self, environment):\r
+ requested = environment.GetValue("TARGET_ARCH").split(' ')\r
+ host = []\r
+ if GetHostInfo().arch == 'x86':\r
+ #assume 64bit can handle 64 and 32\r
+ #assume 32bit can only handle 32\r
+ ## change once IA32 issues resolved host.append("IA32")\r
+ if GetHostInfo().bit == '64':\r
+ host.append("X64")\r
+ elif GetHostInfo().arch == 'ARM':\r
+ if GetHostInfo().bit == '64':\r
+ host.append("AARCH64")\r
+ elif GetHostInfo().bit == '32':\r
+ host.append("ARM")\r
+\r
+ willrun = set(requested) & set(host)\r
+ return (len(willrun), " ".join(willrun))\r
+\r
+\r
+ ##\r
+ # External function of plugin. This function is used to perform the task of the ICiBuildPlugin Plugin\r
+ #\r
+ # - package is the edk2 path to package. This means workspace/packagepath relative.\r
+ # - edk2path object configured with workspace and packages path\r
+ # - PkgConfig Object (dict) for the pkg\r
+ # - EnvConfig Object\r
+ # - Plugin Manager Instance\r
+ # - Plugin Helper Obj Instance\r
+ # - Junit Logger\r
+ # - output_stream the StringIO output stream from this plugin via logging\r
+ def RunBuildPlugin(self, packagename, Edk2pathObj, pkgconfig, environment, PLM, PLMHelper, tc, output_stream=None):\r
+ self._env = environment\r
+ environment.SetValue("CI_BUILD_TYPE", "host_unit_test", "Set in HostUnitTestCompilerPlugin")\r
+\r
+ # Parse the config for required DscPath element\r
+ if "DscPath" not in pkgconfig:\r
+ tc.SetSkipped()\r
+ tc.LogStdError("DscPath not found in config file. Nothing to compile for HostBasedUnitTests.")\r
+ return -1\r
+\r
+ AP = Edk2pathObj.GetAbsolutePathOnThisSytemFromEdk2RelativePath(packagename)\r
+\r
+ APDSC = os.path.join(AP, pkgconfig["DscPath"].strip())\r
+ AP_Path = Edk2pathObj.GetEdk2RelativePathFromAbsolutePath(APDSC)\r
+ if AP is None or AP_Path is None or not os.path.isfile(APDSC):\r
+ tc.SetSkipped()\r
+ tc.LogStdError("Package HostBasedUnitTest Dsc not found.")\r
+ return -1\r
+\r
+ logging.info("Building {0}".format(AP_Path))\r
+ self._env.SetValue("ACTIVE_PLATFORM", AP_Path, "Set in Compiler Plugin")\r
+ num, RUNNABLE_ARCHITECTURES = self.__GetHostUnitTestArch(environment)\r
+ if(num == 0):\r
+ tc.SetSkipped()\r
+ tc.LogStdError("No host architecture compatibility")\r
+ return -1\r
+\r
+ if not environment.SetValue("TARGET_ARCH",\r
+ RUNNABLE_ARCHITECTURES,\r
+ "Update Target Arch based on Host Support"):\r
+ #use AllowOverride function since this is a controlled attempt to change\r
+ environment.AllowOverride("TARGET_ARCH")\r
+ if not environment.SetValue("TARGET_ARCH",\r
+ RUNNABLE_ARCHITECTURES,\r
+ "Update Target Arch based on Host Support"):\r
+ raise RuntimeError("Can't Change TARGET_ARCH as required")\r
+\r
+ # Parse DSC to check for SUPPORTED_ARCHITECTURES\r
+ dp = DscParser()\r
+ dp.SetBaseAbsPath(Edk2pathObj.WorkspacePath)\r
+ dp.SetPackagePaths(Edk2pathObj.PackagePathList)\r
+ dp.ParseFile(AP_Path)\r
+ if "SUPPORTED_ARCHITECTURES" in dp.LocalVars:\r
+ SUPPORTED_ARCHITECTURES = dp.LocalVars["SUPPORTED_ARCHITECTURES"].split('|')\r
+ TARGET_ARCHITECTURES = environment.GetValue("TARGET_ARCH").split(' ')\r
+\r
+ # Skip if there is no intersection between SUPPORTED_ARCHITECTURES and TARGET_ARCHITECTURES\r
+ if len(set(SUPPORTED_ARCHITECTURES) & set(TARGET_ARCHITECTURES)) == 0:\r
+ tc.SetSkipped()\r
+ tc.LogStdError("No supported architecutres to build for host unit tests")\r
+ return -1\r
+\r
+ uefiBuilder = UefiBuilder()\r
+ # do all the steps\r
+ # WorkSpace, PackagesPath, PInHelper, PInManager\r
+ ret = uefiBuilder.Go(Edk2pathObj.WorkspacePath, os.pathsep.join(Edk2pathObj.PackagePathList), PLMHelper, PLM)\r
+ if ret != 0: # failure:\r
+ tc.SetFailed("Compile failed for {0}".format(packagename), "Compile_FAILED")\r
+ tc.LogStdError("{0} Compile failed with error code {1} ".format(AP_Path, ret))\r
+ return 1\r
+\r
+ else:\r
+ tc.SetSuccess()\r
+ return 0\r
--- /dev/null
+##\r
+# CiBuildPlugin used to build anything that identifies\r
+# as a unit test.\r
+#\r
+# Copyright (c) Microsoft Corporation.\r
+# SPDX-License-Identifier: BSD-2-Clause-Patent\r
+##\r
+{\r
+ "scope": "host-based-test",\r
+ "name": "Host Unit Test Compiler Plugin",\r
+ "module": "HostUnitTestCompilerPlugin"\r
+}\r
--- /dev/null
+# Host UnitTest Compiler Plugin\r
+\r
+A CiBuildPlugin that compiles the dsc for host based unit test apps.\r
+An IUefiBuildPlugin may be attached to this plugin that will run the unit tests and collect the results after successful compilation.\r
+\r
+## Configuration\r
+\r
+The package relative path of the DSC file to build.\r
+\r
+``` yaml\r
+"HostUnitTestCompilerPlugin": {\r
+ "DscPath": "<path to dsc from root of pkg>"\r
+}\r
+```\r
+\r
+### DscPath\r
+\r
+Package relative path to the DSC file to build.\r
+\r
+## Copyright\r
+\r
+Copyright (c) Microsoft Corporation.\r
+SPDX-License-Identifier: BSD-2-Clause-Patent\r
+\r
--- /dev/null
+# @file HostUnitTestDscCompleteCheck.py\r
+#\r
+# This is a copy of DscCompleteCheck with different filtering logic.\r
+# It should be discussed if this should be one plugin\r
+#\r
+# Copyright (c) Microsoft Corporation.\r
+# SPDX-License-Identifier: BSD-2-Clause-Patent\r
+##\r
+import logging\r
+import os\r
+from edk2toolext.environment.plugintypes.ci_build_plugin import ICiBuildPlugin\r
+from edk2toollib.uefi.edk2.parsers.dsc_parser import DscParser\r
+from edk2toollib.uefi.edk2.parsers.inf_parser import InfParser\r
+from edk2toolext.environment.var_dict import VarDict\r
+\r
+\r
+class HostUnitTestDscCompleteCheck(ICiBuildPlugin):\r
+ """\r
+ A CiBuildPlugin that scans the package Host Unit Test dsc file and confirms all Host application modules (inf files) are\r
+ listed in the components sections.\r
+\r
+ Configuration options:\r
+ "HostUnitTestDscCompleteCheck": {\r
+ "DscPath": "", # Path to Host based unit test DSC file\r
+ "IgnoreInf": [] # Ignore INF if found in filesystem but not dsc\r
+ }\r
+ """\r
+\r
+ def GetTestName(self, packagename: str, environment: VarDict) -> tuple:\r
+ """ Provide the testcase name and classname for use in reporting\r
+\r
+ Args:\r
+ packagename: string containing name of package to build\r
+ environment: The VarDict for the test to run in\r
+ Returns:\r
+ a tuple containing the testcase name and the classname\r
+ (testcasename, classname)\r
+ testclassname: a descriptive string for the testcase can include whitespace\r
+ classname: should be patterned <packagename>.<plugin>.<optionally any unique condition>\r
+ """\r
+ return ("Check the " + packagename + " Host Unit Test DSC for a being complete", packagename + ".HostUnitTestDscCompleteCheck")\r
+\r
+ ##\r
+ # External function of plugin. This function is used to perform the task of the MuBuild Plugin\r
+ #\r
+ # - package is the edk2 path to package. This means workspace/packagepath relative.\r
+ # - edk2path object configured with workspace and packages path\r
+ # - PkgConfig Object (dict) for the pkg\r
+ # - VarDict containing the shell environment Build Vars\r
+ # - Plugin Manager Instance\r
+ # - Plugin Helper Obj Instance\r
+ # - Junit Logger\r
+ # - output_stream the StringIO output stream from this plugin via logging\r
+ def RunBuildPlugin(self, packagename, Edk2pathObj, pkgconfig, environment, PLM, PLMHelper, tc, output_stream=None):\r
+ overall_status = 0\r
+\r
+ # Parse the config for required DscPath element\r
+ if "DscPath" not in pkgconfig:\r
+ tc.SetSkipped()\r
+ tc.LogStdError(\r
+ "DscPath not found in config file. Nothing to check.")\r
+ return -1\r
+\r
+ abs_pkg_path = Edk2pathObj.GetAbsolutePathOnThisSytemFromEdk2RelativePath(\r
+ packagename)\r
+ abs_dsc_path = os.path.join(abs_pkg_path, pkgconfig["DscPath"].strip())\r
+ wsr_dsc_path = Edk2pathObj.GetEdk2RelativePathFromAbsolutePath(\r
+ abs_dsc_path)\r
+\r
+ if abs_dsc_path is None or wsr_dsc_path == "" or not os.path.isfile(abs_dsc_path):\r
+ tc.SetSkipped()\r
+ tc.LogStdError("Package Host Unit Test Dsc not found")\r
+ return 0\r
+\r
+ # Get INF Files\r
+ INFFiles = self.WalkDirectoryForExtension([".inf"], abs_pkg_path)\r
+ INFFiles = [Edk2pathObj.GetEdk2RelativePathFromAbsolutePath(\r
+ x) for x in INFFiles] # make edk2relative path so can compare with DSC\r
+\r
+ # remove ignores\r
+\r
+ if "IgnoreInf" in pkgconfig:\r
+ for a in pkgconfig["IgnoreInf"]:\r
+ a = a.replace(os.sep, "/")\r
+ try:\r
+ tc.LogStdOut("Ignoring INF {0}".format(a))\r
+ INFFiles.remove(a)\r
+ except:\r
+ tc.LogStdError(\r
+ "HostUnitTestDscCompleteCheck.IgnoreInf -> {0} not found in filesystem. Invalid ignore file".format(a))\r
+ logging.info(\r
+ "HostUnitTestDscCompleteCheck.IgnoreInf -> {0} not found in filesystem. Invalid ignore file".format(a))\r
+\r
+ # DSC Parser\r
+ dp = DscParser()\r
+ dp.SetBaseAbsPath(Edk2pathObj.WorkspacePath)\r
+ dp.SetPackagePaths(Edk2pathObj.PackagePathList)\r
+ dp.SetInputVars(environment.GetAllBuildKeyValues())\r
+ dp.ParseFile(wsr_dsc_path)\r
+\r
+ # Check if INF in component section\r
+ for INF in INFFiles:\r
+ if not any(INF.strip() in x for x in dp.ThreeMods) and \\r
+ not any(INF.strip() in x for x in dp.SixMods) and \\r
+ not any(INF.strip() in x for x in dp.OtherMods):\r
+\r
+ infp = InfParser().SetBaseAbsPath(Edk2pathObj.WorkspacePath)\r
+ infp.SetPackagePaths(Edk2pathObj.PackagePathList)\r
+ infp.ParseFile(INF)\r
+ if("MODULE_TYPE" not in infp.Dict):\r
+ tc.LogStdOut(\r
+ "Ignoring INF. Missing key for MODULE_TYPE {0}".format(INF))\r
+ continue\r
+\r
+ if(infp.Dict["MODULE_TYPE"] == "HOST_APPLICATION"):\r
+ # should compile test a library that is declared type HOST_APPLICATION\r
+ pass\r
+\r
+ elif len(infp.SupportedPhases) > 0 and \\r
+ "HOST_APPLICATION" in infp.SupportedPhases:\r
+ # should compile test a library that supports HOST_APPLICATION but\r
+ # require it to be an explicit opt-in\r
+ pass\r
+\r
+ else:\r
+ tc.LogStdOut(\r
+ "Ignoring INF. MODULE_TYPE or suppored phases not HOST_APPLICATION {0}".format(INF))\r
+ continue\r
+\r
+ logging.critical(INF + " not in " + wsr_dsc_path)\r
+ tc.LogStdError("{0} not in {1}".format(INF, wsr_dsc_path))\r
+ overall_status = overall_status + 1\r
+\r
+ # If XML object exists, add result\r
+ if overall_status != 0:\r
+ tc.SetFailed("HostUnitTestDscCompleteCheck {0} Failed. Errors {1}".format(\r
+ wsr_dsc_path, overall_status), "CHECK_FAILED")\r
+ else:\r
+ tc.SetSuccess()\r
+ return overall_status\r
--- /dev/null
+##\r
+# CiBuildPlugin used to confirm all INFs are listed in\r
+# the components section of package dsc\r
+#\r
+# Copyright (c) Microsoft Corporation.\r
+# SPDX-License-Identifier: BSD-2-Clause-Patent\r
+##\r
+{\r
+ "scope": "host-based-test",\r
+ "name": "Host Unit Test Dsc Complete Check Test",\r
+ "module": "HostUnitTestDscCompleteCheck"\r
+ }\r
--- /dev/null
+# Host Unit Test Dsc Complete Check Plugin\r
+\r
+This CiBuildPlugin scans all INF files from a package for those related to host\r
+based unit tests confirms they are listed in the unit test DSC file for the package.\r
+The test considers it an error if any INF meeting the requirements does not appear\r
+in the `Components` section of the unit test DSC. This is critical because\r
+much of the CI infrastructure assumes that modules will be listed in the DSC\r
+and compiled.\r
+\r
+This test will only require INFs in the following cases:\r
+\r
+1. When MODULE_TYPE = HOST_APPLICATION\r
+2. When a Library instance supports the HOST_APPLICATION environment\r
+\r
+## Configuration\r
+\r
+The plugin has a few configuration options to support the UEFI codebase.\r
+\r
+``` yaml\r
+"HostUnitTestDscCompleteCheck": {\r
+ "DscPath": "", # Path to Host based unit test DSC file\r
+ "IgnoreInf": [] # Ignore INF if found in filesystem but not dsc\r
+}\r
+```\r
+\r
+### DscPath\r
+\r
+Path to DSC to consider platform dsc\r
+\r
+### IgnoreInf\r
+\r
+Ignore error if Inf file is not listed in DSC file\r
\r
\r
# If XML object exists, add result\r
- if overall_status is not 0:\r
+ if overall_status != 0:\r
tc.SetFailed("LibraryClassCheck {0} Failed. Errors {1}".format(wsr_dec_path, overall_status), "CHECK_FAILED")\r
else:\r
tc.SetSuccess()\r