def test_get_packages_with_version_spec(mocker):
    mocker.patch(
        "conda_env_tracker.env.get_dependencies",
        return_value={
            "conda": {
                "pandas": Package("pandas", "pandas", "0.23", "py_36"),
                "numpy": Package("numpy", "numpy", "0.13", "py_36"),
            },
            "pip": {
                "pytest": Package("pytest", "pytest", "4.0")
            },
        },
    )
    local_packages = HistoryPackages.create(
        (Package.from_spec("pandas=0.23"), ))
    local_packages.update_packages(
        packages=(Package.from_spec("pytest==4.0"), ), source="pip")
    local_history = History(
        name=ENV_NAME,
        packages=local_packages,
        channels=Channels("defaults"),
        logs=Logs([]),
        actions=Actions(),
        debug=Debug(),
    )
    env = Environment(name=ENV_NAME, history=local_history)

    expected = {
        "conda": [Package("pandas", "pandas=0.23", "0.23", "py_36")],
        "pip": [Package("pytest", "pytest==4.0", "4.0")],
    }
    actual = get_packages(env)
    assert actual == expected
示例#2
0
def setup_tests(mocker):
    """Set up for pull function"""
    remote_packages = (Package.from_spec("pandas"),
                       Package.from_spec("pytest"))
    remote_logs = [
        "conda create --name pull_testing_environment pandas",
        "conda install --name pull_testing_environment pytest",
    ]
    remote_actions = [
        "conda create --name pull_testing_environment pandas=0.23=py36",
        "conda install --name pull_testing_environment pytest=0.1=py36_3",
    ]
    remote_history = History(
        name=ENV_NAME,
        channels=CHANNELS,
        packages=HistoryPackages.create(remote_packages),
        logs=Logs([log for log in remote_logs]),
        actions=Actions(remote_actions),
        debug=Debug(),
    )

    mocker.patch("conda_env_tracker.conda.conda_install")
    mocker.patch("conda_env_tracker.conda.conda_update_all")
    mocker.patch("conda_env_tracker.conda.conda_remove")
    mocker.patch("conda_env_tracker.pip.pip_install")
    mocker.patch("conda_env_tracker.pip.pip_remove")
    mocker.patch("conda_env_tracker.history.get_pip_version")
    get_dependencies = mocker.patch("conda_env_tracker.env.get_dependencies")

    overwrite_mock = mocker.patch(
        "conda_env_tracker.pull.EnvIO.overwrite_local")
    mocker.patch("conda_env_tracker.pull.EnvIO.get_remote_dir",
                 return_value="~/path/to/remote")
    mocker.patch("conda_env_tracker.pull.EnvIO.get_history",
                 return_value=remote_history)
    mocker.patch("conda_env_tracker.pull.prompt_yes_no", return_value=True)
    mocker.patch("conda_env_tracker.pull.update_conda_environment")
    mocker.patch("conda_env_tracker.pull.update_r_environment")
    mocker.patch("conda_env_tracker.pull.Environment.export")
    mocker.patch("conda_env_tracker.pull.Environment.validate")
    mocker.patch(
        "conda_env_tracker.pull.Environment.validate_installed_packages")

    yield {
        "get_dependencies": get_dependencies,
        "overwrite_mock": overwrite_mock,
        "remote_history": remote_history,
    }

    env_dir = USER_ENVS_DIR / ENV_NAME
    if env_dir.exists():
        shutil.rmtree(env_dir)
示例#3
0
def test_write_history_file(env_io):
    """Test to create history yaml file and test get history"""
    env_io.write_history_file(
        History.create(
            name="test-env",
            channels=Channels(["main"]),
            packages=PackageRevision(
                {"conda": {
                    "python": Package.from_spec("python")
                }}),
            logs=Logs(["conda create -n test-env python"]),
            actions=Actions([
                "conda create -n test-env python=3.7.3=buildstring --override-channels --channel main"
            ]),
            diff=Diff({
                "conda": {
                    "upsert": {
                        "python": Package("python", version="3.7.3")
                    }
                }
            }),
            debug=["blah"],
        ))
    assert ["main"] == env_io.get_history().channels
    assert {
        "conda": {
            "python": Package.from_spec("python")
        }
    } == env_io.get_history().packages
    assert (Revisions(
        **{
            "logs": ["conda create -n test-env python"],
            "actions": [
                "conda create -n test-env python=3.7.3=buildstring --override-channels --channel main"
            ],
            "packages": [{
                "conda": {
                    "python": Package.from_spec("python")
                }
            }],
            "diffs": [{
                "conda": {
                    "upsert": {
                        "python": Package("python", "python", version="3.7.3")
                    }
                }
            }],
            "debug": ["blah"],
        }) == env_io.get_history().revisions)
