Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Tests for core and cli modules #149

Merged
merged 80 commits into from
Nov 5, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
80 commits
Select commit Hold shift + click to select a range
fb8f90e
add two tests for core utils
strickvl Oct 26, 2021
9b19fec
Switch customise to customize [American]
strickvl Oct 26, 2021
5622c18
remove empty test file in wrong location
strickvl Oct 26, 2021
2077753
change spelling of customise -> customize
strickvl Oct 26, 2021
4bdd0fb
add test for component_factory
strickvl Oct 26, 2021
1dde009
add extra assertion for component_fact tests
strickvl Oct 26, 2021
cacce40
add cli base test
strickvl Oct 26, 2021
a66031a
refactor base test
strickvl Oct 27, 2021
d275b93
remove empty return docstring
strickvl Oct 27, 2021
09c88f7
undo renaming of customise_sources
strickvl Oct 27, 2021
eb8243b
add stubs for tests
strickvl Oct 27, 2021
bf4813f
add implementation todo
strickvl Oct 27, 2021
06cb86a
add stub tests for config
strickvl Oct 27, 2021
5d470ed
remove doublequoted comments
strickvl Oct 27, 2021
ea1d018
add stub tests for pipeline CLI
strickvl Oct 27, 2021
3084794
add stub tests for stack
strickvl Oct 27, 2021
534fba9
add stub tests for pipeline
strickvl Oct 27, 2021
1be061c
fix typo
strickvl Oct 27, 2021
3bc2dbe
add stub tests for cli utils
strickvl Oct 27, 2021
07c8f2d
Merge remote-tracking branch 'origin/main' into alex/ENG-44-tests-cor…
strickvl Oct 27, 2021
6a80726
add version test stubs
strickvl Oct 27, 2021
c729f33
merge origin/main
strickvl Oct 28, 2021
bc3a2ba
add more tests for example CLI
strickvl Oct 28, 2021
12a6222
remove testing for deleted version module
strickvl Oct 28, 2021
6c09eee
fix failing utils test
strickvl Oct 28, 2021
8b2e49b
add tests checking return of callable
strickvl Oct 28, 2021
884515a
add test for cli version
strickvl Oct 28, 2021
353f45c
Implement test for CLI group
strickvl Oct 28, 2021
7a2e28d
add test of metadata listing
strickvl Oct 28, 2021
13d933d
add better test for info
strickvl Oct 28, 2021
8132fb3
add new test
strickvl Oct 28, 2021
9b74e58
add possible refactorings for these config tests
strickvl Oct 28, 2021
d227163
test formatting of times and dates
strickvl Oct 28, 2021
118b586
add testing for parse_unknown_options function
strickvl Oct 28, 2021
4ffe771
fix typo in docstring
strickvl Oct 28, 2021
f538878
Add test
strickvl Oct 28, 2021
33398db
add another mapping_utils test
strickvl Oct 28, 2021
e2f336a
Fix failing test and remove comments
strickvl Oct 29, 2021
d431e3e
refactor imports
strickvl Oct 29, 2021
e59b41f
add type annotations to tests
strickvl Oct 29, 2021
2df978b
fix non-testing test
strickvl Oct 29, 2021
90ca98a
add two tests for core-repo
strickvl Oct 29, 2021
4057a93
add test checking local service is spun up
strickvl Oct 29, 2021
363d6b1
fix failing test
strickvl Oct 29, 2021
4b79a34
add test for initialization
strickvl Oct 29, 2021
bc17e5b
add test for creation of zen folder
strickvl Oct 29, 2021
274da2b
remove old tests relating to datasources
strickvl Oct 29, 2021
d2f5e54
fix failing test
strickvl Oct 29, 2021
9d84226
fix typo in gitwrapper class docstring
strickvl Oct 29, 2021
184e624
add test for get_git_wrapper
strickvl Oct 29, 2021
7e32ae3
add test to get active service
strickvl Oct 29, 2021
1aa4954
add several tests for core-repo
strickvl Oct 29, 2021
8e907ef
fix typo in local_service test
strickvl Oct 29, 2021
e2c44a8
add tests for local_service
strickvl Oct 29, 2021
1e72710
add testing for local_service
strickvl Oct 29, 2021
5df8a9d
add local_service tests
strickvl Oct 29, 2021
3d70ec9
Add test to check exception is raised
strickvl Oct 29, 2021
e18aee1
add artifact store tests
strickvl Oct 29, 2021
423d068
add CRUD tests for artifact store
strickvl Oct 29, 2021
2e7a9c8
add metadata store CRUD tests
strickvl Oct 29, 2021
7393d7e
add local_service tests
strickvl Nov 1, 2021
0a1c754
fix broken test
strickvl Nov 1, 2021
c3064b6
fix failing test
strickvl Nov 1, 2021
4b4dbcd
Merge remote-tracking branch 'origin/main' into alex/ENG-44-tests-cor…
strickvl Nov 4, 2021
6112000
clean up test comments
strickvl Nov 4, 2021
d68649a
add extra test for exception in cli base
strickvl Nov 4, 2021
e86cbc8
add test for dict content
strickvl Nov 4, 2021
164b273
add tests to check readme content
strickvl Nov 4, 2021
de1e18c
reword docstring
strickvl Nov 4, 2021
cf01120
add specific exception
strickvl Nov 4, 2021
51602c8
add specific exception
strickvl Nov 4, 2021
1c4915f
add specific exceptions
strickvl Nov 4, 2021
10f17aa
add todo for future refactor
strickvl Nov 4, 2021
48b9d20
refactor readme test and add markdown parser
strickvl Nov 4, 2021
4c63ab8
add extra test for new functionality
strickvl Nov 4, 2021
415acff
remove rich.markdown functionality
strickvl Nov 4, 2021
eb94030
remove the markdown parser completely
strickvl Nov 4, 2021
8ca413f
add warning message about redownload
strickvl Nov 5, 2021
f850ab9
Merge remote-tracking branch 'origin/main' into alex/ENG-44-tests-cor…
strickvl Nov 5, 2021
6d43400
fix broken tests around new metadata.py
strickvl Nov 5, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 0 additions & 3 deletions src/zenml/cli/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,9 +70,6 @@ def clean(yes: bool = False) -> None:

