Skip to content

Commit

Permalink
Interrupt test run, wait, then re-run on file change.
Browse files Browse the repository at this point in the history
  • Loading branch information
joeyespo committed Apr 4, 2016
1 parent 0cf6b93 commit 6e07f80
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 3 deletions.
23 changes: 23 additions & 0 deletions pytest_watch/helpers.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import os
import signal
import subprocess
import sys
from time import sleep
Expand Down Expand Up @@ -52,3 +53,25 @@ def samepath(left, right):
"""
return (os.path.abspath(os.path.normcase(left)) ==
os.path.abspath(os.path.normcase(right)))


def send_keyboard_interrupt(proc):
"""
Sends a KeyboardInterrupt to the specified child process.
"""
if is_windows:
try:
# Send KeyboardInterrupt to self, and therefore, to child processes
try:
os.kill(0, signal.CTRL_C_EVENT)
except AttributeError:
# Python 2.6 and below
import ctypes
ctypes.windll.kernel32.GenerateConsoleCtrlEvent(0, 0)
# Immediately throws KeyboardInterrupt from the simulated CTRL-C
proc.wait()
except KeyboardInterrupt:
# Ignore the simulated CTRL-C
pass
else:
os.kill(proc.pid, signal.SIGINT)
24 changes: 21 additions & 3 deletions pytest_watch/watcher.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@
from watchdog.observers import Observer
from watchdog.observers.polling import PollingObserver

from .helpers import beep, clear, dequeue_all, is_windows, samepath
from .helpers import (
beep, clear, dequeue_all, is_windows, samepath, send_keyboard_interrupt)


ALL_EXTENSIONS = object()
Expand Down Expand Up @@ -221,8 +222,25 @@ def watch(directories=[], ignore=[], auto_clear=False, beep_on_failure=True,

# Run tests
p = subprocess.Popen(argv, shell=is_windows)
# TODO: Check event_listener, send SIGINT to child process on event
exit_code = p.wait()
try:
while True:
# Check for completion
exit_code = p.poll()
if exit_code is not None:
break
# Interrupt the current test run on filesystem event
if not event_listener.event_queue.empty():
send_keyboard_interrupt(p)
exit_code = p.wait()
break
# Allow user to initiate a keyboard interrupt
sleep(0.1)
except KeyboardInterrupt:
# Wait for current test run cleanup
if p.wait() == EXIT_INTERRUPTED:
run_hook(oninterrupt)
# Exit, since this keyboard interrupt was user-initiated
break

# Run custom commands
if exit_code == EXIT_INTERRUPTED:
Expand Down

0 comments on commit 6e07f80

Please sign in to comment.