Patchwork [2,of,2] run-tests: skip threading for a single test RFC

login
register
mail settings
Submitter timeless@mozdev.org
Date Dec. 28, 2015, 5:54 p.m.
Message ID <45191891ec1fa89c03b6.1451325277@waste.org>
Download mbox | patch
Permalink /patch/12369/
State Accepted
Headers show

Comments

timeless@mozdev.org - Dec. 28, 2015, 5:54 p.m.
# HG changeset patch
# User timeless <timeless@mozdev.org>
# Date 1451324920 0
#      Mon Dec 28 17:48:40 2015 +0000
# Node ID 45191891ec1fa89c03b6473a2e78b03e603857d3
# Parent  87ab92b56034a975ad99ac1f592cdd19461c5bbc
run-tests: skip threading for a single test RFC

Threading is incompatible with most Python debuggers,
which makes debugging run-tests.py a real pain.

If there is only one test to run, skip using a thread for it.

Note that --debug is not compatible with debugging tests,
since it bypasses the output handling, which is where
much of the excitement is.
Augie Fackler - Jan. 7, 2016, 1:02 a.m.
On Mon, Dec 28, 2015 at 11:54:37AM -0600, timeless wrote:
> # HG changeset patch
> # User timeless <timeless@mozdev.org>
> # Date 1451324920 0
> #      Mon Dec 28 17:48:40 2015 +0000
> # Node ID 45191891ec1fa89c03b6473a2e78b03e603857d3
> # Parent  87ab92b56034a975ad99ac1f592cdd19461c5bbc
> run-tests: skip threading for a single test RFC

Queued, though I'm slightly dubious of the overall value here given
that it strikes me that many problems will be because of threading. Thanks!

>
> Threading is incompatible with most Python debuggers,
> which makes debugging run-tests.py a real pain.
>
> If there is only one test to run, skip using a thread for it.
>
> Note that --debug is not compatible with debugging tests,
> since it bypasses the output handling, which is where
> much of the excitement is.
>
> diff --git a/tests/run-tests.py b/tests/run-tests.py
> --- a/tests/run-tests.py
> +++ b/tests/run-tests.py
> @@ -1557,41 +1557,45 @@
>              statthread.start()
>
>          try:
> -            while tests or running:
> -                if not done.empty() or running == self._jobs or not tests:
> -                    try:
> -                        done.get(True, 1)
> -                        running -= 1
> -                        if result and result.shouldStop:
> -                            stoppedearly = True
> -                            break
> -                    except queue.Empty:
> -                        continue
> -                if tests and not running == self._jobs:
> -                    test = tests.pop(0)
> -                    if self._loop:
> -                        if getattr(test, 'should_reload', False):
> -                            num_tests[0] += 1
> -                            tests.append(
> -                                self._loadtest(test.name, num_tests[0]))
> -                        else:
> -                            tests.append(test)
> -                    t = threading.Thread(target=job, name=test.name,
> -                                         args=(test, result))
> -                    t.start()
> -                    running += 1
> +            if len(tests) == 1:
> +                test = tests.pop(0)
> +                test.run(result)
> +            else:
> +                while tests or running:
> +                    if not done.empty() or running == self._jobs or not tests:
> +                        try:
> +                            done.get(True, 1)
> +                            running -= 1
> +                            if result and result.shouldStop:
> +                                stoppedearly = True
> +                                break
> +                        except queue.Empty:
> +                            continue
> +                    if tests and not running == self._jobs:
> +                        test = tests.pop(0)
> +                        if self._loop:
> +                            if getattr(test, 'should_reload', False):
> +                                num_tests[0] += 1
> +                                tests.append(
> +                                    self._loadtest(test.name, num_tests[0]))
> +                            else:
> +                                tests.append(test)
> +                        t = threading.Thread(target=job, name=test.name,
> +                                             args=(test, result))
> +                        t.start()
> +                        running += 1
>
> -            # If we stop early we still need to wait on started tests to
> -            # finish. Otherwise, there is a race between the test completing
> -            # and the test's cleanup code running. This could result in the
> -            # test reporting incorrect.
> -            if stoppedearly:
> -                while running:
> -                    try:
> -                        done.get(True, 1)
> -                        running -= 1
> -                    except queue.Empty:
> -                        continue
> +                # If we stop early we still need to wait on started tests to
> +                # finish. Otherwise, there is a race between the test completing
> +                # and the test's cleanup code running. This could result in the
> +                # test reporting incorrect.
> +                if stoppedearly:
> +                    while running:
> +                        try:
> +                            done.get(True, 1)
> +                            running -= 1
> +                        except queue.Empty:
> +                            continue
>          except KeyboardInterrupt:
>              for test in runtests:
>                  test.abort()
> _______________________________________________
> Mercurial-devel mailing list
> Mercurial-devel@selenic.com
> https://selenic.com/mailman/listinfo/mercurial-devel

Patch

diff --git a/tests/run-tests.py b/tests/run-tests.py
--- a/tests/run-tests.py
+++ b/tests/run-tests.py
@@ -1557,41 +1557,45 @@ 
             statthread.start()
 
         try:
-            while tests or running:
-                if not done.empty() or running == self._jobs or not tests:
-                    try:
-                        done.get(True, 1)
-                        running -= 1
-                        if result and result.shouldStop:
-                            stoppedearly = True
-                            break
-                    except queue.Empty:
-                        continue
-                if tests and not running == self._jobs:
-                    test = tests.pop(0)
-                    if self._loop:
-                        if getattr(test, 'should_reload', False):
-                            num_tests[0] += 1
-                            tests.append(
-                                self._loadtest(test.name, num_tests[0]))
-                        else:
-                            tests.append(test)
-                    t = threading.Thread(target=job, name=test.name,
-                                         args=(test, result))
-                    t.start()
-                    running += 1
+            if len(tests) == 1:
+                test = tests.pop(0)
+                test.run(result)
+            else:
+                while tests or running:
+                    if not done.empty() or running == self._jobs or not tests:
+                        try:
+                            done.get(True, 1)
+                            running -= 1
+                            if result and result.shouldStop:
+                                stoppedearly = True
+                                break
+                        except queue.Empty:
+                            continue
+                    if tests and not running == self._jobs:
+                        test = tests.pop(0)
+                        if self._loop:
+                            if getattr(test, 'should_reload', False):
+                                num_tests[0] += 1
+                                tests.append(
+                                    self._loadtest(test.name, num_tests[0]))
+                            else:
+                                tests.append(test)
+                        t = threading.Thread(target=job, name=test.name,
+                                             args=(test, result))
+                        t.start()
+                        running += 1
 
-            # If we stop early we still need to wait on started tests to
-            # finish. Otherwise, there is a race between the test completing
-            # and the test's cleanup code running. This could result in the
-            # test reporting incorrect.
-            if stoppedearly:
-                while running:
-                    try:
-                        done.get(True, 1)
-                        running -= 1
-                    except queue.Empty:
-                        continue
+                # If we stop early we still need to wait on started tests to
+                # finish. Otherwise, there is a race between the test completing
+                # and the test's cleanup code running. This could result in the
+                # test reporting incorrect.
+                if stoppedearly:
+                    while running:
+                        try:
+                            done.get(True, 1)
+                            running -= 1
+                        except queue.Empty:
+                            continue
         except KeyboardInterrupt:
             for test in runtests:
                 test.abort()