From e7d139832d70623f705894c6ec7eef335bb485e5 Mon Sep 17 00:00:00 2001 From: Burt Holzman Date: Wed, 5 Feb 2025 16:46:18 -0600 Subject: [PATCH 1/7] Add test case for test_create::test_target_prefix This adds the case to simulate what happens when ${MAMBA_ROOT_PREFIX}/envs already exists. --- micromamba/tests/test_create.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/micromamba/tests/test_create.py b/micromamba/tests/test_create.py index 56b0089c4d..78f9c5be3d 100644 --- a/micromamba/tests/test_create.py +++ b/micromamba/tests/test_create.py @@ -253,6 +253,7 @@ def test_env_logging_overhead_regression(tmp_home, tmp_root_prefix, tmp_path): "similar_non_canonical,non_canonical_position", ((False, None), (True, "append"), (True, "prepend")), ) +@pytest.mark.parametrize("root_prefix_env_exists", (False, True)) def test_target_prefix( tmp_home, tmp_root_prefix, @@ -266,6 +267,7 @@ def test_target_prefix( current_target_prefix_fallback, similar_non_canonical, non_canonical_position, + root_prefix_env_exists ): cmd = [] @@ -277,6 +279,9 @@ def test_target_prefix( else: root_prefix = Path(os.environ["MAMBA_ROOT_PREFIX"]) + if root_prefix_env_exists: + os.mkdir((Path(os.environ["MAMBA_ROOT_PREFIX"]) / "envs")) + env_prefix = tmp_path / "myenv" if target_is_root: From f6e2e27da9b07f8533f09e0c5668ca07565535c4 Mon Sep 17 00:00:00 2001 From: Burt Holzman Date: Fri, 7 Feb 2025 17:23:03 -0600 Subject: [PATCH 2/7] Source for config item is a list of at least size 1 --- libmamba/include/mamba/api/configuration_impl.hpp | 2 +- libmamba/src/core/context.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/libmamba/include/mamba/api/configuration_impl.hpp b/libmamba/include/mamba/api/configuration_impl.hpp index 365205b800..dd16254b42 100644 --- a/libmamba/include/mamba/api/configuration_impl.hpp +++ b/libmamba/include/mamba/api/configuration_impl.hpp @@ -83,7 +83,7 @@ namespace mamba { static std::vector default_value(const std::vector& init) { - return std::vector(init.size(), "default"); + return std::vector(std::max(1, init.size()), "default"); }; static void merge( diff --git a/libmamba/src/core/context.cpp b/libmamba/src/core/context.cpp index e436c59f97..f734c0f7b6 100644 --- a/libmamba/src/core/context.cpp +++ b/libmamba/src/core/context.cpp @@ -181,7 +181,7 @@ namespace mamba prefix_params.root_prefix = detail::get_root_prefix(); prefix_params.conda_prefix = prefix_params.root_prefix; - envs_dirs = { prefix_params.root_prefix / "envs" }; + envs_dirs = { }; pkgs_dirs = { prefix_params.root_prefix / "pkgs", fs::u8path("~") / ".mamba" / "pkgs" #ifdef _WIN32 From 93008a4d4a0dfb496c5e6bd54b4f56e411bec8b2 Mon Sep 17 00:00:00 2001 From: Burt Holzman Date: Tue, 11 Feb 2025 11:25:03 -0600 Subject: [PATCH 3/7] Linter fixes --- libmamba/include/mamba/api/configuration_impl.hpp | 2 +- libmamba/src/core/context.cpp | 2 +- micromamba/tests/test_create.py | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/libmamba/include/mamba/api/configuration_impl.hpp b/libmamba/include/mamba/api/configuration_impl.hpp index dd16254b42..45e82424be 100644 --- a/libmamba/include/mamba/api/configuration_impl.hpp +++ b/libmamba/include/mamba/api/configuration_impl.hpp @@ -83,7 +83,7 @@ namespace mamba { static std::vector default_value(const std::vector& init) { - return std::vector(std::max(1, init.size()), "default"); + return std::vector(std::max(1, init.size()), "default"); }; static void merge( diff --git a/libmamba/src/core/context.cpp b/libmamba/src/core/context.cpp index f734c0f7b6..b0b1310f47 100644 --- a/libmamba/src/core/context.cpp +++ b/libmamba/src/core/context.cpp @@ -181,7 +181,7 @@ namespace mamba prefix_params.root_prefix = detail::get_root_prefix(); prefix_params.conda_prefix = prefix_params.root_prefix; - envs_dirs = { }; + envs_dirs = {}; pkgs_dirs = { prefix_params.root_prefix / "pkgs", fs::u8path("~") / ".mamba" / "pkgs" #ifdef _WIN32 diff --git a/micromamba/tests/test_create.py b/micromamba/tests/test_create.py index 78f9c5be3d..06d5ed34fc 100644 --- a/micromamba/tests/test_create.py +++ b/micromamba/tests/test_create.py @@ -267,7 +267,7 @@ def test_target_prefix( current_target_prefix_fallback, similar_non_canonical, non_canonical_position, - root_prefix_env_exists + root_prefix_env_exists, ): cmd = [] @@ -280,7 +280,7 @@ def test_target_prefix( root_prefix = Path(os.environ["MAMBA_ROOT_PREFIX"]) if root_prefix_env_exists: - os.mkdir((Path(os.environ["MAMBA_ROOT_PREFIX"]) / "envs")) + os.mkdir(Path(os.environ["MAMBA_ROOT_PREFIX"]) / "envs") env_prefix = tmp_path / "myenv" From dfe768a9da8c91dddfb2d9a3d151008d626a9244 Mon Sep 17 00:00:00 2001 From: Burt Holzman Date: Tue, 11 Feb 2025 16:06:13 -0600 Subject: [PATCH 4/7] Add test for root prefix precedence --- micromamba/tests/test_create.py | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/micromamba/tests/test_create.py b/micromamba/tests/test_create.py index 06d5ed34fc..1b07d1349b 100644 --- a/micromamba/tests/test_create.py +++ b/micromamba/tests/test_create.py @@ -666,6 +666,39 @@ def test_create_envs_dirs(tmp_root_prefix: Path, tmp_path: Path): assert (tmp_path / env_name / "conda-meta" / "history").exists() +@pytest.mark.parametrize("cli_root_prefix", (False, True)) +@pytest.mark.parametrize("user_envs_dirs", (False, True)) +def test_root_prefix_precedence(monkeypatch, tmp_path, user_envs_dirs, cli_root_prefix): + """Test for root prefix precedence""" + + envroot = tmp_path / "envroot" + cliroot = tmp_path / "cliroot" + userenv = tmp_path / "userenv" / "envs" + + map(lambda p: os.makedirs(p), (envroot, cliroot, userenv)) + + monkeypatch.setenv("MAMBA_ROOT_PREFIX", str(envroot)) + cmd = ["mamba", "create", "-n", "foo", "--print-config-only", "--debug"] + + if cli_root_prefix: + cmd += ["-r", cliroot] + + if user_envs_dirs: + monkeypatch.setenv("CONDA_ENVS_DIRS", str(userenv)) + + res = helpers.create(*cmd) + envs_dirs = res["envs_dirs"] + + if user_envs_dirs: + assert envs_dirs[0] == str(userenv) + envs_dirs = envs_dirs[1:] + + if cli_root_prefix: + assert envs_dirs[0] == str(cliroot / "envs") + else: + assert envs_dirs[0] == str(envroot / "envs") + + @pytest.mark.skipif( helpers.dry_run_tests is helpers.DryRun.ULTRA_DRY, reason="Running only ultra-dry tests", From 94fffbc5a1b8f6972343d11cbbf73be5d29ab242 Mon Sep 17 00:00:00 2001 From: Burt Holzman Date: Wed, 12 Feb 2025 09:57:25 -0600 Subject: [PATCH 5/7] Add env create to root prefix precedence test --- micromamba/tests/test_create.py | 54 ++++++++++++++++++++++----------- 1 file changed, 36 insertions(+), 18 deletions(-) diff --git a/micromamba/tests/test_create.py b/micromamba/tests/test_create.py index 1b07d1349b..d68c857ae7 100644 --- a/micromamba/tests/test_create.py +++ b/micromamba/tests/test_create.py @@ -280,7 +280,7 @@ def test_target_prefix( root_prefix = Path(os.environ["MAMBA_ROOT_PREFIX"]) if root_prefix_env_exists: - os.mkdir(Path(os.environ["MAMBA_ROOT_PREFIX"]) / "envs") + os.makedirs(Path(os.environ["MAMBA_ROOT_PREFIX"]) / "envs", exist_ok=True) env_prefix = tmp_path / "myenv" @@ -668,35 +668,53 @@ def test_create_envs_dirs(tmp_root_prefix: Path, tmp_path: Path): @pytest.mark.parametrize("cli_root_prefix", (False, True)) @pytest.mark.parametrize("user_envs_dirs", (False, True)) -def test_root_prefix_precedence(monkeypatch, tmp_path, user_envs_dirs, cli_root_prefix): +@pytest.mark.parametrize("check_config", (False, True)) +def test_root_prefix_precedence( + monkeypatch, tmp_path, user_envs_dirs, cli_root_prefix, check_config +): """Test for root prefix precedence""" envroot = tmp_path / "envroot" + envroot_envs = envroot / "envs" cliroot = tmp_path / "cliroot" - userenv = tmp_path / "userenv" / "envs" - - map(lambda p: os.makedirs(p), (envroot, cliroot, userenv)) + cliroot_envs = cliroot / "envs" + userenv = tmp_path / "userenv" + userenv_envs = userenv / "envs" monkeypatch.setenv("MAMBA_ROOT_PREFIX", str(envroot)) - cmd = ["mamba", "create", "-n", "foo", "--print-config-only", "--debug"] - - if cli_root_prefix: - cmd += ["-r", cliroot] - if user_envs_dirs: - monkeypatch.setenv("CONDA_ENVS_DIRS", str(userenv)) + monkeypatch.setenv("CONDA_ENVS_DIRS", str(userenv_envs)) - res = helpers.create(*cmd) - envs_dirs = res["envs_dirs"] + for i in (envroot, cliroot, userenv_envs): + os.makedirs(i, exist_ok=True) - if user_envs_dirs: - assert envs_dirs[0] == str(userenv) - envs_dirs = envs_dirs[1:] + cmd = ["-n", "foo"] + + if check_config: + cmd += ["--print-config-only", "--debug"] if cli_root_prefix: - assert envs_dirs[0] == str(cliroot / "envs") + cmd += ["-r", cliroot] + + res = helpers.create(*cmd, create_cmd="create") + + if check_config: + envs_dirs = res["envs_dirs"] + if user_envs_dirs: + assert envs_dirs[0] == str(userenv_envs) + envs_dirs = envs_dirs[1:] + if cli_root_prefix: + assert envs_dirs[0] == str(cliroot_envs) + else: + assert envs_dirs[0] == str(envroot_envs) else: - assert envs_dirs[0] == str(envroot / "envs") + if user_envs_dirs: + assert Path(userenv_envs / "foo").exists() + else: + if cli_root_prefix: + assert Path(cliroot_envs / "foo").exists() + else: + assert Path(envroot_envs / "foo").exists() @pytest.mark.skipif( From c7e4db42fd27a2c4b50eec61192413968b95928f Mon Sep 17 00:00:00 2001 From: Burt Holzman Date: Thu, 13 Feb 2025 13:21:42 -0600 Subject: [PATCH 6/7] Add condarc envs_dirs check to root prefix precedence test, clean up --- micromamba/tests/test_create.py | 90 ++++++++++++++++++++++----------- 1 file changed, 61 insertions(+), 29 deletions(-) diff --git a/micromamba/tests/test_create.py b/micromamba/tests/test_create.py index d68c857ae7..637870e075 100644 --- a/micromamba/tests/test_create.py +++ b/micromamba/tests/test_create.py @@ -666,55 +666,87 @@ def test_create_envs_dirs(tmp_root_prefix: Path, tmp_path: Path): assert (tmp_path / env_name / "conda-meta" / "history").exists() +@pytest.mark.parametrize("set_in_conda_envs_dirs", (False, True)) +@pytest.mark.parametrize("set_in_condarc", (False, True)) @pytest.mark.parametrize("cli_root_prefix", (False, True)) -@pytest.mark.parametrize("user_envs_dirs", (False, True)) @pytest.mark.parametrize("check_config", (False, True)) def test_root_prefix_precedence( - monkeypatch, tmp_path, user_envs_dirs, cli_root_prefix, check_config + tmp_path, + tmp_home, + monkeypatch, + set_in_condarc, + set_in_conda_envs_dirs, + cli_root_prefix, + check_config, ): - """Test for root prefix precedence""" + """ + Test for root prefix precedence + + Environments can be created in several places depending, in this order: + - 1. in the folder of `CONDA_ENVS_DIRS` if it is set + - 2. in the folder of `envs_dirs` if set in the rc file + - 3. the root prefix given by the user's command (e.g. specified via the `-r` option) + - 4. the usual root prefix (set generally by `MAMBA_ROOT_PREFIX`) + """ - envroot = tmp_path / "envroot" - envroot_envs = envroot / "envs" - cliroot = tmp_path / "cliroot" - cliroot_envs = cliroot / "envs" - userenv = tmp_path / "userenv" - userenv_envs = userenv / "envs" + # Given by `CONDA_ENVS_DIRS` + conda_envs_dirs = tmp_path / "conda_envs_dirs" / "envs" + # Given by `envs_dirs` in the rc file + condarc_envs_dirs = tmp_path / "condarc_envs_dirs" / "envs" + # Given via the CLI + cli_provided_root = tmp_path / "cliroot" + cli_provided_root_envs = cli_provided_root / "envs" + # Given by `MAMBA_ROOT_PREFIX` + mamba_root_prefix = tmp_path / "envroot" + mamba_root_prefix_envs = mamba_root_prefix / "envs" - monkeypatch.setenv("MAMBA_ROOT_PREFIX", str(envroot)) - if user_envs_dirs: - monkeypatch.setenv("CONDA_ENVS_DIRS", str(userenv_envs)) + env_name = "foo" + monkeypatch.setenv("MAMBA_ROOT_PREFIX", str(mamba_root_prefix)) + if set_in_conda_envs_dirs: + monkeypatch.setenv("CONDA_ENVS_DIRS", str(conda_envs_dirs)) - for i in (envroot, cliroot, userenv_envs): - os.makedirs(i, exist_ok=True) + with open(tmp_home / ".condarc", "w+") as f: + if set_in_condarc: + f.write(f"envs_dirs: [{str(condarc_envs_dirs)}]") - cmd = ["-n", "foo"] + for envs_folder in (condarc_envs_dirs, conda_envs_dirs, cli_provided_root, mamba_root_prefix): + os.makedirs(envs_folder, exist_ok=True) + + cmd = ["-n", env_name, "--rc-file", tmp_home / ".condarc"] if check_config: cmd += ["--print-config-only", "--debug"] if cli_root_prefix: - cmd += ["-r", cliroot] + cmd += ["-r", cli_provided_root] + + res = helpers.create(*cmd, no_rc=False) - res = helpers.create(*cmd, create_cmd="create") + def assert_env_exists(prefix_path): + assert Path(prefix_path / env_name).exists() if check_config: envs_dirs = res["envs_dirs"] - if user_envs_dirs: - assert envs_dirs[0] == str(userenv_envs) - envs_dirs = envs_dirs[1:] + expected_envs_dirs = [] + + if set_in_conda_envs_dirs: + expected_envs_dirs.append(conda_envs_dirs) + if set_in_condarc: + expected_envs_dirs.append(condarc_envs_dirs) if cli_root_prefix: - assert envs_dirs[0] == str(cliroot_envs) + expected_envs_dirs.append(cli_provided_root_envs) else: - assert envs_dirs[0] == str(envroot_envs) + expected_envs_dirs.append(mamba_root_prefix_envs) + assert envs_dirs == [str(env_dir) for env_dir in expected_envs_dirs] + + elif set_in_conda_envs_dirs: + assert_env_exists(conda_envs_dirs) + elif set_in_condarc: + assert_env_exists(condarc_envs_dirs) + elif cli_root_prefix: + assert_env_exists(cli_provided_root_envs) else: - if user_envs_dirs: - assert Path(userenv_envs / "foo").exists() - else: - if cli_root_prefix: - assert Path(cliroot_envs / "foo").exists() - else: - assert Path(envroot_envs / "foo").exists() + assert_env_exists(mamba_root_prefix_envs) @pytest.mark.skipif( From 125e2251ad233675d68675a01fe9e3c1763ce09e Mon Sep 17 00:00:00 2001 From: Burt Holzman Date: Fri, 14 Feb 2025 09:44:07 -0600 Subject: [PATCH 7/7] Add comments and fix nits on root prefix precedence test --- micromamba/tests/test_create.py | 28 +++++++++++++++++----------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/micromamba/tests/test_create.py b/micromamba/tests/test_create.py index 637870e075..562f744f3d 100644 --- a/micromamba/tests/test_create.py +++ b/micromamba/tests/test_create.py @@ -279,6 +279,8 @@ def test_target_prefix( else: root_prefix = Path(os.environ["MAMBA_ROOT_PREFIX"]) + # TODO: Remove this call to `os.makedirs` once + # https://github.com/mamba-org/mamba/issues/3790 is fixed if root_prefix_env_exists: os.makedirs(Path(os.environ["MAMBA_ROOT_PREFIX"]) / "envs", exist_ok=True) @@ -669,7 +671,7 @@ def test_create_envs_dirs(tmp_root_prefix: Path, tmp_path: Path): @pytest.mark.parametrize("set_in_conda_envs_dirs", (False, True)) @pytest.mark.parametrize("set_in_condarc", (False, True)) @pytest.mark.parametrize("cli_root_prefix", (False, True)) -@pytest.mark.parametrize("check_config", (False, True)) +@pytest.mark.parametrize("check_config_only", (False, True)) def test_root_prefix_precedence( tmp_path, tmp_home, @@ -677,7 +679,7 @@ def test_root_prefix_precedence( set_in_condarc, set_in_conda_envs_dirs, cli_root_prefix, - check_config, + check_config_only, ): """ Test for root prefix precedence @@ -709,12 +711,14 @@ def test_root_prefix_precedence( if set_in_condarc: f.write(f"envs_dirs: [{str(condarc_envs_dirs)}]") + # TODO: Remove this call to `os.makedirs` once + # https://github.com/mamba-org/mamba/issues/3790 is fixed for envs_folder in (condarc_envs_dirs, conda_envs_dirs, cli_provided_root, mamba_root_prefix): os.makedirs(envs_folder, exist_ok=True) cmd = ["-n", env_name, "--rc-file", tmp_home / ".condarc"] - if check_config: + if check_config_only: cmd += ["--print-config-only", "--debug"] if cli_root_prefix: @@ -725,20 +729,22 @@ def test_root_prefix_precedence( def assert_env_exists(prefix_path): assert Path(prefix_path / env_name).exists() - if check_config: - envs_dirs = res["envs_dirs"] + if check_config_only: expected_envs_dirs = [] - if set_in_conda_envs_dirs: - expected_envs_dirs.append(conda_envs_dirs) + expected_envs_dirs.append(str(conda_envs_dirs)) if set_in_condarc: - expected_envs_dirs.append(condarc_envs_dirs) + expected_envs_dirs.append(str(condarc_envs_dirs)) if cli_root_prefix: - expected_envs_dirs.append(cli_provided_root_envs) + expected_envs_dirs.append(str(cli_provided_root_envs)) else: - expected_envs_dirs.append(mamba_root_prefix_envs) - assert envs_dirs == [str(env_dir) for env_dir in expected_envs_dirs] + expected_envs_dirs.append(str(mamba_root_prefix_envs)) + + effective_envs_dirs = res["envs_dirs"] + assert effective_envs_dirs == expected_envs_dirs + # Otherwise, we check that `foo` has been created in the directory + # based on precedence given above. elif set_in_conda_envs_dirs: assert_env_exists(conda_envs_dirs) elif set_in_condarc: