Skip to content

Commit

Permalink
Tests for config file (#99)
Browse files Browse the repository at this point in the history
* fixes issue #38

* added example tests - one failing

* added more tests

* added more tests

* update purge config

* added another test

* start stub for get config test

* added test for get_config

* added a new test for write_config

* update init tests

* add test for config manager init

* updated CHANGELOG and version, added function descriptions to config_test

* update minor formatting

* update changelog

* update changelog

Co-authored-by: Faiyaz Hasan <[email protected]>
  • Loading branch information
HaimHorowitzAgnostiq and FyzHsn authored Feb 11, 2022
1 parent 5a3a1c2 commit ab0a659
Show file tree
Hide file tree
Showing 5 changed files with 201 additions and 5 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [0.24.13] - 2022-02-11

### Added

- Tests for covalent/_shared_files/config.py

## [0.24.12] - 2022-02-10

### Added
Expand Down
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
0.24.12
0.24.13
3 changes: 2 additions & 1 deletion covalent/_shared_files/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,8 @@ def purge_config(self) -> None:
None
"""

shutil.rmtree(os.path.dirname(self.config_file), ignore_errors=True)
dir_name = os.path.dirname(self.config_file)
shutil.rmtree(dir_name, ignore_errors=True)

def get(self, key: str) -> Any:
"""
Expand Down
Empty file.
195 changes: 192 additions & 3 deletions tests/covalent_tests/shared_files/config_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,16 +19,82 @@
# Relief from the License may be granted by purchasing a commercial license.

import os
import tempfile
from unittest.mock import patch

from covalent._shared_files.config import _ConfigManager
import pytest
import toml

from covalent._shared_files.config import _ConfigManager, get_config, reload_config, set_config
from covalent._shared_files.defaults import _DEFAULT_CONFIG

CONFIG_DIR = os.path.join(os.path.dirname(__file__), "test_files")


@pytest.mark.parametrize(
"dir_env,conf_dir",
[
("COVALENT_CONFIG_DIR", "covalent/covalent.conf"),
("XDG_CONFIG_DIR", "covalent/covalent.conf"),
("HOME", ".config/covalent/covalent.conf"),
],
)
def test_config_manager_init_directory_setting(monkeypatch, dir_env, conf_dir):
"""Test the init method for the config manager."""

with tempfile.TemporaryDirectory() as tmp_dir:
monkeypatch.setenv(dir_env, tmp_dir)
cm = _ConfigManager()
assert cm.config_file == f"{tmp_dir}/{conf_dir}"


@pytest.mark.parametrize(
"path_exists,write_config_called,update_config_called",
[(False, True, False), (True, False, True)],
)
def test_config_manager_init_write_update_config(
mocker, monkeypatch, path_exists, write_config_called, update_config_called
):
"""Test the init method for the config manager."""

config_keys = [
"sdk.log_dir",
"dispatcher.cache_dir",
"dispatcher.results_dir",
"dispatcher.log_dir",
"user_interface.log_dir",
]

with tempfile.TemporaryDirectory() as tmp_dir:
monkeypatch.setenv("COVALENT_CONFIG_DIR", tmp_dir)
update_config_mock = mocker.patch(
"covalent._shared_files.config._ConfigManager.update_config"
)
write_config_mock = mocker.patch(
"covalent._shared_files.config._ConfigManager.write_config"
)
get_mock = mocker.patch(
"covalent._shared_files.config._ConfigManager.get", side_effect=config_keys
)
path_mock = mocker.patch("pathlib.Path.__init__", return_value=None)

mocker.patch("os.path.exists", return_value=path_exists)

cm = _ConfigManager()
assert hasattr(cm, "config_data")
assert write_config_mock.called is write_config_called
assert update_config_mock.called is update_config_called

get_mock_calls = get_mock.mock_calls
path_mock_calls = path_mock.mock_calls

for key in config_keys:
assert mocker.call(key) in get_mock_calls and path_mock_calls


@patch.dict(os.environ, {"COVALENT_CONFIG_DIR": CONFIG_DIR}, clear=True)
def test_read_config():
"""Test that configuration file is properly read"""
"""Test that configuration file is read properly."""

config_manager = _ConfigManager()
config_manager.read_config()
Expand Down Expand Up @@ -57,7 +123,7 @@ def test_read_config():

@patch.dict(os.environ, {"COVALENT_CONFIG_DIR": CONFIG_DIR}, clear=True)
def test_update_config():
"""Test that updating the existing config data with the config file works"""
"""Test that updating the existing config data with the config file works."""

config_manager = _ConfigManager()
config_manager.config_data = {
Expand Down Expand Up @@ -125,3 +191,126 @@ def test_update_config():
}

assert config_manager.config_data == expected_dict


def test_set_config_str_key(mocker):
"""Test the set_config method when the input is a string."""

cm_set_mock = mocker.patch("covalent._shared_files.config._config_manager.set")
cm_write_config = mocker.patch("covalent._shared_files.config._config_manager.write_config")
set_config("mock_section.mock_variable", "mock_value")
cm_set_mock.assert_called_once_with("mock_section.mock_variable", "mock_value")
cm_write_config.assert_called_once_with()


def test_set_config_dict_key(mocker):
"""Test the set_config method when the input is a dictionary."""

cm_set_mock = mocker.patch("covalent._shared_files.config._config_manager.set")
cm_write_config = mocker.patch("covalent._shared_files.config._config_manager.write_config")
set_config({"mock_section.mock_variable": "mock_value"})
cm_set_mock.assert_called_once_with("mock_section.mock_variable", "mock_value")
cm_write_config.assert_called_once_with()


def test_generate_default_config(mocker):
"""Tests that the default configuration was loaded."""

cm = _ConfigManager()
cm_deepcopy_mock = mocker.patch("covalent._shared_files.config.copy.deepcopy", return_value={})

cm.generate_default_config()
cm_deepcopy_mock.assert_called_once_with(_DEFAULT_CONFIG)
assert cm.config_data == _DEFAULT_CONFIG


def test_read_config(mocker):
"""Test the read_config method for the config manager."""

cm = _ConfigManager()
test_data = {"test": "test"}
toml_load_mock = mocker.patch(
"covalent._shared_files.config.toml.load", return_value=test_data
)
cm.read_config()
toml_load_mock.assert_called_with(cm.config_file)
assert cm.config_data == test_data


def test_get():
"""Test the get method for the config manager."""

cm = _ConfigManager()

assert cm.get("dispatcher.port") == cm.config_data["dispatcher"]["port"]


def test_generate_default_config():
"""Test that the default configuration was loaded."""

cm = _ConfigManager()
cm.generate_default_config()
assert cm.config_data == _DEFAULT_CONFIG
assert cm.config_data is not _DEFAULT_CONFIG


def test_reload_config(mocker):
"""Test the reload_config method."""

cm_read_config = mocker.patch("covalent._shared_files.config._config_manager.read_config")
reload_config()
cm_read_config.assert_called_once_with()


def test_purge_config(mocker):
"""Test the purge_config method for config manager."""

cm = _ConfigManager()
os_dir_mock = mocker.patch(
"covalent._shared_files.config.os.path.dirname", return_value="mock_dir"
)
rmtree_mock = mocker.patch("covalent._shared_files.config.shutil.rmtree")
cm.purge_config()
os_dir_mock.assert_called_once_with(cm.config_file)
rmtree_mock.assert_called_once_with("mock_dir", ignore_errors=True)


def test_get_config():
"""Test config retrieval function."""

from covalent._shared_files.config import _config_manager

# Case 1 - Empty list
assert get_config(entries=[]) == _config_manager.config_data

# Case 2 - List with one item
assert (
get_config(entries=["dispatcher.port"])
== _config_manager.config_data["dispatcher"]["port"]
)

# Case 3 - String
assert (
get_config(entries="dispatcher.port") == _config_manager.config_data["dispatcher"]["port"]
)

# Case 4 - List with > 1 items

test_list = ["dispatcher.address", "dispatcher.port"]

assert get_config(entries=test_list) == {
"dispatcher.address": _config_manager.config_data["dispatcher"]["address"],
"dispatcher.port": _config_manager.config_data["dispatcher"]["port"],
}


def test_write_config(mocker):
"""Test the write_config method for config manager."""

cm = _ConfigManager()
toml_dump_mock = mocker.patch("covalent._shared_files.config.toml.dump")
open_mock = mocker.patch("covalent._shared_files.config.open")
mock_file = open_mock.return_value.__enter__.return_value
cm.write_config()
toml_dump_mock.assert_called_once_with(cm.config_data, mock_file)
open_mock.assert_called_once_with(cm.config_file, "w")

0 comments on commit ab0a659

Please sign in to comment.