Args:
yes: bool: (Default value = False)

Returns:

"""
if not yes:
_ = confirmation(
Expand Down
1 change: 1 addition & 0 deletions src/zenml/cli/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ def logging() -> None:
)
def set_logging_verbosity(verbosity: str) -> None:
"""Set logging level"""
# TODO: [Medium] Implement this.
verbosity = verbosity.upper()
if verbosity not in LoggingLevels.__members__:
raise KeyError(
Expand Down
30 changes: 25 additions & 5 deletions src/zenml/cli/example.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@

class GitExamplesHandler(object):
def __init__(self, redownload: str = "") -> None:
"""Initialize the GitExamplesHandler class."""
self.clone_repo(redownload)

def clone_repo(self, redownload_version: str = "") -> None:
Expand Down Expand Up @@ -99,6 +100,11 @@ def clone_when_examples_already_cloned(
desired_version = parse(version)

if last_release < desired_version:
warning(
f"You tried to download {desired_version}."
f"The latest version you currently have available is {last_release}."
f"Recloning the repository from scratch to try to obtain {desired_version}"
)
self.delete_example_source_dir(str(local_dir_path))
self.clone_from_zero(GIT_REPO_URL, local_dir, str(desired_version))
else:
Expand All @@ -123,7 +129,11 @@ def get_all_examples(self) -> List[str]:
]

def get_example_readme(self, example_path: str) -> str:
"""Get the example README file contents."""
"""Get the example README file contents.

