Example #1
0
def test_errors_pip_overwrites():
    with pytest.raises(CondaPackException) as exc:
        CondaEnv.from_prefix(py36_broken_path)

    msg = str(exc.value)
    assert "pip" in msg
    assert "toolz" in msg
Example #2
0
def test_missing_files():
    with pytest.raises(CondaPackException) as exc:
        CondaEnv.from_prefix(py36_missing_files_path)

    msg = str(exc.value)
    assert "{}toolz{}__init__.py".format(os.sep, os.sep) in msg, msg
    assert "{}toolz{}_signatures.py".format(os.sep, os.sep) in msg, msg
Example #3
0
def test_errors_root_environment():
    info = subprocess.check_output("conda info --json", shell=True).decode()
    root_prefix = json.loads(info)['root_prefix']

    with pytest.raises(CondaPackException) as exc:
        CondaEnv.from_prefix(root_prefix)

    assert "Cannot package root environment" in str(exc.value)
Example #4
0
def test_missing_package_cache(broken_package_cache):
    with pytest.warns(UserWarning) as record:
        env = CondaEnv.from_prefix(py27_path)

    assert len(env)

    assert len(record) == 1
    msg = str(record[0].message)
    assert 'conda_pack_test_lib2' in msg

    with pytest.raises(CondaPackException):
        CondaEnv.from_prefix(py27_path, on_missing_cache='raise')
Example #5
0
def test_from_prefix():
    env = CondaEnv.from_prefix(os.path.join(rel_env_dir, 'py36'))
    assert len(env)
    # relative path is normalized
    assert env.prefix == py36_path

    # Path is missing
    with pytest.raises(CondaPackException):
        CondaEnv.from_prefix(os.path.join(env_dir, "this_path_doesnt_exist"))

    # Path exists, but isn't a conda environment
    with pytest.raises(CondaPackException):
        CondaEnv.from_prefix(os.path.join(env_dir))
Example #6
0
def test_from_prefix():
    rel_env_dir = os.path.relpath(py36_path, os.getcwd())
    env = CondaEnv.from_prefix(rel_env_dir)
    assert len(env)
    # relative path is normalized
    assert os.path.normcase(env.prefix) == os.path.normcase(py36_path)

    # Path is missing
    with pytest.raises(CondaPackException):
        CondaEnv.from_prefix(os.path.join(env_dir, "this_path_doesnt_exist"))

    # Path exists, but isn't a conda environment
    with pytest.raises(CondaPackException):
        CondaEnv.from_prefix(os.path.join(env_dir))
Example #7
0
def test_pack_with_conda(tmpdir):
    env = CondaEnv.from_prefix(has_conda_path)
    out_path = os.path.join(str(tmpdir), 'has_conda.tar')
    env.pack(out_path)

    extract_path = os.path.join(str(tmpdir), 'output')
    os.mkdir(extract_path)

    assert os.path.exists(out_path)
    assert tarfile.is_tarfile(out_path)

    with tarfile.open(out_path) as fil:
        names = fil.getnames()

        # Check conda/activate/deactivate all present
        if on_win:
            assert 'Scripts/conda.exe' in names
        else:
            assert 'bin/conda' in names
            assert 'bin/activate' in names
            assert 'bin/deactivate' in names

        # Extract tarfile
        fil.extractall(extract_path)

    # Check the packaged conda works, and the output is a conda environment
    if not on_win:
        command = (". {path}/bin/activate && "
                   "conda list --json -p {path} &&"
                   ". {path}/bin/deactivate").format(path=extract_path)
        out = subprocess.check_output(['/usr/bin/env', 'bash', '-c', command],
                                      stderr=subprocess.STDOUT).decode()
        data = json.loads(out)
        assert 'conda' in {i['name'] for i in data}

    # Check the conda-meta directory has been anonymized
    for path in glob(os.path.join(extract_path, 'conda-meta', '*.json')):
        with open(path) as fil:
            data = json.load(fil)

        for field in ["extracted_package_dir", "package_tarball_full_path"]:
            if field in data:
                assert data[field] == ""

        if "link" in data and "source" in data["link"]:
            assert data["link"]["source"] == ""
Example #8
0
def test_activate(tmpdir):
    out_path = os.path.join(str(tmpdir), 'activate_scripts.tar')
    extract_path = str(tmpdir)

    env = CondaEnv.from_prefix(activate_scripts_path)
    env.pack(out_path)

    with tarfile.open(out_path) as fil:
        fil.extractall(extract_path)

    # Check that activate environment variable is set
    command = (". {path}/bin/activate && "
               "test $CONDAPACK_ACTIVATED -eq 1 && "
               ". {path}/bin/deactivate && "
               "test ! $CONDAPACK_ACTIVATED && "
               "echo 'Done'").format(path=extract_path)

    out = subprocess.check_output(['/usr/bin/env', 'bash', '-c', command],
                                  stderr=subprocess.STDOUT).decode()

    assert out == 'Done\n'
