This allows unit tests to easily include BaseTools python modules. This is very useful for writing unit tests. Actually, previously, we would do this when RunTests.py was executed, so unit tests could easily import BaseTools modules, so long as they were executed via RunTests. This change allows running the unit test files individually which can be faster for developing the new unit test cases. Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Jordan Justen <jordan.l.justen@intel.com> Reviewed-by: Michael D Kinney <michael.d.kinney@intel.com> Reviewed-by: Yingke Liu <yingke.d.liu@intel.com> git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@17691 6f19259b-4bc3-4df7-8a09-765794883524
187 lines
5.9 KiB
Python
187 lines
5.9 KiB
Python
## @file
|
|
# Utility functions and classes for BaseTools unit tests
|
|
#
|
|
# Copyright (c) 2008 - 2015, Intel Corporation. All rights reserved.<BR>
|
|
#
|
|
# This program and the accompanying materials
|
|
# are licensed and made available under the terms and conditions of the BSD License
|
|
# which accompanies this distribution. The full text of the license may be found at
|
|
# http://opensource.org/licenses/bsd-license.php
|
|
#
|
|
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
|
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
|
#
|
|
|
|
##
|
|
# Import Modules
|
|
#
|
|
import base64
|
|
import os
|
|
import os.path
|
|
import random
|
|
import shutil
|
|
import subprocess
|
|
import sys
|
|
import types
|
|
import unittest
|
|
|
|
TestsDir = os.path.realpath(os.path.split(sys.argv[0])[0])
|
|
BaseToolsDir = os.path.realpath(os.path.join(TestsDir, '..'))
|
|
CSourceDir = os.path.join(BaseToolsDir, 'Source', 'C')
|
|
PythonSourceDir = os.path.join(BaseToolsDir, 'Source', 'Python')
|
|
TestTempDir = os.path.join(TestsDir, 'TestTempDir')
|
|
|
|
if PythonSourceDir not in sys.path:
|
|
#
|
|
# Allow unit tests to import BaseTools python modules. This is very useful
|
|
# for writing unit tests.
|
|
#
|
|
sys.path.append(PythonSourceDir)
|
|
|
|
def MakeTheTestSuite(localItems):
|
|
tests = []
|
|
for name, item in localItems.iteritems():
|
|
if isinstance(item, types.TypeType):
|
|
if issubclass(item, unittest.TestCase):
|
|
tests.append(unittest.TestLoader().loadTestsFromTestCase(item))
|
|
elif issubclass(item, unittest.TestSuite):
|
|
tests.append(item())
|
|
return lambda: unittest.TestSuite(tests)
|
|
|
|
def GetBaseToolsPaths():
|
|
if sys.platform in ('win32', 'win64'):
|
|
return [ os.path.join(BaseToolsDir, 'Bin', sys.platform.title()) ]
|
|
else:
|
|
uname = os.popen('uname -sm').read().strip()
|
|
for char in (' ', '/'):
|
|
uname = uname.replace(char, '-')
|
|
return [
|
|
os.path.join(BaseToolsDir, 'Bin', uname),
|
|
os.path.join(BaseToolsDir, 'BinWrappers', uname),
|
|
os.path.join(BaseToolsDir, 'BinWrappers', 'PosixLike')
|
|
]
|
|
|
|
BaseToolsBinPaths = GetBaseToolsPaths()
|
|
|
|
class BaseToolsTest(unittest.TestCase):
|
|
|
|
def cleanOutDir(self, dir):
|
|
for dirItem in os.listdir(dir):
|
|
if dirItem in ('.', '..'): continue
|
|
dirItem = os.path.join(dir, dirItem)
|
|
self.RemoveFileOrDir(dirItem)
|
|
|
|
def CleanUpTmpDir(self):
|
|
if os.path.exists(self.testDir):
|
|
self.cleanOutDir(self.testDir)
|
|
|
|
def HandleTreeDeleteError(self, function, path, excinfo):
|
|
os.chmod(path, stat.S_IWRITE)
|
|
function(path)
|
|
|
|
def RemoveDir(self, dir):
|
|
shutil.rmtree(dir, False, self.HandleTreeDeleteError)
|
|
|
|
def RemoveFileOrDir(self, path):
|
|
if not os.path.exists(path):
|
|
return
|
|
elif os.path.isdir(path):
|
|
self.RemoveDir(path)
|
|
else:
|
|
os.remove(path)
|
|
|
|
def DisplayBinaryData(self, description, data):
|
|
print description, '(base64 encoded):'
|
|
b64data = base64.b64encode(data)
|
|
print b64data
|
|
|
|
def DisplayFile(self, fileName):
|
|
sys.stdout.write(self.ReadTmpFile(fileName))
|
|
sys.stdout.flush()
|
|
|
|
def FindToolBin(self, toolName):
|
|
for binPath in BaseToolsBinPaths:
|
|
bin = os.path.join(binPath, toolName)
|
|
if os.path.exists(bin):
|
|
break
|
|
assert os.path.exists(bin)
|
|
return bin
|
|
|
|
def RunTool(self, *args, **kwd):
|
|
if 'toolName' in kwd: toolName = kwd['toolName']
|
|
else: toolName = None
|
|
if 'logFile' in kwd: logFile = kwd['logFile']
|
|
else: logFile = None
|
|
|
|
if toolName is None: toolName = self.toolName
|
|
bin = self.FindToolBin(toolName)
|
|
if logFile is not None:
|
|
logFile = open(os.path.join(self.testDir, logFile), 'w')
|
|
popenOut = logFile
|
|
else:
|
|
popenOut = subprocess.PIPE
|
|
|
|
args = [toolName] + list(args)
|
|
|
|
Proc = subprocess.Popen(
|
|
args, executable=bin,
|
|
stdout=popenOut, stderr=subprocess.STDOUT
|
|
)
|
|
|
|
if logFile is None:
|
|
Proc.stdout.read()
|
|
|
|
return Proc.wait()
|
|
|
|
def GetTmpFilePath(self, fileName):
|
|
return os.path.join(self.testDir, fileName)
|
|
|
|
def OpenTmpFile(self, fileName, mode = 'r'):
|
|
return open(os.path.join(self.testDir, fileName), mode)
|
|
|
|
def ReadTmpFile(self, fileName):
|
|
f = open(self.GetTmpFilePath(fileName), 'r')
|
|
data = f.read()
|
|
f.close()
|
|
return data
|
|
|
|
def WriteTmpFile(self, fileName, data):
|
|
f = open(self.GetTmpFilePath(fileName), 'w')
|
|
f.write(data)
|
|
f.close()
|
|
|
|
def GenRandomFileData(self, fileName, minlen = None, maxlen = None):
|
|
if maxlen is None: maxlen = minlen
|
|
f = self.OpenTmpFile(fileName, 'w')
|
|
f.write(self.GetRandomString(minlen, maxlen))
|
|
f.close()
|
|
|
|
def GetRandomString(self, minlen = None, maxlen = None):
|
|
if minlen is None: minlen = 1024
|
|
if maxlen is None: maxlen = minlen
|
|
return ''.join(
|
|
[chr(random.randint(0,255))
|
|
for x in xrange(random.randint(minlen, maxlen))
|
|
])
|
|
|
|
def setUp(self):
|
|
self.savedEnvPath = os.environ['PATH']
|
|
self.savedSysPath = sys.path[:]
|
|
|
|
for binPath in BaseToolsBinPaths:
|
|
os.environ['PATH'] = \
|
|
os.path.pathsep.join((os.environ['PATH'], binPath))
|
|
|
|
self.testDir = TestTempDir
|
|
if not os.path.exists(self.testDir):
|
|
os.mkdir(self.testDir)
|
|
else:
|
|
self.cleanOutDir(self.testDir)
|
|
|
|
def tearDown(self):
|
|
self.RemoveFileOrDir(self.testDir)
|
|
|
|
os.environ['PATH'] = self.savedEnvPath
|
|
sys.path = self.savedSysPath
|
|
|