tests/killdaemons.py
author Simon Heimberg <simohe@besonet.ch>
Fri, 17 Jan 2014 21:13:08 +0100
branchstable
changeset 1329 10d0d9d5c0f0
parent 1128 7f09e7ac63a7
child 1330 e2fe607966f6
permissions -rw-r--r--
tests: kill for windows in killdaemons.py checks return values The return values of the windll calls are checked and when an error is indicated, it is raised. The handle is still closed properly. [ original upstream message ]
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
1123
17bcbb020dda tests: add killdaemons helper script
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
     1
#!/usr/bin/env python
17bcbb020dda tests: add killdaemons helper script
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
     2
1128
7f09e7ac63a7 killdaemons: take file argument explicitely
Patrick Mezard <patrick@mezard.eu>
parents: 1127
diff changeset
     3
import os, sys, time, errno, signal
1123
17bcbb020dda tests: add killdaemons helper script
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
     4
1127
79d7aa832cf4 killdaemons: add windows implementation
Patrick Mezard <patrick@mezard.eu>
parents: 1126
diff changeset
     5
if os.name =='nt':
79d7aa832cf4 killdaemons: add windows implementation
Patrick Mezard <patrick@mezard.eu>
parents: 1126
diff changeset
     6
    import ctypes
1329
10d0d9d5c0f0 tests: kill for windows in killdaemons.py checks return values
Simon Heimberg <simohe@besonet.ch>
parents: 1128
diff changeset
     7
10d0d9d5c0f0 tests: kill for windows in killdaemons.py checks return values
Simon Heimberg <simohe@besonet.ch>
parents: 1128
diff changeset
     8
    def _check(ret, expectederr=None):
10d0d9d5c0f0 tests: kill for windows in killdaemons.py checks return values
Simon Heimberg <simohe@besonet.ch>
parents: 1128
diff changeset
     9
        if ret == 0:
10d0d9d5c0f0 tests: kill for windows in killdaemons.py checks return values
Simon Heimberg <simohe@besonet.ch>
parents: 1128
diff changeset
    10
            winerrno = ctypes.GetLastError()
10d0d9d5c0f0 tests: kill for windows in killdaemons.py checks return values
Simon Heimberg <simohe@besonet.ch>
parents: 1128
diff changeset
    11
            if winerrno == expectederr:
10d0d9d5c0f0 tests: kill for windows in killdaemons.py checks return values
Simon Heimberg <simohe@besonet.ch>
parents: 1128
diff changeset
    12
                return True
10d0d9d5c0f0 tests: kill for windows in killdaemons.py checks return values
Simon Heimberg <simohe@besonet.ch>
parents: 1128
diff changeset
    13
            raise ctypes.WinError(winerrno)
10d0d9d5c0f0 tests: kill for windows in killdaemons.py checks return values
Simon Heimberg <simohe@besonet.ch>
parents: 1128
diff changeset
    14
1127
79d7aa832cf4 killdaemons: add windows implementation
Patrick Mezard <patrick@mezard.eu>
parents: 1126
diff changeset
    15
    def kill(pid, logfn, tryhard=True):
79d7aa832cf4 killdaemons: add windows implementation
Patrick Mezard <patrick@mezard.eu>
parents: 1126
diff changeset
    16
        logfn('# Killing daemon process %d' % pid)
79d7aa832cf4 killdaemons: add windows implementation
Patrick Mezard <patrick@mezard.eu>
parents: 1126
diff changeset
    17
        PROCESS_TERMINATE = 1
79d7aa832cf4 killdaemons: add windows implementation
Patrick Mezard <patrick@mezard.eu>
parents: 1126
diff changeset
    18
        handle = ctypes.windll.kernel32.OpenProcess(
79d7aa832cf4 killdaemons: add windows implementation
Patrick Mezard <patrick@mezard.eu>
parents: 1126
diff changeset
    19
                PROCESS_TERMINATE, False, pid)
1329
10d0d9d5c0f0 tests: kill for windows in killdaemons.py checks return values
Simon Heimberg <simohe@besonet.ch>
parents: 1128
diff changeset
    20
        if handle == 0:
10d0d9d5c0f0 tests: kill for windows in killdaemons.py checks return values
Simon Heimberg <simohe@besonet.ch>
parents: 1128
diff changeset
    21
            # TODO: call _check(0, expected) to check if "process not found"
10d0d9d5c0f0 tests: kill for windows in killdaemons.py checks return values
Simon Heimberg <simohe@besonet.ch>
parents: 1128
diff changeset
    22
            return # process not found, already finished
