diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml new file mode 100644 index 00000000..a132d0a9 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -0,0 +1,64 @@ +name: Bug Report +description: File a bug report +title: "[Bug]: " +labels: ["new", "bug"] + +body: + - type: markdown + attributes: + value: Thanks for taking the time to file this bug! + - type: input + id: contact + attributes: + label: Contact Details + description: "How can we get in touch with you if we need more info?" + placeholder: ex. email@example.com + validations: + required: false + - type: textarea + id: bug-description + attributes: + label: Describe the Bug + description: "A clear and concise description of what the bug is." + validations: + required: true + - type: textarea + id: repro + attributes: + label: Reproduction steps + description: "How did you find this bug? Walk us through it step by step." + placeholder: | + 1. + 2. + 3. + ... + validations: + required: true + - type: textarea + id: expected-behavior + attributes: + label: Expected behavior + description: "A clear and concise description of what you expected to happen." + validations: + required: true + - type: textarea + id: env + attributes: + label: Execution Environment + description: "List the OS, python version, system environment variables, etc." + validations: + required: false + - type: textarea + id: pip + attributes: + label: Pip packages + description: "If python related, run 'python -m pip list' and copy the output here." + validations: + required: false + - type: textarea + id: context + attributes: + label: Additional context + description: "Any other additional context about the problem not covered by the above." + validations: + required: false diff --git a/.github/ISSUE_TEMPLATE/feature_request.yml b/.github/ISSUE_TEMPLATE/feature_request.yml new file mode 100644 index 00000000..da91eddd --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.yml @@ -0,0 +1,38 @@ +name: Feature Request +description: Submit a feature request +title: "[Feature]: " +labels: ["new", "enhancement"] + +body: + - type: markdown + attributes: + value: Thanks for suggesting an idea for this project! + - type: textarea + id: description + attributes: + label: What does the feature solve? + description: "Is your feature request related to a problem?" + placeholder: "Ex. I'm always frustrated when..." + validations: + required: true + - type: textarea + id: solution + attributes: + label: Describe the solution + description: "A clear and concise description of what you want to happen" + validations: + required: true + - type: textarea + id: alternative + attributes: + label: Have you considered any alternatives? + description: "A clear and concise description of any alternative solutions, features, or workarounds you've considered" + validations: + required: false + - type: textarea + id: context + attributes: + label: Additional context + description: "Any other additional context about the problem not covered by the above." + validations: + required: false diff --git a/edk2basetools/Common/Expression.py b/edk2basetools/Common/Expression.py index d76e0da3..c81125ff 100644 --- a/edk2basetools/Common/Expression.py +++ b/edk2basetools/Common/Expression.py @@ -1026,7 +1026,7 @@ def __call__(self, RealValue=False, Depth=0): Size += ItemSize if Size > 0: - PcdValue = '{' + ','.join(AllPcdValueList) + '}' + PcdValue = '{' + ', '.join(AllPcdValueList) + '}' else: raise BadExpression("Type: %s, Value: %s, %s"%(self.PcdType, PcdValue, Value)) diff --git a/edk2basetools/Common/VpdInfoFile.py b/edk2basetools/Common/VpdInfoFile.py index b8ea39de..7cc524b6 100644 --- a/edk2basetools/Common/VpdInfoFile.py +++ b/edk2basetools/Common/VpdInfoFile.py @@ -248,8 +248,8 @@ def CallExtenalBPDGTool(ToolPath, VpdFileName): PopenObject.wait() if PopenObject.returncode != 0: - EdkLogger.debug(EdkLogger.DEBUG_1, "Fail to call BPDG tool", str(error)) + EdkLogger.debug(EdkLogger.DEBUG_1, "Fail to call BPDG tool", str(error.decode())) EdkLogger.error("BPDG", BuildToolError.COMMAND_FAILURE, "Fail to execute BPDG tool with exit code: %d, the error message is: \n %s" % \ - (PopenObject.returncode, str(error))) + (PopenObject.returncode, str(error.decode()))) return PopenObject.returncode diff --git a/edk2basetools/CommonDataClass/FdfClass.py b/edk2basetools/CommonDataClass/FdfClass.py index 8e70121f..bd021d65 100644 --- a/edk2basetools/CommonDataClass/FdfClass.py +++ b/edk2basetools/CommonDataClass/FdfClass.py @@ -190,6 +190,18 @@ def __init__(self): self.FvParentAddr = None self.IncludeFvSection = False +## SubType GUID section data in FDF +# +# +class SubTypeGuidSectionClassObject (SectionClassObject) : + ## The constructor + # + # @param self The object pointer + # + def __init__(self): + SectionClassObject.__init__(self) + self.SubTypeGuid = None + ## UI section data in FDF # # diff --git a/edk2basetools/Ecc/EccToolError.py b/edk2basetools/Ecc/EccToolError.py index 7765f0e5..109f099a 100644 --- a/edk2basetools/Ecc/EccToolError.py +++ b/edk2basetools/Ecc/EccToolError.py @@ -186,7 +186,7 @@ ERROR_META_DATA_FILE_CHECK_BINARY_INF_IN_FDF : "An INF file is specified in the FDF file, but not in the DSC file, therefore the INF file must be for a Binary module only", ERROR_META_DATA_FILE_CHECK_PCD_DUPLICATE : "Duplicate PCDs found", ERROR_META_DATA_FILE_CHECK_PCD_FLASH : "PCD settings in the FDF file should only be related to flash", - ERROR_META_DATA_FILE_CHECK_PCD_NO_USE : "There should be no PCDs declared in INF files that are not specified in in either a DSC or FDF file", + ERROR_META_DATA_FILE_CHECK_PCD_NO_USE : "There should be no PCDs declared in INF files that are not specified in either a DSC or FDF file", ERROR_META_DATA_FILE_CHECK_DUPLICATE_GUID : "Duplicate GUID found", ERROR_META_DATA_FILE_CHECK_DUPLICATE_PROTOCOL : "Duplicate PROTOCOL found", ERROR_META_DATA_FILE_CHECK_DUPLICATE_PPI : "Duplicate PPI found", diff --git a/edk2basetools/FMMT/FMMT.py b/edk2basetools/FMMT/FMMT.py index 24943234..5f2c8eb9 100644 --- a/edk2basetools/FMMT/FMMT.py +++ b/edk2basetools/FMMT/FMMT.py @@ -24,7 +24,8 @@ If not given TargetFvName, all the existed target Ffs will be deleted'") parser.add_argument("-e", "--Extract", dest="Extract", nargs='+', help="Extract a Ffs Info: '-e inputfile TargetFvName(Optional) TargetFfsName outputfile\ - If not given TargetFvName, the first found target Ffs will be extracted'") + If not given TargetFvName, the first found target Ffs will be extracted.\ + If only given TargetFvName, not given TargetFfsName, the TargetFv will be extracted to output file'") parser.add_argument("-a", "--Add", dest="Add", nargs='+', help="Add a Ffs into a FV:'-a inputfile TargetFvName newffsfile outputfile'") parser.add_argument("-r", "--Replace", dest="Replace", nargs='+', @@ -40,6 +41,8 @@ FmmtConf file saves the target guidtool used in compress/uncompress process.\ If do not provide, FMMT tool will search the inputfile folder for FmmtConf.ini firstly, if not found,\ the FmmtConf.ini saved in FMMT tool's folder will be used as default.") +parser.add_argument("-s", "--ShrinkFv", dest="ShrinkFv", nargs='+', + help="Shrink the Fv file: '-s InputFvfile OutputFvfile") def print_banner(): print("") @@ -110,6 +113,9 @@ def Replace(self,inputfile: str, Ffs_name: str, newffsfile: str, outputfile: str else: ReplaceFfs(inputfile, self.CheckFfsName(Ffs_name), newffsfile, outputfile) + def Shrink(self,inputfile: str, outputfile: str) -> None: + self.SetDestPath(inputfile) + ShrinkFv(inputfile, outputfile) def main(): args=parser.parse_args() @@ -141,6 +147,8 @@ def main(): fmmt.Replace(args.Replace[0],args.Replace[2],args.Replace[3],args.Replace[4],args.Replace[1]) else: fmmt.Replace(args.Replace[0],args.Replace[1],args.Replace[2],args.Replace[3]) + elif args.ShrinkFv: + fmmt.Shrink(args.ShrinkFv[0], args.ShrinkFv[1]) else: parser.print_help() except Exception as e: diff --git a/edk2basetools/FMMT/core/FMMTOperation.py b/edk2basetools/FMMT/core/FMMTOperation.py index 2fda32a5..4a12d491 100644 --- a/edk2basetools/FMMT/core/FMMTOperation.py +++ b/edk2basetools/FMMT/core/FMMTOperation.py @@ -63,9 +63,10 @@ def DeleteFfs(inputfile: str, TargetFfs_name: str, outputfile: str, Fv_name: str FmmtParser.WholeFvTree.FindNode(TargetFfs_name, FmmtParser.WholeFvTree.Findlist) # Choose the Specfic DeleteFfs with Fv info if Fv_name: - for item in FmmtParser.WholeFvTree.Findlist: - if item.Parent.key != Fv_name and item.Parent.Data.Name != Fv_name: - FmmtParser.WholeFvTree.Findlist.remove(item) + FindNum = len(FmmtParser.WholeFvTree.Findlist) + for index in range(FindNum-1, -1, -1): + if FmmtParser.WholeFvTree.Findlist[index].Parent.key != Fv_name and FmmtParser.WholeFvTree.Findlist[index].Parent.Data.Name != Fv_name: + FmmtParser.WholeFvTree.Findlist.remove(FmmtParser.WholeFvTree.Findlist[index]) Status = False if FmmtParser.WholeFvTree.Findlist != []: for Delete_Ffs in FmmtParser.WholeFvTree.Findlist: @@ -149,9 +150,10 @@ def ReplaceFfs(inputfile: str, Ffs_name: str, newffsfile: str, outputfile: str, new_ffs.Data.PadData = GetPadSize(new_ffs.Data.Size, FFS_COMMON_ALIGNMENT) * b'\xff' FmmtParser.WholeFvTree.FindNode(Ffs_name, FmmtParser.WholeFvTree.Findlist) if Fv_name: - for item in FmmtParser.WholeFvTree.Findlist: - if item.Parent.key != Fv_name and item.Parent.Data.Name != Fv_name: - FmmtParser.WholeFvTree.Findlist.remove(item) + FindNum = len(FmmtParser.WholeFvTree.Findlist) + for index in range(FindNum-1, -1, -1): + if FmmtParser.WholeFvTree.Findlist[index].Parent.key != Fv_name and FmmtParser.WholeFvTree.Findlist[index].Parent.Data.Name != Fv_name: + FmmtParser.WholeFvTree.Findlist.remove(FmmtParser.WholeFvTree.Findlist[index]) if FmmtParser.WholeFvTree.Findlist != []: for TargetFfs in FmmtParser.WholeFvTree.Findlist: FfsMod = FvHandler(newFmmtParser.WholeFvTree.Child[0], TargetFfs) @@ -180,18 +182,51 @@ def ExtractFfs(inputfile: str, Ffs_name: str, outputfile: str, Fv_name: str=None logger.debug('Done!') FmmtParser.WholeFvTree.FindNode(Ffs_name, FmmtParser.WholeFvTree.Findlist) if Fv_name: - for item in FmmtParser.WholeFvTree.Findlist: - if item.Parent.key != Fv_name and item.Parent.Data.Name != Fv_name: - FmmtParser.WholeFvTree.Findlist.remove(item) + FindNum = len(FmmtParser.WholeFvTree.Findlist) + for index in range(FindNum-1, -1, -1): + if FmmtParser.WholeFvTree.Findlist[index].Parent.key != Fv_name and FmmtParser.WholeFvTree.Findlist[index].Parent.Data.Name != Fv_name: + FmmtParser.WholeFvTree.Findlist.remove(FmmtParser.WholeFvTree.Findlist[index]) if FmmtParser.WholeFvTree.Findlist != []: TargetNode = FmmtParser.WholeFvTree.Findlist[0] - TargetFv = TargetNode.Parent - if TargetFv.Data.Header.Attributes & EFI_FVB2_ERASE_POLARITY: - TargetNode.Data.Header.State = c_uint8( - ~TargetNode.Data.Header.State) - FinalData = struct2stream(TargetNode.Data.Header) + TargetNode.Data.Data - with open(outputfile, "wb") as f: - f.write(FinalData) - logger.debug('Extract ffs data is saved in {}.'.format(outputfile)) + if TargetNode.type == FV_TREE or SEC_FV_TREE or DATA_FV_TREE: + FinalData = struct2stream(TargetNode.Data.Header) + TargetNode.Data.Data + with open(outputfile, "wb") as f: + f.write(FinalData) + logger.debug('Extract fv data is saved in {}.'.format(outputfile)) + else: + TargetFv = TargetNode.Parent + if TargetFv.Data.Header.Attributes & EFI_FVB2_ERASE_POLARITY: + TargetNode.Data.Header.State = c_uint8( + ~TargetNode.Data.Header.State) + FinalData = struct2stream(TargetNode.Data.Header) + TargetNode.Data.Data + with open(outputfile, "wb") as f: + f.write(FinalData) + logger.debug('Extract ffs data is saved in {}.'.format(outputfile)) else: - logger.error('Target Ffs not found!!!') + logger.error('Target Ffs/Fv not found!!!') + +def ShrinkFv(inputfile: str, outputfile: str) -> None: + if not os.path.exists(inputfile): + logger.error("Invalid inputfile, can not open {}.".format(inputfile)) + raise Exception("Process Failed: Invalid inputfile!") + # 1. Data Prepare + with open(inputfile, "rb") as f: + whole_data = f.read() + FmmtParser = FMMTParser(inputfile, ROOT_TREE) + # 2. DataTree Create + logger.debug('Parsing inputfile data......') + FmmtParser.ParserFromRoot(FmmtParser.WholeFvTree, whole_data) + logger.debug('Done!') + TargetFv = FmmtParser.WholeFvTree.Child[0] + if TargetFv: + FvMod = FvHandler(TargetFv) + Status = FvMod.ShrinkFv() + else: + logger.error('Target Fv not found!!!') + # 4. Data Encapsulation + if Status: + logger.debug('Start encapsulating data......') + FmmtParser.Encapsulation(FmmtParser.WholeFvTree, False) + with open(outputfile, "wb") as f: + f.write(FmmtParser.FinalData) + logger.debug('Encapsulated data is saved in {}.'.format(outputfile)) diff --git a/edk2basetools/FMMT/core/FvHandler.py b/edk2basetools/FMMT/core/FvHandler.py index cb5f7207..dc303c2c 100644 --- a/edk2basetools/FMMT/core/FvHandler.py +++ b/edk2basetools/FMMT/core/FvHandler.py @@ -145,7 +145,7 @@ def ModifyFvSystemGuid(TargetFv) -> None: TargetFv.Data.Data += struct2stream(item.Data.Header)+ item.Data.Data + item.Data.PadData class FvHandler: - def __init__(self, NewFfs, TargetFfs) -> None: + def __init__(self, NewFfs, TargetFfs=None) -> None: self.NewFfs = NewFfs self.TargetFfs = TargetFfs self.Status = False @@ -155,7 +155,6 @@ def __init__(self, NewFfs, TargetFfs) -> None: def CompressData(self, TargetTree) -> None: TreePath = TargetTree.GetTreePath() pos = len(TreePath) - self.Status = False while pos: if not self.Status: if TreePath[pos-1].type == SECTION_TREE and TreePath[pos-1].Data.Type == 0x02: @@ -487,7 +486,6 @@ def AddFfs(self) -> bool: ~self.NewFfs.Data.Header.State) # If TargetFv have enough free space, just move part of the free space to NewFfs, split free space to NewFfs and new free space. if TargetLen < 0: - self.Status = True self.TargetFfs.Data.Data = b'\xff' * (-TargetLen) TargetFv.Data.Free_Space = (-TargetLen) TargetFv.Data.ModFvExt() @@ -498,13 +496,14 @@ def AddFfs(self) -> bool: ModifyFfsType(self.NewFfs) # Recompress from the Fv node to update all the related node data. self.CompressData(TargetFv) - elif TargetLen == 0: self.Status = True + elif TargetLen == 0: TargetFv.Child.remove(self.TargetFfs) TargetFv.insertChild(self.NewFfs) ModifyFfsType(self.NewFfs) # Recompress from the Fv node to update all the related node data. self.CompressData(TargetFv) + self.Status = True # If TargetFv do not have enough free space, need move part of the free space of TargetFv's parent Fv to TargetFv/NewFfs. else: if TargetFv.type == FV_TREE: @@ -639,3 +638,29 @@ def DeleteFfs(self) -> bool: self.Status = True logger.debug('Done!') return self.Status + + def ShrinkFv(self) -> bool: + TargetFv = self.NewFfs + TargetFv.Data.Data = b'' + if not TargetFv.Data.Free_Space: + self.Status = True + else: + BlockSize = TargetFv.Data.Header.BlockMap[0].Length + New_Free_Space = TargetFv.Data.Free_Space%BlockSize + Removed_Space = TargetFv.Data.Free_Space - New_Free_Space + TargetFv.Child[-1].Data.Data = b'\xff' * New_Free_Space + TargetFv.Data.Size -= Removed_Space + TargetFv.Data.Header.Fvlength = TargetFv.Data.Size + ModifyFvSystemGuid(TargetFv) + for item in TargetFv.Child: + if item.type == FFS_FREE_SPACE: + TargetFv.Data.Data += item.Data.Data + item.Data.PadData + else: + TargetFv.Data.Data += struct2stream(item.Data.Header)+ item.Data.Data + item.Data.PadData + TargetFv.Data.ModFvExt() + TargetFv.Data.ModFvSize() + TargetFv.Data.ModExtHeaderData() + ModifyFvExtData(TargetFv) + TargetFv.Data.ModCheckSum() + self.Status = True + return self.Status diff --git a/edk2basetools/GenFds/FdfParser.py b/edk2basetools/GenFds/FdfParser.py index d931f5ef..1383805d 100644 --- a/edk2basetools/GenFds/FdfParser.py +++ b/edk2basetools/GenFds/FdfParser.py @@ -42,6 +42,7 @@ from .DepexSection import DepexSection from .CompressSection import CompressSection from .GuidSection import GuidSection +from .SubTypeGuidSection import SubTypeGuidSection from .Capsule import EFI_CERT_TYPE_PKCS7_GUID, EFI_CERT_TYPE_RSA2048_SHA256_GUID, Capsule from .CapsuleData import CapsuleFfs, CapsulePayload, CapsuleFv, CapsuleFd, CapsuleAnyFile, CapsuleAfile from .RuleComplexFile import RuleComplexFile @@ -2892,6 +2893,27 @@ def _GetLeafSection(self, Obj): DepexSectionObj.Expression = self._SkippedChars.rstrip(T_CHAR_BRACE_R) Obj.SectionList.append(DepexSectionObj) + elif self._IsKeyword("SUBTYPE_GUID"): + if AlignValue == 'Auto': + raise Warning("Auto alignment can only be used in PE32 or TE section ", self.FileName, self.CurrentLineNumber) + SubTypeGuidValue = None + if not self._GetNextGuid(): + raise Warning.Expected("GUID", self.FileName, self.CurrentLineNumber) + else: + SubTypeGuidValue = self._Token + + if not self._IsToken(TAB_EQUAL_SPLIT): + raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber) + if not self._GetNextToken(): + raise Warning.Expected("section file path", self.FileName, self.CurrentLineNumber) + FileName = self._Token + + SubTypeGuidSectionObj = SubTypeGuidSection() + SubTypeGuidSectionObj.Alignment = AlignValue + SubTypeGuidSectionObj.SubTypeGuid = SubTypeGuidValue + SubTypeGuidSectionObj.SectFileName = FileName + Obj.SectionList.append(SubTypeGuidSectionObj) + else: if not self._GetNextWord(): raise Warning.Expected("section type", self.FileName, self.CurrentLineNumber) @@ -3996,7 +4018,7 @@ def _CheckRuleSectionFileType(self, SectionType, FileType): if FileType not in {BINARY_FILE_TYPE_PE32, "SEC_PE32"}: raise Warning(WarningString % FileType, self.FileName, self.CurrentLineNumber) elif SectionType == BINARY_FILE_TYPE_PIC: - if FileType not in {BINARY_FILE_TYPE_PIC, BINARY_FILE_TYPE_PIC}: + if FileType not in {BINARY_FILE_TYPE_PIC, "SEC_PIC"}: raise Warning(WarningString % FileType, self.FileName, self.CurrentLineNumber) elif SectionType == BINARY_FILE_TYPE_TE: if FileType not in {BINARY_FILE_TYPE_TE, "SEC_TE"}: diff --git a/edk2basetools/GenFds/Section.py b/edk2basetools/GenFds/Section.py index 6779c5d5..72198b87 100644 --- a/edk2basetools/GenFds/Section.py +++ b/edk2basetools/GenFds/Section.py @@ -28,6 +28,7 @@ class Section (SectionClassObject): BINARY_FILE_TYPE_PIC : 'EFI_SECTION_PIC', BINARY_FILE_TYPE_TE : 'EFI_SECTION_TE', 'FV_IMAGE' : 'EFI_SECTION_FIRMWARE_VOLUME_IMAGE', + 'COMPAT16' : 'EFI_SECTION_COMPATIBILITY16', BINARY_FILE_TYPE_DXE_DEPEX : 'EFI_SECTION_DXE_DEPEX', BINARY_FILE_TYPE_PEI_DEPEX : 'EFI_SECTION_PEI_DEPEX', 'GUIDED' : 'EFI_SECTION_GUID_DEFINED', diff --git a/edk2basetools/GenFds/SubTypeGuidSection.py b/edk2basetools/GenFds/SubTypeGuidSection.py new file mode 100644 index 00000000..56ef75a7 --- /dev/null +++ b/edk2basetools/GenFds/SubTypeGuidSection.py @@ -0,0 +1,76 @@ +## @file +# process Subtype GUIDed section generation +# +# Copyright (c) 2022, Konstantin Aladyshev +# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# + +## +# Import Modules +# +from __future__ import absolute_import +from . import Section +import subprocess +from .Ffs import SectionSuffix +import Common.LongFilePathOs as os +from .GenFdsGlobalVariable import GenFdsGlobalVariable +from .GenFdsGlobalVariable import FindExtendTool +from CommonDataClass.FdfClass import SubTypeGuidSectionClassObject +import sys +from Common import EdkLogger +from Common.BuildToolError import * +from .FvImageSection import FvImageSection +from Common.LongFilePathSupport import OpenLongFilePath as open +from Common.DataType import * + +## generate SubType GUIDed section +# +# +class SubTypeGuidSection(SubTypeGuidSectionClassObject) : + + ## The constructor + # + # @param self The object pointer + # + def __init__(self): + SubTypeGuidSectionClassObject.__init__(self) + + ## GenSection() method + # + # Generate GUIDed section + # + # @param self The object pointer + # @param OutputPath Where to place output file + # @param ModuleName Which module this section belongs to + # @param SecNum Index of section + # @param KeyStringList Filter for inputs of section generation + # @param FfsInf FfsInfStatement object that contains this section data + # @param Dict dictionary contains macro and its value + # @retval tuple (Generated file name, section alignment) + # + def GenSection(self, OutputPath, ModuleName, SecNum, KeyStringList, FfsInf=None, Dict=None, IsMakefile=False): + # + # Generate all section + # + self.KeyStringList = KeyStringList + self.CurrentArchList = GenFdsGlobalVariable.ArchList + if FfsInf is not None: + self.Alignment = FfsInf.__ExtendMacro__(self.Alignment) + self.SubTypeGuid = FfsInf.__ExtendMacro__(self.SubTypeGuid) + self.SectionType = FfsInf.__ExtendMacro__(self.SectionType) + self.CurrentArchList = [FfsInf.CurrentArch] + + if Dict is None: + Dict = {} + + self.SectFileName = GenFdsGlobalVariable.ReplaceWorkspaceMacro(self.SectFileName) + self.SectFileName = GenFdsGlobalVariable.MacroExtend(self.SectFileName, Dict) + + OutputFile = os.path.join(OutputPath, ModuleName + SUP_MODULE_SEC + SecNum + SectionSuffix.get("SUBTYPE_GUID")) + GenFdsGlobalVariable.GenerateSection(OutputFile, [self.SectFileName], 'EFI_SECTION_FREEFORM_SUBTYPE_GUID', Guid=self.SubTypeGuid, IsMakefile=IsMakefile) + + OutputFileList = [] + OutputFileList.append(OutputFile) + return OutputFileList, self.Alignment + diff --git a/edk2basetools/Workspace/DscBuildData.py b/edk2basetools/Workspace/DscBuildData.py index bbf74b94..ff5662f3 100644 --- a/edk2basetools/Workspace/DscBuildData.py +++ b/edk2basetools/Workspace/DscBuildData.py @@ -2089,12 +2089,12 @@ def GenerateDefaultValueAssignFunction(self, Pcd): pcdarraysize = Pcd.PcdArraySize() if "{CODE(" in Pcd.DefaultValueFromDec: if Pcd.Capacity[-1] != "-1": - CApp = CApp + '__STATIC_ASSERT(sizeof(%s_%s_INIT_Value) < %d * sizeof(%s), "Pcd %s.%s Value in Dec exceed the array capability %s"); // From %s Line %s \n ' % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName,pcdarraysize,Pcd.BaseDatumType,Pcd.TokenSpaceGuidCName, Pcd.TokenCName,Pcd.DatumType,Pcd.DefaultValueFromDecInfo[0],Pcd.DefaultValueFromDecInfo[1]) + CApp = CApp + '__STATIC_ASSERT(sizeof(%s_%s_INIT_Value) <= %d * sizeof(%s), "Pcd %s.%s Value in Dec exceed the array capability %s"); // From %s Line %s \n ' % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName,pcdarraysize,Pcd.BaseDatumType,Pcd.TokenSpaceGuidCName, Pcd.TokenCName,Pcd.DatumType,Pcd.DefaultValueFromDecInfo[0],Pcd.DefaultValueFromDecInfo[1]) CApp = CApp + ' PcdArraySize = sizeof(%s_%s_INIT_Value);\n ' % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName) CApp = CApp + ' memcpy (Pcd, %s_%s_INIT_Value,PcdArraySize);\n ' % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName) else: if Pcd.Capacity[-1] != "-1": - CApp = CApp + '__STATIC_ASSERT(%d < %d * sizeof(%s), "Pcd %s.%s Value in Dec exceed the array capability %s"); // From %s Line %s \n' % (ValueSize,pcdarraysize,Pcd.BaseDatumType,Pcd.TokenSpaceGuidCName, Pcd.TokenCName,Pcd.DatumType,Pcd.DefaultValueFromDecInfo[0],Pcd.DefaultValueFromDecInfo[1]) + CApp = CApp + '__STATIC_ASSERT(%d <= %d * sizeof(%s), "Pcd %s.%s Value in Dec exceed the array capability %s"); // From %s Line %s \n' % (ValueSize,pcdarraysize,Pcd.BaseDatumType,Pcd.TokenSpaceGuidCName, Pcd.TokenCName,Pcd.DatumType,Pcd.DefaultValueFromDecInfo[0],Pcd.DefaultValueFromDecInfo[1]) CApp = CApp + ' PcdArraySize = %d;\n' % ValueSize CApp = CApp + ' Value = %s; // From DEC Default Value %s\n' % (DscBuildData.IntToCString(Value, ValueSize), Pcd.DefaultValueFromDec) CApp = CApp + ' memcpy (Pcd, Value, PcdArraySize);\n' @@ -2204,7 +2204,7 @@ def GenerateInitValueFunction(self, Pcd, SkuName, DefaultStoreName): if "{CODE(" in Value: if Pcd.IsArray() and Pcd.Capacity[-1] != "-1": pcdarraysize = Pcd.PcdArraySize() - CApp = CApp + '__STATIC_ASSERT(sizeof(%s_%s_%s_%s_Value) < %d * sizeof(%s), "Pcd %s.%s Value in Dsc exceed the array capability %s"); // From %s \n' % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName,SkuName, DefaultStoreName,pcdarraysize,Pcd.BaseDatumType,Pcd.TokenSpaceGuidCName, Pcd.TokenCName,Pcd.DatumType, valuefrom) + CApp = CApp + '__STATIC_ASSERT(sizeof(%s_%s_%s_%s_Value) <= %d * sizeof(%s), "Pcd %s.%s Value in Dsc exceed the array capability %s"); // From %s \n' % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName,SkuName, DefaultStoreName,pcdarraysize,Pcd.BaseDatumType,Pcd.TokenSpaceGuidCName, Pcd.TokenCName,Pcd.DatumType, valuefrom) CApp = CApp+ ' PcdArraySize = sizeof(%s_%s_%s_%s_Value);\n ' % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName,SkuName, DefaultStoreName) CApp = CApp + ' memcpy (Pcd, &%s_%s_%s_%s_Value,PcdArraySize);\n ' % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName,SkuName, DefaultStoreName) else: @@ -2217,12 +2217,12 @@ def GenerateInitValueFunction(self, Pcd, SkuName, DefaultStoreName): pcdarraysize = Pcd.PcdArraySize() if "{CODE(" in pcddefaultvalue: if Pcd.Capacity[-1] != "-1": - CApp = CApp + '__STATIC_ASSERT(sizeof(%s_%s_%s_%s_Value) < %d * sizeof(%s), "Pcd %s.%s Value in Dsc exceed the array capability %s"); // From %s \n' % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName,SkuName, DefaultStoreName,pcdarraysize,Pcd.BaseDatumType,Pcd.TokenSpaceGuidCName, Pcd.TokenCName,Pcd.DatumType,valuefrom) + CApp = CApp + '__STATIC_ASSERT(sizeof(%s_%s_%s_%s_Value) <= %d * sizeof(%s), "Pcd %s.%s Value in Dsc exceed the array capability %s"); // From %s \n' % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName,SkuName, DefaultStoreName,pcdarraysize,Pcd.BaseDatumType,Pcd.TokenSpaceGuidCName, Pcd.TokenCName,Pcd.DatumType,valuefrom) CApp = CApp + ' PcdArraySize = sizeof(%s_%s_%s_%s_Value);\n ' % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName,SkuName, DefaultStoreName) CApp = CApp + ' memcpy (Pcd, %s_%s_%s_%s_Value, PcdArraySize);\n' % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName,SkuName, DefaultStoreName) else: if Pcd.Capacity[-1] != "-1": - CApp = CApp + '__STATIC_ASSERT(%d < %d * sizeof(%s), "Pcd %s.%s Value in Dsc exceed the array capability %s"); // From %s \n' % (ValueSize,pcdarraysize,Pcd.BaseDatumType,Pcd.TokenSpaceGuidCName, Pcd.TokenCName,Pcd.DatumType,valuefrom) + CApp = CApp + '__STATIC_ASSERT(%d <= %d * sizeof(%s), "Pcd %s.%s Value in Dsc exceed the array capability %s"); // From %s \n' % (ValueSize,pcdarraysize,Pcd.BaseDatumType,Pcd.TokenSpaceGuidCName, Pcd.TokenCName,Pcd.DatumType,valuefrom) CApp = CApp + ' PcdArraySize = %d;\n' % ValueSize CApp = CApp + ' Value = %s; // From DSC Default Value %s\n' % (DscBuildData.IntToCString(Value, ValueSize), Pcd.DefaultFromDSC.get(TAB_DEFAULT, {}).get(TAB_DEFAULT_STORES_DEFAULT, Pcd.DefaultValue) if Pcd.DefaultFromDSC else Pcd.DefaultValue) CApp = CApp + ' memcpy (Pcd, Value, PcdArraySize);\n' @@ -2238,7 +2238,7 @@ def GenerateInitValueFunction(self, Pcd, SkuName, DefaultStoreName): if "{CODE(" in Value: if Pcd.IsArray() and Pcd.Capacity[-1] != "-1": pcdarraysize = Pcd.PcdArraySize() - CApp = CApp + '__STATIC_ASSERT(sizeof(%s_%s_%s_%s_Value) < %d * sizeof(%s), "Pcd %s.%s Value in Dsc exceed the array capability %s"); // From %s \n' % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName,SkuName, DefaultStoreName,pcdarraysize,Pcd.BaseDatumType,Pcd.TokenSpaceGuidCName, Pcd.TokenCName,Pcd.DatumType,valuefrom) + CApp = CApp + '__STATIC_ASSERT(sizeof(%s_%s_%s_%s_Value) <= %d * sizeof(%s), "Pcd %s.%s Value in Dsc exceed the array capability %s"); // From %s \n' % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName,SkuName, DefaultStoreName,pcdarraysize,Pcd.BaseDatumType,Pcd.TokenSpaceGuidCName, Pcd.TokenCName,Pcd.DatumType,valuefrom) CApp = CApp + ' PcdArraySize = sizeof(%s_%s_%s_%s_Value);\n '% (Pcd.TokenSpaceGuidCName, Pcd.TokenCName,SkuName, DefaultStoreName) CApp = CApp + ' memcpy (Pcd, &%s_%s_%s_%s_Value, PcdArraySize);\n' % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName,SkuName, DefaultStoreName) else: @@ -2251,12 +2251,12 @@ def GenerateInitValueFunction(self, Pcd, SkuName, DefaultStoreName): pcdarraysize = Pcd.PcdArraySize() if "{CODE(" in pcddefaultvalue: if Pcd.Capacity[-1] != "-1": - CApp = CApp + '__STATIC_ASSERT(sizeof(%s_%s_%s_%s_Value) < %d * sizeof(%s), "Pcd %s.%s Value in Dsc exceed the array capability %s"); // From %s \n' % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName,SkuName, DefaultStoreName,pcdarraysize,Pcd.BaseDatumType,Pcd.TokenSpaceGuidCName, Pcd.TokenCName,Pcd.DatumType,valuefrom) + CApp = CApp + '__STATIC_ASSERT(sizeof(%s_%s_%s_%s_Value) <= %d * sizeof(%s), "Pcd %s.%s Value in Dsc exceed the array capability %s"); // From %s \n' % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName,SkuName, DefaultStoreName,pcdarraysize,Pcd.BaseDatumType,Pcd.TokenSpaceGuidCName, Pcd.TokenCName,Pcd.DatumType,valuefrom) CApp + ' PcdArraySize = sizeof(%s_%s_%s_%s_Value);\n ' % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName,SkuName, DefaultStoreName) CApp = CApp + ' memcpy (Pcd, %s_%s_%s_%s_Value, PcdArraySize);\n' % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName,SkuName, DefaultStoreName) else: if Pcd.Capacity[-1] != "-1": - CApp = CApp + '__STATIC_ASSERT(%d < %d * sizeof(%s), "Pcd %s.%s Value in Dsc exceed the array capability %s"); // From %s \n' % (ValueSize,pcdarraysize,Pcd.BaseDatumType,Pcd.TokenSpaceGuidCName, Pcd.TokenCName,Pcd.DatumType,valuefrom) + CApp = CApp + '__STATIC_ASSERT(%d <= %d * sizeof(%s), "Pcd %s.%s Value in Dsc exceed the array capability %s"); // From %s \n' % (ValueSize,pcdarraysize,Pcd.BaseDatumType,Pcd.TokenSpaceGuidCName, Pcd.TokenCName,Pcd.DatumType,valuefrom) CApp = CApp + ' PcdArraySize = %d;\n' % ValueSize CApp = CApp + ' Value = %s; // From DSC Default Value %s\n' % (DscBuildData.IntToCString(Value, ValueSize), Pcd.DscRawValue.get(TAB_DEFAULT, {}).get(TAB_DEFAULT_STORES_DEFAULT, Pcd.DefaultValue) if Pcd.DefaultFromDSC else Pcd.DefaultValue) CApp = CApp + ' memcpy (Pcd, Value, PcdArraySize);\n' diff --git a/edk2basetools/build/build.py b/edk2basetools/build/build.py index 7e12095b..1ccb4be5 100755 --- a/edk2basetools/build/build.py +++ b/edk2basetools/build/build.py @@ -207,7 +207,7 @@ def __init__(self,*args, **argv): # # This method will call subprocess.Popen to execute an external program with # given options in specified directory. Because of the dead-lock issue during -# redirecting output of the external program, threads are used to to do the +# redirecting output of the external program, threads are used to do the # redirection work. # # @param Command A list or string containing the call of the program diff --git a/integration_test/.gitignore b/integration_test/.gitignore new file mode 100644 index 00000000..d3ced31d --- /dev/null +++ b/integration_test/.gitignore @@ -0,0 +1,5 @@ +/test +/report +stderr.txt +stdout.txt +/edk2/ \ No newline at end of file diff --git a/integration_test/Shared_Keywords.robot b/integration_test/Shared_Keywords.robot new file mode 100644 index 00000000..e9343b8b --- /dev/null +++ b/integration_test/Shared_Keywords.robot @@ -0,0 +1,119 @@ +*** Settings *** +Documentation A shared set of common keywords for stuart operations and git operations +# +# Copyright (c), Microsoft Corporation +# SPDX-License-Identifier: BSD-2-Clause-Patent + +Library Process +Library OperatingSystem + +# Suite Setup + +*** Variables *** + +#Test output location +${TEST_OUTPUT} ${TEST_OUTPUT_BASE} + +*** Keywords *** + +### Git operations ### +Clone the git repo + [Arguments] ${git_url} ${ws_name} + + Log To console cloning ${git_url} to ${TEST_OUTPUT} + ${result}= Run Process git clone ${git_url} ${ws_name} + ... cwd=${TEST_OUTPUT} stdout=stdout.txt stderr=stderr.txt + Log Many stdout: ${result.stdout} stderr: ${result.stderr} + + ${result}= Run Process git fetch --all --prune + ... cwd=${TEST_OUTPUT}${/}${ws_name} stdout=stdout.txt stderr=stderr.txt + Log Many stdout: ${result.stdout} stderr: ${result.stderr} + Should Be Equal As Integers ${result.rc} 0 + +Reset git repo to default branch + [Arguments] ${ws} ${default_branch_name} + + # checkout remote tag for origin/ + ${result}= Run Process git checkout origin/${default_branch_name} + ... cwd=${ws} stdout=stdout.txt stderr=stderr.txt + Log Many stdout: ${result.stdout} stderr: ${result.stderr} + Should Be Equal As Integers ${result.rc} 0 + + # clean non ignored files quietly to avoid log overflow + ${result}= Run Process git clean -qfd cwd=${ws} + Log Many stdout: ${result.stdout} stderr: ${result.stderr} + Should Be Equal As Integers ${result.rc} 0 + + # reset to restore files + ${result}= Run Process git reset --hard + ... cwd=${ws} stdout=stdout.txt stderr=stderr.txt + Log Many stdout: ${result.stdout} stderr: ${result.stderr} + Should Be Equal As Integers ${result.rc} 0 + +Get default branch from remote + [Arguments] ${ws} + + # Set origin head to auto + ${result}= Run Process git remote set-head origin --auto + ... cwd=${ws} + Log Many stdout: ${result.stdout} stderr: ${result.stderr} + Should Be Equal As Integers ${result.rc} 0 + + # get the head + ${result}= Run Process git rev-parse --abbrev-ref origin/HEAD + ... cwd=${ws} + Log Many stdout: ${result.stdout} stderr: ${result.stderr} + Should Be Equal As Integers ${result.rc} 0 + + # Strip off origin/ from the branch because all other commands + # add the remote name. + ${branch}= Get Substring ${result.stdout} 7 + + [Return] ${branch} + +### Stuart operations ### +Stuart setup + [Arguments] ${setting_file} ${arch} ${target} ${packages} ${tool_chain} ${ws} + Log to console Stuart Setup + ${result}= Run Process stuart_setup + ... -c ${setting_file} -a ${arch} TOOL_CHAIN_TAG\=${tool_chain} -t ${target} -p ${packages} TARGET\=${target} + ... cwd=${ws} stdout=stdout.txt stderr=stderr.txt + Log Many stdout: ${result.stdout} stderr: ${result.stderr} + Should Be Equal As Integers ${result.rc} 0 + +Stuart update + [Arguments] ${setting_file} ${arch} ${target} ${packages} ${tool_chain} ${ws} + Log to console Stuart Update + ${result}= Run Process stuart_update + ... -c ${setting_file} -a ${arch} TOOL_CHAIN_TAG\=${tool_chain} -t ${target} -p ${packages} TARGET\=${target} + ... cwd=${ws} stdout=stdout.txt stderr=stderr.txt + Log Many stdout: ${result.stdout} stderr: ${result.stderr} + Should Be Equal As Integers ${result.rc} 0 + +Stuart platform build + [Arguments] ${setting_file} ${arch} ${target} ${tool_chain} ${ws} + Log to console Stuart Build + ${result}= Run Process stuart_build + ... -c ${setting_file} -a ${arch} TOOL_CHAIN_TAG\=${tool_chain} TARGET\=${target} + ... cwd=${ws} stdout=stdout.txt stderr=stderr.txt + Log Many stdout: ${result.stdout} stderr: ${result.stderr} + Should Be Equal As Integers ${result.rc} 0 + +Stuart platform run + [Arguments] ${setting_file} ${arch} ${target} ${tool_chain} ${addtional_flags} ${ws} + Log to console Stuart Build Run + ${result}= Run Process stuart_build + ... -c ${setting_file} -a ${arch} TOOL_CHAIN_TAG\=${tool_chain} TARGET\=${target} --FlashOnly ${addtional_flags} + ... cwd=${ws} stdout=stdout.txt stderr=stderr.txt + Log Many stdout: ${result.stdout} stderr: ${result.stderr} + Should Be Equal As Integers ${result.rc} 0 + +### Edk2 BaseTools Build operations ### +Build BaseTools + [Arguments] ${tool_chain} ${ws} + Log to console Compile basetools + ${result}= Run Process python + ... BaseTools/Edk2ToolsBuild.py -t ${tool_chain} + ... cwd=${ws} shell=True stdout=stdout.txt stderr=stderr.txt + Log Many stdout: ${result.stdout} stderr: ${result.stderr} + Should Be Equal As Integers ${result.rc} 0 diff --git a/integration_test/azure-pipelines/robot-integration-test.yml b/integration_test/azure-pipelines/robot-integration-test.yml new file mode 100644 index 00000000..972d9322 --- /dev/null +++ b/integration_test/azure-pipelines/robot-integration-test.yml @@ -0,0 +1,101 @@ +## +# Azure Pipeline integration test using robot framework +# and edk2 / Project Mu public repositories +# + +# Copyright (c) 2019, Microsoft Corporation +# SPDX-License-Identifier: BSD-2-Clause-Patent +## + +jobs: +- job: Integration_Test + + #Use matrix to speed up the build process + strategy: + matrix: + #EDK2_VS2019: + # Tag: 'Windows' + # Image: 'windows-2019' + EDK2_GCC5: + Tag: 'Ubuntu' + Image: 'ubuntu-18.04' + + workspace: + clean: all + + pool: + vmImage: $(Image) + + steps: + - task: UsePythonVersion@0 + inputs: + versionSpec: '3.10.x' + architecture: 'x64' + + - script: pip install --upgrade -r requirements.txt + displayName: 'Install requirements' + + - script: pip install --upgrade -r integration_test/pip-requirements.txt + displayName: 'Install Integration test requirements' + + - script: pip install -e . + displayName: 'Install from Source' + + - powershell: choco install qemu --version=2020.08.14; Write-Host "##vso[task.prependpath]c:\Program Files\qemu" + displayName: Install QEMU and Set QEMU on path # friendly name displayed in the UI + condition: contains(variables.Tag, 'Windows') + + - script: sudo dpkg --add-architecture i386 + displayName: EmulatorPkg - Add i386 Arch + condition: contains(variables.Tag, 'Ubuntu') + + - script: sudo apt-get update + displayName: Update for dependencies + condition: contains(variables.Tag, 'Ubuntu') + + - script: sudo apt-get install uuid-dev + displayName: Install General dependencies + condition: contains(variables.Tag, 'Ubuntu') + + - script: sudo apt-get install libc6-dev:i386 libx11-dev:i386 libxext-dev:i386 lib32gcc-7-dev + displayName: EmulatorPkg - Install dependencies + condition: contains(variables.Tag, 'Ubuntu') + + - script: git config --global user.email "you@example.com" + displayName: Configure git user user.email + + - script: git config --global user.name "Your Name" + displayName: Configure git user user.name + + - script: python -m robot.run -v TEST_OUTPUT_BASE:$(Build.BinariesDirectory) -d report --xunit xunittestresults.xml --include $(Tag) -L TRACE . + displayName: 'Run Robot Tests' + workingDirectory: "integration_test" + + # Copy the build logs to the artifact staging directory + - task: CopyFiles@2 + displayName: "Copy logs" + inputs: + targetFolder: '$(Build.ArtifactStagingDirectory)' + SourceFolder: 'integration_test/report' + contents: | + log.html + output.xml + report.html + flattenFolders: true + condition: succeededOrFailed() + + # Publish build artifacts to Azure Artifacts/TFS or a file share + - task: PublishBuildArtifacts@1 + continueOnError: true + displayName: "Publish logs" + inputs: + pathtoPublish: '$(Build.ArtifactStagingDirectory)' + artifactName: 'Logs $(System.JobName)' + condition: succeededOrFailed() + + - task: PublishTestResults@2 + inputs: + testResultsFiles: xunittestresults.xml + searchFolder: 'integration_test/report' + condition: succeededOrFailed() + displayName: 'Publish Test Results' diff --git a/integration_test/edk2_platform_Ubuntu.robot b/integration_test/edk2_platform_Ubuntu.robot new file mode 100644 index 00000000..cb1b828c --- /dev/null +++ b/integration_test/edk2_platform_Ubuntu.robot @@ -0,0 +1,234 @@ +*** Settings *** +Documentation A test suite to test Platform CI on edk2 repo +# +# Copyright (c), Microsoft Corporation +# SPDX-License-Identifier: BSD-2-Clause-Patent + +Library Process +Library OperatingSystem +Library String + +Resource Shared_Keywords.robot + +Suite Setup One time setup ${repo_url} ${ws_dir} + +# Suite Setup + +*** Variables *** +${repo_url} https://github.com/tianocore/edk2.git +${default_branch} not_yet_set +${ws_dir} edk2 +${ws_root} ${TEST_OUTPUT}${/}${ws_dir} +${tool_chain} GCC5 + + +*** Keywords *** +One time setup + [Arguments] ${url} ${folder} + ## Dump pip versions + ${result}= Run Process python -m pip list shell=True + Log ${result.stdout} + + ## Make output directory if doesn't already exist + Create Directory ${TEST_OUTPUT} + + ## Clone repo + Run Keyword Clone the git repo ${url} ${folder} + + ## Figure out default branch + ${branch}= Get default branch from remote ${ws_root} + Set Suite Variable ${default_branch} ${branch} + + +*** Test Cases *** +Run Edk2 Ovmf IA32 DEBUG + [Documentation] This test will run IA32 DEBUG build for OvmfPkg + [Tags] PlatformCI OvmfPkg IA32 GCC5 Ubuntu Qemu Edk2 + ${arch}= Set Variable IA32 + ${target}= Set Variable DEBUG + ${package}= Set Variable OvmfPkg + ${ci_file}= Set Variable ${package}${/}PlatformCI${/}PlatformBuild.py + + # make sure on default branch + Reset git repo to default branch ${ws_root} ${default_branch} + + Stuart setup ${ci_file} ${arch} ${target} ${package} ${tool_chain} ${ws_root} + Stuart update ${ci_file} ${arch} ${target} ${package} ${tool_chain} ${ws_root} + Build BaseTools ${tool_chain} ${ws_root} + Stuart platform build ${ci_file} ${arch} ${target} ${tool_chain} ${ws_root} + +Run Edk2 Ovmf IA32 RELEASE + [Documentation] This test will run IA32 RELEASE build for OvmfPkg + [Tags] PlatformCI OvmfPkg IA32 GCC5 Ubuntu Qemu Edk2 + ${arch}= Set Variable IA32 + ${target}= Set Variable RELEASE + ${package}= Set Variable OvmfPkg + ${ci_file}= Set Variable ${package}${/}PlatformCI${/}PlatformBuild.py + + # make sure on default branch + Reset git repo to default branch ${ws_root} ${default_branch} + + Stuart setup ${ci_file} ${arch} ${target} ${package} ${tool_chain} ${ws_root} + Stuart update ${ci_file} ${arch} ${target} ${package} ${tool_chain} ${ws_root} + Build BaseTools ${tool_chain} ${ws_root} + Stuart platform build ${ci_file} ${arch} ${target} ${tool_chain} ${ws_root} + +Run Edk2 Ovmf X64 DEBUG + [Documentation] This test will run X64 DEBUG build for OvmfPkg + [Tags] PlatformCI OvmfPkg X64 GCC5 Ubuntu Qemu Edk2 + ${arch}= Set Variable X64 + ${target}= Set Variable DEBUG + ${package}= Set Variable OvmfPkg + ${ci_file}= Set Variable ${package}${/}PlatformCI${/}PlatformBuild.py + + # make sure on default branch + Reset git repo to default branch ${ws_root} ${default_branch} + + Stuart setup ${ci_file} ${arch} ${target} ${package} ${tool_chain} ${ws_root} + Stuart update ${ci_file} ${arch} ${target} ${package} ${tool_chain} ${ws_root} + Build BaseTools ${tool_chain} ${ws_root} + Stuart platform build ${ci_file} ${arch} ${target} ${tool_chain} ${ws_root} + +Run Edk2 Ovmf X64 RELEASE + [Documentation] This test will run X64 RELEASE build for OvmfPkg + [Tags] PlatformCI OvmfPkg X64 GCC5 Ubuntu Qemu Edk2 + ${arch}= Set Variable X64 + ${target}= Set Variable RELEASE + ${package}= Set Variable OvmfPkg + ${ci_file}= Set Variable ${package}${/}PlatformCI${/}PlatformBuild.py + + # make sure on default branch + Reset git repo to default branch ${ws_root} ${default_branch} + + Stuart setup ${ci_file} ${arch} ${target} ${package} ${tool_chain} ${ws_root} + Stuart update ${ci_file} ${arch} ${target} ${package} ${tool_chain} ${ws_root} + Build BaseTools ${tool_chain} ${ws_root} + Stuart platform build ${ci_file} ${arch} ${target} ${tool_chain} ${ws_root} + +Run Edk2 Emulator IA32 DEBUG + [Documentation] This test will run IA32 DEBUG build for EmulatorPkg + [Tags] PlatformCI EmulatorPkg IA32 GCC5 Ubuntu Qemu Edk2 + ${arch}= Set Variable IA32 + ${target}= Set Variable DEBUG + ${package}= Set Variable EmulatorPkg + ${ci_file}= Set Variable ${package}${/}PlatformCI${/}PlatformBuild.py + + # make sure on default branch + Reset git repo to default branch ${ws_root} ${default_branch} + + Stuart setup ${ci_file} ${arch} ${target} ${package} ${tool_chain} ${ws_root} + Stuart update ${ci_file} ${arch} ${target} ${package} ${tool_chain} ${ws_root} + Build BaseTools ${tool_chain} ${ws_root} + Stuart platform build ${ci_file} ${arch} ${target} ${tool_chain} ${ws_root} + +Run Edk2 Emulator IA32 RELEASE + [Documentation] This test will run IA32 RELEASE build for EmulatorPkg + [Tags] PlatformCI EmulatorPkg IA32 GCC5 Ubuntu Qemu Edk2 + ${arch}= Set Variable IA32 + ${target}= Set Variable RELEASE + ${package}= Set Variable EmulatorPkg + ${ci_file}= Set Variable ${package}${/}PlatformCI${/}PlatformBuild.py + + # make sure on default branch + Reset git repo to default branch ${ws_root} ${default_branch} + + Stuart setup ${ci_file} ${arch} ${target} ${package} ${tool_chain} ${ws_root} + Stuart update ${ci_file} ${arch} ${target} ${package} ${tool_chain} ${ws_root} + Build BaseTools ${tool_chain} ${ws_root} + Stuart platform build ${ci_file} ${arch} ${target} ${tool_chain} ${ws_root} + +Run Edk2 Emulator X64 DEBUG + [Documentation] This test will run X64 DEBUG build for EmulatorPkg + [Tags] PlatformCI EmulatorPkg X64 GCC5 Ubuntu Qemu Edk2 + ${arch}= Set Variable X64 + ${target}= Set Variable DEBUG + ${package}= Set Variable EmulatorPkg + ${ci_file}= Set Variable ${package}${/}PlatformCI${/}PlatformBuild.py + + # make sure on default branch + Reset git repo to default branch ${ws_root} ${default_branch} + + Stuart setup ${ci_file} ${arch} ${target} ${package} ${tool_chain} ${ws_root} + Stuart update ${ci_file} ${arch} ${target} ${package} ${tool_chain} ${ws_root} + Build BaseTools ${tool_chain} ${ws_root} + Stuart platform build ${ci_file} ${arch} ${target} ${tool_chain} ${ws_root} + +Run Edk2 Emulator X64 RELEASE + [Documentation] This test will run X64 RELEASE build for EmulatorPkg + [Tags] PlatformCI EmulatorPkg X64 GCC5 Ubuntu Qemu Edk2 + ${arch}= Set Variable X64 + ${target}= Set Variable RELEASE + ${package}= Set Variable EmulatorPkg + ${ci_file}= Set Variable ${package}${/}PlatformCI${/}PlatformBuild.py + + # make sure on default branch + Reset git repo to default branch ${ws_root} ${default_branch} + + Stuart setup ${ci_file} ${arch} ${target} ${package} ${tool_chain} ${ws_root} + Stuart update ${ci_file} ${arch} ${target} ${package} ${tool_chain} ${ws_root} + Build BaseTools ${tool_chain} ${ws_root} + Stuart platform build ${ci_file} ${arch} ${target} ${tool_chain} ${ws_root} + +Run Edk2 ArmVirt ARM DEBUG + [Documentation] This test will run ARM DEBUG build for ArmVirtPkg + [Tags] PlatformCI ArmVirtPkg ARM GCC5 Ubuntu Qemu Edk2 + ${arch}= Set Variable ARM + ${target}= Set Variable DEBUG + ${package}= Set Variable ArmVirtPkg + ${ci_file}= Set Variable ${package}${/}PlatformCI${/}PlatformBuild.py + + # make sure on default branch + Reset git repo to default branch ${ws_root} ${default_branch} + + Stuart setup ${ci_file} ${arch} ${target} ${package} ${tool_chain} ${ws_root} + Stuart update ${ci_file} ${arch} ${target} ${package} ${tool_chain} ${ws_root} + Build BaseTools ${tool_chain} ${ws_root} + Stuart platform build ${ci_file} ${arch} ${target} ${tool_chain} ${ws_root} + +Run Edk2 ArmVirt ARM RELEASE + [Documentation] This test will run ARM RELEASE build for ArmVirtPkg + [Tags] PlatformCI ArmVirtPkg ARM GCC5 Ubuntu Qemu Edk2 + ${arch}= Set Variable ARM + ${target}= Set Variable RELEASE + ${package}= Set Variable ArmVirtPkg + ${ci_file}= Set Variable ${package}${/}PlatformCI${/}PlatformBuild.py + + # make sure on default branch + Reset git repo to default branch ${ws_root} ${default_branch} + + Stuart setup ${ci_file} ${arch} ${target} ${package} ${tool_chain} ${ws_root} + Stuart update ${ci_file} ${arch} ${target} ${package} ${tool_chain} ${ws_root} + Build BaseTools ${tool_chain} ${ws_root} + Stuart platform build ${ci_file} ${arch} ${target} ${tool_chain} ${ws_root} + +Run Edk2 ArmVirt AARCH64 DEBUG + [Documentation] This test will run AARCH64 DEBUG build for ArmVirtPkg + [Tags] PlatformCI ArmVirtPkg AARCH64 GCC5 Ubuntu Qemu Edk2 + ${arch}= Set Variable AARCH64 + ${target}= Set Variable DEBUG + ${package}= Set Variable ArmVirtPkg + ${ci_file}= Set Variable ${package}${/}PlatformCI${/}PlatformBuild.py + + # make sure on default branch + Reset git repo to default branch ${ws_root} ${default_branch} + + Stuart setup ${ci_file} ${arch} ${target} ${package} ${tool_chain} ${ws_root} + Stuart update ${ci_file} ${arch} ${target} ${package} ${tool_chain} ${ws_root} + Build BaseTools ${tool_chain} ${ws_root} + Stuart platform build ${ci_file} ${arch} ${target} ${tool_chain} ${ws_root} + +Run Edk2 ArmVirt AARCH64 RELEASE + [Documentation] This test will run AARCH64 RELEASE build for ArmVirtPkg + [Tags] PlatformCI ArmVirtPkg AARCH64 GCC5 Ubuntu Qemu Edk2 + ${arch}= Set Variable AARCH64 + ${target}= Set Variable RELEASE + ${package}= Set Variable ArmVirtPkg + ${ci_file}= Set Variable ${package}${/}PlatformCI${/}PlatformBuild.py + + # make sure on default branch + Reset git repo to default branch ${ws_root} ${default_branch} + + Stuart setup ${ci_file} ${arch} ${target} ${package} ${tool_chain} ${ws_root} + Stuart update ${ci_file} ${arch} ${target} ${package} ${tool_chain} ${ws_root} + Build BaseTools ${tool_chain} ${ws_root} + Stuart platform build ${ci_file} ${arch} ${target} ${tool_chain} ${ws_root} diff --git a/integration_test/edk2_platform_Windows.robot b/integration_test/edk2_platform_Windows.robot new file mode 100644 index 00000000..c12f8c02 --- /dev/null +++ b/integration_test/edk2_platform_Windows.robot @@ -0,0 +1,178 @@ +*** Settings *** +Documentation A test suite to test Platform CI on edk2 repo +# +# Copyright (c), Microsoft Corporation +# SPDX-License-Identifier: BSD-2-Clause-Patent + +Library Process +Library OperatingSystem +Library String + +Resource Shared_Keywords.robot + +Suite Setup One time setup ${repo_url} ${ws_dir} + +# Suite Setup + +*** Variables *** +${repo_url} https://github.com/tianocore/edk2.git +${default_branch} not_yet_set +${ws_dir} edk2 +${ws_root} ${TEST_OUTPUT}${/}${ws_dir} +${tool_chain} VS2019 + + +*** Keywords *** +One time setup + [Arguments] ${url} ${folder} + ## Dump pip versions + ${result}= Run Process python -m pip list shell=True + Log ${result.stdout} + + ## Make output directory if doesn't already exist + Create Directory ${TEST_OUTPUT} + + ## Clone repo + Run Keyword Clone the git repo ${url} ${folder} + + ## Figure out default branch + ${branch}= Get default branch from remote ${ws_root} + Set Suite Variable ${default_branch} ${branch} + + +*** Test Cases *** +Run Edk2 Ovmf IA32 DEBUG + [Documentation] This test will run IA32 DEBUG build for OvmfPkg + [Tags] PlatformCI OvmfPkg IA32 VS2019 Windows Qemu Edk2 + ${arch}= Set Variable IA32 + ${target}= Set Variable DEBUG + ${package}= Set Variable OvmfPkg + ${ci_file}= Set Variable ${package}${/}PlatformCI${/}PlatformBuild.py + + # make sure on default branch + Reset git repo to default branch ${ws_root} ${default_branch} + + Stuart setup ${ci_file} ${arch} ${target} ${package} ${tool_chain} ${ws_root} + Stuart update ${ci_file} ${arch} ${target} ${package} ${tool_chain} ${ws_root} + Build BaseTools ${tool_chain} ${ws_root} + Stuart platform build ${ci_file} ${arch} ${target} ${tool_chain} ${ws_root} + Stuart platform run ${ci_file} ${arch} ${target} ${tool_chain} MAKE_STARTUP_NSH\=TRUE ${ws_root} + +Run Edk2 Ovmf IA32 RELEASE + [Documentation] This test will run IA32 RELEASE build for OvmfPkg + [Tags] PlatformCI OvmfPkg IA32 VS2019 Windows Qemu Edk2 + ${arch}= Set Variable IA32 + ${target}= Set Variable RELEASE + ${package}= Set Variable OvmfPkg + ${ci_file}= Set Variable ${package}${/}PlatformCI${/}PlatformBuild.py + + # make sure on default branch + Reset git repo to default branch ${ws_root} ${default_branch} + + Stuart setup ${ci_file} ${arch} ${target} ${package} ${tool_chain} ${ws_root} + Stuart update ${ci_file} ${arch} ${target} ${package} ${tool_chain} ${ws_root} + Build BaseTools ${tool_chain} ${ws_root} + Stuart platform build ${ci_file} ${arch} ${target} ${tool_chain} ${ws_root} + Stuart platform run ${ci_file} ${arch} ${target} ${tool_chain} MAKE_STARTUP_NSH\=TRUE ${ws_root} + +Run Edk2 Ovmf X64 DEBUG + [Documentation] This test will run X64 DEBUG build for OvmfPkg + [Tags] PlatformCI OvmfPkg X64 VS2019 Windows Qemu Edk2 + ${arch}= Set Variable X64 + ${target}= Set Variable DEBUG + ${package}= Set Variable OvmfPkg + ${ci_file}= Set Variable ${package}${/}PlatformCI${/}PlatformBuild.py + + # make sure on default branch + Reset git repo to default branch ${ws_root} ${default_branch} + + Stuart setup ${ci_file} ${arch} ${target} ${package} ${tool_chain} ${ws_root} + Stuart update ${ci_file} ${arch} ${target} ${package} ${tool_chain} ${ws_root} + Build BaseTools ${tool_chain} ${ws_root} + Stuart platform build ${ci_file} ${arch} ${target} ${tool_chain} ${ws_root} + Stuart platform run ${ci_file} ${arch} ${target} ${tool_chain} MAKE_STARTUP_NSH\=TRUE ${ws_root} + +Run Edk2 Ovmf X64 RELEASE + [Documentation] This test will run X64 RELEASE build for OvmfPkg + [Tags] PlatformCI OvmfPkg X64 VS2019 Windows Qemu Edk2 + ${arch}= Set Variable X64 + ${target}= Set Variable RELEASE + ${package}= Set Variable OvmfPkg + ${ci_file}= Set Variable ${package}${/}PlatformCI${/}PlatformBuild.py + + # make sure on default branch + Reset git repo to default branch ${ws_root} ${default_branch} + + Stuart setup ${ci_file} ${arch} ${target} ${package} ${tool_chain} ${ws_root} + Stuart update ${ci_file} ${arch} ${target} ${package} ${tool_chain} ${ws_root} + Build BaseTools ${tool_chain} ${ws_root} + Stuart platform build ${ci_file} ${arch} ${target} ${tool_chain} ${ws_root} + Stuart platform run ${ci_file} ${arch} ${target} ${tool_chain} MAKE_STARTUP_NSH\=TRUE ${ws_root} + +Run Edk2 Emulator IA32 DEBUG + [Documentation] This test will run IA32 DEBUG build for EmulatorPkg + [Tags] PlatformCI EmulatorPkg IA32 VS2019 Windows Qemu Edk2 + ${arch}= Set Variable IA32 + ${target}= Set Variable DEBUG + ${package}= Set Variable EmulatorPkg + ${ci_file}= Set Variable ${package}${/}PlatformCI${/}PlatformBuild.py + + # make sure on default branch + Reset git repo to default branch ${ws_root} ${default_branch} + + Stuart setup ${ci_file} ${arch} ${target} ${package} ${tool_chain} ${ws_root} + Stuart update ${ci_file} ${arch} ${target} ${package} ${tool_chain} ${ws_root} + Build BaseTools ${tool_chain} ${ws_root} + Stuart platform build ${ci_file} ${arch} ${target} ${tool_chain} ${ws_root} + Stuart platform run ${ci_file} ${arch} ${target} ${tool_chain} MAKE_STARTUP_NSH\=TRUE ${ws_root} + +Run Edk2 Emulator IA32 RELEASE + [Documentation] This test will run IA32 RELEASE build for EmulatorPkg + [Tags] PlatformCI EmulatorPkg IA32 VS2019 Windows Qemu Edk2 + ${arch}= Set Variable IA32 + ${target}= Set Variable RELEASE + ${package}= Set Variable EmulatorPkg + ${ci_file}= Set Variable ${package}${/}PlatformCI${/}PlatformBuild.py + + # make sure on default branch + Reset git repo to default branch ${ws_root} ${default_branch} + + Stuart setup ${ci_file} ${arch} ${target} ${package} ${tool_chain} ${ws_root} + Stuart update ${ci_file} ${arch} ${target} ${package} ${tool_chain} ${ws_root} + Build BaseTools ${tool_chain} ${ws_root} + Stuart platform build ${ci_file} ${arch} ${target} ${tool_chain} ${ws_root} + Stuart platform run ${ci_file} ${arch} ${target} ${tool_chain} MAKE_STARTUP_NSH\=TRUE ${ws_root} + +Run Edk2 Emulator X64 DEBUG + [Documentation] This test will run X64 DEBUG build for EmulatorPkg + [Tags] PlatformCI EmulatorPkg X64 VS2019 Windows Qemu Edk2 + ${arch}= Set Variable X64 + ${target}= Set Variable DEBUG + ${package}= Set Variable EmulatorPkg + ${ci_file}= Set Variable ${package}${/}PlatformCI${/}PlatformBuild.py + + # make sure on default branch + Reset git repo to default branch ${ws_root} ${default_branch} + + Stuart setup ${ci_file} ${arch} ${target} ${package} ${tool_chain} ${ws_root} + Stuart update ${ci_file} ${arch} ${target} ${package} ${tool_chain} ${ws_root} + Build BaseTools ${tool_chain} ${ws_root} + Stuart platform build ${ci_file} ${arch} ${target} ${tool_chain} ${ws_root} + Stuart platform run ${ci_file} ${arch} ${target} ${tool_chain} MAKE_STARTUP_NSH\=TRUE ${ws_root} + +Run Edk2 Emulator X64 RELEASE + [Documentation] This test will run X64 RELEASE build for EmulatorPkg + [Tags] PlatformCI EmulatorPkg X64 VS2019 Windows Qemu Edk2 + ${arch}= Set Variable X64 + ${target}= Set Variable RELEASE + ${package}= Set Variable EmulatorPkg + ${ci_file}= Set Variable ${package}${/}PlatformCI${/}PlatformBuild.py + + # make sure on default branch + Reset git repo to default branch ${ws_root} ${default_branch} + + Stuart setup ${ci_file} ${arch} ${target} ${package} ${tool_chain} ${ws_root} + Stuart update ${ci_file} ${arch} ${target} ${package} ${tool_chain} ${ws_root} + Build BaseTools ${tool_chain} ${ws_root} + Stuart platform build ${ci_file} ${arch} ${target} ${tool_chain} ${ws_root} + Stuart platform run ${ci_file} ${arch} ${target} ${tool_chain} MAKE_STARTUP_NSH\=TRUE ${ws_root} diff --git a/integration_test/pip-requirements.txt b/integration_test/pip-requirements.txt new file mode 100644 index 00000000..a5032d75 --- /dev/null +++ b/integration_test/pip-requirements.txt @@ -0,0 +1,4 @@ +edk2-pytool-library==0.11.2 # Match edk2 +edk2-pytool-extensions~=0.16.0 # Match edk2 +robotframework +regex \ No newline at end of file