示例#1
0
def test_trigger():
    instance = TriggerConcurrentModel()
    assert instance.pk is None
    assert instance.version == 0

    instance.username = next(nextname)
    instance.save()  # insert
    instance = refetch(instance)
    assert instance.version == 1

    instance.username = next(nextname)
    instance.save()  # update
    assert instance.version == 2

    instance.username = next(nextname)
    instance.save()  # update
    assert instance.version == 3

    instance.username = next(nextname)
    instance.save(refetch=True)  # update
    assert instance.version == 4

    copy = refetch(instance)
    copy.save()

    with pytest.raises(RecordModifiedError):
        instance.save()
def test_trigger():
    instance = TriggerConcurrentModel()
    assert instance.pk is None
    assert instance.version == 0

    instance.username = next(nextname)
    instance.save()  # insert
    instance = refetch(instance)
    assert instance.version == 1

    instance.username = next(nextname)
    instance.save()  # update
    assert instance.version == 2

    instance.username = next(nextname)
    instance.save()  # update
    assert instance.version == 3

    instance.username = next(nextname)
    instance.save(refetch=True)  # update
    assert instance.version == 4

    copy = refetch(instance)
    copy.save()

    with pytest.raises(RecordModifiedError):
        instance.save()
def test_save_allowed(instance):
    # Scenario: batch change field NOT present in ConcurrencyMeta.check_fields
    # the user is ALLOWED to save
    batch_instance = instance.__class__.objects.get(pk=instance.pk)
    assert batch_instance.version == instance.version
    instance = refetch(instance)
    batch_instance = refetch(instance)

    batch_instance.field3 = 'aaaa'
    batch_instance.save()
    instance.save()
def test_save_allowed(instance):
    # Scenario: batch change field NOT present in ConcurrencyMeta.check_fields
    # the user is ALLOWED to save
    batch_instance = instance.__class__.objects.get(pk=instance.pk)
    assert batch_instance.version == instance.version
    instance = refetch(instance)
    batch_instance = refetch(instance)

    batch_instance.field3 = 'aaaa'
    batch_instance.save()
    instance.save()
def test_disable_concurrency_instance(model_class=SimpleConcurrentModel):
    instance1 = model_class(username=next(nextname))
    instance1.save()
    copy1 = refetch(instance1)
    copy1.save()

    instance2 = model_class(username=next(nextname))
    instance2.save()
    copy2 = refetch(instance2)
    copy2.save()

    with disable_concurrency(instance1):
        instance1.save()
        with pytest.raises(RecordModifiedError):
            instance2.save()
def test_disable_concurrency_instance(model_class=SimpleConcurrentModel):
    instance1 = model_class(username=next(nextname))
    instance1.save()
    copy1 = refetch(instance1)
    copy1.save()

    instance2 = model_class(username=next(nextname))
    instance2.save()
    copy2 = refetch(instance2)
    copy2.save()

    with disable_concurrency(instance1):
        instance1.save()
        with pytest.raises(RecordModifiedError):
            instance2.save()
def test_disable_concurrency_class(model_class=SimpleConcurrentModel):
    instance = model_class(username=next(nextname))
    instance.save()
    copy = refetch(instance)
    copy.save()
    with disable_concurrency(SimpleConcurrentModel):
        instance.save()
def test_disable_concurrency_class(model_class=SimpleConcurrentModel):
    instance = model_class(username=next(nextname))
    instance.save()
    copy = refetch(instance)
    copy.save()
    with disable_concurrency(SimpleConcurrentModel):
        instance.save()
示例#9
0
def test_get_version(model_class=SimpleConcurrentModel):
    instance = model_class(username=next(nextname))
    instance.save()
    copy = refetch(instance)
    copy.save()
    instance = get_version(instance, copy.version)
    assert instance.get_concurrency_version() == copy.get_concurrency_version()
def test_trigger_external_create():
    with connection.cursor() as c:
        c.execute("INSERT INTO {} (username, count, cm_version_id) VALUES ('abc', 1, -1)".format(
            TriggerConcurrentModel._meta.db_table))
    instance = TriggerConcurrentModel.objects.get(username='******')
    obj = refetch(instance)
    assert obj.version == -1
示例#11
0
def test_threads():
    if db.connection.vendor == 'sqlite':
        pytest.skip("in-memory sqlite db can't be used between threads")

    obj = TriggerConcurrentModel.objects.create()
    transaction.commit()

    @concurrently(25)
    def run():
        for i in range(5):
            while True:
                x = refetch(obj)
                transaction.commit()
                x.count += 1
                try:
                    x.save()
                    transaction.commit()
                except RecordModifiedError:
                    # retry
                    pass
                else:
                    break

    run()
    assert refetch(obj).count == 5 * 25
