Esempio n. 1
0
    def test_forwardCalls(self):
        cb = ContextBroker()

        fwdCalls = {
            'getToi': 1,
            'addToi': 1,
            'createToi': 3,
            'changeToi': 2,
            'deleteToi': 1,
            'register': 1,
            'runQuery': 1,
            'requestAttribute': 2,
            'callMethod': 1,
            'newId': 0,
        }

        callCollector = CallCollector()
        cb.pushContext(callCollector)

        expected = []
        for call, argN in fwdCalls.items():
            args = tuple(object() for i in range(argN))
            retVal = getattr(cb, call)(*args)
            expected.append((call, args, {}, retVal))

        assert callCollector.calls == expected
Esempio n. 2
0
    def test_popContext_returnValOk(self):
        cb = ContextBroker()
        ctx = object()
        cb.pushContext(ctx)

        assert cb.context is ctx
        assert cb.popContext() is ctx
Esempio n. 3
0
    def test_otherThread_startsEmpty(self):
        cb = ContextBroker()
        ctx = object()
        cb.pushContext(ctx)

        def getContext():
            return cb.context

        py.test.raises(LookupError, runInThread, 1.0, getContext)
Esempio n. 4
0
    def test_effectOfPopContextOk(self):
        cb = ContextBroker()
        py.test.raises(IndexError, cb.popContext)
        ctx1 = object()
        ctx2 = object()
        cb.pushContext(ctx1)
        cb.pushContext(ctx2)

        assert cb.context is ctx2
        assert cb.popContext() is ctx2
        assert cb.context is ctx1
Esempio n. 5
0
    def test_rerun_conflicting_commit(self):
        toi = blm.testcommit.Test(name=['foo'])
        self.sync()
        assert self.find_one({'_id': toi.id[0]})
        cctx = self.newcontext()
        op = commit.CallToi(toi.id[0], 'add', [['bar']])
        commitId = cctx.runCommit([op], processCommits=False)
        ContextBroker().popContext()
        toi.extra = ['conflict']
        self.sync()

        _rerunCommit = cctx.rerunCommit

        def rerunCommit(*args, **kw):
            db_toi_data = self.find_one({'_id': toi.id[0]})
            assert db_toi_data.get('_terms', []) == []
            return _rerunCommit(*args, **kw)

        cctx.rerunCommit = rerunCommit

        cctx.processCommits(commitId)
        self.sync()

        cctx = self.newcontext()
        toi, = blm.testcommit.Test._query().run()
        assert toi.extra == ['conflict', 'bar']

        db_toi_data = self.find_one({'_id': toi.id[0]})
        py.test.skip('full text index disabled for now')
        assert db_toi_data['_terms'] == [{
            'toid': toi.id[0],
            'data': ['bar', 'conflict']
        }]
Esempio n. 6
0
    def test_runAfterCommitFailing(self):
        py.test.xfail("post-commit hooks not supported")
        callbackCalled = []

        def callback(tid, *args, **kw):
            callbackCalled.append((tid, args, kw))
            raise RuntimeError('error')

        def callback2(tid, *args, **kw):
            callbackCalled.append((tid, args, kw))

        class Op(commit.OperateBase):
            def checkPermissions(self, context):
                pass

            def operate(self, context):
                context.runAfterCommit(callback, 42, foo='bar')
                context.runAfterCommit(callback2, 43)

        cctx = commit.CommitContext(self.database)
        ContextBroker().pushContext(cctx)
        cctx.setMayChange(True)

        results = cctx.runCommit([Op()])

        assert callbackCalled == [(None, (42, ), {
            'foo': 'bar'
        }), (None, (43, ), {})]
Esempio n. 7
0
 def newcontext(self, user=None):
     if user is None:
         user = self.user
     ctx = commit.CommitContext(self.database, user)
     ctx.setMayChange(True)
     ContextBroker().pushContext(ctx)
     return ctx
Esempio n. 8
0
    def test_otherThread_pushContext(self):
        cb = ContextBroker()
        ctx = object()

        def check_pushContext():
            cb.pushContext(ctx)
            assert cb.context is ctx
            assert cb.popContext() is ctx

        runInThread(1.0, check_pushContext)