示例#4
0
def test_pull_no_new_action_in_local(setup_tests):
    overwrite_mock = setup_tests["overwrite_mock"]
    remote_history = setup_tests["remote_history"]

    local_packages = (Package.from_spec("pandas"), )
    local_logs = ["conda create --name pull_testing_environment pandas"]
    local_actions = [
        "conda create --name pull_testing_environment pandas=0.23=py36"
    ]

    local_history = History(
        name=ENV_NAME,
        packages=HistoryPackages.create(local_packages),
        channels=Channels(),
        logs=Logs([log for log in local_logs]),
        actions=Actions(local_actions),
        debug=Debug(),
    )
    env = Environment(name=ENV_NAME, history=local_history)

    pull(env=env)

    assert env.history.packages == remote_history.packages
    assert env.history.logs == remote_history.logs
    assert env.history.actions == remote_history.actions
    overwrite_mock.called_once()
示例#5
0
def test_extract_packages_from_logs(spec):
    """Test parsing the packges from action item"""
    log = Logs(f"conda install --name test {spec}")
    packages = log.extract_packages(index=0,
                                    packages=Packages.from_specs(spec))

    assert packages[0] == Package.from_spec(spec)
示例#6
0
def test_parse_with_package_with_version():
    """Test to parse yaml file without any package"""
    history = History.parse({
        "name":
        "environment-name",
        "channels": ["conda-forge", "main"],
        "packages": {
            "conda": {
                "pytest": "3.7=py36_0"
            }
        },
        "logs": ["conda create --name test pytest=3.7=py36_0"],
        "actions": ["conda create --name test pytest=3.7=py36_0"],
        "debug": [{
            "platform": "osx",
            "conda_version": "4.5.12"
        }],
    })
    assert history.name == "environment-name"
    assert history.channels == ["conda-forge", "main"]
    assert history.packages == {
        "conda": {
            "pytest": Package.from_spec("pytest=3.7=py36_0")
        }
    }
    assert history.logs == ["conda create --name test pytest=3.7=py36_0"]
    assert history.actions == ["conda create --name test pytest=3.7=py36_0"]
    assert history.debug == [{"platform": "osx", "conda_version": "4.5.12"}]
示例#7
0
def test_jupyter_kernel_install_query_user_says_no(mocker):
    run_mock = mocker.patch(
        "conda_env_tracker.gateways.jupyter.subprocess.run")
    run_mock.configure_mock(
        **{
            "return_value.returncode":
            0,
            "return_value.stdout":
            ("Available kernels:\n"
             "  arl             /home/username/.local/share/jupyter/kernels/arl\n"
             "  test-env        /home/username/.local/share/jupyter/kernels/test-env\n"
             "  rasterstats     /home/username/.local/share/jupyter/kernels/rasterstats"
             ),
        })
    mocker.patch(
        "conda_env_tracker.gateways.jupyter.prompt_yes_no",
        new=mocker.Mock(return_value=False),
    )
    debug_mock = mocker.patch(
        "conda_env_tracker.gateways.jupyter.logger.debug")

    jupyter_kernel_install_query(name="myenv",
                                 packages=[Package.from_spec("jupyter")])

    debug_mock.assert_not_called()
    assert len(run_mock.call_args_list) == 1
示例#8
0
    def history_diff(env_name: str, env, env_reader) -> ListLike:
        """return the difference between history and local environment"""
        version_diff_pkges: ListLike = []
        new_pkges: ListLike = []
        missing_pkges: ListLike = []

        history_conda_pkges = env_reader.get_environment()["dependencies"]
        history_conda_pkges_dict = {}
        for spec in history_conda_pkges:
            name, package = Package.from_spec(spec)
            history_conda_pkges_dict[name] = package
        local_conda_pkges = get_dependencies(name=env_name)["conda"]
        for name, package in local_conda_pkges.items():
            if name in history_conda_pkges_dict:
                if package.version != history_conda_pkges_dict[name].version:
                    version_diff_pkges.append("-" + name + "=" +
                                              history_conda_pkges_dict[name])
                    version_diff_pkges.append("+" + name + "=" +
                                              package.version)
            else:
                new_pkges.append("+" + name + "=" + package.version)
        for package in env.history.packages["conda"]:
            if package not in local_conda_pkges.keys():
                missing_pkges.append("-" + package)

        return version_diff_pkges, new_pkges, missing_pkges