10d0d9d5c0f0 tests: kill for windows in killdaemons.py checks return values
Simon Heimberg <simohe@besonet.ch>
parents: 1128
diff changeset
    23
        try:
10d0d9d5c0f0 tests: kill for windows in killdaemons.py checks return values
Simon Heimberg <simohe@besonet.ch>
parents: 1128
diff changeset
    24
            _check(ctypes.windll.kernel32.TerminateProcess(handle, -1), 5)
10d0d9d5c0f0 tests: kill for windows in killdaemons.py checks return values
Simon Heimberg <simohe@besonet.ch>
parents: 1128
diff changeset
    25
            #      windows error 5 when process does not exist or no access TODO
10d0d9d5c0f0 tests: kill for windows in killdaemons.py checks return values
Simon Heimberg <simohe@besonet.ch>
parents: 1128
diff changeset
    26
        except: #re-raises
10d0d9d5c0f0 tests: kill for windows in killdaemons.py checks return values
Simon Heimberg <simohe@besonet.ch>
parents: 1128
diff changeset
    27
            ctypes.windll.kernel32.CloseHandle(handle) # no _check, keep error
10d0d9d5c0f0 tests: kill for windows in killdaemons.py checks return values
Simon Heimberg <simohe@besonet.ch>
parents: 1128
diff changeset
    28
            raise
10d0d9d5c0f0 tests: kill for windows in killdaemons.py checks return values
Simon Heimberg <simohe@besonet.ch>
parents: 1128
diff changeset
    29
        _check(ctypes.windll.kernel32.CloseHandle(handle))
10d0d9d5c0f0 tests: kill for windows in killdaemons.py checks return values
Simon Heimberg <simohe@besonet.ch>
parents: 1128
diff changeset
    30
1127
79d7aa832cf4 killdaemons: add windows implementation
Patrick Mezard <patrick@mezard.eu>
parents: 1126
diff changeset
    31
else:
79d7aa832cf4 killdaemons: add windows implementation
Patrick Mezard <patrick@mezard.eu>
parents: 1126
diff changeset
    32
    def kill(pid, logfn, tryhard=True):
79d7aa832cf4 killdaemons: add windows implementation
Patrick Mezard <patrick@mezard.eu>
parents: 1126
diff changeset
    33
        try:
79d7aa832cf4 killdaemons: add windows implementation
Patrick Mezard <patrick@mezard.eu>
parents: 1126
diff changeset
    34
            os.kill(pid, 0)
79d7aa832cf4 killdaemons: add windows implementation
Patrick Mezard <patrick@mezard.eu>
parents: 1126
diff changeset
    35
            logfn('# Killing daemon process %d' % pid)
79d7aa832cf4 killdaemons: add windows implementation
Patrick Mezard <patrick@mezard.eu>
parents: 1126
diff changeset
    36
            os.kill(pid, signal.SIGTERM)
79d7aa832cf4 killdaemons: add windows implementation
Patrick Mezard <patrick@mezard.eu>
parents: 1126
diff changeset
    37
            if tryhard:
79d7aa832cf4 killdaemons: add windows implementation
Patrick Mezard <patrick@mezard.eu>
parents: 1126
diff changeset
    38
                for i in range(10):
79d7aa832cf4 killdaemons: add windows implementation
Patrick Mezard <patrick@mezard.eu>
parents: 1126
diff changeset
    39
                    time.sleep(0.05)
79d7aa832cf4 killdaemons: add windows implementation
Patrick Mezard <patrick@mezard.eu>
parents: 1126
diff changeset
    40
                    os.kill(pid, 0)
79d7aa832cf4 killdaemons: add windows implementation
Patrick Mezard <patrick@mezard.eu>
parents: 1126
diff changeset
    41
            else:
79d7aa832cf4 killdaemons: add windows implementation
Patrick Mezard <patrick@mezard.eu>
parents: 1126
diff changeset
    42
                time.sleep(0.1)
79d7aa832cf4 killdaemons: add windows implementation
Patrick Mezard <patrick@mezard.eu>
parents: 1126
diff changeset
    43
                os.kill(pid, 0)
79d7aa832cf4 killdaemons: add windows implementation
Patrick Mezard <patrick@mezard.eu>
parents: 1126
diff changeset
    44
            logfn('# Daemon process %d is stuck - really killing it' % pid)
79d7aa832cf4 killdaemons: add windows implementation
Patrick Mezard <patrick@mezard.eu>
parents: 1126
diff changeset
    45
            os.kill(pid, signal.SIGKILL)
79d7aa832cf4 killdaemons: add windows implementation
Patrick Mezard <patrick@mezard.eu>
parents: 1126
diff changeset
    46
        except OSError, err:
