Skip to content

Commit

Permalink
test: Add more tests for bootstrap.
Browse files Browse the repository at this point in the history
Also fixed some incorrect types in udp/tcp port getters.
  • Loading branch information
iphydf committed Feb 26, 2024
1 parent 9c7efc6 commit 0cc7616
Show file tree
Hide file tree
Showing 10 changed files with 79 additions and 17 deletions.
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -44,4 +44,4 @@ COPY test /build/test
RUN . /path/to/venv/bin/activate \
&& coverage run -m unittest discover -v -p "*_test.py"
RUN . /path/to/venv/bin/activate \
&& coverage report -m --fail-under=67
&& coverage report -m --fail-under=70
4 changes: 3 additions & 1 deletion pytox/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,11 @@ class PytoxException(Exception):


class ApiException(PytoxException):
code: enum.Enum

def __init__(self, err: enum.Enum):
super().__init__(err.name)
self.error = err
self.code = err


class LengthException(PytoxException):
Expand Down
9 changes: 6 additions & 3 deletions pytox/toxcore/tox.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -473,7 +473,10 @@ cdef class Tox_Ptr:
def bootstrap(self, host: str, port: int, public_key: bytes) -> bool:
common.check_len("public_key", public_key, tox_public_key_size())
cdef Tox_Err_Bootstrap err = TOX_ERR_BOOTSTRAP_OK
return tox_bootstrap(self._get(), host.encode("utf-8"), port, public_key, &err)
cdef bool res = tox_bootstrap(self._get(), host.encode("utf-8"), port, public_key, &err)
if err:
raise ApiException(Tox_Err_Bootstrap(err))
return res

@property
def iteration_interval(self) -> int:
Expand Down Expand Up @@ -515,15 +518,15 @@ cdef class Tox_Ptr:
@property
def udp_port(self) -> int:
cdef Tox_Err_Get_Port err = TOX_ERR_GET_PORT_OK
cdef bool res = tox_self_get_udp_port(self._get(), &err)
cdef uint16_t res = tox_self_get_udp_port(self._get(), &err)
if err:
raise ApiException(Tox_Err_Get_Port(err))
return res

@property
def tcp_port(self) -> int:
cdef Tox_Err_Get_Port err = TOX_ERR_GET_PORT_OK
cdef bool res = tox_self_get_tcp_port(self._get(), &err)
cdef uint16_t res = tox_self_get_tcp_port(self._get(), &err)
if err:
raise ApiException(Tox_Err_Get_Port(err))
return res
Expand Down
2 changes: 1 addition & 1 deletion test/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
load("@rules_python//python:defs.bzl", "py_test")
load("//third_party/python:build_defs.bzl", "mypy_test")

TESTS = glob(["**/*.py"])
TESTS = glob(["**/*_test.py"])