示例#12
0
def test_get_version(model_class=SimpleConcurrentModel):
    instance = model_class(username=next(nextname))
    instance.save()
    copy = refetch(instance)
    copy.save()
    instance = get_version(instance, copy.version)
    assert instance.get_concurrency_version() == copy.get_concurrency_version()
示例#13
0
def test_update_fields(model_class):
    """
    Calling save with update_fields not containing version doesn't update
    the version.
    """

    instance = model_class.objects.create(username='******')
    copy = refetch(instance)

    # do not update version
    instance.save(update_fields=['username'])

    # copy can be saved
    copy.username = '******'
    copy.save()
    assert refetch(instance).username, 'def'
    assert refetch(instance).version == copy.version
示例#14
0
def test_trigger_external_create():
    with connection.cursor() as c:
        c.execute(
            "INSERT INTO {} (username, count, cm_version_id) VALUES ('abc', 1, -1)"
            .format(TriggerConcurrentModel._meta.db_table))
    instance = TriggerConcurrentModel.objects.get(username='******')
    obj = refetch(instance)
    assert obj.version == -1
示例#15
0
def test_update(model_class):
    # Manager.update() does not change version number
    instance = model_class.objects.create(pk=next(unique_id), username=next(nextname).lower())
    field_value = instance.username
    model_class.objects.filter(pk=instance.pk).update(username=instance.username.upper())

    instance2 = refetch(instance)
    assert instance2.username == field_value.upper()
    assert instance2.get_concurrency_version() == instance.get_concurrency_version()
示例#16
0
def test_get_or_create_with_pk(model_class):
    instance, __ = model_class.objects.get_or_create(pk=next(unique_id))
    assert instance.get_concurrency_version()
    instance.save()
    copy = refetch(instance)
    copy.save()
    with pytest.raises(RecordModifiedError):
        instance.save()
    assert copy.get_concurrency_version() > instance.get_concurrency_version()
示例#17
0
def test_get_or_create_with_pk(model_class):
    instance, __ = model_class.objects.get_or_create(pk=next(unique_id))
    assert instance.get_concurrency_version()
    instance.save()
    copy = refetch(instance)
    copy.save()
    with pytest.raises(RecordModifiedError):
        instance.save()
    assert copy.get_concurrency_version() > instance.get_concurrency_version()
示例#18
0
 def inner(self, force_insert=False, force_update=False, using=None, **kwargs):
     reload = kwargs.pop('refetch', False)
     ret = func(self, force_insert, force_update, using, **kwargs)
     TriggerVersionField._increment_version_number(self)
     if reload:
         ret = refetch(self)
         setattr(self,
                 self._concurrencymeta.field.attname,
                 get_revision_of_object(ret))
     return ret
def test_select_lock(settings):
    s1 = SimpleConcurrentModel.objects.create()
    s2 = refetch(s1)
    assert s1.version == s2.version
    s2.save()
    with pytest.raises(RecordModifiedError):
        _select_lock(s1)

    settings.CONCURRENCY_ENABLED = False
    _select_lock(s1)
def test_trigger_external_update():
    instance = TriggerConcurrentModel()
    assert instance.pk is None
    assert instance.version == 0

    instance.save()
    assert instance.version == 1
    with connection.cursor() as c:
        c.execute("UPDATE {} SET username='******' WHERE id='{}'".format(instance._meta.db_table, instance.pk))
    obj = refetch(instance)
    assert obj.version == 2
示例#21
0
def test_apply_concurrency_check():
    apply_concurrency_check(Group, 'version', IntegerVersionField)

    instance, __ = Group.objects.get_or_create(name=next(nextgroup))
    instance.save()

    copy = refetch(instance)
    copy.save()

    with pytest.raises(RecordModifiedError):
        instance.save()
示例#22
0
def test_apply_concurrency_check():
    apply_concurrency_check(Group, 'version', IntegerVersionField)

    instance, __ = Group.objects.get_or_create(name=next(nextgroup))
    instance.save()

    copy = refetch(instance)
    copy.save()

    with pytest.raises(RecordModifiedError):
        instance.save()
示例#23
0
def test_update(model_class):
    # Manager.update() does not change version number
    instance = model_class.objects.create(pk=next(unique_id),
                                          username=next(nextname).lower())
    field_value = instance.username
    model_class.objects.filter(pk=instance.pk).update(
        username=instance.username.upper())

    instance2 = refetch(instance)
    assert instance2.username == field_value.upper()
    assert instance2.get_concurrency_version(
    ) == instance.get_concurrency_version()
示例#24
0
def test_trigger_external_update():
    instance = TriggerConcurrentModel()
    assert instance.pk is None
    assert instance.version == 0

    instance.save()
    assert instance.version == 1
    with connection.cursor() as c:
        c.execute("UPDATE {} SET username='******' WHERE id='{}'".format(
            instance._meta.db_table, instance.pk))
    obj = refetch(instance)
    assert obj.version == 2
