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