File: test_multi_db.py

package info (click to toggle)
python-django-pgtrigger 4.15.3-1
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 956 kB
  • sloc: python: 4,412; makefile: 114; sh: 8; sql: 2
file content (137 lines) | stat: -rw-r--r-- 5,236 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
"""Tests multi-database support"""

import contextlib

import ddf
import pytest
from django.contrib.auth.models import User
from django.core.management import call_command
from django.db import transaction

import pgtrigger
from pgtrigger import core
from pgtrigger.tests import models, utils


class ToLogRouter:
    """
    Route the "ToLog" model to the "other" database
    """

    route_app_labels = {"auth", "contenttypes"}

    def db_for_write(self, model, **hints):
        if model == models.ToLogModel:
            return "other"

        return None


@pytest.fixture(autouse=True)
def routed_db(settings):
    settings.DATABASE_ROUTERS = [
        "pgtrigger.tests.test_multi_db.ToLogRouter",
        "pgtrigger.tests.models.Router",
    ]


@pytest.mark.django_db(databases=["default", "sqlite", "other"], transaction=True)
def test_multi_db_ignore():
    """Tests ignoring triggers across multiple databases"""
    trigger = pgtrigger.Protect(operation=pgtrigger.Delete, name="protect_deletes")

    with contextlib.ExitStack() as stack:
        stack.enter_context(trigger.register(models.ToLogModel))
        stack.enter_context(trigger.register(User))
        stack.enter_context(trigger.install(models.ToLogModel, database="other"))
        stack.enter_context(trigger.install(User))

        with utils.raises_trigger_error(match="Cannot delete", database="other"):
            log = ddf.G(models.ToLogModel)
            log.delete()

        with utils.raises_trigger_error(match="Cannot delete"):
            user = ddf.G(User)
            user.delete()

        with transaction.atomic():
            with pgtrigger.ignore("tests.ToLogModel:protect_deletes", "auth.User:protect_deletes"):
                log = models.ToLogModel.objects.create()
                log.delete()
                user = ddf.G(User)
                user.delete()

            with utils.raises_trigger_error(match="Cannot delete"):
                user = User.objects.create(username="hi")
                user.delete()

            with utils.raises_trigger_error(match="Cannot delete", database="other"):
                log = models.ToLogModel.objects.create()
                log.delete()


@pytest.mark.django_db(databases=["default", "sqlite", "other"])
def test_full_ls(capsys):
    call_command("pgtrigger", "ls")
    captured = capsys.readouterr()
    lines = [line for line in captured.out.split("\n") if line]
    for line in lines:
        assert "\x1b[92mINSTALLED\x1b[0m" in line

    call_command("pgtrigger", "ls", "-d", "other")
    captured = capsys.readouterr()
    lines = [line for line in captured.out.split("\n") if line]
    for line in lines:
        # The router ignores partition models for the default DB
        if "tests.PartitionModel:protect_delete" in line:
            assert "\x1b[94mUNALLOWED\x1b[0m" in line
        else:
            assert "\x1b[92mINSTALLED\x1b[0m" in line

    call_command("pgtrigger", "ls", "-d", "sqlite")
    captured = capsys.readouterr()
    lines = [line for line in captured.out.split("\n") if line]
    for line in lines:
        assert "\x1b[94mUNALLOWED\x1b[0m" in line


@pytest.mark.django_db(databases=["other"])
def test_disable_enable(capsys):
    call_command("pgtrigger", "disable", "-d", "other")
    for model, trigger in pgtrigger.registered():
        expected_status = None if model == models.PartitionModel else False
        assert trigger.get_installation_status(model, database="other")[1] is expected_status

    call_command("pgtrigger", "enable", "--database", "other")
    for model, trigger in pgtrigger.registered():
        expected_status = None if model == models.PartitionModel else True
        assert trigger.get_installation_status(model, database="other")[1] is expected_status


@pytest.mark.django_db(databases=["sqlite"])
def test_ignore_non_postgres_dbs():
    call_command("pgtrigger", "uninstall", "-d", "sqlite")
    call_command("pgtrigger", "install", "-d", "sqlite")
    call_command("pgtrigger", "install", "-d", "sqlite")
    call_command("pgtrigger", "prune", "-d", "sqlite")


@pytest.mark.django_db(databases=["other", "default", "sqlite"])
def test_uninstall_install():
    for model, trigger in pgtrigger.registered():
        expected_status = core.UNALLOWED if model == models.PartitionModel else core.INSTALLED
        assert trigger.get_installation_status(model, database="other")[0] == expected_status

    call_command("pgtrigger", "uninstall", "-d", "other")
    call_command("pgtrigger", "uninstall", "-d", "default")
    for model, trigger in pgtrigger.registered():
        expected_status = core.UNALLOWED if model == models.PartitionModel else core.UNINSTALLED
        assert trigger.get_installation_status(model, database="other")[0] == expected_status

    call_command("pgtrigger", "install", "--database", "other")
    for model, trigger in pgtrigger.registered():
        expecetd_status = core.UNALLOWED if model == models.PartitionModel else core.INSTALLED
        assert trigger.get_installation_status(model, database="other")[0] == expecetd_status

    for model, trigger in pgtrigger.registered():
        assert trigger.get_installation_status(model, database="default")[0] == core.UNINSTALLED