예제 #1
0
def test_cursor_write_query(db, col, docs):
    cursor = db.aql.execute(
        '''
        FOR d IN {col} FILTER d._key == @first OR d._key == @second
        UPDATE {{_key: d._key, _val: @val }} IN {col}
        RETURN NEW
        '''.format(col=col.name),
        bind_vars={'first': '1', 'second': '2', 'val': 42},
        count=True,
        batch_size=1,
        ttl=1000,
        optimizer_rules=['+all'],
        profile=True
    )
    cursor_id = cursor.id
    assert 'Cursor' in repr(cursor)
    assert cursor.has_more() is True
    assert cursor.cached() is False
    assert cursor.warnings() == []
    assert cursor.count() == len(cursor) == 2
    assert clean_doc(cursor.batch()) == [docs[0]]

    statistics = cursor.statistics()
    assert statistics['modified'] == 2
    assert statistics['filtered'] == 0
    assert statistics['ignored'] == 0
    assert statistics['scanned_full'] == 0
    assert statistics['scanned_index'] == 2
    assert statistics['execution_time'] > 0
    assert statistics['http_requests'] == 0
    assert cursor.warnings() == []

    profile = cursor.profile()
    assert profile['initializing'] > 0
    assert profile['parsing'] > 0

    assert clean_doc(cursor.next()) == docs[0]
    assert cursor.id == cursor_id
    assert cursor.has_more() is True
    assert cursor.cached() is False
    assert cursor.statistics() == statistics
    assert cursor.profile() == profile
    assert cursor.warnings() == []
    assert cursor.count() == len(cursor) == 2
    assert clean_doc(cursor.batch()) == []

    assert clean_doc(cursor.next()) == docs[1]
    assert cursor.id == cursor_id
    assert cursor.has_more() is False
    assert cursor.cached() is False
    assert cursor.statistics() == statistics
    assert cursor.profile() == profile
    assert cursor.warnings() == []
    assert cursor.count() == len(cursor) == 2
    assert clean_doc(cursor.batch()) == []

    with pytest.raises(CursorCloseError) as err:
        cursor.close(ignore_missing=False)
    assert err.value.error_code == 1600
    assert cursor.close(ignore_missing=True) is False
예제 #2
0
def test_cursor_write_query(db, col, docs):
    cursor = db.aql.execute(
        '''
        FOR d IN {col} FILTER d._key == @first OR d._key == @second
        UPDATE {{_key: d._key, _val: @val }} IN {col}
        RETURN NEW
        '''.format(col=col.name),
        bind_vars={'first': '1', 'second': '2', 'val': 42},
        count=True,
        batch_size=1,
        ttl=1000,
        optimizer_rules=['+all'],
        profile=True
    )
    cursor_id = cursor.id
    assert 'Cursor' in repr(cursor)
    assert cursor.has_more() is True
    assert cursor.cached() is False
    assert cursor.warnings() == []
    assert cursor.count() == len(cursor) == 2
    assert clean_doc(cursor.batch()) == [docs[0]]

    statistics = cursor.statistics()
    assert statistics['modified'] == 2
    assert statistics['filtered'] == 0
    assert statistics['ignored'] == 0
    assert statistics['scanned_full'] == 0
    assert statistics['scanned_index'] == 2
    assert statistics['execution_time'] > 0
    assert statistics['http_requests'] == 0
    assert cursor.warnings() == []

    profile = cursor.profile()
    assert profile['initializing'] > 0
    assert profile['parsing'] > 0

    assert clean_doc(cursor.next()) == docs[0]
    assert cursor.id == cursor_id
    assert cursor.has_more() is True
    assert cursor.cached() is False
    assert cursor.statistics() == statistics
    assert cursor.profile() == profile
    assert cursor.warnings() == []
    assert cursor.count() == len(cursor) == 2
    assert clean_doc(cursor.batch()) == []

    assert clean_doc(cursor.next()) == docs[1]
    assert cursor.id == cursor_id
    assert cursor.has_more() is False
    assert cursor.cached() is False
    assert cursor.statistics() == statistics
    assert cursor.profile() == profile
    assert cursor.warnings() == []
    assert cursor.count() == len(cursor) == 2
    assert clean_doc(cursor.batch()) == []

    with pytest.raises(CursorCloseError) as err:
        cursor.close(ignore_missing=False)
    assert err.value.error_code == 1600
    assert cursor.close(ignore_missing=True) is False
예제 #3
0
def test_batch_double_commit(db, col, docs):
    batch_db = db.begin_batch_execution()
    job = batch_db.collection(col.name).insert(docs[0])

    # Test first commit
    assert batch_db.commit() == [job]
    assert job.status() == 'done'
    assert len(col) == 1
    assert clean_doc(col.random()) == docs[0]

    # Test second commit which should fail
    with pytest.raises(BatchStateError) as err:
        batch_db.commit()
    assert 'already committed' in str(err.value)
    assert len(col) == 1
    assert clean_doc(col.random()) == docs[0]
예제 #4
0
def test_batch_double_commit(db, col, docs):
    batch_db = db.begin_batch_execution()
    job = batch_db.collection(col.name).insert(docs[0])

    # Test first commit
    assert batch_db.commit() == [job]
    assert job.status() == 'done'
    assert len(col) == 1
    assert clean_doc(col.random()) == docs[0]

    # Test second commit which should fail
    with pytest.raises(BatchStateError) as err:
        batch_db.commit()
    assert 'already committed' in str(err.value)
    assert len(col) == 1
    assert clean_doc(col.random()) == docs[0]
예제 #5
0
def test_cursor_context_manager(db, col, docs):
    with db.aql.execute('FOR d IN {} SORT d._key RETURN d'.format(col.name),
                        count=True,
                        batch_size=2,
                        ttl=1000,
                        optimizer_rules=['+all'],
                        profile=True) as cursor:
        assert clean_doc(cursor.next()) == docs[0]

    with pytest.raises(CursorCloseError) as err:
        cursor.close(ignore_missing=False)
    assert err.value.error_code == 1600
    assert cursor.close(ignore_missing=True) is False
예제 #6
0
def test_cursor_context_manager(db, col, docs):
    with db.aql.execute(
            'FOR d IN {} SORT d._key RETURN d'.format(col.name),
            count=True,
            batch_size=2,
            ttl=1000,
            optimizer_rules=['+all'],
            profile=True
    ) as cursor:
        assert clean_doc(cursor.next()) == docs[0]

    with pytest.raises(CursorCloseError) as err:
        cursor.close(ignore_missing=False)
    assert err.value.error_code == 1600
    assert cursor.close(ignore_missing=True) is False
예제 #7
0
def test_cursor_premature_close(db, col, docs):
    cursor = db.c8ql.execute(
        'FOR d IN {} SORT d._key RETURN d'.format(col.name),
        count=True,
        batch_size=2,
        ttl=1000,
        optimizer_rules=['+all'],
        profile=True
    )
    assert clean_doc(cursor.batch()) == docs[:2]
    assert cursor.close() is True
    with pytest.raises(CursorCloseError) as err:
        cursor.close(ignore_missing=False)
    assert err.value.error_code == 1600
    assert cursor.close(ignore_missing=True) is False