Raises:
FileNotFoundError: if the file doesn't exist.
"""
with open(os.path.join(example_path, "README.md")) as readme:
readme_content = readme.read()
return readme_content
Expand Down Expand Up @@ -171,7 +181,6 @@ def example() -> None:
def list(git_examples_handler: Any) -> None:
"""List all available examples."""
declare("Listing examples: \n")
# git_examples_handler.get_all_examples()
for name in git_examples_handler.get_all_examples():
declare(f"{name}")
declare("\nTo pull the examples, type: ")
Expand All @@ -184,12 +193,23 @@ def list(git_examples_handler: Any) -> None:
# TODO: [MEDIUM] Use a better type for the git_examples_handler
def info(git_examples_handler: Any, example_name: str) -> None:
"""Find out more about an example."""
# TODO: [MEDIUM] format the output so that it looks nicer (not a pure .md dump)
# TODO: [MEDIUM] fix markdown formatting so that it looks nicer (not a pure .md dump)
example_dir = os.path.join(
git_examples_handler.get_examples_dir(), example_name
)
readme_content = git_examples_handler.get_example_readme(example_dir)
click.echo(readme_content)
try:
readme_content = git_examples_handler.get_example_readme(example_dir)
click.echo(readme_content)
except FileNotFoundError:
if path_utils.file_exists(example_dir) and path_utils.is_dir(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice!

example_dir
):
error(f"No README.md file found in {example_dir}")
else:
error(
f"Example {example_name} is not one of the available options."
f"\nTo list all available examples, type: `zenml example list`"
)


@example.command(
Expand Down
26 changes: 13 additions & 13 deletions src/zenml/cli/pipeline.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
# # Copyright (c) ZenML GmbH 2020. All Rights Reserved.
# #
# # Licensed under the Apache License, Version 2.0 (the "License");
# # you may not use this file except in compliance with the License.
# # You may obtain a copy of the License at:
# #
# # http://www.apache.org/licenses/LICENSE-2.0
# #
# # Unless required by applicable law or agreed to in writing, software
# # distributed under the License is distributed on an "AS IS" BASIS,
# # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
# # or implied. See the License for the specific language governing
# # permissions and limitations under the License.
# Copyright (c) ZenML GmbH 2020. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at:
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
# or implied. See the License for the specific language governing
# permissions and limitations under the License.
"""CLI to interact with pipelines."""
import types
from typing import Any
Expand Down
2 changes: 1 addition & 1 deletion src/zenml/cli/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,7 @@ def format_timedelta(td: timedelta) -> str:


def parse_unknown_options(args: List[str]) -> Dict[str, Any]:
"""Parse unknown options from the cli.
"""Parse unknown options from the CLI.

Args:
args: A list of strings from the CLI.
Expand Down
2 changes: 1 addition & 1 deletion src/zenml/core/git_wrapper.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ class GitWrapper:

def __init__(self, repo_path: str):
"""
Initialize GitWrapper. Should be initialize by ZenML Repository.
Initialize GitWrapper. Should be initialized by ZenML Repository.
Args:
repo_path:

Expand Down
2 changes: 1 addition & 1 deletion src/zenml/core/mapping_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ class UUIDSourceTuple(BaseModel):


def get_key_from_uuid(uuid: UUID, mapping: Dict[str, UUIDSourceTuple]) -> str:
"""Return they key that points to a certain uuid in a mapping.
"""Return the key that points to a certain uuid in a mapping.

Args:
uuid: uuid to query.
Expand Down
Empty file removed src/zenml/core/repo_test.py
Empty file.
20 changes: 19 additions & 1 deletion tests/cli/test_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,19 +13,37 @@
# permissions and limitations under the License.

import os
from pathlib import Path

import pytest
from click.testing import CliRunner
from git import Repo

from zenml.cli.base import init
from zenml.cli.cli import cli
from zenml.core.constants import ZENML_DIR_NAME


def test_init_creates_zen_folder(tmp_path):
def test_init_creates_zen_folder(tmp_path: Path) -> None:
"""Check that init command creates a .zen folder inside temporary directory"""
runner = CliRunner()
Repo.init(tmp_path, mkdir=True)
repository_path = tmp_path
runner.invoke(init, ["--repo_path", str(repository_path)])
dir_files = os.listdir(repository_path)
assert ZENML_DIR_NAME in dir_files


