1## @file 2# Utility functions and classes for BaseTools unit tests 3# 4# Copyright (c) 2008 - 2015, Intel Corporation. All rights reserved.<BR> 5# 6# This program and the accompanying materials 7# are licensed and made available under the terms and conditions of the BSD License 8# which accompanies this distribution. The full text of the license may be found at 9# http://opensource.org/licenses/bsd-license.php 10# 11# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, 12# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. 13# 14 15## 16# Import Modules 17# 18import base64 19import os 20import os.path 21import random 22import shutil 23import subprocess 24import sys 25import types 26import unittest 27 28TestsDir = os.path.realpath(os.path.split(sys.argv[0])[0]) 29BaseToolsDir = os.path.realpath(os.path.join(TestsDir, '..')) 30CSourceDir = os.path.join(BaseToolsDir, 'Source', 'C') 31PythonSourceDir = os.path.join(BaseToolsDir, 'Source', 'Python') 32TestTempDir = os.path.join(TestsDir, 'TestTempDir') 33 34if PythonSourceDir not in sys.path: 35 # 36 # Allow unit tests to import BaseTools python modules. This is very useful 37 # for writing unit tests. 38 # 39 sys.path.append(PythonSourceDir) 40 41def MakeTheTestSuite(localItems): 42 tests = [] 43 for name, item in localItems.iteritems(): 44 if isinstance(item, types.TypeType): 45 if issubclass(item, unittest.TestCase): 46 tests.append(unittest.TestLoader().loadTestsFromTestCase(item)) 47 elif issubclass(item, unittest.TestSuite): 48 tests.append(item()) 49 return lambda: unittest.TestSuite(tests) 50 51def GetBaseToolsPaths(): 52 if sys.platform in ('win32', 'win64'): 53 return [ os.path.join(BaseToolsDir, 'Bin', sys.platform.title()) ] 54 else: 55 uname = os.popen('uname -sm').read().strip() 56 for char in (' ', '/'): 57 uname = uname.replace(char, '-') 58 return [ 59 os.path.join(BaseToolsDir, 'Bin', uname), 60 os.path.join(BaseToolsDir, 'BinWrappers', uname), 61 os.path.join(BaseToolsDir, 'BinWrappers', 'PosixLike') 62 ] 63 64BaseToolsBinPaths = GetBaseToolsPaths() 65 66class BaseToolsTest(unittest.TestCase): 67 68 def cleanOutDir(self, dir): 69 for dirItem in os.listdir(dir): 70 if dirItem in ('.', '..'): continue 71 dirItem = os.path.join(dir, dirItem) 72 self.RemoveFileOrDir(dirItem) 73 74 def CleanUpTmpDir(self): 75 if os.path.exists(self.testDir): 76 self.cleanOutDir(self.testDir) 77 78 def HandleTreeDeleteError(self, function, path, excinfo): 79 os.chmod(path, stat.S_IWRITE) 80 function(path) 81 82 def RemoveDir(self, dir): 83 shutil.rmtree(dir, False, self.HandleTreeDeleteError) 84 85 def RemoveFileOrDir(self, path): 86 if not os.path.exists(path): 87 return 88 elif os.path.isdir(path): 89 self.RemoveDir(path) 90 else: 91 os.remove(path) 92 93 def DisplayBinaryData(self, description, data): 94 print description, '(base64 encoded):' 95 b64data = base64.b64encode(data) 96 print b64data 97 98 def DisplayFile(self, fileName): 99 sys.stdout.write(self.ReadTmpFile(fileName)) 100 sys.stdout.flush() 101 102 def FindToolBin(self, toolName): 103 for binPath in BaseToolsBinPaths: 104 bin = os.path.join(binPath, toolName) 105 if os.path.exists(bin): 106 break 107 assert os.path.exists(bin) 108 return bin 109 110 def RunTool(self, *args, **kwd): 111 if 'toolName' in kwd: toolName = kwd['toolName'] 112 else: toolName = None 113 if 'logFile' in kwd: logFile = kwd['logFile'] 114 else: logFile = None 115 116 if toolName is None: toolName = self.toolName 117 bin = self.FindToolBin(toolName) 118 if logFile is not None: 119 logFile = open(os.path.join(self.testDir, logFile), 'w') 120 popenOut = logFile 121 else: 122 popenOut = subprocess.PIPE 123 124 args = [toolName] + list(args) 125 126 Proc = subprocess.Popen( 127 args, executable=bin, 128 stdout=popenOut, stderr=subprocess.STDOUT 129 ) 130 131 if logFile is None: 132 Proc.stdout.read() 133 134 return Proc.wait() 135 136 def GetTmpFilePath(self, fileName): 137 return os.path.join(self.testDir, fileName) 138 139 def OpenTmpFile(self, fileName, mode = 'r'): 140 return open(os.path.join(self.testDir, fileName), mode) 141 142 def ReadTmpFile(self, fileName): 143 f = open(self.GetTmpFilePath(fileName), 'r') 144 data = f.read() 145 f.close() 146 return data 147 148 def WriteTmpFile(self, fileName, data): 149 f = open(self.GetTmpFilePath(fileName), 'w') 150 f.write(data) 151 f.close() 152 153 def GenRandomFileData(self, fileName, minlen = None, maxlen = None): 154 if maxlen is None: maxlen = minlen 155 f = self.OpenTmpFile(fileName, 'w') 156 f.write(self.GetRandomString(minlen, maxlen)) 157 f.close() 158 159 def GetRandomString(self, minlen = None, maxlen = None): 160 if minlen is None: minlen = 1024 161 if maxlen is None: maxlen = minlen 162 return ''.join( 163 [chr(random.randint(0,255)) 164 for x in xrange(random.randint(minlen, maxlen)) 165 ]) 166 167 def setUp(self): 168 self.savedEnvPath = os.environ['PATH'] 169 self.savedSysPath = sys.path[:] 170 171 for binPath in BaseToolsBinPaths: 172 os.environ['PATH'] = \ 173 os.path.pathsep.join((os.environ['PATH'], binPath)) 174 175 self.testDir = TestTempDir 176 if not os.path.exists(self.testDir): 177 os.mkdir(self.testDir) 178 else: 179 self.cleanOutDir(self.testDir) 180 181 def tearDown(self): 182 self.RemoveFileOrDir(self.testDir) 183 184 os.environ['PATH'] = self.savedEnvPath 185 sys.path = self.savedSysPath 186 187