Ejemplo n.º 1
0
def remote(remote_dir, if_missing, name):
    """Setup the remote directory to share the cet environment.

    If remote directory is not specified, then creates .cet in the root directory of the current git repo.
    """
    name = _infer_name_if_necessary(name)
    main.setup_remote(name=name, remote_dir=remote_dir, if_missing=if_missing)
Ejemplo n.º 2
0
def create(packages, name, channel, sync_arg, infer, yes,
           strict_channel_priority):
    """Create the software environment."""
    if infer:
        main.infer(name=name, specs=packages, channels=channel)
    else:
        main.create(
            name=name,
            specs=packages,
            channels=channel,
            yes=yes,
            strict_channel_priority=strict_channel_priority,
        )
    if sync_arg:
        main.setup_remote(name=name, yes=yes)
        main.push(name=name)
Ejemplo n.º 3
0
def end_to_end_setup(request):
    """Setup and teardown for tests."""
    name = "end_to_end_test"
    channels = ["defaults"]
    env_dir = USER_ENVS_DIR / name

    remote_path = Path(__file__).parent.absolute() / "remote_test_dir"
    if remote_path.exists():
        shutil.rmtree(remote_path)
    remote_path.mkdir()

    def teardown():
        delete_conda_environment(name=name)
        if env_dir.is_dir():
            shutil.rmtree(env_dir)
        if remote_path.is_dir():
            shutil.rmtree(remote_path)

    request.addfinalizer(teardown)

    try:
        env = create(
            name=name, specs=["python=3.6", "colorama"], channels=channels, yes=True
        )
        setup_remote(name=name, remote_dir=remote_path, yes=True)
    except CondaEnvTrackerCondaError as err:
        teardown()
        raise err

    channel_command = (
        "--override-channels --strict-channel-priority --channel "
        + " --channel ".join(channels)
    )

    return {
        "name": name,
        "env": env,
        "env_dir": env_dir,
        "channels": channels,
        "channel_command": channel_command,
        "remote_dir": remote_path,
    }
Ejemplo n.º 4
0
def r_end_to_end_setup(request):
    """Setup and teardown for R end to end tests."""
    name = "r_end_to_end_test"
    channels = ["r", "defaults"]
    env_dir = USER_ENVS_DIR / name

    remote_path = Path(__file__).parent.absolute() / "remote_test_dir"
    if remote_path.exists():
        shutil.rmtree(remote_path)
    remote_path.mkdir()

    def teardown():
        delete_conda_environment(name=name)
        if env_dir.is_dir():
            shutil.rmtree(env_dir)
        if remote_path.is_dir():
            shutil.rmtree(remote_path)

    request.addfinalizer(teardown)

    try:
        env = create(name=name,
                     specs=["r-base", "r-devtools"],
                     channels=channels,
                     yes=True)
        setup_remote(name=name, remote_dir=remote_path, yes=True)
    except CondaEnvTrackerCondaError as err:
        teardown()
        raise err

    return {
        "name": name,
        "env": env,
        "env_dir": env_dir,
        "channels": channels,
        "remote_dir": remote_path,
    }
Ejemplo n.º 5
0
def setup_env(request):
    """Creating cet remotes to test cet auto shell script."""
    # pylint: disable=too-many-statements
    env_dir = USER_ENVS_DIR / CET_ENV_NAME
    unseen_local_dir = USER_ENVS_DIR / UNSEEN_ENV_NAME

    empty_dir = Path.home() / ".cet" / "empty_dir"
    cet_dir = Path.home() / ".cet" / "cet_dir"
    identical_history_dir = Path.home() / ".cet" / "identical_history_dir"
    unseen_cet_dir = Path.home() / ".cet" / "unseen_cet_dir"

    remote_path = cet_dir / ".cet"
    identical_remote_path = identical_history_dir / ".cet"
    unseen_remote = unseen_cet_dir / ".cet"

    def teardown():
        conda.delete_conda_environment(name=CET_ENV_NAME)
        conda.delete_conda_environment(name=UNSEEN_ENV_NAME)
        if env_dir.is_dir():
            shutil.rmtree(env_dir)
        if cet_dir.is_dir():
            shutil.rmtree(cet_dir)
        if unseen_cet_dir.is_dir():
            shutil.rmtree(unseen_cet_dir)
        if identical_history_dir.is_dir():
            shutil.rmtree(identical_history_dir)
        if empty_dir.is_dir():
            shutil.rmtree(empty_dir)
        if unseen_local_dir.is_dir():
            shutil.rmtree(unseen_local_dir)

    request.addfinalizer(teardown)

    empty_dir.mkdir()
    cet_dir.mkdir()
    identical_history_dir.mkdir()
    unseen_cet_dir.mkdir()

    if request.param:
        subprocess.run(f"cd {empty_dir}; git init --quiet", shell=True)
        subprocess.run(f"cd {cet_dir}; git init --quiet", shell=True)
        subprocess.run(f"cd {identical_history_dir}; git init --quiet",
                       shell=True)
        subprocess.run(f"cd {unseen_cet_dir}; git init --quiet", shell=True)

    remote_path.mkdir()
    identical_remote_path.mkdir()
    unseen_remote.mkdir()

    try:
        env = main.create(name=CET_ENV_NAME,
                          specs=["python"],
                          channels=["defaults"],
                          yes=True)
        main.setup_remote(name=CET_ENV_NAME, remote_dir=remote_path, yes=True)
        main.push(name=env.name)
    except errors.CondaEnvTrackerCondaError as err:
        teardown()
        raise err

    remote_history_file = remote_path / "history.yaml"
    content = remote_history_file.read_text()

    # We add newline characters to the remote history file so that the unix utility `wc -m` will find more
    # characters in the remote history.yaml file than in the local history.yaml file. This prompts the cet_auto
    # shell function to ask the user to pull the changes from remote into local.
    additional_characters = "\n\n\n"
    remote_history_file.write_text(content + additional_characters)

    identical_remote_history_file = identical_remote_path / "history.yaml"
    identical_remote_history_file.write_text(content)

    unseen_history_file = unseen_remote / "history.yaml"
    unseen_history_file.write_text(
        content.replace(CET_ENV_NAME, UNSEEN_ENV_NAME))

    local_conda_env = env_dir / "conda-env.yaml"
    conda_env_content = local_conda_env.read_text()
    unseen_conda_env = unseen_remote / "conda-env.yaml"
    unseen_conda_env.write_text(
        conda_env_content.replace(CET_ENV_NAME, UNSEEN_ENV_NAME))

    return {
        "cet": cet_dir,
        "empty_cet": empty_dir,
        "identical_cet": identical_history_dir,
        "unseen_cet": unseen_cet_dir,
        "remote_history_file": remote_history_file,
        "local_history_file": env_dir / "history.yaml",
    }
