From e98c5580a072acb21e4625852217d0376213bf2c Mon Sep 17 00:00:00 2001
From: Christine Lytwynec <clytwynec@edx.org>
Date: Fri, 30 Jan 2015 11:20:50 -0500
Subject: [PATCH] split unittests into shards for in jenkins

---
 pavelib/js_test.py                            |  6 ++++--
 pavelib/tests.py                              | 15 ++++++++++++---
 pavelib/utils/test/suites/acceptance_suite.py |  3 ++-
 pavelib/utils/test/suites/bokchoy_suite.py    |  4 +++-
 pavelib/utils/test/suites/js_suite.py         |  3 ++-
 pavelib/utils/test/suites/python_suite.py     |  2 +-
 pavelib/utils/test/suites/suite.py            |  1 +
 pavelib/utils/test/utils.py                   | 11 +++++++++--
 scripts/all-tests.sh                          | 18 ++++++++++++++++--
 9 files changed, 50 insertions(+), 13 deletions(-)

diff --git a/pavelib/js_test.py b/pavelib/js_test.py
index 7053975e63a..d381374009d 100644
--- a/pavelib/js_test.py
+++ b/pavelib/js_test.py
@@ -19,13 +19,15 @@ __test__ = False  # do not collect
     ("mode=", "m", "dev or run"),
     ("coverage", "c", "Run test under coverage"),
     ("port=", "p", "Port to run test server on (dev mode only)"),
-])
+    ('skip_clean', 'C', 'skip cleaning repository before running tests'),
+], share_with=["pavelib.utils.tests.utils.clean_reports_dir"])
 def test_js(options):
     """
     Run the JavaScript tests
     """
     mode = getattr(options, 'mode', 'run')
     port = None
+    skip_clean = getattr(options, 'skip_clean', False)
 
     if mode == 'run':
         suite = getattr(options, 'suite', 'all')
@@ -46,7 +48,7 @@ def test_js(options):
         )
         return
 
-    test_suite = JsTestSuite(suite, mode=mode, with_coverage=coverage, port=port)
+    test_suite = JsTestSuite(suite, mode=mode, with_coverage=coverage, port=port, skip_clean=skip_clean)
     test_suite.run()
 
 
diff --git a/pavelib/tests.py b/pavelib/tests.py
index cbf42047fc9..3e665def77f 100644
--- a/pavelib/tests.py
+++ b/pavelib/tests.py
@@ -29,10 +29,11 @@ __test__ = False  # do not collect
     ("fasttest", "a", "Run without collectstatic"),
     ('extra_args=', 'e', 'adds as extra args to the test command'),
     ('cov_args=', 'c', 'adds as args to coverage for the test run'),
+    ('skip_clean', 'C', 'skip cleaning repository before running tests'),
     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),
-])
+], share_with=['pavelib.utils.test.utils.clean_reports_dir'])
 def test_system(options):
     """
     Run tests on our djangoapps for lms and cms
@@ -47,6 +48,7 @@ def test_system(options):
         'verbosity': getattr(options, 'verbosity', 1),
         'extra_args': getattr(options, 'extra_args', ''),
         'cov_args': getattr(options, 'cov_args', ''),
+        'skip_clean': getattr(options, 'skip_clean', False),
     }
 
     if test_id:
@@ -79,10 +81,11 @@ def test_system(options):
     ("fail_fast", "x", "Run only failed tests"),
     ('extra_args=', 'e', 'adds as extra args to the test command'),
     ('cov_args=', 'c', 'adds as args to coverage for the test run'),
+    ('skip_clean', 'C', 'skip cleaning repository before running tests'),
     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),
-])
+], share_with=['pavelib.utils.test.utils.clean_reports_dir'])
 def test_lib(options):
     """
     Run tests for common/lib/ and pavelib/ (paver-tests)
@@ -96,6 +99,7 @@ def test_lib(options):
         'verbosity': getattr(options, 'verbosity', 1),
         'extra_args': getattr(options, 'extra_args', ''),
         'cov_args': getattr(options, 'cov_args', ''),
+        'skip_clean': getattr(options, 'skip_clean', False),
     }
 
     if test_id:
