yunohost/src/tests/test_app_resources.py
2022-04-27 22:06:50 +02:00

343 lines
10 KiB
Python

import os
import pytest
from moulinette.utils.process import check_output
from yunohost.app import app_setting
from yunohost.utils.resources import AppResource, AppResourceManager, AppResourceClassesByType
dummyfile = "/tmp/dummyappresource-testapp"
class DummyAppResource(AppResource):
type = "dummy"
default_properties = {
"file": "/tmp/dummyappresource-__APP__",
"content": "foo",
}
def provision_or_update(self, context):
open(self.file, "w").write(self.content)
if self.content == "forbiddenvalue":
raise Exception("Emeged you used the forbidden value!1!£&")
def deprovision(self, context):
os.system(f"rm -f {self.file}")
AppResourceClassesByType["dummy"] = DummyAppResource
def setup_function(function):
clean()
os.system("mkdir /etc/yunohost/apps/testapp")
os.system("echo 'id: testapp' > /etc/yunohost/apps/testapp/settings.yml")
os.system("echo 'packaging_format = 2' > /etc/yunohost/apps/testapp/manifest.toml")
os.system("echo 'id = \"testapp\"' >> /etc/yunohost/apps/testapp/manifest.toml")
def teardown_function(function):
clean()
def clean():
os.system(f"rm -f {dummyfile}")
os.system("rm -rf /etc/yunohost/apps/testapp")
os.system("rm -rf /var/www/testapp")
os.system("rm -rf /home/yunohost.app/testapp")
os.system("apt remove lolcat sl nyancat yarn >/dev/null 2>/dev/null")
os.system("userdel testapp 2>/dev/null")
def test_provision_dummy():
current = {"resources": {}}
wanted = {"resources": {"dummy": {}}}
assert not os.path.exists(dummyfile)
AppResourceManager("testapp", current=current, wanted=wanted).apply(rollback_if_failure=False)
assert open(dummyfile).read().strip() == "foo"
def test_deprovision_dummy():
current = {"resources": {"dummy": {}}}
wanted = {"resources": {}}
open(dummyfile, "w").write("foo")
assert open(dummyfile).read().strip() == "foo"
AppResourceManager("testapp", current=current, wanted=wanted).apply(rollback_if_failure=False)
assert not os.path.exists(dummyfile)
def test_provision_dummy_nondefaultvalue():
current = {"resources": {}}
wanted = {"resources": {"dummy": {"content": "bar"}}}
assert not os.path.exists(dummyfile)
AppResourceManager("testapp", current=current, wanted=wanted).apply(rollback_if_failure=False)
assert open(dummyfile).read().strip() == "bar"
def test_update_dummy():
current = {"resources": {"dummy": {}}}
wanted = {"resources": {"dummy": {"content": "bar"}}}
open(dummyfile, "w").write("foo")
assert open(dummyfile).read().strip() == "foo"
AppResourceManager("testapp", current=current, wanted=wanted).apply(rollback_if_failure=False)
assert open(dummyfile).read().strip() == "bar"
def test_update_dummy_fail():
current = {"resources": {"dummy": {}}}
wanted = {"resources": {"dummy": {"content": "forbiddenvalue"}}}
open(dummyfile, "w").write("foo")
assert open(dummyfile).read().strip() == "foo"
with pytest.raises(Exception):
AppResourceManager("testapp", current=current, wanted=wanted).apply(rollback_if_failure=False)
assert open(dummyfile).read().strip() == "forbiddenvalue"
def test_update_dummy_failwithrollback():
current = {"resources": {"dummy": {}}}
wanted = {"resources": {"dummy": {"content": "forbiddenvalue"}}}
open(dummyfile, "w").write("foo")
assert open(dummyfile).read().strip() == "foo"
with pytest.raises(Exception):
AppResourceManager("testapp", current=current, wanted=wanted).apply(rollback_if_failure=True)
assert open(dummyfile).read().strip() == "foo"
def test_resource_system_user():
r = AppResourceClassesByType["system_user"]
conf = {}
assert os.system("getent passwd testapp 2>/dev/null") != 0
r(conf, "testapp").provision_or_update()
assert os.system("getent passwd testapp >/dev/null") == 0
assert os.system("groups testapp | grep -q 'sftp.app'") != 0
conf["allow_sftp"] = True
r(conf, "testapp").provision_or_update()
assert os.system("getent passwd testapp >/dev/null") == 0
assert os.system("groups testapp | grep -q 'sftp.app'") == 0
r(conf, "testapp").deprovision()
assert os.system("getent passwd testapp 2>/dev/null") != 0
def test_resource_install_dir():
r = AppResourceClassesByType["install_dir"]
conf = {"owner": "nobody:rx", "group": "nogroup:rx"}
# FIXME: should also check settings ?
# FIXME: should also check automigrate from final_path
# FIXME: should also test changing the install folder location ?
assert not os.path.exists("/var/www/testapp")
r(conf, "testapp").provision_or_update()
assert os.path.exists("/var/www/testapp")
unixperms = check_output("ls -ld /var/www/testapp").split()
assert unixperms[0] == "dr-xr-x---"
assert unixperms[2] == "nobody"
assert unixperms[3] == "nogroup"
conf["owner"] = "nobody:rwx"
conf["group"] = "www-data:x"
r(conf, "testapp").provision_or_update()
assert os.path.exists("/var/www/testapp")
unixperms = check_output("ls -ld /var/www/testapp").split()
assert unixperms[0] == "drwx--x---"
assert unixperms[2] == "nobody"
assert unixperms[3] == "www-data"
r(conf, "testapp").deprovision()
assert not os.path.exists("/var/www/testapp")
def test_resource_data_dir():
r = AppResourceClassesByType["data_dir"]
conf = {"owner": "nobody:rx", "group": "nogroup:rx"}
assert not os.path.exists("/home/yunohost.app/testapp")
r(conf, "testapp").provision_or_update()
assert os.path.exists("/home/yunohost.app/testapp")
unixperms = check_output("ls -ld /home/yunohost.app/testapp").split()
assert unixperms[0] == "dr-xr-x---"
assert unixperms[2] == "nobody"
assert unixperms[3] == "nogroup"
conf["owner"] = "nobody:rwx"
conf["group"] = "www-data:x"
r(conf, "testapp").provision_or_update()
assert os.path.exists("/home/yunohost.app/testapp")
unixperms = check_output("ls -ld /home/yunohost.app/testapp").split()
assert unixperms[0] == "drwx--x---"
assert unixperms[2] == "nobody"
assert unixperms[3] == "www-data"
r(conf, "testapp").deprovision()
# FIXME : implement and check purge option
#assert not os.path.exists("/home/yunohost.app/testapp")
def test_resource_ports():
r = AppResourceClassesByType["ports"]
conf = {}
assert not app_setting("testapp", "port")
r(conf, "testapp").provision_or_update()
assert app_setting("testapp", "port")
r(conf, "testapp").deprovision()
assert not app_setting("testapp", "port")
def test_resource_ports_several():
r = AppResourceClassesByType["ports"]
conf = {"main": {"default": 12345}, "foobar": {"default": 23456}}
assert not app_setting("testapp", "port")
assert not app_setting("testapp", "port_foobar")
r(conf, "testapp").provision_or_update()
assert app_setting("testapp", "port")
assert app_setting("testapp", "port_foobar")
r(conf, "testapp").deprovision()
assert not app_setting("testapp", "port")
assert not app_setting("testapp", "port_foobar")
def test_resource_database():
r = AppResourceClassesByType["database"]
conf = {"type": "mysql"}
assert os.system("mysqlshow 'testapp' >/dev/null 2>/dev/null") != 0
assert not app_setting("testapp", "db_name")
assert not app_setting("testapp", "db_user")
assert not app_setting("testapp", "db_pwd")
r(conf, "testapp").provision_or_update()
assert os.system("mysqlshow 'testapp' >/dev/null 2>/dev/null") == 0
assert app_setting("testapp", "db_name")
assert app_setting("testapp", "db_user")
assert app_setting("testapp", "db_pwd")
r(conf, "testapp").deprovision()
assert os.system("mysqlshow 'testapp' >/dev/null 2>/dev/null") != 0
assert not app_setting("testapp", "db_name")
assert not app_setting("testapp", "db_user")
assert not app_setting("testapp", "db_pwd")
def test_resource_apt():
r = AppResourceClassesByType["apt"]
conf = {
"packages": "nyancat, sl",
"extras": {
"yarn": {
"repo": "deb https://dl.yarnpkg.com/debian/ stable main",
"key": "https://dl.yarnpkg.com/debian/pubkey.gpg",
"packages": "yarn",
}
}
}
assert os.system("dpkg --list | grep -q 'ii *nyancat '") != 0
assert os.system("dpkg --list | grep -q 'ii *sl '") != 0
assert os.system("dpkg --list | grep -q 'ii *yarn '") != 0
assert os.system("dpkg --list | grep -q 'ii *lolcat '") != 0
assert os.system("dpkg --list | grep -q 'ii *testapp-ynh-deps '") != 0
r(conf, "testapp").provision_or_update()
assert os.system("dpkg --list | grep -q 'ii *nyancat '") == 0
assert os.system("dpkg --list | grep -q 'ii *sl '") == 0
assert os.system("dpkg --list | grep -q 'ii *yarn '") == 0
assert os.system("dpkg --list | grep -q 'ii *lolcat '") != 0 # Lolcat shouldnt be installed yet
assert os.system("dpkg --list | grep -q 'ii *testapp-ynh-deps '") == 0
conf["packages"] += ", lolcat"
r(conf, "testapp").provision_or_update()
assert os.system("dpkg --list | grep -q 'ii *nyancat '") == 0
assert os.system("dpkg --list | grep -q 'ii *sl '") == 0
assert os.system("dpkg --list | grep -q 'ii *yarn '") == 0
assert os.system("dpkg --list | grep -q 'ii *lolcat '") == 0
assert os.system("dpkg --list | grep -q 'ii *testapp-ynh-deps '") == 0
r(conf, "testapp").deprovision()
assert os.system("dpkg --list | grep -q 'ii *nyancat '") != 0
assert os.system("dpkg --list | grep -q 'ii *sl '") != 0
assert os.system("dpkg --list | grep -q 'ii *yarn '") != 0
assert os.system("dpkg --list | grep -q 'ii *lolcat '") != 0
assert os.system("dpkg --list | grep -q 'ii *testapp-ynh-deps '") != 0
def test_resource_permissions():
raise NotImplementedError()
r = AppResourceClassesByType["permissions"]
conf = {
"main": {
"url": "/",
"allowed": "visitors"
# protected?
}
}
pass