예제 #8
0
def test_edge_management(ecol, bad_ecol, edocs, fvcol, fvdocs, tvcol, tvdocs):
    for vertex in fvdocs:
        fvcol.insert(vertex)
    for vertex in tvdocs:
        tvcol.insert(vertex)

    edge = edocs[0]
    key = edge['_key']

    # Test insert edge with no key
    result = ecol.insert({'_from': edge['_from'], '_to': edge['_to']})
    assert result['_key'] in ecol
    assert len(ecol) == 1
    ecol.truncate()

    # Test insert vertex with ID
    edge_id = ecol.name + '/' + 'foo'
    ecol.insert({
        '_id': edge_id,
        '_from': edge['_from'],
        '_to': edge['_to']
    })
    assert 'foo' in ecol
    assert edge_id in ecol
    assert len(ecol) == 1
    ecol.truncate()

    with assert_raises(DocumentParseError) as err:
        ecol.insert({
            '_id': generate_col_name() + '/' + 'foo',
            '_from': edge['_from'],
            '_to': edge['_to']
        })
    assert 'bad collection name' in err.value.message

    # Test insert first valid edge
    result = ecol.insert(edge)
    assert result['_key'] == key
    assert '_rev' in result
    assert edge in ecol and key in ecol
    assert len(ecol) == 1
    assert ecol[key]['_from'] == edge['_from']
    assert ecol[key]['_to'] == edge['_to']

    # Test insert duplicate edge
    with assert_raises(DocumentInsertError) as err:
        assert ecol.insert(edge)
    assert err.value.error_code in {1906, 1210}
    assert len(ecol) == 1

    edge = edocs[1]
    key = edge['_key']

    # Test insert second valid edge with silent set to True
    assert ecol.insert(edge, sync=True, silent=True) is True
    assert edge in ecol and key in ecol
    assert len(ecol) == 2
    assert ecol[key]['_from'] == edge['_from']
    assert ecol[key]['_to'] == edge['_to']

    # Test insert third valid edge using link method
    from_vertex = fvcol.get(fvdocs[2])
    to_vertex = tvcol.get(tvdocs[2])
    result = ecol.link(from_vertex, to_vertex, sync=False)
    assert result['_key'] in ecol
    assert len(ecol) == 3

    # Test insert fourth valid edge using link method
    from_vertex = fvcol.get(fvdocs[2])
    to_vertex = tvcol.get(tvdocs[0])
    assert ecol.link(
        from_vertex['_id'],
        to_vertex['_id'],
        {'_id': ecol.name + '/foo'},
        sync=True,
        silent=True
    ) is True
    assert 'foo' in ecol
    assert len(ecol) == 4

    with assert_raises(DocumentParseError) as err:
        assert ecol.link({}, {})
    assert err.value.message == 'field "_id" required'

    # Test get missing vertex
    bad_document_key = generate_doc_key()
    if ecol.context != 'transaction':
        assert ecol.get(bad_document_key) is None

    # Test get existing edge by body with "_key" field
    result = ecol.get({'_key': key})
    assert clean_doc(result) == edge

    # Test get existing edge by body with "_id" field
    result = ecol.get({'_id': ecol.name + '/' + key})
    assert clean_doc(result) == edge

    # Test get existing edge by key
    result = ecol.get(key)
    assert clean_doc(result) == edge

    # Test get existing edge by ID
    result = ecol.get(ecol.name + '/' + key)
    assert clean_doc(result) == edge

    # Test get existing edge with bad revision
    old_rev = result['_rev']
    with assert_raises(DocumentRevisionError) as err:
        ecol.get(key, rev=old_rev + '1')
    assert err.value.error_code in {1903, 1200}

    # Test get existing edge with bad fabric
    with assert_raises(DocumentGetError) as err:
        bad_ecol.get(key)
    assert err.value.error_code == 1228

    # Test update edge with a single field change
    assert 'foo' not in ecol.get(key)
    result = ecol.update({'_key': key, 'foo': 100})
    assert result['_key'] == key
    assert ecol[key]['foo'] == 100
    old_rev = ecol[key]['_rev']

    # Test update edge with multiple field changes
    result = ecol.update({'_key': key, 'foo': 200, 'bar': 300})
    assert result['_key'] == key
    assert result['_old_rev'] == old_rev
    assert ecol[key]['foo'] == 200
    assert ecol[key]['bar'] == 300
    old_rev = result['_rev']

    # Test update edge with correct revision
    result = ecol.update({'_key': key, '_rev': old_rev, 'bar': 400})
    assert result['_key'] == key
    assert result['_old_rev'] == old_rev
    assert ecol[key]['foo'] == 200
    assert ecol[key]['bar'] == 400
    old_rev = result['_rev']

    if ecol.context != 'transaction':
        # Test update edge with bad revision
        new_rev = old_rev + '1'
        with assert_raises(DocumentRevisionError):
            ecol.update({'_key': key, '_rev': new_rev, 'bar': 500})
        assert ecol[key]['foo'] == 200
        assert ecol[key]['bar'] == 400

    # Test update edge in missing edge collection
    with assert_raises(DocumentUpdateError) as err:
        bad_ecol.update({'_key': key, 'bar': 500})
    assert err.value.error_code == 1228
    assert ecol[key]['foo'] == 200
    assert ecol[key]['bar'] == 400

    # Test update edge with sync option
    result = ecol.update({'_key': key, 'bar': 500}, sync=True)
    assert result['_key'] == key
    assert result['_old_rev'] == old_rev
    assert ecol[key]['foo'] == 200
    assert ecol[key]['bar'] == 500
    old_rev = result['_rev']

    # Test update edge with silent option
    assert ecol.update({'_key': key, 'bar': 600}, silent=True) is True
    assert ecol[key]['foo'] == 200
    assert ecol[key]['bar'] == 600
    assert ecol[key]['_rev'] != old_rev
    old_rev = ecol[key]['_rev']

    # Test update edge without keep_none option
    result = ecol.update({'_key': key, 'bar': None}, keep_none=True)
    assert result['_key'] == key
    assert result['_old_rev'] == old_rev
    assert ecol[key]['foo'] == 200
    assert ecol[key]['bar'] is None
    old_rev = result['_rev']

    # Test update edge with keep_none option
    result = ecol.update({'_key': key, 'foo': None}, keep_none=False)
    assert result['_key'] == key
    assert result['_old_rev'] == old_rev
    assert 'foo' not in ecol[key]
    assert ecol[key]['bar'] is None

    # Test replace edge with a single field change
    edge['foo'] = 100
    result = ecol.replace(edge)
    assert result['_key'] == key
    assert ecol[key]['foo'] == 100
    old_rev = ecol[key]['_rev']

    # Test replace edge with silent set to True
    edge['bar'] = 200
    assert ecol.replace(edge, silent=True) is True
    assert ecol[key]['foo'] == 100
    assert ecol[key]['bar'] == 200
    assert ecol[key]['_rev'] != old_rev
    old_rev = ecol[key]['_rev']

    # Test replace edge with multiple field changes
    edge['foo'] = 200
    edge['bar'] = 300
    result = ecol.replace(edge)
    assert result['_key'] == key
    assert result['_old_rev'] == old_rev
    assert ecol[key]['foo'] == 200
    assert ecol[key]['bar'] == 300
    old_rev = result['_rev']

    # Test replace edge with correct revision
    edge['foo'] = 300
    edge['bar'] = 400
    edge['_rev'] = old_rev
    result = ecol.replace(edge)
    assert result['_key'] == key
    assert result['_old_rev'] == old_rev
    assert ecol[key]['foo'] == 300
    assert ecol[key]['bar'] == 400
    old_rev = result['_rev']

    edge['bar'] = 500
    if ecol.context != 'transaction':
        # Test replace edge with bad revision
        edge['_rev'] = old_rev + key
        with assert_raises(DocumentRevisionError) as err:
            ecol.replace(edge)
        assert err.value.error_code == 1903
        assert ecol[key]['foo'] == 300
        assert ecol[key]['bar'] == 400

    # Test replace edge with bad fabric
    with assert_raises(DocumentReplaceError) as err:
        bad_ecol.replace(edge)
    assert err.value.error_code == 1228
    assert ecol[key]['foo'] == 300
    assert ecol[key]['bar'] == 400

    # Test replace edge with sync option
    result = ecol.replace(edge, sync=True, check_rev=False)
    assert result['_key'] == key
    assert result['_old_rev'] == old_rev
    assert ecol[key]['foo'] == 300
    assert ecol[key]['bar'] == 500

    # Test delete edge with bad revision
    if ecol.context != 'transaction':
        old_rev = ecol[key]['_rev']
        edge['_rev'] = old_rev + '1'
        with assert_raises(DocumentRevisionError) as err:
            ecol.delete(edge, check_rev=True)
        assert err.value.error_code == 1903
        edge['_rev'] = old_rev
        assert edge in ecol

    # Test delete missing edge
    with assert_raises(DocumentDeleteError) as err:
        ecol.delete(bad_document_key, ignore_missing=False)
    assert err.value.error_code == 1202
    if ecol.context != 'transaction':
        assert not ecol.delete(bad_document_key, ignore_missing=True)

    # Test delete existing edge with sync set to True
    assert ecol.delete(edge, sync=True, check_rev=False) is True
    if ecol.context != 'transaction':
        assert ecol[edge] is None
    assert edge not in ecol
    ecol.truncate()
