Skip to content

Commit

Permalink
updated test coverage
Browse files Browse the repository at this point in the history
  • Loading branch information
toluaina committed Feb 6, 2022
1 parent 9ba95bb commit b1c39c3
Show file tree
Hide file tree
Showing 8 changed files with 227 additions and 58 deletions.
4 changes: 3 additions & 1 deletion .coveragerc
@@ -1,2 +1,4 @@
[run]
omit = pgsync/constants.py
omit =
pgsync/constants.py
pgsync/__init__.py
3 changes: 2 additions & 1 deletion pgsync/helper.py
Expand Up @@ -20,13 +20,14 @@ def teardown(
drop_index: bool = True,
delete_checkpoint: bool = True,
config: Optional[str] = None,
validate: bool = False,
) -> None:
"""Teardown helper."""
config: str = get_config(config)

with open(config, "r") as documents:
for document in json.load(documents):
sync: Sync = Sync(document, validate=False)
sync: Sync = Sync(document, validate=validate)
if truncate_db:
try:
sync.truncate_schemas()
Expand Down
18 changes: 16 additions & 2 deletions tests/test_helper.py
@@ -1,5 +1,6 @@
"""Helper tests."""
import pytest
import sqlalchemy as sa
from mock import patch

from pgsync.helper import teardown
Expand All @@ -9,9 +10,22 @@
class TestHelper(object):
"""Helper tests."""

@patch("pgsync.helper.logger")
@patch("pgsync.helper.get_config")
@patch("pgsync.helper.Sync")
def test_teardown(self, mock_sync, mock_config):
def test_teardown_with_drop_db(self, mock_sync, mock_config, mock_logger):
mock_config.return_value = "tests/fixtures/schema.json"
mock_sync.truncate_schemas.return_value = None
teardown(drop_db=False, config="fixtures/schema.json")
with patch("pgsync.helper.drop_database") as mock_db:
teardown(drop_db=True, config="fixtures/schema.json")
mock_db.assert_called_once()
mock_logger.warning.assert_not_called()

@patch("pgsync.helper.logger")
@patch("pgsync.helper.get_config")
def test_teardown_without_drop_db(self, mock_config, mock_logger):
mock_config.return_value = "tests/fixtures/schema.json"
with patch("pgsync.sync.Sync") as mock_sync:
mock_sync.truncate_schemas.side_effect = sa.exc.OperationalError
teardown(drop_db=False, config="fixtures/schema.json")
mock_logger.warning.assert_called_once()
95 changes: 95 additions & 0 deletions tests/test_sync.py
Expand Up @@ -4,6 +4,9 @@
import pytest
from mock import patch

from pgsync.exc import RDSError, SchemaError
from pgsync.sync import Sync

ROW = namedtuple("Row", ["data", "xid"])


Expand Down Expand Up @@ -64,3 +67,95 @@ def test_logical_slot_changes(self, sync):
mock_get.assert_called_once()
mock_sync.assert_called_once()
sync.es.close()

def test_sync_validate(self):
with pytest.raises(SchemaError) as excinfo:
sync = Sync(
document={
"index": "testdb",
"nodes": ["foo"],
},
verbose=False,
validate=True,
repl_slots=False,
)
assert (
"Incompatible schema. Please run v2 schema migration"
in str(excinfo.value)
)

sync = Sync(
document={
"index": "testdb",
"nodes": {"table": "book"},
"plugins": ["Hero"],
},
verbose=False,
validate=True,
repl_slots=False,
)

def _side_effect(*args, **kwargs):
if args[0] == 0:
return 0
elif args[0] == "max_replication_slots":
raise RuntimeError(
"Ensure there is at least one replication slot defined "
"by setting max_replication_slots=1"
)

elif args[0] == "wal_level":
raise RuntimeError(
"Enable logical decoding by setting wal_level=logical"
)
elif args[0] == "rds_logical_replication":
raise RDSError("rds.logical_replication is not enabled")
else:
return args[0]

