BaseTools/GNUmakefile:
[people/mcb30/basetools.git] / Tests / TestTools.py
1 ## @file
2 # Utility functions and classes for BaseTools unit tests
3 #
4 #  Copyright (c) 2008, Intel Corporation
5 #
6 #  All rights reserved. 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 #
18 import base64
19 import os
20 import os.path
21 import random
22 import shutil
23 import subprocess
24 import sys
25 import types
26 import unittest
27
28 TestsDir = os.path.realpath(os.path.split(sys.argv[0])[0])
29 BaseToolsDir = os.path.realpath(os.path.join(TestsDir, '..'))
30 CSource = os.path.join(BaseToolsDir, 'Source', 'C')
31 PythonSource = os.path.join(BaseToolsDir, 'Source', 'Python')
32 TestTempDir = os.path.join(TestsDir, 'TestTempDir')
33
34 def MakeTheTestSuite(localItems):
35     tests = []
36     for name, item in localItems.iteritems():
37         if isinstance(item, types.TypeType):
38             if issubclass(item, unittest.TestCase):
39                 tests.append(unittest.TestLoader().loadTestsFromTestCase(item))
40             elif issubclass(item, unittest.TestSuite):
41                 tests.append(item())
42     return lambda: unittest.TestSuite(tests)
43
44 def GetBaseToolsPath():
45     if sys.platform in ('win32', 'win64'):
46         return os.path.join(BaseToolsDir, 'Bin', sys.platform.title())
47     else:
48         uname = os.popen('uname -sm').read().strip()
49         for char in (' ', '/'):
50             uname = uname.replace(char, '-')
51         return os.path.join(BaseToolsDir, 'BinWrappers', uname)
52
53 BaseToolsBinPath = GetBaseToolsPath()
54
55 class BaseToolsTest(unittest.TestCase):
56
57     def cleanOutDir(self, dir):
58         for dirItem in os.listdir(dir):
59             if dirItem in ('.', '..'): continue
60             dirItem = os.path.join(dir, dirItem)
61             self.RemoveFileOrDir(dirItem)
62
63     def CleanUpTmpDir(self):
64         if os.path.exists(self.testDir):
65             self.cleanOutDir(self.testDir)
66
67     def HandleTreeDeleteError(self, function, path, excinfo):
68         os.chmod(path, stat.S_IWRITE)
69         function(path)
70     
71     def RemoveDir(self, dir):
72         shutil.rmtree(dir, False, self.HandleTreeDeleteError)
73
74     def RemoveFileOrDir(self, path):
75         if not os.path.exists(path):
76             return
77         elif os.path.isdir(path):
78             self.RemoveDir(path)
79         else:
80             os.remove(path)
81
82     def DisplayBinaryData(self, description, data):
83         print description, '(base64 encoded):'
84         b64data = base64.b64encode(data)
85         print b64data
86
87     def DisplayFile(self, fileName):
88         sys.stdout.write(self.ReadTmpFile(fileName))
89         sys.stdout.flush()
90
91     def RunTool(self, *args, **kwd):
92         if 'toolName' in kwd: toolName = kwd['toolName']
93         else: toolName = None
94         if 'logFile' in kwd: logFile = kwd['logFile']
95         else: logFile = None
96
97         if toolName is None: toolName = self.toolName
98         bin = os.path.join(self.baseToolsBins, toolName)
99         if logFile is not None:
100             logFile = open(os.path.join(self.testDir, logFile), 'w')
101             popenOut = logFile
102         else:
103             popenOut = subprocess.PIPE
104
105         args = [toolName] + list(args)
106
107         Proc = subprocess.Popen(
108             args, executable=bin,
109             stdout=popenOut, stderr=subprocess.STDOUT
110             )
111
112         if logFile is None:
113             Proc.stdout.read()
114
115         return Proc.wait()
116
117     def GetTmpFilePath(self, fileName):
118         return os.path.join(self.testDir, fileName)
119
120     def OpenTmpFile(self, fileName, mode = 'r'):
121         return open(os.path.join(self.testDir, fileName), mode)
122
123     def ReadTmpFile(self, fileName):
124         f = open(self.GetTmpFilePath(fileName), 'r')
125         data = f.read()
126         f.close()
127         return data
128
129     def WriteTmpFile(self, fileName, data):
130         f = open(self.GetTmpFilePath(fileName), 'w')
131         f.write(data)
132         f.close()
133
134     def GenRandomFileData(self, fileName, minlen = None, maxlen = None):
135         if maxlen is None: maxlen = minlen
136         f = self.OpenTmpFile(fileName, 'w')
137         f.write(self.GetRandomString(minlen, maxlen))
138         f.close()
139
140     def GetRandomString(self, minlen = None, maxlen = None):
141         if minlen is None: minlen = 1024
142         if maxlen is None: maxlen = minlen
143         return ''.join(
144             [chr(random.randint(0,255))
145              for x in xrange(random.randint(minlen, maxlen))
146             ])
147
148     def setUp(self):
149         self.savedEnvPath = os.environ['PATH']
150         self.savedSysPath = sys.path[:]
151
152         self.baseToolsBins = BaseToolsBinPath
153         os.environ['PATH'] = \
154             os.path.pathsep.join((os.environ['PATH'], self.baseToolsBins))
155
156         self.testDir = TestTempDir
157         if not os.path.exists(self.testDir):
158             os.mkdir(self.testDir)
159         else:
160             self.cleanOutDir(self.testDir)
161
162     def tearDown(self):
163         self.RemoveFileOrDir(self.testDir)
164
165         os.environ['PATH'] = self.savedEnvPath
166         sys.path = self.savedSysPath
167