From c7e33c6c9fedb150126b7f1bf066211e15b4117b Mon Sep 17 00:00:00 2001 From: Tommy Ip Date: Thu, 9 Feb 2017 21:58:43 +0000 Subject: [PATCH] optimization: Use Python to test management commands. The original test was written in shell script which launches a new django instance for every tests. By doing it in Python, we avoid the overhead and reduce the test time to <1 second. Fixes #3620. --- tools/test-all | 2 -- tools/test-management | 18 ------------ tools/travis/backend | 2 -- zerver/lib/test_helpers.py | 10 +++++++ zerver/tests/test_management_commands.py | 36 +++++++++++++++++++++--- 5 files changed, 42 insertions(+), 26 deletions(-) delete mode 100755 tools/test-management diff --git a/tools/test-all b/tools/test-all index 3af9885feb..7dacc0a668 100755 --- a/tools/test-all +++ b/tools/test-all @@ -39,8 +39,6 @@ run ./tools/test-js-with-node run ./tools/run-mypy run ./tools/test-backend $FORCEARG run ./tools/test-js-with-casper $FORCEARG -# Not running management test since it takes 40s and thus is too slow to be worth it. -# run ./tools/test-management # Not running queue worker reload tests since it's low-churn code # run ./tools/test-queue-worker-reload # Not running documentation tests since it takes 20s and only tests documentation diff --git a/tools/test-management b/tools/test-management deleted file mode 100755 index 5451bea2fa..0000000000 --- a/tools/test-management +++ /dev/null @@ -1,18 +0,0 @@ -#!/bin/bash -set -e - -echo "Testing management commands start!" -failed=0 -for i in `ls */management/commands/ | grep .py$ | grep -v __init__ | sed 's/[.]py$//'`; do - if ! $(./manage.py $i --help >/dev/null); then - failed=$(expr $failed + 1) - echo "ERROR: \`./manage.py $i --help\` crashes!"; - fi -done - -if [ $failed -gt 0 ]; then - echo - echo "$failed management commands don't start!" - exit 1 -fi -echo "All management commands start!" diff --git a/tools/travis/backend b/tools/travis/backend index 85eddfb6e7..2905ec3395 100755 --- a/tools/travis/backend +++ b/tools/travis/backend @@ -7,7 +7,6 @@ set -x ./tools/lint-all --pep8 # Include the slow and thus non-default pep8 linter check ./tools/test-backend --coverage --no-verbose-coverage -./tools/test-management ./tools/test-migrations ./tools/test-run-dev ./tools/test-documentation @@ -15,4 +14,3 @@ set -x ./tools/test-api # Some test suites disabled in CI for being flaky #./tools/test-queue-worker-reload - diff --git a/zerver/lib/test_helpers.py b/zerver/lib/test_helpers.py index bb60ba5bb8..5f457638a6 100644 --- a/zerver/lib/test_helpers.py +++ b/zerver/lib/test_helpers.py @@ -163,6 +163,16 @@ def queries_captured(include_savepoints=False): TimeTrackingCursor.execute = old_execute # type: ignore # https://github.com/JukkaL/mypy/issues/1167 TimeTrackingCursor.executemany = old_executemany # type: ignore # https://github.com/JukkaL/mypy/issues/1167 +@contextmanager +def stdout_suppressed(): + # type: () -> Iterator[IO[str]] + """Redirect stdout to /dev/null.""" + + with open(os.devnull, 'a') as devnull: + stdout, sys.stdout = sys.stdout, devnull # type: ignore + yield stdout + sys.stdout = stdout + def get_test_image_file(filename): # type: (str) -> IO[Any] test_avatar_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), '../tests/images')) diff --git a/zerver/tests/test_management_commands.py b/zerver/tests/test_management_commands.py index 7873d1190d..25eca8eb51 100644 --- a/zerver/tests/test_management_commands.py +++ b/zerver/tests/test_management_commands.py @@ -1,13 +1,41 @@ # -*- coding: utf-8 -*- +from __future__ import absolute_import, print_function + import os -from mock import patch, MagicMock -from django.test import TestCase +import glob +from datetime import timedelta +from mock import MagicMock, patch +from six.moves import map, filter + from django.conf import settings from django.core.management import call_command +from django.test import TestCase +from zerver.lib.test_classes import ZulipTestCase +from zerver.lib.test_helpers import stdout_suppressed from zerver.models import get_realm from confirmation.models import RealmCreationKey, generate_realm_creation_url -from datetime import timedelta -from zerver.lib.test_classes import ZulipTestCase + +class TestCommandsCanStart(TestCase): + + def setUp(self): + # type: () -> None + self.commands = filter( + lambda filename: filename != '__init__', + map( + lambda file: os.path.basename(file).replace('.py', ''), + glob.iglob('*/management/commands/*.py') + ) + ) + + def test_management_commands_show_help(self): + # type: () -> None + with stdout_suppressed() as stdout: + for command in self.commands: + print('Testing management command: {}'.format(command), + file=stdout) + + with self.assertRaises(SystemExit): + call_command(command, '--help') class TestSendWebhookFixtureMessage(TestCase): COMMAND_NAME = 'send_webhook_fixture_message'