with pytest.raises(RuntimeError) as excinfo:
with patch(
"pgsync.base.Base.pg_settings",
side_effects=_side_effect("max_replication_slots"),
):
sync = Sync(
document={
"index": "testdb",
"nodes": {"table": "book"},
"plugins": ["Hero"],
},
)
assert (
"Ensure there is at least one replication slot defined "
"by setting max_replication_slots=1" in str(excinfo.value)
)

with pytest.raises(RuntimeError) as excinfo:
with patch(
"pgsync.base.Base.pg_settings",
side_effects=_side_effect("wal_level"),
):
sync = Sync(
document={
"index": "testdb",
"nodes": {"table": "book"},
"plugins": ["Hero"],
},
)
assert "Enable logical decoding by setting wal_level=logical" in str(
excinfo.value
)

with pytest.raises(RDSError) as excinfo:
with patch(
"pgsync.base.Base.pg_settings",
side_effects=_side_effect("rds_logical_replication"),
):
sync = Sync(
document={
"index": "testdb",
"nodes": {"table": "book"},
"plugins": ["Hero"],
},
)
assert "rds.logical_replication is not enabled" in str(excinfo.value)
2 changes: 0 additions & 2 deletions tests/test_sync_nested_children.py
Expand Up @@ -1092,8 +1092,6 @@ def poll_db():
},
]
for i, doc in enumerate(docs):
# assert doc["_id"] == expected[i]["_id"]
# assert doc["_index"] == expected[i]["_index"]
for key in [
"_meta",
"authors",
Expand Down
12 changes: 12 additions & 0 deletions tests/test_transform.py
Expand Up @@ -6,6 +6,7 @@
_concat_fields,
_get_transform,
_rename_fields,
get_private_keys,
transform,
)

Expand Down Expand Up @@ -400,3 +401,14 @@ def test_concat_fields(self):
# - withour delimiter
# - with list order maintained
# - without destination specified

def test_get_private_keys(self):
primary_keys = [
{"publisher": {"id": [4]}},
None,
None,
None,
None,
None,
]
assert get_private_keys(primary_keys) == {"publisher": {"id": [4]}}
83 changes: 83 additions & 0 deletions tests/test_urls.py
@@ -0,0 +1,83 @@
"""URLS tests."""
import pytest
from mock import MagicMock, patch

from pgsync.exc import SchemaError
from pgsync.plugin import Plugins
from pgsync.urls import (
_get_auth,
get_elasticsearch_url,
get_postgres_url,
get_redis_url,
)
from pgsync.utils import get_config


@pytest.mark.usefixtures("table_creator")
class TestUrls(object):
"""URLS tests."""

@patch("pgsync.urls.logger")
def test_get_elasticsearch_url(self, mock_logger):
assert get_elasticsearch_url() == "http://localhost:9200"
mock_logger.debug.assert_called_once()
assert (
get_elasticsearch_url(scheme="https") == "https://localhost:9200"
)
assert mock_logger.debug.call_count == 2
assert (
get_elasticsearch_url(
user="kermit",
password="1234",
)
== "http://kermit:1234@localhost:9200"
)
assert get_elasticsearch_url(port=9999) == "http://localhost:9999"

def test_get_postgres_url(self):
url = get_postgres_url("mydb")
assert url.endswith("@localhost:5432/mydb")
assert (
get_postgres_url("mydb", user="kermit", password="12345")
== "postgresql://kermit:12345@localhost:5432/mydb"
)
url = get_postgres_url("mydb", port=9999)
assert url.endswith("@localhost:9999/mydb")

@patch("pgsync.urls.logger")
def test_get_redis_url(self, mock_logger):
assert get_redis_url() == "redis://localhost:6379/0"
mock_logger.debug.assert_called_with(
"Connecting to Redis without password."
)
assert (
get_redis_url(
password="1234",
port=9999,
)
== "redis://:1234@localhost:9999/0"
)
assert get_redis_url(host="skynet") == "redis://skynet:6379/0"

