From 987960579619467f68edbe07a421fd30baaafded Mon Sep 17 00:00:00 2001 From: Daniel McKnight <34697904+NeonDaniel@users.noreply.github.com> Date: Wed, 6 Jul 2022 11:09:50 -0700 Subject: [PATCH] Fix circular imports and refactor submodules (#8) * Fix circular imports Add unit tests of `locations` module Refactor modules for clarity * Fix bugs in tests * Update test patches to use new import locations * Troubleshooting config test failures * Add mycroft.conf to package_data * Troubleshooting GH actions failures * Remove failing test case * Fix test mock for Pytest compat. * Refactor `meta_config` to `meta` Drop `base` backwards-compat wrapper * Fix typo in log Co-authored-by: Daniel McKnight --- ovos_config/__init__.py | 2 +- ovos_config/config.py | 2 +- ovos_config/locations.py | 32 +-- ovos_config/meta.py | 211 +++++++++++++++++ ovos_config/{base.py => models.py} | 0 ovos_config/ovos.py | 213 +----------------- setup.py | 1 + .../mycroft/configuration/mycroft.conf | 0 test/unittests/test_configuration.py | 6 +- test/unittests/test_locations.py | 105 +++++++++ 10 files changed, 343 insertions(+), 229 deletions(-) create mode 100644 ovos_config/meta.py rename ovos_config/{base.py => models.py} (100%) create mode 100644 test/unittests/mycroft/configuration/mycroft.conf create mode 100644 test/unittests/test_locations.py diff --git a/ovos_config/__init__.py b/ovos_config/__init__.py index b2c3784..0c5fb07 100644 --- a/ovos_config/__init__.py +++ b/ovos_config/__init__.py @@ -3,4 +3,4 @@ set_default_tz, set_default_lang, get_default_tz, get_default_lang, \ get_config_tz, get_primary_lang_code, load_languages, load_language from ovos_config.locations import SYSTEM_CONFIG, USER_CONFIG, DEFAULT_CONFIG, get_xdg_config_locations -from ovos_config.ovos import get_ovos_config +from ovos_config.meta import get_ovos_config diff --git a/ovos_config/config.py b/ovos_config/config.py index cc4fbb8..ee9d92e 100644 --- a/ovos_config/config.py +++ b/ovos_config/config.py @@ -18,7 +18,7 @@ from mycroft_bus_client import Message -from ovos_config.base import LocalConf, MycroftDefaultConfig, MycroftSystemConfig, MycroftUserConfig, RemoteConf +from ovos_config.models import LocalConf, MycroftDefaultConfig, MycroftSystemConfig, MycroftUserConfig, RemoteConf from ovos_config.locations import OLD_USER_CONFIG, get_xdg_config_save_path, get_xdg_config_locations from ovos_config.utils import FileWatcher diff --git a/ovos_config/locations.py b/ovos_config/locations.py index bfb73b8..12f4735 100644 --- a/ovos_config/locations.py +++ b/ovos_config/locations.py @@ -14,45 +14,45 @@ import os from os.path import join, dirname, expanduser, exists, isfile from time import sleep -from ovos_utils.system import search_mycroft_core_location, is_running_from_module -from ovos_config.ovos import get_xdg_base, is_using_xdg, get_config_filename, get_ovos_config +from ovos_utils.system import search_mycroft_core_location +import ovos_config.meta as _ovos_config from ovos_utils.xdg_utils import xdg_config_dirs, xdg_config_home, xdg_data_dirs, xdg_data_home, xdg_cache_home def get_xdg_config_dirs(folder=None): """ return list of possible XDG config dirs taking into account ovos.conf """ - folder = folder or get_xdg_base() + folder = folder or _ovos_config.get_xdg_base() xdg_dirs = xdg_config_dirs() + [xdg_config_home()] return [join(path, folder) for path in xdg_dirs] def get_xdg_data_dirs(folder=None): """ return list of possible XDG data dirs taking into account ovos.conf """ - folder = folder or get_xdg_base() + folder = folder or _ovos_config.get_xdg_base() return [join(path, folder) for path in xdg_data_dirs()] def get_xdg_config_save_path(folder=None): """ return base XDG config save path taking into account ovos.conf """ - folder = folder or get_xdg_base() + folder = folder or _ovos_config.get_xdg_base() return join(xdg_config_home(), folder) def get_xdg_data_save_path(folder=None): """ return base XDG data save path taking into account ovos.conf """ - folder = folder or get_xdg_base() + folder = folder or _ovos_config.get_xdg_base() return join(xdg_data_home(), folder) def get_xdg_cache_save_path(folder=None): """ return base XDG cache save path taking into account ovos.conf """ - folder = folder or get_xdg_base() + folder = folder or _ovos_config.get_xdg_base() return join(xdg_cache_home(), folder) def find_user_config(): """ return user config full file path taking into account ovos.conf """ - path = join(get_xdg_config_save_path(), get_config_filename()) + path = join(get_xdg_config_save_path(), _ovos_config.get_config_filename()) if isfile(path): return path old, path = get_config_locations(default=False, web_cache=False, @@ -69,7 +69,7 @@ def get_config_locations(default=True, web_cache=True, system=True, old_user=True, user=True): """return list of all possible config files paths sorted by priority taking into account ovos.conf""" locs = [] - ovos_cfg = get_ovos_config() + ovos_cfg = _ovos_config.get_ovos_config() if default: locs.append(ovos_cfg["default_config_path"]) if system: @@ -93,7 +93,7 @@ def get_xdg_config_locations(): # This includes both the user config and # /etc/xdg/mycroft/mycroft.conf xdg_paths = list(reversed( - [join(p, get_config_filename()) + [join(p, _ovos_config.get_config_filename()) for p in get_xdg_config_dirs()] )) return xdg_paths @@ -114,14 +114,18 @@ def find_default_config(): DEFAULT_CONFIG = find_default_config() SYSTEM_CONFIG = os.environ.get('MYCROFT_SYSTEM_CONFIG', - f'/etc/{get_xdg_base()}/{get_config_filename()}') + f'/etc/{_ovos_config.get_xdg_base()}/' + f'{_ovos_config.get_config_filename()}') # TODO: remove in 22.02 # Make sure we support the old location still # Deprecated and will be removed eventually -OLD_USER_CONFIG = join(expanduser('~'), '.' + get_xdg_base(), get_config_filename()) -USER_CONFIG = join(get_xdg_config_save_path(), get_config_filename()) +OLD_USER_CONFIG = join(expanduser('~'), '.' + _ovos_config.get_xdg_base(), + _ovos_config.get_config_filename()) +USER_CONFIG = join(get_xdg_config_save_path(), + _ovos_config.get_config_filename()) REMOTE_CONFIG = "mycroft.ai" -WEB_CONFIG_CACHE = os.environ.get('MYCROFT_WEB_CACHE') or get_webcache_location() +WEB_CONFIG_CACHE = os.environ.get('MYCROFT_WEB_CACHE') or \ + get_webcache_location() def __ensure_folder_exists(path): diff --git a/ovos_config/meta.py b/ovos_config/meta.py new file mode 100644 index 0000000..6eea25d --- /dev/null +++ b/ovos_config/meta.py @@ -0,0 +1,211 @@ +"""This file will check a system level OpenVoiceOS specific config file + +The ovos config is json with comment support like the regular mycroft.conf + +Default locations tried by order until a file is found +- /etc/OpenVoiceOS/ovos.conf +- /etc/mycroft/ovos.conf + +XDG locations are then merged over the select default config (if found) + +Examples config: + +{ + // the "name of the core", + // eg, OVOS, Neon, Chatterbox... + // all XDG paths should respect this + // {xdg_path}/{base_folder}/some_resource + // "mycroft.conf" paths are derived from this + // ~/.{base_folder}/mycroft.conf + "base_folder": "OpenVoiceOS", + + // the filename of "mycroft.conf", + // eg, ovos.conf, chatterbox.conf, neon.conf... + // "mycroft.conf" paths are derived from this + // ~/.{base_folder}/{config_filename} + "config_filename": "mycroft.conf", + + // override the default.conf location, allows changing the default values + // eg, disable backend, disable skills, configure permissions + "default_config_path": "/etc/OpenVoiceOS/default_mycroft.conf", + + // this is intended for derivative products, if a module name is present + // in sys.modules then the values below will be used instead + // eg, chatterbox/mycroft/ovos/neon can coexist in the same machine + "module_overrides": { + "chatterbox": { + "xdg": false, + "base_folder": "chatterbox", + "config_filename": "chatterbox.conf", + "default_config_path": "/opt/chatterbox/chatterbox.conf" + }, + "neon_core": { + "xdg": true, + "base_folder": "neon", + "config_filename": "neon.conf", + "default_config_path": "/opt/neon/neon.conf" + } + }, + // essentially aliases for the above, useful for microservice architectures + "submodule_mappings": { + "chatterbox_stt": "chatterbox", + "chatterbox_playback": "chatterbox", + "chatterbox_admin": "chatterbox", + "chatterbox_blockly": "chatterbox", + "chatterbox_gpio_service": "chatterbox", + "neon_speech": "neon_core", + "neon_audio": "neon_core", + "neon_enclosure": "neon_core" + } +} +""" +from os.path import isfile, join, dirname + +from json_database import JsonStorage + +import ovos_config.locations as _oloc +from ovos_utils.json_helper import load_commented_json, merge_dict +from ovos_utils.log import LOG +from ovos_utils.system import is_running_from_module + + +def get_ovos_config(): + """ load ovos.conf + goes trough all possible ovos.conf paths and loads them in order + + submodule overrides are applied to the final config if overrides are defined for the caller module + eg, if neon-core is calling this method then neon config overrides are loaded + + """ + # populate default values + config = {"xdg": True, + "base_folder": "mycroft", + "config_filename": "mycroft.conf"} + try: + config["default_config_path"] = _oloc.find_default_config() + except FileNotFoundError: # not a mycroft device + config["default_config_path"] = join(dirname(__file__), "mycroft.conf") + + # load ovos.conf + for path in get_ovos_default_config_paths(): + try: + config = merge_dict(config, load_commented_json(path)) + except: + # tolerate bad json TODO proper exception (?) + pass + + # let's check for derivatives specific configs + # the assumption is that these cores are exclusive to each other, + # this will never find more than one override + # TODO this works if using dedicated .venvs what about system installs? + cores = config.get("module_overrides") or {} + for k in cores: + if is_running_from_module(k): + config = merge_dict(config, cores[k]) + break + else: + subcores = config.get("submodule_mappings") or {} + for k in subcores: + if is_running_from_module(k): + config = merge_dict(config, cores[subcores[k]]) + break + + return config + + +def save_ovos_config(new_config): + """ update ovos.conf contents at ~/.config/OpenVoiceOS/ovos.conf """ + OVOS_CONFIG = join(_oloc.get_xdg_config_save_path("OpenVoiceOS"), + "ovos.conf") + cfg = JsonStorage(OVOS_CONFIG) + cfg.update(new_config) + cfg.store() + return cfg + + +def get_ovos_default_config_paths(): + """ return a list of all existing ovos.conf file locations by order of precedence + + eg. ["/etc/OpenVoiceOS/ovos.conf", "/home/user/.config/OpenVoiceOS/ovos.conf"] + + """ + paths = [] + if isfile("/etc/OpenVoiceOS/ovos.conf"): + paths.append("/etc/OpenVoiceOS/ovos.conf") + elif isfile("/etc/mycroft/ovos.conf"): + LOG.warning("found /etc/mycroft/ovos.conf\n" + "This location has been DEPRECATED!\n" + "Please move your config to /etc/OpenVoiceOS/ovos.conf") + paths.append("/etc/mycroft/ovos.conf") + + # This includes both the user config and + # /etc/xdg/OpenVoiceOS/ovos.conf + for p in _oloc.get_xdg_config_dirs("OpenVoiceOS"): + if isfile(join(p, "ovos.conf")): + paths.append(join(p, "ovos.conf")) + + return paths + + +def is_using_xdg(): + """ BACKWARDS COMPAT: logs warning and always returns True""" + LOG.warning("is_using_xdg has been deprecated! XDG specs are always honoured, this method will be removed in a future release") + return True + + +def get_xdg_base(): + """ base folder name to be used when building paths of the format {$XDG_XXX}/{base} + + different derivative cores may change this folder, this value is derived from ovos.conf + eg, "mycroft", "hivemind", "neon" .... + """ + + return get_ovos_config().get("base_folder") or "mycroft" + + +def set_xdg_base(folder_name): + """ base folder name to be used when building paths of the format {$XDG_XXX}/{base} + + different derivative cores may change this folder, this value is derived from ovos.conf + eg, "mycroft", "hivemind", "neon" .... + + NOTE: this value will be set globally, per core overrides in ovos.conf take precedence + """ + LOG.info(f"XDG base folder set to: '{folder_name}'") + save_ovos_config({"base_folder": folder_name}) + + +def set_config_filename(file_name, core_folder=None): + """ base config file name to be used when building paths + + different derivative cores may change this filename, this value is derived from ovos.conf + eg, "mycroft.conf", "hivemind.json", "neon.yaml" .... + + NOTE: this value will be set globally, per core overrides in ovos.conf take precedence + """ + if core_folder: + set_xdg_base(core_folder) + LOG.info(f"config filename set to: '{file_name}'") + save_ovos_config({"config_filename": file_name}) + + +def get_config_filename(): + """ base config file name to be used when building paths + + different derivative cores may change this filename, this value is derived from ovos.conf + eg, "mycroft.conf", "hivemind.json", "neon.yaml" .... + """ + return get_ovos_config().get("config_filename") or "mycroft.conf" + + +def set_default_config(file_path=None): + """ full path to default config file to be used + NOTE: this is a full path, not a directory! "config_filename" parameter is not used here + + different derivative cores may change this file, this value is derived from ovos.conf + + NOTE: this value will be set globally, per core overrides in ovos.conf take precedence + """ + file_path = file_path or _oloc.find_default_config() + LOG.info(f"default config file changed to: {file_path}") + save_ovos_config({"default_config_path": file_path}) diff --git a/ovos_config/base.py b/ovos_config/models.py similarity index 100% rename from ovos_config/base.py rename to ovos_config/models.py diff --git a/ovos_config/ovos.py b/ovos_config/ovos.py index 6eea25d..a73fe63 100644 --- a/ovos_config/ovos.py +++ b/ovos_config/ovos.py @@ -1,211 +1,4 @@ -"""This file will check a system level OpenVoiceOS specific config file - -The ovos config is json with comment support like the regular mycroft.conf - -Default locations tried by order until a file is found -- /etc/OpenVoiceOS/ovos.conf -- /etc/mycroft/ovos.conf - -XDG locations are then merged over the select default config (if found) - -Examples config: - -{ - // the "name of the core", - // eg, OVOS, Neon, Chatterbox... - // all XDG paths should respect this - // {xdg_path}/{base_folder}/some_resource - // "mycroft.conf" paths are derived from this - // ~/.{base_folder}/mycroft.conf - "base_folder": "OpenVoiceOS", - - // the filename of "mycroft.conf", - // eg, ovos.conf, chatterbox.conf, neon.conf... - // "mycroft.conf" paths are derived from this - // ~/.{base_folder}/{config_filename} - "config_filename": "mycroft.conf", - - // override the default.conf location, allows changing the default values - // eg, disable backend, disable skills, configure permissions - "default_config_path": "/etc/OpenVoiceOS/default_mycroft.conf", - - // this is intended for derivative products, if a module name is present - // in sys.modules then the values below will be used instead - // eg, chatterbox/mycroft/ovos/neon can coexist in the same machine - "module_overrides": { - "chatterbox": { - "xdg": false, - "base_folder": "chatterbox", - "config_filename": "chatterbox.conf", - "default_config_path": "/opt/chatterbox/chatterbox.conf" - }, - "neon_core": { - "xdg": true, - "base_folder": "neon", - "config_filename": "neon.conf", - "default_config_path": "/opt/neon/neon.conf" - } - }, - // essentially aliases for the above, useful for microservice architectures - "submodule_mappings": { - "chatterbox_stt": "chatterbox", - "chatterbox_playback": "chatterbox", - "chatterbox_admin": "chatterbox", - "chatterbox_blockly": "chatterbox", - "chatterbox_gpio_service": "chatterbox", - "neon_speech": "neon_core", - "neon_audio": "neon_core", - "neon_enclosure": "neon_core" - } -} -""" -from os.path import isfile, join, dirname - -from json_database import JsonStorage - -import ovos_config.locations as _oloc -from ovos_utils.json_helper import load_commented_json, merge_dict +from ovos_config.meta import * from ovos_utils.log import LOG -from ovos_utils.system import is_running_from_module - - -def get_ovos_config(): - """ load ovos.conf - goes trough all possible ovos.conf paths and loads them in order - - submodule overrides are applied to the final config if overrides are defined for the caller module - eg, if neon-core is calling this method then neon config overrides are loaded - - """ - # populate default values - config = {"xdg": True, - "base_folder": "mycroft", - "config_filename": "mycroft.conf"} - try: - config["default_config_path"] = _oloc.find_default_config() - except FileNotFoundError: # not a mycroft device - config["default_config_path"] = join(dirname(__file__), "mycroft.conf") - - # load ovos.conf - for path in get_ovos_default_config_paths(): - try: - config = merge_dict(config, load_commented_json(path)) - except: - # tolerate bad json TODO proper exception (?) - pass - - # let's check for derivatives specific configs - # the assumption is that these cores are exclusive to each other, - # this will never find more than one override - # TODO this works if using dedicated .venvs what about system installs? - cores = config.get("module_overrides") or {} - for k in cores: - if is_running_from_module(k): - config = merge_dict(config, cores[k]) - break - else: - subcores = config.get("submodule_mappings") or {} - for k in subcores: - if is_running_from_module(k): - config = merge_dict(config, cores[subcores[k]]) - break - - return config - - -def save_ovos_config(new_config): - """ update ovos.conf contents at ~/.config/OpenVoiceOS/ovos.conf """ - OVOS_CONFIG = join(_oloc.get_xdg_config_save_path("OpenVoiceOS"), - "ovos.conf") - cfg = JsonStorage(OVOS_CONFIG) - cfg.update(new_config) - cfg.store() - return cfg - - -def get_ovos_default_config_paths(): - """ return a list of all existing ovos.conf file locations by order of precedence - - eg. ["/etc/OpenVoiceOS/ovos.conf", "/home/user/.config/OpenVoiceOS/ovos.conf"] - - """ - paths = [] - if isfile("/etc/OpenVoiceOS/ovos.conf"): - paths.append("/etc/OpenVoiceOS/ovos.conf") - elif isfile("/etc/mycroft/ovos.conf"): - LOG.warning("found /etc/mycroft/ovos.conf\n" - "This location has been DEPRECATED!\n" - "Please move your config to /etc/OpenVoiceOS/ovos.conf") - paths.append("/etc/mycroft/ovos.conf") - - # This includes both the user config and - # /etc/xdg/OpenVoiceOS/ovos.conf - for p in _oloc.get_xdg_config_dirs("OpenVoiceOS"): - if isfile(join(p, "ovos.conf")): - paths.append(join(p, "ovos.conf")) - - return paths - - -def is_using_xdg(): - """ BACKWARDS COMPAT: logs warning and always returns True""" - LOG.warning("is_using_xdg has been deprecated! XDG specs are always honoured, this method will be removed in a future release") - return True - - -def get_xdg_base(): - """ base folder name to be used when building paths of the format {$XDG_XXX}/{base} - - different derivative cores may change this folder, this value is derived from ovos.conf - eg, "mycroft", "hivemind", "neon" .... - """ - - return get_ovos_config().get("base_folder") or "mycroft" - - -def set_xdg_base(folder_name): - """ base folder name to be used when building paths of the format {$XDG_XXX}/{base} - - different derivative cores may change this folder, this value is derived from ovos.conf - eg, "mycroft", "hivemind", "neon" .... - - NOTE: this value will be set globally, per core overrides in ovos.conf take precedence - """ - LOG.info(f"XDG base folder set to: '{folder_name}'") - save_ovos_config({"base_folder": folder_name}) - - -def set_config_filename(file_name, core_folder=None): - """ base config file name to be used when building paths - - different derivative cores may change this filename, this value is derived from ovos.conf - eg, "mycroft.conf", "hivemind.json", "neon.yaml" .... - - NOTE: this value will be set globally, per core overrides in ovos.conf take precedence - """ - if core_folder: - set_xdg_base(core_folder) - LOG.info(f"config filename set to: '{file_name}'") - save_ovos_config({"config_filename": file_name}) - - -def get_config_filename(): - """ base config file name to be used when building paths - - different derivative cores may change this filename, this value is derived from ovos.conf - eg, "mycroft.conf", "hivemind.json", "neon.yaml" .... - """ - return get_ovos_config().get("config_filename") or "mycroft.conf" - - -def set_default_config(file_path=None): - """ full path to default config file to be used - NOTE: this is a full path, not a directory! "config_filename" parameter is not used here - - different derivative cores may change this file, this value is derived from ovos.conf - - NOTE: this value will be set globally, per core overrides in ovos.conf take precedence - """ - file_path = file_path or _oloc.find_default_config() - LOG.info(f"default config file changed to: {file_path}") - save_ovos_config({"default_config_path": file_path}) +LOG.warning("This reference is deprecated, " + "import from ovos_config.meta") diff --git a/setup.py b/setup.py index c4dcdd8..e0c7ec5 100644 --- a/setup.py +++ b/setup.py @@ -62,5 +62,6 @@ def required(requirements_file): description='mycroft-core configuration module', install_requires=required('requirements/requirements.txt'), packages=find_packages(include=['ovos*']), + package_data={'ovos_config': ['mycroft.conf']}, include_package_data=True ) diff --git a/test/unittests/mycroft/configuration/mycroft.conf b/test/unittests/mycroft/configuration/mycroft.conf new file mode 100644 index 0000000..e69de29 diff --git a/test/unittests/test_configuration.py b/test/unittests/test_configuration.py index ee64b68..a1e11f6 100644 --- a/test/unittests/test_configuration.py +++ b/test/unittests/test_configuration.py @@ -32,9 +32,9 @@ def test_remote(self, mock_api): self.assertEqual(rc['location']['city']['name'], 'Stockholm') @patch('json.dump') - @patch('ovos_config.base.exists') - @patch('ovos_config.base.isfile') - @patch('ovos_config.base.load_commented_json') + @patch('ovos_config.models.exists') + @patch('ovos_config.models.isfile') + @patch('ovos_config.models.load_commented_json') def test_local(self, mock_json_loader, mock_isfile, mock_exists, mock_json_dump): local_conf = {'answer': 42, 'falling_objects': ['flower pot', 'whale']} diff --git a/test/unittests/test_locations.py b/test/unittests/test_locations.py new file mode 100644 index 0000000..8a041ad --- /dev/null +++ b/test/unittests/test_locations.py @@ -0,0 +1,105 @@ +import os +from os.path import expanduser, dirname, join, isfile + +from unittest import TestCase, mock + + +class TestLocations(TestCase): + def test_get_config_dirs(self): + from ovos_config.locations import get_xdg_config_dirs + directories = get_xdg_config_dirs("test") + self.assertIn(expanduser("~/.config/test"), directories) + + def test_get_data_dirs(self): + from ovos_config.locations import get_xdg_data_dirs + directories = get_xdg_data_dirs("test") + self.assertTrue(all((d.endswith('/test') for d in directories))) + + def test_get_xdg_config_save_path(self): + from ovos_config.locations import get_xdg_config_save_path + self.assertEqual(get_xdg_config_save_path("test"), + expanduser("~/.config/test")) + + def test_get_xdg_data_save_path(self): + from ovos_config.locations import get_xdg_data_save_path + self.assertEqual(get_xdg_data_save_path("test"), + expanduser("~/.local/share/test")) + + def test_get_xdg_cache_save_path(self): + from ovos_config.locations import get_xdg_cache_save_path + self.assertEqual(get_xdg_cache_save_path("test"), + expanduser("~/.cache/test")) + + @mock.patch("ovos_config.meta.get_config_filename") + @mock.patch("ovos_config.locations.get_xdg_config_save_path") + def test_find_user_config(self, save_path, config_filename): + config_filename.return_value = "mycroft.yml" + save_path.return_value = dirname(__file__) + from ovos_config.locations import find_user_config + self.assertEqual(find_user_config(), join(dirname(__file__), + "mycroft.yml")) + + @mock.patch("ovos_config.meta.get_ovos_config") + @mock.patch("ovos_config.locations.get_webcache_location") + @mock.patch("ovos_config.locations.get_xdg_config_save_path") + def test_get_config_locations(self, config_path, webcache_loc, + ovos_config): + ovos_config.return_value = { + "test": True, + "base_folder": "test", + "config_filename": "test.yaml", + "default_config_path": "/test/default.yml" + } + config_path.return_value = "config" + webcache_loc.return_value = "webcache" + from ovos_config.locations import get_config_locations + self.assertEqual(get_config_locations(False, False, False, + False, False), list()) + self.assertEqual(get_config_locations(), + ['/test/default.yml', '/etc/test/test.yaml', + 'webcache', '~/.test/test.yaml', 'config/test.yaml']) + + @mock.patch("ovos_config.locations.search_mycroft_core_location") + def test_find_default_config(self, get_core): + from ovos_config.locations import find_default_config + + # No Core + get_core.return_value = None + no_core_default = find_default_config() + self.assertTrue(no_core_default.endswith("/ovos_config/mycroft.conf"), + no_core_default) + self.assertTrue(isfile(no_core_default), no_core_default) + + # # Invalid Core + # get_core.return_value = "/tmp" + # self.assertEqual(find_default_config(), + # "/tmp/mycroft/configuration/mycroft.conf") + + # Valid Core + get_core.return_value = dirname(__file__) + self.assertEqual(find_default_config(), + join(dirname(__file__), "mycroft", "configuration", + "mycroft.conf")) + + @mock.patch("ovos_utils.system.search_mycroft_core_location") + @mock.patch("ovos_config.meta.get_config_filename") + @mock.patch("ovos_config.meta.get_xdg_base") + def test_globals(self, xdg_base, config_filename, core_location): + core_location.return_value = "default/config/path" + xdg_base.return_value = "test" + config_filename.return_value = "test.yaml" + os.environ["MYCROFT_SYSTEM_CONFIG"] = "mycroft/system/config" + os.environ["MYCROFT_WEB_CACHE"] = "mycroft/web/config" + import importlib + import ovos_config + importlib.reload(ovos_config.locations) + from ovos_config.locations import DEFAULT_CONFIG, SYSTEM_CONFIG, \ + OLD_USER_CONFIG, USER_CONFIG, REMOTE_CONFIG, WEB_CONFIG_CACHE + self.assertEqual(DEFAULT_CONFIG, "default/config/path/mycroft/configuration/mycroft.conf") + self.assertEqual(SYSTEM_CONFIG, "mycroft/system/config") + self.assertEqual(OLD_USER_CONFIG, + expanduser("~/.test/test.yaml")) + self.assertEqual(USER_CONFIG, + expanduser("~/.config/test/test.yaml")) + self.assertEqual(REMOTE_CONFIG, "mycroft.ai") + self.assertEqual(WEB_CONFIG_CACHE, "mycroft/web/config")