예제 #9
0
def test_vertex_management(fvcol, bad_fvcol, fvdocs):
    # Test insert vertex with no key
    result = fvcol.insert({})
    assert result['_key'] in fvcol
    assert len(fvcol) == 1
    fvcol.truncate()

    # Test insert vertex with ID
    vertex_id = fvcol.name + '/' + 'foo'
    fvcol.insert({'_id': vertex_id})
    assert 'foo' in fvcol
    assert vertex_id in fvcol
    assert len(fvcol) == 1
    fvcol.truncate()

    with assert_raises(DocumentParseError) as err:
        fvcol.insert({'_id': generate_col_name() + '/' + 'foo'})
    assert 'bad collection name' in err.value.message

    vertex = fvdocs[0]
    key = vertex['_key']

    # Test insert first valid vertex
    result = fvcol.insert(vertex)
    assert result['_key'] == key
    assert '_rev' in result
    assert vertex in fvcol and key in fvcol
    assert len(fvcol) == 1
    assert fvcol[key]['val'] == vertex['val']

    # Test insert duplicate vertex
    with assert_raises(DocumentInsertError) as err:
        fvcol.insert(vertex)
    assert err.value.error_code == 1210
    assert len(fvcol) == 1

    vertex = fvdocs[1]
    key = vertex['_key']

    # Test insert second valid vertex
    result = fvcol.insert(vertex, sync=True)
    assert result['_key'] == key
    assert vertex in fvcol and key in fvcol
    assert len(fvcol) == 2
    assert fvcol[key]['val'] == vertex['val']

    vertex = fvdocs[2]
    key = vertex['_key']

    # Test insert third valid vertex with silent set to True
    assert fvcol.insert(vertex, silent=True) is True
    assert len(fvcol) == 3
    assert fvcol[key]['val'] == vertex['val']

    # Test get missing vertex
    if fvcol.context != 'transaction':
        assert fvcol.get(generate_doc_key()) is None

    # Test get existing edge by body with "_key" field
    result = fvcol.get({'_key': key})
    assert clean_doc(result) == vertex

    # Test get existing edge by body with "_id" field
    result = fvcol.get({'_id': fvcol.name + '/' + key})
    assert clean_doc(result) == vertex

    # Test get existing vertex by key
    result = fvcol.get(key)
    assert clean_doc(result) == vertex

    # Test get existing vertex by ID
    result = fvcol.get(fvcol.name + '/' + key)
    assert clean_doc(result) == vertex

    # Test get existing vertex with bad revision
    old_rev = result['_rev']
    with assert_raises(DocumentRevisionError) as err:
        fvcol.get(key, rev=old_rev + '1', check_rev=True)
    assert err.value.error_code in {1903, 1200}

    # Test get existing vertex with bad fabric
    with assert_raises(DocumentGetError) as err:
        bad_fvcol.get(key)
    assert err.value.error_code == 1228

    # Test update vertex with a single field change
    assert 'foo' not in fvcol.get(key)
    result = fvcol.update({'_key': key, 'foo': 100})
    assert result['_key'] == key
    assert fvcol[key]['foo'] == 100
    old_rev = fvcol[key]['_rev']

    # Test update vertex with silent set to True
    assert 'bar' not in fvcol[vertex]
    assert fvcol.update({'_key': key, 'bar': 200}, silent=True) is True
    assert fvcol[vertex]['bar'] == 200
    assert fvcol[vertex]['_rev'] != old_rev
    old_rev = fvcol[key]['_rev']

    # Test update vertex with multiple field changes
    result = fvcol.update({'_key': key, 'foo': 200, 'bar': 300})
    assert result['_key'] == key
    assert result['_old_rev'] == old_rev
    assert fvcol[key]['foo'] == 200
    assert fvcol[key]['bar'] == 300
    old_rev = result['_rev']

    # Test update vertex with correct revision
    result = fvcol.update({'_key': key, '_rev': old_rev, 'bar': 400})
    assert result['_key'] == key
    assert result['_old_rev'] == old_rev
    assert fvcol[key]['foo'] == 200
    assert fvcol[key]['bar'] == 400
    old_rev = result['_rev']

    # Test update vertex with bad revision
    if fvcol.context != 'transaction':
        new_rev = old_rev + '1'
        with assert_raises(DocumentRevisionError) as err:
            fvcol.update({'_key': key, '_rev': new_rev, 'bar': 500})
        assert err.value.error_code == 1903
        assert fvcol[key]['foo'] == 200
        assert fvcol[key]['bar'] == 400

    # Test update vertex in missing vertex collection
    with assert_raises(DocumentUpdateError) as err:
        bad_fvcol.update({'_key': key, 'bar': 500})
    assert err.value.error_code == 1228
    assert fvcol[key]['foo'] == 200
    assert fvcol[key]['bar'] == 400

    # Test update vertex with sync set to True
    result = fvcol.update({'_key': key, 'bar': 500}, sync=True)
    assert result['_key'] == key
    assert result['_old_rev'] == old_rev
    assert fvcol[key]['foo'] == 200
    assert fvcol[key]['bar'] == 500
    old_rev = result['_rev']

    # Test update vertex with keep_none set to True
    result = fvcol.update({'_key': key, 'bar': None}, keep_none=True)
    assert result['_key'] == key
    assert result['_old_rev'] == old_rev
    assert fvcol[key]['foo'] == 200
    assert fvcol[key]['bar'] is None
    old_rev = result['_rev']

    # Test update vertex with keep_none set to False
    result = fvcol.update({'_key': key, 'foo': None}, keep_none=False)
    assert result['_key'] == key
    assert result['_old_rev'] == old_rev
    assert 'foo' not in fvcol[key]
    assert fvcol[key]['bar'] is None

    # Test replace vertex with a single field change
    result = fvcol.replace({'_key': key, 'baz': 100})
    assert result['_key'] == key
    assert 'foo' not in fvcol[key]
    assert 'bar' not in fvcol[key]
    assert fvcol[key]['baz'] == 100
    old_rev = result['_rev']

    # Test replace vertex with silent set to True
    assert fvcol.replace({'_key': key, 'bar': 200}, silent=True) is True
    assert 'foo' not in fvcol[key]
    assert 'baz' not in fvcol[vertex]
    assert fvcol[vertex]['bar'] == 200
    assert len(fvcol) == 3
    assert fvcol[vertex]['_rev'] != old_rev
    old_rev = fvcol[vertex]['_rev']

    # Test replace vertex with multiple field changes
    vertex = {'_key': key, 'foo': 200, 'bar': 300}
    result = fvcol.replace(vertex)
    assert result['_key'] == key
    assert result['_old_rev'] == old_rev
    assert clean_doc(fvcol[key]) == vertex
    old_rev = result['_rev']

    # Test replace vertex with correct revision
    vertex = {'_key': key, '_rev': old_rev, 'bar': 500}
    result = fvcol.replace(vertex)
    assert result['_key'] == key
    assert result['_old_rev'] == old_rev
    assert clean_doc(fvcol[key]) == clean_doc(vertex)
    old_rev = result['_rev']

    # Test replace vertex with bad revision
    if fvcol.context != 'transaction':
        new_rev = old_rev + '10'
        vertex = {'_key': key, '_rev': new_rev, 'bar': 600}
        with assert_raises(DocumentRevisionError) as err:
            fvcol.replace(vertex)
        assert err.value.error_code == 1903
        assert fvcol[key]['bar'] == 500
        assert 'foo' not in fvcol[key]

    # Test replace vertex with bad fabric
    with assert_raises(DocumentReplaceError) as err:
        bad_fvcol.replace({'_key': key, 'bar': 600})
    assert err.value.error_code == 1228
    assert fvcol[key]['bar'] == 500
    assert 'foo' not in fvcol[key]

    # Test replace vertex with sync set to True
    vertex = {'_key': key, 'bar': 400, 'foo': 200}
    result = fvcol.replace(vertex, sync=True)
    assert result['_key'] == key
    assert result['_old_rev'] == old_rev
    assert fvcol[key]['foo'] == 200
    assert fvcol[key]['bar'] == 400

    # Test delete vertex with bad revision
    if fvcol.context != 'transaction':
        old_rev = fvcol[key]['_rev']
        vertex['_rev'] = old_rev + '1'
        with assert_raises(DocumentRevisionError) as err:
            fvcol.delete(vertex, check_rev=True)
        assert err.value.error_code == 1903
        vertex['_rev'] = old_rev
        assert vertex in fvcol

    # Test delete missing vertex
    bad_key = generate_doc_key()
    with assert_raises(DocumentDeleteError) as err:
        fvcol.delete(bad_key, ignore_missing=False)
    assert err.value.error_code == 1202
    if fvcol.context != 'transaction':
        assert fvcol.delete(bad_key, ignore_missing=True) is False

    # Test delete existing vertex with sync set to True
    assert fvcol.delete(vertex, sync=True, check_rev=False) is True
    if fvcol.context != 'transaction':
        assert fvcol[vertex] is None
    assert vertex not in fvcol
    assert len(fvcol) == 2
    fvcol.truncate()
예제 #10
0
def test_cursor_from_execute_query(db, col, docs):
    cursor = db.aql.execute('FOR d IN {} SORT d._key RETURN d'.format(
        col.name),
                            count=True,
                            batch_size=2,
                            ttl=1000,
                            optimizer_rules=['+all'],
                            profile=True)
    cursor_id = cursor.id
    assert 'Cursor' in repr(cursor)
    assert cursor.type == 'cursor'
    assert cursor.has_more() is True
    assert cursor.cached() is False
    assert cursor.warnings() == []
    assert cursor.count() == len(cursor) == 6
    assert clean_doc(cursor.batch()) == docs[:2]

    statistics = cursor.statistics()
    assert statistics['modified'] == 0
    assert statistics['filtered'] == 0
    assert statistics['ignored'] == 0
    assert statistics['execution_time'] > 0
    assert 'http_requests' in statistics
    assert 'scanned_full' in statistics
    assert 'scanned_index' in statistics
    assert cursor.warnings() == []

    profile = cursor.profile()
    assert profile['initializing'] > 0
    assert profile['parsing'] > 0

    assert clean_doc(cursor.next()) == docs[0]
    assert cursor.id == cursor_id
    assert cursor.has_more() is True
    assert cursor.cached() is False
    assert cursor.statistics() == statistics
    assert cursor.profile() == profile
    assert cursor.warnings() == []
    assert cursor.count() == len(cursor) == 6
    assert clean_doc(cursor.batch()) == [docs[1]]

    assert clean_doc(cursor.next()) == docs[1]
    assert cursor.id == cursor_id
    assert cursor.has_more() is True
    assert cursor.cached() is False
    assert cursor.statistics() == statistics
    assert cursor.profile() == profile
    assert cursor.warnings() == []
    assert cursor.count() == len(cursor) == 6
    assert clean_doc(cursor.batch()) == []

    assert clean_doc(cursor.next()) == docs[2]
    assert cursor.id == cursor_id
    assert cursor.has_more() is True
    assert cursor.cached() is False
    assert cursor.statistics() == statistics
    assert cursor.profile() == profile
    assert cursor.warnings() == []
    assert cursor.count() == len(cursor) == 6
    assert clean_doc(cursor.batch()) == [docs[3]]

    assert clean_doc(cursor.next()) == docs[3]
    assert clean_doc(cursor.next()) == docs[4]
    assert clean_doc(cursor.next()) == docs[5]
    assert cursor.id == cursor_id
    assert cursor.has_more() is False
    assert cursor.statistics() == statistics
    assert cursor.profile() == profile
    assert cursor.warnings() == []
    assert cursor.count() == len(cursor) == 6
    assert clean_doc(cursor.batch()) == []
    with pytest.raises(StopIteration):
        cursor.next()
    assert cursor.close(ignore_missing=True) is False
