[PATCH 1 of 2] run-tests: implement proper process killing for Windows

Adrian Buehlmann adrian at cadifra.com
Mon Jun 18 04:04:36 CDT 2012


On 2012-06-18 02:20, Mads Kiilerich wrote:
> Adrian Buehlmann wrote, On 06/18/2012 12:35 AM:
>> # HG changeset patch
>> # User Adrian Buehlmann <adrian at cadifra.com>
>> # Date 1339972395 -7200
>> # Node ID 954a063d12edfe1d2a3d32df1a540c0ee5268156
>> # Parent  191f0c6cc47c1cf85372f5e5943ca94aa14fcb65
>> run-tests: implement proper process killing for Windows
> 
> This is allegedly a hard problem. It is great to have it solved!
> 
>> diff --git a/tests/run-tests.py b/tests/run-tests.py
>> --- a/tests/run-tests.py
>> +++ b/tests/run-tests.py
>> @@ -347,6 +347,25 @@
>>       except OSError:
>>           pass
>>   
>> +if os.name == 'nt':
>> +    import ctypes
>> +    def killprocess(pid):
>> +        vlog('# Killing daemon process %d' % pid)
>> +        PROCESS_TERMINATE = 1
>> +        k = ctypes.windll.kernel32
>> +        handle = k.OpenProcess(PROCESS_TERMINATE, False, pid)
>> +        k.TerminateProcess(handle, -1)
>> +        k.CloseHandle(handle)

[..]

> The non-windows variant try to make the process terminate cleanly before 
> kill-killing it. Is that relevant and possible on Windows too?

I have thought a bit more about this.

I don't think it is relevant for the particular case when killdaemons()
in run-tests.py is called.

At that point, we are done with that testfile, run() has finished, no
one is going to look at the repos of that particular test again, so, if
hard-killing a "hg serve" server would be a problem there in the sense
of leaving a test repo in a "damaged" limbo state, then no one cares
about it, the temporary directory will be removed soonish anyway.

In theory, it could be a problem for the tests that use
tests/killdaemons.py, provided they want to use a repo that was modified
by a process that was killed right before in the very same test. So we
will have to examine tests/killdaemons.py and the tests they use it. But
I don't touch tests/killdaemons.py here.

killdaemons() in run-tests.py is different. No one cares about those
test-toy repos an more.

The only thing we care about is that the resources like sockets are
reliably freed again for the next test. Otherwise the port is blocked
for the next test, causing it to fail.

>> +else:
>> +    def killprocess(pid):
>> +        os.kill(pid, 0)
>> +        vlog('# Killing daemon process %d' % pid)
>> +        os.kill(pid, signal.SIGTERM)
>> +        time.sleep(0.1)
>> +        os.kill(pid, 0)
>> +        vlog('# Daemon process %d is stuck - really killing it' % pid)
>> +        os.kill(pid, signal.SIGKILL)
>> +
>>   def killdaemons():
>>       # Kill off any leftover daemon processes
>>       try:


More information about the Mercurial-devel mailing list