tests/fsmonitor-run-tests.py
changeset 43076 2372284d9457
parent 40208 b7ba1cfba174
child 44468 55c443fcb4fc
equal deleted inserted replaced
43075:57875cf423c9 43076:2372284d9457
    26 
    26 
    27 osenvironb = getattr(os, 'environb', os.environ)
    27 osenvironb = getattr(os, 'environb', os.environ)
    28 
    28 
    29 if sys.version_info > (3, 5, 0):
    29 if sys.version_info > (3, 5, 0):
    30     PYTHON3 = True
    30     PYTHON3 = True
    31     xrange = range # we use xrange in one place, and we'd rather not use range
    31     xrange = range  # we use xrange in one place, and we'd rather not use range
       
    32 
    32     def _bytespath(p):
    33     def _bytespath(p):
    33         return p.encode('utf-8')
    34         return p.encode('utf-8')
    34 
    35 
       
    36 
    35 elif sys.version_info >= (3, 0, 0):
    37 elif sys.version_info >= (3, 0, 0):
    36     print('%s is only supported on Python 3.5+ and 2.7, not %s' %
    38     print(
    37           (sys.argv[0], '.'.join(str(v) for v in sys.version_info[:3])))
    39         '%s is only supported on Python 3.5+ and 2.7, not %s'
    38     sys.exit(70) # EX_SOFTWARE from `man 3 sysexit`
    40         % (sys.argv[0], '.'.join(str(v) for v in sys.version_info[:3]))
       
    41     )
       
    42     sys.exit(70)  # EX_SOFTWARE from `man 3 sysexit`
    39 else:
    43 else:
    40     PYTHON3 = False
    44     PYTHON3 = False
    41 
    45 
    42     # In python 2.x, path operations are generally done using
    46     # In python 2.x, path operations are generally done using
    43     # bytestrings by default, so we don't have to do any extra
    47     # bytestrings by default, so we don't have to do any extra
    44     # fiddling there. We define the wrapper functions anyway just to
    48     # fiddling there. We define the wrapper functions anyway just to
    45     # help keep code consistent between platforms.
    49     # help keep code consistent between platforms.
    46     def _bytespath(p):
    50     def _bytespath(p):
    47         return p
    51         return p
    48 
    52 
       
    53 
    49 def getparser():
    54 def getparser():
    50     """Obtain the argument parser used by the CLI."""
    55     """Obtain the argument parser used by the CLI."""
    51     parser = argparse.ArgumentParser(
    56     parser = argparse.ArgumentParser(
    52         description='Run tests with fsmonitor enabled.',
    57         description='Run tests with fsmonitor enabled.',
    53         epilog='Unrecognized options are passed to run-tests.py.')
    58         epilog='Unrecognized options are passed to run-tests.py.',
       
    59     )
    54     # - keep these sorted
    60     # - keep these sorted
    55     # - none of these options should conflict with any in run-tests.py
    61     # - none of these options should conflict with any in run-tests.py
    56     parser.add_argument('--keep-fsmonitor-tmpdir', action='store_true',
    62     parser.add_argument(
    57         help='keep temporary directory with fsmonitor state')
    63         '--keep-fsmonitor-tmpdir',
    58     parser.add_argument('--watchman',
    64         action='store_true',
       
    65         help='keep temporary directory with fsmonitor state',
       
    66     )
       
    67     parser.add_argument(
       
    68         '--watchman',
    59         help='location of watchman binary (default: watchman in PATH)',
    69         help='location of watchman binary (default: watchman in PATH)',
    60         default='watchman')
    70         default='watchman',
       
    71     )
    61 
    72 
    62     return parser
    73     return parser
       
    74 
    63 
    75 
    64 @contextlib.contextmanager
    76 @contextlib.contextmanager
    65 def watchman(args):
    77 def watchman(args):
    66     basedir = tempfile.mkdtemp(prefix='hg-fsmonitor')
    78     basedir = tempfile.mkdtemp(prefix='hg-fsmonitor')
    67     try:
    79     try:
    80         pidfile = os.path.join(basedir, 'pid')
    92         pidfile = os.path.join(basedir, 'pid')
    81         statefile = os.path.join(basedir, 'state')
    93         statefile = os.path.join(basedir, 'state')
    82 
    94 
    83         argv = [
    95         argv = [
    84             args.watchman,
    96             args.watchman,
    85             '--sockname', sockfile,
    97             '--sockname',
    86             '--logfile', logfile,
    98             sockfile,
    87             '--pidfile', pidfile,
    99             '--logfile',
    88             '--statefile', statefile,
   100             logfile,
       
   101             '--pidfile',
       
   102             pidfile,
       
   103             '--statefile',
       
   104             statefile,
    89             '--foreground',
   105             '--foreground',
    90             '--log-level=2', # debug logging for watchman
   106             '--log-level=2',  # debug logging for watchman
    91         ]
   107         ]
    92 
   108 
    93         envb = osenvironb.copy()
   109         envb = osenvironb.copy()
    94         envb[b'WATCHMAN_CONFIG_FILE'] = _bytespath(cfgfile)
   110         envb[b'WATCHMAN_CONFIG_FILE'] = _bytespath(cfgfile)
    95         with open(clilogfile, 'wb') as f:
   111         with open(clilogfile, 'wb') as f:
    96             proc = subprocess.Popen(
   112             proc = subprocess.Popen(
    97                 argv, env=envb, stdin=None, stdout=f, stderr=f)
   113                 argv, env=envb, stdin=None, stdout=f, stderr=f
       
   114             )
    98             try:
   115             try:
    99                 yield sockfile
   116                 yield sockfile
   100             finally:
   117             finally:
   101                 proc.terminate()
   118                 proc.terminate()
   102                 proc.kill()
   119                 proc.kill()
   103     finally:
   120     finally:
   104         if args.keep_fsmonitor_tmpdir:
   121         if args.keep_fsmonitor_tmpdir:
   105             print('fsmonitor dir available at %s' % basedir)
   122             print('fsmonitor dir available at %s' % basedir)
   106         else:
   123         else:
   107             shutil.rmtree(basedir, ignore_errors=True)
   124             shutil.rmtree(basedir, ignore_errors=True)
       
   125 
   108 
   126 
   109 def run():
   127 def run():
   110     parser = getparser()
   128     parser = getparser()
   111     args, runtestsargv = parser.parse_known_args()
   129     args, runtestsargv = parser.parse_known_args()
   112 
   130 
   118         runtestdir = os.path.dirname(__file__)
   136         runtestdir = os.path.dirname(__file__)
   119         runtests = os.path.join(runtestdir, 'run-tests.py')
   137         runtests = os.path.join(runtestdir, 'run-tests.py')
   120         blacklist = os.path.join(runtestdir, 'blacklists', 'fsmonitor')
   138         blacklist = os.path.join(runtestdir, 'blacklists', 'fsmonitor')
   121 
   139 
   122         runtestsargv.insert(0, runtests)
   140         runtestsargv.insert(0, runtests)
   123         runtestsargv.extend([
   141         runtestsargv.extend(
   124             '--extra-config',
   142             [
   125             'extensions.fsmonitor=',
   143                 '--extra-config',
   126             # specify fsmonitor.mode=paranoid always in order to force
   144                 'extensions.fsmonitor=',
   127             # fsmonitor extension execute "paranoid" code path
   145                 # specify fsmonitor.mode=paranoid always in order to force
   128             #
   146                 # fsmonitor extension execute "paranoid" code path
   129             # TODO: make fsmonitor-run-tests.py accept specific options
   147                 #
   130             '--extra-config',
   148                 # TODO: make fsmonitor-run-tests.py accept specific options
   131             'fsmonitor.mode=paranoid',
   149                 '--extra-config',
   132             '--blacklist',
   150                 'fsmonitor.mode=paranoid',
   133             blacklist,
   151                 '--blacklist',
   134         ])
   152                 blacklist,
       
   153             ]
       
   154         )
   135 
   155 
   136         return subprocess.call(runtestsargv)
   156         return subprocess.call(runtestsargv)
   137 
   157 
       
   158 
   138 if __name__ == '__main__':
   159 if __name__ == '__main__':
   139     sys.exit(run())
   160     sys.exit(run())