diff --git a/src/tee/admin.py b/src/tee/admin.py index e83b35d1c..84fc1ab4e 100644 --- a/src/tee/admin.py +++ b/src/tee/admin.py @@ -19,8 +19,7 @@ class LogAdmin(admin.ModelAdmin): readonly_fields = [ "started_on", "finished_on", - "exit_code", - "exit_value", + "finished_successfully", "command_name", "args", "stdout", diff --git a/src/tee/const.py b/src/tee/const.py new file mode 100644 index 000000000..117fca932 --- /dev/null +++ b/src/tee/const.py @@ -0,0 +1 @@ +DONT_CALL = "Used by django_tee tests. Don't call, does nothing. " diff --git a/src/tee/core.py b/src/tee/core.py index 5bdc08406..42a76f0fa 100644 --- a/src/tee/core.py +++ b/src/tee/core.py @@ -2,7 +2,6 @@ import traceback from contextlib import redirect_stderr, redirect_stdout -import simplejson from django.core.management import ManagementUtility from tee.models import Log @@ -21,37 +20,21 @@ def execute(argv, **kwargs): stdout = TeeIO(kwargs.get("stdout") if "stdout" in kwargs else sys.stdout) stderr = TeeIO(kwargs.get("stderr") if "stderr" in kwargs else sys.stdout) - log = Log.objects.create(command_name=argv[1], args=argv[2:]) - res = 127 + log = Log.objects.create(command_name=argv[0], args=argv[1:]) + try: with redirect_stderr(stderr): with redirect_stdout(stdout): try: utility = ManagementUtility(argv) utility.execute() + log.finished_successfully = True except Exception: - res = 1 + log.finished_successfully = False log.traceback = traceback.format_exc(limit=65535) finally: log.stdout = stdout.getvalue() log.stderr = stderr.getvalue() log.finished_on = timezone.now() - - if res is None: - log.exit_code = 0 - elif isinstance(res, int): - log.exit_code = res - else: - log.exit_code = -1 - - # if the return value is json-encodeable, save it to db: - try: - simplejson.dumps(res) - log.exit_value = res - except TypeError: - log.exit_value = ( - "Unable to encode results as JSON, thus unable to store it " - "in the database. Repr: %r" % res - ) log.save() diff --git a/src/tee/management/commands/tee.py b/src/tee/management/commands/tee.py index 0864a05f2..924ffd167 100644 --- a/src/tee/management/commands/tee.py +++ b/src/tee/management/commands/tee.py @@ -11,5 +11,12 @@ def add_arguments(self, parser): parser.add_argument("otherthings", nargs="*") # parser.add def handle(self, command_name, otherthings, *args, **options): - new_argv = [sys.argv[0]] + sys.argv[2:] - core.execute(new_argv) + new_argv = [sys.argv[0], command_name] + otherthings + + kwargs = {} + + for elem in ["stdout", "stderr"]: + if options.get(elem): + kwargs[elem] = options.get(elem) + + core.execute(new_argv, **kwargs) diff --git a/src/tee/management/commands/tee_test_exception.py b/src/tee/management/commands/tee_test_exception.py index 2d06282b6..66e452ba9 100644 --- a/src/tee/management/commands/tee_test_exception.py +++ b/src/tee/management/commands/tee_test_exception.py @@ -1,7 +1,11 @@ from django.core.management import BaseCommand +from tee import const + class Command(BaseCommand): + help = const.DONT_CALL + def handle(self, *args, **options): self.stderr.write("wrote to stderr") diff --git a/src/tee/management/commands/tee_test_okay.py b/src/tee/management/commands/tee_test_okay.py index be0f8ecd1..5efd6c1c8 100644 --- a/src/tee/management/commands/tee_test_okay.py +++ b/src/tee/management/commands/tee_test_okay.py @@ -1,7 +1,11 @@ from django.core.management import BaseCommand +from tee import const + class Command(BaseCommand): + help = const.DONT_CALL + def handle(self, *args, **options): self.stderr.write("wrote to stderr") diff --git a/src/tee/management/commands/tee_test_result.py b/src/tee/management/commands/tee_test_result.py deleted file mode 100644 index c87e9f961..000000000 --- a/src/tee/management/commands/tee_test_result.py +++ /dev/null @@ -1,6 +0,0 @@ -from django.core.management import BaseCommand - - -class Command(BaseCommand): - def handle(self, *args, **options): - return complex() diff --git a/src/tee/migrations/0004_auto_20220109_0151.py b/src/tee/migrations/0004_auto_20220109_0151.py new file mode 100644 index 000000000..0873c249e --- /dev/null +++ b/src/tee/migrations/0004_auto_20220109_0151.py @@ -0,0 +1,30 @@ +# Generated by Django 3.0.14 on 2022-01-09 00:51 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ("tee", "0003_log_traceback"), + ] + + operations = [ + migrations.RemoveField( + model_name="log", + name="exit_code", + ), + migrations.RemoveField( + model_name="log", + name="exit_value", + ), + migrations.RemoveField( + model_name="log", + name="kwargs", + ), + migrations.AddField( + model_name="log", + name="finished_successfully", + field=models.NullBooleanField(), + ), + ] diff --git a/src/tee/models.py b/src/tee/models.py index 09fc329a8..1a45ee3a1 100644 --- a/src/tee/models.py +++ b/src/tee/models.py @@ -6,21 +6,7 @@ class Log(models.Model): started_on = models.DateTimeField(auto_now_add=True) finished_on = models.DateTimeField(blank=True, null=True) - - exit_code = models.SmallIntegerField( - blank=True, - null=True, - help_text="""If value returned by - django.core.management.call_command is None, this will be zero. If value returned by d.c.m.call_command - is an int, this will be that int. If different, this is set to -1 and exit_value field is set. """, - ) - - exit_value = JSONField( - blank=True, - null=True, - help_text="""JSON-encoded value, returned by - django.core.management.call_command function, if different than None or an int. """, - ) + finished_successfully = models.NullBooleanField() command_name = models.TextField() args = JSONField(blank=True, null=True) diff --git a/src/tee/tests.py b/src/tee/tests.py index c3618986c..0b872b047 100644 --- a/src/tee/tests.py +++ b/src/tee/tests.py @@ -17,20 +17,18 @@ def stderr(): @pytest.mark.django_db -def test_tee_okay(stdout: StringIO, stderr: StringIO): - call_command("tee", "tee_test_okay", stdout=stdout, stderr=stderr) - assert Log.objects.first().exit_code == 0 +def test_tee_okay(stdout: StringIO, stderr: StringIO, mocker): + with mocker.patch("django.db.connections.close_all"): + # patch wymagany, bo BaseCommand wywołuje close_all + call_command("tee", "tee_test_okay", stdout=stdout, stderr=stderr) + assert Log.objects.first().finished_successfully assert "Used print()" in stdout.getvalue() assert "Used print()" in stderr.getvalue() @pytest.mark.django_db -def test_tee_exception(stdout, stderr): - call_command("tee", "tee_test_exception", stdout=stdout, stderr=stderr) +def test_tee_exception(stdout, stderr, mocker): + with mocker.patch("django.db.connections.close_all"): + # patch wymagany, bo BaseCommand wywołuje close_all + call_command("tee", "tee_test_exception", stdout=stdout, stderr=stderr) assert Log.objects.first().traceback - - -@pytest.mark.django_db -def test_tee_result(stdout, stderr): - call_command("tee", "tee_test_result", stdout=stdout, stderr=stderr) - assert "Unable to encode" in Log.objects.first().exit_value