From 6af95ae828a6b6a75b5cb950a103c416b0b27c3f Mon Sep 17 00:00:00 2001
From: David Baumgold <david@davidbaumgold.com>
Date: Wed, 15 Apr 2015 17:01:19 -0400
Subject: [PATCH] Enable --pdb debugging

This allows developers to pass the `--pdb` flag to paver test commands,
and that flag will be proxied to the `nosetests` command. It's useful
for debugging purposes.
---
 docs/en_us/internal/testing.rst               | 18 +++++++++---------
 pavelib/acceptance_test.py                    |  2 ++
 pavelib/bok_choy.py                           |  2 ++
 pavelib/tests.py                              |  8 ++++++++
 pavelib/utils/test/suites/acceptance_suite.py |  3 ++-
 pavelib/utils/test/suites/bokchoy_suite.py    |  1 +
 pavelib/utils/test/suites/nose_suite.py       |  3 +++
 pavelib/utils/test/suites/suite.py            |  1 +
 8 files changed, 28 insertions(+), 10 deletions(-)

diff --git a/docs/en_us/internal/testing.rst b/docs/en_us/internal/testing.rst
index bd28e8e8ac1..1b644b62e89 100644
--- a/docs/en_us/internal/testing.rst
+++ b/docs/en_us/internal/testing.rst
@@ -236,7 +236,8 @@ you can do one of::
     paver test_system -s cms -t common/djangoapps/terrain/stubs/tests/test_youtube_stub.py
     python -m coverage run --rcfile=cms/.coveragerc `which ./manage.py` cms --settings test test --traceback common/djangoapps/terrain/stubs/tests/test_youtube_stub.py
 
-Very handy: if you uncomment the ``pdb=1`` line in ``setup.cfg``, it
+Very handy: if you pass the ``--pdb`` flag to a paver test function, or
+uncomment the ``pdb=1`` line in ``setup.cfg``, the test runner
 will drop you into pdb on error. This lets you go up and down the stack
 and see what the values of the variables are. Check out `the pdb
 documentation <http://docs.python.org/library/pdb.html>`__
@@ -297,18 +298,18 @@ writing robust `Selenium <http://docs.seleniumhq.org/>`__ tests in
 tests reliable and maintainable by utilizing the Page Object and Promise
 design patterns.
 
-**Prerequisites**: 
+**Prerequisites**:
 
 These prerequisites are all automatically installed and available in `Devstack
 <https://github.com/edx/configuration/wiki/edX-Developer-Stack>`__, the
-supported development enviornment for the edX Platform. 
+supported development enviornment for the edX Platform.
 
 * Chromedriver and Chrome (see Running Lettuce Acceptance Tests below for
-  the latest tested versions) 
+  the latest tested versions)
 
-* Mongo 
+* Mongo
 
-* Memcache 
+* Memcache
 
 * mySQL
 
@@ -394,10 +395,9 @@ To test only a specific scenario
 
     paver test_acceptance -s lms --extra_args="lms/djangoapps/courseware/features/problems.feature -s 3"
 
-To start the debugger on failure, add the ``--pdb`` option to
-extra\_args::
+To start the debugger on failure, pass the ``--pdb`` option to the paver command::
 
-    paver test_acceptance -s lms --extra_args="lms/djangoapps/courseware/features/problems.feature --pdb"
+    paver test_acceptance -s lms --pdb --extra_args="lms/djangoapps/courseware/features/problems.feature"
 
 To run tests faster by not collecting static files, you can use
 ``paver test_acceptance -s lms --fasttest`` and
diff --git a/pavelib/acceptance_test.py b/pavelib/acceptance_test.py
index 2389af7d3db..31ac46c954a 100644
--- a/pavelib/acceptance_test.py
+++ b/pavelib/acceptance_test.py
@@ -26,6 +26,7 @@ __test__ = False  # do not collect
     make_option("--verbose", action="store_const", const=2, dest="verbosity"),
     make_option("-q", "--quiet", action="store_const", const=0, dest="verbosity"),
     make_option("-v", "--verbosity", action="count", dest="verbosity"),
