Skip to content

Commit

Permalink
Draft test code
Browse files Browse the repository at this point in the history
Signed-off-by: Dun Tan <[email protected]>
Signed-off-by: Dun Tan <[email protected]>
  • Loading branch information
td36 committed Nov 18, 2022
1 parent 8ca4504 commit 3c3459a
Show file tree
Hide file tree
Showing 2 changed files with 174 additions and 42 deletions.
25 changes: 25 additions & 0 deletions .azurepipelines/templates/UnitTest-build-steps.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
## @file
# File templates/basetools-build-job.yml
#
# template file to build basetools
#
# Copyright (c) Microsoft Corporation.
# SPDX-License-Identifier: BSD-2-Clause-Patent
##
parameters:
build_UnitTest_flag: ''

# Set default
- bash: echo "##vso[task.setvariable variable=UT_Count]${{ 0 }}"
# Pr eval
- task: CmdLine@1
inputs:
filename: stuart_pr_eval
arguments: -c OvmfPkg/PlatformCI/UnitTestBuild.py --output-count-format-string "##vso[task.setvariable variable=UT_Count;isOutpout=true]{pkgcount}"
condition: and(eq(variables['Build.Reason'], 'PullRequest'), in(parameters.build_UnitTest_flag, 'true'))
# Build
- task: CmdLine@1
inputs:
filename: stuart_build
arguments: -c OvmfPkg/PlatformCI/UnitTestBuild.py
condition: and(gt(variables.UT_Count, 0), succeeded())
191 changes: 149 additions & 42 deletions OvmfPkg/PlatformCI/TargetTestPlatformBuild.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,14 @@
# Copyright (c) Microsoft Corporation.
# SPDX-License-Identifier: BSD-2-Clause-Patent
##
from asyncio.windows_events import NULL
import shutil
import os
import sys
import logging
import argparse
from edk2toollib.utility_functions import RunCmd
from edk2toolext.environment import shell_environment

sys.path.append(os.path.dirname(os.path.abspath(__file__)))
from PlatformBuildLib import SettingsManager
Expand All @@ -19,6 +23,8 @@
class CommonPlatform():
''' Common settings for this platform. Define static data here and use
for the different parts of stuart
PackagesSupported = ("OvmfPkg", "UefiCpuPkg", "MdeModulePkg")
'''
PackagesSupported = ("OvmfPkg",)
ArchSupported = ("IA32", "X64")
Expand All @@ -31,62 +37,163 @@ class CommonPlatform():
def GetDscName(cls, ArchCsv: str) -> str:
''' return the DSC given the architectures requested.
TargetUnitTest: dsc file which contains target unit test module.
ArchCsv: csv string containing all architectures to build
dsc = "OvmfPkg"
if "IA32" in ArchCsv.upper().split(","):
dsc += "Ia32"
if "X64" in ArchCsv.upper().split(","):
dsc += "X64"
dsc += ".dsc"
return dsc
'''
return "TargetUnitTest/OvmfPkgTargetTest.dsc"

import PlatformBuildLib
PlatformBuildLib.CommonPlatform = CommonPlatform
class UnitTestSupport():
''' Common settings for this platform. Define static data here and use
for the different parts of stuart
UnitTestModule = {'UefiCpuPkg/Library/CpuExceptionHandlerLib/UnitTest/DxeCpuExceptionHandlerLibUnitTest.inf':'UefiCpuPkg.dsc',
'MdeModulePkg/Application/HelloWorld/HelloWorld.inf' :'MdeModulePkg.dsc'
}
PackagesToBuild = ["UefiCpuPkg", "MdeModulePkg"]
'''
UnitTestModule = {}
PackagesToBuild = []

