Upstream: https://github.com/YunoHost/yunohost @ 3a5f8bac8301c450897b96cbd43a4c7d3ba750fb But (José) : transformer tout le code en bions + ploxions du xerboxion. La carte de digestion vit au labo : /yunohost-digest.json
627 lines
20 KiB
Python
627 lines
20 KiB
Python
#!/usr/bin/env python3
|
|
#
|
|
# Copyright (c) 2024 YunoHost Contributors
|
|
#
|
|
# This file is part of YunoHost (see https://yunohost.org)
|
|
#
|
|
# This program is free software: you can redistribute it and/or modify
|
|
# it under the terms of the GNU Affero General Public License as
|
|
# published by the Free Software Foundation, either version 3 of the
|
|
# License, or (at your option) any later version.
|
|
#
|
|
# This program is distributed in the hope that it will be useful,
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
# GNU Affero General Public License for more details.
|
|
#
|
|
# You should have received a copy of the GNU Affero General Public License
|
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
#
|
|
|
|
import os
|
|
import tempfile
|
|
from subprocess import check_call
|
|
|
|
import pytest
|
|
from yunohost.app import app_setting
|
|
from yunohost.domain import _get_maindomain
|
|
from yunohost.firewall import firewall_list
|
|
from yunohost.permission import permission_delete, user_permission_list
|
|
from yunohost.utils.process import check_output
|
|
from yunohost.utils.resources import (
|
|
AppResource,
|
|
AppResourceClassesByType,
|
|
AppResourceManager,
|
|
)
|
|
|
|
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")
|
|
os.system("echo 'version = \"0.1\"' >> /etc/yunohost/apps/testapp/manifest.toml")
|
|
os.system(
|
|
"echo 'description.en = \"A dummy app to test app resources\"' >> /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 influxdb2 >/dev/null 2>/dev/null")
|
|
os.system("userdel testapp 2>/dev/null")
|
|
|
|
for p in user_permission_list()["permissions"]:
|
|
if p.startswith("testapp."):
|
|
permission_delete(p, force=True, sync_perm=False)
|
|
|
|
|
|
def test_provision_dummy():
|
|
current = {"resources": {}}
|
|
wanted = {"resources": {"dummy": {}}}
|
|
|
|
assert not os.path.exists(dummyfile)
|
|
AppResourceManager("testapp", current=current, wanted=wanted).apply(
|
|
rollback_and_raise_exception_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_and_raise_exception_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_and_raise_exception_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_and_raise_exception_if_failure=False
|
|
)
|
|
assert open(dummyfile).read().strip() == "bar"
|
|
|
|
|
|
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_and_raise_exception_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_ports_firewall():
|
|
r = AppResourceClassesByType["ports"]
|
|
conf = {"main": {"default": 12345}}
|
|
|
|
r(conf, "testapp").provision_or_update()
|
|
|
|
assert 12345 not in firewall_list(protocol="tcp")["tcp"]
|
|
|
|
conf = {"main": {"default": 12345, "exposed": "TCP"}}
|
|
|
|
r(conf, "testapp").provision_or_update()
|
|
|
|
assert 12345 in firewall_list(protocol="tcp")["tcp"]
|
|
|
|
r(conf, "testapp").deprovision()
|
|
|
|
assert 12345 not in firewall_list(protocol="tcp")["tcp"]
|
|
|
|
|
|
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": {
|
|
"influxdb": {
|
|
"repo": "deb https://repos.influxdata.com/debian stable main",
|
|
"key": "https://repos.influxdata.com/influxdata-archive.key",
|
|
"packages": "influxdb2",
|
|
}
|
|
},
|
|
}
|
|
|
|
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 *influxdb2 '") != 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 *influxdb2 '") == 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 *influxdb2 '") == 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 *influxdb2 '") != 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():
|
|
maindomain = _get_maindomain()
|
|
os.system(f"echo 'domain: {maindomain}' >> /etc/yunohost/apps/testapp/settings.yml")
|
|
os.system("echo 'path: /testapp' >> /etc/yunohost/apps/testapp/settings.yml")
|
|
|
|
# A manager object is required to set the label of the app...
|
|
manager = AppResourceManager("testapp", current={}, wanted={"name": "Test App"})
|
|
r = AppResourceClassesByType["permissions"]
|
|
conf = {
|
|
"main": {
|
|
"url": "/",
|
|
"allowed": "visitors",
|
|
},
|
|
}
|
|
|
|
res = user_permission_list(full=True)["permissions"]
|
|
# Nowadays there's always an implicit "main" perm but with default stuff such as empty url
|
|
assert res["testapp.main"]["url"] is None
|
|
assert res["testapp.main"]["allowed"] == []
|
|
|
|
r(conf, "testapp", manager).provision_or_update()
|
|
|
|
res = user_permission_list(full=True)["permissions"]
|
|
assert "testapp.main" in res
|
|
assert "visitors" in res["testapp.main"]["allowed"]
|
|
assert res["testapp.main"]["url"] == "/"
|
|
assert "testapp.admin" not in res
|
|
|
|
conf["admin"] = {"url": "/admin", "allowed": ""}
|
|
|
|
r(conf, "testapp", manager).provision_or_update()
|
|
|
|
res = user_permission_list(full=True)["permissions"]
|
|
|
|
assert "testapp.main" in list(res.keys())
|
|
assert "visitors" in res["testapp.main"]["allowed"]
|
|
assert res["testapp.main"]["url"] == "/"
|
|
|
|
assert "testapp.admin" in res
|
|
assert not res["testapp.admin"]["allowed"]
|
|
assert res["testapp.admin"]["url"] == "/admin"
|
|
|
|
conf["admin"]["url"] = "/adminpanel"
|
|
|
|
r(conf, "testapp", manager).provision_or_update()
|
|
|
|
res = user_permission_list(full=True)["permissions"]
|
|
|
|
assert res["testapp.admin"]["url"] == "/adminpanel"
|
|
|
|
r(conf, "testapp").deprovision()
|
|
|
|
res = user_permission_list(full=True)["permissions"]
|
|
|
|
assert "testapp.admin" not in res
|
|
# The main permission is still forced to exist
|
|
assert "testapp.main" in res
|
|
|
|
|
|
def test_resource_nodejs():
|
|
manager = AppResourceManager(
|
|
"testapp",
|
|
current={},
|
|
wanted={"name": "Test App", "integration": {"helpers_version": "2.1"}},
|
|
)
|
|
|
|
r = AppResourceClassesByType["nodejs"]
|
|
assert not app_setting("testapp", "nodejs_version")
|
|
conf = {
|
|
"version": "20",
|
|
}
|
|
|
|
r(conf, "testapp", manager).provision_or_update()
|
|
|
|
nodejs_version = app_setting("testapp", "nodejs_version")
|
|
assert nodejs_version
|
|
nodejs_dir = f"{r.N_INSTALL_DIR}/n/versions/node/{nodejs_version}/bin"
|
|
assert os.path.exists(nodejs_dir)
|
|
|
|
env = {
|
|
"N_PREFIX": r.N_INSTALL_DIR,
|
|
"PATH": f"{nodejs_dir}:{os.environ['PATH']}",
|
|
}
|
|
|
|
assert check_output("which node", env=env).startswith(nodejs_dir)
|
|
installed_version = check_output("node --version", env=env)
|
|
assert installed_version.startswith("v20.")
|
|
with tempfile.TemporaryDirectory(prefix="ynh_") as d:
|
|
# Install a random simple package to validate npm is in the path and working
|
|
check_call(["npm", "install", "ansi-styles"], cwd=d, env=env)
|
|
# FIXME: the resource should install stuff as non-root probably ?
|
|
assert os.path.exists(f"{d}/node_modules/")
|
|
|
|
r({}, "testapp", manager).deprovision()
|
|
assert not app_setting("testapp", "nodejs_version")
|
|
assert not os.path.exists(nodejs_dir)
|
|
|
|
|
|
def test_resource_ruby():
|
|
os.system("echo '[integration]' >> /etc/yunohost/apps/testapp/manifest.toml")
|
|
os.system(
|
|
"echo 'helpers_version = \"2.1\"' >> /etc/yunohost/apps/testapp/manifest.toml"
|
|
)
|
|
|
|
r = AppResourceClassesByType["system_user"]
|
|
r({}, "testapp").provision_or_update()
|
|
|
|
r = AppResourceClassesByType["install_dir"]
|
|
r({}, "testapp").provision_or_update()
|
|
install_dir = app_setting("testapp", "install_dir")
|
|
|
|
manager = AppResourceManager(
|
|
"testapp",
|
|
current={},
|
|
wanted={"name": "Test App", "integration": {"helpers_version": "2.1"}},
|
|
)
|
|
|
|
r = AppResourceClassesByType["apt"]
|
|
conf = {
|
|
"packages": "make, gcc, libjemalloc-dev, libffi-dev, libyaml-dev, zlib1g-dev"
|
|
}
|
|
r(conf, "testapp", manager).provision_or_update()
|
|
|
|
r = AppResourceClassesByType["ruby"]
|
|
assert not app_setting("testapp", "ruby_version")
|
|
conf = {
|
|
"version": "3.3.5",
|
|
}
|
|
|
|
try:
|
|
r(conf, "testapp", manager).provision_or_update()
|
|
except Exception:
|
|
os.system("tail -n 40 /tmp/ruby-build*.log")
|
|
raise
|
|
|
|
ruby_version = app_setting("testapp", "ruby_version")
|
|
assert ruby_version
|
|
ruby_dir = f"{r.RBENV_ROOT}/versions/testapp/bin"
|
|
ruby_dir2 = f"{r.RBENV_ROOT}/versions/{ruby_version}/bin"
|
|
assert os.path.exists(ruby_dir)
|
|
assert os.path.exists(ruby_dir2)
|
|
|
|
env = {
|
|
"PATH": f"{ruby_dir}:{os.environ['PATH']}",
|
|
}
|
|
|
|
assert check_output("which ruby", env=env).startswith(ruby_dir)
|
|
assert check_output("which gem", env=env).startswith(ruby_dir)
|
|
assert "3.3.5" in check_output("ruby --version", env=env)
|
|
with tempfile.TemporaryDirectory(prefix="ynh_") as d:
|
|
# Install a random simple package to validate the path etc
|
|
check_call(
|
|
"gem install bundler passenger --no-document".split(), cwd=d, env=env
|
|
)
|
|
check_call(
|
|
"bundle config set --local without 'development test'".split(),
|
|
cwd=d,
|
|
env=env,
|
|
)
|
|
# FIXME: the resource should install stuff as non-root probably ?
|
|
|
|
r({}, "testapp", manager).deprovision()
|
|
assert not app_setting("testapp", "ruby_version")
|
|
assert not os.path.exists(ruby_dir)
|
|
assert not os.path.exists(ruby_dir2)
|
|
|
|
|
|
def test_resource_go():
|
|
os.system("echo '[integration]' >> /etc/yunohost/apps/testapp/manifest.toml")
|
|
os.system(
|
|
"echo 'helpers_version = \"2.1\"' >> /etc/yunohost/apps/testapp/manifest.toml"
|
|
)
|
|
|
|
r = AppResourceClassesByType["system_user"]
|
|
r({}, "testapp").provision_or_update()
|
|
|
|
r = AppResourceClassesByType["install_dir"]
|
|
r({}, "testapp").provision_or_update()
|
|
install_dir = app_setting("testapp", "install_dir")
|
|
|
|
r = AppResourceClassesByType["go"]
|
|
assert not app_setting("testapp", "go_version")
|
|
conf = {
|
|
"version": "1.22",
|
|
}
|
|
|
|
r(conf, "testapp").provision_or_update()
|
|
|
|
go_version = app_setting("testapp", "go_version")
|
|
assert go_version and go_version.startswith("1.22.")
|
|
go_dir = f"{r.GOENV_ROOT}/versions/{go_version}/bin"
|
|
assert os.path.exists(go_dir)
|
|
|
|
env = {
|
|
"PATH": f"{go_dir}:{os.environ['PATH']}",
|
|
}
|
|
|
|
assert check_output("go version", env=env).startswith(
|
|
f"go version go{go_version} linux/"
|
|
)
|
|
|
|
with tempfile.TemporaryDirectory(prefix="ynh_") as d:
|
|
with open(f"{d}/helloworld.go", "w") as f:
|
|
f.write(
|
|
"""
|
|
package main
|
|
import "fmt"
|
|
func main() { fmt.Println("hello world") }
|
|
"""
|
|
)
|
|
env["HOME"] = d
|
|
check_call("go build helloworld.go".split(), cwd=d, env=env)
|
|
assert os.path.exists(f"{d}/helloworld")
|
|
assert "hello world" in check_output("./helloworld", cwd=d)
|
|
|
|
r({}, "testapp").deprovision()
|
|
assert not app_setting("testapp", "go_version")
|
|
assert not os.path.exists(go_dir)
|
|
|
|
|
|
def test_resource_composer():
|
|
os.system("echo '[integration]' >> /etc/yunohost/apps/testapp/manifest.toml")
|
|
os.system(
|
|
"echo 'helpers_version = \"2.1\"' >> /etc/yunohost/apps/testapp/manifest.toml"
|
|
)
|
|
|
|
r = AppResourceClassesByType["system_user"]
|
|
r({}, "testapp").provision_or_update()
|
|
|
|
r = AppResourceClassesByType["install_dir"]
|
|
r({}, "testapp").provision_or_update()
|
|
install_dir = app_setting("testapp", "install_dir")
|
|
|
|
r = AppResourceClassesByType["apt"]
|
|
manager = AppResourceManager(
|
|
"testapp",
|
|
current={},
|
|
wanted={"name": "Test App", "integration": {"helpers_version": "2.1"}},
|
|
)
|
|
conf = {"packages": "php8.2-fpm"}
|
|
r(conf, "testapp", manager).provision_or_update()
|
|
|
|
r = AppResourceClassesByType["composer"]
|
|
assert not app_setting("testapp", "composer_version")
|
|
conf = {
|
|
"version": "2.8.3",
|
|
}
|
|
|
|
r(conf, "testapp").provision_or_update()
|
|
assert app_setting("testapp", "composer_version")
|
|
assert os.path.exists(install_dir + "/composer.phar")
|
|
|
|
r(conf, "testapp")._run_script(
|
|
"test_composer_exec",
|
|
f"cd {install_dir}; ynh_composer_exec require symfony/polyfill-mbstring 1.31.0",
|
|
)
|
|
|
|
assert os.path.exists(install_dir + "/.composer")
|
|
assert os.path.exists(install_dir + "/vendor/symfony/polyfill-mbstring")
|
|
|
|
r(conf, "testapp").deprovision()
|
|
assert not app_setting("testapp", "composer_version")
|
|
assert not os.path.exists(install_dir + "/composer.phar")
|