Cleanup
publish / publish (push) Successful in 11m4s

This commit is contained in:
khodowany
2026-10-08 01:31:14 -05:00
parent 3efbe5020a
commit fb93acca1a
19 changed files with 1297 additions and 1207 deletions
+2 -2
View File
@@ -1,3 +1,4 @@
import modulus.build_context
import os
import pathlib
import tempfile
@@ -6,7 +7,6 @@ import unittest.mock
import urllib.error
import modulus.artifacts
import modulus.cli
import modulus.config
class ArtifactTests(unittest.TestCase):
@@ -15,7 +15,7 @@ class ArtifactTests(unittest.TestCase):
self.addCleanup(self.temporary.cleanup)
self.root = pathlib.Path(self.temporary.name)
config = modulus.config.normalize({'package': {'name': 'example', 'artifact': {'enabled': True, 'targets': ['arm_64_gcc12_release']}}})
self.context = modulus.cli.build_context(self.root, config)
self.context = modulus.build_context.build_context(self.root, config)
self.directory = self.root / 'build/packages'
self.directory.mkdir(parents=True)
self.archive = self.directory / modulus.artifacts.archive_name('example', 'arm_64_gcc12_release')
+15 -10
View File
@@ -1,3 +1,8 @@
import modulus.conan
import modulus.build_context
import modulus.container
import modulus.packaging
import modulus.process
import ast
import json
import os
@@ -31,9 +36,9 @@ class BootstrapTests(unittest.TestCase):
def test_read_environments_strip_all_credential_forms(self):
credentials = dict.fromkeys(('CONAN_USER', 'CONAN_TOKEN', 'CONAN_LOGIN_USERNAME', 'CONAN_PASSWORD', 'CONAN_LOGIN_USERNAME_KHODO', 'CONAN_PASSWORD_KHODO'), 'secret')
root = Path('/tmp/project')
context = modulus.cli.build_context(root, modulus.config.normalize({'package': {'name': 'sample'}}))
context = modulus.build_context.build_context(root, modulus.config.normalize({'package': {'name': 'sample'}}))
with patch.dict(os.environ, credentials):
for env in (modulus.bootstrap.fetch_env(root), modulus.cli.subprocess_environment(context, ['conan', 'install'])):
for env in (modulus.bootstrap.fetch_env(root), modulus.process.subprocess_environment(context, ['conan', 'install'])):
self.assertFalse(set(credentials) & env.keys())
self.assertEqual(env['CONAN_NON_INTERACTIVE'], '1')
self.assertEqual(env['CONAN_HOME'], str(root / 'build/build_common/conan_cache'))
@@ -100,26 +105,26 @@ class BootstrapTests(unittest.TestCase):
modulus.export.sync_project(root, package)
self.assertEqual(runtime.read_text(), 'old runtime')
def test_upload_exception_still_logs_out(self):
context = modulus.cli.build_context(Path('/tmp/project'), modulus.config.normalize({'package': {'name': 'sample'}}))
with patch.object(modulus.cli, 'configure_conan_remote', return_value=0), patch.object(modulus.cli, 'upload_all_packages', side_effect=RuntimeError('upload failed')), patch.object(modulus.cli, 'run', return_value=0) as run:
context = modulus.build_context.build_context(Path('/tmp/project'), modulus.config.normalize({'package': {'name': 'sample'}}))
with patch.object(modulus.conan, 'configure_conan_remote', return_value=0), patch.object(modulus.packaging, 'upload_all_packages', side_effect=RuntimeError('upload failed')), patch.object(modulus.process, 'run', return_value=0) as run:
with self.assertRaisesRegex(RuntimeError, 'upload failed'):
modulus.cli.upload_packages(context)
modulus.packaging.upload_packages(context)
run.assert_called_once_with(context, ['conan', 'remote', 'logout', 'khodo'])
def test_socket_is_scoped_and_docker_inputs_change_fingerprint(self):
with tempfile.TemporaryDirectory() as directory:
root = Path(directory)
config = modulus.config.normalize({'package': {'name': 'sample'}, 'tooling': {'docker': {'dockerfile': 'package/build/Dockerfile', 'inputs': ['requirements.txt'], 'socket_commands': ['build', 'package']}}})
context = modulus.cli.build_context(root, config)
context = modulus.build_context.build_context(root, config)
context.dockerfile.parent.mkdir(parents=True)
context.dockerfile.write_text('FROM scratch')
context.docker_inputs[0].parent.mkdir(parents=True)
for path in context.docker_inputs:
path.write_text('old')
before = modulus.clangd.recipe_digest(context)
before = modulus.container.recipe_digest(context)
context.docker_inputs[-1].write_text('new')
self.assertNotEqual(before, modulus.clangd.recipe_digest(context))
self.assertNotEqual(before, modulus.container.recipe_digest(context))
with patch.object(Path, 'is_socket', return_value=True), patch.object(Path, 'stat') as stat:
stat.return_value.st_gid = 123
for command in ('configure', 'test', 'lsp', 'clangd', 'format'):
self.assertEqual(modulus.cli.docker_socket_args(context, command), [])
self.assertIn('/var/run/docker.sock:/var/run/docker.sock', modulus.cli.docker_socket_args(context, 'package'))
self.assertEqual(modulus.container.docker_socket_args(context, command), [])
self.assertIn('/var/run/docker.sock:/var/run/docker.sock', modulus.container.docker_socket_args(context, 'package'))
+17 -13
View File
@@ -1,3 +1,7 @@
import modulus.process
import modulus.build_context
import modulus.container
import modulus.lsp
import contextlib
import io
import json
@@ -19,7 +23,7 @@ class clangd_test(unittest.TestCase):
temporary = tempfile.TemporaryDirectory()
self.addCleanup(temporary.cleanup)
self.root = pathlib.Path(temporary.name)
self.context = modulus.cli.build_context(self.root, modulus.config.normalize({"package": {"name": "sample"}}))
self.context = modulus.build_context.build_context(self.root, modulus.config.normalize({"package": {"name": "sample"}}))
self.context.docker_marker = self.root / "not-in-container"
self.context.dockerfile.parent.mkdir(parents=True)
self.context.dockerfile.write_text("FROM sample\n")
@@ -39,15 +43,15 @@ class clangd_test(unittest.TestCase):
with self.subTest(invalid=invalid), self.assertRaises(modulus.config.config_error):
modulus.config.normalize({"package": {"name": "sample"}, "tooling": {"lsp": {"clangd": invalid}}})
def test_image_fingerprint_and_architecture(self):
image = {"Id": self.image, "Architecture": "amd64", "Config": {"Labels": {modulus.clangd.image_label: modulus.clangd.recipe_digest(self.context)}}}
image = {"Id": self.image, "Architecture": "amd64", "Config": {"Labels": {modulus.container.image_label: modulus.container.recipe_digest(self.context)}}}
with patch.object(subprocess, "run", return_value=subprocess.CompletedProcess([], 0, json.dumps([image]))):
self.assertEqual(modulus.clangd.current_image(self.context), self.image)
self.assertIsNone(modulus.clangd.current_image(self.context, "arm64"))
self.assertEqual(modulus.container.current_image(self.context), self.image)
self.assertIsNone(modulus.container.current_image(self.context, "arm64"))
self.context.dockerfile.write_text("FROM changed\n")
self.assertIsNone(modulus.clangd.current_image(self.context))
self.assertIsNone(modulus.container.current_image(self.context))
def test_cache_is_shared_by_image_and_header_settings_not_repo(self):
cache = modulus.clangd.cache_directory(self.context, self.image)
other = modulus.cli.build_context(self.root / "other", self.context.config)
other = modulus.build_context.build_context(self.root / "other", self.context.config)
self.assertEqual(cache, modulus.clangd.cache_directory(other, self.image))
self.context.lsp_settings["clangd"]["arguments"].append("--log=error")
self.assertEqual(cache, modulus.clangd.cache_directory(self.context, self.image))
@@ -69,8 +73,8 @@ class clangd_test(unittest.TestCase):
self.assertIn("--query-driver=/usr/bin/gcc-12,/usr/bin/g++-12,/usr/bin/aarch64-linux-gnu-gcc-12,/usr/bin/aarch64-linux-gnu-g++-12", command)
def test_startup_failure_does_not_prepare_and_keeps_stdout_clean(self):
output, errors = io.StringIO(), io.StringIO()
with patch.object(modulus.clangd, "current_image", return_value=None), patch.object(modulus.clangd, "prepare") as prepare, \
patch.object(modulus.cli, "ensure_build_image") as build, contextlib.redirect_stdout(output), contextlib.redirect_stderr(errors):
with patch.object(modulus.container, "current_image", return_value=None), patch.object(modulus.clangd, "prepare") as prepare, \
patch.object(modulus.container, "ensure_build_image") as build, contextlib.redirect_stdout(output), contextlib.redirect_stderr(errors):
self.assertEqual(modulus.clangd.launch(self.context, []), 1)
prepare.assert_not_called()
build.assert_not_called()
@@ -100,7 +104,7 @@ class clangd_test(unittest.TestCase):
cache = self.root / "cache"
(cache / "rootfs/usr/include").mkdir(parents=True)
(cache / "manifest.json").write_text(json.dumps({"version": modulus.clangd.cache_version, "roots": ["/usr/include"]}))
with patch.object(modulus.clangd, "cache_directory", return_value=cache), patch.object(modulus.clangd, "current_image", return_value=self.image), \
with patch.object(modulus.clangd, "cache_directory", return_value=cache), patch.object(modulus.container, "current_image", return_value=self.image), \
patch.object(subprocess, "run") as run:
self.assertEqual(modulus.clangd.prepare(self.context), 0)
run.assert_not_called()
@@ -109,7 +113,7 @@ class clangd_test(unittest.TestCase):
process = MagicMock()
process.__enter__.return_value = process
process.stdout = self.archive("../escape")
with patch.object(modulus.clangd, "cache_directory", return_value=cache), patch.object(modulus.clangd, "current_image", return_value=self.image), \
with patch.object(modulus.clangd, "cache_directory", return_value=cache), patch.object(modulus.container, "current_image", return_value=self.image), \
patch.object(subprocess, "run", return_value=subprocess.CompletedProcess([], 0, '["/usr/include"]')), \
patch.object(subprocess, "Popen", return_value=process), contextlib.redirect_stderr(io.StringIO()):
self.assertEqual(modulus.clangd.prepare(self.context), 1)
@@ -138,13 +142,13 @@ class clangd_test(unittest.TestCase):
modulus.export.sync_nvim_file(self.root, {"enabled": False})
self.assertEqual(path.read_text(), "-- user settings\n")
def test_lsp_prepares_after_successful_database_refresh_only(self):
with patch.object(modulus.cli, "in_docker", return_value=False), patch.object(modulus.cli, "docker_run", return_value=0) as run, \
with patch.object(modulus.process, "in_docker", return_value=False), patch.object(modulus.container, "docker_run", return_value=0) as run, \
patch.object(modulus.clangd, "prepare", return_value=0) as prepare:
self.assertEqual(modulus.cli.lsp(self.context, []), 0)
self.assertEqual(modulus.lsp.lsp(self.context, []), 0)
prepare.assert_called_once_with(self.context)
prepare.reset_mock()
run.return_value = 1
self.assertEqual(modulus.cli.lsp(self.context, []), 1)
self.assertEqual(modulus.lsp.lsp(self.context, []), 1)
prepare.assert_not_called()
if __name__ == "__main__":
+140 -127
View File
@@ -1,3 +1,12 @@
import modulus.process
import modulus.build
import modulus.build_context
import modulus.conan
import modulus.container
import modulus.export
import modulus.lsp
import modulus.packaging
import modulus.run
import json
import os
import pathlib
@@ -58,7 +67,7 @@ class upload_packages_test(unittest.TestCase):
"name": "sample",
},
}
return modulus.cli.build_context(repo_root or pathlib.Path(os.getcwd()), modulus.config.normalize(config))
return modulus.build_context.build_context(repo_root or pathlib.Path(os.getcwd()), modulus.config.normalize(config))
def test_cli_import_does_not_import_conan_recipe_module(self):
repo = pathlib.Path(__file__).resolve().parents[1]
command = [
@@ -68,13 +77,17 @@ class upload_packages_test(unittest.TestCase):
]
completed = subprocess.run(command, cwd=repo, check=False)
self.assertEqual(completed.returncode, 0)
def test_build_context_does_not_import_command_or_execution_modules(self):
repo = pathlib.Path(__file__).resolve().parents[1]
command = [sys.executable, "-c", "import sys; import modulus.build_context; forbidden = {'modulus.cli', 'modulus.build', 'modulus.lsp', 'modulus.container', 'modulus.packaging', 'modulus.process'}; raise SystemExit(bool(forbidden & sys.modules.keys()))"]
self.assertEqual(subprocess.run(command, cwd=repo, check=False).returncode, 0)
def test_project_root_build_is_rejected(self):
with tempfile.TemporaryDirectory() as directory:
root = pathlib.Path(directory)
context = self.context(root)
context.config["tooling"]["targets"]["native"]["build_dir"] = "."
with self.assertRaisesRegex(modulus.config.config_error, "project and source roots"):
modulus.cli.build_context(root, context.config)
modulus.build_context.build_context(root, context.config)
def test_configure_and_lsp_refresh_project_editor_settings(self):
with tempfile.TemporaryDirectory() as directory:
root = pathlib.Path(directory)
@@ -84,9 +97,9 @@ class upload_packages_test(unittest.TestCase):
]
config = {"package": {"name": "sample"}, "tooling": {"editor": {"clangd": fragments}}}
(root / "modulus.json").write_text(json.dumps(config), encoding="utf-8")
with unittest.mock.patch.object(modulus.cli, "find_repo_root", return_value=root):
with unittest.mock.patch.object(modulus.build_context, "find_repo_root", return_value=root):
for command in ("configure", "lsp"):
with self.subTest(command=command), unittest.mock.patch.object(modulus.cli, command, return_value=0):
with self.subTest(command=command), unittest.mock.patch.object({'configure': modulus.build, 'lsp': modulus.lsp}[command], command, return_value=0):
(root / ".clangd").write_text("stale", encoding="utf-8")
self.assertEqual(modulus.cli.main(command), 0)
content = (root / ".clangd").read_text(encoding="utf-8").split("\n", 1)[1]
@@ -100,36 +113,36 @@ class upload_packages_test(unittest.TestCase):
context = self.context(root)
cache = root / "CMakeCache.txt"
cache.write_text("keep", encoding="utf-8")
with unittest.mock.patch.object(modulus.cli, "clear_lsp_cmake_cache") as clear:
with unittest.mock.patch.object(modulus.lsp, "clear_lsp_cmake_cache") as clear:
for build_dir in (".", "alias", "subproject"):
if build_dir == "alias":
(root / "alias").symlink_to(root, target_is_directory=True)
with self.subTest(build_dir=build_dir), self.assertRaises(modulus.config.config_error):
modulus.cli.configure_lsp_database(context, {"source_dir": "subproject", "build_dir": build_dir})
modulus.lsp.configure_lsp_database(context, {"source_dir": "subproject", "build_dir": build_dir})
clear.assert_not_called()
self.assertEqual(cache.read_text(encoding="utf-8"), "keep")
@unittest.mock.patch.object(modulus.cli, "upload_all_packages", return_value=37)
@unittest.mock.patch.object(modulus.cli, "configure_conan_remote", return_value=0)
@unittest.mock.patch.object(modulus.cli, "run", return_value=0)
@unittest.mock.patch.object(modulus.packaging, "upload_all_packages", return_value=37)
@unittest.mock.patch.object(modulus.conan, "configure_conan_remote", return_value=0)
@unittest.mock.patch.object(modulus.process, "run", return_value=0)
def test_failed_upload_does_not_force_by_default(self, run, configure, upload):
context = self.context()
with unittest.mock.patch.dict(os.environ, {}, clear=True):
status = modulus.cli.upload_packages(context)
status = modulus.packaging.upload_packages(context)
self.assertEqual(status, 37)
configure.assert_called_once_with(context, authenticate=True)
upload.assert_called_once_with(context, "origin", force=False)
run.assert_called_once_with(context, ["conan", "remote", "logout", "origin"])
@unittest.mock.patch.object(modulus.cli, "upload_all_packages")
@unittest.mock.patch.object(modulus.cli, "configure_conan_remote")
@unittest.mock.patch.object(modulus.packaging, "upload_all_packages")
@unittest.mock.patch.object(modulus.conan, "configure_conan_remote")
def test_replace_requires_guard_env(self, configure, upload):
with unittest.mock.patch.dict(os.environ, {}, clear=True):
status = modulus.cli.upload_packages(self.context(), replace=True)
status = modulus.packaging.upload_packages(self.context(), replace=True)
self.assertEqual(status, 1)
configure.assert_not_called()
upload.assert_not_called()
@unittest.mock.patch.object(modulus.cli, "upload_all_packages", return_value=0)
@unittest.mock.patch.object(modulus.cli, "configure_conan_remote", return_value=0)
@unittest.mock.patch.object(modulus.cli, "run", return_value=0)
@unittest.mock.patch.object(modulus.packaging, "upload_all_packages", return_value=0)
@unittest.mock.patch.object(modulus.conan, "configure_conan_remote", return_value=0)
@unittest.mock.patch.object(modulus.process, "run", return_value=0)
def test_replace_forces_upload_when_guarded(self, run, configure, upload):
context = self.context()
with unittest.mock.patch.dict(
@@ -139,20 +152,20 @@ class upload_packages_test(unittest.TestCase):
},
clear=True,
):
status = modulus.cli.upload_packages(context, replace=True)
status = modulus.packaging.upload_packages(context, replace=True)
self.assertEqual(status, 0)
configure.assert_called_once_with(context, authenticate=True)
upload.assert_called_once_with(context, "origin", force=True)
@unittest.mock.patch.object(modulus.cli, "run", return_value=0)
@unittest.mock.patch.object(modulus.process, "run", return_value=0)
def test_upload_defaults_to_latest_reference(self, run):
with unittest.mock.patch.dict(os.environ, {}, clear=True):
status = modulus.cli.upload_all_packages(self.context(), "origin")
status = modulus.packaging.upload_all_packages(self.context(), "origin")
self.assertEqual(status, 0)
self.assertIn("sample/latest:*", run.call_args.args[1])
self.assertNotIn("--force", run.call_args.args[1])
@unittest.mock.patch.object(modulus.cli, "run", return_value=0)
@unittest.mock.patch.object(modulus.process, "run", return_value=0)
def test_replace_upload_uses_conan_force(self, run):
status = modulus.cli.upload_all_packages(self.context(), "origin", force=True)
status = modulus.packaging.upload_all_packages(self.context(), "origin", force=True)
self.assertEqual(status, 0)
self.assertIn("--force", run.call_args.args[1])
def test_checked_in_ci_overwrites_latest_on_master(self):
@@ -187,11 +200,11 @@ class upload_packages_test(unittest.TestCase):
finally:
os.chdir(previous_cwd)
def test_docker_passthrough_includes_replace_env(self):
passthrough = modulus.cli.docker_passthrough_env(self.context())
passthrough = modulus.container.docker_passthrough_env(self.context())
self.assertIn("MODULUS_ALLOW_PACKAGE_REPLACE", passthrough)
for name in ("CONAN_USER", "CONAN_TOKEN", "PACKAGE_REGISTRY_USER", "PACKAGE_REGISTRY_TOKEN"):
self.assertNotIn(name, passthrough)
self.assertIn(name, modulus.cli.docker_passthrough_env(self.context(), publishing=True))
self.assertIn(name, modulus.container.docker_passthrough_env(self.context(), publishing=True))
self.assertIn("SAMPLE_PACKAGE_UPLOAD", passthrough)
self.assertNotIn("CONAN_PACKAGE_VERSION", passthrough)
self.assertNotIn("MODULUS_EXPORT_RUNTIME", passthrough)
@@ -228,13 +241,13 @@ class upload_packages_test(unittest.TestCase):
},
},
})
@unittest.mock.patch.object(modulus.cli, "in_docker", return_value=True)
@unittest.mock.patch.object(modulus.process, "in_docker", return_value=True)
def test_run_is_disabled_by_default(self, docker):
status = modulus.cli.product_run(self.context(), [])
status = modulus.run.product_run(self.context(), [])
self.assertEqual(status, 1)
docker.assert_not_called()
@unittest.mock.patch.object(modulus.cli, "run", return_value=0)
@unittest.mock.patch.object(modulus.cli, "in_docker", return_value=True)
@unittest.mock.patch.object(modulus.process, "run", return_value=0)
@unittest.mock.patch.object(modulus.process, "in_docker", return_value=True)
def test_run_executes_configured_product_executable(self, docker, run):
with tempfile.TemporaryDirectory() as repo_dir:
repo = pathlib.Path(repo_dir)
@@ -251,7 +264,7 @@ class upload_packages_test(unittest.TestCase):
context.default_target.build_dir.mkdir(parents=True)
executable = context.default_target.build_dir / "sample-app"
executable.write_text("#!/bin/sh\n", encoding="utf-8")
status = modulus.cli.product_run(
status = modulus.run.product_run(
context,
[
"--",
@@ -271,15 +284,15 @@ class upload_packages_test(unittest.TestCase):
)
self.assertEqual(run.call_args.kwargs["env_overrides"], {"SAMPLE_WEB_ROOT": "build/web"})
docker.assert_called_once()
@unittest.mock.patch.object(modulus.cli, "docker_run", return_value=0)
@unittest.mock.patch.object(modulus.cli, "in_docker", return_value=False)
@unittest.mock.patch.object(modulus.container, "docker_run", return_value=0)
@unittest.mock.patch.object(modulus.process, "in_docker", return_value=False)
def test_run_publishes_configured_ports_when_wrapped_by_docker(self, docker, docker_run):
context = self.context()
context.run_settings.update({
"enabled": True,
"ports": ["127.0.0.1:8000:8000/tcp"],
})
status = modulus.cli.product_run(context, ["--target", "native"])
status = modulus.run.product_run(context, ["--target", "native"])
self.assertEqual(status, 0)
docker_run.assert_called_once_with(
context,
@@ -294,7 +307,7 @@ class upload_packages_test(unittest.TestCase):
],
)
docker.assert_called_once()
@unittest.mock.patch.object(modulus.cli, "run", return_value=0)
@unittest.mock.patch.object(modulus.process, "run", return_value=0)
def test_build_image_honors_docker_platform_env(self, run):
context = self.context()
with unittest.mock.patch.dict(
@@ -304,7 +317,7 @@ class upload_packages_test(unittest.TestCase):
},
clear=True,
):
status = modulus.cli.build_image(context)
status = modulus.container.build_image(context)
self.assertEqual(status, 0)
self.assertEqual(
run.call_args.args[1],
@@ -318,15 +331,15 @@ class upload_packages_test(unittest.TestCase):
"--tag",
"sample-build:dev",
"--label",
f"{modulus.cli.modulus.clangd.image_label}={modulus.cli.modulus.clangd.recipe_digest(context)}",
f"{modulus.cli.modulus.container.image_label}={modulus.cli.modulus.container.recipe_digest(context)}",
"--build-arg",
"MODULUS_TOOLS=tools",
".",
],
)
@unittest.mock.patch.object(modulus.cli, "ensure_build_image", return_value=0)
@unittest.mock.patch.object(modulus.cli, "run", return_value=0)
@unittest.mock.patch.object(modulus.cli, "in_container", return_value=False)
@unittest.mock.patch.object(modulus.container, "ensure_build_image", return_value=0)
@unittest.mock.patch.object(modulus.process, "run", return_value=0)
@unittest.mock.patch.object(modulus.process, "in_container", return_value=False)
def test_docker_run_honors_docker_platform_env(self, in_container, run, ensure_image):
context = self.context()
with unittest.mock.patch.dict(
@@ -336,7 +349,7 @@ class upload_packages_test(unittest.TestCase):
},
clear=True,
):
status = modulus.cli.docker_run(context, ["true"])
status = modulus.container.docker_run(context, ["true"])
self.assertEqual(status, 0)
self.assertIn("--platform", run.call_args.args[1])
self.assertIn("linux/arm64", run.call_args.args[1])
@@ -344,17 +357,17 @@ class upload_packages_test(unittest.TestCase):
in_container.assert_called_once()
def test_conan_remote_url_uses_config_by_default(self):
with unittest.mock.patch.dict(os.environ, {}, clear=True):
self.assertEqual(modulus.cli.conan_remote_url(self.context()), "https://example.test/conan")
@unittest.mock.patch.object(modulus.cli, "ensure_build_image", return_value=0)
@unittest.mock.patch.object(modulus.cli, "run", return_value=0)
@unittest.mock.patch.object(modulus.cli, "in_container", return_value=False)
self.assertEqual(modulus.conan.conan_remote_url(self.context()), "https://example.test/conan")
@unittest.mock.patch.object(modulus.container, "ensure_build_image", return_value=0)
@unittest.mock.patch.object(modulus.process, "run", return_value=0)
@unittest.mock.patch.object(modulus.process, "in_container", return_value=False)
def test_publish_forwards_credentials_but_python_does_not(self, in_container, run, ensure_image):
context = self.context()
with unittest.mock.patch.dict(os.environ, {"PACKAGE_REGISTRY_TOKEN": "secret"}, clear=True):
modulus.cli.docker_run(context, ["tools/publish.py"])
modulus.container.docker_run(context, ["tools/publish.py"])
self.assertIn("PACKAGE_REGISTRY_TOKEN", run.call_args.args[1])
self.assertNotIn("secret", run.call_args.args[1])
modulus.cli.docker_run(context, ["tools/python.py", "-m", "generator"])
modulus.container.docker_run(context, ["tools/python.py", "-m", "generator"])
self.assertNotIn("PACKAGE_REGISTRY_TOKEN", run.call_args.args[1])
def test_conan_remote_url_uses_config_in_ci(self):
with unittest.mock.patch.dict(
@@ -364,7 +377,7 @@ class upload_packages_test(unittest.TestCase):
},
clear=True,
):
self.assertEqual(modulus.cli.conan_remote_url(self.context()), "https://example.test/conan")
self.assertEqual(modulus.conan.conan_remote_url(self.context()), "https://example.test/conan")
def test_conan_credentials_only_uses_conan_environment(self):
with unittest.mock.patch.dict(
os.environ,
@@ -375,13 +388,13 @@ class upload_packages_test(unittest.TestCase):
},
clear=True,
):
user, token = modulus.cli.conan_credentials()
user, token = modulus.conan.conan_credentials()
self.assertEqual(user, "dev")
self.assertEqual(token, "secret")
@unittest.mock.patch.object(modulus.cli, "run", return_value=0)
@unittest.mock.patch.object(modulus.process, "run", return_value=0)
def test_configure_remote_skips_login_without_conan_credentials(self, run):
with unittest.mock.patch.dict(os.environ, {}, clear=True):
status = modulus.cli.configure_conan_remote(self.context())
status = modulus.conan.configure_conan_remote(self.context())
self.assertEqual(status, 0)
self.assertEqual(len(run.call_args_list), 2)
self.assertEqual(run.call_args_list[-1].args[1], ["conan", "remote", "logout", "origin"])
@@ -396,13 +409,13 @@ class upload_packages_test(unittest.TestCase):
"https://example.test/conan",
],
)
@unittest.mock.patch.object(modulus.cli, "run", return_value=0)
@unittest.mock.patch.object(modulus.process, "run", return_value=0)
def test_configure_remote_ignores_partial_conan_credentials(self, run):
with unittest.mock.patch.dict(os.environ, {"CONAN_USER": "dev"}, clear=True):
status = modulus.cli.configure_conan_remote(self.context())
status = modulus.conan.configure_conan_remote(self.context())
self.assertEqual(status, 0)
self.assertEqual(run.call_args_list[-1].args[1], ["conan", "remote", "logout", "origin"])
@unittest.mock.patch.object(modulus.cli, "run", return_value=0)
@unittest.mock.patch.object(modulus.process, "run", return_value=0)
def test_configure_remote_skips_login_until_authentication_is_requested(self, run):
context = self.context()
with unittest.mock.patch.dict(
@@ -413,7 +426,7 @@ class upload_packages_test(unittest.TestCase):
},
clear=True,
):
status = modulus.cli.configure_conan_remote(context)
status = modulus.conan.configure_conan_remote(context)
self.assertEqual(status, 0)
self.assertEqual(len(run.call_args_list), 2)
self.assertEqual(
@@ -427,7 +440,7 @@ class upload_packages_test(unittest.TestCase):
"https://example.test/conan",
],
)
@unittest.mock.patch.object(modulus.cli, "run", return_value=0)
@unittest.mock.patch.object(modulus.process, "run", return_value=0)
def test_configure_remote_logs_in_with_hidden_token_when_authenticating(self, run):
context = self.context()
with unittest.mock.patch.dict(
@@ -438,7 +451,7 @@ class upload_packages_test(unittest.TestCase):
},
clear=True,
):
status = modulus.cli.configure_conan_remote(context, authenticate=True)
status = modulus.conan.configure_conan_remote(context, authenticate=True)
self.assertEqual(status, 0)
self.assertEqual(
run.call_args_list[0].args[1],
@@ -526,7 +539,7 @@ class upload_packages_test(unittest.TestCase):
"name": "sample",
},
}
return modulus.cli.build_context(pathlib.Path(os.getcwd()), config)
return modulus.build_context.build_context(pathlib.Path(os.getcwd()), config)
def test_selected_targets_default_to_default_target_only(self):
context = self.multi_target_context()
selected = context.selected_targets(
@@ -541,8 +554,8 @@ class upload_packages_test(unittest.TestCase):
True,
)
self.assertEqual([target.name for target in selected], ["debug", "release"])
@unittest.mock.patch.object(modulus.cli, "run", return_value=0)
@unittest.mock.patch.object(modulus.cli, "in_docker", return_value=True)
@unittest.mock.patch.object(modulus.process, "run", return_value=0)
@unittest.mock.patch.object(modulus.process, "in_docker", return_value=True)
def test_build_can_target_one_cmake_target(self, docker, run):
directory = tempfile.TemporaryDirectory()
self.addCleanup(directory.cleanup)
@@ -550,7 +563,7 @@ class upload_packages_test(unittest.TestCase):
context.default_target.build_dir.mkdir(parents=True, exist_ok=True)
(context.default_target.build_dir / "CMakeCache.txt").write_text("", encoding="utf-8")
(context.default_target.build_dir / "build.ninja").write_text("", encoding="utf-8")
status = modulus.cli.build(
status = modulus.build.build(
context,
[
"--target",
@@ -573,14 +586,14 @@ class upload_packages_test(unittest.TestCase):
],
)
docker.assert_called_once()
@unittest.mock.patch.object(modulus.cli, "run", return_value=0)
@unittest.mock.patch.object(modulus.cli, "configure_one", return_value=0)
@unittest.mock.patch.object(modulus.cli, "configure_conan_remote", return_value=0)
@unittest.mock.patch.object(modulus.cli, "in_docker", return_value=True)
@unittest.mock.patch.object(modulus.process, "run", return_value=0)
@unittest.mock.patch.object(modulus.build, "configure_one", return_value=0)
@unittest.mock.patch.object(modulus.conan, "configure_conan_remote", return_value=0)
@unittest.mock.patch.object(modulus.process, "in_docker", return_value=True)
def test_build_auto_configures_missing_target(self, docker, configure_remote, configure_one, run):
with tempfile.TemporaryDirectory() as repo_dir:
context = self.context(repo_root=pathlib.Path(repo_dir))
status = modulus.cli.build(context, [])
status = modulus.build.build(context, [])
self.assertEqual(status, 0)
configure_remote.assert_called_once_with(context)
configure_one.assert_called_once_with(context, context.default_target, update=False)
@@ -595,17 +608,17 @@ class upload_packages_test(unittest.TestCase):
],
)
docker.assert_called_once()
@unittest.mock.patch.object(modulus.cli, "run", return_value=0)
@unittest.mock.patch.object(modulus.cli, "configure_one", return_value=0)
@unittest.mock.patch.object(modulus.cli, "configure_conan_remote", return_value=0)
@unittest.mock.patch.object(modulus.cli, "in_docker", return_value=True)
@unittest.mock.patch.object(modulus.process, "run", return_value=0)
@unittest.mock.patch.object(modulus.build, "configure_one", return_value=0)
@unittest.mock.patch.object(modulus.conan, "configure_conan_remote", return_value=0)
@unittest.mock.patch.object(modulus.process, "in_docker", return_value=True)
def test_build_skips_configure_when_target_is_configured(self, docker, configure_remote, configure_one, run):
with tempfile.TemporaryDirectory() as repo_dir:
context = self.context(repo_root=pathlib.Path(repo_dir))
context.default_target.build_dir.mkdir(parents=True)
(context.default_target.build_dir / "CMakeCache.txt").write_text("", encoding="utf-8")
(context.default_target.build_dir / "build.ninja").write_text("", encoding="utf-8")
status = modulus.cli.build(context, [])
status = modulus.build.build(context, [])
self.assertEqual(status, 0)
configure_remote.assert_not_called()
configure_one.assert_not_called()
@@ -620,10 +633,10 @@ class upload_packages_test(unittest.TestCase):
],
)
docker.assert_called_once()
@unittest.mock.patch.object(modulus.cli, "run", return_value=0)
@unittest.mock.patch.object(modulus.cli, "configure_one", return_value=0)
@unittest.mock.patch.object(modulus.cli, "configure_conan_remote", return_value=0)
@unittest.mock.patch.object(modulus.cli, "in_docker", return_value=True)
@unittest.mock.patch.object(modulus.process, "run", return_value=0)
@unittest.mock.patch.object(modulus.build, "configure_one", return_value=0)
@unittest.mock.patch.object(modulus.conan, "configure_conan_remote", return_value=0)
@unittest.mock.patch.object(modulus.process, "in_docker", return_value=True)
def test_build_reconfigures_when_target_cmake_definition_differs(self, docker, configure_remote, configure_one, run):
with tempfile.TemporaryDirectory() as repo_dir:
context = self.context(repo_root=pathlib.Path(repo_dir))
@@ -633,7 +646,7 @@ class upload_packages_test(unittest.TestCase):
context.default_target.build_dir.mkdir(parents=True)
(context.default_target.build_dir / "CMakeCache.txt").write_text("SAMPLE_WITH_WEB:BOOL=OFF\n", encoding="utf-8")
(context.default_target.build_dir / "build.ninja").write_text("", encoding="utf-8")
status = modulus.cli.build(context, [])
status = modulus.build.build(context, [])
self.assertEqual(status, 0)
configure_remote.assert_called_once_with(context)
configure_one.assert_called_once_with(context, context.default_target, update=False)
@@ -648,26 +661,26 @@ class upload_packages_test(unittest.TestCase):
],
)
docker.assert_called_once()
@unittest.mock.patch.object(modulus.cli, "run", return_value=0)
@unittest.mock.patch.object(modulus.cli, "configure_one", return_value=37)
@unittest.mock.patch.object(modulus.cli, "configure_conan_remote", return_value=0)
@unittest.mock.patch.object(modulus.cli, "in_docker", return_value=True)
@unittest.mock.patch.object(modulus.process, "run", return_value=0)
@unittest.mock.patch.object(modulus.build, "configure_one", return_value=37)
@unittest.mock.patch.object(modulus.conan, "configure_conan_remote", return_value=0)
@unittest.mock.patch.object(modulus.process, "in_docker", return_value=True)
def test_build_stops_when_auto_configure_fails(self, docker, configure_remote, configure_one, run):
with tempfile.TemporaryDirectory() as repo_dir:
context = self.context(repo_root=pathlib.Path(repo_dir))
status = modulus.cli.build(context, [])
status = modulus.build.build(context, [])
self.assertEqual(status, 37)
configure_remote.assert_called_once_with(context)
configure_one.assert_called_once_with(context, context.default_target, update=False)
run.assert_not_called()
docker.assert_called_once()
@unittest.mock.patch.object(modulus.cli, "configure_one", return_value=0)
@unittest.mock.patch.object(modulus.cli, "configure_conan_remote", return_value=0)
@unittest.mock.patch.object(modulus.cli, "in_docker", return_value=True)
@unittest.mock.patch.object(modulus.build, "configure_one", return_value=0)
@unittest.mock.patch.object(modulus.conan, "configure_conan_remote", return_value=0)
@unittest.mock.patch.object(modulus.process, "in_docker", return_value=True)
def test_configure_no_remote_skips_remote_setup(self, docker, configure_remote, configure_one):
with tempfile.TemporaryDirectory() as repo_dir:
context = self.context(repo_root=pathlib.Path(repo_dir))
status = modulus.cli.configure(
status = modulus.build.configure(
context,
[
"--target",
@@ -679,10 +692,10 @@ class upload_packages_test(unittest.TestCase):
configure_remote.assert_not_called()
configure_one.assert_called_once_with(context, context.default_target, False, no_remote=True)
docker.assert_called_once()
@unittest.mock.patch.object(modulus.cli, "upload_packages", return_value=0)
@unittest.mock.patch.object(modulus.cli, "create_package", return_value=0)
@unittest.mock.patch.object(modulus.cli, "configure_conan_remote", return_value=0)
@unittest.mock.patch.object(modulus.cli, "in_docker", return_value=True)
@unittest.mock.patch.object(modulus.packaging, "upload_packages", return_value=0)
@unittest.mock.patch.object(modulus.packaging, "create_package", return_value=0)
@unittest.mock.patch.object(modulus.conan, "configure_conan_remote", return_value=0)
@unittest.mock.patch.object(modulus.process, "in_docker", return_value=True)
def test_package_no_remote_skips_remote_setup_and_upload(self, docker, configure_remote, create_package, upload):
context = self.context()
with unittest.mock.patch.dict(
@@ -692,7 +705,7 @@ class upload_packages_test(unittest.TestCase):
},
clear=True,
):
status = modulus.cli.package(
status = modulus.packaging.package(
context,
[
"--target",
@@ -705,10 +718,10 @@ class upload_packages_test(unittest.TestCase):
create_package.assert_called_once_with(context, context.default_target, False, no_remote=True)
upload.assert_not_called()
docker.assert_called_once()
@unittest.mock.patch.object(modulus.cli, "upload_packages", return_value=0)
@unittest.mock.patch.object(modulus.cli, "create_package", return_value=0)
@unittest.mock.patch.object(modulus.cli, "configure_conan_remote", return_value=0)
@unittest.mock.patch.object(modulus.cli, "in_docker", return_value=True)
@unittest.mock.patch.object(modulus.packaging, "upload_packages", return_value=0)
@unittest.mock.patch.object(modulus.packaging, "create_package", return_value=0)
@unittest.mock.patch.object(modulus.conan, "configure_conan_remote", return_value=0)
@unittest.mock.patch.object(modulus.process, "in_docker", return_value=True)
def test_package_configures_remote_once_before_upload(self, docker, configure_remote, create_package, upload):
context = self.context()
with unittest.mock.patch.dict(
@@ -720,7 +733,7 @@ class upload_packages_test(unittest.TestCase):
},
clear=True,
):
status = modulus.cli.package(
status = modulus.packaging.package(
context,
[
"--target",
@@ -732,10 +745,10 @@ class upload_packages_test(unittest.TestCase):
create_package.assert_called_once_with(context, context.default_target, False, no_remote=False)
upload.assert_called_once_with(context, replace=False)
docker.assert_called_once()
@unittest.mock.patch.object(modulus.cli, "upload_packages", return_value=1)
@unittest.mock.patch.object(modulus.cli, "create_package", return_value=0)
@unittest.mock.patch.object(modulus.cli, "configure_conan_remote", return_value=0)
@unittest.mock.patch.object(modulus.cli, "in_docker", return_value=True)
@unittest.mock.patch.object(modulus.packaging, "upload_packages", return_value=1)
@unittest.mock.patch.object(modulus.packaging, "create_package", return_value=0)
@unittest.mock.patch.object(modulus.conan, "configure_conan_remote", return_value=0)
@unittest.mock.patch.object(modulus.process, "in_docker", return_value=True)
def test_package_defers_conan_upload_credentials_until_after_create(self, docker, configure_remote, create_package, upload):
context = self.context()
with unittest.mock.patch.dict(
@@ -745,7 +758,7 @@ class upload_packages_test(unittest.TestCase):
},
clear=True,
):
status = modulus.cli.package(
status = modulus.packaging.package(
context,
[
"--target",
@@ -757,9 +770,9 @@ class upload_packages_test(unittest.TestCase):
create_package.assert_called_once_with(context, context.default_target, False, no_remote=False)
upload.assert_called_once_with(context, replace=False)
docker.assert_called_once()
@unittest.mock.patch.object(modulus.cli, "create_package", return_value=0)
@unittest.mock.patch.object(modulus.cli, "run", return_value=0)
@unittest.mock.patch.object(modulus.cli, "in_docker", return_value=True)
@unittest.mock.patch.object(modulus.packaging, "create_package", return_value=0)
@unittest.mock.patch.object(modulus.process, "run", return_value=0)
@unittest.mock.patch.object(modulus.process, "in_docker", return_value=True)
def test_package_checks_credentials_only_at_upload(self, docker, run, create_package):
context = self.context()
with unittest.mock.patch.dict(
@@ -770,7 +783,7 @@ class upload_packages_test(unittest.TestCase):
},
clear=True,
):
status = modulus.cli.package(
status = modulus.packaging.package(
context,
[
"--target",
@@ -781,11 +794,11 @@ class upload_packages_test(unittest.TestCase):
create_package.assert_called_once()
self.assertEqual(run.call_args_list[-1].args[1], ["conan", "remote", "logout", "origin"])
docker.assert_called_once()
@unittest.mock.patch.object(modulus.cli, "clear_conan_deps")
@unittest.mock.patch.object(modulus.cli, "run", return_value=0)
@unittest.mock.patch.object(modulus.build, "clear_conan_deps")
@unittest.mock.patch.object(modulus.process, "run", return_value=0)
def test_configure_one_passes_no_remote_to_conan_install(self, run, clear):
context = self.context()
status = modulus.cli.configure_one(context, context.default_target, update=False, no_remote=True)
status = modulus.build.configure_one(context, context.default_target, update=False, no_remote=True)
self.assertEqual(status, 0)
conan_command = run.call_args_list[0].args[1]
self.assertIn("--no-remote", conan_command)
@@ -796,8 +809,8 @@ class upload_packages_test(unittest.TestCase):
self.assertIn(f"-DCMAKE_TOOLCHAIN_FILE={context.default_target.build_dir / 'conan' / 'conan_toolchain.cmake'}", run.call_args_list[1].args[1])
self.assertIn("-DCMAKE_BUILD_TYPE=Release", run.call_args_list[1].args[1])
clear.assert_called_once()
@unittest.mock.patch.object(modulus.cli, "clear_conan_deps")
@unittest.mock.patch.object(modulus.cli, "run", return_value=0)
@unittest.mock.patch.object(modulus.build, "clear_conan_deps")
@unittest.mock.patch.object(modulus.process, "run", return_value=0)
def test_configure_one_passes_target_cmake_definitions(self, run, clear):
context = self.context()
context.default_target.cmake_definitions = {
@@ -805,17 +818,17 @@ class upload_packages_test(unittest.TestCase):
"SAMPLE_MODE": "dev",
"SAMPLE_LIMIT": 2,
}
status = modulus.cli.configure_one(context, context.default_target, update=False)
status = modulus.build.configure_one(context, context.default_target, update=False)
self.assertEqual(status, 0)
cmake_command = run.call_args_list[1].args[1]
self.assertIn("-DSAMPLE_WITH_WEB=ON", cmake_command)
self.assertIn("-DSAMPLE_MODE=dev", cmake_command)
self.assertIn("-DSAMPLE_LIMIT=2", cmake_command)
clear.assert_called_once()
@unittest.mock.patch.object(modulus.cli, "configure_lsp_database", return_value=0)
@unittest.mock.patch.object(modulus.cli, "configure_one", return_value=0)
@unittest.mock.patch.object(modulus.cli, "configure_conan_remote", return_value=0)
@unittest.mock.patch.object(modulus.cli, "in_docker", return_value=True)
@unittest.mock.patch.object(modulus.lsp, "configure_lsp_database", return_value=0)
@unittest.mock.patch.object(modulus.build, "configure_one", return_value=0)
@unittest.mock.patch.object(modulus.conan, "configure_conan_remote", return_value=0)
@unittest.mock.patch.object(modulus.process, "in_docker", return_value=True)
def test_lsp_configures_default_target_and_extra_databases(self, docker, configure_remote, configure_one, configure_lsp):
context = self.context()
database = {
@@ -833,18 +846,18 @@ class upload_packages_test(unittest.TestCase):
"enabled": True,
"compile_databases": [database],
}
status = modulus.cli.lsp(context, [])
status = modulus.lsp.lsp(context, [])
self.assertEqual(status, 0)
configure_remote.assert_called_once_with(context)
configure_one.assert_called_once_with(context, context.default_target, False, no_remote=False)
configure_lsp.assert_called_once_with(context, database)
docker.assert_called_once()
@unittest.mock.patch.object(modulus.cli, "run", return_value=0)
@unittest.mock.patch.object(modulus.process, "run", return_value=0)
def test_configure_lsp_database_passes_cmake_definitions_and_unsets_env(self, run):
with tempfile.TemporaryDirectory() as repo_dir:
repo = pathlib.Path(repo_dir)
context = self.context(repo_root=repo)
status = modulus.cli.configure_lsp_database(
status = modulus.lsp.configure_lsp_database(
context,
{
"name": "pico",
@@ -865,30 +878,30 @@ class upload_packages_test(unittest.TestCase):
self.assertIn("-DVAMP_PICO_FIRMWARE_PROJECT=ON", command)
self.assertEqual(run.call_args.kwargs["env_overrides"], {"PICO_SDK_PATH": "/opt/pico-sdk"})
self.assertEqual(run.call_args.kwargs["env_unset"], ["CC", "CXX"])
@unittest.mock.patch.object(modulus.cli, "clear_conan_deps")
@unittest.mock.patch.object(modulus.cli, "run", return_value=0)
@unittest.mock.patch.object(modulus.build, "clear_conan_deps")
@unittest.mock.patch.object(modulus.process, "run", return_value=0)
def test_configure_one_allows_public_repos_to_build_missing_dependencies(self, run, clear):
context = self.context()
status = modulus.cli.configure_one(context, context.default_target, update=False)
status = modulus.build.configure_one(context, context.default_target, update=False)
self.assertEqual(status, 0)
conan_command = run.call_args_list[0].args[1]
self.assertIn("--build=missing", conan_command)
clear.assert_called_once()
@unittest.mock.patch.object(modulus.cli, "run", return_value=0)
@unittest.mock.patch.object(modulus.process, "run", return_value=0)
def test_create_package_passes_no_remote_to_conan_create(self, run):
with tempfile.TemporaryDirectory() as repo_dir:
context = self.context(repo_root=pathlib.Path(repo_dir))
status = modulus.cli.create_package(context, context.default_target, update=False, no_remote=True)
status = modulus.packaging.create_package(context, context.default_target, update=False, no_remote=True)
self.assertEqual(status, 0)
self.assertIn("&:with_tests=False", run.call_args.args[1])
self.assertIn("--build=sample/*", run.call_args.args[1])
self.assertIn("--build=missing", run.call_args.args[1])
self.assertIn("--no-remote", run.call_args.args[1])
@unittest.mock.patch.object(modulus.cli, "run", return_value=0)
@unittest.mock.patch.object(modulus.process, "run", return_value=0)
def test_create_package_allows_public_repos_to_build_missing_dependencies(self, run):
with tempfile.TemporaryDirectory() as repo_dir:
context = self.context(repo_root=pathlib.Path(repo_dir))
status = modulus.cli.create_package(context, context.default_target, update=False)
status = modulus.packaging.create_package(context, context.default_target, update=False)
self.assertEqual(status, 0)
self.assertIn("--build=sample/*", run.call_args.args[1])
self.assertIn("--build=missing", run.call_args.args[1])
@@ -909,12 +922,12 @@ class upload_packages_test(unittest.TestCase):
})
def fake_run(run_context, command, **kwargs):
if command[:2] == ["cmake", "--install"]:
install_root = modulus.cli.package_artifact_build_root(context, context.default_target) / "stage" / "usr"
install_root = modulus.packaging.package_artifact_build_root(context, context.default_target) / "stage" / "usr"
(install_root / "bin").mkdir(parents=True)
(install_root / "bin" / "sample").write_text("binary\n", encoding="utf-8")
return 0
with unittest.mock.patch.object(modulus.cli, "run", side_effect=fake_run) as run:
status, artifacts = modulus.cli.create_artifact_package(context, context.default_target, update=False, no_remote=True)
with unittest.mock.patch.object(modulus.process, "run", side_effect=fake_run) as run:
status, artifacts = modulus.packaging.create_artifact_package(context, context.default_target, update=False, no_remote=True)
self.assertEqual(status, 0)
archive = repo / "build" / "packages" / "sample_native.tar.gz"
checksum = archive.with_name(archive.name + ".sha256")
@@ -933,13 +946,13 @@ class upload_packages_test(unittest.TestCase):
cmake_command = run.call_args_list[1].args[1]
self.assertIn("-DSAMPLE_WITH_WEB=ON", cmake_command)
self.assertIn(f"-DCMAKE_INSTALL_PREFIX={repo / 'build' / 'build_common' / 'artifacts' / 'native' / 'stage' / 'usr'}", cmake_command)
@unittest.mock.patch.object(modulus.cli, "in_docker", return_value=True)
@unittest.mock.patch.object(modulus.cli, "create_artifact_package", return_value=(0, []))
@unittest.mock.patch.object(modulus.process, "in_docker", return_value=True)
@unittest.mock.patch.object(modulus.packaging, "create_artifact_package", return_value=(0, []))
def test_artifact_command_needs_no_release_argument(self, create, docker):
with tempfile.TemporaryDirectory() as temporary:
context = self.context(repo_root=pathlib.Path(temporary))
context.package["artifact"]["enabled"] = True
self.assertEqual(modulus.cli.package_artifacts(context, ["--no-remote"]), 0)
self.assertEqual(modulus.packaging.package_artifacts(context, ["--no-remote"]), 0)
create.assert_called_once_with(context, context.default_target, False, no_remote=True)
if __name__ == "__main__":
+6 -3
View File
@@ -1,3 +1,6 @@
import modulus.container
import modulus.build_context
import modulus.clangd
import ast
import contextlib
import io
@@ -114,13 +117,13 @@ class formatting_test(unittest.TestCase):
def test_stdin_failure_has_no_output_and_never_builds_image(self):
with tempfile.TemporaryDirectory() as directory:
root = pathlib.Path(directory)
context = modulus.cli.build_context(root, modulus.config.normalize({"package": {"name": "sample"}}))
context = modulus.build_context.build_context(root, modulus.config.normalize({"package": {"name": "sample"}}))
context.docker_marker = root / "not-in-container"
output, errors = io.StringIO(), io.StringIO()
with patch.dict(os.environ, {"MODULUS_DIRECT": "1"}), patch("sys.stdin", io.StringIO("def broken(")), contextlib.redirect_stdout(output), contextlib.redirect_stderr(errors):
self.assertEqual(modulus.formatting.launch(context, ["--stdin-filename", "test.py"]), 1)
self.assertEqual(output.getvalue(), "")
with patch.dict(os.environ, {"MODULUS_DIRECT": "0"}), patch.object(modulus.clangd, "current_image", return_value=None), patch.object(modulus.cli, "ensure_build_image") as build, contextlib.redirect_stderr(errors):
with patch.dict(os.environ, {"MODULUS_DIRECT": "0"}), patch.object(modulus.container, "current_image", return_value=None), patch.object(modulus.container, "ensure_build_image") as build, contextlib.redirect_stderr(errors):
self.assertEqual(modulus.formatting.launch(context, ["--check"]), 1)
build.assert_not_called()
def test_discovery_excludes_generated_and_symlinks(self):
@@ -142,7 +145,7 @@ class formatting_test(unittest.TestCase):
source = 'def example(name):\n return f"""first {name}\n\nsecond\n\nthird"""\n'
self.assertEqual(self.formatted(source, ".py"), source)
def test_alias_check_distinguishes_module_aliases_from_saved_callbacks(self):
source = 'import modulus.cli\nsaved = modulus.cli.docker_run\nconfig = modulus.cli\nItems = list[int]\n'
source = 'import modulus.cli\nsaved = modulus.container.docker_run\nconfig = modulus.cli\nItems = list[int]\n'
self.assertEqual([line for line, _ in modulus.format_layout.alias_diagnostics(source, ".py")], [3, 4])
def test_exported_stdin_formatter_needs_no_compile_database(self):
with tempfile.TemporaryDirectory() as directory:
+5 -4
View File
@@ -1,3 +1,5 @@
import modulus.build_context
import modulus.process
import pathlib
import subprocess
import sys
@@ -5,13 +7,12 @@ import tempfile
import unittest
import unittest.mock
import modulus.cli
import modulus.config
import modulus.python
class PythonTests(unittest.TestCase):
def context(self, root, groups):
return modulus.cli.build_context(root, modulus.config.normalize({'package': {'name': 'example'}, 'tooling': {'python': {'groups': groups}}}))
return modulus.build_context.build_context(root, modulus.config.normalize({'package': {'name': 'example'}, 'tooling': {'python': {'groups': groups}}}))
def test_optional_packages_are_not_needed_by_default(self):
with tempfile.TemporaryDirectory() as temporary, unittest.mock.patch.object(subprocess, 'run') as run:
context = self.context(pathlib.Path(temporary), [])
@@ -20,10 +21,10 @@ class PythonTests(unittest.TestCase):
def test_conan_reuses_the_project_environment_and_preserves_offline_mode(self):
with tempfile.TemporaryDirectory() as temporary:
context = self.context(pathlib.Path(temporary), ['assets'])
environment = modulus.cli.subprocess_environment(context, ['conan', 'install', '.', '--no-remote'])
environment = modulus.process.subprocess_environment(context, ['conan', 'install', '.', '--no-remote'])
self.assertEqual(environment['MODULUS_PYTHON_COMMON_DIR'], str(context.common_dir))
self.assertEqual(environment['MODULUS_PYTHON_OFFLINE'], '1')
environment = modulus.cli.subprocess_environment(context, ['conan', 'install', '.'])
environment = modulus.process.subprocess_environment(context, ['conan', 'install', '.'])
self.assertEqual(environment['MODULUS_PYTHON_OFFLINE'], '0')
def test_missing_dependencies_require_configure_and_never_download_during_build(self):
with tempfile.TemporaryDirectory() as temporary, unittest.mock.patch.object(subprocess, 'run') as run: