def test_dsc_include_single_file(self):
        ''' This tests whether includes work properly '''
        workspace = tempfile.mkdtemp()

        file1_name = "file1.dsc"
        file2_name = "file2.dsc"
        file1_path = os.path.join(workspace, file1_name)
        file2_path = os.path.join(workspace, file2_name)

        file1_data = f"!include {file2_name}"
        file2_data = "[Defines]\nINCLUDED = TRUE"

        TestDscParserIncludes.write_to_file(file1_path, file1_data)
        TestDscParserIncludes.write_to_file(file2_path, file2_data)

        parser = DscParser()
        parser.SetBaseAbsPath(workspace)
        parser.ParseFile(file1_path)

        # test to make sure we did it right
        self.assertEqual(len(parser.LocalVars),
                         1)  # make sure we only have one define
        self.assertEqual(parser.LocalVars["INCLUDED"],
                         "TRUE")  # make sure we got the defines
        self.assertEqual(len(parser.GetAllDscPaths()),
                         2)  # make sure we have two dsc paths
    def ParseDscFile(self):
        if self.env.GetValue("ACTIVE_PLATFORM") is None:
            logging.error(
                "The DSC file was not set. Please set ACTIVE_PLATFORM")
            return -1
        dsc_file_path = self.mws.join(self.ws,
                                      self.env.GetValue("ACTIVE_PLATFORM"))
        if (os.path.isfile(dsc_file_path)):
            # parse DSC File
            logging.debug(
                "Parse Active Platform DSC file: {0}".format(dsc_file_path))

            # Get the vars from the environment that are not build keys
            input_vars = self.env.GetAllNonBuildKeyValues()
            # Update with special environment set build keys
            input_vars.update(self.env.GetAllBuildKeyValues())

            dscp = DscParser().SetBaseAbsPath(self.ws).SetPackagePaths(
                self.pp.split(os.pathsep)).SetInputVars(input_vars)
            dscp.ParseFile(dsc_file_path)
            for key, value in dscp.LocalVars.items():
                # set env as overrideable
                self.env.SetValue(key, value, "From Platform DSC File", True)
        else:
            logging.error("Failed to find DSC file")
            return -1

        return 0
    def test_dsc_parse_file_on_package_path(self):
        ''' This tests whether includes work properly if no fail mode is on'''
        workspace = tempfile.mkdtemp()
        working_dir_name = "working"
        working2_dir_name = "working2"

        working_folder = os.path.join(workspace, working_dir_name)
        working2_folder = os.path.join(working_folder, working2_dir_name)
        os.makedirs(working_folder, exist_ok=True)
        os.makedirs(working2_folder, exist_ok=True)

        file1_name = "file1.dsc"
        file1_path = os.path.join(working2_folder, file1_name)
        file1_short_path = os.path.join(working2_dir_name, file1_name)
        file1_data = "[Defines]\n INCLUDED=TRUE"

        TestDscParserIncludes.write_to_file(file1_path, file1_data)
        with self.assertRaises(FileNotFoundError):
            parser = DscParser()
            parser.SetBaseAbsPath(workspace)
            parser.ParseFile(file1_short_path)

        parser = DscParser()
        parser.SetBaseAbsPath(workspace)
        parser.SetPackagePaths([
            working_folder,
        ])
        parser.ParseFile(file1_short_path)
        self.assertEqual(parser.LocalVars["INCLUDED"],
                         "TRUE")  # make sure we got the defines
    def test_dsc_include_missing_file(self):
        ''' This tests whether includes work properly '''
        workspace = tempfile.gettempdir()

        file1_name = "file1.dsc"
        file1_path = os.path.join(workspace, file1_name)

        file1_data = f"!include BAD_FILE.dsc"

        TestDscParserIncludes.write_to_file(file1_path, file1_data)

        parser = DscParser()
        parser.SetBaseAbsPath(workspace)
        with self.assertRaises(FileNotFoundError):
            parser.ParseFile(file1_path)
    def test_dsc_include_missing_file_no_fail_mode(self):
        ''' This tests whether includes work properly if no fail mode is on'''
        workspace = tempfile.mkdtemp()

        file1_name = "file1.dsc"
        file1_path = os.path.join(workspace, file1_name)

        file1_data = "!include BAD_FILE.dsc"

        TestDscParserIncludes.write_to_file(file1_path, file1_data)

        parser = DscParser()
        parser.SetNoFailMode()
        parser.SetBaseAbsPath(workspace)
        parser.ParseFile(file1_path)
