Skip to content

Commit

Permalink
override channels and update slow tests
Browse files Browse the repository at this point in the history
--override-channels is added to address #336

some slow tests have been updated to avoid deadlocks identified in #360
  • Loading branch information
AlbertDeFusco committed Feb 6, 2022
1 parent b03ce0b commit 26b9c9e
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 61 deletions.
37 changes: 24 additions & 13 deletions anaconda_project/internal/conda_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,10 +62,6 @@ def _call_conda(extra_args, json_mode=False, platform=None, stdout_callback=None
if platform is not None:
env = os.environ.copy()
env['CONDA_SUBDIR'] = platform
if 'win' in platform:
env['CONDA_CHANNELS'] = 'defaults,msys2'
else:
env['CONDA_CHANNELS'] = 'defaults'

try:
(p, stdout_lines, stderr_lines) = streaming_popen.popen(cmd_list,
Expand Down Expand Up @@ -163,10 +159,13 @@ def create(prefix, pkgs=None, channels=(), stdout_callback=None, stderr_callback
if os.path.exists(prefix):
raise CondaEnvExistsError('Conda environment [%s] already exists' % prefix)

cmd_list = ['create', '--yes', '--prefix', prefix]
cmd_list = ['create', '--override-channels', '--yes', '--prefix', prefix]

for channel in channels:
cmd_list.extend(['--channel', channel])
if channels:
for channel in channels:
cmd_list.extend(['--channel', channel])
else:
cmd_list.extend(['--channel', 'defaults'])

cmd_list.extend(pkgs)
_call_conda(cmd_list, stdout_callback=stdout_callback, stderr_callback=stderr_callback)
Expand All @@ -192,11 +191,14 @@ def install(prefix, pkgs=None, channels=(), stdout_callback=None, stderr_callbac
raise TypeError('must specify a list of one or more packages to install into existing environment, not %r',
pkgs)

cmd_list = ['install', '--yes']
cmd_list = ['install', '--override-channels', '--yes']
cmd_list.extend(['--prefix', prefix])

for channel in channels:
cmd_list.extend(['--channel', channel])
if channels:
for channel in channels:
cmd_list.extend(['--channel', channel])
else:
cmd_list.extend(['--channel', 'defaults'])

cmd_list.extend(pkgs)
_call_conda(cmd_list, stdout_callback=stdout_callback, stderr_callback=stderr_callback)
Expand Down Expand Up @@ -268,10 +270,19 @@ def resolve_dependencies(pkgs, channels=(), platform=None):
# after we remove it, and then conda's mkdir would fail.
os.rmdir(prefix)

cmd_list = ['create', '--yes', '--quiet', '--json', '--dry-run', '--prefix', prefix]
cmd_list = ['create', '--override-channels', '--yes', '--quiet', '--json', '--dry-run', '--prefix', prefix]

for channel in channels:
cmd_list.extend(['--channel', channel])
if channels:
for channel in channels:
cmd_list.extend(['--channel', channel])
else:
cmd_list.extend(['--channel', 'defaults'])

# This is only needed here (cross-platform solves) and not in create
# or install since Conda defaults already ensure that msys2 is present.
if platform is not None:
if 'win' in platform:
cmd_list.extend(['--channel', 'msys2'])

cmd_list.extend(pkgs)
try:
Expand Down
80 changes: 32 additions & 48 deletions anaconda_project/internal/test/test_conda_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -249,15 +249,17 @@ def do_test(dirname):

def test_conda_create_gets_channels(monkeypatch):
def mock_call_conda(extra_args, json_mode=False, platform=None, stdout_callback=None, stderr_callback=None):
assert ['create', '--yes', '--prefix', '/prefix', '--channel', 'foo', 'python'] == extra_args
assert ['create', '--override-channels', '--yes', '--prefix', '/prefix', '--channel', 'foo',
'python'] == extra_args

monkeypatch.setattr('anaconda_project.internal.conda_api._call_conda', mock_call_conda)
conda_api.create(prefix='/prefix', pkgs=['python'], channels=['foo'])


def test_conda_install_gets_channels(monkeypatch):
def mock_call_conda(extra_args, json_mode=False, platform=None, stdout_callback=None, stderr_callback=None):
assert ['install', '--yes', '--prefix', '/prefix', '--channel', 'foo', 'python'] == extra_args
assert ['install', '--override-channels', '--yes', '--prefix', '/prefix', '--channel', 'foo',
'python'] == extra_args

monkeypatch.setattr('anaconda_project.internal.conda_api._call_conda', mock_call_conda)
conda_api.install(prefix='/prefix', pkgs=['python'], channels=['foo'])
Expand Down Expand Up @@ -636,40 +638,41 @@ def test_environ_set_prefix_to_root():


@pytest.mark.slow
def test_resolve_dependencies_with_actual_conda_current_platform():
@pytest.mark.parametrize('p', conda_api.default_platforms_plus_32_bit)
def test_resolve_dependencies_with_actual_conda(p):
try:
result = conda_api.resolve_dependencies(['bokeh=0.12.7'], platform=None)
result = conda_api.resolve_dependencies(['requests=2.20.1'], platform=p)
except conda_api.CondaError as e:
print("*** Dependency resolution failed on %s" % p)
pprint(e.json)
raise e

names = [pkg[0] for pkg in result]
assert 'bokeh' in names
assert 'requests' in names
names_and_versions = [(pkg[0], pkg[1]) for pkg in result]
assert ('bokeh', '0.12.7') in names_and_versions
assert len(result) > 1 # bokeh has some dependencies so should be >1
assert ('requests', '2.20.1') in names_and_versions
assert len(result) > 1 # requests has some dependencies so should be >1

print("Dependency resolution test OK on %s" % p)


@pytest.mark.slow
def test_resolve_dependencies_with_actual_conda_other_platforms():
for p in conda_api.default_platforms_plus_32_bit:
if p == conda_api.current_platform():
print("Skipping dependency resolution test on current platform %s" % p)
continue
try:
result = conda_api.resolve_dependencies(['bokeh=0.12.7'], platform=p)
except conda_api.CondaError as e:
print("*** Dependency resolution failed on %s" % p)
pprint(e.json)
raise e
@pytest.mark.parametrize('p', [p for p in conda_api.default_platforms_plus_32_bit if 'win' in p])
def test_resolve_msys2_dependencies_with_actual_conda(p):
try:
result = conda_api.resolve_dependencies(['m2-msys2-runtime=2.5.0.17080.65c939c'], platform=p)
except conda_api.CondaError as e:
print("*** Dependency resolution failed on %s" % p)
pprint(e.json)
raise e

names = [pkg[0] for pkg in result]
assert 'bokeh' in names
names_and_versions = [(pkg[0], pkg[1]) for pkg in result]
assert ('bokeh', '0.12.7') in names_and_versions
assert len(result) > 1 # bokeh has some dependencies so should be >1
names = [pkg[0] for pkg in result]
assert 'm2-msys2-runtime' in names
names_and_versions = [(pkg[0], pkg[1]) for pkg in result]
assert ('m2-msys2-runtime', '2.5.0.17080.65c939c') in names_and_versions
assert len(result) > 1 # requests has some dependencies so should be >1

print("Dependency resolution test OK on %s" % p)
print("Dependency resolution test OK on %s" % p)


@pytest.mark.slow
Expand Down Expand Up @@ -1135,35 +1138,16 @@ def test_current_platform_non_x86_linux(monkeypatch):
assert conda_api.current_platform() == 'linux-armv7l'


def test_current_platform_non_x86_mac(monkeypatch):
monkeypatch.setenv('CONDA_SUBDIR', 'osx-arm64')
assert conda_api.current_platform() == 'osx-arm64'


# this test assumes all dev and CI happens on popular platforms.
def test_current_platform_is_in_default():
assert conda_api.current_platform() in conda_api.default_platforms


@pytest.mark.slow
def test_msys_for_all_platforms():
for p in conda_api.default_platforms_plus_32_bit:
(name, bits) = conda_api.parse_platform(p)
info = conda_api.info(platform=p)
print("*** info() for %s" % p)
pprint(info)
assert 'channels' in info

# conda 4.1 has a slash on the channels and 4.3 does not
def no_slash(url):
if url.endswith("/"):
return url[:-1]
else:
return url

channels = [no_slash(channel) for channel in info['channels']]
# Designed to handle repo.continuum.io and repo.anaconda.com
channels = '\n'.join(channels)
if name == 'win':
assert '/msys2/%s' % p in channels
assert '/msys2/noarch' in channels


def test_sort_platform_list():
everything_sorted = ('all', 'linux', 'osx', 'win') + conda_api.default_platforms_plus_32_bit
backward = list(reversed(everything_sorted))
Expand Down

0 comments on commit 26b9c9e

Please sign in to comment.