예제 #11
0
def test_edge_management(ecol, bad_ecol, edocs, fvcol, fvdocs, tvcol, tvdocs):
    for vertex in fvdocs:
        fvcol.insert(vertex)
    for vertex in tvdocs:
        tvcol.insert(vertex)

    edge = edocs[0]
    key = edge['_key']

    # Test insert edge with no key
    result = ecol.insert({'_from': edge['_from'], '_to': edge['_to']})
    assert result['_key'] in ecol
    assert len(ecol) == 1
    ecol.truncate()

    # Test insert vertex with ID
    edge_id = ecol.name + '/' + 'foo'
    ecol.insert({
        '_id': edge_id,
        '_from': edge['_from'],
        '_to': edge['_to']
    })
    assert 'foo' in ecol
    assert edge_id in ecol
    assert len(ecol) == 1
    ecol.truncate()

    with assert_raises(DocumentParseError) as err:
        ecol.insert({
            '_id': generate_col_name() + '/' + 'foo',
            '_from': edge['_from'],
            '_to': edge['_to']
        })
    assert 'bad collection name' in err.value.message

    # Test insert first valid edge
    result = ecol.insert(edge)
    assert result['_key'] == key
    assert '_rev' in result
    assert edge in ecol and key in ecol
    assert len(ecol) == 1
    assert ecol[key]['_from'] == edge['_from']
    assert ecol[key]['_to'] == edge['_to']

    # Test insert duplicate edge
    with assert_raises(DocumentInsertError) as err:
        assert ecol.insert(edge)
    assert err.value.error_code in {1202, 1210, 1906}
    assert len(ecol) == 1

    edge = edocs[1]
    key = edge['_key']

    # Test insert second valid edge with silent set to True
    assert ecol.insert(edge, sync=True, silent=True) is True
    assert edge in ecol and key in ecol
    assert len(ecol) == 2
    assert ecol[key]['_from'] == edge['_from']
    assert ecol[key]['_to'] == edge['_to']

    # Test insert third valid edge using link method
    from_vertex = fvcol.get(fvdocs[2])
    to_vertex = tvcol.get(tvdocs[2])
    result = ecol.link(from_vertex, to_vertex, sync=False)
    assert result['_key'] in ecol
    assert len(ecol) == 3

    # Test insert fourth valid edge using link method
    from_vertex = fvcol.get(fvdocs[2])
    to_vertex = tvcol.get(tvdocs[0])
    assert ecol.link(
        from_vertex['_id'],
        to_vertex['_id'],
        {'_id': ecol.name + '/foo'},
        sync=True,
        silent=True
    ) is True
    assert 'foo' in ecol
    assert len(ecol) == 4

    with assert_raises(DocumentParseError) as err:
        assert ecol.link({}, {})
    assert err.value.message == 'field "_id" required'

    # Test get missing vertex
    bad_document_key = generate_doc_key()
    if ecol.context != 'transaction':
        assert ecol.get(bad_document_key) is None

    # Test get existing edge by body with "_key" field
    result = ecol.get({'_key': key})
    assert clean_doc(result) == edge

    # Test get existing edge by body with "_id" field
    result = ecol.get({'_id': ecol.name + '/' + key})
    assert clean_doc(result) == edge

    # Test get existing edge by key
    result = ecol.get(key)
    assert clean_doc(result) == edge

    # Test get existing edge by ID
    result = ecol.get(ecol.name + '/' + key)
    assert clean_doc(result) == edge

    # Test get existing edge with bad revision
    old_rev = result['_rev']
    with assert_raises(DocumentRevisionError) as err:
        ecol.get(key, rev=old_rev + '1')
    assert err.value.error_code in {1903, 1200}

    # Test get existing edge with bad database
    with assert_raises(DocumentGetError) as err:
        bad_ecol.get(key)
    assert err.value.error_code in {11, 1228}

    # Test update edge with a single field change
    assert 'foo' not in ecol.get(key)
    result = ecol.update({'_key': key, 'foo': 100})
    assert result['_key'] == key
    assert ecol[key]['foo'] == 100
    old_rev = ecol[key]['_rev']

    # Test update edge with multiple field changes
    result = ecol.update({'_key': key, 'foo': 200, 'bar': 300})
    assert result['_key'] == key
    assert result['_old_rev'] == old_rev
    assert ecol[key]['foo'] == 200
    assert ecol[key]['bar'] == 300
    old_rev = result['_rev']

    # Test update edge with correct revision
    result = ecol.update({'_key': key, '_rev': old_rev, 'bar': 400})
    assert result['_key'] == key
    assert result['_old_rev'] == old_rev
    assert ecol[key]['foo'] == 200
    assert ecol[key]['bar'] == 400
    old_rev = result['_rev']

    if ecol.context != 'transaction':
        # Test update edge with bad revision
        new_rev = old_rev + '1'
        with assert_raises(DocumentRevisionError, DocumentUpdateError):
            ecol.update({'_key': key, '_rev': new_rev, 'bar': 500})
        assert ecol[key]['foo'] == 200
        assert ecol[key]['bar'] == 400

    # Test update edge in missing edge collection
    with assert_raises(DocumentUpdateError) as err:
        bad_ecol.update({'_key': key, 'bar': 500})
    assert err.value.error_code in {11, 1228}
    assert ecol[key]['foo'] == 200
    assert ecol[key]['bar'] == 400

    # Test update edge with sync option
    result = ecol.update({'_key': key, 'bar': 500}, sync=True)
    assert result['_key'] == key
    assert result['_old_rev'] == old_rev
    assert ecol[key]['foo'] == 200
    assert ecol[key]['bar'] == 500
    old_rev = result['_rev']

    # Test update edge with silent option
    assert ecol.update({'_key': key, 'bar': 600}, silent=True) is True
    assert ecol[key]['foo'] == 200
    assert ecol[key]['bar'] == 600
    assert ecol[key]['_rev'] != old_rev
    old_rev = ecol[key]['_rev']

    # Test update edge without keep_none option
    result = ecol.update({'_key': key, 'bar': None}, keep_none=True)
    assert result['_key'] == key
    assert result['_old_rev'] == old_rev
    assert ecol[key]['foo'] == 200
    assert ecol[key]['bar'] is None
    old_rev = result['_rev']

    # Test update edge with keep_none option
    result = ecol.update({'_key': key, 'foo': None}, keep_none=False)
    assert result['_key'] == key
    assert result['_old_rev'] == old_rev
    assert 'foo' not in ecol[key]
    assert ecol[key]['bar'] is None

    # Test replace edge with a single field change
    edge['foo'] = 100
    result = ecol.replace(edge)
    assert result['_key'] == key
    assert ecol[key]['foo'] == 100
    old_rev = ecol[key]['_rev']

    # Test replace edge with silent set to True
    edge['bar'] = 200
    assert ecol.replace(edge, silent=True) is True
    assert ecol[key]['foo'] == 100
    assert ecol[key]['bar'] == 200
    assert ecol[key]['_rev'] != old_rev
    old_rev = ecol[key]['_rev']

    # Test replace edge with multiple field changes
    edge['foo'] = 200
    edge['bar'] = 300
    result = ecol.replace(edge)
    assert result['_key'] == key
    assert result['_old_rev'] == old_rev
    assert ecol[key]['foo'] == 200
    assert ecol[key]['bar'] == 300
    old_rev = result['_rev']

    # Test replace edge with correct revision
    edge['foo'] = 300
    edge['bar'] = 400
    edge['_rev'] = old_rev
    result = ecol.replace(edge)
    assert result['_key'] == key
    assert result['_old_rev'] == old_rev
    assert ecol[key]['foo'] == 300
    assert ecol[key]['bar'] == 400
    old_rev = result['_rev']

    edge['bar'] = 500
    if ecol.context != 'transaction':
        # Test replace edge with bad revision
        edge['_rev'] = old_rev + key
        with assert_raises(DocumentRevisionError, DocumentReplaceError) as err:
            ecol.replace(edge)
        assert err.value.error_code in {1200, 1903}
        assert ecol[key]['foo'] == 300
        assert ecol[key]['bar'] == 400

    # Test replace edge with bad database
    with assert_raises(DocumentReplaceError) as err:
        bad_ecol.replace(edge)
    assert err.value.error_code in {11, 1228}
    assert ecol[key]['foo'] == 300
    assert ecol[key]['bar'] == 400

    # Test replace edge with sync option
    result = ecol.replace(edge, sync=True, check_rev=False)
    assert result['_key'] == key
    assert result['_old_rev'] == old_rev
    assert ecol[key]['foo'] == 300
    assert ecol[key]['bar'] == 500

    # Test delete edge with bad revision
    if ecol.context != 'transaction':
        old_rev = ecol[key]['_rev']
        edge['_rev'] = old_rev + '1'
        with assert_raises(DocumentRevisionError, DocumentDeleteError) as err:
            ecol.delete(edge, check_rev=True)
        assert err.value.error_code in {1200, 1903}
        edge['_rev'] = old_rev
        assert edge in ecol

    # Test delete missing edge
    with assert_raises(DocumentDeleteError) as err:
        ecol.delete(bad_document_key, ignore_missing=False)
    assert err.value.error_code == 1202
    if ecol.context != 'transaction':
        assert not ecol.delete(bad_document_key, ignore_missing=True)

    # Test delete existing edge with sync set to True
    assert ecol.delete(edge, sync=True, check_rev=False) is True
    if ecol.context != 'transaction':
        assert ecol[edge] is None
    assert edge not in ecol
    ecol.truncate()
