2019-06-28 19:54:45 +02:00
|
|
|
"""Pytest fixtures for testing."""
|
|
|
|
|
2019-12-21 17:36:20 +01:00
|
|
|
import toml
|
|
|
|
import yaml
|
2019-06-28 19:54:45 +02:00
|
|
|
import json
|
|
|
|
import os
|
2019-08-22 03:27:31 +02:00
|
|
|
import shutil
|
2019-06-28 19:54:45 +02:00
|
|
|
import pytest
|
|
|
|
|
2020-01-07 18:38:03 +01:00
|
|
|
from src.ldap_server import LDAPServer
|
|
|
|
|
2019-06-28 19:54:45 +02:00
|
|
|
|
|
|
|
def patch_init(moulinette):
|
|
|
|
"""Configure moulinette to use the YunoHost namespace."""
|
|
|
|
old_init = moulinette.core.Moulinette18n.__init__
|
|
|
|
|
2019-11-25 17:21:13 +01:00
|
|
|
def monkey_path_i18n_init(self, package, default_locale="en"):
|
2019-06-28 19:54:45 +02:00
|
|
|
old_init(self, package, default_locale)
|
2019-11-25 17:21:13 +01:00
|
|
|
self.load_namespace("moulinette")
|
2019-06-28 19:54:45 +02:00
|
|
|
|
|
|
|
moulinette.core.Moulinette18n.__init__ = monkey_path_i18n_init
|
|
|
|
|
|
|
|
|
|
|
|
def patch_translate(moulinette):
|
|
|
|
"""Configure translator to raise errors when there are missing keys."""
|
|
|
|
old_translate = moulinette.core.Translator.translate
|
|
|
|
|
|
|
|
def new_translate(self, key, *args, **kwargs):
|
|
|
|
if key not in self._translations[self.default_locale].keys():
|
2019-11-25 17:21:13 +01:00
|
|
|
message = "Unable to retrieve key %s for default locale!" % key
|
2019-06-28 19:54:45 +02:00
|
|
|
raise KeyError(message)
|
|
|
|
|
|
|
|
return old_translate(self, key, *args, **kwargs)
|
|
|
|
|
|
|
|
moulinette.core.Translator.translate = new_translate
|
|
|
|
|
|
|
|
def new_m18nn(self, key, *args, **kwargs):
|
|
|
|
return self._global.translate(key, *args, **kwargs)
|
|
|
|
|
|
|
|
moulinette.core.Moulinette18n.g = new_m18nn
|
|
|
|
|
|
|
|
|
|
|
|
def patch_logging(moulinette):
|
|
|
|
"""Configure logging to use the custom logger."""
|
2019-11-25 17:21:13 +01:00
|
|
|
handlers = set(["tty", "api"])
|
2019-06-28 19:54:45 +02:00
|
|
|
root_handlers = set(handlers)
|
|
|
|
|
2019-11-25 17:21:13 +01:00
|
|
|
level = "INFO"
|
|
|
|
tty_level = "INFO"
|
2019-06-28 19:54:45 +02:00
|
|
|
|
2019-08-22 12:30:26 +02:00
|
|
|
return {
|
2019-11-25 17:21:13 +01:00
|
|
|
"version": 1,
|
|
|
|
"disable_existing_loggers": True,
|
|
|
|
"formatters": {
|
|
|
|
"tty-debug": {"format": "%(relativeCreated)-4d %(fmessage)s"},
|
|
|
|
"precise": {
|
|
|
|
"format": "%(asctime)-15s %(levelname)-8s %(name)s %(funcName)s - %(fmessage)s" # noqa
|
2019-06-28 19:54:45 +02:00
|
|
|
},
|
|
|
|
},
|
2020-01-02 16:18:28 +01:00
|
|
|
"filters": {"action": {"()": "moulinette.utils.log.ActionFilter"}},
|
2019-11-25 17:21:13 +01:00
|
|
|
"handlers": {
|
|
|
|
"api": {
|
|
|
|
"level": level,
|
|
|
|
"class": "moulinette.interfaces.api.APIQueueHandler",
|
2019-08-22 03:27:31 +02:00
|
|
|
},
|
2019-11-25 17:21:13 +01:00
|
|
|
"tty": {
|
|
|
|
"level": tty_level,
|
|
|
|
"class": "moulinette.interfaces.cli.TTYHandler",
|
|
|
|
"formatter": "",
|
2019-06-28 19:54:45 +02:00
|
|
|
},
|
|
|
|
},
|
2019-11-25 17:21:13 +01:00
|
|
|
"loggers": {
|
2020-01-02 16:18:28 +01:00
|
|
|
"moulinette": {"level": level, "handlers": [], "propagate": True},
|
2019-11-25 17:21:13 +01:00
|
|
|
"moulinette.interface": {
|
|
|
|
"level": level,
|
|
|
|
"handlers": handlers,
|
|
|
|
"propagate": False,
|
2019-06-28 19:54:45 +02:00
|
|
|
},
|
|
|
|
},
|
2020-01-02 16:18:28 +01:00
|
|
|
"root": {"level": level, "handlers": root_handlers},
|
2019-06-28 19:54:45 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2020-01-02 16:50:21 +01:00
|
|
|
def patch_lock(moulinette):
|
2020-01-06 18:15:26 +01:00
|
|
|
moulinette.core.MoulinetteLock.base_lockfile = "moulinette_%s.lock"
|
2020-01-02 16:50:21 +01:00
|
|
|
|
|
|
|
|
2019-11-25 17:21:13 +01:00
|
|
|
@pytest.fixture(scope="session", autouse=True)
|
2019-08-22 12:30:26 +02:00
|
|
|
def moulinette(tmp_path_factory):
|
2019-06-28 19:54:45 +02:00
|
|
|
import moulinette
|
|
|
|
|
2019-08-22 12:30:26 +02:00
|
|
|
# Can't call the namespace just 'test' because
|
|
|
|
# that would lead to some "import test" not importing the right stuff
|
|
|
|
namespace = "moulitest"
|
2019-08-23 02:37:57 +02:00
|
|
|
tmp_cache = str(tmp_path_factory.mktemp("cache"))
|
2019-08-22 12:30:26 +02:00
|
|
|
tmp_data = str(tmp_path_factory.mktemp("data"))
|
|
|
|
tmp_lib = str(tmp_path_factory.mktemp("lib"))
|
2019-11-25 17:21:13 +01:00
|
|
|
os.environ["MOULINETTE_CACHE_DIR"] = tmp_cache
|
|
|
|
os.environ["MOULINETTE_DATA_DIR"] = tmp_data
|
|
|
|
os.environ["MOULINETTE_LIB_DIR"] = tmp_lib
|
2019-08-22 12:30:26 +02:00
|
|
|
shutil.copytree("./test/actionsmap", "%s/actionsmap" % tmp_data)
|
|
|
|
shutil.copytree("./test/src", "%s/%s" % (tmp_lib, namespace))
|
|
|
|
shutil.copytree("./test/locales", "%s/%s/locales" % (tmp_lib, namespace))
|
|
|
|
|
2019-06-28 19:54:45 +02:00
|
|
|
patch_init(moulinette)
|
|
|
|
patch_translate(moulinette)
|
2020-01-02 16:50:21 +01:00
|
|
|
patch_lock(moulinette)
|
2019-08-22 12:30:26 +02:00
|
|
|
logging = patch_logging(moulinette)
|
|
|
|
|
2019-11-25 17:21:13 +01:00
|
|
|
moulinette.init(logging_config=logging, _from_source=False)
|
2019-06-28 19:54:45 +02:00
|
|
|
|
|
|
|
return moulinette
|
|
|
|
|
|
|
|
|
2019-11-19 21:06:55 +01:00
|
|
|
@pytest.fixture
|
2019-08-22 12:30:26 +02:00
|
|
|
def moulinette_webapi(moulinette):
|
|
|
|
|
2019-11-19 21:06:55 +01:00
|
|
|
from webtest import TestApp
|
|
|
|
from webtest.app import CookiePolicy
|
|
|
|
|
|
|
|
# Dirty hack needed, otherwise cookies ain't reused between request .. not
|
|
|
|
# sure why :|
|
|
|
|
def return_true(self, cookie, request):
|
|
|
|
return True
|
2019-11-25 17:21:13 +01:00
|
|
|
|
2019-11-19 21:06:55 +01:00
|
|
|
CookiePolicy.return_ok_secure = return_true
|
|
|
|
|
2020-05-01 01:13:40 +02:00
|
|
|
moulinette_webapi = moulinette.init_interface(
|
2019-11-25 17:21:13 +01:00
|
|
|
"api",
|
|
|
|
kwargs={"routes": {}, "use_websocket": False},
|
|
|
|
actionsmap={"namespaces": ["moulitest"], "use_cache": True},
|
2019-11-19 21:06:55 +01:00
|
|
|
)
|
2019-08-22 03:27:31 +02:00
|
|
|
|
2019-11-19 21:06:55 +01:00
|
|
|
return TestApp(moulinette_webapi._app)
|
2019-08-22 03:27:31 +02:00
|
|
|
|
|
|
|
|
2020-01-02 05:33:10 +01:00
|
|
|
@pytest.fixture
|
2020-01-02 16:17:32 +01:00
|
|
|
def moulinette_cli(moulinette, mocker):
|
2020-01-02 05:33:10 +01:00
|
|
|
# Dirty hack needed, otherwise cookies ain't reused between request .. not
|
|
|
|
# sure why :|
|
|
|
|
import argparse
|
2020-01-02 16:41:21 +01:00
|
|
|
|
2020-01-02 05:33:10 +01:00
|
|
|
parser = argparse.ArgumentParser(add_help=False)
|
2020-01-02 16:41:21 +01:00
|
|
|
parser.add_argument(
|
|
|
|
"--debug",
|
|
|
|
action="store_true",
|
|
|
|
default=False,
|
|
|
|
help="Log and print debug messages",
|
|
|
|
)
|
2020-01-02 16:17:32 +01:00
|
|
|
mocker.patch("os.isatty", return_value=True)
|
2020-05-01 01:13:40 +02:00
|
|
|
moulinette_cli = moulinette.init_interface(
|
2020-01-02 05:33:10 +01:00
|
|
|
"cli",
|
2020-01-02 16:41:21 +01:00
|
|
|
actionsmap={
|
|
|
|
"namespaces": ["moulitest"],
|
|
|
|
"use_cache": False,
|
|
|
|
"parser_kwargs": {"top_parser": parser},
|
|
|
|
},
|
2020-01-02 05:33:10 +01:00
|
|
|
)
|
2020-01-02 16:17:32 +01:00
|
|
|
mocker.stopall()
|
2020-01-02 05:33:10 +01:00
|
|
|
|
|
|
|
return moulinette_cli
|
|
|
|
|
|
|
|
|
2019-06-28 19:54:45 +02:00
|
|
|
@pytest.fixture
|
|
|
|
def test_file(tmp_path):
|
2019-11-25 17:21:13 +01:00
|
|
|
test_text = "foo\nbar\n"
|
|
|
|
test_file = tmp_path / "test.txt"
|
2019-06-28 19:54:45 +02:00
|
|
|
test_file.write_bytes(test_text)
|
|
|
|
return test_file
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.fixture
|
|
|
|
def test_json(tmp_path):
|
2019-11-25 17:21:13 +01:00
|
|
|
test_json = json.dumps({"foo": "bar"})
|
|
|
|
test_file = tmp_path / "test.json"
|
2019-06-28 19:54:45 +02:00
|
|
|
test_file.write_bytes(test_json)
|
|
|
|
return test_file
|
|
|
|
|
|
|
|
|
2019-12-21 17:36:20 +01:00
|
|
|
@pytest.fixture
|
|
|
|
def test_yaml(tmp_path):
|
|
|
|
test_yaml = yaml.dump({"foo": "bar"})
|
|
|
|
test_file = tmp_path / "test.txt"
|
|
|
|
test_file.write_bytes(test_yaml)
|
|
|
|
return test_file
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.fixture
|
|
|
|
def test_toml(tmp_path):
|
|
|
|
test_toml = toml.dumps({"foo": "bar"})
|
|
|
|
test_file = tmp_path / "test.txt"
|
|
|
|
test_file.write_bytes(str(test_toml))
|
|
|
|
return test_file
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.fixture
|
|
|
|
def test_ldif(tmp_path):
|
|
|
|
test_file = tmp_path / "test.txt"
|
2019-12-22 11:16:54 +01:00
|
|
|
from ldif import LDIFWriter
|
2019-12-21 17:36:20 +01:00
|
|
|
|
2020-01-02 16:41:21 +01:00
|
|
|
writer = LDIFWriter(open(str(test_file), "wb"))
|
|
|
|
|
|
|
|
writer.unparse(
|
|
|
|
"mail=alice@example.com",
|
|
|
|
{
|
|
|
|
"cn": ["Alice Alison"],
|
|
|
|
"mail": ["alice@example.com"],
|
|
|
|
"objectclass": ["top", "person"],
|
|
|
|
},
|
|
|
|
)
|
2019-12-21 17:36:20 +01:00
|
|
|
|
|
|
|
return test_file
|
|
|
|
|
|
|
|
|
2019-06-28 19:54:45 +02:00
|
|
|
@pytest.fixture
|
|
|
|
def user():
|
|
|
|
return os.getlogin()
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.fixture
|
|
|
|
def test_url():
|
2019-11-25 17:21:13 +01:00
|
|
|
return "https://some.test.url/yolo.txt"
|
2020-01-07 18:38:03 +01:00
|
|
|
|
|
|
|
|
|
|
|
@pytest.fixture
|
|
|
|
def ldap_server():
|
|
|
|
server = LDAPServer()
|
|
|
|
server.start()
|
|
|
|
yield server
|
|
|
|
server.stop()
|