def check_fails_while_listing_installed(dirname): def sabotaged_installed_command(prefix): from anaconda_project.internal import conda_api raise conda_api.CondaError("sabotage!") monkeypatch.setattr('anaconda_project.internal.conda_api.installed', sabotaged_installed_command) project_dir_disable_dedicated_env(dirname) local_state = LocalStateFile.load_for_directory(dirname) requirement = CondaEnvRequirement( registry=PluginRegistry(), env_specs=dict( default=EnvSpec('default', ['not_a_real_package'], []))) environ = minimal_environ(PROJECT_DIR=dirname) status = requirement.check_status( environ, local_state, 'default', UserConfigOverrides(inherited_env=environ.get(conda_env_var))) assert status.status_description.startswith( "Conda failed while listing installed packages in ") assert status.status_description.endswith(": sabotage!")
def check(dirname): _monkeypatch_pwd(monkeypatch, dirname) local_state = LocalStateFile.load_for_directory(dirname) local_state.set_service_run_state('ABC', { 'shutdown_commands': [_echo_commandline + ['"shutting down ABC"']] }) local_state.set_service_run_state('TEST', { 'shutdown_commands': [_echo_commandline + ['"shutting down TEST"']] }) local_state.save() code = _parse_args_and_run_subcommand( ['anaconda-project', 'remove-service', 'redis']) assert code == 1 out, err = capsys.readouterr() assert '' == out expected_err = ( "Conflicting #1lab_results, found 2 matches, use list-services" " to identify which service you want to remove\n") assert expected_err == err
def config_html(dirname): FILENAME = os.path.join(dirname, 'data.csv') local_state_file = LocalStateFile.load_for_directory(dirname) requirement = _download_requirement() environ = minimal_environ(PROJECT_DIR=dirname) status = requirement.check_status(environ, local_state_file, 'default', UserConfigOverrides()) provider = DownloadProvider() html = provider.config_html(requirement, environ, local_state_file, UserConfigOverrides(), status) assert 'Download {} to {}'.format(requirement.url, requirement.filename) in html with open(FILENAME, 'w') as f: f.write('boo') env = minimal_environ(PROJECT_DIR=dirname) status = requirement.check_status(env, local_state_file, 'default', UserConfigOverrides()) html = provider.config_html(requirement, env, local_state_file, UserConfigOverrides(), status) expected_choice = 'Use already-downloaded file {}'.format(FILENAME) assert expected_choice in html
def check_provide_contents(dirname): environ = dict() 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()) workpath = context.ensure_service_directory("foo") assert os.path.isdir(workpath) assert workpath.endswith("foo") parent = os.path.dirname(workpath) assert parent.endswith("services") parent = os.path.dirname(parent) assert parent == dirname # be sure we can create if it already exists workpath2 = context.ensure_service_directory("foo") assert os.path.isdir(workpath2) assert workpath == workpath2
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) context = ConfigurePrepareContext(dict(), local_state_file, 'default', UserConfigOverrides(), []) server = UIServer(project, _no_op_prepare(context), event_handler, io_loop) get_response = http_get(io_loop, server.url) print(repr(get_response)) post_response = http_post(io_loop, server.url, body="") print(repr(post_response)) server.unlisten() assert len(events) == 1 assert isinstance(events[0], UIServerDoneEvent)
def start_local_redis(dirname): project = project_no_dedicated_env(dirname) result = _prepare_printing_errors(project, environ=minimal_environ()) assert result local_state_file = LocalStateFile.load_for_directory(dirname) state = local_state_file.get_service_run_state('REDIS_URL') assert 'port' in state port = state['port'] assert dict(REDIS_URL=("redis://localhost:" + str(port)), PROJECT_DIR=project.directory_path) == strip_environ( result.environ) assert len(can_connect_args_list) >= 2 servicedir = os.path.join(dirname, "services") redisdir = os.path.join(servicedir, "REDIS_URL") pidfile = os.path.join(redisdir, "redis.pid") logfile = os.path.join(redisdir, "redis.log") assert os.path.exists(pidfile) assert os.path.exists(logfile) assert real_can_connect_to_socket(host='localhost', port=port) # now clean it up status = unprepare(project, result) assert status assert not os.path.exists(pidfile) assert not os.path.exists(logfile) assert not os.path.exists(redisdir) assert not os.path.exists(servicedir) assert not real_can_connect_to_socket(host='localhost', port=port) local_state_file.load() assert dict() == local_state_file.get_service_run_state("REDIS_URL")
def _internal_prepare_in_stages(project, environ_copy, overrides, keep_going_until_success, mode, provide_whitelist, command_name, command, extra_command_args, refresh): assert not project.problems if mode not in _all_provide_modes: raise ValueError("invalid provide mode " + mode) assert not (command_name is not None and command is not None) assert command_name is None or (command_name in project.commands) or (command_name == 'default') assert overrides.env_spec_name is None or overrides.env_spec_name in project.env_specs if command is None: command = project.command_for_name(command_name) # at this point, "command" is only None if there are no # commands for this project. default_env_name = project.default_env_spec_name_for_command(command) our_root = project.directory_path local_state = LocalStateFile.load_for_directory(our_root) if refresh: # To do: move the refresh flag into the provider somehow. Thought: add # the refresh flag to overrides, and have the conda env requirements # engine interpret that and schedule a refresh and create. env_name = overrides.env_spec_name or default_env_name _remove_env_path(project.env_specs[env_name].path(our_root), our_root) statuses = [] for requirement in project.requirements(overrides.env_spec_name): status = requirement.check_status(environ_copy, local_state, default_env_name, overrides, latest_provide_result=None) statuses.append(status) return _first_stage(project, environ_copy, local_state, statuses, keep_going_until_success, mode, provide_whitelist, overrides, command, extra_command_args)
def check_provide_contents(dirname): environ = dict() local_state_file = LocalStateFile.load_for_directory(dirname) local_state_file.set_service_run_state("myservice", dict(port=42)) requirement = EnvVarRequirement(PluginRegistry(), 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) def transform_it(state): assert 42 == state['port'] state['port'] = 43 state['foo'] = 'bar' return 1234 result = context.transform_service_run_state("myservice", transform_it) assert 1234 == result assert dict( port=43, foo='bar') == local_state_file.get_service_run_state("myservice")
def start_local_redis(dirname): project = project_no_dedicated_env(dirname) result = test_redis_provider._prepare_printing_errors( project, environ=minimal_environ()) assert result local_state_file = LocalStateFile.load_for_directory(dirname) state = local_state_file.get_service_run_state('REDIS_URL') assert 'port' in state port = state['port'] assert dict(REDIS_URL=("redis://localhost:" + str(port)), PROJECT_DIR=project.directory_path) == strip_environ( result.environ) assert len(can_connect_args_list) >= 2 pidfile = os.path.join(dirname, "services/REDIS_URL/redis.pid") logfile = os.path.join(dirname, "services/REDIS_URL/redis.log") assert os.path.exists(pidfile) assert os.path.exists(logfile) assert real_can_connect_to_socket(host='localhost', port=port) # now clean it up code = _parse_args_and_run_subcommand([ 'anaconda-project', 'remove-service', 'REDIS_URL', '--directory', dirname ]) assert code == 0 assert not os.path.exists(pidfile) assert not os.path.exists(os.path.join(dirname, "services")) assert not real_can_connect_to_socket(host='localhost', port=port) local_state_file.load() assert dict() == local_state_file.get_service_run_state("REDIS_URL")
def project_dir_disable_dedicated_env(dirname): """Modify project config to disable having a dedicated environment.""" local_state = LocalStateFile.load_for_directory(dirname) local_state.set_value('inherit_environment', True) local_state.save()
def check_file(dirname): filename = os.path.join(dirname, relative_name) assert os.path.exists(filename) local_state_file = LocalStateFile.load_for_directory(dirname) state = local_state_file.get_service_run_state("foobar") assert dict(port=42, shutdown_commands=[["foo"]]) == state
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("foobar") assert dict() == state
def check_cannot_use_non_dict(dirname): local_state_file = LocalStateFile.load_for_directory(dirname) with pytest.raises(ValueError) as excinfo: local_state_file.set_service_run_state("foo", 42) assert "service state should be a dict" in repr(excinfo.value)
def check(dirname): local_state_file = LocalStateFile.load_for_directory(dirname) status = shutdown_service_run_state(local_state_file, 'foo') assert status assert status.status_description == 'Nothing to do to shut down foo.'
def check_not_set(dirname): local_state = LocalStateFile.load_for_directory(dirname) requirement = RedisRequirement(registry=RequirementsRegistry(), env_var="REDIS_URL") status = requirement.check_status(dict(), local_state, 'default', UserConfigOverrides()) assert not status assert "Environment variable REDIS_URL is not set." == status.status_description
def prepare_after_setting_scope(dirname): local_state = LocalStateFile.load_for_directory(dirname) requirement = _redis_requirement() provider = RedisProvider() environ = minimal_environ() config = provider.read_config(requirement, environ, local_state, 'default', UserConfigOverrides()) assert config['source'] == 'find_all' provider.set_config_values_as_strings(requirement, environ, local_state, 'default', UserConfigOverrides(), dict(source='find_project')) config = provider.read_config(requirement, environ, local_state, 'default', UserConfigOverrides()) assert config['source'] == 'find_project' provider.set_config_values_as_strings(requirement, environ, local_state, 'default', UserConfigOverrides(), dict(source='find_all')) config = provider.read_config(requirement, environ, local_state, 'default', UserConfigOverrides()) assert config['source'] == 'find_all' provider.set_config_values_as_strings(requirement, environ, local_state, 'default', UserConfigOverrides(), dict(source='environ')) config = provider.read_config(requirement, environ, local_state, 'default', UserConfigOverrides()) assert config['source'] == 'find_all' # default if no env var set provider.set_config_values_as_strings(requirement, environ, local_state, 'default', UserConfigOverrides(), dict(source='environ')) environ_with_redis_url = environ.copy() environ_with_redis_url['REDIS_URL'] = 'blah' config = provider.read_config(requirement, environ_with_redis_url, local_state, 'default', UserConfigOverrides()) assert config['source'] == 'environ' # default when the env var IS set # use local variable when env var not set provider.set_config_values_as_strings(requirement, environ, local_state, 'default', UserConfigOverrides(), dict(source='variables', value='foo')) config = provider.read_config(requirement, environ, local_state, 'default', UserConfigOverrides()) assert config['source'] == 'variables' assert config['value'] == 'foo' # use local variable when env var _is_ set provider.set_config_values_as_strings(requirement, environ_with_redis_url, local_state, 'default', UserConfigOverrides(), dict(source='variables', value='foo')) config = provider.read_config(requirement, environ, local_state, 'default', UserConfigOverrides()) assert config['source'] == 'variables' assert config['value'] == 'foo' # set to use system, which should override using the local state provider.set_config_values_as_strings(requirement, environ, local_state, 'default', UserConfigOverrides(), dict(source='find_system')) config = provider.read_config(requirement, environ, local_state, 'default', UserConfigOverrides()) assert config['source'] == 'find_system' project = project_no_dedicated_env(dirname) result = _prepare_printing_errors(project, environ=minimal_environ()) assert result assert dict(REDIS_URL="redis://localhost:6379", PROJECT_DIR=project.directory_path) == strip_environ(result.environ) assert dict(host='localhost', port=6379, timeout_seconds=0.5) == can_connect_args
def unprepare(project, prepare_result, whitelist=None): """Attempt to clean up project-scoped resources allocated by prepare(). This will retain any user configuration choices about how to provide requirements, but it stops project-scoped services. Global system services or other services potentially shared among projects will not be stopped. To stop a single service, use ``whitelist=["SERVICE_VARIABLE"]``. Args: project (Project): the project prepare_result (PrepareResult): result from the previous prepare whitelist (iterable of str or type): ONLY call shutdown commands for the listed env vars' requirements Returns: a ``Status`` instance """ if project.problems: errors = [] for problem in project.problems: errors.append(problem) return SimpleStatus(success=False, description="Unable to load the project.", errors=errors) local_state_file = LocalStateFile.load_for_directory( project.directory_path) # note: if the prepare_result was a failure before statuses # were even checked, then statuses could be empty failed_statuses = [] failed_requirements = [] success_statuses = [] for status in prepare_result.statuses: requirement = status.requirement if not _in_provide_whitelist(whitelist, requirement): continue provider = status.provider unprovide_status = provider.unprovide(requirement, prepare_result.environ, local_state_file, prepare_result.overrides, status) if not unprovide_status: failed_requirements.append(requirement) failed_statuses.append(unprovide_status) else: success_statuses.append(unprovide_status) if not failed_statuses: if len(success_statuses) > 1: logs = [status.status_description for status in success_statuses] return SimpleStatus(success=True, description="Success.", logs=logs) elif len(success_statuses) > 0: return success_statuses[0] else: return SimpleStatus(success=True, description="Nothing to clean up.") elif len(failed_statuses) == 1: return failed_statuses[0] else: all_errors = [ error for status in failed_statuses for error in status.errors ] all_names = sorted([ req.env_var for req in failed_requirements if isinstance(req, EnvVarRequirement) ]) return SimpleStatus(success=False, description=("Failed to clean up %s." % ", ".join(all_names)), errors=all_errors)