def test_init_cli_command_fails_when_repo_not_git_repo(tmp_path: Path) -> None:
"""Ensure ZenML CLI fails when the given path is not a git repository"""
runner = CliRunner()
zen_fake_repo_path = tmp_path / ZENML_DIR_NAME
result = runner.invoke(init, ["--repo_path", str(zen_fake_repo_path)])
assert result.exit_code == 2
schustmi marked this conversation as resolved.
Show resolved Hide resolved


def test_init_raises_error_when_repo_not_git_repo(tmp_path: Path) -> None:
"""Ensure ZenML fails when the given path is not a git repository"""
zen_fake_repo_path = tmp_path / ZENML_DIR_NAME
with pytest.raises(Exception):
cli.init(str(zen_fake_repo_path))
9 changes: 5 additions & 4 deletions tests/cli/test_cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,11 @@
# or implied. See the License for the specific language governing
# permissions and limitations under the License.

from click.core import Group

def test_cli_command_defines_a_cli_group():
# TODO: [Medium] implement this test
"""Check that cli command defines a CLI group when invoked"""
from zenml.cli import cli


# TODO: [LOW] check that CLI command sets the logging verbosity
def test_cli_command_defines_a_cli_group() -> None:
"""Check that cli command defines a CLI group when invoked"""
assert isinstance(cli, Group)
20 changes: 18 additions & 2 deletions tests/cli/test_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,18 @@

import os

import pytest
from click import get_app_dir
from click.testing import CliRunner

from zenml.cli.config import opt_in, opt_out
from zenml.cli.config import opt_in, opt_out, set_logging_verbosity
from zenml.config.constants import GLOBAL_CONFIG_NAME
from zenml.config.global_config import GlobalConfig
from zenml.constants import APP_NAME
from zenml.constants import APP_NAME, ZENML_LOGGING_VERBOSITY
from zenml.utils.yaml_utils import read_json

NOT_LOGGING_LEVELS = ["abc", "my_cat_is_called_aria", "pipeline123"]


def read_global_config():
"""Read the global config file"""
Expand Down Expand Up @@ -61,3 +64,16 @@ def test_analytics_opt_out_amends_global_config():
assert result.exit_code == 0
assert not read_global_config()["analytics_opt_in"]
set_analytics_opt_in_status(pre_test_status)


@pytest.mark.parametrize("not_a_level", NOT_LOGGING_LEVELS)
def test_set_logging_verbosity_stops_when_not_real_level(
not_a_level: str,
) -> None:
"""Check that set_logging_verbosity doesn't run when no real level"""
# TODO: [Medium] replace the pytest params with hypothesis params
pre_test_logging_status = ZENML_LOGGING_VERBOSITY
runner = CliRunner()
result = runner.invoke(set_logging_verbosity, [not_a_level])
os.environ["ZENML_LOGGING_VERBOSITY"] = pre_test_logging_status
assert result.exit_code == 2
98 changes: 97 additions & 1 deletion tests/cli/test_example.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,17 +12,26 @@
# or implied. See the License for the specific language governing
# permissions and limitations under the License.

import os

import click
import pytest
from click.testing import CliRunner
from git.repo.base import Repo

from zenml import __version__ as running_zenml_version
from zenml.cli.example import info, list, pull
from zenml.cli.example import EXAMPLES_GITHUB_REPO, info, list, pull
from zenml.constants import APP_NAME
from zenml.logger import get_logger

# from hypothesis import given
# from hypothesis.strategies import text


logger = get_logger(__name__)

ZERO_FIVE_RELEASE_EXAMPLES = ["airflow", "legacy", "quickstart"]
NOT_ZERO_FIVE_RELEASE_EXAMPLES = ["not_airflow", "not_legacy", "not_quickstart"]
BAD_VERSIONS = ["aaa", "999999", "111111"]


