|
@@ -2,10 +2,12 @@ from __future__ import absolute_import
|
|
|
|
|
|
from sentry.utils.compat import mock
|
|
|
import os
|
|
|
+from hashlib import md5
|
|
|
|
|
|
from django.conf import settings
|
|
|
from sentry_sdk import Hub
|
|
|
|
|
|
+import six
|
|
|
|
|
|
TEST_ROOT = os.path.normpath(
|
|
|
os.path.join(os.path.dirname(__file__), os.pardir, os.pardir, os.pardir, os.pardir, "tests")
|
|
@@ -263,3 +265,57 @@ def pytest_runtest_teardown(item):
|
|
|
model.objects.clear_local_cache()
|
|
|
|
|
|
Hub.main.bind_client(None)
|
|
|
+
|
|
|
+
|
|
|
+def pytest_collection_modifyitems(config, items):
|
|
|
+ """
|
|
|
+ After collection, we need to:
|
|
|
+
|
|
|
+ - Filter tests that subclass SnubaTestCase as tests in `tests/acceptance` are not being marked as `snuba`
|
|
|
+ - Select tests based on group and group strategy
|
|
|
+
|
|
|
+ """
|
|
|
+
|
|
|
+ total_groups = int(os.environ.get("TOTAL_TEST_GROUPS", 1))
|
|
|
+ current_group = int(os.environ.get("TEST_GROUP", 0))
|
|
|
+ grouping_strategy = os.environ.get("TEST_GROUP_STRATEGY", "file")
|
|
|
+
|
|
|
+ accepted, keep, discard = [], [], []
|
|
|
+
|
|
|
+ for index, item in enumerate(items):
|
|
|
+ # XXX: For some reason tests in `tests/acceptance` are not being
|
|
|
+ # marked as snuba, so deselect test cases not a subclass of SnubaTestCase
|
|
|
+ if os.environ.get("RUN_SNUBA_TESTS_ONLY"):
|
|
|
+ from sentry.testutils import SnubaTestCase
|
|
|
+ import inspect
|
|
|
+
|
|
|
+ if inspect.isclass(item.cls) and not issubclass(item.cls, SnubaTestCase):
|
|
|
+ # No need to group if we are deselecting this
|
|
|
+ discard.append(item)
|
|
|
+ continue
|
|
|
+ accepted.append(item)
|
|
|
+ else:
|
|
|
+ accepted.append(item)
|
|
|
+
|
|
|
+ # In the case where we group by round robin (e.g. TEST_GROUP_STRATEGY is not `file`),
|
|
|
+ # we want to only include items in `accepted` list
|
|
|
+
|
|
|
+ # TODO(joshuarli): six 1.12.0 adds ensure_binary: six.ensure_binary(item.location[0])
|
|
|
+ item_to_group = (
|
|
|
+ int(md5(six.text_type(item.location[0]).encode("utf-8")).hexdigest(), 16)
|
|
|
+ if grouping_strategy == "file"
|
|
|
+ else len(accepted) - 1
|
|
|
+ )
|
|
|
+
|
|
|
+ # Split tests in different groups
|
|
|
+ group_num = item_to_group % total_groups
|
|
|
+
|
|
|
+ if group_num == current_group:
|
|
|
+ keep.append(item)
|
|
|
+ else:
|
|
|
+ discard.append(item)
|
|
|
+
|
|
|
+ # This only needs to be done if there are items to be de-selected
|
|
|
+ if len(discard) > 0:
|
|
|
+ items[:] = keep
|
|
|
+ config.hook.pytest_deselected(items=discard)
|