def test_remote_end_to_end(end_to_end_setup, mocker):
    """Test setup, create, install, pull and push feature of conda_env_tracker"""
    env = end_to_end_setup["env"]
    remote_dir = end_to_end_setup["remote_dir"]
    channels = end_to_end_setup["channels"]
    channel_command = end_to_end_setup["channel_command"]

    setup_remote(name=env.name, remote_dir=remote_dir)

    local_io = EnvIO(env_directory=USER_ENVS_DIR / env.name)
    assert str(local_io.get_remote_dir()) == str(remote_dir)
    assert not list(remote_dir.glob("*"))

    push(name=env.name)
    remote_io = EnvIO(env_directory=remote_dir)
    assert remote_io.get_history() == local_io.get_history()
    assert remote_io.get_environment() == local_io.get_environment()

    env = conda_install(name=env.name, specs=["pytest"], yes=True)
    assert env.local_io.get_history() != remote_io.get_history()
    env = push(name=env.name)
    assert env.local_io.get_history() == remote_io.get_history()

    log_mock = mocker.patch("conda_env_tracker.pull.logging.Logger.info")
    env = pull(name=env.name)
    log_mock.assert_called_once_with("Nothing to pull.")

    remove_package_from_history(env, "pytest")

    conda_dependencies = env.dependencies["conda"]
    assert env.local_io.get_history() != remote_io.get_history()
    assert env.history.packages == {
        "conda": {
            "python":
            Package(
                "python",
                "python=3.6",
                version=conda_dependencies["python"].version,
                build=conda_dependencies["python"].build,
            ),
            "colorama":
            Package(
                "colorama",
                "colorama",
                version=conda_dependencies["colorama"].version,
                build=conda_dependencies["colorama"].build,
            ),
        }
    }

    env = pull(name=env.name)

    assert env.local_io.get_history() == remote_io.get_history()
    assert remote_io.get_environment() == local_io.get_environment()

    remove_package_from_history(env, "pytest")
    assert env.local_io.get_history() != remote_io.get_history()

    env = conda_install(name=env.name,
                        specs=["pytest-cov"],
                        channels=("main", ),
                        yes=True)
    env = pull(name=env.name, yes=True)

    conda_dependencies = env.dependencies["conda"]
    assert env.history.packages == {
        "conda": {
            "python":
            Package(
                "python",
                "python=3.6",
                version=conda_dependencies["python"].version,
                build=conda_dependencies["python"].build,
            ),
            "colorama":
            Package(
                "colorama",
                "colorama",
                version=conda_dependencies["colorama"].version,
                build=conda_dependencies["colorama"].build,
            ),
            "pytest":
            Package(
                "pytest",
                "pytest",
                version=conda_dependencies["pytest"].version,
                build=conda_dependencies["pytest"].build,
            ),
            "pytest-cov":
            Package(
                "pytest-cov",
                "pytest-cov",
                version=conda_dependencies["pytest-cov"].version,
                build=conda_dependencies["pytest-cov"].build,
            ),
        }
    }

    log_list = [
        f"conda create --name {env.name} python=3.6 colorama {channel_command}",
        f"conda install --name {env.name} pytest",
        f"conda install --name {env.name} pytest-cov --channel main",
    ]
    assert env.history.logs == log_list

    actual_env = (env.local_io.env_dir / "environment.yml").read_text()
    conda_dependencies = get_dependencies(name=env.name)["conda"]
    expected_env = [f"name: {env.name}", "channels:"]
    for channel in channels + ["nodefaults"]:
        expected_env.append(f"  - {channel}")
    expected_env = ("\n".join(expected_env + [
        "dependencies:",
        "  - python=" + conda_dependencies["python"].version,
        "  - colorama=" + conda_dependencies["colorama"].version,
        "  - pytest=" + conda_dependencies["pytest"].version,
        "  - pytest-cov=" + conda_dependencies["pytest-cov"].version,
    ]) + "\n")
    assert actual_env == expected_env

    expected_debug = 3 * [{
        "platform": get_platform_name(),
        "conda_version": CONDA_VERSION,
        "pip_version": get_pip_version(name=env.name),
        "timestamp": str(date.today()),
    }]
    for i in range(len(env.history.debug)):
        for key, val in expected_debug[i].items():
            if key == "timestamp":
                assert env.history.debug[i][key].startswith(val)
            else:
                assert env.history.debug[i][key] == val