示例#25
0
def test_update_fields_still_checks(model_class):
    """
    Excluding the VersionField from update_fields should still check
    for conflicts.
    """
    instance = model_class.objects.create(username='******')
    copy = refetch(instance)
    instance.save()
    copy.name = 'def'

    with pytest.raises(RecordModifiedError):
        copy.save(update_fields=['username'])
示例#26
0
def test_conflict_no_version_and_no_skip_flag(model_class):
    """When IGNORE_DEFAULT is disabled, attempting to update a record with a default version number should fail."""
    with override_settings(CONCURRENCY_IGNORE_DEFAULT=False):
        id = next(unique_id)
        instance, __ = model_class.objects.get_or_create(pk=id)
        instance.save()

        copy = refetch(instance)
        copy.version = 0

        with pytest.raises(RecordModifiedError):
            copy.save()
示例#27
0
def test_conflict(model_class, protocol, monkeypatch):
    monkeypatch.setattr(concurrency.config.conf, 'PROTOCOL', protocol)

    id = next(unique_id)
    instance = model_class.objects.get_or_create(pk=id)[0]
    instance.save()

    copy = refetch(instance)
    copy.save()

    with pytest.raises(RecordModifiedError):
        instance.save()
    assert copy.get_concurrency_version() > instance.get_concurrency_version()
示例#28
0
def test_conflict(model_class, protocol, monkeypatch):
    monkeypatch.setattr(concurrency.config.conf, 'PROTOCOL', protocol)

    id = next(unique_id)
    instance = model_class.objects.get_or_create(pk=id)[0]
    instance.save()

    copy = refetch(instance)
    copy.save()

    with pytest.raises(RecordModifiedError):
        instance.save()
    assert copy.get_concurrency_version() > instance.get_concurrency_version()
示例#29
0
 def run():
     for i in range(5):
         while True:
             x = refetch(obj)
             transaction.commit()
             x.count += 1
             try:
                 x.save()
                 transaction.commit()
             except RecordModifiedError:
                 # retry
                 pass
             else:
                 break
示例#30
0
def test_do_not_check_if_no_version(model_class):
    id = next(unique_id)
    instance, __ = model_class.objects.get_or_create(pk=id)
    instance.save()

    copy = refetch(instance)
    copy.save()

    with pytest.raises(RecordModifiedError):
        _set_version(instance, 1)
        instance.version = 1
        instance.save()

    _set_version(instance, 0)
    instance.save()
    assert instance.get_concurrency_version() > 0
    assert instance.get_concurrency_version() != copy.get_concurrency_version()
def test_disable_concurrency_global():
    instance1 = SimpleConcurrentModel(username=next(nextname))
    instance2 = AutoIncConcurrentModel(username=next(nextname))
    instance1.save()
    instance2.save()
    refetch(instance1).save()
    refetch(instance2).save()
    with disable_concurrency():
        instance1.save()
        instance2.save()

    copy2 = refetch(instance2)
    refetch(instance2).save()
    with pytest.raises(RecordModifiedError):
        copy2.save()
    def test_concurrency(self):
        id = 1
        admin_register(ListEditableConcurrentModel, ActionsModelAdmin)
        model_admin = site._registry[ListEditableConcurrentModel]
        with attributes((ConcurrentModelAdmin, 'list_editable_policy', CONCURRENCY_LIST_EDITABLE_POLICY_SILENT),
                        (ConcurrentModelAdmin, 'form', ConcurrentForm), ):
            obj, __ = ListEditableConcurrentModel.objects.get_or_create(pk=id)
            request1 = get_fake_request('pk=%s&_concurrency_version_1=2' % id)

            model_admin.save_model(request1, obj, None, True)

            self.assertIn(obj.pk, model_admin._get_conflicts(request1))

            obj = refetch(obj)
            request2 = get_fake_request('pk=%s&_concurrency_version_1=%s' % (id, obj.version))
            model_admin.save_model(request2, obj, None, True)
            self.assertNotIn(obj.pk, model_admin._get_conflicts(request2))
def test_disable_concurrency_global():
    instance1 = SimpleConcurrentModel(username=next(nextname))
    instance2 = AutoIncConcurrentModel(username=next(nextname))
    instance1.save()
    instance2.save()
    refetch(instance1).save()
    refetch(instance2).save()
    with disable_concurrency():
        instance1.save()
        instance2.save()

    copy2 = refetch(instance2)
    refetch(instance2).save()
    with pytest.raises(RecordModifiedError):
        copy2.save()