예제 #12
0
def test_vertex_management(fvcol, bad_fvcol, fvdocs):
    # Test insert vertex with no key
    result = fvcol.insert({})
    assert result['_key'] in fvcol
    assert len(fvcol) == 1
    fvcol.truncate()

    # Test insert vertex with ID
    vertex_id = fvcol.name + '/' + 'foo'
    fvcol.insert({'_id': vertex_id})
    assert 'foo' in fvcol
    assert vertex_id in fvcol
    assert len(fvcol) == 1
    fvcol.truncate()

    with assert_raises(DocumentParseError) as err:
        fvcol.insert({'_id': generate_col_name() + '/' + 'foo'})
    assert 'bad collection name' in err.value.message

    vertex = fvdocs[0]
    key = vertex['_key']

    # Test insert first valid vertex
    result = fvcol.insert(vertex, sync=True)
    assert result['_key'] == key
    assert '_rev' in result
    assert vertex in fvcol and key in fvcol
    assert len(fvcol) == 1
    assert fvcol[key]['val'] == vertex['val']

    # Test insert duplicate vertex
    with assert_raises(DocumentInsertError) as err:
        fvcol.insert(vertex)
    assert err.value.error_code in {1202, 1210}
    assert len(fvcol) == 1

    vertex = fvdocs[1]
    key = vertex['_key']

    # Test insert second valid vertex
    result = fvcol.insert(vertex)
    assert result['_key'] == key
    assert '_rev' in result
    assert vertex in fvcol and key in fvcol
    assert len(fvcol) == 2
    assert fvcol[key]['val'] == vertex['val']

    vertex = fvdocs[2]
    key = vertex['_key']

    # Test insert third valid vertex with silent set to True
    assert fvcol.insert(vertex, silent=True) is True
    assert len(fvcol) == 3
    assert fvcol[key]['val'] == vertex['val']

    # Test get missing vertex
    if fvcol.context != 'transaction':
        assert fvcol.get(generate_doc_key()) is None

    # Test get existing edge by body with "_key" field
    result = fvcol.get({'_key': key})
    assert clean_doc(result) == vertex

    # Test get existing edge by body with "_id" field
    result = fvcol.get({'_id': fvcol.name + '/' + key})
    assert clean_doc(result) == vertex

    # Test get existing vertex by key
    result = fvcol.get(key)
    assert clean_doc(result) == vertex

    # Test get existing vertex by ID
    result = fvcol.get(fvcol.name + '/' + key)
    assert clean_doc(result) == vertex

    # Test get existing vertex with bad revision
    old_rev = result['_rev']
    with assert_raises(DocumentRevisionError) as err:
        fvcol.get(key, rev=old_rev + '1', check_rev=True)
    assert err.value.error_code in {1903, 1200}

    # Test get existing vertex with bad database
    with assert_raises(DocumentGetError) as err:
        bad_fvcol.get(key)
    assert err.value.error_code in {11, 1228}

    # Test update vertex with a single field change
    assert 'foo' not in fvcol.get(key)
    result = fvcol.update({'_key': key, 'foo': 100})
    assert result['_key'] == key
    assert fvcol[key]['foo'] == 100
    old_rev = fvcol[key]['_rev']

    # Test update vertex with silent set to True
    assert 'bar' not in fvcol[vertex]
    assert fvcol.update({'_key': key, 'bar': 200}, silent=True) is True
    assert fvcol[vertex]['bar'] == 200
    assert fvcol[vertex]['_rev'] != old_rev
    old_rev = fvcol[key]['_rev']

    # Test update vertex with multiple field changes
    result = fvcol.update({'_key': key, 'foo': 200, 'bar': 300})
    assert result['_key'] == key
    assert result['_old_rev'] == old_rev
    assert fvcol[key]['foo'] == 200
    assert fvcol[key]['bar'] == 300
    old_rev = result['_rev']

    # Test update vertex with correct revision
    result = fvcol.update({'_key': key, '_rev': old_rev, 'bar': 400})
    assert result['_key'] == key
    assert result['_old_rev'] == old_rev
    assert fvcol[key]['foo'] == 200
    assert fvcol[key]['bar'] == 400
    old_rev = result['_rev']

    # # Test update vertex with bad revision
    # if fvcol.context != 'transaction':
    #     new_rev = old_rev + '1'
    #     with assert_raises(DocumentRevisionError) as err:
    #         fvcol.update({'_key': key, '_rev': new_rev, 'bar': 500})
    #     assert err.value.error_code == 1903
    #     assert fvcol[key]['foo'] == 200
    #     assert fvcol[key]['bar'] == 400

    # Test update vertex in missing vertex collection
    with assert_raises(DocumentUpdateError) as err:
        bad_fvcol.update({'_key': key, 'bar': 500})
    assert err.value.error_code in {11, 1228}
    assert fvcol[key]['foo'] == 200
    assert fvcol[key]['bar'] == 400

    # Test update vertex with sync set to True
    result = fvcol.update({'_key': key, 'bar': 500}, sync=True)
    assert result['_key'] == key
    assert result['_old_rev'] == old_rev
    assert fvcol[key]['foo'] == 200
    assert fvcol[key]['bar'] == 500
    old_rev = result['_rev']

    # Test update vertex with keep_none set to True
    result = fvcol.update({'_key': key, 'bar': None}, keep_none=True)
    assert result['_key'] == key
    assert result['_old_rev'] == old_rev
    assert fvcol[key]['foo'] == 200
    assert fvcol[key]['bar'] is None
    old_rev = result['_rev']

    # Test update vertex with keep_none set to False
    result = fvcol.update({'_key': key, 'foo': None}, keep_none=False)
    assert result['_key'] == key
    assert result['_old_rev'] == old_rev
    assert 'foo' not in fvcol[key]
    assert fvcol[key]['bar'] is None
    old_rev = result['_rev']

    # # Test update vertex with return_new and return_old set to True
    # result = fvcol.update({'_key': key}, return_new=True, return_old=True)
    # assert result['_key'] == key
    # assert result['_old_rev'] == old_rev
    # assert 'old' in result
    # assert 'new' in result
    # assert 'foo' not in fvcol[key]
    # assert fvcol[key]['bar'] is None

    # Test replace vertex with a single field change
    result = fvcol.replace({'_key': key, 'baz': 100})
    assert result['_key'] == key
    assert 'foo' not in fvcol[key]
    assert 'bar' not in fvcol[key]
    assert fvcol[key]['baz'] == 100
    old_rev = result['_rev']

    # Test replace vertex with silent set to True
    assert fvcol.replace({'_key': key, 'bar': 200}, silent=True) is True
    assert 'foo' not in fvcol[key]
    assert 'baz' not in fvcol[vertex]
    assert fvcol[vertex]['bar'] == 200
    assert len(fvcol) == 3
    assert fvcol[vertex]['_rev'] != old_rev
    old_rev = fvcol[vertex]['_rev']

    # Test replace vertex with multiple field changes
    vertex = {'_key': key, 'foo': 200, 'bar': 300}
    result = fvcol.replace(vertex)
    assert result['_key'] == key
    assert result['_old_rev'] == old_rev
    assert clean_doc(fvcol[key]) == vertex
    old_rev = result['_rev']

    # Test replace vertex with correct revision
    vertex = {'_key': key, '_rev': old_rev, 'bar': 500}
    result = fvcol.replace(vertex)
    assert result['_key'] == key
    assert result['_old_rev'] == old_rev
    assert clean_doc(fvcol[key]) == clean_doc(vertex)
    old_rev = result['_rev']

    # Test replace vertex with bad revision
    if fvcol.context != 'transaction':
        new_rev = old_rev + '10'
        vertex = {'_key': key, '_rev': new_rev, 'bar': 600}
        with assert_raises(DocumentRevisionError, DocumentReplaceError) as err:
            fvcol.replace(vertex)
        assert err.value.error_code in {1200, 1903}
        assert fvcol[key]['bar'] == 500
        assert 'foo' not in fvcol[key]

    # Test replace vertex with bad database
    with assert_raises(DocumentReplaceError) as err:
        bad_fvcol.replace({'_key': key, 'bar': 600})
    assert err.value.error_code in {11, 1228}
    assert fvcol[key]['bar'] == 500
    assert 'foo' not in fvcol[key]

    # Test replace vertex with sync set to True
    vertex = {'_key': key, 'bar': 400, 'foo': 200}
    result = fvcol.replace(vertex, sync=True)
    assert result['_key'] == key
    assert result['_old_rev'] == old_rev
    assert fvcol[key]['foo'] == 200
    assert fvcol[key]['bar'] == 400

    # Test delete vertex with bad revision
    if fvcol.context != 'transaction':
        old_rev = fvcol[key]['_rev']
        vertex['_rev'] = old_rev + '1'
        with assert_raises(DocumentRevisionError, DocumentDeleteError) as err:
            fvcol.delete(vertex, check_rev=True)
        assert err.value.error_code in {1200, 1903}
        vertex['_rev'] = old_rev
        assert vertex in fvcol

    # Test delete missing vertex
    bad_key = generate_doc_key()
    with assert_raises(DocumentDeleteError) as err:
        fvcol.delete(bad_key, ignore_missing=False)
    assert err.value.error_code == 1202
    if fvcol.context != 'transaction':
        assert fvcol.delete(bad_key, ignore_missing=True) is False

    # Test delete existing vertex with sync set to True
    assert fvcol.delete(vertex, sync=True, check_rev=False) is True
    if fvcol.context != 'transaction':
        assert fvcol[vertex] is None
    assert vertex not in fvcol
    assert len(fvcol) == 2
    fvcol.truncate()