Example #9
0
def test_activate(tmpdir):
    out_path = os.path.join(str(tmpdir), 'activate_scripts.tar')
    extract_path = str(tmpdir.join('env'))

    env = CondaEnv.from_prefix(activate_scripts_path)
    env.pack(out_path)

    with tarfile.open(out_path) as fil:
        fil.extractall(extract_path)

    # Check that activate environment variable is set
    if on_win:
        command = (r"@CALL {path}\Scripts\activate"
                   "\r\n"
                   r"@ECHO CONDAPACK_ACTIVATED=%CONDAPACK_ACTIVATED%"
                   "\r\n"
                   r"@CALL {path}\Scripts\deactivate"
                   "\r\n"
                   r"@ECHO CONDAPACK_ACTIVATED=%CONDAPACK_ACTIVATED%"
                   "\r\n"
                   r"@echo Done").format(path=extract_path)
        unpack = tmpdir.join('unpack.bat')
        unpack.write(command)

        out = subprocess.check_output(['cmd', '/c', str(unpack)],
                                      stderr=subprocess.STDOUT).decode()

        assert out == 'CONDAPACK_ACTIVATED=1\r\nCONDAPACK_ACTIVATED=\r\nDone\r\n'

    else:
        command = (". {path}/bin/activate && "
                   "test $CONDAPACK_ACTIVATED -eq 1 && "
                   ". {path}/bin/deactivate && "
                   "test ! $CONDAPACK_ACTIVATED && "
                   "echo 'Done'").format(path=extract_path)

        out = subprocess.check_output(['/usr/bin/env', 'bash', '-c', command],
                                      stderr=subprocess.STDOUT).decode()

        assert out == 'Done\n'
Example #10
0
def test_zip64(tmpdir):
    # Create an environment that requires ZIP64 extensions, but doesn't use a
    # lot of disk/RAM
    source = os.path.join(str(tmpdir), 'source.txt')
    with open(source, 'wb') as f:
        f.write(b'0')

    files = [File(source, target='foo%d' % i) for i in range(1 << 16)]
    large_env = CondaEnv('large', files=files)

    out_path = os.path.join(str(tmpdir), 'large.zip')

    # Errors if ZIP64 disabled
    with pytest.raises(CondaPackException) as exc:
        large_env.pack(output=out_path, zip_64=False)
    assert 'ZIP64' in str(exc.value)
    assert not os.path.exists(out_path)

    # Works fine if ZIP64 not disabled
    large_env.pack(output=out_path)
    assert os.path.exists(out_path)
Example #11
0
def test_errors_conda_missing(bad_conda_exe):
    with pytest.raises(CondaPackException) as exc:
        CondaEnv.from_name('probably_fake_env')

    assert 'Failed to determine path to environment' in str(exc.value)
Example #12
0
def test_errors_editable_packages():
    with pytest.raises(CondaPackException) as exc:
        CondaEnv.from_prefix(py36_editable_path)

    assert "Editable packages found" in str(exc.value)
Example #13
0
def test_missing_files():
    with pytest.raises(CondaPackException) as exc:
        CondaEnv.from_prefix(py36_missing_files_path)

    msg = str(exc.value)
    assert "toolz" in msg
Example #14
0
def test_missing_files_ignored():
    CondaEnv.from_prefix(py36_missing_files_path, ignore_missing_files=True)
Example #15
0
def test_pack_with_conda(tmpdir, fix_dest):
    env = CondaEnv.from_prefix(has_conda_path)
    out_path = os.path.join(str(tmpdir), 'has_conda.tar')
    extract_path = os.path.join(str(tmpdir), 'output')
    env.pack(out_path, dest_prefix=extract_path if fix_dest else None)

    os.mkdir(extract_path)

    assert os.path.exists(out_path)
    assert tarfile.is_tarfile(out_path)
    # Extract tarfile
    with tarfile.open(out_path, ignore_zeros=True) as fil:
        fil.extractall(extract_path)

    if on_win:
        fnames = ['conda.exe', 'activate.bat']
        # New conda drops deactivate.bat files
        if not fix_dest:
            fnames.append("deactivate.bat")
    else:
        fnames = ['conda', 'activate', 'deactivate']
    # Check conda/activate/deactivate all present
    for fname in fnames:
        fpath = os.path.join(extract_path, BIN_DIR, fname)
        assert os.path.exists(fpath)
        # Make sure we have replaced the activate/deactivate scripts
        # if the dest_prefix was not fixed; make sure we haven't
        # done so if it is.
        if 'activate' in fname:
            with open(fpath) as fp:
                data = fp.read()
                if fix_dest:
                    assert 'CONDA_PACK' not in data
                else:
                    assert 'CONDA_PACK' in data

    # Check the packaged conda works and recognizes its environment.
    # We need to unset CONDA_PREFIX to simulate unpacking into an environment
    # where conda is not already present.
    if on_win:
        if fix_dest:
            # XXX: Conda windows activatation scripts now seem to assume a base
            # conda install, rather than relative paths. Given that this tool
            # is mostly for deploying code, and usually on servers (not
            # windows), this failure isn't critical but isn't 100% correct.
            # Ideally this test shouldn't need to special case `fix_dest`, and
            # use the same batch commands in both cases.
            commands = (r"@call {path}\condabin\conda activate".format(
                path=extract_path), r"@conda info --json",
                        r"@conda deactivate")
        else:
            commands = (r"@set CONDA_PREFIX=", r"@set CONDA_SHVL=",
                        r"@call {path}\Scripts\activate".format(
                            path=extract_path), r"@conda info --json",
                        r"@deactivate")
        script_file = tmpdir.join('unpack.bat')
        cmd = ['cmd', '/c', str(script_file)]

    else:
        commands = ("unset CONDA_PREFIX", "unset CONDA_SHLVL",
                    ". {path}/bin/activate".format(path=extract_path),
                    "conda info --json", ". deactivate >/dev/null 2>/dev/null")
        script_file = tmpdir.join('unpack.sh')
        cmd = ['/usr/bin/env', 'bash', str(script_file)]

    script_file.write('\n'.join(commands))
    out = subprocess.check_output(cmd, stderr=subprocess.STDOUT).decode()
    conda_info = json.loads(out)
    extract_path_n = normpath(extract_path)
    for var in ('conda_prefix', 'sys.prefix', 'default_prefix', 'root_prefix'):
        assert normpath(conda_info[var]) == extract_path_n
    assert extract_path_n in list(map(normpath, conda_info['envs']))

    # Check the conda-meta directory has been anonymized
    for path in glob(os.path.join(extract_path, 'conda-meta', '*.json')):
        with open(path) as fil:
            data = json.load(fil)

        for field in ["extracted_package_dir", "package_tarball_full_path"]:
            if field in data:
                assert data[field] == ""

        if "link" in data and "source" in data["link"]:
            assert data["link"]["source"] == ""
