示例#1
0
    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', )
示例#2
0
    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 ")
示例#3
0
    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)
示例#4
0
    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)
示例#5
0
    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)
示例#6
0
    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)