Esempio n. 9
0
    def test_notifyChanges_being_called(self):
        result = []

        def notifyChanges(commits):
            result.append([c._id for c in commits])

        cctx = self.newcontext()
        cctx.id = None  # cheat - pretend that this commit is unhandled
        commit1 = cctx.createCommit([], [])
        commit1.save(self.database)
        ContextBroker().popContext()

        cctx = self.newcontext()
        commit2 = cctx.createCommit([], [])
        ContextBroker().popContext()

        cctx.notifyChanges = notifyChanges
        cctx.processCommits(commit2)

        expected = [[commit2._id, commit1._id]]
        assert result == expected
Esempio n. 10
0
    def test_with_no_context(self):
        py.test.raises(Exception, lambda: ContextBroker().context)  # sanity
        database = object()

        @context.maybe_with_context()
        def foo(arg):
            assert isinstance(ContextBroker().context, context.ReadonlyContext)
            assert ContextBroker().context.database is database
            return arg

        obj = object()
        assert foo(obj, database=database) is obj
Esempio n. 11
0
    def test_createToi(self):
        cctx = self.newcontext()
        toi = cctx.createToi(blm.testcommit.Test, cctx.newId(),
                             {'name': ['test']})

        assert toi.name == ['test']
        assert toi.__class__._query(name='test').run()[0] is toi
        assert self.find({'_toc': 'testcommit.Test'}).count() == 0

        ContextBroker().popContext()
        cctx.runCommit([])
        assert self.find({'_toc': 'testcommit.Test'}).count() == 1
Esempio n. 12
0
    def test_canWrite_new_toi(self):
        user = blm.fundamental.AccessHolder()
        cctx = self.newcontext(user=user)
        toi = cctx.createToi(blm.testcommit.Test, cctx.newId(),
                             {'name': ['test']})
        self.sync()
        assert toi.name == ['test']
        assert toi.__class__._query(name='test').run()[0] is toi
        assert self.find({'_toc': 'testcommit.Test'}).count() == 0

        ContextBroker().popContext()
        cctx.runCommit([])
        assert self.find({'_toc': 'testcommit.Test'}).count() == 1
Esempio n. 13
0
def setuid(user=None):
    context = ContextBroker().context
    current = context.user
    context.setUser(user)
    try:
        yield
    finally:
        context.setUser(current)
Esempio n. 14
0
    def _commit(self,
                interested=None,
                _id=ObjectId(),
                operations=[],
                result=[['result'], 42],
                error=None):
        toiToDelete = blm.testcommit.Test(name=['baz'])
        toiToChange = blm.testcommit.Test(name=['foo'])
        cctx = self.newcontext()
        toiToCreate = blm.testcommit.Test(name=['bar'])

        new = DiffTOI()
        new.setToi(toiToCreate)

        changed = DiffTOI()
        changed.setAttrDiff(toiToChange.__class__, toiToChange.id[0],
                            toiToChange._attrData, {'name': ['apa']})
        doc = {
            '_id': _id,
            'newTois': [new],
            'changedTois': [changed],
            'deletedTois': [toiToDelete.id[0]],
            'operations': operations,
            'addedBlobVals': {},
            'deletedBlobVals': {},
            'results': result,
            'error': error,
            'indexData': [],
            'handled_by': cctx.id,
            'user': cctx.user,
            'interested': interested
        }
        commitId = mongo.insert(self.database.commits, doc)
        assert commitId
        self.sync()
        ContextBroker().popContext()

        assert self.find_one({'_id': toiToChange.id[0]})['name'] == ['foo']
        assert not self.find_one({'_id': toiToCreate.id[0]})
        assert self.find_one({'_id': toiToDelete.id[0]})
        cctx.commit(commit.Commit.fromquery(self.database, {'_id': commitId}))
        self.sync()

        assert self.find_one({'_id': toiToChange.id[0]})['name'] == ['apa']
        assert self.find_one({'_id': toiToCreate.id[0]})
        assert not self.find_one({'_id': toiToDelete.id[0]})
        return commitId
