Wed, 31 Dec 2014 06:09:35 +0100
Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.
michael@0 | 1 | #!/usr/bin/env python |
michael@0 | 2 | # |
michael@0 | 3 | # This Source Code Form is subject to the terms of the Mozilla Public |
michael@0 | 4 | # License, v. 2.0. If a copy of the MPL was not distributed with this file, |
michael@0 | 5 | # You can obtain one at http://mozilla.org/MPL/2.0/. |
michael@0 | 6 | # |
michael@0 | 7 | |
michael@0 | 8 | import os |
michael@0 | 9 | import sys |
michael@0 | 10 | import tempfile |
michael@0 | 11 | |
michael@0 | 12 | from subprocess import call |
michael@0 | 13 | from shutil import rmtree |
michael@0 | 14 | |
michael@0 | 15 | import logging |
michael@0 | 16 | import unittest |
michael@0 | 17 | |
michael@0 | 18 | |
michael@0 | 19 | def banner(): |
michael@0 | 20 | """ |
michael@0 | 21 | Display interpreter and system info for the test env |
michael@0 | 22 | """ |
michael@0 | 23 | print '*' * 75 |
michael@0 | 24 | cmd = os.path.basename(__file__) |
michael@0 | 25 | print "%s: python version is %s" % (cmd, sys.version) |
michael@0 | 26 | print '*' * 75 |
michael@0 | 27 | |
michael@0 | 28 | |
michael@0 | 29 | def myopts(vals): |
michael@0 | 30 | """ |
michael@0 | 31 | Storage for extra command line args passed. |
michael@0 | 32 | |
michael@0 | 33 | Returns: |
michael@0 | 34 | hash - argparse::Namespace object values |
michael@0 | 35 | """ |
michael@0 | 36 | |
michael@0 | 37 | if not hasattr(myopts, 'vals'): |
michael@0 | 38 | if 'argparse' in sys.modules: |
michael@0 | 39 | tmp = { } # key existance enables unittest module debug |
michael@0 | 40 | else: |
michael@0 | 41 | tmp = { 'debug': False, 'verbose': False } |
michael@0 | 42 | |
michael@0 | 43 | for k in dir(vals): |
michael@0 | 44 | if k[0:1] == '_': |
michael@0 | 45 | continue |
michael@0 | 46 | tmp[k] = getattr(vals, k) |
michael@0 | 47 | myopts.vals = tmp |
michael@0 | 48 | |
michael@0 | 49 | return myopts.vals |
michael@0 | 50 | |
michael@0 | 51 | |
michael@0 | 52 | def path2posix(src): |
michael@0 | 53 | """ |
michael@0 | 54 | Normalize directory path syntax |
michael@0 | 55 | |
michael@0 | 56 | Keyword arguments: |
michael@0 | 57 | src - path to normalize |
michael@0 | 58 | |
michael@0 | 59 | Returns: |
michael@0 | 60 | scalar - a file path with drive separators and windows slashes removed |
michael@0 | 61 | |
michael@0 | 62 | Todo: |
michael@0 | 63 | move to {build,config,tools,toolkit}/python for use in a library |
michael@0 | 64 | """ |
michael@0 | 65 | |
michael@0 | 66 | ## (drive, tail) = os.path.splitdrive(src) |
michael@0 | 67 | ## Support path testing on all platforms |
michael@0 | 68 | drive = '' |
michael@0 | 69 | winpath = src.find(':') |
michael@0 | 70 | if -1 != winpath and 10 > winpath: |
michael@0 | 71 | (drive, tail) = src.split(':', 1) |
michael@0 | 72 | |
michael@0 | 73 | if drive: |
michael@0 | 74 | todo = [ '', drive.rstrip(':').lstrip('/').lstrip('\\') ] |
michael@0 | 75 | todo.extend( tail.lstrip('/').lstrip('\\').split('\\') ) # c:\a => [a] |
michael@0 | 76 | else: # os.name == 'posix' |
michael@0 | 77 | todo = src.split('\\') |
michael@0 | 78 | |
michael@0 | 79 | dst = '/'.join(todo) |
michael@0 | 80 | return dst |
michael@0 | 81 | |
michael@0 | 82 | |
michael@0 | 83 | def checkMkdir(work, debug=False): |
michael@0 | 84 | """ |
michael@0 | 85 | Verify arg permutations for directory mutex creation. |
michael@0 | 86 | |
michael@0 | 87 | Keyword arguments: |
michael@0 | 88 | None |
michael@0 | 89 | |
michael@0 | 90 | Returns: |
michael@0 | 91 | Exception on error |
michael@0 | 92 | |
michael@0 | 93 | Note: |
michael@0 | 94 | Exception() rather than self.assertTrue() is used in this test |
michael@0 | 95 | function to enable scatch cleanup on test exit/failure conditions. |
michael@0 | 96 | Not guaranteed by python closures on early exit. |
michael@0 | 97 | """ |
michael@0 | 98 | |
michael@0 | 99 | logging.debug("Testing: checkMkdir") |
michael@0 | 100 | |
michael@0 | 101 | # On Windows, don't convert paths to POSIX |
michael@0 | 102 | skipposix = sys.platform == "win32" |
michael@0 | 103 | if skipposix: |
michael@0 | 104 | path = os.path.abspath(__file__) |
michael@0 | 105 | dirname_fun = os.path.dirname |
michael@0 | 106 | else: |
michael@0 | 107 | path = path2posix(os.path.abspath(__file__)) |
michael@0 | 108 | import posixpath |
michael@0 | 109 | dirname_fun = posixpath.dirname |
michael@0 | 110 | |
michael@0 | 111 | src = dirname_fun(path) |
michael@0 | 112 | # root is 5 directories up from path |
michael@0 | 113 | root = reduce(lambda x, _: dirname_fun(x), xrange(5), path) |
michael@0 | 114 | |
michael@0 | 115 | rootP = path2posix(root) |
michael@0 | 116 | srcP = path2posix(src) |
michael@0 | 117 | workP = path2posix(work) |
michael@0 | 118 | |
michael@0 | 119 | # C:\foo -vs- /c/foo |
michael@0 | 120 | # [0] command paths use /c/foo |
michael@0 | 121 | # [1] os.path.exists() on mingw() requires C:\ |
michael@0 | 122 | paths = [ |
michael@0 | 123 | "mkdir_bycall", # function generated |
michael@0 | 124 | "mkdir_bydep", # explicit dependency |
michael@0 | 125 | "mkdir_bygen", # by GENERATED_DIRS macro |
michael@0 | 126 | ] |
michael@0 | 127 | |
michael@0 | 128 | ## Use make from the parent "make check" call when available |
michael@0 | 129 | cmd = { 'make': 'make' } |
michael@0 | 130 | shell0 = os.environ.get('MAKE') |
michael@0 | 131 | if shell0: |
michael@0 | 132 | shell = os.path.splitext(shell0)[0] # strip: .exe, .py |
michael@0 | 133 | if -1 != shell.find('make'): |
michael@0 | 134 | print "MAKE COMMAND FOUND: %s" % (shell0) |
michael@0 | 135 | cmd['make'] = shell0 if skipposix else path2posix(shell0) |
michael@0 | 136 | |
michael@0 | 137 | args = [] |
michael@0 | 138 | args.append('%s' % (cmd['make'])) |
michael@0 | 139 | args.append('-C %s' % (work if skipposix else workP)) |
michael@0 | 140 | args.append("-f %s/testor.tmpl" % (src if skipposix else srcP)) |
michael@0 | 141 | args.append('topsrcdir=%s' % (root if skipposix else rootP)) |
michael@0 | 142 | args.append('deps_mkdir_bycall=%s' % paths[0]) |
michael@0 | 143 | args.append('deps_mkdir_bydep=%s' % paths[1]) |
michael@0 | 144 | args.append('deps_mkdir_bygen=%s' % paths[2]) |
michael@0 | 145 | args.append('checkup') # target |
michael@0 | 146 | |
michael@0 | 147 | # Call will fail on mingw with output redirected ?!? |
michael@0 | 148 | if debug: |
michael@0 | 149 | pass |
michael@0 | 150 | if False: # if not debug: |
michael@0 | 151 | args.append('>/dev/null') |
michael@0 | 152 | |
michael@0 | 153 | cmd = '%s' % (' '.join(args)) |
michael@0 | 154 | logging.debug("Running: %s" % (cmd)) |
michael@0 | 155 | rc = call(cmd, shell=True) |
michael@0 | 156 | if rc: |
michael@0 | 157 | raise Exception("make failed ($?=%s): cmd=%s" % (rc, cmd)) |
michael@0 | 158 | |
michael@0 | 159 | for i in paths: |
michael@0 | 160 | path = os.path.join(work, i) |
michael@0 | 161 | logging.debug("Did testing mkdir(%s) succeed?" % (path)) |
michael@0 | 162 | if not os.path.exists(path): |
michael@0 | 163 | raise Exception("Test path %s does not exist" % (path)) |
michael@0 | 164 | |
michael@0 | 165 | |
michael@0 | 166 | def parseargs(): |
michael@0 | 167 | """ |
michael@0 | 168 | Support additional command line arguments for testing |
michael@0 | 169 | |
michael@0 | 170 | Returns: |
michael@0 | 171 | hash - arguments of interested parsed from the command line |
michael@0 | 172 | """ |
michael@0 | 173 | |
michael@0 | 174 | opts = None |
michael@0 | 175 | try: |
michael@0 | 176 | import argparse2 |
michael@0 | 177 | parser = argparse.ArgumentParser() |
michael@0 | 178 | parser.add_argument('--debug', |
michael@0 | 179 | action="store_true", |
michael@0 | 180 | default=False, |
michael@0 | 181 | help='Enable debug mode') |
michael@0 | 182 | # Cannot overload verbose, Verbose: False enables debugging |
michael@0 | 183 | parser.add_argument('--verbose', |
michael@0 | 184 | action="store_true", |
michael@0 | 185 | default=False, |
michael@0 | 186 | help='Enable verbose mode') |
michael@0 | 187 | parser.add_argument('unittest_args', |
michael@0 | 188 | nargs='*' |
michael@0 | 189 | # help='Slurp/pass remaining args to unittest' |
michael@0 | 190 | ) |
michael@0 | 191 | opts = parser.parse_args() |
michael@0 | 192 | |
michael@0 | 193 | except ImportError: |
michael@0 | 194 | pass |
michael@0 | 195 | |
michael@0 | 196 | return opts |
michael@0 | 197 | |
michael@0 | 198 | |
michael@0 | 199 | class TestMakeLogic(unittest.TestCase): |
michael@0 | 200 | """ |
michael@0 | 201 | Test suite used to validate makefile library rules and macros |
michael@0 | 202 | """ |
michael@0 | 203 | |
michael@0 | 204 | def setUp(self): |
michael@0 | 205 | opts = myopts(None) # NameSpace object not hash |
michael@0 | 206 | self.debug = opts['debug'] |
michael@0 | 207 | self.verbose = opts['verbose'] |
michael@0 | 208 | |
michael@0 | 209 | if self.debug: |
michael@0 | 210 | logging.basicConfig(level=logging.DEBUG) |
michael@0 | 211 | |
michael@0 | 212 | if self.verbose: |
michael@0 | 213 | |
michael@0 | 214 | print "ENVIRONMENT DUMP:" |
michael@0 | 215 | print '=' * 75 |
michael@0 | 216 | for k,v in os.environ.items(): |
michael@0 | 217 | print "env{%s} => %s" % (k, v) |
michael@0 | 218 | |
michael@0 | 219 | |
michael@0 | 220 | |
michael@0 | 221 | def test_path2posix(self): |
michael@0 | 222 | |
michael@0 | 223 | todo = { |
michael@0 | 224 | '/dev/null' : '/dev/null', |
michael@0 | 225 | 'A:\\a\\b\\c' : '/A/a/b/c', |
michael@0 | 226 | 'B:/x/y' : '/B/x/y', |
michael@0 | 227 | 'C:/x\\y/z' : '/C/x/y/z', |
michael@0 | 228 | '//FOO/bar/tans': '//FOO/bar/tans', |
michael@0 | 229 | '//X\\a/b\\c/d' : '//X/a/b/c/d', |
michael@0 | 230 | '\\c:mozilla\\sandbox': '/c/mozilla/sandbox', |
michael@0 | 231 | } |
michael@0 | 232 | |
michael@0 | 233 | for val,exp in todo.items(): |
michael@0 | 234 | found = path2posix(val) |
michael@0 | 235 | tst = "posix2path(%s): %s != %s)" % (val, exp, found) |
michael@0 | 236 | self.assertEqual(exp, found, "%s: invalid path detected" % (tst)) |
michael@0 | 237 | |
michael@0 | 238 | |
michael@0 | 239 | def test_mkdir(self): |
michael@0 | 240 | """ |
michael@0 | 241 | Verify directory creation rules and macros |
michael@0 | 242 | """ |
michael@0 | 243 | |
michael@0 | 244 | failed = True |
michael@0 | 245 | |
michael@0 | 246 | # Exception handling is used to cleanup scratch space on error |
michael@0 | 247 | try: |
michael@0 | 248 | work = tempfile.mkdtemp() |
michael@0 | 249 | checkMkdir(work, self.debug) |
michael@0 | 250 | failed = False |
michael@0 | 251 | finally: |
michael@0 | 252 | if os.path.exists(work): |
michael@0 | 253 | rmtree(work) |
michael@0 | 254 | |
michael@0 | 255 | self.assertFalse(failed, "Unit test failure detected") |
michael@0 | 256 | |
michael@0 | 257 | |
michael@0 | 258 | if __name__ == '__main__': |
michael@0 | 259 | banner() |
michael@0 | 260 | opts = parseargs() |
michael@0 | 261 | myopts(opts) |
michael@0 | 262 | |
michael@0 | 263 | if opts: |
michael@0 | 264 | if hasattr(opts, 'unittest_args'): |
michael@0 | 265 | sys.argv[1:] = opts.unittest_args |
michael@0 | 266 | else: |
michael@0 | 267 | sys.argv[1:] = [] |
michael@0 | 268 | |
michael@0 | 269 | unittest.main() |