## @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