@patch("pgsync.urls.logger")
def test_get_config(self, mock_logger):
assert __file__ == get_config(config=__file__)
with pytest.raises(SchemaError) as excinfo:
get_config()
assert "Schema config not set" in str(excinfo.value)
with pytest.raises(IOError) as excinfo:
get_config("/tmp/nonexistent")
assert 'Schema config "/tmp/nonexistent" not found' in str(
excinfo.value
)

@patch("pgsync.urls.logger")
def test_get_auth(self, mock_logger):
assert __file__ == get_config(config=__file__)
with patch("pgsync.urls.Plugins", return_value=MagicMock()):
auth = _get_auth("something")
mock_logger.assert_not_called()

with patch("pgsync.urls.Plugins", side_effect=ModuleNotFoundError):
auth = _get_auth("something")
mock_logger.warning.assert_called_once()
68 changes: 16 additions & 52 deletions tests/test_utils.py
Expand Up @@ -3,64 +3,28 @@
from mock import patch

from pgsync.exc import SchemaError
from pgsync.urls import get_elasticsearch_url, get_postgres_url, get_redis_url
from pgsync.utils import get_config
from pgsync.utils import get_config, show_settings


@pytest.mark.usefixtures("table_creator")
class TestUtils(object):
"""Utils tests."""

@patch("pgsync.urls.logger")
def test_get_elasticsearch_url(self, mock_logger):
assert get_elasticsearch_url() == "http://localhost:9200"
mock_logger.debug.assert_called_once()
assert (
get_elasticsearch_url(scheme="https") == "https://localhost:9200"
)
assert mock_logger.debug.call_count == 2
assert (
get_elasticsearch_url(
user="kermit",
password="1234",
)
== "http://kermit:1234@localhost:9200"
)
assert get_elasticsearch_url(port=9999) == "http://localhost:9999"
def test_get_config(self):
with pytest.raises(SchemaError) as excinfo:
get_config()
assert "Schema config not set" in str(excinfo.value)

def test_get_postgres_url(self):
url = get_postgres_url("mydb")
assert url.endswith("@localhost:5432/mydb")
assert (
get_postgres_url("mydb", user="kermit", password="12345")
== "postgresql://kermit:12345@localhost:5432/mydb"
)
url = get_postgres_url("mydb", port=9999)
assert url.endswith("@localhost:9999/mydb")
with pytest.raises(OSError) as excinfo:
get_config("non_existent")
assert 'Schema config "non_existent" not found' in str(excinfo.value)
config = get_config("tests/fixtures/schema.json")
assert config == "tests/fixtures/schema.json"

@patch("pgsync.urls.logger")
def test_get_redis_url(self, mock_logger):
assert get_redis_url() == "redis://localhost:6379/0"
mock_logger.debug.assert_called_with(
"Connecting to Redis without password."
@patch("pgsync.utils.logger")
def test_show_settings(self, mock_logger):
show_settings(schema="tests/fixtures/schema.json")
mock_logger.info.assert_any_call("\033[4mSettings\033[0m:")
mock_logger.info.assert_any_call(
f'{"Schema":<10s}: {"tests/fixtures/schema.json"}'
)
assert (
get_redis_url(
password="1234",
port=9999,
)
== "redis://:1234@localhost:9999/0"
)
assert get_redis_url(host="skynet") == "redis://skynet:6379/0"

@patch("pgsync.urls.logger")
def test_get_config(self, mock_logger):
assert __file__ == get_config(config=__file__)
with pytest.raises(SchemaError) as excinfo:
get_config()
assert "Schema config not set" in str(excinfo.value)
with pytest.raises(IOError) as excinfo:
get_config("/tmp/nonexistent")
assert 'Schema config "/tmp/nonexistent" not found' in str(
excinfo.value
)

0 comments on commit b1c39c3

Please sign in to comment.