Example #16
0
def py36_env():
    return CondaEnv.from_prefix(py36_path)
Example #17
0
def test_works_with_no_python():
    # Collection doesn't require python
    env = CondaEnv.from_prefix(nopython_path)
    # non-empty
    assert len(env)
Example #18
0
def test_ignore_errors_editable_packages():
    CondaEnv.from_prefix(py36_editable_path, ignore_editable_packages=True)
Example #19
0
def test_pack_with_conda(tmpdir, fix_dest):
    env = CondaEnv.from_prefix(has_conda_path)
    out_path = os.path.join(str(tmpdir), 'has_conda.tar')
    extract_path = os.path.join(str(tmpdir), 'output')
    env.pack(out_path, dest_prefix=extract_path if fix_dest else None)

    os.mkdir(extract_path)

    assert os.path.exists(out_path)
    assert tarfile.is_tarfile(out_path)
    # Extract tarfile
    with tarfile.open(out_path) as fil:
        fil.extractall(extract_path)

    if on_win:
        fnames = ('conda.exe', 'activate.bat', 'deactivate.bat')
    else:
        fnames = ('conda', 'activate', 'deactivate')
    # Check conda/activate/deactivate all present
    for fname in fnames:
        fpath = os.path.join(extract_path, BIN_DIR, fname)
        assert os.path.exists(fpath)
        # Make sure we have replaced the activate/deactivate scripts
        # if the dest_prefix was not fixed; make sure we haven't
        # done so if it is.
        if 'activate' in fname:
            with open(fpath) as fp:
                data = fp.read()
                if fix_dest:
                    assert 'CONDA_PACK' not in data
                else:
                    assert 'CONDA_PACK' in data

    # Check the packaged conda works and recognizes its environment.
    # We need to unset CONDA_PREFIX to simulate unpacking into an environment
    # where conda is not already present.
    if on_win:
        commands = (r"@set CONDA_PREFIX=",
                    r"@call {path}\Scripts\activate".format(path=extract_path),
                    r"@conda info --json", r"@deactivate")
        script_file = tmpdir.join('unpack.bat')
        cmd = ['cmd', '/c', str(script_file)]

    else:
        commands = ("unset CONDA_PREFIX",
                    ". {path}/bin/activate".format(path=extract_path),
                    "conda info --json", ". deactivate")
        script_file = tmpdir.join('unpack.sh')
        cmd = ['/usr/bin/env', 'bash', str(script_file)]

    script_file.write('\n'.join(commands))
    out = subprocess.check_output(cmd, stderr=subprocess.STDOUT).decode()
    conda_info = json.loads(out)
    extract_path_n = normpath(extract_path)
    for var in ('conda_prefix', 'sys.prefix', 'default_prefix', 'root_prefix'):
        assert normpath(conda_info[var]) == extract_path_n
    assert extract_path_n in list(map(normpath, conda_info['envs']))

    # Check the conda-meta directory has been anonymized
    for path in glob(os.path.join(extract_path, 'conda-meta', '*.json')):
        with open(path) as fil:
            data = json.load(fil)

        for field in ["extracted_package_dir", "package_tarball_full_path"]:
            if field in data:
                assert data[field] == ""

        if "link" in data and "source" in data["link"]:
            assert data["link"]["source"] == ""