Skip to content

Commit

Permalink
-more unit tests. (seeking code coverage helped me find one bug)
Browse files Browse the repository at this point in the history
-update docs
-bumped version (will do a release)
  • Loading branch information
toppk committed Nov 23, 2019
1 parent 81ac73e commit ad3d841
Show file tree
Hide file tree
Showing 6 changed files with 172 additions and 25 deletions.
25 changes: 6 additions & 19 deletions README.md
@@ -1,20 +1,14 @@
## NOTICE

This project has just started.
This project has just started. In order to get the SDLC complete, this project is published on github and pypi, but I don't recommend anyone use it just yet.

In order to get the SDLC complete, this project is published on github and pypi.

This is only recommened for people who want
However, it is for anyone who wants

* to get involved in development,
* give feedback
* are happy with it's very limited state

Please check back often, I hope to get this to a generally useful state this year.

Contributions, advice welcome, development coodinated on github

* to give feedback,
* or are happy with it's very limited state

Please check back often, I hope to get this to a generally useful state this year. Contributions, advice welcome, development is coodinated on github.

<p align="center">
<a href="https://pysandra.readthedocs.org/"><img width="350" height="208" src="https://raw.githubusercontent.com/toppk/pysandra/master/docs/img/logo.png" alt='pysandra'></a>
Expand Down Expand Up @@ -76,16 +70,9 @@ Aims to be:
* make user objects user friendly (exceptions, EventChage, Rows)
* AUTH
* batch
* client connection routing
* cqlshell

## Developing

$ cd pysandra
$ python3 -m venv venv
$ source venv/bin/activate
$ pip install -r test-requirements.txt
$ pip install -e .


## License & Contributions

Expand Down
26 changes: 24 additions & 2 deletions docs/developing.md
@@ -1,2 +1,24 @@
pip install -e tools/cqlshell
PYSANDRA_LOG_LEVEL=DEBUG python -mcqlshell.testasync foo



Developers Guide
================

Setting up your environment
---------------------------


1. install prerequisites (python >= 3.6, git, optionally lz4, snappy)
2. go into your workspace directory (e.g. `cd ~/workspace` )
3. checkout the project: `git clone https://github.com/toppk/pysandra`
4. switch to project directory: `cd pysandra`
5. Setup your virtualenv (e.g. `python -m venv venv/` )
6. active virtualenv (e.g. `source venv/bin/activate`)
7. install development dependencies
8. `pip install -r test-requirements.txt`
9. `pip install -e .`
10. `pip install -e tools/cqlshell`
11. run testsuit: `pytest`
12. run testing utilit `python -mcqlshell.testasync dml`
13. run testing utilit with DEBUGGING `PYSANDRA_LOG_LEVEL=DEBUG python -mcqlshell.testasync dml`
14. run test automation: `nox`
2 changes: 1 addition & 1 deletion pysandra/__about__.py
Expand Up @@ -12,7 +12,7 @@
__title__ = "pysandra"
__description__ = "Python driver for Cassandra focusing on asyncio users (INCOMPLETE)."
__uri__ = "https://github.com/toppk/pysandra"
__version__ = "0.2.5"
__version__ = "0.2.6"
__author__ = "Kenneth Topp"
__email__ = "toppk@bllue.org"
__license__ = "MIT or Apache License, Version 2.0"
Expand Down
6 changes: 4 additions & 2 deletions pysandra/protocol.py
Expand Up @@ -138,12 +138,14 @@ def encode_string(value: Union[str, bytes]) -> bytes:
)