예제 #13
0
def test_cursor_from_execute_query(db, col, docs):
    cursor = db.aql.execute(
        'FOR d IN {} SORT d._key RETURN d'.format(col.name),
        count=True,
        batch_size=2,
        ttl=1000,
        optimizer_rules=['+all'],
        profile=True
    )
    cursor_id = cursor.id
    assert 'Cursor' in repr(cursor)
    assert cursor.type == 'cursor'
    assert cursor.has_more() is True
    assert cursor.cached() is False
    assert cursor.warnings() == []
    assert cursor.count() == len(cursor) == 6
    assert clean_doc(cursor.batch()) == docs[:2]

    statistics = cursor.statistics()
    assert statistics['modified'] == 0
    assert statistics['filtered'] == 0
    assert statistics['ignored'] == 0
    assert statistics['scanned_full'] == 6
    assert statistics['scanned_index'] == 0
    assert statistics['execution_time'] > 0
    assert statistics['http_requests'] == 0
    assert cursor.warnings() == []

    profile = cursor.profile()
    assert profile['initializing'] > 0
    assert profile['parsing'] > 0

    assert clean_doc(cursor.next()) == docs[0]
    assert cursor.id == cursor_id
    assert cursor.has_more() is True
    assert cursor.cached() is False
    assert cursor.statistics() == statistics
    assert cursor.profile() == profile
    assert cursor.warnings() == []
    assert cursor.count() == len(cursor) == 6
    assert clean_doc(cursor.batch()) == [docs[1]]

    assert clean_doc(cursor.next()) == docs[1]
    assert cursor.id == cursor_id
    assert cursor.has_more() is True
    assert cursor.cached() is False
    assert cursor.statistics() == statistics
    assert cursor.profile() == profile
    assert cursor.warnings() == []
    assert cursor.count() == len(cursor) == 6
    assert clean_doc(cursor.batch()) == []

    assert clean_doc(cursor.next()) == docs[2]
    assert cursor.id == cursor_id
    assert cursor.has_more() is True
    assert cursor.cached() is False
    assert cursor.statistics() == statistics
    assert cursor.profile() == profile
    assert cursor.warnings() == []
    assert cursor.count() == len(cursor) == 6
    assert clean_doc(cursor.batch()) == [docs[3]]

    assert clean_doc(cursor.next()) == docs[3]
    assert clean_doc(cursor.next()) == docs[4]
    assert clean_doc(cursor.next()) == docs[5]
    assert cursor.id == cursor_id
    assert cursor.has_more() is False
    assert cursor.statistics() == statistics
    assert cursor.profile() == profile
    assert cursor.warnings() == []
    assert cursor.count() == len(cursor) == 6
    assert clean_doc(cursor.batch()) == []
    with pytest.raises(StopIteration):
        cursor.next()
    assert cursor.close(ignore_missing=True) is False
예제 #14
0
def test_cursor_write_query(db, col, docs):
    cursor = db.aql.execute(
        """
        FOR d IN {col} FILTER d._key == @first OR d._key == @second
        UPDATE {{_key: d._key, _val: @val }} IN {col}
        RETURN NEW
        """.format(
            col=col.name
        ),
        bind_vars={"first": "1", "second": "2", "val": 42},
        count=True,
        batch_size=1,
        ttl=1000,
        optimizer_rules=["+all"],
        profile=True,
        max_runtime=0.0,
    )
    cursor_id = cursor.id
    assert "Cursor" in repr(cursor)
    assert cursor.has_more() is True
    assert cursor.cached() is False
    assert cursor.warnings() == []
    assert cursor.count() == len(cursor) == 2
    assert clean_doc(cursor.batch()) == [docs[0]]

    statistics = cursor.statistics()
    assert statistics["modified"] == 2
    assert statistics["filtered"] == 0
    assert statistics["ignored"] == 0
    assert statistics["execution_time"] > 0
    assert "http_requests" in statistics
    assert "scanned_full" in statistics
    assert "scanned_index" in statistics
    assert cursor.warnings() == []

    profile = cursor.profile()
    assert profile["initializing"] > 0
    assert profile["parsing"] > 0

    assert clean_doc(cursor.next()) == docs[0]
    assert cursor.id == cursor_id
    assert cursor.has_more() is True
    assert cursor.cached() is False
    assert cursor.statistics() == statistics
    assert cursor.profile() == profile
    assert cursor.warnings() == []
    assert cursor.count() == len(cursor) == 2
    assert clean_doc(cursor.batch()) == []

    assert clean_doc(cursor.next()) == docs[1]
    assert cursor.id == cursor_id
    assert cursor.has_more() is False
    assert cursor.cached() is False
    assert cursor.statistics() == statistics
    assert cursor.profile() == profile
    assert cursor.warnings() == []
    assert cursor.count() == len(cursor) == 2
    assert clean_doc(cursor.batch()) == []

    with pytest.raises(CursorCloseError) as err:
        cursor.close(ignore_missing=False)
    assert err.value.error_code == 1600
    assert cursor.close(ignore_missing=True) is False
예제 #15
0
def test_cursor_from_execute_query(db, col, docs):
    cursor = db.aql.execute(
        f"FOR d IN {col.name} SORT d._key RETURN d",
        count=True,
        batch_size=2,
        ttl=1000,
        optimizer_rules=["+all"],
        profile=True,
    )
    cursor_id = cursor.id
    assert "Cursor" in repr(cursor)
    assert cursor.type == "cursor"
    assert cursor.has_more() is True
    assert cursor.cached() is False
    assert cursor.warnings() == []
    assert cursor.count() == len(cursor) == 6
    assert clean_doc(cursor.batch()) == docs[:2]

    statistics = cursor.statistics()
    assert statistics["modified"] == 0
    assert statistics["filtered"] == 0
    assert statistics["ignored"] == 0
    assert statistics["execution_time"] > 0
    assert "http_requests" in statistics
    assert "scanned_full" in statistics
    assert "scanned_index" in statistics
    assert cursor.warnings() == []

    profile = cursor.profile()
    assert profile["initializing"] > 0
    assert profile["parsing"] > 0

    assert clean_doc(cursor.next()) == docs[0]
    assert cursor.id == cursor_id
    assert cursor.has_more() is True
    assert cursor.cached() is False
    assert cursor.statistics() == statistics
    assert cursor.profile() == profile
    assert cursor.warnings() == []
    assert cursor.count() == len(cursor) == 6
    assert clean_doc(cursor.batch()) == [docs[1]]

    assert clean_doc(cursor.next()) == docs[1]
    assert cursor.id == cursor_id
    assert cursor.has_more() is True
    assert cursor.cached() is False
    assert cursor.statistics() == statistics
    assert cursor.profile() == profile
    assert cursor.warnings() == []
    assert cursor.count() == len(cursor) == 6
    assert clean_doc(cursor.batch()) == []

    assert clean_doc(cursor.next()) == docs[2]
    assert cursor.id == cursor_id
    assert cursor.has_more() is True
    assert cursor.cached() is False
    assert cursor.statistics() == statistics
    assert cursor.profile() == profile
    assert cursor.warnings() == []
    assert cursor.count() == len(cursor) == 6
    assert clean_doc(cursor.batch()) == [docs[3]]

    assert clean_doc(cursor.next()) == docs[3]
    assert clean_doc(cursor.next()) == docs[4]
    assert clean_doc(cursor.next()) == docs[5]
    assert cursor.id == cursor_id
    assert cursor.has_more() is False
    assert cursor.statistics() == statistics
    assert cursor.profile() == profile
    assert cursor.warnings() == []
    assert cursor.count() == len(cursor) == 6
    assert clean_doc(cursor.batch()) == []
    with pytest.raises(StopIteration):
        cursor.next()
    assert cursor.close(ignore_missing=True) is False
