diff options
Diffstat (limited to 'src/VBox/Devices/EFI/Firmware/.pytool/Plugin/HostUnitTestCompilerPlugin')
3 files changed, 185 insertions, 0 deletions
diff --git a/src/VBox/Devices/EFI/Firmware/.pytool/Plugin/HostUnitTestCompilerPlugin/HostUnitTestCompilerPlugin.py b/src/VBox/Devices/EFI/Firmware/.pytool/Plugin/HostUnitTestCompilerPlugin/HostUnitTestCompilerPlugin.py new file mode 100755 index 00000000..eaf1beb2 --- /dev/null +++ b/src/VBox/Devices/EFI/Firmware/.pytool/Plugin/HostUnitTestCompilerPlugin/HostUnitTestCompilerPlugin.py @@ -0,0 +1,149 @@ +# @file HostUnitTestCompilerPlugin.py +## +# Copyright (c) Microsoft Corporation. +# SPDX-License-Identifier: BSD-2-Clause-Patent +## + +import logging +import os +import re +from edk2toollib.uefi.edk2.parsers.dsc_parser import DscParser +from edk2toolext.environment.plugintypes.ci_build_plugin import ICiBuildPlugin +from edk2toolext.environment.uefi_build import UefiBuilder +from edk2toolext import edk2_logging +from edk2toolext.environment.var_dict import VarDict +from edk2toollib.utility_functions import GetHostInfo + + +class HostUnitTestCompilerPlugin(ICiBuildPlugin): + """ + A CiBuildPlugin that compiles the dsc for host based unit test apps. + An IUefiBuildPlugin may be attached to this plugin that will run the + unit tests and collect the results after successful compilation. + + Configuration options: + "HostUnitTestCompilerPlugin": { + "DscPath": "<path to dsc from root of pkg>" + } + """ + + def GetTestName(self, packagename: str, environment: VarDict) -> tuple: + """ Provide the testcase name and classname for use in reporting + testclassname: a descriptive string for the testcase can include whitespace + classname: should be patterned <packagename>.<plugin>.<optionally any unique condition> + + Args: + packagename: string containing name of package to build + environment: The VarDict for the test to run in + Returns: + a tuple containing the testcase name and the classname + (testcasename, classname) + """ + num,types = self.__GetHostUnitTestArch(environment) + types = types.replace(" ", "_") + + return ("Compile and Run Host-Based UnitTests for " + packagename + " on arch " + types, + packagename + ".HostUnitTestCompiler." + types) + + def RunsOnTargetList(self): + return ["NOOPT"] + + # + # Find the intersection of application types that can run on this host + # and the TARGET_ARCH being build in this request. + # + # return tuple with (number of UEFI arch types, space separated string) + def __GetHostUnitTestArch(self, environment): + requested = environment.GetValue("TARGET_ARCH").split(' ') + host = [] + if GetHostInfo().arch == 'x86': + #assume 64bit can handle 64 and 32 + #assume 32bit can only handle 32 + ## change once IA32 issues resolved host.append("IA32") + if GetHostInfo().bit == '64': + host.append("X64") + elif GetHostInfo().arch == 'ARM': + if GetHostInfo().bit == '64': + host.append("AARCH64") + elif GetHostInfo().bit == '32': + host.append("ARM") + + willrun = set(requested) & set(host) + return (len(willrun), " ".join(willrun)) + + + ## + # External function of plugin. This function is used to perform the task of the ICiBuildPlugin Plugin + # + # - package is the edk2 path to package. This means workspace/packagepath relative. + # - edk2path object configured with workspace and packages path + # - PkgConfig Object (dict) for the pkg + # - EnvConfig Object + # - Plugin Manager Instance + # - Plugin Helper Obj Instance + # - Junit Logger + # - output_stream the StringIO output stream from this plugin via logging + def RunBuildPlugin(self, packagename, Edk2pathObj, pkgconfig, environment, PLM, PLMHelper, tc, output_stream=None): + self._env = environment + environment.SetValue("CI_BUILD_TYPE", "host_unit_test", "Set in HostUnitTestCompilerPlugin") + + # Parse the config for required DscPath element + if "DscPath" not in pkgconfig: + tc.SetSkipped() + tc.LogStdError("DscPath not found in config file. Nothing to compile for HostBasedUnitTests.") + return -1 + + AP = Edk2pathObj.GetAbsolutePathOnThisSytemFromEdk2RelativePath(packagename) + + APDSC = os.path.join(AP, pkgconfig["DscPath"].strip()) + AP_Path = Edk2pathObj.GetEdk2RelativePathFromAbsolutePath(APDSC) + if AP is None or AP_Path is None or not os.path.isfile(APDSC): + tc.SetSkipped() + tc.LogStdError("Package HostBasedUnitTest Dsc not found.") + return -1 + + logging.info("Building {0}".format(AP_Path)) + self._env.SetValue("ACTIVE_PLATFORM", AP_Path, "Set in Compiler Plugin") + num, RUNNABLE_ARCHITECTURES = self.__GetHostUnitTestArch(environment) + if(num == 0): + tc.SetSkipped() + tc.LogStdError("No host architecture compatibility") + return -1 + + if not environment.SetValue("TARGET_ARCH", + RUNNABLE_ARCHITECTURES, + "Update Target Arch based on Host Support"): + #use AllowOverride function since this is a controlled attempt to change + environment.AllowOverride("TARGET_ARCH") + if not environment.SetValue("TARGET_ARCH", + RUNNABLE_ARCHITECTURES, + "Update Target Arch based on Host Support"): + raise RuntimeError("Can't Change TARGET_ARCH as required") + + # Parse DSC to check for SUPPORTED_ARCHITECTURES + dp = DscParser() + dp.SetBaseAbsPath(Edk2pathObj.WorkspacePath) + dp.SetPackagePaths(Edk2pathObj.PackagePathList) + dp.ParseFile(AP_Path) + if "SUPPORTED_ARCHITECTURES" in dp.LocalVars: + SUPPORTED_ARCHITECTURES = dp.LocalVars["SUPPORTED_ARCHITECTURES"].split('|') + TARGET_ARCHITECTURES = environment.GetValue("TARGET_ARCH").split(' ') + + # Skip if there is no intersection between SUPPORTED_ARCHITECTURES and TARGET_ARCHITECTURES + if len(set(SUPPORTED_ARCHITECTURES) & set(TARGET_ARCHITECTURES)) == 0: + tc.SetSkipped() + tc.LogStdError("No supported architecutres to build for host unit tests") + return -1 + + uefiBuilder = UefiBuilder() + # do all the steps + # WorkSpace, PackagesPath, PInHelper, PInManager + ret = uefiBuilder.Go(Edk2pathObj.WorkspacePath, os.pathsep.join(Edk2pathObj.PackagePathList), PLMHelper, PLM) + if ret != 0: # failure: + tc.SetFailed("Compile failed for {0}".format(packagename), "Compile_FAILED") + tc.LogStdError("{0} Compile failed with error code {1} ".format(AP_Path, ret)) + return 1 + + else: + tc.SetSuccess() + return 0 diff --git a/src/VBox/Devices/EFI/Firmware/.pytool/Plugin/HostUnitTestCompilerPlugin/HostUnitTestCompiler_plug_in.yaml b/src/VBox/Devices/EFI/Firmware/.pytool/Plugin/HostUnitTestCompilerPlugin/HostUnitTestCompiler_plug_in.yaml new file mode 100644 index 00000000..dea9b056 --- /dev/null +++ b/src/VBox/Devices/EFI/Firmware/.pytool/Plugin/HostUnitTestCompilerPlugin/HostUnitTestCompiler_plug_in.yaml @@ -0,0 +1,12 @@ +## +# CiBuildPlugin used to build anything that identifies +# as a unit test. +# +# Copyright (c) Microsoft Corporation. +# SPDX-License-Identifier: BSD-2-Clause-Patent +## +{ + "scope": "host-based-test", + "name": "Host Unit Test Compiler Plugin", + "module": "HostUnitTestCompilerPlugin" +} diff --git a/src/VBox/Devices/EFI/Firmware/.pytool/Plugin/HostUnitTestCompilerPlugin/Readme.md b/src/VBox/Devices/EFI/Firmware/.pytool/Plugin/HostUnitTestCompilerPlugin/Readme.md new file mode 100644 index 00000000..f0def4c5 --- /dev/null +++ b/src/VBox/Devices/EFI/Firmware/.pytool/Plugin/HostUnitTestCompilerPlugin/Readme.md @@ -0,0 +1,24 @@ +# Host UnitTest Compiler Plugin + +A CiBuildPlugin that compiles the dsc for host based unit test apps. +An IUefiBuildPlugin may be attached to this plugin that will run the unit tests and collect the results after successful compilation. + +## Configuration + +The package relative path of the DSC file to build. + +``` yaml +"HostUnitTestCompilerPlugin": { + "DscPath": "<path to dsc from root of pkg>" +} +``` + +### DscPath + +Package relative path to the DSC file to build. + +## Copyright + +Copyright (c) Microsoft Corporation. +SPDX-License-Identifier: BSD-2-Clause-Patent + |