def check(dirname): prefix = os.path.join(dirname, "myenv") os.makedirs(os.path.join(prefix, 'conda-meta')) def mock_installed(prefix): return {'bokeh': ('bokeh', '0.12.4', '1')} monkeypatch.setattr('anaconda_project.internal.conda_api.installed', mock_installed) spec_with_matching_bokeh = EnvSpec(name='myenv', conda_packages=['bokeh=0.12.4=1'], pip_packages=[], channels=[]) spec_with_more_vague_bokeh = EnvSpec(name='myenv', conda_packages=['bokeh=0.12'], pip_packages=[], channels=[]) spec_with_unspecified_bokeh = EnvSpec(name='myenv', conda_packages=['bokeh'], pip_packages=[], channels=[]) spec_with_wrong_version_bokeh = EnvSpec( name='myenv', conda_packages=['bokeh=0.12.3'], pip_packages=[], channels=[]) spec_with_wrong_build_bokeh = EnvSpec( name='myenv', conda_packages=['bokeh=0.12.4=0'], pip_packages=[], channels=[]) manager = DefaultCondaManager(frontend=NullFrontend()) deviations = manager.find_environment_deviations( prefix, spec_with_matching_bokeh) assert deviations.missing_packages == () assert deviations.wrong_version_packages == () deviations = manager.find_environment_deviations( prefix, spec_with_more_vague_bokeh) assert deviations.missing_packages == () assert deviations.wrong_version_packages == () deviations = manager.find_environment_deviations( prefix, spec_with_unspecified_bokeh) assert deviations.missing_packages == () assert deviations.wrong_version_packages == () deviations = manager.find_environment_deviations( prefix, spec_with_wrong_version_bokeh) assert deviations.missing_packages == () assert deviations.wrong_version_packages == ('bokeh', ) deviations = manager.find_environment_deviations( prefix, spec_with_wrong_build_bokeh) assert deviations.missing_packages == () assert deviations.wrong_version_packages == ('bokeh', )
def do_test(dirname): envdir = os.path.join(dirname, spec.name) manager = DefaultCondaManager(frontend=NullFrontend()) deviations = manager.find_environment_deviations(envdir, spec) error = "Env spec 'myenv' does not have the current platform %s in the lock file" % conda_api.current_platform() assert error == deviations.summary with pytest.raises(CondaManagerError) as excinfo: manager.fix_environment_deviations(envdir, spec, deviations=deviations) assert str(excinfo.value).startswith("Unable to update environment at ")
def do_test(dirname): envdir = os.path.join(dirname, spec.name) manager = DefaultCondaManager(frontend=NullFrontend()) def print_timestamps(when): newest_in_prefix = 0 for d in manager._timestamp_comparison_directories(envdir): try: t = os.path.getmtime(d) except Exception: t = 0 if t > newest_in_prefix: newest_in_prefix = t timestamp_fname = manager._timestamp_file(envdir, spec) try: timestamp_file = os.path.getmtime(timestamp_fname) except Exception: timestamp_file = 0 print("%s: timestamp file %d prefix %d diff %g" % (when, timestamp_file, newest_in_prefix, newest_in_prefix - timestamp_file)) print_timestamps("before env creation") assert not os.path.isdir(envdir) assert not os.path.exists(os.path.join(envdir, IPYTHON_BINARY)) assert not os.path.exists(os.path.join(envdir, PYINSTRUMENT_BINARY)) assert not manager._timestamp_file_up_to_date(envdir, spec) deviations = manager.find_environment_deviations(envdir, spec) assert set(deviations.missing_packages) == {'python', 'ipython'} assert deviations.missing_pip_packages == ('pyinstrument', ) assert not deviations.ok manager.fix_environment_deviations(envdir, spec, deviations) print_timestamps("after fixing deviations") assert os.path.isdir(envdir) assert os.path.isdir(os.path.join(envdir, "conda-meta")) assert os.path.exists(os.path.join(envdir, IPYTHON_BINARY)) assert os.path.exists(os.path.join(envdir, PYINSTRUMENT_BINARY)) assert manager._timestamp_file_up_to_date(envdir, spec) called = [] from anaconda_project.internal.pip_api import installed as real_pip_installed from anaconda_project.internal.conda_api import installed as real_conda_installed def traced_pip_installed(*args, **kwargs): called.append(("pip_api.installed", args, kwargs)) return real_pip_installed(*args, **kwargs) monkeypatch.setattr('anaconda_project.internal.pip_api.installed', traced_pip_installed) def trace_conda_installed(*args, **kwargs): called.append(("conda_api.installed", args, kwargs)) return real_conda_installed(*args, **kwargs) monkeypatch.setattr('anaconda_project.internal.conda_api.installed', trace_conda_installed) deviations = manager.find_environment_deviations(envdir, spec) assert [] == called assert deviations.missing_packages == () assert deviations.missing_pip_packages == () assert deviations.ok assert manager._timestamp_file_up_to_date(envdir, spec) # now modify conda-meta and check that we DO call the package managers time.sleep(1.1) # be sure we are in a new second conda_meta_dir = os.path.join(envdir, "conda-meta") print("conda-meta original timestamp: %d" % os.path.getmtime(conda_meta_dir)) inside_conda_meta = os.path.join(conda_meta_dir, "thing.txt") with codecs.open(inside_conda_meta, 'w', encoding='utf-8') as f: f.write(u"This file should change the mtime on conda-meta\n") print("file inside conda-meta %d and conda-meta itself %d" % (os.path.getmtime(inside_conda_meta), os.path.getmtime(conda_meta_dir))) os.remove(inside_conda_meta) print_timestamps("after touching conda-meta") assert not manager._timestamp_file_up_to_date(envdir, spec) deviations = manager.find_environment_deviations(envdir, spec) assert len(called) == 2 assert deviations.missing_packages == () assert deviations.missing_pip_packages == () # deviations should not be ok (due to timestamp) assert not deviations.ok assert not manager._timestamp_file_up_to_date(envdir, spec) # we want to be sure we update the timestamp file even though # there wasn't any actual work to do manager.fix_environment_deviations(envdir, spec, deviations) print_timestamps("after fixing deviations 2") assert manager._timestamp_file_up_to_date(envdir, spec)
def do_test(dirname): from codecs import open as real_open envdir = os.path.join(dirname, spec.name) manager = DefaultCondaManager(frontend=NullFrontend()) is_readonly = dict(readonly=False) def mock_open(*args, **kwargs): if is_readonly['readonly']: raise IOError("did not open") return real_open(*args, **kwargs) monkeypatch.setattr('codecs.open', mock_open) assert not os.path.isdir(envdir) assert not os.path.exists(os.path.join(envdir, IPYTHON_BINARY)) assert not os.path.exists(os.path.join(envdir, FLAKE8_BINARY)) assert not manager._timestamp_file_up_to_date(envdir, spec) deviations = manager.find_environment_deviations(envdir, spec) assert set(deviations.missing_packages) == {'python', 'ipython'} assert deviations.missing_pip_packages == ('pyinstrument', ) # with create=False, we won't create the env with pytest.raises(CondaManagerError) as excinfo: manager.fix_environment_deviations(envdir, spec, deviations, create=False) assert 'does not exist' in str(excinfo.value) assert not os.path.isdir(envdir) # now create the env manager.fix_environment_deviations(envdir, spec, deviations) assert os.path.isdir(envdir) assert os.path.isdir(os.path.join(envdir, "conda-meta")) assert os.path.exists(os.path.join(envdir, IPYTHON_BINARY)) assert os.path.exists(os.path.join(envdir, PYINSTRUMENT_BINARY)) assert manager._timestamp_file_up_to_date(envdir, spec) assert not manager._timestamp_file_up_to_date( envdir, spec_with_phony_pip_package) # test bad pip package throws error deviations = manager.find_environment_deviations( envdir, spec_with_phony_pip_package) assert deviations.missing_packages == () assert deviations.wrong_version_packages == () assert deviations.missing_pip_packages == ('nope_not_a_thing', ) with pytest.raises(CondaManagerError) as excinfo: manager.fix_environment_deviations(envdir, spec_with_phony_pip_package, deviations) assert 'Failed to install missing pip packages' in str(excinfo.value) assert not manager._timestamp_file_up_to_date( envdir, spec_with_phony_pip_package) # test bad url package throws error deviations = manager.find_environment_deviations( envdir, spec_with_bad_url_pip_package) assert deviations.missing_packages == () assert deviations.wrong_version_packages == () assert deviations.missing_pip_packages == ('phony', ) with pytest.raises(CondaManagerError) as excinfo: manager.fix_environment_deviations(envdir, spec_with_bad_url_pip_package, deviations) assert 'Failed to install missing pip packages' in str(excinfo.value) assert not manager._timestamp_file_up_to_date( envdir, spec_with_bad_url_pip_package) # test we notice wrong ipython version AND missing bokeh AND readonly environment is_readonly['readonly'] = True deviations = manager.find_environment_deviations( envdir, spec_with_bokeh_and_old_ipython) assert deviations.missing_packages == ('bokeh', ) assert deviations.wrong_version_packages == ('ipython', ) assert deviations.unfixable is_readonly['readonly'] = False # test we notice only missing bokeh deviations = manager.find_environment_deviations( envdir, spec_with_bokeh) assert deviations.missing_packages == ('bokeh', ) assert deviations.wrong_version_packages == () assert not deviations.unfixable # test we notice wrong ipython version and can downgrade deviations = manager.find_environment_deviations( envdir, spec_with_old_ipython) assert deviations.missing_packages == () assert deviations.wrong_version_packages == ('ipython', ) assert not deviations.unfixable manager.fix_environment_deviations(envdir, spec_with_old_ipython, deviations) assert manager._timestamp_file_up_to_date(envdir, spec_with_old_ipython) deviations = manager.find_environment_deviations( envdir, spec_with_old_ipython) assert deviations.missing_packages == () assert deviations.wrong_version_packages == () # update timestamp; this doesn't re-upgrade because `spec` doesn't # specify an ipython version assert not manager._timestamp_file_up_to_date(envdir, spec) deviations = manager.find_environment_deviations(envdir, spec) assert deviations.missing_packages == () assert deviations.wrong_version_packages == () # fix_environment_deviations should be a no-op on readonly envs # with no deviations, in particular the time stamp file should # not be changed and therefore not be up to date is_readonly['readonly'] = True manager.fix_environment_deviations(envdir, spec, deviations) assert not manager._timestamp_file_up_to_date(envdir, spec) # when the environment is readwrite, the timestamp file should # be updated is_readonly['readonly'] = False manager.fix_environment_deviations(envdir, spec, deviations) assert manager._timestamp_file_up_to_date(envdir, spec) deviations = manager.find_environment_deviations(envdir, spec) assert deviations.missing_packages == () assert deviations.wrong_version_packages == () # test that we can remove a package assert manager._timestamp_file_up_to_date(envdir, spec) time.sleep( 1) # removal is fast enough to break our timestamp resolution manager.remove_packages(prefix=envdir, packages=['ipython']) assert not os.path.exists(os.path.join(envdir, IPYTHON_BINARY)) assert not manager._timestamp_file_up_to_date(envdir, spec) # test for error removing with pytest.raises(CondaManagerError) as excinfo: manager.remove_packages(prefix=envdir, packages=['ipython']) # different versions of conda word this differently message = str(excinfo.value) valid_strings = ('no packages found to remove', 'Package not found', "named 'ipython' found to remove", 'PackagesNotFoundError:', "is missing from the environment") assert any(s in message for s in valid_strings) assert not manager._timestamp_file_up_to_date(envdir, spec) # test failure to exec pip def mock_call_pip(*args, **kwargs): raise pip_api.PipError("pip fail") monkeypatch.setattr('anaconda_project.internal.pip_api._call_pip', mock_call_pip) with pytest.raises(CondaManagerError) as excinfo: deviations = manager.find_environment_deviations(envdir, spec) assert 'pip failed while listing' in str(excinfo.value)
def do_test(dirname): envdir = os.path.join(dirname, spec.name) manager = DefaultCondaManager() assert not os.path.isdir(envdir) assert not os.path.exists(os.path.join(envdir, IPYTHON_BINARY)) assert not os.path.exists(os.path.join(envdir, FLAKE8_BINARY)) assert not manager._timestamp_file_up_to_date(envdir, spec) deviations = manager.find_environment_deviations(envdir, spec) assert deviations.missing_packages == ('ipython', ) assert deviations.missing_pip_packages == ('flake8', ) manager.fix_environment_deviations(envdir, spec, deviations) assert os.path.isdir(envdir) assert os.path.isdir(os.path.join(envdir, "conda-meta")) assert os.path.exists(os.path.join(envdir, IPYTHON_BINARY)) assert os.path.exists(os.path.join(envdir, FLAKE8_BINARY)) assert manager._timestamp_file_up_to_date(envdir, spec) assert not manager._timestamp_file_up_to_date( envdir, spec_with_phony_pip_package) # test bad pip package throws error deviations = manager.find_environment_deviations( envdir, spec_with_phony_pip_package) assert deviations.missing_packages == () assert deviations.missing_pip_packages == ('nope_not_a_thing', ) with pytest.raises(CondaManagerError) as excinfo: manager.fix_environment_deviations(envdir, spec_with_phony_pip_package, deviations) assert 'Failed to install missing pip packages' in str(excinfo.value) assert not manager._timestamp_file_up_to_date( envdir, spec_with_phony_pip_package) # test bad url package throws error deviations = manager.find_environment_deviations( envdir, spec_with_bad_url_pip_package) assert deviations.missing_packages == () assert deviations.missing_pip_packages == ('phony', ) with pytest.raises(CondaManagerError) as excinfo: manager.fix_environment_deviations(envdir, spec_with_bad_url_pip_package, deviations) assert 'Failed to install missing pip packages' in str(excinfo.value) assert not manager._timestamp_file_up_to_date( envdir, spec_with_bad_url_pip_package) # test that we can remove a package assert manager._timestamp_file_up_to_date(envdir, spec) manager.remove_packages(prefix=envdir, packages=['ipython']) assert not os.path.exists(os.path.join(envdir, IPYTHON_BINARY)) assert not manager._timestamp_file_up_to_date(envdir, spec) # test for error removing with pytest.raises(CondaManagerError) as excinfo: manager.remove_packages(prefix=envdir, packages=['ipython']) # different versions of conda word this differently assert 'no packages found to remove' in str( excinfo.value) or 'Package not found' in str(excinfo.value) assert not manager._timestamp_file_up_to_date(envdir, spec) # test failure to exec pip def mock_call_pip(*args, **kwargs): raise pip_api.PipError("pip fail") monkeypatch.setattr('anaconda_project.internal.pip_api._call_pip', mock_call_pip) with pytest.raises(CondaManagerError) as excinfo: deviations = manager.find_environment_deviations(envdir, spec) assert 'pip failed while listing' in str(excinfo.value)
def do_test(dirname): envdir = os.path.join(dirname, spec.name) manager = DefaultCondaManager(frontend=NullFrontend()) assert not os.path.isdir(envdir) assert not os.path.exists(os.path.join(envdir, IPYTHON_BINARY)) assert not os.path.exists(os.path.join(envdir, FLAKE8_BINARY)) assert not manager._timestamp_file_up_to_date(envdir, spec) deviations = manager.find_environment_deviations(envdir, spec) assert deviations.missing_packages == ('ipython', ) assert deviations.missing_pip_packages == ('pyinstrument', ) # with create=False, we won't create the env with pytest.raises(CondaManagerError) as excinfo: manager.fix_environment_deviations(envdir, spec, deviations, create=False) assert 'does not exist' in str(excinfo.value) assert not os.path.isdir(envdir) # now create the env manager.fix_environment_deviations(envdir, spec, deviations) assert os.path.isdir(envdir) assert os.path.isdir(os.path.join(envdir, "conda-meta")) assert os.path.exists(os.path.join(envdir, IPYTHON_BINARY)) assert os.path.exists(os.path.join(envdir, PYINSTRUMENT_BINARY)) assert manager._timestamp_file_up_to_date(envdir, spec) assert not manager._timestamp_file_up_to_date(envdir, spec_with_phony_pip_package) # test bad pip package throws error deviations = manager.find_environment_deviations(envdir, spec_with_phony_pip_package) assert deviations.missing_packages == () assert deviations.wrong_version_packages == () assert deviations.missing_pip_packages == ('nope_not_a_thing', ) with pytest.raises(CondaManagerError) as excinfo: manager.fix_environment_deviations(envdir, spec_with_phony_pip_package, deviations) assert 'Failed to install missing pip packages' in str(excinfo.value) assert not manager._timestamp_file_up_to_date(envdir, spec_with_phony_pip_package) # test bad url package throws error deviations = manager.find_environment_deviations(envdir, spec_with_bad_url_pip_package) assert deviations.missing_packages == () assert deviations.wrong_version_packages == () assert deviations.missing_pip_packages == ('phony', ) with pytest.raises(CondaManagerError) as excinfo: manager.fix_environment_deviations(envdir, spec_with_bad_url_pip_package, deviations) assert 'Failed to install missing pip packages' in str(excinfo.value) assert not manager._timestamp_file_up_to_date(envdir, spec_with_bad_url_pip_package) # test we notice wrong ipython version AND missing bokeh deviations = manager.find_environment_deviations(envdir, spec_with_bokeh_and_old_ipython) assert deviations.missing_packages == ('bokeh', ) assert deviations.wrong_version_packages == ('ipython', ) # test we notice only missing bokeh deviations = manager.find_environment_deviations(envdir, spec_with_bokeh) assert deviations.missing_packages == ('bokeh', ) assert deviations.wrong_version_packages == () # test we notice wrong ipython version and can downgrade deviations = manager.find_environment_deviations(envdir, spec_with_old_ipython) assert deviations.missing_packages == () assert deviations.wrong_version_packages == ('ipython', ) manager.fix_environment_deviations(envdir, spec_with_old_ipython, deviations) assert manager._timestamp_file_up_to_date(envdir, spec_with_old_ipython) deviations = manager.find_environment_deviations(envdir, spec_with_old_ipython) assert deviations.missing_packages == () assert deviations.wrong_version_packages == () # update timestamp; this doesn't re-upgrade because `spec` doesn't # specify an ipython version assert not manager._timestamp_file_up_to_date(envdir, spec) deviations = manager.find_environment_deviations(envdir, spec) assert deviations.missing_packages == () assert deviations.wrong_version_packages == () manager.fix_environment_deviations(envdir, spec, deviations) assert manager._timestamp_file_up_to_date(envdir, spec) deviations = manager.find_environment_deviations(envdir, spec) assert deviations.missing_packages == () assert deviations.wrong_version_packages == () # test that we can remove a package assert manager._timestamp_file_up_to_date(envdir, spec) time.sleep(1) # removal is fast enough to break our timestamp resolution manager.remove_packages(prefix=envdir, packages=['ipython']) assert not os.path.exists(os.path.join(envdir, IPYTHON_BINARY)) assert not manager._timestamp_file_up_to_date(envdir, spec) # test for error removing with pytest.raises(CondaManagerError) as excinfo: manager.remove_packages(prefix=envdir, packages=['ipython']) # different versions of conda word this differently message = str(excinfo.value) valid_strings = ('no packages found to remove', 'Package not found', "named 'ipython' found to remove", "is missing from the environment") assert any(s in message for s in valid_strings) assert not manager._timestamp_file_up_to_date(envdir, spec) # test failure to exec pip def mock_call_pip(*args, **kwargs): raise pip_api.PipError("pip fail") monkeypatch.setattr('anaconda_project.internal.pip_api._call_pip', mock_call_pip) with pytest.raises(CondaManagerError) as excinfo: deviations = manager.find_environment_deviations(envdir, spec) assert 'pip failed while listing' in str(excinfo.value)