@@ -151,6 +155,9 @@ def test_python(options):
     'pavelib.utils.test.utils.clean_reports_dir',
 )
 @cmdopts([
+    ("suites", "s", "List of unit test suites to run. (js, lib, cms, lms)"),
+    ('extra_args=', 'e', 'adds as extra args to the test command'),
+    ('cov_args=', 'c', 'adds as args to coverage for the test run'),
     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),
@@ -160,7 +167,9 @@ def test(options):
     Run all tests
     """
     opts = {
-        'verbosity': getattr(options, 'verbosity', 1)
+        'verbosity': getattr(options, 'verbosity', 1),
+        'extra_args': getattr(options, 'extra_args', ''),
+        'cov_args': getattr(options, 'cov_args', ''),
     }
     # 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 55ac4572090..c21b59efadc 100644
--- a/pavelib/utils/test/suites/acceptance_suite.py
+++ b/pavelib/utils/test/suites/acceptance_suite.py
@@ -90,7 +90,8 @@ class AcceptanceTestSuite(TestSuite):
 
     def __enter__(self):
         super(AcceptanceTestSuite, self).__enter__()
-        test_utils.clean_test_files()
+        if not self.skip_clean:
+            test_utils.clean_test_files()
 
         if not self.fasttest:
             self._setup_acceptance_db()
diff --git a/pavelib/utils/test/suites/bokchoy_suite.py b/pavelib/utils/test/suites/bokchoy_suite.py
index 562cbaf74e7..6f14a2ea74c 100644
--- a/pavelib/utils/test/suites/bokchoy_suite.py
+++ b/pavelib/utils/test/suites/bokchoy_suite.py
@@ -51,7 +51,9 @@ class BokChoyTestSuite(TestSuite):
         self.har_dir.makedirs_p()
         self.report_dir.makedirs_p()
         test_utils.clean_reports_dir()
-        test_utils.clean_test_files()
+
+        if not self.skip_clean:
+            test_utils.clean_test_files()
 
         msg = colorize('green', "Checking for mongo, memchache, and mysql...")
         print(msg)
diff --git a/pavelib/utils/test/suites/js_suite.py b/pavelib/utils/test/suites/js_suite.py
index 07a5da39e81..0adf4f4dd18 100644
--- a/pavelib/utils/test/suites/js_suite.py
+++ b/pavelib/utils/test/suites/js_suite.py
@@ -32,7 +32,8 @@ class JsTestSuite(TestSuite):
     def __enter__(self):
         super(JsTestSuite, self).__enter__()
         self.report_dir.makedirs_p()
-        test_utils.clean_test_files()
+        if not self.skip_clean:
+            test_utils.clean_test_files()
 
         if self.mode == 'run' and not self.run_under_coverage:
             test_utils.clean_dir(self.report_dir)
diff --git a/pavelib/utils/test/suites/python_suite.py b/pavelib/utils/test/suites/python_suite.py
index ba2d845d667..fb3eb31c0e9 100644
--- a/pavelib/utils/test/suites/python_suite.py
+++ b/pavelib/utils/test/suites/python_suite.py
@@ -21,7 +21,7 @@ class PythonTestSuite(TestSuite):
 
     def __enter__(self):
         super(PythonTestSuite, self).__enter__()
-        if not self.fasttest:
+        if not (self.fasttest or self.skip_clean):
             test_utils.clean_test_files()
 
     @property
diff --git a/pavelib/utils/test/suites/suite.py b/pavelib/utils/test/suites/suite.py
index 0fab139923d..7756583ce0b 100644
--- a/pavelib/utils/test/suites/suite.py
+++ b/pavelib/utils/test/suites/suite.py
@@ -22,6 +22,7 @@ class TestSuite(object):
         self.subsuites = kwargs.get('subsuites', [])
         self.failed_suites = []
         self.verbosity = kwargs.get('verbosity', 1)
+        self.skip_clean = kwargs.get('skip_clean', False)
 
     def __enter__(self):
         """
diff --git a/pavelib/utils/test/utils.py b/pavelib/utils/test/utils.py
index 7f61cd56f51..3a68599c06c 100644
--- a/pavelib/utils/test/utils.py
+++ b/pavelib/utils/test/utils.py
@@ -1,7 +1,7 @@
 """
 Helper functions for test tasks
 """
-from paver.easy import sh, task
+from paver.easy import sh, task, cmdopts
 from pavelib.utils.envs import Env
 import os
 import subprocess
@@ -33,10 +33,17 @@ def clean_dir(directory):
 
 
 @task
-def clean_reports_dir():
+@cmdopts([
+    ('skip_clean', 'C', 'skip cleaning repository before running tests'),
+])
+def clean_reports_dir(options):
     """
     Clean coverage files, to ensure that we don't use stale data to generate reports.
     """
+    if getattr(options, 'skip_clean', False):
+        print('--skip_clean is set, skipping...')
+        return
+
     # We delete the files but preserve the directory structure
     # so that coverage.py has a place to put the reports.
     reports_dir = Env.REPORT_DIR.makedirs_p()
diff --git a/scripts/all-tests.sh b/scripts/all-tests.sh
index 4ba0fc89b65..8dbd7ca9205 100755
--- a/scripts/all-tests.sh
+++ b/scripts/all-tests.sh
@@ -126,8 +126,22 @@ END
         ;;
 
     "unit")
-        paver test
-        paver coverage
+        case "$SHARD" in        
+            "lms")
+                paver test_system -s lms
+                paver coverage
+                ;;
+            "other")
+                paver test_system -s cms
+                paver test_js --coverage --skip_clean
+                paver test_lib --skip_clean
+                paver coverage
+                ;;
+            *)
+                paver test
+                paver coverage
+                ;;
+        esac
         ;;
 
     "lms-acceptance")
-- 
GitLab