示例#9
0
def test_parse_with_package():
    """Test to parse yaml file without any package"""
    history = History.parse({
        "channels": ["conda-forge", "main"],
        "packages": {
            "conda": {
                "pytest": "*"
            }
        },
        "logs": ["conda create --name test pytest"],
        "actions": [
            "conda create --name test pytest=0.1=py36_0 "
            "--channel conda-forge "
            "--channel main"
        ],
        "debug": [{
            "platform": "linux",
            "conda_version": "4.5.11"
        }],
    })
    assert ["conda-forge", "main"] == history.channels
    assert {
        "conda": {
            "pytest": Package.from_spec("pytest")
        }
    } == history.packages
    assert ["conda create --name test pytest"] == history.logs
    assert [
        "conda create --name test pytest=0.1=py36_0 "
        "--channel conda-forge "
        "--channel main"
    ] == history.actions
    assert [{"platform": "linux", "conda_version": "4.5.11"}] == history.debug
示例#10
0
def test_export_success(mocker):
    """Test package export"""
    mocker.patch(
        "conda_env_tracker.history.history.uuid4").return_value = "unique_uuid"
    expected = {
        "name":
        "environment-name",
        "id":
        "unique_uuid",
        "history-file-version":
        "1.0",
        "channels": ["conda-forge", "main"],
        "packages": {
            "conda": {
                "pytest": "*"
            }
        },
        "revisions": [{
            "log":
            "conda create --name test pytest",
            "action":
            "conda create --name test pytest=4.0=py36_0 "
            "--channel conda-forge "
            "--channel main",
            "debug": {
                "platform": "osx",
                "conda_version": "4.5.10"
            },
            "packages": {
                "conda": {
                    "pytest": "*"
                }
            },
            "diff": {
                "conda": {
                    "upsert": ["pytest=4.0"]
                }
            },
        }],
    }
    actual = History.create(
        name="environment-name",
        channels=Channels(["conda-forge", "main"]),
        packages=PackageRevision(conda=dict(
            pytest=Package.from_spec("pytest"))),
        logs=Logs(["conda create --name test pytest"]),
        actions=Actions([
            "conda create --name test pytest=4.0=py36_0 "
            "--channel conda-forge "
            "--channel main"
        ]),
        diff=Diff(conda=dict(upsert=dict(
            pytest=Package("pytest", version="4.0")))),
        debug=[{
            "platform": "osx",
            "conda_version": "4.5.10"
        }],
    ).export()
    assert expected == actual
示例#11
0
def test_jupyter_kernel_install_query_jupyter_not_in_packages(mocker):
    run_mock = mocker.patch(
        "conda_env_tracker.gateways.jupyter.subprocess.run")

    jupyter_kernel_install_query(name="myenv",
                                 packages=[Package.from_spec("numpy")])

    run_mock.assert_not_called()
示例#12
0
def test_strict_channel_priority_update_all(setup_env, use_package, mocker):
    env = setup_env["env"]
    env_io = setup_env["env_io"]
    expected = setup_env["expected"]

    get_package_mock = setup_env["get_package_mock"]
    get_package_mock.configure_mock(
        return_value={
            "conda": {
                "pyspark": Package("pyspark", "pyspark", "2.3.2", "py_36"),
                "pandas": Package("pandas", "pandas", "0.23", "py_36"),
            }
        })

    mocker.patch("conda_env_tracker.conda.conda_update_all")

    expected_packages = copy.deepcopy(expected["packages"])

    expected_packages["conda"]["pandas"] = Package.from_spec("pandas")

    update_all_channel_string = "--override-channels " + " ".join(
        f"--channel {channel}" for channel in expected["channels"])

    if use_package:
        CondaHandler(env=env).update_all(
            packages=Packages.from_specs("pyspark"),
            strict_channel_priority=False)
        expected_packages["conda"]["pyspark"] = Package.from_spec("pyspark")
        log = f"conda update --all --name {env.name} pyspark"
        action = f"conda update --all --name {env.name} pyspark=2.3.2=py_36 {update_all_channel_string}"
    else:
        CondaHandler(env=env).update_all(strict_channel_priority=False)
        log = f"conda update --all --name {env.name}"
        action = f"conda update --all --name {env.name} {update_all_channel_string}"

    history = env_io.get_history()

    expected_logs = expected["logs"].copy()
    expected_logs.append(log)

    expected_actions = expected["actions"].copy()
    expected_actions.append(action)

    assert history.packages == expected_packages
    assert history.actions == expected_actions
    assert history.logs == expected_logs