示例#6
0
    def RunBuildPlugin(self, packagename, Edk2pathObj, pkgconfig, environment, PLM, PLMHelper, tc, output_stream=None):
        self._env = environment

        # 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.")
            return -1

        AP = Edk2pathObj.GetAbsolutePathOnThisSystemFromEdk2RelativePath(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 Dsc not found.")
            return -1

        logging.info("Building {0}".format(AP_Path))
        self._env.SetValue("ACTIVE_PLATFORM", AP_Path, "Set in Compiler Plugin")

        # 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")
                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
    def test_dsc_include_relative_path(self):
        ''' This tests whether includes work properly with a relative path'''
        workspace = tempfile.mkdtemp()
        outside_folder = os.path.join(workspace, "outside")
        inside_folder = os.path.join(outside_folder, "inside")
        inside2_folder = os.path.join(outside_folder, "inside2")
        random_folder = os.path.join(outside_folder, "random")
        os.makedirs(inside_folder, exist_ok=True)
        os.makedirs(inside2_folder, exist_ok=True)
        os.makedirs(random_folder, exist_ok=True)
        cwd = os.getcwd()
        os.chdir(random_folder)
        try:

            file1_name = "file1.dsc"
            file1_path = os.path.join(outside_folder, file1_name)

            file2_name = "file2.dsc"
            file2_path = os.path.join(inside_folder, file2_name)

            file3_name = "file3.dsc"
            file3_path = os.path.join(inside2_folder, file3_name)

            file1_data = "!include " + os.path.relpath(
                file2_path, os.path.dirname(file1_path)).replace("\\", "/")
            file2_data = "!include " + os.path.relpath(
                file3_path, os.path.dirname(file2_path)).replace("\\", "/")
            file3_data = "[Defines]\n INCLUDED=TRUE"

            print(f"{file1_path}: {file1_data}")
            print(f"{file2_path}: {file2_data}")
            print(f"{file3_path}: {file3_data}")

            TestDscParserIncludes.write_to_file(file1_path, file1_data)
            TestDscParserIncludes.write_to_file(file2_path, file2_data)
            TestDscParserIncludes.write_to_file(file3_path, file3_data)

            parser = DscParser()
            parser.SetBaseAbsPath(workspace)
            parser.ParseFile(file1_path)

            self.assertEqual(parser.LocalVars["INCLUDED"],
                             "TRUE")  # make sure we got the defines
        finally:
            os.chdir(cwd)
    def ParseDscFile(self):
        dsc_file_path = self.mws.join(self.ws,
                                      self.env.GetValue("ACTIVE_PLATFORM"))
        if (os.path.isfile(dsc_file_path)):
            # parse DSC File
            logging.debug(
                "Parse Active Platform DSC file: {0}".format(dsc_file_path))
            dscp = DscParser().SetBaseAbsPath(self.ws).SetPackagePaths(
                self.pp.split(os.pathsep)).SetInputVars(
                    self.env.GetAllBuildKeyValues())
            dscp.ParseFile(dsc_file_path)
            for key, value in dscp.LocalVars.items():
                # set env as overrideable
                self.env.SetValue(key, value, "From Platform DSC File", True)

        else:
            logging.error("Failed to find DSC file")
            return -1

        return 0
    def ParseFdfFile(self):
        if (self.env.GetValue("FLASH_DEFINITION") is None):
            logging.debug("No flash definition set")
            return 0
        if (os.path.isfile(
                self.mws.join(self.ws,
                              self.env.GetValue("FLASH_DEFINITION")))):
            # parse the FDF file- fdf files have similar syntax to DSC and therefore parser works for both.
            logging.debug("Parse Active Flash Definition (FDF) file")
            fdf_parser = DscParser().SetBaseAbsPath(self.ws).SetPackagePaths(
                self.pp.split(os.pathsep)).SetInputVars(
                    self.env.GetAllBuildKeyValues())
            pa = self.mws.join(self.ws, self.env.GetValue("FLASH_DEFINITION"))
            fdf_parser.ParseFile(pa)
            for key, value in fdf_parser.LocalVars.items():
                self.env.SetValue(key, value, "From Platform FDF File", True)

        else:
            logging.error("Failed to find FDF file")
            return -2

        return 0
 def test_dsc_to_file_and_back_again(self):
     filepath = self.write_file("test.dsc", self.test_dsc)
     print(filepath)
     # parse the original DSC
     parser = DscParser()
     parser._ErrorLimit = 0
     # NEXTVER: actually parse the file
     dsc_obj = []  # parser.ParseFile(filepath)
     # Write out to disk
     test_path = os.path.join(os.path.dirname(filepath), "test2.dsc")
     DscTranslator.dsc_to_file(dsc_obj, test_path)
     # parse in the outputted DSC
     parser2 = DscParser()
     parser2._ErrorLimit = 0
     print(test_path)
示例#11
0
    def RunBuildPlugin(self,
                       packagename,
                       Edk2pathObj,
                       pkgconfig,
                       environment,
                       PLM,
                       PLMHelper,
                       tc,
                       output_stream=None):
        overall_status = 0

        # Parse the config for required DscPath element
        if "DscPath" not in pkgconfig:
            tc.SetSkipped()
            tc.LogStdError(
                "DscPath not found in config file.  Nothing to check.")
            return -1

        abs_pkg_path = Edk2pathObj.GetAbsolutePathOnThisSytemFromEdk2RelativePath(
            packagename)
        abs_dsc_path = os.path.join(abs_pkg_path, pkgconfig["DscPath"].strip())
        wsr_dsc_path = Edk2pathObj.GetEdk2RelativePathFromAbsolutePath(
            abs_dsc_path)

        if abs_dsc_path is None or wsr_dsc_path == "" or not os.path.isfile(
                abs_dsc_path):
            tc.SetSkipped()
            tc.LogStdError("Package Host Unit Test Dsc not found")
            return 0

        # Get INF Files
        INFFiles = self.WalkDirectoryForExtension([".inf"], abs_pkg_path)
        INFFiles = [
            Edk2pathObj.GetEdk2RelativePathFromAbsolutePath(x)
            for x in INFFiles
        ]  # make edk2relative path so can compare with DSC

        # remove ignores

        if "IgnoreInf" in pkgconfig:
            for a in pkgconfig["IgnoreInf"]:
                a = a.replace(os.sep, "/")
                try:
                    tc.LogStdOut("Ignoring INF {0}".format(a))
                    INFFiles.remove(a)
                except:
                    tc.LogStdError(
                        "HostUnitTestDscCompleteCheck.IgnoreInf -> {0} not found in filesystem.  Invalid ignore file"
                        .format(a))
                    logging.info(
                        "HostUnitTestDscCompleteCheck.IgnoreInf -> {0} not found in filesystem.  Invalid ignore file"
                        .format(a))

        # DSC Parser
        dp = DscParser()
        dp.SetBaseAbsPath(Edk2pathObj.WorkspacePath)
        dp.SetPackagePaths(Edk2pathObj.PackagePathList)
        dp.SetInputVars(environment.GetAllBuildKeyValues())
        dp.ParseFile(wsr_dsc_path)

        # Check if INF in component section
        for INF in INFFiles:
            if not any(INF.strip() in x for x in dp.ThreeMods) and \
               not any(INF.strip() in x for x in dp.SixMods) and \
               not any(INF.strip() in x for x in dp.OtherMods):

                infp = InfParser().SetBaseAbsPath(Edk2pathObj.WorkspacePath)
                infp.SetPackagePaths(Edk2pathObj.PackagePathList)
                infp.ParseFile(INF)
                if ("MODULE_TYPE" not in infp.Dict):
                    tc.LogStdOut(
                        "Ignoring INF. Missing key for MODULE_TYPE {0}".format(
                            INF))
                    continue

                if (infp.Dict["MODULE_TYPE"] == "HOST_APPLICATION"):
                    # should compile test a library that is declared type HOST_APPLICATION
                    pass

                elif len(infp.SupportedPhases) > 0 and \
                        "HOST_APPLICATION" in infp.SupportedPhases:
                    # should compile test a library that supports HOST_APPLICATION but
                    # require it to be an explicit opt-in
                    pass

                else:
                    tc.LogStdOut(
                        "Ignoring INF. MODULE_TYPE or suppored phases not HOST_APPLICATION {0}"
                        .format(INF))
                    continue

                logging.critical(INF + " not in " + wsr_dsc_path)
                tc.LogStdError("{0} not in {1}".format(INF, wsr_dsc_path))
                overall_status = overall_status + 1

        # If XML object exists, add result
        if overall_status != 0:
            tc.SetFailed(
                "HostUnitTestDscCompleteCheck {0} Failed.  Errors {1}".format(
                    wsr_dsc_path, overall_status), "CHECK_FAILED")
        else:
            tc.SetSuccess()
        return overall_status
    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
示例#13
0
    def do_pre_build(self, thebuilder):
        try:
            error_count = 0
            '''
            # this scans the whole build directory for bmp's
            bmp_search_path = os.path.join(thebuilder.ws,"**","*.bmp");
            for found_item in glob.iglob(bmp_search_path, recursive=True):
              if CheckBmp(found_item):
                logging.error("{} failed image check".format(found_item))
                error_count += 1
            return error_count
            '''

            fp = FdfParser()
            dp = DscParser()

            ws = thebuilder.ws
            pp = thebuilder.pp.split(";")
            edk2 = Edk2Path(ws, pp)

            ActiveDsc = edk2.GetAbsolutePathOnThisSystemFromEdk2RelativePath(
                thebuilder.env.GetValue("ACTIVE_PLATFORM"))
            ActiveFdf = edk2.GetAbsolutePathOnThisSystemFromEdk2RelativePath(
                thebuilder.env.GetValue("FLASH_DEFINITION"))

            if ActiveFdf is None:
                self.logger.info("No FDF found- BMP check skipped")
                return 0
            # parse the DSC and the FDF
            dp.SetBaseAbsPath(ws).SetPackagePaths(pp)
            dp.SetInputVars(thebuilder.env.GetAllBuildKeyValues()).ParseFile(
                ActiveDsc)  # parse the DSC for build vars
            fp.SetBaseAbsPath(ws).SetPackagePaths(pp)
            fp.SetInputVars(dp.LocalVars).ParseFile(
                ActiveFdf)  # give FDF parser the vars from DSC

            # for each FV section in the DSC
            for FV_name in fp.FVs:
                FV_files = fp.FVs[FV_name]["Files"]
                # now look for images in each file of this FV
                for fv_file_name in FV_files:
                    fv_file = FV_files[fv_file_name]
                    if fv_file["type"].upper() != 'FREEFORM':
                        continue
                    fv_file_raw = fv_file['RAW']
                    fv_file_raw_list = []
                    if isinstance(fv_file_raw, list):
                        fv_file_raw_list = fv_file_raw
                    else:
                        fv_file_raw_list.append(fv_file_raw)
                    # for each file that is RAW type
                    for fv_file_raw_item in fv_file_raw_list:
                        # check if it ends with a bmp
                        if fv_file_raw_item.lower().endswith(".bmp"):
                            logging.debug(fv_file_raw_item)
                            BmpFilePath = edk2.GetAbsolutePathOnThisSystemFromEdk2RelativePath(
                                fv_file_raw_item)
                            logging.debug(BmpFilePath)
                            if BmpCheckPlugin.CheckBmp(
                                    BmpFilePath):  # do the check
                                self.logger.error(
                                    "{} failed image check".format(
                                        fv_file_raw_item))
                                error_count += 1
            return error_count
        except:
            self.logger.warning(
                "Unable to read the FDF. Please update your Edk2-Pytools-* Packages"
            )
            return 0
 def test_creation(self):
     a = DscParser()
     self.assertNotEqual(a, None)
示例#15
0
    def get_packages_to_build(self, possible_packages: list) -> dict:
        self.parsed_dec_cache = {}
        (rc, files) = self._get_files_that_changed_in_this_pr(self.pr_target)
        if rc != 0:
            return {}

        remaining_packages = possible_packages.copy(
        )  # start with all possible packages and remove each
        # package once it is determined to be build.  This optimization
        # avoids checking packages that already will be built.

        packages_to_build = {
        }  # packages to build.  Key = pkg name, Value = 1st reason for build

        #
        # Policy 1 - CI Settings file defined
        #
        after = self.PlatformSettings.FilterPackagesToTest(
            files, remaining_packages)
        for a in after:
            if a not in remaining_packages:
                raise ValueError(
                    f"PlatformSettings.FilterPackagesToTest returned package not allowed {a}"
                )
            packages_to_build[
                a] = "Policy 1 - PlatformSettings - Filter Packages"
            remaining_packages.remove(a)

        #
        # Policy 2: Build any package that has changed
        #
        for f in files:
            try:
                pkg = self.edk2_path_obj.GetContainingPackage(
                    os.path.abspath(f))

            except Exception as e:
                self.logger.error(
                    f"Failed to get package for file {f}.  Exception {e}")
                # Ignore a file in which we fail to get the package
                continue

            if (pkg not in packages_to_build.keys()
                    and pkg in remaining_packages):
                packages_to_build[
                    pkg] = "Policy 2 - Build any package that has changed"
                remaining_packages.remove(pkg)

        #
        # Policy 3: If a file change is a public file then build all packages that
        #           are dependent on that package.
        #

        # list of packages with public files that have changed
        public_package_changes = []

        # Get all public files in packages
        for f in files:
            try:
                pkg = self.edk2_path_obj.GetContainingPackage(
                    os.path.abspath(f))

            except Exception as e:
                self.logger.error(
                    f"Failed to get package for file {f}.  Exception {e}")
                # Ignore a file in which we fail to get the package
                continue

            if self._is_public_file(f):
                public_package_changes.append(pkg)
        # de-duplicate list
        public_package_changes = list(set(public_package_changes))

        # Now check all remaining packages to see if they depend on the set of packages
        # with public file changes.
        # NOTE: future enhancement could be to check actual file dependencies
        for a in public_package_changes:
            for p in remaining_packages[:]:  # slice so we can delete as we go
                if (self._does_pkg_depend_on_package(p, a)):
                    packages_to_build[p] = f"Policy 3 - Package depends on {a}"
                    remaining_packages.remove(
                        p)  # remove from remaining packages

        #
        # Policy 4: If a file changed in a module and that module is used in the provided dsc file
        # then the package of the dSC file must be built
        #
        PlatformDscInfo = self.PlatformSettings.GetPlatformDscAndConfig()
        if PlatformDscInfo is not None and len(remaining_packages) > 0:
            if len(remaining_packages) != 1:
                raise Exception(
                    "Policy 4 can only be used by builds for a single package")

            # files are all the files changed edk2 workspace root relative path
            changed_modules = self._get_unique_module_infs_changed(files)

            # now check DSC
            dsc = DscParser()
            dsc.SetBaseAbsPath(self.edk2_path_obj.WorkspacePath)
            dsc.SetPackagePaths(self.edk2_path_obj.PackagePathList)
            dsc.SetInputVars(PlatformDscInfo[1])
            dsc.ParseFile(PlatformDscInfo[0])
            allinfs = dsc.OtherMods + dsc.ThreeMods + dsc.SixMods + dsc.Libs  # get list of all INF files

            #
            # Note: for now we assume that remaining_packages has only 1 package and that it corresponds
            # to the DSC file provided.
            #
            for p in remaining_packages[:]:  # slice so we can delete as we go
                for cm in changed_modules:
                    if cm in allinfs:  # is the changed module listed in the DSC file?
                        packages_to_build[
                            p] = f"Policy 4 - Package Dsc depends on {cm}"
                        remaining_packages.remove(
                            p)  # remove from remaining packages
                        break

        return packages_to_build
示例#16
0
    def do_post_build(self, thebuilder):

        starttime = datetime.now()
        logging.info(
            "---------------------------------------------------------")
        logging.info(
            "-----------Postbuild Image Validation Starting-----------")
        logging.info(
            "---------------------------------------------------------")

        # Load Configuration Data
        config_path = thebuilder.env.GetValue("PE_VALIDATION_PATH", None)
        tool_chain_tag = thebuilder.env.GetValue("TOOL_CHAIN_TAG")
        if config_path is None:
            logging.info(
                "PE_VALIDATION_PATH not set, PE Image Validation Skipped")
            return 0  # Path not set, Plugin skipped

        if not os.path.isfile(config_path):
            logging.error("Invalid PE_VALIDATION_PATH. File not Found")
            return 1

        with open(config_path) as jsonfile:
            config_data = json.load(jsonfile)

        self.test_manager.config_data = config_data
        self.config_data = config_data
        self.ignore_list = config_data["IGNORE_LIST"]
        self.arch_dict = config_data["TARGET_ARCH"]

        count = 0

        # Start Pre-Compiled Image Verification
        fdf_parser = FdfParser()
        dsc_parser = DscParser()

        ws = thebuilder.ws
        pp = thebuilder.pp.split(os.pathsep)
        edk2 = Edk2Path(ws, pp)

        ActiveDsc = edk2.GetAbsolutePathOnThisSystemFromEdk2RelativePath(
            thebuilder.env.GetValue("ACTIVE_PLATFORM"))
        ActiveFdf = edk2.GetAbsolutePathOnThisSystemFromEdk2RelativePath(
            thebuilder.env.GetValue("FLASH_DEFINITION"))

        if ActiveFdf is None:
            logging.info("No FDF found - PE Image Validation skipped")
            return 0

        # parse the DSC and the FDF
        dsc_parser.SetBaseAbsPath(ws).SetPackagePaths(pp)
        dsc_parser.SetInputVars(
            thebuilder.env.GetAllBuildKeyValues()).ParseFile(
                ActiveDsc)  # parse the DSC for build vars
        fdf_parser.SetBaseAbsPath(ws).SetPackagePaths(pp)
        fdf_parser.SetInputVars(dsc_parser.LocalVars).ParseFile(
            ActiveFdf)  # give FDF parser the vars from DSC

        # Test all pre-compiled efis described in the fdf
        result = Result.PASS
        for FV_name in fdf_parser.FVs:  # Get all Firmware volumes
            FV_files = fdf_parser.FVs[FV_name]["Files"]
            for fv_file_name in FV_files:  # Iterate over each file in the firmware volume
                fv_file = FV_files[fv_file_name]
                if "PE32" in fv_file:  # Any PE32 section in the FV contains a path to the efi
                    # could have multiple PE32 sections
                    for efi_path in fv_file["PE32"]:
                        efi_path = self._resolve_vars(thebuilder, efi_path)
                        efi_path = edk2.GetAbsolutePathOnThisSystemFromEdk2RelativePath(
                            efi_path)
                        if efi_path == None:
                            logging.warn(
                                "Unable to parse the path to the pre-compiled efi"
                            )
                            continue
                        if os.path.basename(efi_path) in self.ignore_list:
                            continue
                        logging.info(
                            f'Performing Image Verification ... {os.path.basename(efi_path)}'
                        )
                        if self._validate_image(
                                efi_path, fv_file["type"]) == Result.FAIL:
                            result = Result.FAIL
                        count += 1
        # End Pre-Compiled Image Verification

        # Start Build Time Compiled Image Verification
        result = Result.PASS
        for arch in thebuilder.env.GetValue("TARGET_ARCH").split():
            efi_path_list = self._walk_directory_for_extension(
                ['.efi'],
                f'{thebuilder.env.GetValue("BUILD_OUTPUT_BASE")}/{arch}')

            for efi_path in efi_path_list:
                if os.path.basename(efi_path) in self.ignore_list:
                    continue

                # Perform Image Verification on any output efi's
                # Grab profile from makefile
                if efi_path.__contains__("OUTPUT"):
                    try:
                        if tool_chain_tag.__contains__("VS"):
                            profile = self._get_profile_from_makefile(
                                f'{Path(efi_path).parent.parent}/Makefile')

                        elif tool_chain_tag.__contains__("GCC"):
                            profile = self._get_profile_from_makefile(
                                f'{Path(efi_path).parent.parent}/GNUmakefile')

                        elif tool_chain_tag.__contains__("CLANG"):
                            profile = self._get_profile_from_makefile(
                                f'{Path(efi_path).parent.parent}/GNUmakefile')
                        else:
                            logging.warn(
                                "Unexpected TOOL_CHAIN_TAG... Cannot parse makefile. Using DEFAULT profile."
                            )
                            profile = "DEFAULT"
                    except:
                        logging.warn(
                            f'Failed to parse makefile at [{Path(efi_path).parent.parent}/GNUmakefile]'
                        )
                        logging.warn(f'Using DEFAULT profile')
                        profile = "DEFAULT"

                    logging.info(
                        f'Performing Image Verification ... {os.path.basename(efi_path)}'
                    )
                    if self._validate_image(efi_path, profile) == Result.FAIL:
                        result = Result.FAIL
                    count += 1
        # End Built Time Compiled Image Verification

        endtime = datetime.now()
        delta = endtime - starttime
        logging.info(
            "---------------------------------------------------------")
        logging.info(
            "-----------Postbuild Image Validation Finished-----------")
        logging.info(
            "------------------{:04d} Images Verified-------------------".
            format(count))
        logging.info(
            "-------------- Running Time (mm:ss): {0[0]:02}:{0[1]:02} --------------"
            .format(divmod(delta.seconds, 60)))
        logging.info(
            "---------------------------------------------------------")

        if result == Result.FAIL:
            return 1
        else:
            return 0