Esempio n. 15
0
    def test_deleteToi(self):
        toi = blm.testcommit.Test(name=['text'])
        print(toi, toi.__class__)
        self.sync()

        cctx = self.newcontext()
        toi, = blm.testcommit.Test._query().run()
        toi._delete()
        print(toi, toi.__class__)
        assert toi.__class__._query().run() == []
        self.sync()
        assert self.find({'_toc': 'testcommit.Test'}).count() == 1

        ContextBroker().popContext()
        cctx.runCommit([])

        assert self.find({'_toc': 'testcommit.Test'}).count() == 0
Esempio n. 16
0
 def _run(self, params, state):
     tois = ContextBroker().runQuery(params['criteria'])
     result = dict([(str(t.id[0]), t._fullname) for t in tois])
     update = None
     if result != state:
         state = state or {}
         added = dict(item for item in list(result.items())
                      if item not in list(state.items()))
         deleted = dict(item for item in list(state.items())
                        if item not in list(result.items()))
         update = { 'add' : added,
                    'del' : deleted,
                    'relevance' : None,
                    'error' : None }
     persistent = params.get('subscription')
     self.update(update, persistent=persistent)
     if persistent:
         self.save(params, result)
Esempio n. 17
0
    def test_changeToi(self):
        toi = blm.testcommit.Test(name=['test'])
        self.sync()

        cctx = self.newcontext()
        # New context, so we have to look it up again
        toi = blm.testcommit.Test._query().run()[0]

        toi(extra=['fOo'])

        assert toi.extra == ['fOo']
        assert toi.__class__._query(extra='fOo').run()[0] is toi
        assert toi.__class__._query(extra=None).run() == []
        dbtoi, = list(self.database.tois.find({'_toc': 'testcommit.Test'}))
        assert dbtoi.get('extra', []) == []

        ContextBroker().popContext()
        cctx.runCommit([])

        dbtoi, = list(self.database.tois.find({'_toc': 'testcommit.Test'}))
        assert dbtoi['extra'] == ['fOo']
Esempio n. 18
0
    def test_changeToi_with_nop_change(self):
        toi = blm.testcommit.Test(name=['test'])
        self.sync()

        cctx = self.newcontext()
        # New context, so we have to look it up again
        toi = blm.testcommit.Test._query(_attrList=['name']).run()[0]

        toi(name=['fOo'])

        assert toi.name == ['fOo']
        assert toi.__class__._query(name='fOo').run()[0] is toi
        assert toi.__class__._query(name=None).run() == []
        dbtoi, = list(self.database.tois.find({'_toc': 'testcommit.Test'}))
        assert dbtoi.get('extra', []) == []

        toi(name=['test'])  # Restore to original value

        ContextBroker().popContext()
        commit = cctx.runCommit([])
        assert commit.state != 'failed'

        dbtoi, = list(self.database.tois.find({'_toc': 'testcommit.Test'}))
        assert dbtoi['name'] == ['test']
Esempio n. 19
0
 def __enter__(self):
     ContextBroker().pushContext(self)
     return self
Esempio n. 20
0
 def foo():
     assert isinstance(ContextBroker().context, MyContext)
Esempio n. 21
0
 def foo(arg):
     assert isinstance(ContextBroker().context, context.ReadonlyContext)
     assert ContextBroker().context.database is database
     return arg
Esempio n. 22
0
 def teardown_method(self, method):
     super(TestBlobVal, self).teardown_method(method)
     ContextBroker().popContext()
Esempio n. 23
0
 def setup_method(self, method):
     super(TestBlobVal, self).setup_method(method)
     class FakeContext(object):
         database = self.database
     ContextBroker().pushContext(FakeContext())
Esempio n. 24
0
 def test_pushContext(self):
     cb = ContextBroker()
     ctx = object()
     cb.pushContext(ctx)
     assert cb.context is ctx
Esempio n. 25
0
 def test_popEmpty(self):
     cb = ContextBroker()
     py.test.raises(IndexError, lambda: cb.popContext())
Esempio n. 26
0
 def test_singleton(self):
     "Enshures that the ContextBroker is a singleton."
     assert ContextBroker() is ContextBroker()
Esempio n. 27
0
 def __exit__(self, exc_type, exc_val, exc_tb):
     assert ContextBroker().context == self
     ContextBroker().popContext()