示例#13
0
def test_install_upgrade_version_success(setup_env, mocker):
    env = setup_env["env"]
    env_io = setup_env["env_io"]
    expected = setup_env["expected"]

    get_package_mock = setup_env["get_package_mock"]
    get_package_mock.configure_mock(
        return_value={
            "conda": {
                "numpy": Package("numpy", "numpy", "1.1", "py_36"),
                "pandas": Package("pandas", "pandas", "0.24", "py_36"),
            }
        }
    )

    mocker.patch("conda_env_tracker.conda.conda_install")

    packages = Packages.from_specs("numpy")
    CondaHandler(env=env).install(packages=packages)

    history = env_io.get_history()

    channel_string = "--override-channels --strict-channel-priority " + " ".join(
        [f"--channel " + channel for channel in expected["channels"]]
    )
    expected_log = expected["logs"].copy()
    expected_log.append(f"conda install --name {env.name} numpy")

    expected_action = expected["actions"].copy()

    expected_packages = copy.deepcopy(expected["packages"])
    expected_packages["conda"]["numpy"] = Package.from_spec("numpy")
    if expected_packages["conda"]["pandas"].spec_is_name():
        expected_action.append(
            f"conda install --name {env.name} numpy=1.1=py_36 {channel_string}"
        )
    else:
        expected_packages["conda"]["pandas"] = Package.from_spec("pandas=0.24=py_36")
        expected_action.append(
            f"conda install --name {env.name} numpy=1.1=py_36 pandas=0.24=py_36 {channel_string}"
        )

    assert history.packages == expected_packages
    assert history.logs == expected_log
    assert history.actions == expected_action
示例#14
0
def test_ignore_empty_pip_packages(mocker):
    """When a user installs a pip package and then removes it, the pip packages is an empty dictionry which
    does not need to show up in the history file.
    """
    mocker.patch(
        "conda_env_tracker.history.history.uuid4").return_value = "unique_uuid"
    expected = {
        "name":
        "environment-name",
        "id":
        "unique_uuid",
        "history-file-version":
        "1.0",
        "channels": ["main"],
        "packages": {
            "conda": {
                "pytest": "*"
            }
        },
        "revisions": [{
            "log": "conda create --name test pytest",
            "action": "conda create --name test pytest=4.0=py36_0 "
            "--channel main",
            "debug": {
                "platform": "osx",
                "conda_version": "4.5.10"
            },
            "packages": {
                "conda": {
                    "pytest": "*"
                }
            },
            "diff": {
                "conda": {
                    "upsert": ["pytest=4.0"]
                }
            },
        }],
    }
    actual = History.create(
        name="environment-name",
        channels=Channels(["main"]),
        packages=PackageRevision(
            conda=dict(pytest=Package.from_spec("pytest")), pip={}),
        logs=Logs(["conda create --name test pytest"]),
        actions=Actions(
            ["conda create --name test pytest=4.0=py36_0 "
             "--channel main"]),
        diff=Diff(
            dict(conda=dict(upsert=dict(
                pytest=Package("pytest", version="4.0"))))),
        debug=[{
            "platform": "osx",
            "conda_version": "4.5.10"
        }],
    ).export()
    assert expected == actual
