Mercurial > hg
annotate tests/killdaemons.py @ 25591:f1d46075b13a
verify: check the subrepository references in .hgsubstate
While hopefully atypical, there are reasons that a subrepository revision can be
lost that aren't covered by corruption of the .hgsubstate revlog. Such things
can happen when a subrepo is amended, stripped or simply isn't pulled from
upstream because the parent repo revision wasn't updated yet. There's no way to
know if it is an error, but this will find potential problems sooner than when
some random revision is updated.
Until recently, convert made no attempt at rewriting the .hgsubstate file. The
impetuous for this is to verify the conversion of some repositories, and this is
orders of magnitude faster than a bash script from 0..tip that does an
'hg update -C $rev'. But it is equally useful to determine if everything has
been pulled down before taking a thumb drive on the go.
It feels somewhat wrong to leave this out of verifymod (mostly because the file
is already read in there, and the final summary is printed before the subrepos
are checked). But verifymod looks very low level, so importing subrepo stuff
there seems more wrong.
author | Matt Harbison <matt_harbison@yahoo.com> |
---|---|
date | Tue, 16 Jun 2015 16:15:15 -0400 |
parents | 123c99034cb6 |
children | 05cb9c6f310e |
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 |
20496
acbd19b9fbe1
tests: killdaemons.py for windows distinguishes access violation and terminated
Simon Heimberg <simohe@besonet.ch>
parents:
20495
diff
changeset
|
18 PROCESS_QUERY_INFORMATION = 0x400 |
20698
1147563faf62
killdaemons: drop superfluous L suffix from constant
Augie Fackler <raf@durin42.com>
parents:
20496
diff
changeset
|
19 SYNCHRONIZE = 0x00100000 |
20494
ea3adeac5248
tests: killdaemons.py for windows waits for killed process to terminate
Simon Heimberg <simohe@besonet.ch>
parents:
20493
diff
changeset
|
20 WAIT_OBJECT_0 = 0 |
ea3adeac5248
tests: killdaemons.py for windows waits for killed process to terminate
Simon Heimberg <simohe@besonet.ch>
parents:
20493
diff
changeset
|
21 WAIT_TIMEOUT = 258 |
17465
2d4a096e213c
killdaemons: add windows implementation
Patrick Mezard <patrick@mezard.eu>
parents:
17464
diff
changeset
|
22 handle = ctypes.windll.kernel32.OpenProcess( |
20496
acbd19b9fbe1
tests: killdaemons.py for windows distinguishes access violation and terminated
Simon Heimberg <simohe@besonet.ch>
parents:
20495
diff
changeset
|
23 PROCESS_TERMINATE|SYNCHRONIZE|PROCESS_QUERY_INFORMATION, |
acbd19b9fbe1
tests: killdaemons.py for windows distinguishes access violation and terminated
Simon Heimberg <simohe@besonet.ch>
parents:
20495
diff
changeset
|
24 False, pid) |
20493
b5f43dbf64ca
tests: kill for windows in killdaemons.py checks return values
Simon Heimberg <simohe@besonet.ch>
parents:
17466
diff
changeset
|
25 if handle == 0: |
20495
0cf1c8c452d3
tests: killdaemons.py for checks reason when getting no process handle
Simon Heimberg <simohe@besonet.ch>
parents:
20494
diff
changeset
|
26 _check(0, 87) # err 87 when process not found |
20493
b5f43dbf64ca
tests: kill for windows in killdaemons.py checks return values
Simon Heimberg <simohe@besonet.ch>
parents:
17466
diff
changeset
|
27 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
|
28 try: |
20496
acbd19b9fbe1
tests: killdaemons.py for windows distinguishes access violation and terminated
Simon Heimberg <simohe@besonet.ch>
parents:
20495
diff
changeset
|
29 r = ctypes.windll.kernel32.WaitForSingleObject(handle, 100) |
acbd19b9fbe1
tests: killdaemons.py for windows distinguishes access violation and terminated
Simon Heimberg <simohe@besonet.ch>
parents:
20495
diff
changeset
|
30 if r == WAIT_OBJECT_0: |
acbd19b9fbe1
tests: killdaemons.py for windows distinguishes access violation and terminated
Simon Heimberg <simohe@besonet.ch>
parents:
20495
diff
changeset
|
31 pass # terminated, but process handle still available |
acbd19b9fbe1
tests: killdaemons.py for windows distinguishes access violation and terminated
Simon Heimberg <simohe@besonet.ch>
parents:
20495
diff
changeset
|
32 elif r == WAIT_TIMEOUT: |
acbd19b9fbe1
tests: killdaemons.py for windows distinguishes access violation and terminated
Simon Heimberg <simohe@besonet.ch>
parents:
20495
diff
changeset
|
33 _check(ctypes.windll.kernel32.TerminateProcess(handle, -1)) |
acbd19b9fbe1
tests: killdaemons.py for windows distinguishes access violation and terminated
Simon Heimberg <simohe@besonet.ch>
parents:
20495
diff
changeset
|
34 else: |
acbd19b9fbe1
tests: killdaemons.py for windows distinguishes access violation and terminated
Simon Heimberg <simohe@besonet.ch>
parents:
20495
diff
changeset
|
35 _check(r) |
20494
ea3adeac5248
tests: killdaemons.py for windows waits for killed process to terminate
Simon Heimberg <simohe@besonet.ch>
parents:
20493
diff
changeset
|
36 |
ea3adeac5248
tests: killdaemons.py for windows waits for killed process to terminate
Simon Heimberg <simohe@besonet.ch>
parents:
20493
diff
changeset
|
37 # TODO?: forcefully kill when timeout |
ea3adeac5248
tests: killdaemons.py for windows waits for killed process to terminate
Simon Heimberg <simohe@besonet.ch>
parents:
20493
diff
changeset
|
38 # and ?shorter waiting time? when tryhard==True |
ea3adeac5248
tests: killdaemons.py for windows waits for killed process to terminate
Simon Heimberg <simohe@besonet.ch>
parents:
20493
diff
changeset
|
39 r = ctypes.windll.kernel32.WaitForSingleObject(handle, 100) |
ea3adeac5248
tests: killdaemons.py for windows waits for killed process to terminate
Simon Heimberg <simohe@besonet.ch>
parents:
20493
diff
changeset
|
40 # timeout = 100 ms |
ea3adeac5248
tests: killdaemons.py for windows waits for killed process to terminate
Simon Heimberg <simohe@besonet.ch>
parents:
20493
diff
changeset
|
41 if r == WAIT_OBJECT_0: |
ea3adeac5248
tests: killdaemons.py for windows waits for killed process to terminate
Simon Heimberg <simohe@besonet.ch>
parents:
20493
diff
changeset
|
42 pass # process is terminated |
ea3adeac5248
tests: killdaemons.py for windows waits for killed process to terminate
Simon Heimberg <simohe@besonet.ch>
parents:
20493
diff
changeset
|
43 elif r == WAIT_TIMEOUT: |
ea3adeac5248
tests: killdaemons.py for windows waits for killed process to terminate
Simon Heimberg <simohe@besonet.ch>
parents:
20493
diff
changeset
|
44 logfn('# Daemon process %d is stuck') |
ea3adeac5248
tests: killdaemons.py for windows waits for killed process to terminate
Simon Heimberg <simohe@besonet.ch>
parents:
20493
diff
changeset
|
45 else: |
21194
476069509e72
killdaemons: correct typo of _check() function caught by pyflakes
Yuya Nishihara <yuya@tcha.org>
parents:
20698
diff
changeset
|
46 _check(r) # any error |
20493
b5f43dbf64ca
tests: kill for windows in killdaemons.py checks return values
Simon Heimberg <simohe@besonet.ch>
parents:
17466
diff
changeset
|
47 except: #re-raises |
b5f43dbf64ca
tests: kill for windows in killdaemons.py checks return values
Simon Heimberg <simohe@besonet.ch>
parents:
17466
diff
changeset
|
48 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
|
49 raise |
b5f43dbf64ca
tests: kill for windows in killdaemons.py checks return values
Simon Heimberg <simohe@besonet.ch>
parents:
17466
diff
changeset
|
50 _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
|
51 |
17465
2d4a096e213c
killdaemons: add windows implementation
Patrick Mezard <patrick@mezard.eu>
parents:
17464
diff
changeset
|
52 else: |
2d4a096e213c
killdaemons: add windows implementation
Patrick Mezard <patrick@mezard.eu>
parents:
17464
diff
changeset
|
53 def kill(pid, logfn, tryhard=True): |
2d4a096e213c
killdaemons: add windows implementation
Patrick Mezard <patrick@mezard.eu>
parents:
17464
diff
changeset
|
54 try: |
2d4a096e213c
killdaemons: add windows implementation
Patrick Mezard <patrick@mezard.eu>
parents:
17464
diff
changeset
|
55 os.kill(pid, 0) |
2d4a096e213c
killdaemons: add windows implementation
Patrick Mezard <patrick@mezard.eu>
parents:
17464
diff
changeset
|
56 logfn('# Killing daemon process %d' % pid) |
2d4a096e213c
killdaemons: add windows implementation
Patrick Mezard <patrick@mezard.eu>
parents:
17464
diff
changeset
|
57 os.kill(pid, signal.SIGTERM) |
2d4a096e213c
killdaemons: add windows implementation
Patrick Mezard <patrick@mezard.eu>
parents:
17464
diff
changeset
|
58 if tryhard: |
2d4a096e213c
killdaemons: add windows implementation
Patrick Mezard <patrick@mezard.eu>
parents:
17464
diff
changeset
|
59 for i in range(10): |
2d4a096e213c
killdaemons: add windows implementation
Patrick Mezard <patrick@mezard.eu>
parents:
17464
diff
changeset
|
60 time.sleep(0.05) |
2d4a096e213c
killdaemons: add windows implementation
Patrick Mezard <patrick@mezard.eu>
parents:
17464
diff
changeset
|
61 os.kill(pid, 0) |
2d4a096e213c
killdaemons: add windows implementation
Patrick Mezard <patrick@mezard.eu>
parents:
17464
diff
changeset
|
62 else: |
2d4a096e213c
killdaemons: add windows implementation
Patrick Mezard <patrick@mezard.eu>
parents:
17464
diff
changeset
|
63 time.sleep(0.1) |
2d4a096e213c
killdaemons: add windows implementation
Patrick Mezard <patrick@mezard.eu>
parents:
17464
diff
changeset
|
64 os.kill(pid, 0) |
2d4a096e213c
killdaemons: add windows implementation
Patrick Mezard <patrick@mezard.eu>
parents:
17464
diff
changeset
|
65 logfn('# Daemon process %d is stuck - really killing it' % pid) |
2d4a096e213c
killdaemons: add windows implementation
Patrick Mezard <patrick@mezard.eu>
parents:
17464
diff
changeset
|
66 os.kill(pid, signal.SIGKILL) |
25031
0adc22a0b6b3
python3: update killdaemons and run-tests print and exception syntax
Augie Fackler <augie@google.com>
parents:
21194
diff
changeset
|
67 except OSError as err: |
17465
2d4a096e213c
killdaemons: add windows implementation
Patrick Mezard <patrick@mezard.eu>
parents:
17464
diff
changeset
|
68 if err.errno != errno.ESRCH: |
2d4a096e213c
killdaemons: add windows implementation
Patrick Mezard <patrick@mezard.eu>
parents:
17464
diff
changeset
|
69 raise |
2d4a096e213c
killdaemons: add windows implementation
Patrick Mezard <patrick@mezard.eu>
parents:
17464
diff
changeset
|
70 |
17464
eddfb9a550d0
run-tests: do not duplicate killdaemons() code
Patrick Mezard <patrick@mezard.eu>
parents:
10905
diff
changeset
|
71 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
|
72 if not logfn: |
eddfb9a550d0
run-tests: do not duplicate killdaemons() code
Patrick Mezard <patrick@mezard.eu>
parents:
10905
diff
changeset
|
73 logfn = lambda s: s |
eddfb9a550d0
run-tests: do not duplicate killdaemons() code
Patrick Mezard <patrick@mezard.eu>
parents:
10905
diff
changeset
|
74 # Kill off any leftover daemon processes |
eddfb9a550d0
run-tests: do not duplicate killdaemons() code
Patrick Mezard <patrick@mezard.eu>
parents:
10905
diff
changeset
|
75 try: |
eddfb9a550d0
run-tests: do not duplicate killdaemons() code
Patrick Mezard <patrick@mezard.eu>
parents:
10905
diff
changeset
|
76 fp = open(pidfile) |
eddfb9a550d0
run-tests: do not duplicate killdaemons() code
Patrick Mezard <patrick@mezard.eu>
parents:
10905
diff
changeset
|
77 for line in fp: |
eddfb9a550d0
run-tests: do not duplicate killdaemons() code
Patrick Mezard <patrick@mezard.eu>
parents:
10905
diff
changeset
|
78 try: |
eddfb9a550d0
run-tests: do not duplicate killdaemons() code
Patrick Mezard <patrick@mezard.eu>
parents:
10905
diff
changeset
|
79 pid = int(line) |
eddfb9a550d0
run-tests: do not duplicate killdaemons() code
Patrick Mezard <patrick@mezard.eu>
parents:
10905
diff
changeset
|
80 except ValueError: |
eddfb9a550d0
run-tests: do not duplicate killdaemons() code
Patrick Mezard <patrick@mezard.eu>
parents:
10905
diff
changeset
|
81 continue |
17465
2d4a096e213c
killdaemons: add windows implementation
Patrick Mezard <patrick@mezard.eu>
parents:
17464
diff
changeset
|
82 kill(pid, logfn, tryhard) |
17464
eddfb9a550d0
run-tests: do not duplicate killdaemons() code
Patrick Mezard <patrick@mezard.eu>
parents:
10905
diff
changeset
|
83 fp.close() |
eddfb9a550d0
run-tests: do not duplicate killdaemons() code
Patrick Mezard <patrick@mezard.eu>
parents:
10905
diff
changeset
|
84 if remove: |
eddfb9a550d0
run-tests: do not duplicate killdaemons() code
Patrick Mezard <patrick@mezard.eu>
parents:
10905
diff
changeset
|
85 os.unlink(pidfile) |
eddfb9a550d0
run-tests: do not duplicate killdaemons() code
Patrick Mezard <patrick@mezard.eu>
parents:
10905
diff
changeset
|
86 except IOError: |
eddfb9a550d0
run-tests: do not duplicate killdaemons() code
Patrick Mezard <patrick@mezard.eu>
parents:
10905
diff
changeset
|
87 pass |
eddfb9a550d0
run-tests: do not duplicate killdaemons() code
Patrick Mezard <patrick@mezard.eu>
parents:
10905
diff
changeset
|
88 |
eddfb9a550d0
run-tests: do not duplicate killdaemons() code
Patrick Mezard <patrick@mezard.eu>
parents:
10905
diff
changeset
|
89 if __name__ == '__main__': |
25473
123c99034cb6
tests: make killdaemons.py use DAEMON_PIDS by default
Matt Mackall <mpm@selenic.com>
parents:
25031
diff
changeset
|
90 if len(sys.argv) > 1: |
123c99034cb6
tests: make killdaemons.py use DAEMON_PIDS by default
Matt Mackall <mpm@selenic.com>
parents:
25031
diff
changeset
|
91 path, = sys.argv[1:] |
123c99034cb6
tests: make killdaemons.py use DAEMON_PIDS by default
Matt Mackall <mpm@selenic.com>
parents:
25031
diff
changeset
|
92 else: |
123c99034cb6
tests: make killdaemons.py use DAEMON_PIDS by default
Matt Mackall <mpm@selenic.com>
parents:
25031
diff
changeset
|
93 path = os.environ["DAEMON_PIDS"] |
123c99034cb6
tests: make killdaemons.py use DAEMON_PIDS by default
Matt Mackall <mpm@selenic.com>
parents:
25031
diff
changeset
|
94 |
17466
d5a3bda6e170
killdaemons: take file argument explicitely
Patrick Mezard <patrick@mezard.eu>
parents:
17465
diff
changeset
|
95 killdaemons(path) |