示例#34
0
def test_do_not_check_if_no_version(model_class):

    with override_settings(CONCURRENCY_VERSION_FIELD_REQUIRED=False):
        id = next(unique_id)
        instance, __ = model_class.objects.get_or_create(pk=id)
        instance.save()

        copy = refetch(instance)
        copy.save()

        with pytest.raises(RecordModifiedError):
            _set_version(instance, 1)
            instance.version = 1
            instance.save()

        _set_version(instance, 0)
        instance.save()
        assert instance.get_concurrency_version() > 0
        assert instance.get_concurrency_version() != copy.get_concurrency_version()
def test_standard_save(instance):
    # only increment if checked field
    instance = refetch(instance)
    version1 = instance.get_concurrency_version()
    assert version1 == 1  # version2 > version1

    instance.field1 = '2'
    instance.save()
    version2 = instance.get_concurrency_version()
    assert version2 == 2  # version2 > version1

    instance.field3 = '3'
    instance.save()
    version3 = instance.get_concurrency_version()
    assert version3 == 2  # version3 == version2

    instance.user = None
    instance.save()
    version4 = instance.get_concurrency_version()
    assert version4 == 3  # version4 > version2
def test_do_not_check_if_no_version(model_class):

    with override_settings(CONCURRENCY_VERSION_FIELD_REQUIRED=False):
        id = next(unique_id)
        instance, __ = model_class.objects.get_or_create(pk=id)
        instance.save()

        copy = refetch(instance)
        copy.save()

        with pytest.raises(RecordModifiedError):
            _set_version(instance, 1)
            instance.version = 1
            instance.save()

        _set_version(instance, 0)
        instance.save()
        assert instance.get_concurrency_version() > 0
        assert instance.get_concurrency_version(
        ) != copy.get_concurrency_version()
def test_standard_save(instance):
    # only increment if checked field
    instance = refetch(instance)
    version1 = instance.get_concurrency_version()
    assert version1 == 1  # version2 > version1

    instance.field1 = '2'
    instance.save()
    version2 = instance.get_concurrency_version()
    assert version2 == 2  # version2 > version1

    instance.field3 = '3'
    instance.save()
    version3 = instance.get_concurrency_version()
    assert version3 == 2  # version3 == version2

    instance.user = None
    instance.save()
    version4 = instance.get_concurrency_version()
    assert version4 == 3  # version4 > version2
示例#38
0
    def test_concurrency(self):
        id = 1
        admin_register(ListEditableConcurrentModel, ActionsModelAdmin)
        model_admin = site._registry[ListEditableConcurrentModel]
        with attributes(
            (ConcurrentModelAdmin, 'list_editable_policy',
             CONCURRENCY_LIST_EDITABLE_POLICY_SILENT),
            (ConcurrentModelAdmin, 'form', ConcurrentForm),
        ):
            obj, __ = ListEditableConcurrentModel.objects.get_or_create(pk=id)
            request1 = get_fake_request('pk=%s&_concurrency_version_1=2' % id)

            model_admin.save_model(request1, obj, None, True)

            self.assertIn(obj.pk, model_admin._get_conflicts(request1))

            obj = refetch(obj)
            request2 = get_fake_request('pk=%s&_concurrency_version_1=%s' %
                                        (id, obj.version))
            model_admin.save_model(request2, obj, None, True)
            self.assertNotIn(obj.pk, model_admin._get_conflicts(request2))
示例#39
0
def test_is_changed(model_class=SimpleConcurrentModel):
    instance = model_class(username=next(nextname))
    instance.save()
    copy = refetch(instance)
    copy.save()
    assert is_changed(instance)
def test_disable_concurrency_settings(settings):
    with override_settings(CONCURRENCY_ENABLED=False):
        instance1 = SimpleConcurrentModel(username=next(nextname))
        instance1.save()
        refetch(instance1).save()
示例#41
0
def test_is_changed(model_class=SimpleConcurrentModel):
    instance = model_class(username=next(nextname))
    instance.save()
    copy = refetch(instance)
    copy.save()
    assert is_changed(instance)
def test_disable_concurrency_settings(settings):
    with override_settings(CONCURRENCY_ENABLED=False):
        instance1 = SimpleConcurrentModel(username=next(nextname))
        instance1.save()
        refetch(instance1).save()
示例#43
0
def test_standard_save(model_class):
    instance = model_class(username=concurrent_model.__name__)
    instance.save()
    assert instance.get_concurrency_version() > 0
    instance = refetch(instance)
    assert instance.get_concurrency_version() > 0
 def test1():
     instance = SimpleConcurrentModel(username=next(nextname))
     instance.save()
     copy = refetch(instance)
     copy.save()
     instance.save()
 def test1():
     instance = SimpleConcurrentModel(username=next(nextname))
     instance.save()
     copy = refetch(instance)
     copy.save()
     instance.save()