示例#15
0
def test_get_packages_r(mocker):
    mocker.patch(
        "conda_env_tracker.env.get_dependencies",
        return_value={
            "conda": {
                "r-base":
                Package("r-base", "r-base", "3.5.1", "h539"),
                "r-devtools":
                Package("r-devtools", "r-devtools", "0.1.0", "r351_0"),
            }
        },
    )
    mocker.patch(
        "conda_env_tracker.env.get_r_dependencies",
        return_value={
            "trelliscopejs": Package("trelliscopejs", "trelliscopejs"
                                     "0.1.0")
        },
    )
    local_packages = HistoryPackages.create(
        Packages(
            (Package.from_spec("r-base"), Package.from_spec("r-devtools"))))
    local_packages.update_packages(
        packages=(Package.from_spec("trelliscopejs"), ), source="r")
    local_history = History(
        name=ENV_NAME,
        packages=local_packages,
        channels=Channels("defaults"),
        logs=Logs([]),
        actions=Actions(),
        debug=Debug(),
    )
    env = Environment(name=ENV_NAME, history=local_history)

    expected = {
        "conda": [
            Package("r-base", "r-base", "3.5.1", "h539"),
            Package("r-devtools", "r-devtools", "0.1.0", "r351_0"),
        ],
        "r": [Package("trelliscopejs", "trelliscopejs", "0.1.0")],
    }
    actual = get_packages(env)
    assert actual == expected
示例#16
0
def test_extract_packages_from_actions(spec):
    """Test parsing the packges from action item"""
    action = Actions.create(
        name="test-extract",
        specs=[spec],
        channels=Channels(["conda-forge", "conda-remote"]),
    )
    packages = action.extract_packages(index=0)

    assert packages[0] == Package.from_spec(spec)
示例#17
0
def test_pull_actions_in_different_order(setup_tests):
    overwrite_mock = setup_tests["overwrite_mock"]
    remote_history = setup_tests["remote_history"]

    new_log = "conda install --name pull_testing_environment pylint"
    new_action = "conda install --name pull_testing_environment pylint=1.11=py36"

    remote_history.packages["pylint"] = "*"
    remote_history.logs.append(new_log)
    remote_history.actions.append(new_action)

    local_packages = (
        Package.from_spec("pandas"),
        Package.from_spec("pylint"),
        Package.from_spec("pytest"),
    )
    local_logs = [
        "conda create --name pull_testing_environment pandas",
        new_log,
        "conda install --name pull_testing_environment pytest",
    ]
    local_actions = [
        "conda create --name pull_testing_environment pandas=0.23=py36",
        new_action,
        "conda install --name pull_testing_environment pytest=0.1=py36_3",
    ]
    local_history = History(
        name=ENV_NAME,
        channels=CHANNELS,
        packages=HistoryPackages.create(local_packages),
        logs=Logs([log for log in local_logs]),
        actions=Actions(local_actions),
        debug=Debug(),
    )
    env = Environment(name=ENV_NAME, history=local_history)

    pull(env=env)

    assert env.history.packages == remote_history.packages
    assert env.history.logs == remote_history.logs
    assert env.history.actions == remote_history.actions
    overwrite_mock.called_once()
示例#18
0
def test_pull_pip(setup_tests):
    new = Package.from_spec("pytest-pylint==0.13.0")
    remote_history = setup_tests["remote_history"]

    remote_history.packages.update_packages(packages=[new], source="pip")
    remote_history.logs.append(f"pip install {new}")
    remote_history.actions.append(f"pip install {new}")

    env = Environment(name="test", history=None)
    final_env = pull(env=env)

    assert final_env.history == remote_history
示例#19
0
def test_pull_different_actions_with_pip(setup_tests):
    new = Package.from_spec("pytest-pylint==0.13.0")
    remote_history = setup_tests["remote_history"]

    local_history = copy.deepcopy(remote_history)
    env = Environment(name=local_history.name, history=local_history)

    remote_history.packages.update_packages(packages=[new], source="pip")
    remote_history.logs.append(f"pip install {new}")
    remote_history.actions.append(f"pip install {new}")

    final_env = pull(env=env)

    assert final_env.history == remote_history