+    make_option("--pdb", action="store_true", help="Launches an interactive debugger upon error"),
 ])
 def test_acceptance(options):
     """
@@ -37,6 +38,7 @@ def test_acceptance(options):
         'default_store': getattr(options, 'default_store', None),
         'verbosity': getattr(options, 'verbosity', 3),
         'extra_args': getattr(options, 'extra_args', ''),
+        'pdb': getattr(options, 'pdb', False),
     }
 
     if opts['system'] not in ['cms', 'lms']:
diff --git a/pavelib/bok_choy.py b/pavelib/bok_choy.py
index b7d8ea34a3b..f771cea020f 100644
--- a/pavelib/bok_choy.py
+++ b/pavelib/bok_choy.py
@@ -27,6 +27,7 @@ __test__ = False  # do not collect
     make_option("--verbose", action="store_const", const=2, dest="verbosity"),
     make_option("-q", "--quiet", action="store_const", const=0, dest="verbosity"),
     make_option("-v", "--verbosity", action="count", dest="verbosity"),
+    make_option("--pdb", action="store_true", help="Drop into debugger on failures or errors"),
     make_option("--skip_firefox_version_validation", action='store_false', dest="validate_firefox_version")
 ])
 def test_bokchoy(options):
@@ -55,6 +56,7 @@ def test_bokchoy(options):
         'default_store': getattr(options, 'default_store', 'split'),
         'verbosity': getattr(options, 'verbosity', 2),
         'extra_args': getattr(options, 'extra_args', ''),
+        'pdb': getattr(options, 'pdb', False),
         'test_dir': 'tests',
     }
     run_bokchoy(**opts)
diff --git a/pavelib/tests.py b/pavelib/tests.py
index 31a07e9544e..6d155d777f7 100644
--- a/pavelib/tests.py
+++ b/pavelib/tests.py
@@ -33,6 +33,7 @@ __test__ = False  # do not collect
     make_option("--verbose", action="store_const", const=2, dest="verbosity"),
     make_option("-q", "--quiet", action="store_const", const=0, dest="verbosity"),
     make_option("-v", "--verbosity", action="count", dest="verbosity", default=1),
+    make_option("--pdb", action="store_true", help="Drop into debugger on failures or errors"),
 ], share_with=['pavelib.utils.test.utils.clean_reports_dir'])
 def test_system(options):
     """
@@ -49,6 +50,7 @@ def test_system(options):
         'extra_args': getattr(options, 'extra_args', ''),
         'cov_args': getattr(options, 'cov_args', ''),
         'skip_clean': getattr(options, 'skip_clean', False),
+        'pdb': getattr(options, 'pdb', False),
     }
 
     if test_id:
@@ -85,6 +87,7 @@ def test_system(options):
     make_option("--verbose", action="store_const", const=2, dest="verbosity"),
     make_option("-q", "--quiet", action="store_const", const=0, dest="verbosity"),
     make_option("-v", "--verbosity", action="count", dest="verbosity", default=1),
+    make_option("--pdb", action="store_true", help="Drop into debugger on failures or errors"),
 ], share_with=['pavelib.utils.test.utils.clean_reports_dir'])
 def test_lib(options):
     """
@@ -100,6 +103,7 @@ def test_lib(options):
         'extra_args': getattr(options, 'extra_args', ''),
         'cov_args': getattr(options, 'cov_args', ''),
         'skip_clean': getattr(options, 'skip_clean', False),
+        'pdb': getattr(options, 'pdb', False),
     }
 
     if test_id:
@@ -129,6 +133,7 @@ def test_lib(options):
     make_option("--verbose", action="store_const", const=2, dest="verbosity"),
     make_option("-q", "--quiet", action="store_const", const=0, dest="verbosity"),
     make_option("-v", "--verbosity", action="count", dest="verbosity", default=1),
+    make_option("--pdb", action="store_true", help="Drop into debugger on failures or errors"),
 ])
 def test_python(options):
     """