예제 #16
0
def test_edge_management(ecol, bad_ecol, edocs, fvcol, fvdocs, tvcol, tvdocs):
    for vertex in fvdocs:
        fvcol.insert(vertex)
    for vertex in tvdocs:
        tvcol.insert(vertex)

    edge = edocs[0]
    key = edge["_key"]

    # Test insert edge with no key
    no_key_edge = {"_from": edge["_from"], "_to": edge["_to"]}
    result = ecol.insert(no_key_edge)
    assert result["_key"] in ecol
    assert len(ecol) == 1
    empty_collection(ecol)

    # Test insert edge with return_new set to True
    result = ecol.insert(no_key_edge, return_new=True)
    assert "new" in result
    assert result["edge"]["_key"] in ecol
    assert len(ecol) == 1
    empty_collection(ecol)

    # Test insert vertex with ID
    edge_id = ecol.name + "/" + "foo"
    ecol.insert({"_id": edge_id, "_from": edge["_from"], "_to": edge["_to"]})
    assert "foo" in ecol
    assert edge_id in ecol
    assert len(ecol) == 1
    empty_collection(ecol)

    with assert_raises(DocumentParseError) as err:
        ecol.insert({
            "_id": generate_col_name() + "/" + "foo",
            "_from": edge["_from"],
            "_to": edge["_to"],
        })
    assert "bad collection name" in err.value.message

    # Test insert first valid edge
    result = ecol.insert(edge)
    assert result["_key"] == key
    assert "_rev" in result
    assert edge in ecol and key in ecol
    assert len(ecol) == 1
    assert ecol[key]["_from"] == edge["_from"]
    assert ecol[key]["_to"] == edge["_to"]

    # Test insert duplicate edge
    with assert_raises(DocumentInsertError) as err:
        assert ecol.insert(edge)
    assert err.value.error_code in {1202, 1210, 1906}
    assert len(ecol) == 1

    edge = edocs[1]
    key = edge["_key"]

    # Test insert second valid edge with silent set to True
    assert ecol.insert(edge, sync=True, silent=True) is True
    assert edge in ecol and key in ecol
    assert len(ecol) == 2
    assert ecol[key]["_from"] == edge["_from"]
    assert ecol[key]["_to"] == edge["_to"]

    # Test insert third valid edge using link method
    from_vertex = fvcol.get(fvdocs[2])
    to_vertex = tvcol.get(tvdocs[2])
    result = ecol.link(from_vertex, to_vertex, sync=False)
    assert result["_key"] in ecol
    assert len(ecol) == 3

    # Test insert fourth valid edge using link method
    from_vertex = fvcol.get(fvdocs[2])
    to_vertex = tvcol.get(tvdocs[0])
    assert (ecol.link(
        from_vertex["_id"],
        to_vertex["_id"],
        {"_id": ecol.name + "/foo"},
        sync=True,
        silent=True,
    ) is True)
    assert "foo" in ecol
    assert len(ecol) == 4

    with assert_raises(DocumentParseError) as err:
        assert ecol.link({}, {})
    assert err.value.message == 'field "_id" required'

    # Test get missing vertex
    bad_document_key = generate_doc_key()
    if ecol.context != "transaction":
        assert ecol.get(bad_document_key) is None

    # Test get existing edge by body with "_key" field
    result = ecol.get({"_key": key})
    assert clean_doc(result) == edge

    # Test get existing edge by body with "_id" field
    result = ecol.get({"_id": ecol.name + "/" + key})
    assert clean_doc(result) == edge

    # Test get existing edge by key
    result = ecol.get(key)
    assert clean_doc(result) == edge

    # Test get existing edge by ID
    result = ecol.get(ecol.name + "/" + key)
    assert clean_doc(result) == edge

    # Test get existing edge with bad revision
    old_rev = result["_rev"]
    with assert_raises(DocumentRevisionError) as err:
        ecol.get(key, rev=old_rev + "1")
    assert err.value.error_code in {1903, 1200}

    # Test get existing edge with bad database
    with assert_raises(DocumentGetError) as err:
        bad_ecol.get(key)
    assert err.value.error_code in {11, 1228}

    # Test update edge with a single field change
    assert "foo" not in ecol.get(key)
    result = ecol.update({"_key": key, "foo": 100})
    assert result["_key"] == key
    assert ecol[key]["foo"] == 100

    # Test update edge with return_old and return_new set to True
    result = ecol.update({
        "_key": key,
        "foo": 100
    },
                         return_old=True,
                         return_new=True)
    assert "old" in result
    assert "new" in result
    assert "edge" in result
    old_rev = ecol[key]["_rev"]

    # Test update edge with multiple field changes
    result = ecol.update({"_key": key, "foo": 200, "bar": 300})
    assert result["_key"] == key
    assert result["_old_rev"] == old_rev
    assert ecol[key]["foo"] == 200
    assert ecol[key]["bar"] == 300
    old_rev = result["_rev"]

    # Test update edge with correct revision
    result = ecol.update({"_key": key, "_rev": old_rev, "bar": 400})
    assert result["_key"] == key
    assert result["_old_rev"] == old_rev
    assert ecol[key]["foo"] == 200
    assert ecol[key]["bar"] == 400
    old_rev = result["_rev"]

    if ecol.context != "transaction":
        # Test update edge with bad revision
        new_rev = old_rev + "1"
        with assert_raises(DocumentRevisionError, DocumentUpdateError):
            ecol.update({"_key": key, "_rev": new_rev, "bar": 500})
        assert ecol[key]["foo"] == 200
        assert ecol[key]["bar"] == 400

    # Test update edge in missing edge collection
    with assert_raises(DocumentUpdateError) as err:
        bad_ecol.update({"_key": key, "bar": 500})
    assert err.value.error_code in {11, 1228}
    assert ecol[key]["foo"] == 200
    assert ecol[key]["bar"] == 400

    # Test update edge with sync option
    result = ecol.update({"_key": key, "bar": 500}, sync=True)
    assert result["_key"] == key
    assert result["_old_rev"] == old_rev
    assert ecol[key]["foo"] == 200
    assert ecol[key]["bar"] == 500
    old_rev = result["_rev"]

    # Test update edge with silent option
    assert ecol.update({"_key": key, "bar": 600}, silent=True) is True
    assert ecol[key]["foo"] == 200
    assert ecol[key]["bar"] == 600
    assert ecol[key]["_rev"] != old_rev
    old_rev = ecol[key]["_rev"]

    # Test update edge without keep_none option
    result = ecol.update({"_key": key, "bar": None}, keep_none=True)
    assert result["_key"] == key
    assert result["_old_rev"] == old_rev
    assert ecol[key]["foo"] == 200
    assert ecol[key]["bar"] is None
    old_rev = result["_rev"]

    # Test update edge with keep_none option
    result = ecol.update({"_key": key, "foo": None}, keep_none=False)
    assert result["_key"] == key
    assert result["_old_rev"] == old_rev
    assert "foo" not in ecol[key]
    assert ecol[key]["bar"] is None

    # Test replace edge with a single field change
    edge["foo"] = 100
    result = ecol.replace(edge)
    assert result["_key"] == key
    assert ecol[key]["foo"] == 100

    # Test replace edge with return_old and return_new set to True
    result = ecol.replace(edge, return_old=True, return_new=True)
    assert "old" in result
    assert "new" in result
    assert "edge" in result
    old_rev = ecol[key]["_rev"]

    # Test replace edge with silent set to True
    edge["bar"] = 200
    assert ecol.replace(edge, silent=True) is True
    assert ecol[key]["foo"] == 100
    assert ecol[key]["bar"] == 200
    assert ecol[key]["_rev"] != old_rev
    old_rev = ecol[key]["_rev"]

    # Test replace edge with multiple field changes
    edge["foo"] = 200
    edge["bar"] = 300
    result = ecol.replace(edge)
    assert result["_key"] == key
    assert result["_old_rev"] == old_rev
    assert ecol[key]["foo"] == 200
    assert ecol[key]["bar"] == 300
    old_rev = result["_rev"]

    # Test replace edge with correct revision
    edge["foo"] = 300
    edge["bar"] = 400
    edge["_rev"] = old_rev
    result = ecol.replace(edge)
    assert result["_key"] == key
    assert result["_old_rev"] == old_rev
    assert ecol[key]["foo"] == 300
    assert ecol[key]["bar"] == 400
    old_rev = result["_rev"]

    edge["bar"] = 500
    if ecol.context != "transaction":
        # Test replace edge with bad revision
        edge["_rev"] = old_rev + key
        with assert_raises(DocumentRevisionError, DocumentReplaceError) as err:
            ecol.replace(edge)
        assert err.value.error_code in {1200, 1903}
        assert ecol[key]["foo"] == 300
        assert ecol[key]["bar"] == 400

    # Test replace edge with bad database
    with assert_raises(DocumentReplaceError) as err:
        bad_ecol.replace(edge)
    assert err.value.error_code in {11, 1228}
    assert ecol[key]["foo"] == 300
    assert ecol[key]["bar"] == 400

    # Test replace edge with sync option
    result = ecol.replace(edge, sync=True, check_rev=False)
    assert result["_key"] == key
    assert result["_old_rev"] == old_rev
    assert ecol[key]["foo"] == 300
    assert ecol[key]["bar"] == 500

    # Test delete edge with bad revision
    if ecol.context != "transaction":
        old_rev = ecol[key]["_rev"]
        edge["_rev"] = old_rev + "1"
        with assert_raises(DocumentRevisionError, DocumentDeleteError) as err:
            ecol.delete(edge, check_rev=True)
        assert err.value.error_code in {1200, 1903}
        edge["_rev"] = old_rev
        assert edge in ecol

    # Test delete missing edge
    with assert_raises(DocumentDeleteError) as err:
        ecol.delete(bad_document_key, ignore_missing=False)
    assert err.value.error_code == 1202
    if ecol.context != "transaction":
        assert not ecol.delete(bad_document_key, ignore_missing=True)

    # Test delete existing edge with sync set to True
    assert ecol.delete(edge, sync=True, check_rev=False) is True
    if ecol.context != "transaction":
        assert ecol[edge] is None
    assert edge not in ecol

    # Test delete existing edge with return_old set to True
    ecol.insert(edge)
    result = ecol.delete(edge, return_old=True, check_rev=False)
    assert "old" in result
    assert edge not in ecol
    empty_collection(ecol)

    ecol.import_bulk(edocs)
    assert len(ecol) == len(edocs)
    empty_collection(ecol)

    ecol.insert_many(edocs)
    assert len(ecol) == len(edocs)

    ecol.delete_many(edocs)
    assert len(ecol) == 1
