From ae9462dccee5d37fc5ef7ca1c6b46c3469d299bb Mon Sep 17 00:00:00 2001 From: Teddy Xinyuan Chen <45612704+tddschn@users.noreply.github.com> Date: Thu, 25 May 2023 14:36:52 +0800 Subject: [PATCH 1/6] add tests/test_serde.py Signed-off-by: Teddy Xinyuan Chen <45612704+tddschn@users.noreply.github.com> --- Makefile | 2 +- tests/test_serde.py | 19 +++++++++++++++++++ 2 files changed, 20 insertions(+), 1 deletion(-) create mode 100644 tests/test_serde.py diff --git a/Makefile b/Makefile index 040b028..306cbb2 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -PY_SOURCE=modelz +PY_SOURCE=modelz tests .DEFAULT_GOAL:=build diff --git a/tests/test_serde.py b/tests/test_serde.py new file mode 100644 index 0000000..e7d5f02 --- /dev/null +++ b/tests/test_serde.py @@ -0,0 +1,19 @@ +import pytest + +from modelz.serde import SerdeEnum + + +@pytest.mark.parametrize( + "serde_name, data, encoded", + [ + ("json", {"foo": "bar"}, '{"foo": "bar"}'), + ("msgpack", {"foo": "bar"}, b"\x81\xa3foo\xa3bar"), + ("raw", b"foobar", b"foobar"), + ("text", "foobar", b"foobar"), + ], +) +def test_serde(serde_name, data, encoded): + serde_cls = getattr(SerdeEnum, serde_name).value + serde = serde_cls() + assert serde.encode(data) == encoded + assert serde.decode(encoded) == data From cdff4ba2e05486c60617213e32ad6a584aa126b8 Mon Sep 17 00:00:00 2001 From: Teddy Xinyuan Chen <45612704+tddschn@users.noreply.github.com> Date: Thu, 25 May 2023 23:08:25 +0800 Subject: [PATCH 2/6] add tests/test_cmd.py Signed-off-by: Teddy Xinyuan Chen <45612704+tddschn@users.noreply.github.com> --- tests/test_cmd.py | 82 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 82 insertions(+) create mode 100644 tests/test_cmd.py diff --git a/tests/test_cmd.py b/tests/test_cmd.py new file mode 100644 index 0000000..d64cec6 --- /dev/null +++ b/tests/test_cmd.py @@ -0,0 +1,82 @@ +import sys +from io import StringIO +from unittest.mock import MagicMock + +from modelz.client import ModelzClient, ModelzResponse +from modelz.cmd import console, inference +from modelz.serde import RawSerde + + +def test_inference(monkeypatch): + # Mocking the behavior of `ModelzClient.inference` + params_dict = {"key": "value"} + params_as_saved_in_file = b"Mocked Response" + b" saved in file" + output_file = "output.bin" + output_written_message = f"result has been written in {output_file}\n" + + try: + + def mock_inference(self, params, serde): + mock_response = ModelzResponse( + resp=MagicMock(status_code=200, content=params), + serde=RawSerde(), + ) + return mock_response + + # Patching the `client.inference` method with the mock + monkeypatch.setattr(ModelzClient, "inference", mock_inference) + mock_init = MagicMock() + mock_init.return_value = None + monkeypatch.setattr(ModelzClient, "__init__", mock_init) + + # Creating a StringIO object to capture the console output + console_output = StringIO() + console.file = console_output + + # Running the inference function with the mocked client and write to file + inference( + deployment="deployment_id", + params=params_dict, + read_stdin=False, + ) + + # Asserting the console output + expected_output = "{'key': 'value'}\n" + assert console_output.getvalue() == expected_output + + # sys.stdin = StringIO(stdin_input) + # Mocking the behavior of `sys.stdin.buffer.read()` + mock_stdin_read = MagicMock(return_value=params_as_saved_in_file) + + # Patching the `sys.stdin.buffer.read()` with the mock + monkeypatch.setattr(sys.stdin.buffer, "read", mock_stdin_read) + + console_output = StringIO() + console.file = console_output + + inference( + deployment="deployment_id", + read_stdin=True, + write_file=output_file, + ) + + # Asserting the file content + with open(output_file, "rb") as file: + file_content = file.read() + assert file_content == params_as_saved_in_file + + # Asserting the console output + assert console_output.getvalue() == output_written_message + + except Exception as e: + # Resetting the sys.stdin + # sys.stdin = sys.__stdin__ + monkeypatch.undo() + + # remove output_file if exists + import os + + if os.path.exists(output_file): + os.remove(output_file) + + raise e From 39085eb6e23e6843bf4d3936905a21035db2358d Mon Sep 17 00:00:00 2001 From: Teddy Xinyuan Chen <45612704+tddschn@users.noreply.github.com> Date: Thu, 25 May 2023 23:13:27 +0800 Subject: [PATCH 3/6] fix tests/test_cmd.py Signed-off-by: Teddy Xinyuan Chen <45612704+tddschn@users.noreply.github.com> --- tests/test_cmd.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tests/test_cmd.py b/tests/test_cmd.py index d64cec6..5d869c2 100644 --- a/tests/test_cmd.py +++ b/tests/test_cmd.py @@ -69,6 +69,9 @@ def mock_inference(self, params, serde): assert console_output.getvalue() == output_written_message except Exception as e: + raise e + + finally: # Resetting the sys.stdin # sys.stdin = sys.__stdin__ monkeypatch.undo() @@ -78,5 +81,3 @@ def mock_inference(self, params, serde): if os.path.exists(output_file): os.remove(output_file) - - raise e From 27f9868c4bf5348e4c801fc8fe88b9cf41b4fcec Mon Sep 17 00:00:00 2001 From: Teddy Xinyuan Chen <45612704+tddschn@users.noreply.github.com> Date: Thu, 25 May 2023 23:13:46 +0800 Subject: [PATCH 4/6] add tests/test_env.py Signed-off-by: Teddy Xinyuan Chen <45612704+tddschn@users.noreply.github.com> --- tests/test_env.py | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 tests/test_env.py diff --git a/tests/test_env.py b/tests/test_env.py new file mode 100644 index 0000000..17c1e4c --- /dev/null +++ b/tests/test_env.py @@ -0,0 +1,26 @@ +import os + +import pytest + +from modelz.env import EnvConfig + + +@pytest.fixture +def config(): + os.environ["MODELZ_API_KEY"] = "abc123" + os.environ["MODELZ_HOST"] = "https://custom.host/" + yield EnvConfig() + os.environ.pop("MODELZ_API_KEY") + os.environ.pop("MODELZ_HOST") + + +def test_update_from_env(config): + assert config.api_key == "abc123" + assert config.host == "https://custom.host/" + + +def test_default(): + with pytest.raises(AttributeError): + config = EnvConfig() + assert config.api_key is None + assert config.host == "https://{}.modelz.io/" From f80f96928db6d9ac570c93826162047d9f2659ec Mon Sep 17 00:00:00 2001 From: Teddy Xinyuan Chen <45612704+tddschn@users.noreply.github.com> Date: Fri, 26 May 2023 12:02:15 +0800 Subject: [PATCH 5/6] use tempfile in test_cmd Signed-off-by: Teddy Xinyuan Chen <45612704+tddschn@users.noreply.github.com> --- tests/test_cmd.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tests/test_cmd.py b/tests/test_cmd.py index 5d869c2..c9623c7 100644 --- a/tests/test_cmd.py +++ b/tests/test_cmd.py @@ -1,5 +1,6 @@ import sys from io import StringIO +import tempfile from unittest.mock import MagicMock from modelz.client import ModelzClient, ModelzResponse @@ -11,7 +12,9 @@ def test_inference(monkeypatch): # Mocking the behavior of `ModelzClient.inference` params_dict = {"key": "value"} params_as_saved_in_file = b"Mocked Response" + b" saved in file" - output_file = "output.bin" + # output_file = "output.bin" + # use a temp file instead + output_file = tempfile.NamedTemporaryFile().name output_written_message = f"result has been written in {output_file}\n" try: From 8b8f8415e64108004da18054b39230ab5025e5a2 Mon Sep 17 00:00:00 2001 From: Teddy Xinyuan Chen <45612704+tddschn@users.noreply.github.com> Date: Fri, 26 May 2023 12:02:17 +0800 Subject: [PATCH 6/6] format --- tests/test_cmd.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_cmd.py b/tests/test_cmd.py index c9623c7..2e615da 100644 --- a/tests/test_cmd.py +++ b/tests/test_cmd.py @@ -1,6 +1,6 @@ import sys -from io import StringIO import tempfile +from io import StringIO from unittest.mock import MagicMock from modelz.client import ModelzClient, ModelzResponse