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=RequirementsRegistry(), 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): envs_dir = os.path.join(dirname, "envs") project = Project(dirname) environ = minimal_environ(PROJECT_DIR=dirname) stage = prepare_in_stages(project, environ=environ) prepare_context = stage.configure() status = _conda_env_status(prepare_context) req = status.requirement provider = status.provider config = provider.read_config(req, prepare_context.environ, prepare_context.local_state_file, prepare_context.default_env_spec_name, prepare_context.overrides) assert dict(env_name='default', source='project', value=os.path.join(envs_dir, 'default')) == config config['env_name'] = 'bar' provider.set_config_values_as_strings( req, prepare_context.environ, prepare_context.local_state_file, prepare_context.default_env_spec_name, prepare_context.overrides, config) config = provider.read_config(req, prepare_context.environ, prepare_context.local_state_file, prepare_context.default_env_spec_name, prepare_context.overrides) assert dict(env_name='bar', source='project', value=os.path.join(envs_dir, 'bar')) == config assert os.path.join( envs_dir, 'bar') == prepare_context.local_state_file.get_value( ['variables', req.env_var])
def provide_download(dirname): @gen.coroutine def mock_downloader_run(self, loop): class Res: pass res = Res() res.code = 200 with open(os.path.join(dirname, 'data.csv'), 'w') as out: out.write('data') self._hash = '12345abcdef' raise gen.Return(res) monkeypatch.setattr( "anaconda_project.internal.http_client.FileDownloader.run", mock_downloader_run) project = project_no_dedicated_env(dirname) result = prepare_without_interaction( project, environ=minimal_environ(PROJECT_DIR=dirname)) assert hasattr(result, 'environ') assert 'DATAFILE' in result.environ filename = os.path.join(dirname, 'data.csv') assert os.path.exists(filename) def mock_remove(path): raise IOError("Not gonna remove this") monkeypatch.setattr("os.remove", mock_remove) status = unprepare(project, result) assert status.logs == [] assert status.status_description == ( 'Failed to remove %s: Not gonna remove this.' % filename) assert status.errors == [] assert not status assert os.path.exists(filename) monkeypatch.undo( ) # so os.remove isn't broken during directory cleanup
def prepare_some_env_var_keep_going(dirname): project = project_no_dedicated_env(dirname) environ = minimal_environ(BAR='bar') stage = prepare_in_stages(project, environ=environ, keep_going_until_success=True) assert "Set up project." == stage.description_of_action assert ['FOO', 'CONDA_PREFIX'] == [status.requirement.env_var for status in stage.statuses_before_execute] # there's an initial stage to set the conda env next_stage = stage.execute() assert ['FOO', 'CONDA_PREFIX'] == [status.requirement.env_var for status in stage.statuses_after_execute] assert not stage.failed assert stage.environ['PROJECT_DIR'] == dirname assert "Set up project." == next_stage.description_of_action assert ['FOO', 'CONDA_PREFIX'] == [status.requirement.env_var for status in next_stage.statuses_before_execute] stage = next_stage for i in range(1, 10): next_stage = stage.execute() assert next_stage is not None assert stage.failed assert stage.environ['PROJECT_DIR'] == dirname stage = next_stage assert dict(BAR='bar') == strip_environ(environ)
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 provide_download(dirname): @gen.coroutine def mock_downloader_run(self, loop): class Res: pass res = Res() res.code = 200 with open(os.path.join(dirname, 'data.csv'), 'w') as out: out.write('data') self._hash = 'mismatched' raise gen.Return(res) monkeypatch.setattr( "anaconda_project.internal.http_client.FileDownloader.run", mock_downloader_run) project = project_no_dedicated_env(dirname) result = prepare_without_interaction( project, environ=minimal_environ(PROJECT_DIR=dirname)) assert not result assert ( 'Error downloading http://localhost/data.csv: mismatched hashes. ' 'Expected: 12345abcdef, calculated: mismatched') in result.errors
def replace_readonly_and_prepare(dirname): with _readonly_env(env_name='default', packages=('python=3.7', )) as ro_prefix: readonly = conda_api.installed(ro_prefix) assert 'python' in readonly assert 'requests' not in readonly ro_envs = os.path.dirname(ro_prefix) environ = minimal_environ( PROJECT_DIR=dirname, ANACONDA_PROJECT_ENVS_PATH=':{}'.format(ro_envs), ANACONDA_PROJECT_READONLY_ENVS_POLICY='replace') monkeypatch.setattr('os.environ', environ) project = Project(dirname) result = prepare_without_interaction(project) assert result assert result.env_prefix == os.path.join(dirname, 'envs', 'default') replaced = conda_api.installed(result.env_prefix) assert 'python' in replaced assert 'requests' in replaced
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 provide_download(dirname): @gen.coroutine def mock_downloader_run(self, loop): raise Exception('error') monkeypatch.setattr( "anaconda_project.internal.http_client.FileDownloader.run", mock_downloader_run) project = project_no_dedicated_env(dirname) result = prepare_without_interaction( project, environ=minimal_environ(PROJECT_DIR=dirname)) assert not result assert ( 'missing requirement to run this project: A downloaded file which is referenced by DATAFILE.' ) in result.errors status = unprepare(project, result) filename = os.path.join(dirname, 'data.csv') assert status.logs == [ "No need to remove %s which wasn't downloaded." % filename, ("Current environment is not in %s, no need to delete it." % dirname) ] assert status.status_description == 'Success.'
def prepare_project_scoped_env(dirname): project = Project(dirname) environ = minimal_environ(PROJECT_DIR=dirname) result = prepare_without_interaction(project, environ=environ) assert result expected_env = os.path.join(dirname, "envs", "default") # Now unprepare def mock_rmtree(path): raise IOError("I will never rm the tree!") monkeypatch.setattr('shutil.rmtree', mock_rmtree) status = unprepare(project, result) assert status.status_description == ( 'Failed to remove environment files in %s: I will never rm the tree!.' % (expected_env)) assert not status assert os.path.exists(expected_env) # so we can rmtree our tmp directory monkeypatch.undo()
def no_start_local_redis(dirname): project = project_no_dedicated_env(dirname) result = _prepare_printing_errors(project, environ=minimal_environ(), mode=provide.PROVIDE_MODE_CHECK) assert not result assert 3 == len(can_connect_args_list)
def prepare_bad_provide_mode(dirname): with pytest.raises(ValueError) as excinfo: project = project_no_dedicated_env(dirname) environ = minimal_environ() prepare_in_stages(project, mode="BAD_PROVIDE_MODE", environ=environ) assert "invalid provide mode" in repr(excinfo.value)
def prepare_some_env_var(dirname): project = project_no_dedicated_env(dirname) environ = minimal_environ(BAR='bar') result = prepare_without_interaction(project, environ=environ) assert not result assert dict(BAR='bar') == strip_environ(environ)
def initial_environ(dirname): return minimal_environ( MYDOWNLOAD=os.path.join(dirname, 'existing_data'))
def initial_environ(dirname): capture_dirname['value'] = dirname return minimal_environ( MYDOWNLOAD=os.path.join(dirname, 'existing_data'))
def provide_download(dirname): project = project_no_dedicated_env(dirname) prepare_without_interaction(project, environ=minimal_environ(PROJECT_DIR=dirname)) assert ("%s: 'downloads:' section should be a dictionary, found ['http://localhost/data.csv']" % DEFAULT_PROJECT_FILENAME) in project.problems
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 start_local_redis(dirname): project = project_no_dedicated_env(dirname) result = _prepare_printing_errors(project, environ=minimal_environ()) assert not result assert 36 == len(can_connect_args_list)
def check_no_autostart(dirname): project = project_no_dedicated_env(dirname) result = _prepare_printing_errors(project, environ=minimal_environ()) assert not result
def provide_download(dirname): project = project_no_dedicated_env(dirname) prepare_without_interaction( project, environ=minimal_environ(PROJECT_DIR=dirname)) assert "Download item DATAFILE has an empty 'url' field." in project.problems
def check(dirname): @gen.coroutine def mock_downloader_run(self, loop): class Res: pass res = Res() res.code = 200 with open(os.path.join(dirname, 'data.csv'), 'w') as out: out.write('data') self._hash = '12345abcdef' raise gen.Return(res) monkeypatch.setattr( "anaconda_project.internal.http_client.FileDownloader.run", mock_downloader_run) project = project_no_dedicated_env(dirname) environ = minimal_environ(PROJECT_DIR=dirname) stage = prepare_in_stages(project, environ=environ) status = None while status is None and stage is not None: prepare_context = stage.configure() status = _download_status(prepare_context) if status is None: stage = stage.execute() assert status is not None req = status.requirement provider = status.provider # check initial config config = provider.read_config(req, prepare_context.environ, prepare_context.local_state_file, prepare_context.default_env_spec_name, prepare_context.overrides) assert dict(source='download') == config config['source'] = 'environ' config['value'] = 'abc.txt' provider.set_config_values_as_strings( req, prepare_context.environ, prepare_context.local_state_file, prepare_context.default_env_spec_name, prepare_context.overrides, config) config = provider.read_config(req, prepare_context.environ, prepare_context.local_state_file, prepare_context.default_env_spec_name, prepare_context.overrides) assert dict(source='download', value='abc.txt') == config config['source'] = 'variables' config['value'] = 'qrs.txt' provider.set_config_values_as_strings( req, prepare_context.environ, prepare_context.local_state_file, prepare_context.default_env_spec_name, prepare_context.overrides, config) config = provider.read_config(req, prepare_context.environ, prepare_context.local_state_file, prepare_context.default_env_spec_name, prepare_context.overrides) assert dict(source='variables', value='qrs.txt') == config
def provide_download(dirname): project = project_no_dedicated_env(dirname) prepare_without_interaction( project, environ=minimal_environ(PROJECT_DIR=dirname)) assert "Multiple checksums for download DATAFILE: md5 and sha1." in project.problems