Esempio n. 28
0
class TestAttribute(object):

    BASIC_VALUE_TESTS = (
        (Bool, (True, False, None)),
        (Blob, ('good float', False, None)),
        (Decimal, (decimal.Decimal('0.0'), 'bad decimal', DecimalValueError)),
        (DecimalMap, (('somekey', decimal.Decimal('1.0')), ('somekey', 'bad val'), DecimalValueError)),
        (DecimalMap, (('somekey', '1.0'), (None, 1), StringValueError)),
        (DecimalMap, (('somekey', 1), 42, TypeError)),
        (Float, (1.0, 'bad float', FloatValueError)),
        (Int, (1, 'bad int', IntValueError)),
        (Int, ('1', False, None)),
        (Int, (1, False, None)),
        (IntMap, (('somekey', 1), ('somekey', 'bad val'), IntValueError)),
        (IntMap, (('somekey', '1'), (None, 1), StringValueError)),
        (IntMap, (('somekey', 1), 42, TypeError)),
        (String, ('good string', False, None)),
        (String, (my_unicode('foo'), False, None)),
        (LimitedString, ('god limited string', False, None)),
        (Timespan, (1, 'bad timespan', TimespanValueError)),
        (TimespanMap, (('somekey', 1), ('somekey', 'bad val'), TimespanValueError)),
        (TimespanMap, (('somekey', '1'), (None, 1), StringValueError)),
        (TimespanMap, (('somekey', 1), 42, TypeError)),
        (Timestamp, (1, 'bad timestamp', TimestampValueError)),
        (TimestampMap, (('somekey', 1), ('somekey', 'bad val'), TimestampValueError)),
        (TimestampMap, (('somekey', '1'), (None, 1), StringValueError)),
        (TimestampMap, (('somekey', 1), 42, TypeError)),
    )

    cb = ContextBroker()

    def setup_method(self, method):
        # Erase leftovers from previous tests...
        self.cb.contextDict.clear()
        self.context = FakeContext()
        self.cb.pushContext(self.context)

    def teardown_method(self, method):
        self.cb.contextDict.clear()

    def test_AttributeInherited(self):
        "Tests that Attribute has to be derived to be used"

        def spam():
            class dummyAttr(Attribute()):
                spam

        raises(SyntaxError, spam)

    def test_ModifierInheritance(self):
        "Tests that attributes only can inherit Modifiers"

        def spam():

            class foo(object):
                pass

            class bar(Int(foo())):
                pass

        raises(TypeError, spam)

    def test_AttributeSimple(self):
        "Tests a simple attribute declaration"

        class spam(Attribute):
            pass

    def test_ModifierValidity(self):
        "Tests that a modifier has to be applicable to be inherited"

        def spam():

            class dummyRest(Restriction):
                pass

            class dummyAttr(Int()):
                pass

            class foo(dummyAttr(dummyRest())):
                pass

        raises(TypeError, spam)

    def test_ToiDeleted(self):
        class FakeToi(object):
            _deleted = True
            _fullname = 'FakeToi'
            id = [27]
            attr = Attribute._instantiate('attr')
            _xlatKey = 'FakeToi'

        toi = FakeToi()
        raises(ToiDeletedError, setattr, toi, 'attr', ['bar'])
        attr = toi.attr
        raises(ToiDeletedError, getattr, attr, 'value')

    def check_createOk(self, AttrClass):
        "Tests that attributes can be constructed and instantiated."

        class AttrDeriv(AttrClass()):
            pass

        AttrDeriv._instantiate('attr')

    def check_typeOk(self, attr, valueOk):
        "Tests that attribute instances accept a correct value."
        return attr.coerceValueList((valueOk,))

    def _badValue_reRaise(self, attr, badVal):
        """
        Feeds an incorrect value to the typechecking of an Attribute, extracts the
        underlaying type error and re-raises that error.
        """
        try:
            attr.coerceValueList((badVal,))
        except CapsAttributeError as e:
            realE = e.error.args[0][1]
            raise realE.__class__(realE)

    def check_type_notOk(self, attr, valueNotOk, error):
        "Tests that attribute type checks raises on incorrect values."
        raises(error, self._badValue_reRaise, attr, valueNotOk)

    def check_equals(self, AttrDeriv, value):
        class FakeToi(object):
            _deleted = False

            def __init__(self, **attrData):
                self._attrData = attrData

        attr1 = AttrDeriv._instantiate('attr1')
        attr2 = AttrDeriv._instantiate('attr2')
        attr3 = AttrDeriv._instantiate('attr3')

        toi = FakeToi(attr1=[value], attr2=[value], attr3=[value, value])
        attr1.toi = attr2.toi = attr3.toi = toi

        assert attr1 == attr2
        assert not (attr1 != attr2)
        assert attr1 != attr3
        assert not (attr1 == attr3)

    def test_Attribute_basics(self):
        "Yields tests that perform sanity tests on Attribute's."

        for AttrClass, (valueOk, valueNotOk, excType) in self.BASIC_VALUE_TESTS:
            yield self.check_createOk, AttrClass

            class AttrDeriv(AttrClass()):
                pass

            attr = AttrDeriv._instantiate('attr')
            attr2 = AttrDeriv._instantiate('attr2')

            yield self.check_typeOk, attr, valueOk
            yield self.check_equals, AttrDeriv, valueOk

            if valueNotOk:
                yield self.check_type_notOk, attr, valueNotOk, excType

    def test_SingleInheritance(self):
        "Test that an attribute only can inherit ONE base attribute type"

        def spam():
            class dummyAttr(Bool(), Bool()):
                pass

        raises(SyntaxError, spam)

    def test_Enum(self):
        "Tests the Enum attribute"

        class spam(Enum()):
            values = ('foo', 'bar')
            pass

    def helpValueError(self, classOb, val, err):

        class foo(object):
            ob = type.__call__(classOb(), 'bar')

        bar = foo()

        try:
            # if err is None:
            #     import pdb; pdb.set_trace()
            bar.ob.coerceValueList(val)
        except AttrValueError as l:
            
            return isinstance(l.args[3].args[0][1], err)

        assert not err
        return True

    def test_EnumTypechecking(self):
        "Tests the Enum attribute value typechecking"

        class spam(Enum()):
            values = ('foo', 'bar')

        y = type.__call__(spam, 'spam')

        assert self.helpValueError(spam, ('spam',), EnumValueError)
        assert self.helpValueError(spam, (y.foo,), None)

    def test_EnumIterator(self):
        "Tests the Enum iterator functionality"

        class spam(Enum()):
            values = ('foo', 'bar', 'moo', 'guu')

        y = type.__call__(spam, 'spam')

        rList = []
        for i in y:
            rList.append(i)

        assert rList == list(spam.values)

    def test_ToiRef(self):
        "Tests the ToiRef attribute"
        class FakeToc(TO):
            _deleted = False
            class spam(ToiRef()):
                pass

        toi = FakeToc(ObjectId())
        ref = FakeToc(ObjectId())
        toi.spam = [ref]
        assert toi.spam == [ref]

        id = ObjectId()
        self.context.requestAttribute = lambda toi, attr: {'spam': [id]}[attr.name]
        assert len(ref.spam) == 1
        assert ref.spam[0].id[0] == id

    def test_defaultEnum(self):
        "Tests the enum defaults"

        class spam(Enum()):
            values = ('foo', 'bar')
            default = 'bar'

        y = type.__call__(spam, 'spam')
        assert y.default[0] == y.bar

    def test_enumSubclassWithDefault(self):

        class spam(Enum()):
            values = ('foo', 'bar')

        class spam2(spam()):
            default = 'bar'

        y = type.__call__(spam2, 'spam')
        assert y.default[0] == y.bar

    def test_ToiRefTypechecking(self):
        "Tests the ToiRef attribute value typechecking"

        class spam(ToiRef()):
            pass

        assert self.helpValueError(spam, ('spam',), ToiRefValueError)
        assert self.helpValueError(spam, (object(),), ToiRefValueError)
        assert self.helpValueError(spam, (42,), ToiRefValueError)
        assert self.helpValueError(spam, (str(ObjectId()),), ToiRefValueError)
        assert self.helpValueError(spam, (ObjectId(),), ToiRefValueError)
        assert self.helpValueError(spam, (TO(),), None)

    def test_ToiRefMapTypechecking(self):
        "Tests the ToiRef attribute value typechecking"

        class spam(ToiRefMap()):
            pass

        assert self.helpValueError(spam, (('foo', 'spam'),), ToiRefValueError)
        assert self.helpValueError(spam, (('foo', object()),), ToiRefValueError)
        assert self.helpValueError(spam, (('foo', 42),), ToiRefValueError)
        assert self.helpValueError(spam, (('foo', str(ObjectId())),), ToiRefValueError)
        assert self.helpValueError(spam, (('foo', ObjectId()),), ToiRefValueError)
        assert self.helpValueError(spam, (('foo', TO()),), None)

    def test_Map_get(self):
        class FakeToc(TO):
            _deleted = False
            class spam(IntMap()):
                pass

        toi = FakeToc(ObjectId())
        self.context.requestAttribute = lambda toi, attr: {'spam': {'foo': 2}}[attr.name]

        assert toi.spam.get('foo') == 2
        assert toi.spam.get('bar', 3) == 3

    def test_Map_dictlike(self):
        class FakeToc(TO):
            _deleted = False
            class spam(IntMap()):
                pass

        toi = FakeToc(ObjectId())
        self.context.requestAttribute = lambda toi, attr: {'spam': {'foo': 2, 'bar': 3}}[attr.name]

        d = {'foo': 2, 'bar': 3}
        assert list(toi.spam.keys()) == list(d.keys())
        assert list(toi.spam.items()) == list(d.items())
        assert list(toi.spam.values()) == list(d.values())

    def test_Relation(self):
        "Tests the Relation attribute"

        class spam(Relation()):
            pass

    def test_validateValues(self):
        class FakeToc(TO):
            _deleted = False
            class spam(Int(Range(1, 10))):
                pass

        toi = FakeToc(ObjectId())
        raises(AttrValueError, toi.spam.validateValues, value=[27])

    def test_validateValues_MapAttr(self):
        class FakeToc(TO):
            _deleted = False
            class spam(IntMap(Range(1, 10))):
                pass

        toi = FakeToc(ObjectId())
        raises(AttrValueError, toi.spam.validateValues, value={'1': 27})
        toi.spam.validateValues(value={'1': 10})

    def test_empty(self):
        class FakeToc(TO):
            class int(Int()):
                default = [1]
            class intmap(IntMap()):
                default = {'foo': 1}

        assert FakeToc.int.empty == []
        assert FakeToc.intmap.empty == {}

    def test_on_computation(self):
        class FakeToc(TO):
            class int(Int()):
                def on_computation(attr, toi):
                    return [27]

        toi = FakeToc()
        assert toi.int == [27]

    def test_attribute_copying(self):
        class FakeToc(TO):
            class int(Int()):
                pass
            class indirect(Int()):
                def on_computation(attr, toi):
                    return toi.int

        toi1 = FakeToc()
        toi2 = FakeToc()

        toi1.int = [27]
        toi2.int = toi1.int

        assert toi1.int == toi2.int == [27]

        toi2.int = [0]
        # this tests that attribute unpacking in Attribute.__set__
        # unpacks all levels of attributes, not just the first
        toi2.int = toi1.indirect
        assert toi2.int == [27]

    def test_add(self):
        class FakeToc(TO):
            class int(Int()):
                pass
        toi = FakeToc()

        toi.int.add(1)
        assert toi.int == [1]

        toi.int.add(1)
        assert toi.int == [1]

        toi.int.add(2)
        assert toi.int == [1, 2]

    def test_discard(self):
        class FakeToc(TO):
            class int(Int()):
                pass
        toi = FakeToc()

        toi.int = [1, 2]
        toi.int.discard(2)
        assert toi.int == [1]

        toi.int.discard(3)
        assert toi.int == [1]
Esempio n. 29
0
 def foo():
     return ContextBroker().context
Esempio n. 30
0
 def test_startsEmpty(self):
     py.test.raises(LookupError, lambda: ContextBroker().context)