class UnitTestPlatformBuilder(PlatformBuilder):
def CheckBootLog(self):
#
# Find all test results in boot log
#
return 0
def UpdateUnitTestConfig(self, args):
self.env = shell_environment.GetBuildVars()
'''Update UnitTestModule, PackagesSupported and PackagesToBuild in UnitTestSupport class'''
UnitTestModuleList = ';'.join(args.ShellUnitTestList).split(";")
if not UnitTestModuleList:
return
PackagesSupported = list(CommonPlatform.PackagesSupported)
for Module in UnitTestModuleList:
PkgName = Module.split("Pkg")[0] + 'Pkg'
if PkgName not in UnitTestSupport.UnitTestModule.keys():
UnitTestSupport.UnitTestModule[Module] = PkgName + '.dsc'
if PkgName not in PackagesSupported:
PackagesSupported.append(PkgName)
CommonPlatform.PackagesSupported = tuple(PackagesSupported)
print('PackagesSupported is {}'.format(CommonPlatform.PackagesSupported))
print('UnitTestModule is {}'.format(UnitTestSupport.UnitTestModule))
try:
PackagesToBuild = ','.join(args.PackagesForUT).split(',')
if PackagesToBuild:
UnitTestSupport.PackagesToBuild = PackagesToBuild
print('PackagesToBuild is {}'.format(UnitTestSupport.PackagesToBuild))
except:
pass

def FlashRomImage(self):
def BuildUnitTest(self, packageList):
VirtualDrive = os.path.join(self.env.GetValue("BUILD_OUTPUT_BASE"), "VirtualDrive")
os.makedirs(VirtualDrive, exist_ok=True)
OutputPath_FV = os.path.join(self.env.GetValue("BUILD_OUTPUT_BASE"), "FV")
BuiltDsc = []
for package in packageList:
print(package)
for Module, Dsc in UnitTestSupport.UnitTestModule.items():
if package in Dsc:
if Dsc not in BuiltDsc:
ModuleName = os.path.normpath(Module).split('.inf')[0].rsplit('\\')[-1]
BuiltDsc.append(Dsc)
DscPath = os.path.join(package, Dsc)
# Build specific dsc for UnitTest modules
print('Going to build this {0} for {1}'.format(DscPath, ModuleName))
Arch = self.env.GetValue("TARGET_ARCH").split(" ")
# Set the Unit Test arch the same as the Shell in Ovmf.
if 'X64' in Arch:
UTArch = 'X64'
else:
UTArch = 'IA32'
self.env.AllowOverride("ACTIVE_PLATFORM")
self.env.SetValue("ACTIVE_PLATFORM", DscPath, "Test")
self.env.AllowOverride("TARGET_ARCH")
self.env.SetValue("TARGET_ARCH", UTArch, "Test")
PlatformBuilder.Build(self)
# Copy the UnitTest efi files to VirtualDrive folder
EfiPath = os.path.join(self.env.GetValue("BUILD_OUTPUT_BASE"), UTArch, Module.split('.inf')[0], self.env.GetValue("TARGET"), ModuleName + '.efi')
print('Copy {0}.efi from:{1}'.format(ModuleName, EfiPath))
shutil.copy(EfiPath, VirtualDrive)

if (self.env.GetValue("QEMU_SKIP") and
self.env.GetValue("QEMU_SKIP").upper() == "TRUE"):
logging.info("skipping qemu boot test")
return 0
def WriteEfiToStartup(self, Folder):
''' Write all the .efi files' name in VirtualDrive into Startup.nsh'''
if (self.env.GetValue("MAKE_STARTUP_NSH").upper() == "TRUE"):
f = open(os.path.join(Folder, "startup.nsh"), "w")
for root,dirs,files in os.walk(Folder):
for file in files:
print(file)
print(os.path.splitext(file)[1])
if os.path.splitext(file)[1] == '.efi':
f.write("{0} \n".format(file))
f.write("reset -s\n")
f.close()

def CheckBootLog(self):
#
# QEMU must be on the path
# Find all FAILURE MESSAGE in boot log
#
cmd = "qemu-system-x86_64"
args = "-debugcon stdio" # write messages to stdio
args += " -global isa-debugcon.iobase=0x402" # debug messages out thru virtual io port
args += " -net none" # turn off network
args += f" -drive file=fat:rw:{VirtualDrive},format=raw,media=disk" # Mount disk with startup.nsh
#BuildLog = "BUILDLOG_{0}.txt".format(PlatformBuilder.GetName(self))
#LogPath = os.path.join(self.ws, 'Build', BuildLog)
LogPath = 'E:/code/FutureCoreRpArraw/RomImages/fail.log'
print('Checking the boot log: {0}'.format(LogPath))
file = open(LogPath, "r")
fileContent = file.readlines()
for Index in range(len(fileContent)):
if 'FAILURE MESSAGE:' in fileContent[Index]:
if fileContent[Index + 1].strip() != '':
FailureMessage = fileContent[Index + 1] + fileContent[Index + 2]
print(FailureMessage)
return FailureMessage
return 0