示例#20
0
def test_package_install_with_custom_channel(setup_env, channels, mocker):
    """The user can specify a list of channels that will override the channel precedence order or
    they can specify a custom channel that is not previously in the environment's channel list"""
    env = setup_env["env"]
    env_io = setup_env["env_io"]
    expected = setup_env["expected"]

    get_package_mock = setup_env["get_package_mock"]
    get_package_mock.configure_mock(
        return_value={
            "conda": {
                "pyspark": Package("pyspark", "pyspark", "0.21", "py_36"),
                "pandas": Package("pandas", "pandas", "0.23", "py_36"),
            }
        }
    )

    mocker.patch("conda_env_tracker.conda.conda_install")

    CondaHandler(env=env).install(
        packages=Packages.from_specs("pyspark"), channels=channels
    )

    history = env_io.get_history()

    expected_log = expected["logs"].copy()
    expected_action = expected["actions"].copy()
    expected_packages = copy.deepcopy(expected["packages"])

    expected_packages["conda"]["pyspark"] = Package.from_spec("pyspark")
    channel_log_string = " ".join(["--channel " + channel for channel in channels])
    expected_log.append(f"conda install --name {env.name} pyspark {channel_log_string}")

    computed_channels = channels.copy()
    for channel in expected["channels"]:
        if not channel in computed_channels:
            computed_channels.append(channel)

    install_channel_string = (
        "--override-channels --strict-channel-priority "
        + " ".join([f"--channel " + channel for channel in computed_channels])
    )

    assert history.packages == expected_packages
    expected_action.append(
        f"conda install --name {env.name} pyspark=0.21=py_36 {install_channel_string}"
    )
    assert history.actions == expected_action
    assert history.logs == expected_log
示例#21
0
def test_replace_existing_env_success(mocker):
    mocker.patch("conda_env_tracker.env.delete_conda_environment")
    mocker.patch("conda_env_tracker.env.prompt_yes_no").return_value = True
    env_name = "conda_env_tracker-test-create-history"
    create_cmd = f"conda create --name {env_name} pandas"
    channels = ["conda-forge", "main"]
    packages = Packages.from_specs("pandas")
    action = "pandas=0.23=py_36"

    mocker.patch(
        "conda_env_tracker.env.get_all_existing_environment").return_value = [
            env_name
        ]
    mocker.patch("conda_env_tracker.env.conda_create",
                 mocker.Mock(return_value=create_cmd))
    mocker.patch(
        "conda_env_tracker.env.get_dependencies",
        mocker.Mock(return_value={
            "conda": {
                "pandas": Package("pandas", "*", "0.23=py_36")
            },
            "pip": {},
        }),
    )
    mocker.patch(
        "conda_env_tracker.history.debug.get_pip_version",
        mocker.Mock(return_value="18.1"),
    )
    mocker.patch("conda_env_tracker.env.get_conda_channels",
                 mocker.Mock(return_value=channels))
    Environment.create(name=env_name, packages=packages)

    writer = EnvIO(env_directory=USER_ENVS_DIR / env_name)
    history = writer.get_history()
    channel_string = "--override-channels --strict-channel-priority " + " ".join(
        "--channel " + channel for channel in channels)
    assert history.actions == [
        f"conda create --name {env_name} {action} {channel_string}"
    ]
    assert history.packages == {
        "conda": {
            "pandas": Package.from_spec("pandas")
        }
    }
    assert history.channels == channels
    assert history.logs == [create_cmd]

    env_dir = Path(USER_ENVS_DIR) / env_name
    shutil.rmtree(env_dir)
示例#22
0
def test_push(setup):
    env, push_should_fail = setup
    if push_should_fail:
        with pytest.raises(CondaEnvTrackerPushError) as err:
            push(env=env)
            assert str(err.value) == PUSH_ERROR_STR.format(
                remote_dir="~/path/to/remote",
                local_dir=env.user_envs_dir / "test-push")
    else:
        push(env=env)
        assert env.history.packages == {
            "conda": {
                "pandas": Package.from_spec("pandas"),
                "pytest": Package.from_spec("pytest"),
            }
        }
        assert env.history.logs == [
            f"conda create --name {env.name} pandas",
            f"conda install --name {env.name} pytest",
        ]
        assert env.history.actions == [
            f"conda create --name {env.name} pandas=0.23=py36",
            f"conda install --name {env.name} pytest=0.11=py36",
        ]
示例#23
0
def test_jupyter_kernel_install_query_jupyter_cant_get_kernelspec(mocker):
    run_mock = mocker.patch(
        "conda_env_tracker.gateways.jupyter.subprocess.run")
    run_mock.configure_mock(**{
        "return_value.returncode": 1,
        "return_value.stderr": "err"
    })
    debug_mock = mocker.patch(
        "conda_env_tracker.gateways.jupyter.logger.debug")

    jupyter_kernel_install_query(name="myenv",
                                 packages=[Package.from_spec("jupyter")])

    debug_mock.assert_called_once_with(
        "Error while installing jupyter kernel: err")
    assert len(run_mock.call_args_list) == 1
