Пример #1
0
def test_conflict(db):
    db.write_sync(Document('test', 1, ('a', ), {'hello': 'world'}))
    db.write_sync(Document('test', 1, ('b', ), {'hello': 'there'}))
    assert list(db.read_sync('test', revs='all')) == [
        Document('test', 1, ('b', ), {'hello': 'there'}),
        Document('test', 1, ('a', ), {'hello': 'world'}),
    ]
Пример #2
0
async def main():
    server_db = InMemoryDatabase()
    jane_db = InMemoryDatabase()
    bob_db = InMemoryDatabase()

    await server_db.write(Document('roadside', 1, ('1a9c',), {'trees_count': 40}))
    await replicate(source=server_db, target=jane_db)
    await replicate(source=server_db, target=bob_db)

    await bob_db.write(Document('roadside', 2, ('e3b0', '1a9c'), {'trees_count': 41}))
    await jane_db.write(Document('roadside', 2, ('6e05', '1a9c'), {'trees_count': 41}))
    await replicate(source=jane_db, target=server_db)
    await replicate(source=bob_db, target=server_db)

    async for doc in server_db.read('roadside', revs='all'):
        print(doc)

    await server_db.write(Document('roadside', 3, ('b617', '6e05', '1a9c'),
                                   is_deleted=True))
    await server_db.write(Document('roadside', 3, ('5bd6', 'e3b0', '1a9c'),
                                   {'trees_count': 42}))

    await replicate(source=server_db, target=jane_db)
    await replicate(source=server_db, target=bob_db)

    print(await anext(jane_db.read('roadside')))
    print(await anext(bob_db.read('roadside')))
Пример #3
0
async def test_view():
    db = InMemoryDatabase()
    view = View(db, map_title, reduce, rereduce)

    doc1 = Document('test', 1, ('a', ), {'title': 'mytest'})
    doc2 = Document('test2', 1, ('b', ), {'title': 'Hello World'})
    await db.write(doc1)
    await db.write(doc2)
    assert await to_list(view.query()) == [
        QueryResult(key='Hello World', value=None, id='test2', document=None),
        QueryResult(key='mytest', value=None, id='test', document=None)
    ]
    assert await to_list(view.query(start_key='m', end_key='n')) == [
        QueryResult(key='mytest', value=None, id='test', document=None)
    ]
    doc3 = Document('test2', 2, ('c', 'b'), {'title': 'Hello World!'})
    await db.write(doc3)
    assert await to_list(view.query()) == [
        QueryResult(key='Hello World!', value=None, id='test2', document=None),
        QueryResult(key='mytest', value=None, id='test', document=None)
    ]
    # with document
    assert await to_list(view.query(doc_opts={})) == [
        QueryResult(key='Hello World!', value=None, id='test2', document=doc3),
        QueryResult(key='mytest', value=None, id='test', document=doc1),
    ]
    assert await to_list(view.aggregate()) == [(None, 2)]

    # maybe a list example would be better
    group_result = [('He', 1), ('my', 1)]
    assert await to_list(view.aggregate(group_level=2)) == group_result

    assert await to_list(view.aggregate(start_key='z')) == [(None, 0)]
Пример #4
0
def test_linear_history(db):
    doc = insert_doc(db)
    docs = [
        Document('test', 2, ('b', 'a'), {'hello': '1'}),
        Document('test', 3, ('c', 'b', 'a'), {'hello': '2'}),
        # skip one
        Document('test', 5, ('e', 'd', 'c', 'b', 'a'), {'hello': '4'})
    ]
    for doc in docs:
        db.write_sync(doc)
    assert list(db.read_sync('test', revs='all')) == [
        Document('test', 5, ('e', 'd', 'c', 'b', 'a'), {'hello': '4'})
    ]
Пример #5
0
async def test_replicate_continuous():
    source = InMemoryDatabase()
    await source.write(Document('test', 1, ('a', ), {}))
    target = InMemoryDatabase()
    async with anyio.create_task_group() as tg:
        create_target, continuous = False, True
        tg.start_soon(replicate, source, target, create_target, continuous)
        # verify the 'normal' replication is done (everything in the db has
        # been replicated succesfully)
        await document_existance(target, Document('test', 1, ('a', ), {}))
        # now write another document to check 'continuous=True'
        await source.write(Document('test2', 1, ('b', ), {}))
        await document_existance(target, Document('test2', 1, ('b', ), {}))
        # clean up
        tg.cancel_scope.cancel()