예제 #17
0
def test_vertex_management(fvcol, bad_fvcol, fvdocs):
    # Test insert vertex with no key
    result = fvcol.insert({})
    assert result["_key"] in fvcol
    assert len(fvcol) == 1
    empty_collection(fvcol)

    # Test insert vertex with ID
    vertex_id = fvcol.name + "/" + "foo"
    fvcol.insert({"_id": vertex_id})
    assert "foo" in fvcol
    assert vertex_id in fvcol
    assert len(fvcol) == 1
    empty_collection(fvcol)

    # Test insert vertex with return_new set to True
    result = fvcol.insert({"_id": vertex_id}, return_new=True)
    assert "new" in result
    assert "vertex" in result
    assert len(fvcol) == 1
    empty_collection(fvcol)

    with assert_raises(DocumentParseError) as err:
        fvcol.insert({"_id": generate_col_name() + "/" + "foo"})
    assert "bad collection name" in err.value.message

    vertex = fvdocs[0]
    key = vertex["_key"]

    # Test insert first valid vertex
    result = fvcol.insert(vertex, sync=True)
    assert result["_key"] == key
    assert "_rev" in result
    assert vertex in fvcol and key in fvcol
    assert len(fvcol) == 1
    assert fvcol[key]["val"] == vertex["val"]

    # Test insert duplicate vertex
    with assert_raises(DocumentInsertError) as err:
        fvcol.insert(vertex)
    assert err.value.error_code in {1202, 1210}
    assert len(fvcol) == 1

    vertex = fvdocs[1]
    key = vertex["_key"]

    # Test insert second valid vertex
    result = fvcol.insert(vertex)
    assert result["_key"] == key
    assert "_rev" in result
    assert vertex in fvcol and key in fvcol
    assert len(fvcol) == 2
    assert fvcol[key]["val"] == vertex["val"]

    vertex = fvdocs[2]
    key = vertex["_key"]

    # Test insert third valid vertex with silent set to True
    assert fvcol.insert(vertex, silent=True) is True
    assert len(fvcol) == 3
    assert fvcol[key]["val"] == vertex["val"]

    # Test get missing vertex
    if fvcol.context != "transaction":
        assert fvcol.get(generate_doc_key()) is None

    # Test get existing edge by body with "_key" field
    result = fvcol.get({"_key": key})
    assert clean_doc(result) == vertex

    # Test get existing edge by body with "_id" field
    result = fvcol.get({"_id": fvcol.name + "/" + key})
    assert clean_doc(result) == vertex

    # Test get existing vertex by key
    result = fvcol.get(key)
    assert clean_doc(result) == vertex

    # Test get existing vertex by ID
    result = fvcol.get(fvcol.name + "/" + key)
    assert clean_doc(result) == vertex

    # Test get existing vertex with bad revision
    old_rev = result["_rev"]
    with assert_raises(DocumentRevisionError) as err:
        fvcol.get(key, rev=old_rev + "1", check_rev=True)
    assert err.value.error_code in {1903, 1200}

    # Test get existing vertex with bad database
    with assert_raises(DocumentGetError) as err:
        bad_fvcol.get(key)
    assert err.value.error_code in {11, 1228}

    # Test update vertex with a single field change
    assert "foo" not in fvcol.get(key)
    result = fvcol.update({"_key": key, "foo": 100})
    assert result["_key"] == key
    assert fvcol[key]["foo"] == 100
    old_rev = fvcol[key]["_rev"]

    # Test update vertex with return_new and return_old set to True
    result = fvcol.update({
        "_key": key,
        "foo": 100
    },
                          return_old=True,
                          return_new=True)
    assert "old" in result
    assert "new" in result
    assert "vertex" in result

    # Test update vertex with silent set to True
    assert "bar" not in fvcol[vertex]
    assert fvcol.update({"_key": key, "bar": 200}, silent=True) is True
    assert fvcol[vertex]["bar"] == 200
    assert fvcol[vertex]["_rev"] != old_rev
    old_rev = fvcol[key]["_rev"]

    # Test update vertex with multiple field changes
    result = fvcol.update({"_key": key, "foo": 200, "bar": 300})
    assert result["_key"] == key
    assert result["_old_rev"] == old_rev
    assert fvcol[key]["foo"] == 200
    assert fvcol[key]["bar"] == 300
    old_rev = result["_rev"]

    # Test update vertex with correct revision
    result = fvcol.update({"_key": key, "_rev": old_rev, "bar": 400})
    assert result["_key"] == key
    assert result["_old_rev"] == old_rev
    assert fvcol[key]["foo"] == 200
    assert fvcol[key]["bar"] == 400
    old_rev = result["_rev"]

    # Test update vertex with bad revision
    if fvcol.context != "transaction":
        new_rev = old_rev + "1"
        with assert_raises(DocumentRevisionError) as err:
            fvcol.update({"_key": key, "_rev": new_rev, "bar": 500})
        assert err.value.error_code in {1200, 1903}
        assert fvcol[key]["foo"] == 200
        assert fvcol[key]["bar"] == 400

    # Test update vertex in missing vertex collection
    with assert_raises(DocumentUpdateError) as err:
        bad_fvcol.update({"_key": key, "bar": 500})
    assert err.value.error_code in {11, 1228}
    assert fvcol[key]["foo"] == 200
    assert fvcol[key]["bar"] == 400

    # Test update vertex with sync set to True
    result = fvcol.update({"_key": key, "bar": 500}, sync=True)
    assert result["_key"] == key
    assert result["_old_rev"] == old_rev
    assert fvcol[key]["foo"] == 200
    assert fvcol[key]["bar"] == 500
    old_rev = result["_rev"]

    # Test update vertex with keep_none set to True
    result = fvcol.update({"_key": key, "bar": None}, keep_none=True)
    assert result["_key"] == key
    assert result["_old_rev"] == old_rev
    assert fvcol[key]["foo"] == 200
    assert fvcol[key]["bar"] is None
    old_rev = result["_rev"]

    # Test update vertex with keep_none set to False
    result = fvcol.update({"_key": key, "foo": None}, keep_none=False)
    assert result["_key"] == key
    assert result["_old_rev"] == old_rev
    assert "foo" not in fvcol[key]
    assert fvcol[key]["bar"] is None

    # Test replace vertex with a single field change
    result = fvcol.replace({"_key": key, "baz": 100})
    assert result["_key"] == key
    assert "foo" not in fvcol[key]
    assert "bar" not in fvcol[key]
    assert fvcol[key]["baz"] == 100
    old_rev = result["_rev"]

    # Test replace vertex with return_new and return_old set to True
    result = fvcol.replace({
        "_key": key,
        "baz": 100
    },
                           return_old=True,
                           return_new=True)
    assert "old" in result
    assert "new" in result
    assert "vertex" in result

    # Test replace vertex with silent set to True
    assert fvcol.replace({"_key": key, "bar": 200}, silent=True) is True
    assert "foo" not in fvcol[key]
    assert "baz" not in fvcol[vertex]
    assert fvcol[vertex]["bar"] == 200
    assert len(fvcol) == 3
    assert fvcol[vertex]["_rev"] != old_rev
    old_rev = fvcol[vertex]["_rev"]

    # Test replace vertex with multiple field changes
    vertex = {"_key": key, "foo": 200, "bar": 300}
    result = fvcol.replace(vertex)
    assert result["_key"] == key
    assert result["_old_rev"] == old_rev
    assert clean_doc(fvcol[key]) == vertex
    old_rev = result["_rev"]

    # Test replace vertex with correct revision
    vertex = {"_key": key, "_rev": old_rev, "bar": 500}
    result = fvcol.replace(vertex)
    assert result["_key"] == key
    assert result["_old_rev"] == old_rev
    assert clean_doc(fvcol[key]) == clean_doc(vertex)
    old_rev = result["_rev"]

    # Test replace vertex with bad revision
    if fvcol.context != "transaction":
        new_rev = old_rev + "10"
        vertex = {"_key": key, "_rev": new_rev, "bar": 600}
        with assert_raises(DocumentRevisionError, DocumentReplaceError) as err:
            fvcol.replace(vertex)
        assert err.value.error_code in {1200, 1903}
        assert fvcol[key]["bar"] == 500
        assert "foo" not in fvcol[key]

    # Test replace vertex with bad database
    with assert_raises(DocumentReplaceError) as err:
        bad_fvcol.replace({"_key": key, "bar": 600})
    assert err.value.error_code in {11, 1228}
    assert fvcol[key]["bar"] == 500
    assert "foo" not in fvcol[key]

    # Test replace vertex with sync set to True
    vertex = {"_key": key, "bar": 400, "foo": 200}
    result = fvcol.replace(vertex, sync=True)
    assert result["_key"] == key
    assert result["_old_rev"] == old_rev
    assert fvcol[key]["foo"] == 200
    assert fvcol[key]["bar"] == 400

    # Test delete vertex with bad revision
    if fvcol.context != "transaction":
        old_rev = fvcol[key]["_rev"]
        vertex["_rev"] = old_rev + "1"
        with assert_raises(DocumentRevisionError, DocumentDeleteError) as err:
            fvcol.delete(vertex, check_rev=True)
        assert err.value.error_code in {1200, 1903}
        vertex["_rev"] = old_rev
        assert vertex in fvcol

    # Test delete missing vertex
    bad_key = generate_doc_key()
    with assert_raises(DocumentDeleteError) as err:
        fvcol.delete(bad_key, ignore_missing=False)
    assert err.value.error_code == 1202
    if fvcol.context != "transaction":
        assert fvcol.delete(bad_key, ignore_missing=True) is False

    # Test delete existing vertex with sync set to True
    assert fvcol.delete(vertex, sync=True, check_rev=False) is True
    if fvcol.context != "transaction":
        assert fvcol[vertex] is None
    assert vertex not in fvcol
    assert len(fvcol) == 2

    # Test delete existing vertex with return_old set to True
    vertex = fvdocs[1]
    result = fvcol.delete(vertex, return_old=True)
    assert "old" in result
    assert len(fvcol) == 1
    empty_collection(fvcol)

    fvcol.import_bulk(fvdocs)
    assert len(fvcol) == len(fvdocs)
    empty_collection(fvcol)

    fvcol.insert_many(fvdocs)
    assert len(fvcol) == len(fvdocs)

    fvcol.delete_many(fvdocs)
    assert len(fvcol) == 0