Exemple #1
0
    async def test_scan_reverse(self, table: Table):

        if table.connection.compat < '0.98':
            with pytest.raises(NotImplementedError):
                await self._scan_list(table, reverse=True)
            return

        async with table.batch() as b:
            for i in range(2000):
                await b.put(f'row-scan-reverse-{i:04}'.encode('ascii'), {
                    b'cf1:col1': b'v1',
                    b'cf1:col2': b'v2'
                })

        scan = table.scan(row_prefix=b'row-scan-reverse', reverse=True)
        assert 2000 == await self._scan_len(scan)

        assert 10 == await self._tbl_scan_len(table, limit=10, reverse=True)

        scan = table.scan(
            row_start=b'row-scan-reverse-1999',
            row_stop=b'row-scan-reverse-0000',
            reverse=True,
        )
        key, data = await scan.__anext__()
        assert b'row-scan-reverse-1999' == key

        key, data = [x async for x in scan][-1]
        assert b'row-scan-reverse-0001' == key
Exemple #2
0
 async def test_sync_batch_context(self, table: Table):
     with pytest.raises(RuntimeError):
         with table.batch():
             pass
     with pytest.raises(RuntimeError):
         table.batch().__enter__()
     batch = await table.batch().__aenter__()
     with pytest.raises(RuntimeError):
         batch.__exit__()
Exemple #3
0
    async def test_batch_order(self, table: Table):
        row = b'row-test-batch-order'
        col = b'cf1:col'

        async with table.batch() as b:
            for i in range(5):
                await b.put(row, {col: str(i).encode()})
        assert (await table.row(row))[col] == b'4'
Exemple #4
0
    async def test_batch_delete_put_same_row(self, table: Table):
        # See https://github.com/python-happybase/happybase/issues/224
        row = b'row-test-batch-delete-put'
        col = b'cf1:col'
        val = b'val'

        await table.put(row, {col: b''})
        async with table.batch() as b:
            await b.delete(row)
            await b.put(row, {col: val})
        result = await table.row(row)
        assert col in result
        assert result[col] == val
Exemple #5
0
    async def test_batch_counters(self, table: Table):
        row = b'row-with-counter'
        col1 = b'cf1:counter1'
        col2 = b'cf1:counter2'

        get = partial(table.counter_get, row)

        async def check_cols(c1: int, c2: int):
            for col, val in [(col1, c1), (col2, c2)]:
                assert await get(col) == val

        async with table.batch() as b:
            inc = partial(b.counter_inc, row)
            dec = partial(b.counter_dec, row)
            await inc(col1, 1)  # c1 == 1, c2 == 0
            await inc(col1, 2)  # c1 == 3, c2 == 0
            await dec(col2, 2)  # c1 == 3, c2 == -2
            await dec(col1, 1)  # c1 == 2, c2 == -2
            await inc(col2, 5)  # c1 == 2, c2 == 3
            # Make sure nothing was sent yet
            await check_cols(0, 0)

        await check_cols(2, 3)

        for c in [col1, col2]:
            await table.counter_set(row, c, 0)
        await check_cols(0, 0)

        async with table.batch(batch_size=2) as b:
            inc = partial(b.counter_inc, row)
            await inc(col1, 1)
            await check_cols(0, 0)  # Not sent yet
            await inc(col1, 1)
            await check_cols(0, 0)  # Same column modified twice, not sent
            await inc(col2, 1)  # Forces send since batch count >= 2
            await check_cols(2, 1)
Exemple #6
0
    async def test_scan_sorting(self, table: Table):
        if table.connection.compat < '0.96':
            return  # not supported

        input_row = {
            f'cf1:col-{i:03}'.encode('ascii'): b''
            for i in range(100)
        }
        input_key = b'row-scan-sorted'
        await table.put(input_key, input_row)

        scan = table.scan(row_start=input_key, sorted_columns=True)
        key, row = await scan.__anext__()
        assert key == input_key
        assert sorted(input_row.items()) == list(row.items())
        await scan.aclose()
Exemple #7
0
    async def test_batch_context_managers(self, table: Table):
        async with table.batch() as b:
            await b.put(b'row4', {b'cf1:col3': b'value3'})
            await b.put(b'row5', {b'cf1:col4': b'value4'})
            await b.put(b'row', {b'cf1:col1': b'value1'})
            await b.delete(b'row', [b'cf1:col4'])
            await b.put(b'row', {b'cf1:col2': b'value2'})

        async with table.batch(timestamp=87654321) as b:
            await b.put(b'row', {
                b'cf1:c3': b'somevalue',
                b'cf1:c5': b'anothervalue'
            })
            await b.delete(b'row', [b'cf1:c3'])

        with pytest.raises(ValueError):
            async with table.batch(transaction=True) as b:
                await b.put(b'fooz', {b'cf1:bar': b'baz'})
                raise ValueError
        assert {} == await table.row(b'fooz', [b'cf1:bar'])

        with pytest.raises(ValueError):
            async with table.batch(transaction=False) as b:
                await b.put(b'fooz', {b'cf1:bar': b'baz'})
                raise ValueError
        assert {b'cf1:bar': b'baz'} == await table.row(b'fooz', [b'cf1:bar'])

        async with table.batch(batch_size=5) as b:
            for i in range(10):
                await b.put(
                    f'row-batch1-{i:03}'.encode('ascii'),
                    {b'cf1:': str(i).encode('ascii')},
                )

        async with table.batch(batch_size=20) as b:
            for i in range(95):
                await b.put(
                    f'row-batch2-{i:03}'.encode('ascii'),
                    {b'cf1:': str(i).encode('ascii')},
                )
        assert 95 == await self._tbl_scan_len(table, row_prefix=b'row-batch2-')

        async with table.batch(batch_size=20) as b:
            for i in range(95):
                await b.delete(f'row-batch2-{i:03}'.encode('ascii'))
        assert 0 == await self._tbl_scan_len(table, row_prefix=b'row-batch2-')