Пример #6
0
def test_attachment(db):
    doc = Document('test', 1, ('a', ), {'test': 1})
    doc.add_attachment('text.txt', [b'Hello World!'])
    db.write_sync(doc)

    new_doc = next(db.read_sync('test'))
    assert new_doc.id == 'test'
    assert new_doc.rev_num == 1
    assert new_doc.path == ('a', )
    assert new_doc.body == {'test': 1}

    meta1 = AttachmentMetadata(1, 'text/plain', 12,
                               'md5-7Qdih1MuhjZehB6Sv8UNjA==')
    assert new_doc.attachments == {'text.txt': AttachmentStub(meta1)}

    new_doc.rev_num = 2
    new_doc.path = ('b', 'a')
    new_doc.add_attachment('test.json', [b'{}'], 'application/json+special')
    db.write_sync(new_doc)

    read_doc = next(db.read_sync('test'))
    meta2 = AttachmentMetadata(2, 'application/json+special', 2,
                               'md5-mZFLkyvTelC5g8XnyQrpOw==')
    assert read_doc.attachments == {
        'text.txt': AttachmentStub(meta1),
        'test.json': AttachmentStub(meta2),
    }
    assert all(a.is_stub for a in read_doc.attachments.values())

    # retrieve text.txt by name
    selection = AttachmentSelector(names=['text.txt'])
    with db.read_with_attachments_sync('test', atts=selection) as resp:
        read_doc2 = next(resp)
        assert b''.join(read_doc2.attachments['text.txt']) == b'Hello World!'

    # retrieve test.json because it's newer
    atts = AttachmentSelector(since_revs=[(1, 'a')])
    with db.read_with_attachments_sync('test', revs='all', atts=atts) as resp:
        read_doc3 = next(resp)
        assert b''.join(read_doc3.attachments['test.json']) == b'{}'
        assert read_doc3.attachments['text.txt'].is_stub

    # retrieve both
    all_atts = AttachmentSelector.all()
    with db.read_with_attachments_sync('test', atts=all_atts) as resp:
        read_doc4 = next(resp)
        assert not any(a.is_stub for a in read_doc4.attachments.values())
        assert b''.join(read_doc3.attachments['test.json']) == b'{}'
Пример #7
0
def test_remove(db):
    insert_doc(db)
    doc2 = Document('test', 2, ('b', 'a'), is_deleted=True)
    db.write_sync(doc2)
    assert list(db.read_sync('test')) == [doc2]
    assert list(db.changes_sync()) == [
        Change('test', seq=2, deleted=True, leaf_revs=[(2, 'b')])
    ]
Пример #8
0
async def new_url(request):
    url = (await request.json())['url']
    assert urlparse(url).scheme == 'https'  # be overly strict

    id = nanoid.generate()
    # auto generate rev + path (DREAMCODE!)
    doc = Document(id=id,
                   rev_num=1,
                   path=(uuid.uuid1().hex, ),
                   body={'url': url})
    await request.app.state.db.write(doc)
    return JSONResponse({
        'shortened_url': request.url_for('redirect', id=id),
        'preview_url': request.url_for('preview', id=id)
    })
Пример #9
0
def test_attachment_errors(db):
    doc = Document('test',
                   1, ('a', ), {},
                   attachments={
                       'mytest':
                       AttachmentStub(
                           AttachmentMetadata(1, 'ct', 0, 'no hash...')),
                   })
    with pytest.raises(PreconditionFailed):  # cannot be a stub
        db.write_sync(doc)
    # retry
    doc.add_attachment('mytest', [b''])
    db.write_sync(doc)
    doc.rev_num = 2
    doc.path = ('b', 'a')
    doc.attachments = {
        # note that the rev_pos (2) is wrong!
        'mytest': AttachmentStub(AttachmentMetadata(2, 'ct', 0, 'no hash')),
    }
    # ... which causes a crash
    with pytest.raises(PreconditionFailed):
        db.write_sync(doc)
Пример #10
0
def test_document():
    doc = Document('test', 1, ('a', ), body={'x': 123})
    assert not doc.is_deleted
    assert doc['x'] == 123
Пример #11
0
def test_overwrite(db):
    insert_doc(db)
    db.write_sync(Document('test', 2, ('a', ), {'hello everyone'}))
    assert list(db.read_sync('test')) == [
        Document('test', 2, ('a', ), {'hello everyone'})
    ]
