config/tests/makefiles/autodeps/check_mkdir.tpy

changeset 0
6474c204b198
     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()

mercurial