示例#24
0
def test_pip_install_fail(mocker):
    name = "env_name"
    packages = [Package.from_spec("not_an_actual_pip_package")]

    run_mock = mocker.patch("conda_env_tracker.gateways.pip.subprocess.run")
    run_mock.configure_mock(
        **{"return_value.returncode": 1, "return_value.stderr": "error"}
    )
    mocker.patch("os.environ.get", mocker.Mock(return_value=name))

    with pytest.raises(PipInstallError) as err:
        pip.pip_install(name=name, packages=packages)
    assert (
        str(err.value)
        == "Pip install ['not_an_actual_pip_package'] failed with message: error"
    )
示例#25
0
def test_jupyter_kernel_install_query_success_from_different_env(mocker):
    run_mock = mocker.patch(
        "conda_env_tracker.gateways.jupyter.subprocess.run")
    run_mock.configure_mock(
        **{
            "return_value.returncode":
            0,
            "return_value.stdout":
            ("Available kernels:\n"
             "  arl             /home/username/.local/share/jupyter/kernels/arl\n"
             "  test-env        /home/username/.local/share/jupyter/kernels/test-env\n"
             "  rasterstats     /home/username/.local/share/jupyter/kernels/rasterstats"
             ),
        })
    mocker.patch(
        "conda_env_tracker.gateways.jupyter.prompt_yes_no",
        new=mocker.Mock(return_value=True),
    )
    mocker.patch(
        "conda_env_tracker.gateways.jupyter.is_current_conda_env",
        new=mocker.Mock(return_value=False),
    )
    mocker.patch(
        "conda_env_tracker.gateways.jupyter.get_conda_activate_command",
        new=mocker.Mock(return_value="conda activate myenv"),
    )
    debug_mock = mocker.patch(
        "conda_env_tracker.gateways.jupyter.logger.debug")

    jupyter_kernel_install_query(name="myenv",
                                 packages=[Package.from_spec("jupyter")])

    debug_mock.assert_not_called()
    assert run_mock.call_args_list == [
        mocker.call(
            "conda activate myenv && jupyter kernelspec list",
            shell=True,
            stdout=subprocess.PIPE,
            encoding="UTF-8",
        ),
        mocker.call(
            "conda activate myenv && python -m ipykernel install --name myenv --user",
            shell=True,
            stderr=subprocess.PIPE,
            encoding="UTF-8",
        ),
    ]
示例#26
0
 def parse(cls, history_section: dict):
     """Parse the history.yaml file."""
     diff = cls()
     for source, sections in history_section.items():
         diff[source] = {}
         for section_name, package_specs in sections.items():
             diff[source][section_name] = {}
             for spec in package_specs:
                 if section_name == "remove" or source == "r":
                     package_name = spec
                     diff[source][section_name][
                         package_name] = Package.from_spec(package_name)
                 else:
                     package_name, version = Package.separate_spec(spec)
                     diff[source][section_name][package_name] = Package(
                         name=package_name,
                         spec=package_name,
                         version=version)
     return diff
示例#27
0
def test_export_success():
    """Test package export"""
    expected = {
        "name":
        "environment-name",
        "channels": ["conda-forge", "main"],
        "packages": {
            "conda": {
                "pytest": "*"
            }
        },
        "logs": ["conda create --name test pytest"],
        "actions": [
            "conda create --name test pytest=0.1=py36_0 "
            "--channel conda-forge "
            "--channel main"
        ],
        "debug": [{
            "platform": "osx",
            "conda_version": "4.5.10"
        }],
    }
    actual = History(
        name="environment-name",
        channels=Channels(["conda-forge", "main"]),
        packages=HistoryPackages(conda=dict(
            pytest=Package.from_spec("pytest"))),
        logs=Logs(["conda create --name test pytest"]),
        actions=Actions([
            "conda create --name test pytest=0.1=py36_0 "
            "--channel conda-forge "
            "--channel main"
        ]),
        debug=[{
            "platform": "osx",
            "conda_version": "4.5.10"
        }],
    ).export()
    assert expected == actual
