Skip to content

Commit

Permalink
fix(conf): allow type coercion for configuration options (#84)
Browse files Browse the repository at this point in the history
* Adds type coercion option for a configuration
* Coerces `mongod_port` to `int`, `ignore_cache` to `bool`, and `use_local_mongod` to `bool`.
* Removes unnecessary warning log for user set MongoD port since the value is advertised with context.
  • Loading branch information
ekarademir authored Sep 9, 2023
1 parent b2eec60 commit 4bc43df
Show file tree
Hide file tree
Showing 14 changed files with 649 additions and 602 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/pypi-publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,10 @@ jobs:
runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@v3
- name: Set up Python 3.7
- name: Set up Python 3.9
uses: actions/setup-python@v4
with:
python-version: 3.7
python-version: 3.9
- name: Install and configure Poetry
run: |
curl -sSL https://install.python-poetry.org | python3 -
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/testing.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@ jobs:
runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@v3
- name: Set up Python 3.7
- name: Set up Python 3.9
uses: actions/setup-python@v4
with:
python-version: 3.7
python-version: 3.9
- name: Install and configure Poetry
run: |
curl -sSL https://install.python-poetry.org | python3 -
Expand Down
2 changes: 1 addition & 1 deletion .python-version
Original file line number Diff line number Diff line change
@@ -1 +1 @@
3.7.16
3.9
4 changes: 1 addition & 3 deletions examples/able_to_connect.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,7 @@
with MongoClient() as client:
db = client["test-db"]
collection = db["my-collection"]
data = {
"some": "data"
}
data = {"some": "data"}
inserted_id = collection.insert_one(data).inserted_id
mongo_dump = bson.decode(client.pim_mongodump("test-db", "my-collection"))
assert mongo_dump["some"] == "data"
Expand Down
4 changes: 1 addition & 3 deletions examples/several_clients.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,7 @@
db2 = client2["test-db"]
collection1 = db1["my-collection"]
collection2 = db2["my-collection"]
data = {
"some": "data"
}
data = {"some": "data"}
inserted_id1 = collection1.insert_one(data).inserted_id
inserted_id2 = collection2.insert_one(data).inserted_id
mongo_dump1 = bson.decode(client1.pim_mongodump("test-db", "my-collection"))
Expand Down
1,099 changes: 539 additions & 560 deletions poetry.lock

Large diffs are not rendered by default.

41 changes: 30 additions & 11 deletions pymongo_inmemory/context.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,13 @@ class OperatingSystemNotFound(ValueError):
pass


def _coercion(constructor, value):
if constructor == bool:
return value == "True"
else:
return constructor(value)


def _check_environment_vars(option, fallback=None):
"Check if `option` is defined in environment variables"
return os.environ.get("PYMONGOIM__{}".format(str(option).upper()), default=fallback)
Expand All @@ -30,7 +37,7 @@ def _check_cfg(option, filename, fallback=None):
return parser.get("pymongo_inmemory", option, fallback=fallback, raw=True)


def conf(option, fallback=None, optional=True):
def conf(option, fallback=None, optional=True, coerce_with=str):
"""Retrieve asked `option` if possible. There are number of places that are checked.
In the order of precedence,
1. Environment variables
Expand Down Expand Up @@ -65,13 +72,25 @@ def conf(option, fallback=None, optional=True):
),
)

if value is None and not optional:
raise ValueError(
(
"Can't determine the value of {} "
"and it is not an optional parameter."
).format(option)
)
if value is None:
if not optional:
raise ValueError(
(
"Can't determine the value of {} "
"and it is not an optional parameter."
).format(option)
)
else:
try:
value = _coercion(coerce_with, value)
except ValueError:
value = None
except Exception:
raise ValueError(
("Can't coerce the value of {} to type {}").format(
option, coerce_with.__qualname__
)
)

logger.debug("Value for {}=={}".format(option, value))

Expand All @@ -83,7 +102,7 @@ def __init__(
self, os_name=None, version=None, os_ver=None, ignore_cache=False
) -> None:
self.mongo_version = conf("mongo_version", version)
self.mongod_port = conf("mongod_port", None)
self.mongod_port = conf("mongod_port", None, coerce_with=int)

self.operating_system = self._build_operating_system_info(os_name)
self.os_version = conf("os_version", os_ver)
Expand All @@ -94,8 +113,8 @@ def __init__(

self.url_hash = hashlib.sha256(bytes(self.download_url, "utf-8")).hexdigest()

self.ignore_cache = bool(conf("ignore_cache", ignore_cache))
self.use_local_mongod = conf("use_local_mongod", None)
self.ignore_cache = conf("ignore_cache", ignore_cache, coerce_with=bool)
self.use_local_mongod = conf("use_local_mongod", False, coerce_with=bool)

self.download_folder = conf(
"download_folder", mkdir_ifnot_exist(CACHE_FOLDER, "download")
Expand Down
1 change: 0 additions & 1 deletion pymongo_inmemory/mongod.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,6 @@ def port(self):
if set_port is None:
return str(find_open_port(range(27017, 28000)))
else:
logger.warning("Using Mongod port set by user: {}".format(set_port))
return set_port


Expand Down
8 changes: 5 additions & 3 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[tool.poetry]
name = "pymongo_inmemory"
version = "0.3.0"
version = "0.3.1"
description = "A mongo mocking library with an ephemeral MongoDB running in memory."
authors = ["Kaizen Dorks <[email protected]>"]
maintainers = [
Expand Down Expand Up @@ -31,14 +31,13 @@ include = ["LICENSE"]
"Bug Reports" = "https://github.com/kaizendorks/pymongo_inmemory/issues"

[tool.poetry.dependencies]
python = "^3.7"
python = "^3.9"
pymongo = "*"

[tool.poetry.dev-dependencies]
flake8 = "*"
mypy = "*"
pytest = "*"
pytest-pythonpath = "*"
twine = "*"
wheel = "*"
setuptools = "*"
Expand All @@ -51,3 +50,6 @@ black = "^23.3.0"
[build-system]
requires = ["poetry>=0.12"]
build-backend = "poetry.masonry.api"

[tool.pytest.ini_options]
pythonpath = "."
4 changes: 0 additions & 4 deletions setup.cfg
Original file line number Diff line number Diff line change
@@ -1,7 +1,3 @@
[flake8]
max-line-length = 89
exclude = .git,__pycache__,.venv

[tool:pytest]
python_paths = .

1 change: 1 addition & 0 deletions tests/functional/test_open_ports_socket.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ def server(request):
# Add finalizer at the point of least possible failure
def fin():
server.close()

request.addfinalizer(fin)

server.setblocking(0)
Expand Down
3 changes: 2 additions & 1 deletion tests/unit/test_async.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,11 @@


def test_init_module_in_loop():
sys.modules.pop('pymongo_inmemory.mongod', None)
sys.modules.pop("pymongo_inmemory.mongod", None)

async def main():
import pymongo_inmemory.mongod # noqa F401

return True

loop = asyncio.new_event_loop()
Expand Down
20 changes: 20 additions & 0 deletions tests/unit/test_context.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,3 +44,23 @@ def test_download_url_setting(monkeypatch):
pim_context = context.Context()
assert pim_context.download_url == provided_url
assert pim_context.url_hash == expected_hash


def test_expected_type_coercion(monkeypatch):
monkeypatch.setenv("PYMONGOIM__MONGOD_PORT", "42")
monkeypatch.setenv("PYMONGOIM__IGNORE_CACHE", "True")
monkeypatch.setenv("PYMONGOIM__USE_LOCAL_MONGOD", "True")
pim_context = context.Context()
assert pim_context.ignore_cache
assert pim_context.use_local_mongod
assert pim_context.mongod_port == 42


def test_type_coercion_uncoercible_values(monkeypatch):
monkeypatch.setenv("PYMONGOIM__MONGOD_PORT", "something")
monkeypatch.setenv("PYMONGOIM__IGNORE_CACHE", "true")
monkeypatch.setenv("PYMONGOIM__USE_LOCAL_MONGOD", "false")
pim_context = context.Context()
assert not pim_context.ignore_cache
assert not pim_context.use_local_mongod
assert pim_context.mongod_port is None
56 changes: 45 additions & 11 deletions tests/unit/test_urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,30 +4,64 @@

import pymongo_inmemory.downloader._urls as utools


def test_best_url():
"""
- Given `major.minor.patch` version:
- Starting from `major` to `patch`
- If there is an exact match it should take it
- If there isn't, it should take the highest and go on with the highest
"""
assert utools.best_url("linux") == ("https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-4.0.28.tgz", "4.0.28"), "Should find latest MongoDB for Linux:Generic"
assert utools.best_url("linux", "3") == ("https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-3.6.23.tgz", "3.6.23"), "Should find latest MongoDB 3 for Linux:Generic"
assert utools.best_url("linux", "3.4") == ("https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-3.4.24.tgz", "3.4.24"), "Should find latest MongoDB 3.4 for Linux:Generic"
assert utools.best_url("linux", "2.6.11") == ("https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-2.6.11.tgz", "2.6.11"), "Should find exact MongoDB 2.6.11 for Linux:Generic"
assert utools.best_url("linux") == (
"https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-4.0.28.tgz",
"4.0.28",
), "Should find latest MongoDB for Linux:Generic"
assert utools.best_url("linux", "3") == (
"https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-3.6.23.tgz",
"3.6.23",
), "Should find latest MongoDB 3 for Linux:Generic"
assert utools.best_url("linux", "3.4") == (
"https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-3.4.24.tgz",
"3.4.24",
), "Should find latest MongoDB 3.4 for Linux:Generic"
assert utools.best_url("linux", "2.6.11") == (
"https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-2.6.11.tgz",
"2.6.11",
), "Should find exact MongoDB 2.6.11 for Linux:Generic"

assert utools.best_url("linux", "4.4.4") == ("https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-4.0.28.tgz", "4.0.28"), "Linux:Generic support ends at 4.0.28, higher versions default to this."
assert utools.best_url("linux", "4.4.4") == (
"https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-4.0.28.tgz",
"4.0.28",
), "Linux:Generic support ends at 4.0.28, higher versions default to this."

assert utools.best_url("ubuntu") == ("https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-ubuntu2004-6.0.6.tgz", "6.0.6"), "Should find latest MongoDB for latest Ubuntu"
assert utools.best_url("ubuntu", os_ver=18) == ("https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-ubuntu1804-6.0.6.tgz", "6.0.6"), "Should find latest MongoDB for Ubuntu 18"
assert utools.best_url("ubuntu", os_ver="14", version="3.0.3") == ("https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-ubuntu1404-3.0.3.tgz", "3.0.3"), "Should find MongoDB 3.0.3 for Ubuntu 14"
assert utools.best_url("ubuntu") == (
"https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-ubuntu2004-6.0.6.tgz",
"6.0.6",
), "Should find latest MongoDB for latest Ubuntu"
assert utools.best_url("ubuntu", os_ver=18) == (
"https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-ubuntu1804-6.0.6.tgz",
"6.0.6",
), "Should find latest MongoDB for Ubuntu 18"
assert utools.best_url("ubuntu", os_ver="14", version="3.0.3") == (
"https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-ubuntu1404-3.0.3.tgz",
"3.0.3",
), "Should find MongoDB 3.0.3 for Ubuntu 14"

with pytest.raises(utools.OperatingSystemNameNotFound):
utools.best_url("xubuntu", os_ver="14", version="3.0.3")

with pytest.raises(utools.OperatingSystemVersionNotFound):
utools.best_url("ubuntu", os_ver="10", version="3.0.3")

assert utools.best_url("ubuntu", os_ver="14", version="1.4.4") == ("https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-ubuntu1404-4.0.28.tgz", "4.0.28"), "If major version is not there should find latest major version of MongoDB for Ubuntu 14"
assert utools.best_url("ubuntu", os_ver="14", version="3.8.4") == ("https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-ubuntu1404-3.6.23.tgz", "3.6.23"), "If minor version is not there should find latest minor version of MongoDB for given major version, for Ubuntu 14"
assert utools.best_url("ubuntu", os_ver="14", version="3.4.22") == ("https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-ubuntu1404-3.4.24.tgz", "3.4.24"), "If patch version is not there should find latest patch version of MongoDB for given major.minor version, for Ubuntu 14"
assert utools.best_url("ubuntu", os_ver="14", version="1.4.4") == (
"https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-ubuntu1404-4.0.28.tgz",
"4.0.28",
), "If major version is not there should find latest major version of MongoDB for Ubuntu 14"
assert utools.best_url("ubuntu", os_ver="14", version="3.8.4") == (
"https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-ubuntu1404-3.6.23.tgz",
"3.6.23",
), "If minor version is not there should find latest minor version of MongoDB for given major version, for Ubuntu 14"
assert utools.best_url("ubuntu", os_ver="14", version="3.4.22") == (
"https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-ubuntu1404-3.4.24.tgz",
"3.4.24",
), "If patch version is not there should find latest patch version of MongoDB for given major.minor version, for Ubuntu 14"

0 comments on commit 4bc43df

Please sign in to comment.