Home | History | Annotate | Download | only in Tests
      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 #

     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 CSourceDir = os.path.join(BaseToolsDir, 'Source', 'C')
     31 PythonSourceDir = os.path.join(BaseToolsDir, 'Source', 'Python')
     32 TestTempDir = os.path.join(TestsDir, 'TestTempDir')
     33 
     34 if 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 
     41 def 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 
     51 def 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 
     64 BaseToolsBinPaths = GetBaseToolsPaths()
     65 
     66 class 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