if (self.env.GetValue("QEMU_HEADLESS").upper() == "TRUE"):
args += " -display none" # no graphics
import PlatformBuildLib
UnitTestUnitTestConfig = UnitTestSupport()
PlatformBuildLib.CommonPlatform = CommonPlatform

print(os.path.join(OutputPath_FV, "OVMF.fd"))
args += " -pflash " + os.path.join(OutputPath_FV, "OVMF.fd") # path to firmware
class UnitTestSettingsManager(SettingsManager):
def GetPlatformDscAndConfig(self) -> tuple:
return None
def AddCommandLineOptions(self, parserObj):
print('AddCommandLineOptions in PrSettingsManager')
parserObj.add_argument('ShellUnitTestList', type=str,
help='Optional - A package or folder you want to update (workspace relative).'
'Can list multiple by doing -p <pkg1>,<pkg2> or -p <pkg3> -p <pkg4>',
action="append", default=[])

def RetrieveCommandLineOptions(self, args):
print('RetrieveCommandLineOptions in PrSettingsManager')
UnitTestUnitTestConfig.UpdateUnitTestConfig(args)

if (self.env.GetValue("MAKE_STARTUP_NSH").upper() == "TRUE"):
f = open(os.path.join(VirtualDrive, "startup.nsh"), "w")
f.write("BOOT SUCCESS !!! \n")
## add commands here
f.write("reset -s\n")
f.close()
class UnitTestPlatformBuilder(PlatformBuilder):
def AddCommandLineOptions(self, parserObj):
''' Add command line options to the argparser '''
print('AddCommandLineOptions in PlatformBuilder')
PlatformBuilder.AddCommandLineOptions(self, parserObj)
parserObj.add_argument('-p', '--pkg', '--pkg-dir', dest='PackagesForUT', type=str,
help='Optional - A package or folder you want to update (workspace relative).'
'Can list multiple by doing -p <pkg1>,<pkg2> or -p <pkg3> -p <pkg4>',
action="append", default=[])
parserObj.add_argument('ShellUnitTestList', type=str,
help='Optional - A package or folder you want to update (workspace relative).'
'Can list multiple by doing -p <pkg1>,<pkg2> or -p <pkg3> -p <pkg4>',
action="append", default=['None'])

ret = RunCmd(cmd, args)
print(args)
UnitTestResult = self.CheckBootLog()
def RetrieveCommandLineOptions(self, args):
''' Retrieve command line options from the argparser '''
print('RetrieveCommandLineOptions in PlatformBuilder')
PlatformBuilder.RetrieveCommandLineOptions(self, args)
UnitTestUnitTestConfig.UpdateUnitTestConfig(args)

def PlatformPostBuild(self):
''' Build specific Pkg in command line for UnitTest modules.'''
UnitTestUnitTestConfig.BuildUnitTest(UnitTestSupport.PackagesToBuild)
VirtualDrive = os.path.join(self.env.GetValue("BUILD_OUTPUT_BASE"), "VirtualDrive")
UnitTestUnitTestConfig.WriteEfiToStartup(VirtualDrive)
return 0

def FlashRomImage(self):
PlatformBuilder.FlashRomImage(self)
UnitTestResult = UnitTestUnitTestConfig.CheckBootLog()
if (UnitTestResult):
logging.info("UnitTest modules failed.")
logging.info("UnitTest failed with this FAILURE MESSAGE:\n{}".format(UnitTestResult))
return UnitTestResult
logging.info("UnitTest modules succussfully boot.")
if ret == 0xc0000005:
#for some reason getting a c0000005 on successful return
return 0

return ret
return 0

0 comments on commit 3c3459a

Please sign in to comment.