1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/config/tests/makefiles/autodeps/check_mkdir.tpy Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,269 @@ 1.4 +#!/usr/bin/env python 1.5 +# 1.6 +# This Source Code Form is subject to the terms of the Mozilla Public 1.7 +# License, v. 2.0. If a copy of the MPL was not distributed with this file, 1.8 +# You can obtain one at http://mozilla.org/MPL/2.0/. 1.9 +# 1.10 + 1.11 +import os 1.12 +import sys 1.13 +import tempfile 1.14 + 1.15 +from subprocess import call 1.16 +from shutil import rmtree 1.17 + 1.18 +import logging 1.19 +import unittest 1.20 + 1.21 + 1.22 +def banner(): 1.23 + """ 1.24 + Display interpreter and system info for the test env 1.25 + """ 1.26 + print '*' * 75 1.27 + cmd = os.path.basename(__file__) 1.28 + print "%s: python version is %s" % (cmd, sys.version) 1.29 + print '*' * 75 1.30 + 1.31 + 1.32 +def myopts(vals): 1.33 + """ 1.34 + Storage for extra command line args passed. 1.35 + 1.36 + Returns: 1.37 + hash - argparse::Namespace object values 1.38 + """ 1.39 + 1.40 + if not hasattr(myopts, 'vals'): 1.41 + if 'argparse' in sys.modules: 1.42 + tmp = { } # key existance enables unittest module debug 1.43 + else: 1.44 + tmp = { 'debug': False, 'verbose': False } 1.45 + 1.46 + for k in dir(vals): 1.47 + if k[0:1] == '_': 1.48 + continue 1.49 + tmp[k] = getattr(vals, k) 1.50 + myopts.vals = tmp 1.51 + 1.52 + return myopts.vals 1.53 + 1.54 + 1.55 +def path2posix(src): 1.56 + """ 1.57 + Normalize directory path syntax 1.58 + 1.59 + Keyword arguments: 1.60 + src - path to normalize 1.61 + 1.62 + Returns: 1.63 + scalar - a file path with drive separators and windows slashes removed 1.64 + 1.65 + Todo: 1.66 + move to {build,config,tools,toolkit}/python for use in a library 1.67 + """ 1.68 + 1.69 + ## (drive, tail) = os.path.splitdrive(src) 1.70 + ## Support path testing on all platforms 1.71 + drive = '' 1.72 + winpath = src.find(':') 1.73 + if -1 != winpath and 10 > winpath: 1.74 + (drive, tail) = src.split(':', 1) 1.75 + 1.76 + if drive: 1.77 + todo = [ '', drive.rstrip(':').lstrip('/').lstrip('\\') ] 1.78 + todo.extend( tail.lstrip('/').lstrip('\\').split('\\') ) # c:\a => [a] 1.79 + else: # os.name == 'posix' 1.80 + todo = src.split('\\') 1.81 + 1.82 + dst = '/'.join(todo) 1.83 + return dst 1.84 + 1.85 + 1.86 +def checkMkdir(work, debug=False): 1.87 + """ 1.88 + Verify arg permutations for directory mutex creation. 1.89 + 1.90 + Keyword arguments: 1.91 + None 1.92 + 1.93 + Returns: 1.94 + Exception on error 1.95 + 1.96 + Note: 1.97 + Exception() rather than self.assertTrue() is used in this test 1.98 + function to enable scatch cleanup on test exit/failure conditions. 1.99 + Not guaranteed by python closures on early exit. 1.100 + """ 1.101 + 1.102 + logging.debug("Testing: checkMkdir") 1.103 + 1.104 + # On Windows, don't convert paths to POSIX 1.105 + skipposix = sys.platform == "win32" 1.106 + if skipposix: 1.107 + path = os.path.abspath(__file__) 1.108 + dirname_fun = os.path.dirname 1.109 + else: 1.110 + path = path2posix(os.path.abspath(__file__)) 1.111 + import posixpath 1.112 + dirname_fun = posixpath.dirname 1.113 + 1.114 + src = dirname_fun(path) 1.115 + # root is 5 directories up from path 1.116 + root = reduce(lambda x, _: dirname_fun(x), xrange(5), path) 1.117 + 1.118 + rootP = path2posix(root) 1.119 + srcP = path2posix(src) 1.120 + workP = path2posix(work) 1.121 + 1.122 + # C:\foo -vs- /c/foo 1.123 + # [0] command paths use /c/foo 1.124 + # [1] os.path.exists() on mingw() requires C:\ 1.125 + paths = [ 1.126 + "mkdir_bycall", # function generated 1.127 + "mkdir_bydep", # explicit dependency 1.128 + "mkdir_bygen", # by GENERATED_DIRS macro 1.129 + ] 1.130 + 1.131 + ## Use make from the parent "make check" call when available 1.132 + cmd = { 'make': 'make' } 1.133 + shell0 = os.environ.get('MAKE') 1.134 + if shell0: 1.135 + shell = os.path.splitext(shell0)[0] # strip: .exe, .py 1.136 + if -1 != shell.find('make'): 1.137 + print "MAKE COMMAND FOUND: %s" % (shell0) 1.138 + cmd['make'] = shell0 if skipposix else path2posix(shell0) 1.139 + 1.140 + args = [] 1.141 + args.append('%s' % (cmd['make'])) 1.142 + args.append('-C %s' % (work if skipposix else workP)) 1.143 + args.append("-f %s/testor.tmpl" % (src if skipposix else srcP)) 1.144 + args.append('topsrcdir=%s' % (root if skipposix else rootP)) 1.145 + args.append('deps_mkdir_bycall=%s' % paths[0]) 1.146 + args.append('deps_mkdir_bydep=%s' % paths[1]) 1.147 + args.append('deps_mkdir_bygen=%s' % paths[2]) 1.148 + args.append('checkup') # target 1.149 + 1.150 + # Call will fail on mingw with output redirected ?!? 1.151 + if debug: 1.152 + pass 1.153 + if False: # if not debug: 1.154 + args.append('>/dev/null') 1.155 + 1.156 + cmd = '%s' % (' '.join(args)) 1.157 + logging.debug("Running: %s" % (cmd)) 1.158 + rc = call(cmd, shell=True) 1.159 + if rc: 1.160 + raise Exception("make failed ($?=%s): cmd=%s" % (rc, cmd)) 1.161 + 1.162 + for i in paths: 1.163 + path = os.path.join(work, i) 1.164 + logging.debug("Did testing mkdir(%s) succeed?" % (path)) 1.165 + if not os.path.exists(path): 1.166 + raise Exception("Test path %s does not exist" % (path)) 1.167 + 1.168 + 1.169 +def parseargs(): 1.170 + """ 1.171 + Support additional command line arguments for testing 1.172 + 1.173 + Returns: 1.174 + hash - arguments of interested parsed from the command line 1.175 + """ 1.176 + 1.177 + opts = None 1.178 + try: 1.179 + import argparse2 1.180 + parser = argparse.ArgumentParser() 1.181 + parser.add_argument('--debug', 1.182 + action="store_true", 1.183 + default=False, 1.184 + help='Enable debug mode') 1.185 + # Cannot overload verbose, Verbose: False enables debugging 1.186 + parser.add_argument('--verbose', 1.187 + action="store_true", 1.188 + default=False, 1.189 + help='Enable verbose mode') 1.190 + parser.add_argument('unittest_args', 1.191 + nargs='*' 1.192 + # help='Slurp/pass remaining args to unittest' 1.193 + ) 1.194 + opts = parser.parse_args() 1.195 + 1.196 + except ImportError: 1.197 + pass 1.198 + 1.199 + return opts 1.200 + 1.201 + 1.202 +class TestMakeLogic(unittest.TestCase): 1.203 + """ 1.204 + Test suite used to validate makefile library rules and macros 1.205 + """ 1.206 + 1.207 + def setUp(self): 1.208 + opts = myopts(None) # NameSpace object not hash 1.209 + self.debug = opts['debug'] 1.210 + self.verbose = opts['verbose'] 1.211 + 1.212 + if self.debug: 1.213 + logging.basicConfig(level=logging.DEBUG) 1.214 + 1.215 + if self.verbose: 1.216 + print 1.217 + print "ENVIRONMENT DUMP:" 1.218 + print '=' * 75 1.219 + for k,v in os.environ.items(): 1.220 + print "env{%s} => %s" % (k, v) 1.221 + print 1.222 + 1.223 + 1.224 + def test_path2posix(self): 1.225 + 1.226 + todo = { 1.227 + '/dev/null' : '/dev/null', 1.228 + 'A:\\a\\b\\c' : '/A/a/b/c', 1.229 + 'B:/x/y' : '/B/x/y', 1.230 + 'C:/x\\y/z' : '/C/x/y/z', 1.231 + '//FOO/bar/tans': '//FOO/bar/tans', 1.232 + '//X\\a/b\\c/d' : '//X/a/b/c/d', 1.233 + '\\c:mozilla\\sandbox': '/c/mozilla/sandbox', 1.234 + } 1.235 + 1.236 + for val,exp in todo.items(): 1.237 + found = path2posix(val) 1.238 + tst = "posix2path(%s): %s != %s)" % (val, exp, found) 1.239 + self.assertEqual(exp, found, "%s: invalid path detected" % (tst)) 1.240 + 1.241 + 1.242 + def test_mkdir(self): 1.243 + """ 1.244 + Verify directory creation rules and macros 1.245 + """ 1.246 + 1.247 + failed = True 1.248 + 1.249 + # Exception handling is used to cleanup scratch space on error 1.250 + try: 1.251 + work = tempfile.mkdtemp() 1.252 + checkMkdir(work, self.debug) 1.253 + failed = False 1.254 + finally: 1.255 + if os.path.exists(work): 1.256 + rmtree(work) 1.257 + 1.258 + self.assertFalse(failed, "Unit test failure detected") 1.259 + 1.260 + 1.261 +if __name__ == '__main__': 1.262 + banner() 1.263 + opts = parseargs() 1.264 + myopts(opts) 1.265 + 1.266 + if opts: 1.267 + if hasattr(opts, 'unittest_args'): 1.268 + sys.argv[1:] = opts.unittest_args 1.269 + else: 1.270 + sys.argv[1:] = [] 1.271 + 1.272 + unittest.main()