Exemple #8
0
    async def test_batch(self, table: Table):
        with pytest.raises(TypeError):
            table.batch(timestamp='invalid')  # noqa

        b = table.batch()
        await b.put(b'row1', {b'cf1:col1': b'value1', b'cf1:col2': b'value2'})
        await b.put(b'row2', {
            b'cf1:col1': b'value1',
            b'cf1:col2': b'value2',
            b'cf1:col3': b'value3'
        })
        await b.delete(b'row1', [b'cf1:col4'])
        await b.delete(b'another-row')
        await b.close()

        table.batch(timestamp=1234567)
        await b.put(b'row1', {b'cf1:col5': b'value5'})
        await b.close()

        with pytest.raises(ValueError):
            table.batch(batch_size=0)

        with pytest.raises(TypeError):
            table.batch(transaction=True, batch_size=10)
Exemple #9
0
    async def test_scan_filter_and_batch_size(self, table: Table):
        # See issue #54 and #56
        filt = b"SingleColumnValueFilter('cf1','col1',=,'binary:%s',true,true)"

        if table.connection.compat == '0.90':
            with pytest.raises(NotImplementedError):
                await self._tbl_scan_len(table, filter=filt % b'hello there')
            return

        assert 0 == await self._tbl_scan_len(table,
                                             filter=filt % b'hello there')

        await table.put(b'row-test-scan-filter', {b'cf1:col1': b'v1'})

        got_results = False
        async for k, v in table.scan(filter=filt % b'v1'):
            got_results = True
            assert next((x for x in v if b'cf1' in x), None) is not None
            assert v[b'cf1:col1'] == b'v1'

        assert got_results, "No results found for cf1:col1='v1'"
Exemple #10
0
 async def _tbl_scan_len(cls, table: Table, **kwargs) -> int:
     return await cls._scan_len(table.scan(**kwargs))
Exemple #11
0
 async def _scan_list(table: Table, *args,
                      **kwargs) -> List[Tuple[bytes, Data]]:
     return [x async for x in table.scan(*args, **kwargs)]
Exemple #12
0
    async def test_scan(self, table: Table):
        with pytest.raises(TypeError):
            await self._scan_list(table, row_prefix='foobar', row_start='xyz')

        if table.connection.compat == '0.90':
            with pytest.raises(NotImplementedError):
                await self._scan_list(table, filter='foo')

        if table.connection.compat < '0.96':
            with pytest.raises(NotImplementedError):
                await self._scan_list(table, sorted_columns=True)

        with pytest.raises(ValueError):
            await self._scan_list(table, batch_size=0)

        with pytest.raises(ValueError):
            await self._scan_list(table, limit=0)

        with pytest.raises(ValueError):
            await self._scan_list(table, scan_batching=0)

        async with table.batch() as b:
            for i in range(2000):
                await b.put(
                    f'row-scan-a{i:05}'.encode('ascii'), {
                        b'cf1:col1': b'v1',
                        b'cf1:col2': b'v2',
                        b'cf2:col1': b'v1',
                        b'cf2:col2': b'v2'
                    })
                await b.put(f'row-scan-b{i:05}'.encode('ascii'), {
                    b'cf1:col1': b'v1',
                    b'cf1:col2': b'v2'
                })

        scanner = table.scan(
            row_start=b'row-scan-a00012',
            row_stop=b'row-scan-a00022',
        )
        assert 10 == await self._scan_len(scanner)

        scanner = table.scan(row_start=b'xyz')
        assert 0 == await self._scan_len(scanner)

        scanner = table.scan(row_start=b'xyz', row_stop=b'zyx')
        assert 0 == await self._scan_len(scanner)

        rows = await self._scan_list(
            table,
            row_start=b'row-scan-',
            row_stop=b'row-scan-a999',
            columns=[b'cf1:col1', b'cf2:col2'],
        )
        row_key, row = rows[0]
        assert row_key == b'row-scan-a00000'
        assert row == {b'cf1:col1': b'v1', b'cf2:col2': b'v2'}
        assert 2000 == len(rows)

        scanner = table.scan(
            row_prefix=b'row-scan-a',
            batch_size=499,
            limit=1000,
        )
        assert 1000 == await self._scan_len(scanner)

        scanner = table.scan(
            row_prefix=b'row-scan-b',
            batch_size=1,
            limit=10,
        )
        assert 10 == await self._scan_len(scanner)

        scanner = table.scan(
            row_prefix=b'row-scan-b',
            batch_size=5,
            limit=10,
        )
        assert 10 == await self._scan_len(scanner)

        scanner = table.scan(timestamp=123)
        assert 0 == await self._scan_len(scanner)

        scanner = table.scan(row_prefix=b'row', timestamp=123)
        assert 0 == await self._scan_len(scanner)

        scanner = table.scan(batch_size=20)
        await scanner.__anext__()
        await scanner.aclose()
        with pytest.raises(StopAsyncIteration):
            await scanner.__anext__()