@@ -140,6 +145,7 @@ def test_python(options):
         'verbosity': getattr(options, 'verbosity', 1),
         'extra_args': getattr(options, 'extra_args', ''),
         'cov_args': getattr(options, 'cov_args', ''),
+        'pdb': getattr(options, 'pdb', False),
     }
 
     python_suite = suites.PythonTestSuite('Python Tests', **opts)
@@ -158,6 +164,7 @@ def test_python(options):
     make_option("--verbose", action="store_const", const=2, dest="verbosity"),
     make_option("-q", "--quiet", action="store_const", const=0, dest="verbosity"),
     make_option("-v", "--verbosity", action="count", dest="verbosity", default=1),
+    make_option("--pdb", action="store_true", help="Drop into debugger on failures or errors"),
 ])
 def test(options):
     """
@@ -167,6 +174,7 @@ def test(options):
         'verbosity': getattr(options, 'verbosity', 1),
         'extra_args': getattr(options, 'extra_args', ''),
         'cov_args': getattr(options, 'cov_args', ''),
+        'pdb': getattr(options, 'pdb', False),
     }
     # Subsuites to be added to the main suite
     python_suite = suites.PythonTestSuite('Python Tests', **opts)
diff --git a/pavelib/utils/test/suites/acceptance_suite.py b/pavelib/utils/test/suites/acceptance_suite.py
index c21b59efadc..356cc544264 100644
--- a/pavelib/utils/test/suites/acceptance_suite.py
+++ b/pavelib/utils/test/suites/acceptance_suite.py
@@ -38,10 +38,11 @@ class AcceptanceTest(TestSuite):
 
         cmd = (
             "DEFAULT_STORE={default_store} ./manage.py {system} --settings acceptance harvest --traceback "
-            "--debug-mode --verbosity {verbosity} {report_args} {extra_args}".format(
+            "--debug-mode --verbosity {verbosity} {pdb} {report_args} {extra_args}".format(
                 default_store=self.default_store,
                 system=self.system,
                 verbosity=self.verbosity,
+                pdb="--pdb" if self.pdb else "",
                 report_args=report_args,
                 extra_args=self.extra_args,
             )
diff --git a/pavelib/utils/test/suites/bokchoy_suite.py b/pavelib/utils/test/suites/bokchoy_suite.py
index 90f7fc960ed..7bda552f56c 100644
--- a/pavelib/utils/test/suites/bokchoy_suite.py
+++ b/pavelib/utils/test/suites/bokchoy_suite.py
@@ -128,6 +128,7 @@ class BokChoyTestSuite(TestSuite):
             "--with-xunit",
             "--xunit-file={}".format(self.xunit_report),
             "--verbosity={}".format(self.verbosity),
+            "--pdb" if self.pdb else "",
             self.extra_args,
         ]
 
diff --git a/pavelib/utils/test/suites/nose_suite.py b/pavelib/utils/test/suites/nose_suite.py
index 27b2d38cdce..ac6f069ba8e 100644
--- a/pavelib/utils/test/suites/nose_suite.py
+++ b/pavelib/utils/test/suites/nose_suite.py
@@ -90,6 +90,9 @@ class NoseTestSuite(TestSuite):
         if self.fail_fast or env_fail_fast_set:
             opts += " --stop"
 
+        if self.pdb:
+            opts += " --pdb"
+
         return opts
 
 
diff --git a/pavelib/utils/test/suites/suite.py b/pavelib/utils/test/suites/suite.py
index 7756583ce0b..82647c96242 100644
--- a/pavelib/utils/test/suites/suite.py
+++ b/pavelib/utils/test/suites/suite.py
@@ -23,6 +23,7 @@ class TestSuite(object):
         self.failed_suites = []
         self.verbosity = kwargs.get('verbosity', 1)
         self.skip_clean = kwargs.get('skip_clean', False)
+        self.pdb = kwargs.get('pdb', False)
 
     def __enter__(self):
         """
-- 
GitLab