From 2b81986c7dab4bb556707299a3d8072f10167459 Mon Sep 17 00:00:00 2001 From: Serhii Koropets <33310880+koropets@users.noreply.github.com> Date: Thu, 13 Apr 2023 17:41:34 +0300 Subject: [PATCH] Update gordo-core and gordo-client (#1313) * Update gordo-core and gordo-client * Update README.md * Update scripts/tests.sh * asset_ calls for mocks * ModelBuilder should not call report. report has called from cli build command * Black reformating * Fix test_gunicorn_execution_hosts * black reformating --- README.md | 4 +- requirements/full_requirements.txt | 47 ++++++++------- requirements/mlflow_requirements.in | 2 +- requirements/requirements.in | 5 +- requirements/test_requirements.in | 11 ++-- requirements/test_requirements.txt | 29 +++++---- scripts/tests.sh | 4 +- tests/gordo/builder/test_builder.py | 11 ---- tests/gordo/cli/test_cli.py | 59 ++++++++++++------- tests/gordo/reporters/test_mlflow_reporter.py | 2 +- tests/gordo/server/test_gordo_server.py | 2 +- 11 files changed, 93 insertions(+), 83 deletions(-) diff --git a/README.md b/README.md index d71b48c7d..adfb2e4a1 100644 --- a/README.md +++ b/README.md @@ -29,9 +29,9 @@ Gordo fulfills the role of inhaling config files and supplying components to the ## Components -* [gordo-controller](https://github.com/equinor/gordo-controller/) - Kubernetes controller for the Gordo CRD. +* [gordo-controller](https://github.com/equinor/gordo-controller/) - Kubernetes controller for the Gordo CRDs. * [gordo-core](https://github.com/equinor/gordo-core/) - Gordo core library. -* [gordo-client](https://github.com/equinor/gordo-client/) - Gordo server's client. It is able to make predictions from deployed models. +* [gordo-client](https://github.com/equinor/gordo-client/) - Gordo server's client. It can make predictions from deployed models. --- ## Install diff --git a/requirements/full_requirements.txt b/requirements/full_requirements.txt index c0fe3f66c..448370157 100644 --- a/requirements/full_requirements.txt +++ b/requirements/full_requirements.txt @@ -12,7 +12,7 @@ adal==1.2.7 # via # azureml-core # msrestazure -alembic==1.10.2 +alembic==1.10.3 # via mlflow argcomplete==2.1.2 # via @@ -29,7 +29,7 @@ azure-common==1.1.28 # azure-mgmt-resource # azure-mgmt-storage # azureml-core -azure-core==1.26.3 +azure-core==1.26.4 # via # azure-mgmt-core # azureml-core @@ -40,20 +40,20 @@ azure-mgmt-authorization==3.0.0 # via azureml-core azure-mgmt-containerregistry==10.1.0 # via azureml-core -azure-mgmt-core==1.3.2 +azure-mgmt-core==1.4.0 # via # azure-mgmt-authorization # azure-mgmt-containerregistry # azure-mgmt-keyvault # azure-mgmt-resource # azure-mgmt-storage -azure-mgmt-keyvault==10.1.0 +azure-mgmt-keyvault==10.2.1 # via azureml-core -azure-mgmt-resource==21.2.1 +azure-mgmt-resource==22.0.0 # via azureml-core -azure-mgmt-storage==20.1.0 +azure-mgmt-storage==21.0.0 # via azureml-core -azureml-core==1.49.0 +azureml-core==1.50.0 # via -r mlflow_requirements.in backports-tempfile==1.0 # via azureml-core @@ -128,7 +128,7 @@ gitdb==4.0.10 # via gitpython gitpython==3.1.31 # via mlflow -google-auth==2.17.1 +google-auth==2.17.3 # via # google-auth-oauthlib # tensorboard @@ -136,9 +136,9 @@ google-auth-oauthlib==1.0.0 # via tensorboard google-pasta==0.2.0 # via tensorflow -gordo-client==6.2.0rc0 +gordo-client==6.2.0 # via -r requirements.in -gordo-core==0.3.0rc0 +gordo-core==0.3.0 # via # -r requirements.in # gordo-client @@ -162,7 +162,7 @@ humanfriendly==10.0 # via azureml-core idna==3.4 # via requests -importlib-metadata==6.1.0 +importlib-metadata==6.3.0 # via # flask # markdown @@ -172,7 +172,9 @@ importlib-resources==5.12.0 influxdb==5.3.1 # via gordo-core isodate==0.6.1 - # via msrest + # via + # azure-mgmt-keyvault + # msrest itsdangerous==2.1.2 # via flask jax==0.4.8 @@ -190,7 +192,7 @@ jmespath==1.0.1 # knack joblib==1.2.0 # via scikit-learn -jsonpickle==2.2.0 +jsonpickle==3.0.1 # via azureml-core keras==2.12.0 # via tensorflow @@ -210,7 +212,6 @@ markdown==3.4.3 # tensorboard markupsafe==2.1.2 # via - # -r requirements.in # jinja2 # mako # werkzeug @@ -224,7 +225,7 @@ matplotlib==3.7.1 # via # catboost # mlflow -ml-dtypes==0.0.4 +ml-dtypes==0.1.0 # via jax mlflow==2.2.2 # via -r mlflow_requirements.in @@ -241,7 +242,6 @@ msrest==0.7.1 # azure-graphrbac # azure-mgmt-authorization # azure-mgmt-containerregistry - # azure-mgmt-keyvault # azure-mgmt-resource # azure-mgmt-storage # azureml-core @@ -306,7 +306,7 @@ pandas==1.5.3 # mlflow # shap # xarray -paramiko==2.12.0 +paramiko==3.1.0 # via azureml-core pathspec==0.11.1 # via azureml-core @@ -316,18 +316,18 @@ pillow==9.5.0 # via matplotlib pkginfo==1.9.6 # via azureml-core -plotly==5.14.0 +plotly==5.14.1 # via catboost portalocker==2.7.0 # via msal-extensions prometheus-client==0.16.0 # via -r requirements.in -protobuf==4.22.1 +protobuf==4.22.3 # via # mlflow # tensorboard # tensorflow -psycopg2-binary==2.9.5 +psycopg2-binary==2.9.6 # via -r postgres_requirements.in pyarrow==10.0.1 # via @@ -344,7 +344,7 @@ pycparser==2.21 # via cffi pydantic==1.10.7 # via gordo-client -pygments==2.14.0 +pygments==2.15.0 # via knack pyjwt[crypto]==2.6.0 # via @@ -421,7 +421,7 @@ secretstorage==3.3.3 # via azureml-core shap==0.41.0 # via mlflow -simplejson==3.18.4 +simplejson==3.19.1 # via # -r requirements.in # gordo-client @@ -436,7 +436,6 @@ six==1.16.0 # influxdb # isodate # msrestazure - # paramiko # python-dateutil # querystring-parser # tensorflow @@ -444,7 +443,7 @@ slicer==0.0.7 # via shap smmap==5.0.0 # via gitdb -sqlalchemy==2.0.8 +sqlalchemy==2.0.9 # via # alembic # mlflow diff --git a/requirements/mlflow_requirements.in b/requirements/mlflow_requirements.in index ae42db20d..e33f62d68 100644 --- a/requirements/mlflow_requirements.in +++ b/requirements/mlflow_requirements.in @@ -1,2 +1,2 @@ -mlflow~=2.2.2 +mlflow~=2.2 azureml-core~=1.49 diff --git a/requirements/requirements.in b/requirements/requirements.in index 5dbf3d466..bdbebc043 100644 --- a/requirements/requirements.in +++ b/requirements/requirements.in @@ -11,6 +11,5 @@ catboost~=1.1.1 prometheus_client~=0.7 # Due to azureml-core 1.49.0 depends on packaging<22.0 packaging>=21.0,<22.0 -gordo-client==6.2.0rc0 -gordo-core==0.3.0rc0 -MarkupSafe>=2.1.2,<3.0.0 +gordo-client==6.2.0 +gordo-core==0.3.0 diff --git a/requirements/test_requirements.in b/requirements/test_requirements.in index 8d0be0d61..5cf7692a9 100644 --- a/requirements/test_requirements.in +++ b/requirements/test_requirements.in @@ -3,18 +3,17 @@ docker>=4.0,<7.0 pytest~=7.2 pytest-xdist~=3.2 pytest-mock~=3.6 -pytest-mypy~=0.9 +pytest-mypy~=0.10 pytest-timeout~=2.1 pytest-cov~=4.0 pytest-benchmark~=4.0 -mock~=4.0 -responses~=0.13 +pytest-flakes~=4.0 +mock~=5.0 +responses~=0.23 # Due to packaging>22.0 in black 23.0, azureml-core~=1.49 requires packaging<22.0 black>=22.0,<23.0 -pytest-flakes~=4.0 notebook~=6.4 -# Due to jinja2>=3.0 from nbconvert==6.5.3 -nbconvert>=6.0,<6.5.0 +nbconvert~=6.5 types-simplejson types-python-dateutil types-PyYAML diff --git a/requirements/test_requirements.txt b/requirements/test_requirements.txt index a2d8c66c3..210658aca 100644 --- a/requirements/test_requirements.txt +++ b/requirements/test_requirements.txt @@ -120,6 +120,8 @@ jupyter-server==1.21.0 # notebook-shim jupyterlab-pygments==0.2.2 # via nbconvert +lxml==4.9.2 + # via nbconvert markupsafe==2.1.2 # via # -c full_requirements.txt @@ -131,7 +133,7 @@ matplotlib-inline==0.1.6 # ipython mistune==0.8.4 # via nbconvert -mock==4.0.3 +mock==5.0.1 # via -r test_requirements.in mypy==0.982 # via pytest-mypy @@ -144,7 +146,7 @@ nbclassic==0.4.8 # via notebook nbclient==0.5.13 # via nbconvert -nbconvert==6.4.5 +nbconvert==6.5.4 # via # -r test_requirements.in # jupyter-server @@ -174,6 +176,7 @@ packaging==21.3 # docker # ipykernel # jupyter-server + # nbconvert # pytest pandocfilters==1.5.0 # via nbconvert @@ -215,7 +218,7 @@ pycparser==2.21 # cffi pyflakes==2.5.0 # via pytest-flakes -pygments==2.14.0 +pygments==2.15.0 # via # -c full_requirements.txt # ipython @@ -258,6 +261,10 @@ python-dateutil==2.8.2 # via # -c full_requirements.txt # jupyter-client +pyyaml==5.4.1 + # via + # -c full_requirements.txt + # responses pyzmq==24.0.1 # via # ipykernel @@ -270,7 +277,7 @@ requests[socks]==2.28.2 # -c full_requirements.txt # docker # responses -responses==0.22.0 +responses==0.23.1 # via -r test_requirements.in send2trash==1.8.0 # via @@ -293,10 +300,8 @@ terminado==0.17.0 # jupyter-server # nbclassic # notebook -testpath==0.6.0 +tinycss2==1.2.1 # via nbconvert -toml==0.10.2 - # via responses tomli==1.2.3 # via # black @@ -331,15 +336,15 @@ types-python-dateutil==2.8.19.2 types-pytz==2022.6.0.1 # via -r test_requirements.in types-pyyaml==6.0.12.1 - # via -r test_requirements.in + # via + # -r test_requirements.in + # responses types-requests==2.28.11.2 # via -r test_requirements.in types-setuptools==65.5.0.2 # via -r test_requirements.in types-simplejson==3.17.7.1 # via -r test_requirements.in -types-toml==0.10.8 - # via responses types-urllib3==1.26.25.1 # via types-requests typing-extensions==4.5.0 @@ -356,7 +361,9 @@ urllib3==1.26.15 wcwidth==0.2.5 # via prompt-toolkit webencodings==0.5.1 - # via bleach + # via + # bleach + # tinycss2 websocket-client==1.5.1 # via # -c full_requirements.txt diff --git a/scripts/tests.sh b/scripts/tests.sh index bd856f318..247fc28d2 100644 --- a/scripts/tests.sh +++ b/scripts/tests.sh @@ -8,7 +8,7 @@ function show_help() { echo "Runs CI pytest action." echo echo "-n uses xdist to speedup slow-running tests" - echo "-p export PYTHONPATH=. environment variable. Helpful when gordo is not being installed in the system" + echo "-p export PYTHONPATH=. environment variable. Helpful when gordo is not installed in the system" echo "-h display this help and exit" exit $1 } @@ -98,7 +98,7 @@ case "$action" in pytest --benchmark-only benchmarks/ ;; *) - echo "Wrong action '$action'." 1>&2 + echo "Wrong action \"$action\"." 1>&2 show_help 2 ;; esac diff --git a/tests/gordo/builder/test_builder.py b/tests/gordo/builder/test_builder.py index b65ab8cd9..b96198436 100644 --- a/tests/gordo/builder/test_builder.py +++ b/tests/gordo/builder/test_builder.py @@ -746,14 +746,3 @@ def test_n_splits_from_config(mocked_pipeline_from_definition, cv): mocked_pipeline_from_definition.assert_called_with( {"sklearn.model_selection.TimeSeriesSplit": {"n_splits": 3}} ) - - -@patch("gordo.machine.Machine.report") -def test_builder_calls_machine_report(mocked_report_method, metadata): - """ - When building a machine, the Modelbuilder.build should call Machine.report() - so that it can run any reporters in the Machine's runtime. - """ - machine = Machine.from_dict(metadata) - ModelBuilder(machine).build() - assert mocked_report_method.called_once() diff --git a/tests/gordo/cli/test_cli.py b/tests/gordo/cli/test_cli.py index f1e5393cc..c1ead8e0d 100644 --- a/tests/gordo/cli/test_cli.py +++ b/tests/gordo/cli/test_cli.py @@ -2,6 +2,7 @@ import pytest import logging import re +import copy from click.testing import CliRunner from unittest import mock @@ -403,28 +404,39 @@ def test_mlflow_reporter_set_cli_build( assert not mock_get_spauth_kwargs.called +DEFAULT_EXPECTED_KWARGS = { + "config_module": None, + "worker_connections": 50, + "threads": 8, + "worker_class": "gthread", + "server_app": "gordo.server.server:build_app()", +} + + @pytest.mark.parametrize( - "arg,value,exception_expected", + "arg,expected_args,expected_kwargs,exception_expected", [ # Valid values - ("--host", "0.0.0.0", False), - ("--host", "127.0.0.0", False), - ("--port", 5555, False), - ("--workers", 1, False), - ("--log-level", "info", False), - ("--log-level", "debug", False), + (["--host", "0.0.0.0"], ["0.0.0.0", 5555, 2, "debug"], {}, False), + (["--host", "127.0.0.0"], ["127.0.0.0", 5555, 2, "debug"], {}, False), + (["--port", 5555], ["0.0.0.0", 5555, 2, "debug"], {}, False), + (["--workers", 1], ["0.0.0.0", 5555, 1, "debug"], {}, False), + (["--log-level", "info"], ["0.0.0.0", 5555, 2, "info"], {}, False), + (["--log-level", "debug"], ["0.0.0.0", 5555, 2, "debug"], {}, False), + (["--threads", 4], ["0.0.0.0", 5555, 2, "debug"], {"threads": 4}, False), + (["--worker-class", "gthread"], ["0.0.0.0", 5555, 2, "debug"], {}, False), # Invalid values - ("--host", "0.0.0", True), - ("--port", 0, True), - ("--port", 70000, True), - ("--workers", -1, True), - ("--threads", 4, False), - ("--threads", "auto", True), - ("--worker-class", "gthread", False), - ("--log-level", "badlevel", True), + (["--host", "0.0.0"], None, None, True), + (["--port", 0], None, None, True), + (["--port", 70000], None, None, True), + (["--workers", -1], None, None, True), + (["--threads", "auto"], None, None, True), + (["--log-level", "badlevel"], None, None, True), ], ) -def test_gunicorn_execution_hosts(runner, arg, value, exception_expected): +def test_gunicorn_execution_hosts( + runner, arg, expected_args, expected_kwargs, exception_expected +): """ Test the validation of input parameters to the `run_server` function via the gordo cli """ @@ -433,12 +445,17 @@ def test_gunicorn_execution_hosts(runner, arg, value, exception_expected): "gordo.server.server.run_server", mock.MagicMock(return_value=None, autospec=True), ) as m: - result = runner.invoke(cli.gordo, ["run-server", arg, value]) + result = runner.invoke(cli.gordo, ["run-server", *arg]) - assert ( - (result.exit_code != 0) if exception_expected else (result.exit_code == 0) - ) - assert m.called_once_with(value) + if result.exit_code != 0: + if not exception_expected: + raise AssertionError("Process exit code equal to %d" % result.exit_code) + else: + if exception_expected: + raise AssertionError("Process succeeded") + kwargs = copy.copy(DEFAULT_EXPECTED_KWARGS) + kwargs.update(expected_kwargs) + m.assert_called_once_with(*expected_args, **kwargs) def test_log_level_cli(): diff --git a/tests/gordo/reporters/test_mlflow_reporter.py b/tests/gordo/reporters/test_mlflow_reporter.py index 8b71066e1..0f9b65e27 100644 --- a/tests/gordo/reporters/test_mlflow_reporter.py +++ b/tests/gordo/reporters/test_mlflow_reporter.py @@ -79,7 +79,7 @@ def test_get_mlflow_client( assert MockInteractiveAuth.call_count == n_interactive assert MockSPAuth.call_count == n_spauth assert MockWorkspace.call_count == n_get_uri - assert MockClient.called_once() + MockClient.assert_called_once() @mock.patch("gordo.reporters.mlflow.InteractiveLoginAuthentication") diff --git a/tests/gordo/server/test_gordo_server.py b/tests/gordo/server/test_gordo_server.py index 2103805bd..e9fc71b98 100644 --- a/tests/gordo/server/test_gordo_server.py +++ b/tests/gordo/server/test_gordo_server.py @@ -244,7 +244,7 @@ def listdir_fail(*args, **kwargs): client = app.test_client() resp = client.get("/gordo/v0/test-project/revisions") - assert mocked_listdir.called_once() + mocked_listdir.assert_called_once() assert set(resp.json.keys()) == {"latest", "available-revisions", "revision"} assert resp.json["latest"] == expected_revision assert isinstance(resp.json["available-revisions"], list)