示例#28
0
def test_jupyter_kernel_install_query_jupyter_cant_install_kernel(mocker):
    run_mock = mocker.patch(
        "conda_env_tracker.gateways.jupyter.subprocess.run",
        new=mocker.Mock(side_effect=[
            mocker.Mock(
                returncode=0,
                stdout=
                ("Available kernels:\n"
                 "  arl             /home/username/.local/share/jupyter/kernels/arl\n"
                 "  test-env        /home/username/.local/share/jupyter/kernels/test-env\n"
                 "  rasterstats     /home/username/.local/share/jupyter/kernels/rasterstats"
                 ),
            ),
            mocker.Mock(returncode=1, stderr="another err"),
        ]),
    )
    debug_mock = mocker.patch(
        "conda_env_tracker.gateways.jupyter.logger.debug")
    mocker.patch(
        "conda_env_tracker.gateways.jupyter.prompt_yes_no",
        new=mocker.Mock(return_value=True),
    )
    mocker.patch(
        "conda_env_tracker.gateways.jupyter.is_current_conda_env",
        new=mocker.Mock(return_value=True),
    )

    jupyter_kernel_install_query(name="myenv",
                                 packages=[Package.from_spec("jupyter")])

    debug_mock.assert_called_once_with(
        "Error while installing jupyter kernel: another err")
    run_mock.assert_called_with(
        "python -m ipykernel install --name myenv --user",
        shell=True,
        stderr=subprocess.PIPE,
        encoding="UTF-8",
    )
    assert len(run_mock.call_args_list) == 2
示例#29
0
def test_install_with_default_version_and_yes_success(setup_env, mocker):
    env = setup_env["env"]
    env_io = setup_env["env_io"]
    expected = setup_env["expected"]
    initial_conda_packages = setup_env["initial_conda_packages"]

    get_package_mock = setup_env["get_package_mock"]
    get_package_mock.configure_mock(
        return_value={
            "conda": {
                **initial_conda_packages,
                "pyspark": Package("pyspark", "pyspark", "0.21", "py_36"),
            }
        }
    )

    mocker.patch("conda_env_tracker.conda.conda_install")

    packages = Packages.from_specs("pyspark")
    CondaHandler(env=env).install(packages=packages)

    history = env_io.get_history()

    expected_log = expected["logs"].copy()
    expected_action = expected["actions"].copy()
    expected_packages = copy.deepcopy(expected["packages"])

    expected_packages["conda"]["pyspark"] = Package.from_spec("pyspark")
    expected_log.append(f"conda install --name {env.name} pyspark")

    assert history.packages == expected_packages
    channel_string = "--override-channels --strict-channel-priority " + " ".join(
        [f"--channel " + channel for channel in expected["channels"]]
    )
    expected_action.append(
        f"conda install --name {env.name} pyspark=0.21=py_36 {channel_string}"
    )
    assert history.actions == expected_action
    assert history.logs == expected_log
示例#30
0
def test_install_unexpectedly_removes_package(setup_env, mocker):
    """Simulating that installing python=3.8 uninstalls pandas and
    there is no version of pandas available for python 3.8
    """
    env = setup_env["env"]
    env_io = setup_env["env_io"]
    expected = setup_env["expected"]
    logger_mock = mocker.patch("conda_env_tracker.env.logger.warning")

    get_package_mock = setup_env["get_package_mock"]
    get_package_mock.configure_mock(
        return_value={"conda": {"python": Package("python", "python", "3.8", "py_38")}}
    )

    mocker.patch("conda_env_tracker.conda.conda_install")

    CondaHandler(env=env).install(packages=Packages.from_specs("python=3.8"))

    history = env_io.get_history()

    channel_string = "--override-channels --strict-channel-priority " + " ".join(
        [f"--channel " + channel for channel in expected["channels"]]
    )
    expected_log = expected["logs"].copy()
    expected_log.append(f"conda install --name {env.name} python=3.8")

    expected_action = expected["actions"].copy()
    expected_action.append(
        f"conda install --name {env.name} python=3.8=py_38 {channel_string}"
    )

    expected_packages = {"conda": {"python": Package.from_spec("python=3.8")}}
    assert history.packages == expected_packages
    assert history.logs == expected_log
    assert history.actions == expected_action
    logger_mock.assert_called_once_with(
        'Package "pandas" was removed during the last command.'
    )