[py_test(
name = src[:-3],
Expand Down
9 changes: 7 additions & 2 deletions test/auto_tests/auto_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,9 @@ class TestTox(core.Tox_Ptr):
conferences: dict[int, ConferenceInfo]

def __init__(self, index: int) -> None:
super(TestTox, self).__init__()
with core.Tox_Options_Ptr() as options:
options.local_discovery_enabled = False
super(TestTox, self).__init__(options)
self.index = index
self.friends = collections.defaultdict(FriendInfo)
self.conferences = collections.defaultdict(ConferenceInfo)
Expand Down Expand Up @@ -176,6 +178,9 @@ def _iterate(self, max_iterate: int, cond: Callable[[], bool]) -> None:
self.fail(f"condition not met after {max_iterate} iterations")

def _wait_for_self_online(self) -> None:
self.tox2.bootstrap("127.0.0.1", self.tox1.udp_port, self.tox1.dht_id)
self.tox3.bootstrap("127.0.0.1", self.tox1.udp_port, self.tox1.dht_id)

def is_online() -> bool:
return bool(
self.tox1.connection_status == core.TOX_CONNECTION_NONE
Expand Down Expand Up @@ -226,7 +231,7 @@ def test_friend_by_public_key(self) -> None:
with self.assertRaises(core.ApiException) as ex:
# We're not our own friend.
self.tox1.friend_by_public_key(self.tox1.public_key)
self.assertEqual(ex.exception.error,
self.assertEqual(ex.exception.code,
core.TOX_ERR_FRIEND_BY_PUBLIC_KEY_NOT_FOUND)

def test_send_message(self) -> None:
Expand Down
7 changes: 6 additions & 1 deletion test/auto_tests/self_connection_status_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,9 @@ class TestTox(core.Tox_Ptr):
friends: dict[int, FriendInfo]

def __init__(self, index: int) -> None:
super(TestTox, self).__init__()
with core.Tox_Options_Ptr() as options:
options.local_discovery_enabled = False
super(TestTox, self).__init__(options)
self.index = index
self.friends = collections.defaultdict(FriendInfo)

Expand Down Expand Up @@ -64,6 +66,9 @@ def _iterate(self, max_iterate: int, cond: Callable[[], bool]) -> None:
self.fail(f"condition not met after {max_iterate} iterations")

def _wait_for_self_online(self) -> None:
self.tox2.bootstrap("127.0.0.1", self.tox1.udp_port, self.tox1.dht_id)
self.tox3.bootstrap("127.0.0.1", self.tox1.udp_port, self.tox1.dht_id)

def is_online() -> bool:
return bool(
self.tox1.connection_status == core.TOX_CONNECTION_NONE
Expand Down
3 changes: 3 additions & 0 deletions test/tox_options_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,9 @@ def test_options(self) -> None:

# Can't test whether it works, but at least we can test that it doesn't crash.
opts.savedata_data = b"test"
with self.assertRaises(Exception):
# not implemented
print(opts.savedata_data)

self.assertFalse(opts.experimental_thread_safety)
opts.experimental_thread_safety = True
Expand Down
56 changes: 50 additions & 6 deletions test/tox_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,6 @@ class ToxTest(unittest.TestCase):
def test_version(self) -> None:
self.assertEqual(len(c.VERSION.split(".")), 3)

def test_options(self) -> None:
opts = c.Tox_Options_Ptr()
self.assertTrue(opts.ipv6_enabled)
opts.ipv6_enabled = False
self.assertFalse(opts.ipv6_enabled)

def test_use_after_free(self) -> None:
opts = c.Tox_Options_Ptr()
with c.Tox_Ptr(opts) as tox:
Expand All @@ -31,11 +25,26 @@ def test_pass_none(self) -> None:
with c.Tox_Ptr(None):
pass

def test_pass_invalid_options(self) -> None:
opts = c.Tox_Options_Ptr()
opts.proxy_type = c.TOX_PROXY_TYPE_SOCKS5
opts.proxy_host = "invalid-host"
opts.proxy_port = 1234
with self.assertRaises(c.ApiException) as e:
c.Tox_Ptr(opts)
self.assertEqual(e.exception.code, c.TOX_ERR_NEW_PROXY_BAD_HOST)

def test_address(self) -> None:
opts = c.Tox_Options_Ptr()
with c.Tox_Ptr(opts) as tox:
self.assertEqual(tox.address, tox.address)

def test_nospam(self) -> None:
with c.Tox_Ptr(None) as tox:
tox.nospam = 0x12345678
self.assertEqual(tox.nospam, 0x12345678)
self.assertEqual(tox.address[-6:-2].hex(), "12345678")

def test_public_key_is_address_prefix(self) -> None:
opts = c.Tox_Options_Ptr()
with c.Tox_Ptr(opts) as tox:
Expand Down Expand Up @@ -89,6 +98,17 @@ def test_friend_add(self) -> None:
with self.assertRaises(common.LengthException):
tox2.friend_add(tox1.public_key, b"oh no!")

def test_invalid_bootstrap(self) -> None:
with c.Tox_Ptr() as tox:
with self.assertRaises(c.ApiException) as e:
tox.bootstrap("invalid-host", 1234, bytes(c.PUBLIC_KEY_SIZE))
self.assertEqual(e.exception.code, c.TOX_ERR_BOOTSTRAP_BAD_HOST)

def test_bootstrap_checks_key_length(self) -> None:
with c.Tox_Ptr() as tox:
with self.assertRaises(common.LengthException):
tox.bootstrap("localhost", 1234, bytes(c.PUBLIC_KEY_SIZE - 1))

def test_friend_delete(self) -> None:
with c.Tox_Ptr() as tox1:
with c.Tox_Ptr() as tox2:
Expand All @@ -98,6 +118,30 @@ def test_friend_delete(self) -> None:
# Deleting again: we don't have that friend anymore.
tox1.friend_delete(0)

def test_udp_port_fails_when_udp_disabled(self) -> None:
with c.Tox_Options_Ptr() as opts:
opts.udp_enabled = False
with c.Tox_Ptr(opts) as tox:
with self.assertRaises(c.ApiException) as e:
print(tox.udp_port)
self.assertEqual(e.exception.code,
c.TOX_ERR_GET_PORT_NOT_BOUND)

def test_tcp_port_fails_when_tcp_disabled(self) -> None:
with c.Tox_Options_Ptr() as opts:
opts.tcp_port = 0
with c.Tox_Ptr(opts) as tox:
with self.assertRaises(c.ApiException) as e:
print(tox.tcp_port)
self.assertEqual(e.exception.code,
c.TOX_ERR_GET_PORT_NOT_BOUND)

def test_tcp_port(self) -> None:
with c.Tox_Options_Ptr() as opts:
opts.tcp_port = 1234
with c.Tox_Ptr(opts) as tox:
self.assertEqual(tox.tcp_port, 1234)


if __name__ == "__main__":
unittest.main()
2 changes: 1 addition & 1 deletion test/toxav_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ class AvTest(unittest.TestCase):
def test_version(self) -> None:
with self.assertRaises(av.ApiException) as ex:
av.Toxav_Ptr(cast(tox.Tox_Ptr, None))
self.assertEqual(ex.exception.error, av.TOXAV_ERR_NEW_NULL)
self.assertEqual(ex.exception.code, av.TOXAV_ERR_NEW_NULL)


if __name__ == "__main__":
Expand Down
2 changes: 1 addition & 1 deletion test/toxencryptsave_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ def test_encrypt_decrypt_with_wrong_salt(self) -> None:
with c.Tox_Pass_Key_Ptr(b"hello", b"b" * 32) as pk2:
with self.assertRaises(c.ApiException) as ex:
pk2.decrypt(pk1.encrypt(b"hello world"))
self.assertEqual(ex.exception.error.name,
self.assertEqual(ex.exception.code.name,
c.TOX_ERR_DECRYPTION_FAILED.name)

def test_salt_too_small(self) -> None:
Expand Down

0 comments on commit 0cc7616

Please sign in to comment.