def encode_value(value: Union[str, bytes, int]) -> bytes:
def encode_value(value: Optional[Union[str, bytes, int]]) -> bytes:
if value is None:
return encode_int(-1)
if isinstance(value, int):
value_bytes = encode_int(value)
elif isinstance(value, str):
value_bytes = value.encode("utf-8")
elif isinstance(value, dict):
elif isinstance(value, bytes):
value_bytes = value
return encode_int(len(value_bytes)) + pack(
f"{NETWORK_ORDER}{len(value_bytes)}{STypes.CHAR}", value_bytes
Expand Down
136 changes: 136 additions & 0 deletions tests/test_protocol_codecs.py
@@ -0,0 +1,136 @@
import pytest

from pysandra.core import SBytes
from pysandra.exceptions import InternalDriverError
from pysandra.protocol import (
decode_int,
decode_int_bytes,
decode_short,
decode_short_bytes,
decode_string,
decode_string_multimap,
decode_strings_list,
encode_int,
encode_long_string,
encode_short,
encode_string,
encode_strings_list,
encode_value,
get_struct,
)


def test_get_bad_struct():
with pytest.raises(InternalDriverError, match=r"not cached"):
get_struct("!Hqqq")


def test_encode_short():
body = 2
assert encode_short(body) == b"\00\02"


def test_encode_int():
body = 5
assert encode_int(body) == b"\00\00\00\05"


def test_encode_string():
body = "test"
assert encode_string(body) == b"\00\04test"


def test_encode_string_bytes():
body = b"test"
assert encode_string(body) == b"\00\04test"


def test_encode_value_string():
body = "asdf"
assert encode_value(body) == b"\x00\x00\x00\x04asdf"


def test_encode_value_int():
body = 123
assert encode_value(body) == b"\x00\x00\x00\x04\x00\x00\x00\x7b"


def test_encode_value_bytes():
body = b"asdf"
assert encode_value(body) == b"\x00\x00\x00\x04asdf"


def test_encode_value_none():
body = None
assert encode_value(body) == b"\xff\xff\xff\xff"


def test_encode_long_string_plain():
body = "longer"
assert encode_long_string(body) == b"\00\00\00\06longer"


def test_encode_long_string_bytes():
body = b"longer"
assert encode_long_string(body) == b"\00\00\00\06longer"


def test_encode_strings_list():
body = ["apple", "orange", "book"]
assert encode_strings_list(body) == b"\00\03\00\05apple\00\06orange\00\04book"


def test_decode_string():
body = SBytes(b"\00\04asdf")
assert decode_string(body) == "asdf"


def test_decode_short():
body = SBytes(b"\00\04")
assert decode_short(body) == 4


def test_decode_int():
body = SBytes(b"\00\04\02\04")
assert decode_int(body) == 262660


def test_decode_short_bytes():
body = SBytes(b"\00\04asdf")
assert decode_short_bytes(body) == b"asdf"


def test_decode_short_bytes_empty():
body = SBytes(b"\00\00")
assert decode_short_bytes(body) == b""


def test_decode_int_bytes_zero():
body = SBytes(b"\00\00\00\00")
assert decode_int_bytes(body) == b""


def test_decode_int_bytes_null():
body = SBytes(b"\xff\xff\xff\xff")
assert decode_int_bytes(body) is None


def test_decode_int_bytes_plain():
body = SBytes(b"\00\00\00\04asdf")
assert decode_int_bytes(body) == b"asdf"


def test_decode_strings_list():
body = SBytes(b"\00\02\00\02as\00\03dfg")
assert decode_strings_list(body) == ["as", "dfg"]


def test_decode_string_multimap():
body = SBytes(
b"\00\03\00\02as\00\02\00\02df\00\03zxc\00\01z\00\03\00\04zxcv\00\01c\00\02vv\00\05last.\00\03\00\03one\00\03two\00\05three"
)
assert decode_string_multimap(body) == {
"as": ["df", "zxc"],
"z": ["zxcv", "c", "vv"],
"last.": ["one", "two", "three"],
}
2 changes: 1 addition & 1 deletion tools/cqlshell/cqlshell/testasync.py
Expand Up @@ -144,7 +144,7 @@ async def test_tls(tester):
await tester.close()
# tester = Tester(Client(host=("127.0.0.1", 9042), use_tls=False, debug_signal=Signals.SIGUSR1))
tester = Tester(
Client(host=("127.0.0.1", 9142), use_tls=False, debug_signal=Signals.SIGUSR1)
Client(host=("127.0.0.1", 9142), use_tls=True, debug_signal=Signals.SIGUSR1)
)
await tester.run_query("SELECT * FROM uprofile.user where user_id=?", (2,))
await tester.run_query("SELECT * FROM uprofile.user where user_id=:id", {"id": 3})
Expand Down

0 comments on commit ad3d841

Please sign in to comment.