def test_upload_failing_s3_upload(monkeypatch): def check(dirname): with fake_server(monkeypatch, expected_basename='foo.zip', fail_these=('s3', )): project = project_ops.create(dirname) archivefile = os.path.join(dirname, "tmp.zip") project_ops.archive(project, archivefile) status = _upload(project, archivefile, "foo.zip", site='unit_test') assert not status assert '501' in status.errors[0] with_directory_contents(dict(), check)
def test_run_command_nonexistent_project(capsys): def check_run_nonexistent(dirname): project_dir = os.path.join(dirname, "nope") result = _parse_args_and_run_subcommand( ['anaconda-project', 'run', '--directory', project_dir]) assert 1 == result out, err = capsys.readouterr() assert out == "" assert ("Project directory '%s' does not exist." % project_dir) in err with_directory_contents(dict(), check_run_nonexistent)
def test_read_yaml_file_that_is_a_directory(): def check_read_directory(dirname): filename = os.path.join(dirname, "dir.yaml") os.makedirs(filename) with pytest.raises(IOError) as excinfo: YamlFile(filename) import platform if platform.system() == 'Windows': assert errno.EACCES == excinfo.value.errno else: assert errno.EISDIR == excinfo.value.errno with_directory_contents(dict(), check_read_directory)
def test_shutdown_service_run_state_command_failure(): def check(dirname): local_state_file = LocalStateFile.load_for_directory(dirname) false_commandline = tmp_script_commandline("""import sys sys.exit(1) """) local_state_file.set_service_run_state('FOO', {'shutdown_commands': [false_commandline]}) status = shutdown_service_run_state(local_state_file, 'FOO') assert not status assert status.status_description == "Shutdown commands failed for FOO." assert status.errors == ["Shutting down FOO, command %r failed with code 1." % false_commandline] with_directory_contents(dict(), check)
def test_conda_default_env_not_set(): def check_conda_default_env_not_set(dirname): requirement = _empty_default_requirement() project_dir_disable_dedicated_env(dirname) local_state = LocalStateFile.load_for_directory(dirname) status = requirement.check_status( minimal_environ_no_conda_env(PROJECT_DIR=dirname), local_state, 'default', UserConfigOverrides()) expected = "'{}' doesn't look like it contains a Conda environment yet.".format( os.path.join(dirname, 'envs', 'default')) assert expected == status.status_description with_directory_contents(dict(), check_conda_default_env_not_set)
def test_shutdown_service_run_state_command_success(): def check(dirname): local_state_file = LocalStateFile.load_for_directory(dirname) true_commandline = tmp_script_commandline("""import sys sys.exit(0) """) local_state_file.set_service_run_state( 'FOO', {'shutdown_commands': [true_commandline]}) status = shutdown_service_run_state(local_state_file, 'FOO') assert status assert status.status_description == "Successfully shut down FOO." with_directory_contents(dict(), check)
def test_conda_default_env_is_bogus(): def check_conda_default_env_is_bogus(dirname): requirement = _empty_default_requirement() project_dir_disable_dedicated_env(dirname) local_state = LocalStateFile.load_for_directory(dirname) status = requirement.check_status( minimal_environ_no_conda_env(**{'PROJECT_DIR': dirname}), local_state, 'default', UserConfigOverrides(inherited_env="not_a_real_env_anyone_has")) expected = "'not_a_real_env_anyone_has' doesn't look like it contains a Conda environment yet." assert expected == status.status_description with_directory_contents(dict(), check_conda_default_env_is_bogus)
def test_prepare_empty_directory(): def prepare_empty(dirname): project = Project(dirname) environ = minimal_environ() result = prepare_without_interaction(project, environ=environ) assert result.errors == [] assert result assert result.env_prefix is not None assert dict(PROJECT_DIR=project.directory_path) == strip_environ(result.environ) assert dict() == strip_environ(environ) assert result.command_exec_info is None with_directory_contents(dict(), prepare_empty)
def test_download_has_http_error(): def inside_directory_get_http_error(dirname): filename = os.path.join(dirname, "downloaded-file") with HttpServerTestContext() as server: url = server.error_url download = FileDownloader(url=url, filename=filename, hash_algorithm='md5') response = IOLoop.current().run_sync(download.run) assert ['Failed download to %s: HTTP 404: Not Found' % filename] == download.errors assert response is None assert not os.path.isfile(filename) assert not os.path.isfile(filename + ".part") with_directory_contents(dict(), inside_directory_get_http_error)
def test_unprepare_nothing_to_do(): def unprepare_nothing(dirname): project = Project(dirname) environ = minimal_environ() result = prepare_without_interaction(project, environ=environ) assert result.errors == [] assert result status = unprepare(project, result, whitelist=[]) assert status.errors == [] assert status assert status.status_description == 'Nothing to clean up.' with_directory_contents(dict(), unprepare_nothing)
def test_conda_invoke_fails(monkeypatch): def mock_popen(args, stdout=None, stderr=None): raise OSError("failed to exec") def do_test(dirname): monkeypatch.setattr('subprocess.Popen', mock_popen) with pytest.raises(conda_api.CondaError) as excinfo: conda_api.info() assert 'failed to exec' in repr(excinfo.value) conda_cmd = os.path.basename(conda_api.CONDA_EXE) assert conda_cmd + ' info' in repr(excinfo.value) with_directory_contents(dict(), do_test)
def test_conda_remove_no_packages(monkeypatch): monkeypatch_conda_not_to_use_links(monkeypatch) def do_test(dirname): envdir = os.path.join(dirname, "myenv") conda_api.create(prefix=envdir, pkgs=['python']) with pytest.raises(TypeError) as excinfo: conda_api.remove(prefix=envdir, pkgs=[]) assert 'must specify a list' in repr(excinfo.value) with_directory_contents(dict(), do_test)
def test_unprepare_empty_directory(monkeypatch): _monkeypatch_reduced_environment(monkeypatch) def unprepare_empty(dirname): project = Project(dirname) environ = minimal_environ() result = prepare_without_interaction(project, environ=environ) assert result.errors == [] assert result status = unprepare(project, result) assert status.errors == [] assert status with_directory_contents(dict(), unprepare_empty)
def test_upload_missing_login(monkeypatch): def check(dirname): with fake_server(monkeypatch, expected_basename='foo.zip', fail_these=('missing_login', )): project = project_ops.create(dirname) archivefile = os.path.join(dirname, "tmp.zip") project_ops.archive(project, archivefile) status = _upload(project, archivefile, "foo.zip", site='unit_test') assert not status assert ['Not logged in.'] == status.errors with_directory_contents(dict(), check)
def test_init_in_pwd(capsys, monkeypatch): def check(dirname): _monkeypatch_pwd(monkeypatch, dirname) code = _parse_args_and_run_subcommand(['anaconda-project', 'init']) assert code == 0 assert os.path.isfile(os.path.join(dirname, DEFAULT_PROJECT_FILENAME)) out, err = capsys.readouterr() assert ("Project configuration is in %s\n" % (os.path.join(dirname, DEFAULT_PROJECT_FILENAME))) == out assert '' == err with_directory_contents(dict(), check)
def test_archive_command_on_empty_project(capsys): def check(dirname): archivefile = os.path.join(dirname, "foo.zip") code = _parse_args_and_run_subcommand(['anaconda-project', 'archive', '--directory', dirname, archivefile]) assert code == 1 out, err = capsys.readouterr() assert "Project file 'anaconda-project.yml' does not exist.\nUnable to load the project.\n" == err assert '' == out assert not os.path.exists(os.path.join(dirname, DEFAULT_PROJECT_FILENAME)) assert not os.path.exists(archivefile) with_directory_contents(dict(), check)
def test_redis_url_cannot_connect(monkeypatch): def check_cannot_connect(dirname): local_state = LocalStateFile.load_for_directory(dirname) requirement = RedisRequirement(registry=RequirementsRegistry(), env_var="REDIS_URL") can_connect_args_list = _monkeypatch_can_connect_to_socket_fails(monkeypatch) status = requirement.check_status(dict(REDIS_URL="redis://example.com:1234/"), local_state, 'default', UserConfigOverrides()) assert dict(host='example.com', port=1234, timeout_seconds=0.5) == can_connect_args_list[0] assert dict(host='localhost', port=6379, timeout_seconds=0.5) == can_connect_args_list[1] assert not status expected = "Cannot connect to Redis at redis://example.com:1234/." assert expected == status.status_description with_directory_contents({}, check_cannot_connect)
def test_interactively_no_fix_empty_project(monkeypatch, capsys): def check(dirname): _monkeypatch_input(monkeypatch, ["n"]) project = load_project(dirname) first_line = "Project file '%s' does not exist." % DEFAULT_PROJECT_FILENAME assert project.problems == [first_line] out, err = capsys.readouterr() assert out == ( "%s\nCreate file '%s'? " % (first_line, os.path.join(dirname, DEFAULT_PROJECT_FILENAME))) assert err == "" with_directory_contents({}, check)
def test_create_missing_project_file(): def create_file(dirname): filename = os.path.join(dirname, DEFAULT_PROJECT_FILENAME) assert not os.path.exists(filename) project_file = ProjectFile.load_for_directory(dirname) assert project_file is not None assert not os.path.exists(filename) project_file.save() assert os.path.exists(filename) with codecs.open(filename, 'r', 'utf-8') as file: contents = file.read() expected = expected_default_file.replace("<NAME>", os.path.basename(dirname)) assert_identical_except_blank_lines(expected, contents) with_directory_contents(dict(), create_file)
def test_filename_not_set(): def check_not_set(dirname): local_state = LocalStateFile.load_for_directory(dirname) requirement = DownloadRequirement(registry=RequirementsRegistry(), env_var=ENV_VAR, url='http://example.com', filename=ENV_VAR) status = requirement.check_status(dict(PROJECT_DIR=dirname), local_state, 'default', UserConfigOverrides()) assert not status assert "Environment variable {} is not set.".format( ENV_VAR) == status.status_description with_directory_contents({}, check_not_set)
def test_missing_package(): def check_missing_package(dirname): requirement = CondaEnvRequirement( registry=RequirementsRegistry(), env_specs=dict(default=EnvSpec( 'default', ['boguspackage', 'boguspackage2'], []))) project_dir_disable_dedicated_env(dirname) local_state = LocalStateFile.load_for_directory(dirname) environ = minimal_environ(PROJECT_DIR=dirname) status = requirement.check_status( environ, local_state, 'default', UserConfigOverrides(inherited_env=environ.get(conda_env_var))) assert "Conda environment is missing packages: boguspackage, boguspackage2" == status.status_description with_directory_contents(dict(), check_missing_package)
def test_get_all_run_states(): def check_file(dirname): filename = os.path.join(dirname, DEFAULT_LOCAL_STATE_FILENAME) assert os.path.exists(filename) local_state_file = LocalStateFile.load_for_directory(dirname) state = local_state_file.get_service_run_state("foo") assert dict(port=42) == state state = local_state_file.get_service_run_state("bar") assert dict(port=43) == state states = local_state_file.get_all_service_run_states() assert dict(foo=dict(port=42), bar=dict(port=43)) == states sample_run_states = SERVICE_RUN_STATES_SECTION + ":\n foo: { port: 42 }\n bar: { port: 43 }\n" with_directory_contents({DEFAULT_LOCAL_STATE_FILENAME: sample_run_states}, check_file)
def test_rename_target_does_not_exist(): def do_test(dirname): name1 = os.path.join(dirname, "foo") name2 = os.path.join(dirname, "bar") assert os.path.exists(name1) assert not os.path.exists(name2) assert open(name1).read() == 'stuff-foo' rename_over_existing(name1, name2) assert not os.path.exists(name1) assert os.path.exists(name2) assert open(name2).read() == 'stuff-foo' with_directory_contents(dict(foo='stuff-foo'), do_test)
def _ui_server_bad_form_name_test(capsys, name_template, expected_err): def do_test(dirname): io_loop = IOLoop() io_loop.make_current() events = [] def event_handler(event): events.append(event) project = Project(dirname) local_state_file = LocalStateFile.load_for_directory(dirname) requirement = EnvVarRequirement(registry=project.plugin_registry, env_var="FOO") status = requirement.check_status(dict(), local_state_file, 'default', UserConfigOverrides()) context = ConfigurePrepareContext(dict(), local_state_file, 'default', UserConfigOverrides(), [status]) server = UIServer(project, _no_op_prepare(context), event_handler, io_loop) # do a get so that _requirements_by_id below exists get_response = http_get(io_loop, server.url) assert 200 == get_response.code req_id = list(server._application._requirements_by_id.keys())[0] if '%s' in name_template: name = name_template % req_id else: name = name_template encoder = MultipartEncoder({name: 'bloop'}) body = encoder.to_string() headers = {'Content-Type': encoder.content_type} post_response = http_post(io_loop, server.url, body=body, headers=headers) # we just ignore bad form names, because they are assumed # to be some sort of hostile thing. we shouldn't ever # generate them on purpose. assert 200 == post_response.code server.unlisten() assert len(events) == 1 assert isinstance(events[0], UIServerDoneEvent) out, err = capsys.readouterr() assert out == "" assert err == expected_err with_directory_contents(dict(), do_test)
def test_installed_version_comparison(monkeypatch): 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', ) with_directory_contents(dict(), check)
def test_provide_context_properties(): def check_provide_contents(dirname): environ = dict(foo='bar') local_state_file = LocalStateFile.load_for_directory(dirname) requirement = EnvVarRequirement(RequirementsRegistry(), env_var="FOO") status = requirement.check_status(environ, local_state_file, 'default', UserConfigOverrides()) context = ProvideContext(environ=environ, local_state_file=local_state_file, default_env_spec_name='default', status=status, mode=PROVIDE_MODE_DEVELOPMENT, frontend=NullFrontend()) assert dict(foo='bar') == context.environ assert context.status is status with_directory_contents(dict(), check_provide_contents)
def test_parse_default_ignore_file(): def check(dirname): project_ops._add_projectignore_if_none(dirname) ignorefile = os.path.join(dirname, ".projectignore") assert os.path.isfile(ignorefile) frontend = FakeFrontend() patterns = archiver._parse_ignore_file(ignorefile, frontend) assert [] == frontend.errors pattern_strings = [pattern.pattern for pattern in patterns] assert pattern_strings == ['/anaconda-project-local.yml', '__pycache__/', '*.pyc', '*.pyo', '*.pyd', '/.ipynb_checkpoints', '/.spyderproject'] with_directory_contents(dict(), check)
def test_download_filename_missing(): def check_missing_filename(dirname): local_state = LocalStateFile.load_for_directory(dirname) filename = '/data.zip' requirement = DownloadRequirement(registry=RequirementsRegistry(), env_var=ENV_VAR, url='http://localhost/data.zip', filename='data.zip') status = requirement.check_status({ ENV_VAR: filename, 'PROJECT_DIR': dirname }, local_state, 'default', UserConfigOverrides()) assert not status assert 'File not found: {}'.format(filename) == status.status_description with_directory_contents({}, check_missing_filename)
def test_make_relative(): def check(dirname): foo = os.path.join(dirname, 'foo') assert 'foo' == subdirectory_relative_to_directory(foo, dirname) foobar = os.path.join(dirname, os.path.join('foo', 'bar')) assert os.path.join('foo', 'bar') == subdirectory_relative_to_directory( foobar, dirname) # keep the path absolute if it isn't inside the parent parent_of_dirname = os.path.dirname(dirname) assert parent_of_dirname == subdirectory_relative_to_directory( parent_of_dirname, dirname) with_directory_contents(dict(), check)
def test_conda_invoke_zero_returncode_with_invalid_json(monkeypatch, capsys): def get_command(extra_args): return tmp_script_commandline("""from __future__ import print_function import sys print("NOT_JSON") sys.exit(0) """) def do_test(dirname): monkeypatch.setattr( 'anaconda_project.internal.conda_api._get_conda_command', get_command) with pytest.raises(conda_api.CondaError) as excinfo: conda_api.info() assert 'Invalid JSON from conda' in repr(excinfo.value) with_directory_contents(dict(), do_test)