annotate tests/killdaemons.py @ 20493:b5f43dbf64ca

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