Пример #12
0
async def test_async(async_db):
    assert await async_db.update_seq == 0
    # query some unexisting rev
    assert await to_list(
        async_db.revs_diff(async_iter([('unexisting', [(1, 'x'), (2, 'y')])]))
    ) == [
        Missing('unexisting', {(1, 'x'), (2, 'y')}, set()),
    ]
    soon_overwritten = Document('mytest', 1, ('x', ), {'Hello': 'World!'})
    soon_overwritten.add_attachment('test.csv', async_iter([b'1,2,3']))
    await async_db.write(soon_overwritten)
    assert len(await to_list(async_db.all_docs())) == 1
    await async_db.write(Document('mytest', 2, (
        'y',
        'x',
    ), is_deleted=True))
    with pytest.raises(AttributeError):
        await async_db.write({})
    req = [
        # three different ways...
        ('mytest', {
            'revs': 'all'
        }),
        ('mytest', {}),
        ('mytest', {
            'revs': [(2, 'y')]
        }),
    ]
    for id, opts in req:
        assert await to_list(async_db.read(id, **opts)) == [
            Document('mytest', 2, ('y', 'x'), is_deleted=True),
        ]
    assert await to_list(async_db.all_docs()) == []
    assert await to_list(async_db.changes()) == [
        Change('mytest', seq=2, deleted=True, leaf_revs=[(2, 'y')])
    ]
    # try never-existing doc
    with pytest.raises(NotFound):
        await to_list(async_db.read('abc'))

    assert 'memory' in await async_db.id

    assert await async_db.revs_limit == 1000
    await async_db.set_revs_limit(500)
    assert await async_db.revs_limit == 500

    # some more attachment testing
    new_doc = Document('csv', 1, ('a', ), {})
    new_doc.add_attachment('test.csv', async_iter([b'4,', b'5,', b'6']))
    await async_db.write(new_doc)
    all_atts = AttachmentSelector.all()
    async with async_db.read_with_attachments('csv', atts=all_atts) as resp:
        loaded_doc = await anext(resp)
        att = loaded_doc.attachments['test.csv']
        assert await to_list(att) == [b'4,', b'5,', b'6']
        assert await to_list(att[0:5]) == [b'4,', b'5,', b'6']
        assert await to_list(att[1:4]) == [b',', b'5,']
        assert await to_list(att[2:3]) == [b'5']
        assert await to_list(att[3:3]) == [b'']
    stub_doc = await anext(async_db.read('csv'))
    assert stub_doc.attachments['test.csv'].is_stub
    # make sure re-inserting stub revision succeeds
    stub_doc.rev_num += 1
    stub_doc.path = ('b', ) + stub_doc.path
    await async_db.write(stub_doc)
Пример #13
0
async def test_collate(async_db):
    docs = [
        Document(complex_key(None), 1, ('a', ), {}),
        Document(complex_key(False), 1, ('b', ), {}),
        Document(complex_key(True), 1, ('c', ), {}),
        Document(complex_key(-5), 1, ('d', ), {}),
        Document(complex_key(0.5), 1, ('e', ), {}),
        Document(complex_key('Test'), 1, ('f', ), {}),
        Document(complex_key('abc'), 1, ('g', ), {}),
        Document(complex_key(()), 1, ('h', ), {}),
        Document(complex_key((None, 456)), 1, ('i', ), {}),
        Document(complex_key((None, '123')), 1, ('j', ), {}),
        Document(complex_key((True, None)), 1, ('k', ), {}),
        Document(complex_key({}), 1, ('l', ), {}),
        Document(complex_key({
            'hello': 'World!',
            'more': ''
        }), 1, ('m', ), {}),
        Document(complex_key({'hello': 'ZZZ'}), 1, ('n', ), {}),
    ]
    random.shuffle(docs)  # make things interesting

    async with async_db.write_transaction() as t:
        for doc in docs:
            t.write(doc)
    all_revs_in_order = [doc.path[0] async for doc in async_db.all_docs()]
    assert all_revs_in_order == list('abcdefghijklmn')
Пример #14
0
def insert_doc(db):
    doc = Document('test', 1, ('a', ), {'hello': 'world'})
    db.write_sync(doc)
    return doc
Пример #15
0
def test_old_conflict(db):
    docs = [
        Document('test', 1, ('a', ), {'x': 1}),
        Document('test', 2, ('b', 'a'), {'x': 2}),
        Document('test', 3, ('c', 'b', 'a'), {'x': 3}),
        # the interesting one (the old conflict):
        Document('test', 2, ('d', 'a'), {'x': 4}),
    ]
    for doc in docs:
        db.write_sync(doc)
    # make sure both leafs are in there
    assert list(db.read_sync('test', revs='all')) == [
        Document('test', 3, ('c', 'b', 'a'), {'x': 3}),
        Document('test', 2, ('d', 'a'), {'x': 4}),
    ]

    # make sure the older leaf is retrievable
    assert list(db.read_sync('test', revs=[(2, 'd')])) == [
        Document('test', 2, ('d', 'a'), {'x': 4}),
    ]

    # remove current winner
    db.write_sync(Document('test', 4, ('e', 'c', 'b', 'a'), is_deleted=True))

    # check the winner is the 'old' leaf now.
    assert list(db.read_sync('test')) == [
        Document('test', 2, ('d', 'a'), {'x': 4}),
    ]

    # remove the remaining non-deleted leaf as well
    db.write_sync(Document('test', 3, ('f', 'd', 'a'), is_deleted=True))

    # check if the current winner is deleted - and has switched back again
    assert list(db.read_sync('test')) == [
        Document('test', 4, ('e', 'c', 'b', 'a'), is_deleted=True),
    ]