79d7aa832cf4 killdaemons: add windows implementation
Patrick Mezard <patrick@mezard.eu>
parents: 1126
diff changeset
    47
            if err.errno != errno.ESRCH:
79d7aa832cf4 killdaemons: add windows implementation
Patrick Mezard <patrick@mezard.eu>
parents: 1126
diff changeset
    48
                raise
79d7aa832cf4 killdaemons: add windows implementation
Patrick Mezard <patrick@mezard.eu>
parents: 1126
diff changeset
    49
1126
dbcb11553a3b run-tests: do not duplicate killdaemons() code
Patrick Mezard <patrick@mezard.eu>
parents: 1125
diff changeset
    50
def killdaemons(pidfile, tryhard=True, remove=False, logfn=None):
dbcb11553a3b run-tests: do not duplicate killdaemons() code
Patrick Mezard <patrick@mezard.eu>
parents: 1125
diff changeset
    51
    if not logfn:
dbcb11553a3b run-tests: do not duplicate killdaemons() code
Patrick Mezard <patrick@mezard.eu>
parents: 1125
diff changeset
    52
        logfn = lambda s: s
dbcb11553a3b run-tests: do not duplicate killdaemons() code
Patrick Mezard <patrick@mezard.eu>
parents: 1125
diff changeset
    53
    # Kill off any leftover daemon processes
dbcb11553a3b run-tests: do not duplicate killdaemons() code
Patrick Mezard <patrick@mezard.eu>
parents: 1125
diff changeset
    54
    try:
dbcb11553a3b run-tests: do not duplicate killdaemons() code
Patrick Mezard <patrick@mezard.eu>
parents: 1125
diff changeset
    55
        fp = open(pidfile)
dbcb11553a3b run-tests: do not duplicate killdaemons() code
Patrick Mezard <patrick@mezard.eu>
parents: 1125
diff changeset
    56
        for line in fp:
dbcb11553a3b run-tests: do not duplicate killdaemons() code
Patrick Mezard <patrick@mezard.eu>
parents: 1125
diff changeset
    57
            try:
dbcb11553a3b run-tests: do not duplicate killdaemons() code
Patrick Mezard <patrick@mezard.eu>
parents: 1125
diff changeset
    58
                pid = int(line)
dbcb11553a3b run-tests: do not duplicate killdaemons() code
Patrick Mezard <patrick@mezard.eu>
parents: 1125
diff changeset
    59
            except ValueError:
dbcb11553a3b run-tests: do not duplicate killdaemons() code
Patrick Mezard <patrick@mezard.eu>
parents: 1125
diff changeset
    60
                continue
1127
79d7aa832cf4 killdaemons: add windows implementation
Patrick Mezard <patrick@mezard.eu>
parents: 1126
diff changeset
    61
            kill(pid, logfn, tryhard)
1126
dbcb11553a3b run-tests: do not duplicate killdaemons() code
Patrick Mezard <patrick@mezard.eu>
parents: 1125
diff changeset
    62
        fp.close()
dbcb11553a3b run-tests: do not duplicate killdaemons() code
Patrick Mezard <patrick@mezard.eu>
parents: 1125
diff changeset
    63
        if remove:
dbcb11553a3b run-tests: do not duplicate killdaemons() code
Patrick Mezard <patrick@mezard.eu>
parents: 1125
diff changeset
    64
            os.unlink(pidfile)
dbcb11553a3b run-tests: do not duplicate killdaemons() code
Patrick Mezard <patrick@mezard.eu>
parents: 1125
diff changeset
    65
    except IOError:
dbcb11553a3b run-tests: do not duplicate killdaemons() code
Patrick Mezard <patrick@mezard.eu>
parents: 1125
diff changeset
    66
        pass
dbcb11553a3b run-tests: do not duplicate killdaemons() code
Patrick Mezard <patrick@mezard.eu>
parents: 1125
diff changeset
    67
dbcb11553a3b run-tests: do not duplicate killdaemons() code
Patrick Mezard <patrick@mezard.eu>
parents: 1125
diff changeset
    68
if __name__ == '__main__':
1128
7f09e7ac63a7 killdaemons: take file argument explicitely
Patrick Mezard <patrick@mezard.eu>
parents: 1127
diff changeset
    69
    path, = sys.argv[1:]
7f09e7ac63a7 killdaemons: take file argument explicitely
Patrick Mezard <patrick@mezard.eu>
parents: 1127
diff changeset
    70
    killdaemons(path)
1126
dbcb11553a3b run-tests: do not duplicate killdaemons() code
Patrick Mezard <patrick@mezard.eu>
parents: 1125
diff changeset
    71