Expand Down Expand Up @@ -95,3 +104,90 @@ def test_pull_of_bad_version_when_valid_version_already_exists(
runner.invoke(pull, ["-f", "-v", "0.5.1"])
result = runner.invoke(pull, ["-f", "-v", bad_version])
assert result.exit_code != 0


def test_pull_without_any_flags_should_exit_without_errors() -> None:
"""Check pull command exits without errors"""
runner = CliRunner()
with runner.isolated_filesystem():
result1 = runner.invoke(pull)
assert result1.exit_code == 0


@pytest.mark.parametrize("example", ZERO_FIVE_RELEASE_EXAMPLES)
def test_info_echos_out_readme_content(example: str) -> None:
"""Check that info subcommand displays readme content"""
# TODO: [LOW] make test handle rich markdown output
runner = CliRunner()
with runner.isolated_filesystem():
# setup the test
runner.invoke(pull, ["-f", "-v", "0.5.0"])

# get path variables
repo_dir = click.get_app_dir(APP_NAME)
examples_dir = os.path.join(repo_dir, EXAMPLES_GITHUB_REPO, "examples")
readme_path = os.path.join(examples_dir, example, "README.md")

result = runner.invoke(info, [example])
assert result.exit_code == 0
assert example in result.output
schustmi marked this conversation as resolved.
Show resolved Hide resolved
with open(readme_path) as f:
for line in f.read().splitlines():
assert line in result.output
examples_dir = os.path.join(os.getcwd(), EXAMPLES_GITHUB_REPO)
assert example in os.listdir(examples_dir)


@pytest.mark.parametrize("bad_example", NOT_ZERO_FIVE_RELEASE_EXAMPLES)
def test_info_fails_gracefully_when_bad_example_given(
tmp_path: str, bad_example: str
) -> None:
"""Check info command fails gracefully when bad example given"""
runner = CliRunner()
with runner.isolated_filesystem(tmp_path):
runner.invoke(pull, ["-f", "-v", "0.5.0"])
result = runner.invoke(info, [bad_example])
assert (
f"Example {bad_example} is not one of the available options."
in result.output
)
assert bad_example not in os.listdir(tmp_path)


@pytest.mark.parametrize("bad_example", NOT_ZERO_FIVE_RELEASE_EXAMPLES)
def test_info_fails_gracefully_when_no_readme_present(
tmp_path: str, bad_example: str
) -> None:
"""Check info command fails gracefully when bad example given"""
# get path variables
repo_dir = click.get_app_dir(APP_NAME)
examples_dir = os.path.join(repo_dir, EXAMPLES_GITHUB_REPO, "examples")

runner = CliRunner()
with runner.isolated_filesystem(tmp_path):
runner.invoke(pull, ["-f", "-v", "0.5.0"])
fake_example_path = os.path.join(examples_dir, bad_example)
os.mkdir(fake_example_path)
result = runner.invoke(info, [bad_example])
assert "No README.md file found" in result.output
os.rmdir(fake_example_path)


def test_user_has_latest_zero_five_version_but_wants_zero_five_one():
"""Test the scenario where the latest version available to the user is 0.5.0
but the user wants to download 0.5.1. In this case, it should redownload
and try to checkout the desired version."""
runner = CliRunner()
with runner.isolated_filesystem():
# save the repository currently on the local system
current_saved_global_examples_path = os.path.join(
click.get_app_dir(APP_NAME), EXAMPLES_GITHUB_REPO
)
current_saved_global_examples_repo = Repo(
current_saved_global_examples_path
)
# reset the repo such that it has 0.5.0 as the latest version
current_saved_global_examples_repo.git.reset("--hard", "0.5.0")
runner.invoke(pull, ["-f", "-v", "0.5.1"])
result = runner.invoke(list)
assert "airflow_local" in result.output
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't this call raise an error somehow if the version does not exist?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@schustmi I didn't understand this. Do you mean that we should add another test to catch this condition (i.e. if the version doesn't exist) or that the currently-written test is doing something unexpected?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure actually how this should be handled, maybe a warning message that the requested version does not exists and that we fallback to the latest one?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@alex-zenml wdyt?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've added a warning message.

Loading