def test_rename_target_does_exist_simulating_windows(monkeypatch): def do_test(dirname): name1 = os.path.join(dirname, "foo") name2 = os.path.join(dirname, "bar") assert os.path.exists(name1) assert os.path.exists(name2) assert open(name1).read() == 'stuff-foo' assert open(name2).read() == 'stuff-bar' saved_backup = {} from os import rename as real_rename def mock_rename(src, dst): if '.bak' in dst: saved_backup['path'] = dst if os.path.exists(dst): _raise_file_exists(dst) else: real_rename(src, dst) monkeypatch.setattr('os.rename', mock_rename) rename_over_existing(name1, name2) assert not os.path.exists(name1) assert os.path.exists(name2) assert open(name2).read() == 'stuff-foo' assert not os.path.exists(saved_backup['path']) with_directory_contents(dict(foo='stuff-foo', bar='stuff-bar'), do_test)
def test_rename_target_to_backup_fails(monkeypatch): def do_test(dirname): name1 = os.path.join(dirname, "foo") name2 = os.path.join(dirname, "bar") assert os.path.exists(name1) assert os.path.exists(name2) assert open(name1).read() == 'stuff-foo' assert open(name2).read() == 'stuff-bar' from os import rename as real_rename def mock_rename(src, dst): if os.path.exists(dst): _raise_file_exists(dst) elif '.bak' in dst: raise OSError("Failing rename to backup") else: real_rename(src, dst) monkeypatch.setattr('os.rename', mock_rename) with pytest.raises(OSError) as excinfo: rename_over_existing(name1, name2) assert 'Failing rename to backup' in repr(excinfo.value) assert os.path.exists(name1) assert os.path.exists(name2) assert open(name1).read() == 'stuff-foo' assert open(name2).read() == 'stuff-bar' with_directory_contents(dict(foo='stuff-foo', bar='stuff-bar'), do_test)
def test_conda_create_and_install_and_remove(monkeypatch): monkeypatch_conda_not_to_use_links(monkeypatch) def do_test(dirname): envdir = os.path.join(dirname, "myenv") # don't specify a python version so we use the one we already have # in the root env, otherwise this might take forever. conda_api.create(prefix=envdir, pkgs=['python']) assert os.path.isdir(envdir) assert os.path.isdir(os.path.join(envdir, "conda-meta")) assert os.path.exists(os.path.join(envdir, PYTHON_BINARY)) # test that if it exists we can't create it again with pytest.raises(conda_api.CondaEnvExistsError) as excinfo: conda_api.create(prefix=envdir, pkgs=['python']) assert 'already exists' in repr(excinfo.value) # test that we can install a package assert not os.path.exists(os.path.join(envdir, IPYTHON_BINARY)) conda_api.install(prefix=envdir, pkgs=['ipython']) assert os.path.exists(os.path.join(envdir, IPYTHON_BINARY)) # test that we can remove it again conda_api.remove(prefix=envdir, pkgs=['ipython']) assert not os.path.exists(os.path.join(envdir, IPYTHON_BINARY)) with_directory_contents(dict(), do_test)
def test_installed(): def check_installed(dirname): expected = { 'numexpr': ('numexpr', '2.4.4', 'np110py27_0'), 'portaudio': ('portaudio', '19', '0'), 'unittest2': ('unittest2', '0.5.1', 'py27_1'), 'websocket': ('websocket', '0.2.1', 'py27_0'), 'ipython-notebook': ('ipython-notebook', '4.0.4', 'py27_0') } installed = conda_api.installed(dirname) assert expected == installed files = { 'conda-meta/websocket-0.2.1-py27_0.json': "", 'conda-meta/unittest2-0.5.1-py27_1.json': "", 'conda-meta/portaudio-19-0.json': "", 'conda-meta/numexpr-2.4.4-np110py27_0.json': "", # note that this has a hyphen in package name 'conda-meta/ipython-notebook-4.0.4-py27_0.json': "", 'conda-meta/not-a-json-file.txt': "", 'conda-meta/json_file_without_proper_name_structure.json': "" } with_directory_contents(files, check_installed)
def test_interactively_fix_project(monkeypatch, capsys): def check(dirname): broken_project = Project(dirname) assert len(broken_project.fixable_problems) == 1 def mock_isatty_true(): return True # python 2 can throw a "readonly" error if you try to patch sys.stdin.isatty itself monkeypatch.setattr( 'conda_kapsel.commands.console_utils.stdin_is_interactive', mock_isatty_true) _monkeypatch_input(monkeypatch, ["y"]) project = load_project(dirname) assert project.problems == [] out, err = capsys.readouterr() assert out == ( "%s has an empty env_specs section.\nAdd an environment spec to kapsel.yml? " % os.path.join(dirname, DEFAULT_PROJECT_FILENAME)) assert err == "" with_directory_contents({DEFAULT_PROJECT_FILENAME: "name: foo"}, check)
def test_ui_server_empty(): 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) with_directory_contents(dict(), do_test)
def test_conda_create_and_install_and_remove_pip_stuff(monkeypatch): monkeypatch_conda_not_to_use_links(monkeypatch) def do_test(dirname): envdir = os.path.join(dirname, "myenv") # don't specify a python version so we use the one we already have # in the root env, otherwise this might take forever. conda_api.create(prefix=envdir, pkgs=['python']) assert os.path.isdir(envdir) assert os.path.isdir(os.path.join(envdir, "conda-meta")) # test that we can install a package via pip assert not os.path.exists(os.path.join(envdir, FLAKE8_BINARY)) pip_api.install(prefix=envdir, pkgs=['flake8']) assert os.path.exists(os.path.join(envdir, FLAKE8_BINARY)) # list what was installed installed = pip_api.installed(prefix=envdir) assert 'flake8' in installed assert installed['flake8'][0] == 'flake8' assert installed['flake8'][1] is not None # test that we can remove it again pip_api.remove(prefix=envdir, pkgs=['flake8']) assert not os.path.exists(os.path.join(envdir, FLAKE8_BINARY)) # no longer in the installed list installed = pip_api.installed(prefix=envdir) assert 'flake8' not in installed with_directory_contents(dict(), do_test)
def test_set_config_values_as_strings(): def set_config(dirname): local_state = LocalStateFile.load_for_directory(dirname) requirement = _redis_requirement() provider = RedisProvider() provider.set_config_values_as_strings(requirement, dict(), local_state, 'default', UserConfigOverrides(), dict(lower_port="6001")) config = provider.read_config(requirement, dict(), local_state, 'default', UserConfigOverrides()) assert config['lower_port'] == 6001 assert config['upper_port'] == 6449 provider.set_config_values_as_strings(requirement, dict(), local_state, 'default', UserConfigOverrides(), dict(upper_port="6700")) config2 = provider.read_config(requirement, dict(), local_state, 'default', UserConfigOverrides()) assert config2['lower_port'] == 6001 assert config2['upper_port'] == 6700 provider.set_config_values_as_strings( requirement, dict(), local_state, 'default', UserConfigOverrides(), dict(lower_port="5500", upper_port="6800")) config2 = provider.read_config(requirement, dict(), local_state, 'default', UserConfigOverrides()) assert config2['lower_port'] == 5500 assert config2['upper_port'] == 6800 with_directory_contents(dict(), set_config)
def test_provide_context_ensure_service_directory(): def check_provide_contents(dirname): environ = dict() local_state_file = LocalStateFile.load_for_directory(dirname) 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) 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 with_directory_contents(dict(), check_provide_contents)
def test_parse_ignore_file(): def check(dirname): errors = [] patterns = archiver._parse_ignore_file( os.path.join(dirname, ".kapselignore"), errors) assert [] == errors pattern_strings = [pattern.pattern for pattern in patterns] assert pattern_strings == [ 'bar', '/baz', 'whitespace_surrounding', 'foo # this comment will be part of the pattern', '#patternwithhash', 'hello' ] with_directory_contents( { ".kapselignore": """ # this is a sample .kapselignore # there can be whitespace before the comment bar /baz whitespace_surrounding%s foo # this comment will be part of the pattern \#patternwithhash # blank line above me hello """ % (" ") }, check)
def test_conda_fails_while_listing_installed(monkeypatch): def check_fails_while_listing_installed(dirname): def sabotaged_installed_command(prefix): from conda_kapsel.internal import conda_api raise conda_api.CondaError("sabotage!") monkeypatch.setattr('conda_kapsel.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!") with_directory_contents(dict(), check_fails_while_listing_installed)
def test_format_flag(monkeypatch): call_pip_results = [ "pip 8.2.1 from /blah/blah (python 3.5)\n", "abc (1.2)\nxyz (3.4)\n", "pip 9.0.1 from /blah/blah (python 3.5)\n", "abc (1.2)\nxyz (3.4)\n", "pip WTF from /blah/blah (python 3.5)\n", "abc (1.2)\nxyz (3.4)\n" ] call_pip_results = [r.encode('utf-8') for r in call_pip_results] pip_extra_args = [] def mock_call_pip(prefix, extra_args): pip_extra_args.append(extra_args) assert len(call_pip_results) > 0 return call_pip_results.pop(0) monkeypatch.setattr('conda_kapsel.internal.pip_api._call_pip', mock_call_pip) def do_test(dirname): envdir = dirname # has to exist because .installed short-circuits if not assert len(call_pip_results) == 6 installed = pip_api.installed(prefix=envdir) assert 'abc' in installed assert [['--version'], ['list']] == pip_extra_args assert len(call_pip_results) == 4 installed = pip_api.installed(prefix=envdir) assert 'abc' in installed assert [['--version'], ['list'], ['--version'], ['list', '--format=legacy']] == pip_extra_args assert len(call_pip_results) == 2 installed = pip_api.installed(prefix=envdir) assert 'abc' in installed assert [['--version'], ['list'], ['--version'], ['list', '--format=legacy'], ['--version'], ['list', '--format=legacy']] == pip_extra_args assert len(call_pip_results) == 0 with_directory_contents(dict(), do_test)
def test_multiple_saves_ignored_if_not_dirty(): def check_dirty_handling(dirname): filename = os.path.join(dirname, "foo.yaml") assert not os.path.exists(filename) yaml = YamlFile(filename) assert yaml.change_count == 1 yaml.set_value(["a", "b"], 42) yaml.save() assert yaml.change_count == 2 assert os.path.exists(filename) time1 = os.path.getmtime(filename) yaml.save() assert time1 == os.path.getmtime(filename) assert yaml.change_count == 2 yaml.save() assert time1 == os.path.getmtime(filename) assert yaml.change_count == 2 yaml.set_value(["a", "b"], 43) assert time1 == os.path.getmtime(filename) assert yaml.change_count == 2 yaml.save() # OS mtime resolution might leave these equal assert time1 <= os.path.getmtime(filename) assert yaml.change_count == 3 with_directory_contents(dict(), check_dirty_handling)
def test_transform_yaml_does_nothing(): def transform_test(dirname): filename = os.path.join(dirname, "foo.yaml") assert not os.path.exists(filename) yaml = YamlFile(filename) assert yaml.change_count == 1 # save so we aren't dirty due to nonexistent file yaml.save() assert yaml.change_count == 2 assert os.path.exists(filename) def transformer(tree): # return True means don't make changes after all return True assert not yaml._dirty yaml.transform_yaml(transformer) assert not yaml._dirty yaml.save() assert yaml.change_count == 2 import codecs with codecs.open(filename, 'r', 'utf-8') as file: changed = file.read() expected = """ # yaml file {} """[1:] assert expected == changed with_directory_contents(dict(), transform_test)
def test_read_missing_yaml_file_and_set_value(): def set_abc(dirname): filename = os.path.join(dirname, "foo.yaml") assert not os.path.exists(filename) yaml = YamlFile(filename) value = yaml.get_value(["a", "b"]) assert value is None yaml.set_value(["a", "b"], 42) yaml.save() assert os.path.exists(filename) import codecs with codecs.open(filename, 'r', 'utf-8') as file: changed = file.read() expected = """ # yaml file a: b: 42 """[1:] assert expected == changed yaml2 = YamlFile(filename) value2 = yaml2.get_value(["a", "b"]) assert 42 == value2 with_directory_contents(dict(), set_abc)
def test_download_fail_to_write_file(monkeypatch): def inside_directory_fail_to_write_file(dirname): filename = os.path.join(dirname, "downloaded-file") with HttpServerTestContext() as server: url = server.new_download_url(download_length=(1024 * 1025), hash_algorithm='md5') download = FileDownloader(url=url, filename=filename, hash_algorithm='md5') def mock_open(filename, mode): return _FakeFileFailsToWrite() if sys.version_info > (3, 0): monkeypatch.setattr('builtins.open', mock_open) else: monkeypatch.setattr('__builtin__.open', mock_open) response = IOLoop.current().run_sync( lambda: download.run(IOLoop.current())) assert ["Failed to write to %s: FAIL" % (filename + ".part") ] == download.errors assert response.code == 200 assert not os.path.isfile(filename) assert not os.path.isfile(filename + ".part") with_directory_contents(dict(), inside_directory_fail_to_write_file)
def test_prepare_choose_environment(): def check(dirname): env_var = conda_api.conda_prefix_variable() try: _push_fake_env_creator() project = Project(dirname) environ = minimal_environ() result = prepare_without_interaction(project, environ=environ, env_spec_name='foo') expected_path = project.env_specs['foo'].path(project.directory_path) assert result.environ[env_var] == expected_path environ = minimal_environ() result = prepare_without_interaction(project, environ=environ, env_spec_name='bar') assert result expected_path = project.env_specs['bar'].path(project.directory_path) assert result.environ[env_var] == expected_path finally: _pop_fake_env_creator() with_directory_contents({DEFAULT_PROJECT_FILENAME: """ env_specs: foo: {} bar: {} """}, check)
def test_prepare_use_command_specified_env_spec(): def check(dirname): env_var = conda_api.conda_prefix_variable() try: _push_fake_env_creator() project = Project(dirname) environ = minimal_environ() # we specify the command name but not the # env_spec_name but it should imply the proper env # spec name. result = prepare_without_interaction(project, environ=environ, command_name='hello') expected_path = project.env_specs['foo'].path(project.directory_path) assert result.environ[env_var] == expected_path finally: _pop_fake_env_creator() with_directory_contents( {DEFAULT_PROJECT_FILENAME: """ env_specs: default: {} foo: {} bar: {} commands: hello: env_spec: foo unix: echo hello windows: echo hello """}, check)
def test_read_missing_yaml_file_and_get_default_due_to_missing_section(): def check_missing(dirname): yaml = YamlFile(os.path.join(dirname, "nope.yaml")) value = yaml.get_value(["z", "b"], "default") assert "default" == value with_directory_contents(dict(), check_missing)
def test_parse_ignore_file(): def check(dirname): errors = [] patterns = archiver._parse_ignore_file(os.path.join(dirname, ".kapselignore"), errors) assert [] == errors pattern_strings = [pattern.pattern for pattern in patterns] assert pattern_strings == ['bar', '/baz', 'whitespace_surrounding', 'foo # this comment will be part of the pattern', '#patternwithhash', 'hello'] with_directory_contents( {".kapselignore": """ # this is a sample .kapselignore # there can be whitespace before the comment bar /baz whitespace_surrounding%s foo # this comment will be part of the pattern \#patternwithhash # blank line above me hello """ % (" ")}, check)
def test_download_fail_to_create_directory(monkeypatch): def inside_directory_fail_to_create_directory(dirname): def mock_makedirs(name): raise IOError("Cannot create %s" % name) monkeypatch.setattr( 'conda_kapsel.internal.makedirs.makedirs_ok_if_exists', mock_makedirs) 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( lambda: download.run(IOLoop.current())) assert [ "Could not create directory '%s': Cannot create %s" % (dirname, dirname) ] == 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_fail_to_create_directory)
def test_set_conda_env_in_path_windows_trailing_slashes(monkeypatch): def check_conda_env_in_path_windows_trailing_slashes(dirname): _windows_monkeypatch(monkeypatch) scripts = "Scripts" library = "Library\\bin" env1 = os.path.join(dirname, "env1") os.makedirs(os.path.join(env1, "conda-meta")) env1scripts = os.path.join(env1, scripts) os.makedirs(env1scripts) env1lib = os.path.join(env1, library) os.makedirs(env1lib) env1path = "%s\\;%s\\;%s\\" % (env1, env1scripts, env1lib) env1path_no_slashes = "%s;%s;%s" % (env1, env1scripts, env1lib) env2 = os.path.join(dirname, "env2") os.makedirs(os.path.join(env2, "conda-meta")) env2scripts = os.path.join(env2, scripts) os.makedirs(env2scripts) env2lib = os.path.join(env2, library) os.makedirs(env2lib) env2path = "%s\\;%s\\;%s\\" % (env2, env2scripts, env2lib) env2path_no_slashes = "%s;%s;%s" % (env2, env2scripts, env2lib) notenv = os.path.join(dirname, "notenv\\") notenvscripts = os.path.join(notenv, scripts) os.makedirs(notenvscripts) notenvlib = os.path.join(notenv, library) os.makedirs(notenvlib) notenvpath = "%s\\;%s\\;%s\\" % (notenv, notenvscripts, notenvlib) notenvpath_no_slashes = "%s;%s;%s" % (notenv, notenvscripts, notenvlib) # add env to empty path path = conda_api.set_conda_env_in_path("", env1) assert env1path_no_slashes == path # add env that's already there path = conda_api.set_conda_env_in_path(env1path, env1) assert env1path_no_slashes == path # we can set a non-env because we don't waste time checking it path = conda_api.set_conda_env_in_path("", notenv) assert notenvpath_no_slashes == path # add an env to a non-env path = conda_api.set_conda_env_in_path(notenvpath, env1) assert (env1path_no_slashes + os.pathsep + notenvpath) == path # add an env to another env path = conda_api.set_conda_env_in_path(env1path, env2) assert env2path_no_slashes == path # replace an env that wasn't at the front path = conda_api.set_conda_env_in_path(notenvpath + os.pathsep + env2path, env1) assert (env1path_no_slashes + os.pathsep + notenvpath) == path # keep a bunch of random stuff random_stuff = "foo;bar;/baz/boo" path = conda_api.set_conda_env_in_path(random_stuff, env1) assert (env1path_no_slashes + os.pathsep + random_stuff) == path with_directory_contents(dict(), check_conda_env_in_path_windows_trailing_slashes)
def test_transform_yaml_does_nothing(): def transform_test(dirname): filename = os.path.join(dirname, "foo.yaml") assert not os.path.exists(filename) yaml = YamlFile(filename) assert yaml.change_count == 1 # save so we aren't dirty due to nonexistent file yaml.save() assert yaml.change_count == 2 assert os.path.exists(filename) def transformer(tree): # return True means don't make changes after all return True assert not yaml._dirty yaml.transform_yaml(transformer) assert not yaml._dirty yaml.save() assert yaml.change_count == 2 import codecs with codecs.open(filename, 'r', 'utf-8') as file: changed = file.read() expected = """ # yaml file {} """ [1:] assert expected == changed with_directory_contents(dict(), transform_test)
def test_download_fail_to_rename_tmp_file(monkeypatch): def inside_directory_fail_to_rename_tmp_file(dirname): filename = os.path.join(dirname, "downloaded-file") with HttpServerTestContext() as server: url = server.new_download_url(download_length=56780, hash_algorithm='md5') download = FileDownloader(url=url, filename=filename, hash_algorithm='md5') def mock_rename(src, dest): raise OSError("FAIL") monkeypatch.setattr( 'conda_kapsel.internal.rename.rename_over_existing', mock_rename) response = IOLoop.current().run_sync( lambda: download.run(IOLoop.current())) assert [ "Failed to rename %s to %s: FAIL" % (filename + ".part", filename) ] == download.errors assert response.code == 200 assert not os.path.isfile(filename) assert not os.path.isfile(filename + ".part") with_directory_contents(dict(), inside_directory_fail_to_rename_tmp_file)
def test_init_do_not_create_directory(capsys, monkeypatch): _monkeypatch_isatty(monkeypatch, True) def mock_input_no(prompt): sys.stdout.write(prompt) return "no" monkeypatch.setattr('conda_kapsel.commands.console_utils._input', mock_input_no) def check(dirname): subdir = os.path.join(dirname, "foo") code = _parse_args_and_run_subcommand( ['conda-kapsel', 'init', '--directory', subdir]) assert code == 1 assert not os.path.isfile( os.path.join(subdir, DEFAULT_PROJECT_FILENAME)) assert not os.path.isdir(subdir) out, err = capsys.readouterr() assert ("Create directory '%s'? " % subdir) == out assert ( "Project directory '%s' does not exist.\nUnable to load the project.\n" % subdir) == err with_directory_contents(dict(), check)
def test_init_create_directory(capsys, monkeypatch): _monkeypatch_isatty(monkeypatch, True) def mock_input_yes(prompt): sys.stdout.write(prompt) return "yes" monkeypatch.setattr('conda_kapsel.commands.console_utils._input', mock_input_yes) def check(dirname): subdir = os.path.join(dirname, "foo") code = _parse_args_and_run_subcommand( ['conda-kapsel', 'init', '--directory', subdir]) assert code == 0 assert os.path.isfile(os.path.join(subdir, DEFAULT_PROJECT_FILENAME)) out, err = capsys.readouterr() assert ( "Create directory '%s'? Project configuration is in %s\n" % (subdir, os.path.join(subdir, DEFAULT_PROJECT_FILENAME))) == out assert '' == err with_directory_contents(dict(), check)
def test_init_do_not_create_directory_not_interactive(capsys, monkeypatch): _monkeypatch_isatty(monkeypatch, False) def mock_input(prompt): raise RuntimeError("This should not have been called") monkeypatch.setattr('conda_kapsel.commands.console_utils._input', mock_input) def check(dirname): subdir = os.path.join(dirname, "foo") code = _parse_args_and_run_subcommand( ['conda-kapsel', 'init', '--directory', subdir]) assert code == 1 assert not os.path.isfile( os.path.join(subdir, DEFAULT_PROJECT_FILENAME)) assert not os.path.isdir(subdir) out, err = capsys.readouterr() assert '' == out assert ( "Project directory '%s' does not exist.\nUnable to load the project.\n" % subdir) == err with_directory_contents(dict(), check)
def test_prepare_download_of_broken_zip_file(monkeypatch): def provide_download_of_zip(dirname): with codecs.open(os.path.join(dirname, DEFAULT_PROJECT_FILENAME), 'w', 'utf-8') as f: f.write(complete_project_file_content(ZIPPED_DATAFILE_CONTENT)) @gen.coroutine def mock_downloader_run(self, loop): class Res: pass res = Res() res.code = 200 assert self._url.endswith(".zip") assert self._filename.endswith(".zip") with codecs.open(self._filename, 'w', 'utf-8') as f: f.write("This is not a zip file.") raise gen.Return(res) monkeypatch.setattr("conda_kapsel.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 [("Failed to unzip %s: File is not a zip file" % os.path.join(dirname, "data.zip")), "missing requirement to run this project: A downloaded file which is referenced by DATAFILE.", " Environment variable DATAFILE is not set."] == result.errors with_directory_contents(dict(), provide_download_of_zip)
def test_read_missing_yaml_file_and_set_value(): def set_abc(dirname): filename = os.path.join(dirname, "foo.yaml") assert not os.path.exists(filename) yaml = YamlFile(filename) value = yaml.get_value(["a", "b"]) assert value is None yaml.set_value(["a", "b"], 42) yaml.save() assert os.path.exists(filename) import codecs with codecs.open(filename, 'r', 'utf-8') as file: changed = file.read() expected = """ # yaml file a: b: 42 """ [1:] assert expected == changed yaml2 = YamlFile(filename) value2 = yaml2.get_value(["a", "b"]) assert 42 == value2 with_directory_contents(dict(), set_abc)
def test_set_conda_env_in_path_unix(monkeypatch): import platform if platform.system() == 'Windows': def mock_system(): return 'Linux' monkeypatch.setattr('platform.system', mock_system) def mock_is_conda_bindir_unix(path): if path.endswith("\\"): path = path[:-1] if not path.endswith("\\bin"): return False possible_prefix = os.path.dirname(path) return os.path.isdir(os.path.join(possible_prefix, "conda-meta")) monkeypatch.setattr( 'conda_kapsel.internal.conda_api._is_conda_bindir_unix', mock_is_conda_bindir_unix) def check_conda_env_in_path_unix(dirname): env1 = os.path.join(dirname, "env1") os.makedirs(os.path.join(env1, "conda-meta")) env1bin = os.path.join(env1, "bin") os.makedirs(env1bin) env2 = os.path.join(dirname, "env2") os.makedirs(os.path.join(env2, "conda-meta")) env2bin = os.path.join(env2, "bin") os.makedirs(env2bin) notenv = os.path.join(dirname, "notenv") notenvbin = os.path.join(notenv, "bin") os.makedirs(notenvbin) # add env to empty path path = conda_api.set_conda_env_in_path("", env1) assert env1bin == path # add env that's already there path = conda_api.set_conda_env_in_path(env1bin, env1) assert env1bin == path # we can set a non-env because we don't waste time checking it path = conda_api.set_conda_env_in_path("", notenv) assert notenvbin == path # add an env to a non-env path = conda_api.set_conda_env_in_path(notenvbin, env1) assert (env1bin + os.pathsep + notenvbin) == path # add an env to another env path = conda_api.set_conda_env_in_path(env1bin, env2) assert env2bin == path # replace an env that wasn't at the front path = conda_api.set_conda_env_in_path( notenvbin + os.pathsep + env2bin, env1) assert (env1bin + os.pathsep + notenvbin) == path # keep a bunch of random stuff random_stuff = "foo:bar/:/baz/boo/" path = conda_api.set_conda_env_in_path(random_stuff, env1) assert (env1bin + os.pathsep + random_stuff) == path with_directory_contents(dict(), check_conda_env_in_path_unix)
def test_run_state_must_be_dict(): 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) with_directory_contents(dict(), check_cannot_use_non_dict)
def test_shutdown_service_run_state_nothing_to_do(): 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.' with_directory_contents(dict(), check)
def test_set_conda_env_in_path_windows(monkeypatch): def check_conda_env_in_path_windows(dirname): _windows_monkeypatch(monkeypatch) scripts = "Scripts" library = "Library\\bin" env1 = os.path.join(dirname, "env1") os.makedirs(os.path.join(env1, "conda-meta")) env1scripts = os.path.join(env1, scripts) os.makedirs(env1scripts) env1lib = os.path.join(env1, library) os.makedirs(env1lib) env1path = "%s;%s;%s" % (env1, env1scripts, env1lib) env2 = os.path.join(dirname, "env2") os.makedirs(os.path.join(env2, "conda-meta")) env2scripts = os.path.join(env2, scripts) os.makedirs(env2scripts) env2lib = os.path.join(env2, library) os.makedirs(env2lib) env2path = "%s;%s;%s" % (env2, env2scripts, env2lib) notenv = os.path.join(dirname, "notenv") notenvscripts = os.path.join(notenv, scripts) os.makedirs(notenvscripts) notenvlib = os.path.join(notenv, library) os.makedirs(notenvlib) notenvpath = "%s;%s;%s" % (notenv, notenvscripts, notenvlib) # add env to empty path path = conda_api.set_conda_env_in_path("", env1) assert env1path == path # add env that's already there path = conda_api.set_conda_env_in_path(env1path, env1) assert env1path == path # we can set a non-env because we don't waste time checking it path = conda_api.set_conda_env_in_path("", notenv) assert notenvpath == path # add an env to a non-env path = conda_api.set_conda_env_in_path(notenvpath, env1) assert (env1path + os.pathsep + notenvpath) == path # add an env to another env path = conda_api.set_conda_env_in_path(env1path, env2) assert env2path == path # replace an env that wasn't at the front path = conda_api.set_conda_env_in_path( notenvpath + os.pathsep + env2path, env1) assert (env1path + os.pathsep + notenvpath) == path # keep a bunch of random stuff random_stuff = "foo;bar;/baz/boo" path = conda_api.set_conda_env_in_path(random_stuff, env1) assert (env1path + os.pathsep + random_stuff) == path with_directory_contents(dict(), check_conda_env_in_path_windows)
def _use_existing_meta_file(relative_name): def check_file(dirname): filename = os.path.join(dirname, relative_name) assert os.path.exists(filename) meta_file = CondaMetaFile.load_for_directory(dirname) assert 'foo' == meta_file.name sample_content = "package:\n name: foo\n" with_directory_contents({relative_name: sample_content}, check_file)
def test_use_empty_existing_local_state_file(): 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 with_directory_contents({DEFAULT_LOCAL_STATE_FILENAME: ""}, check_file)
def test_redis_url_not_set(): def check_not_set(dirname): local_state = LocalStateFile.load_for_directory(dirname) requirement = RedisRequirement(registry=PluginRegistry(), 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 with_directory_contents({}, check_not_set)
def test_unzip_bad_zipfile(): def do_test(workingdir): zipname = os.path.join(workingdir, 'foo') target_path = os.path.join(workingdir, 'boo') errors = [] unpack_zip(zipname, target_path, errors) assert [('Failed to unzip %s: File is not a zip file' % zipname)] == errors with_directory_contents(dict(foo="not a zip file\n"), do_test)
def test_attempt_to_grab_result_early(): def early_result_grab(dirname): project = project_no_dedicated_env(dirname) first_stage = prepare_in_stages(project) with pytest.raises(RuntimeError) as excinfo: first_stage.result assert "result property isn't available" in repr(excinfo.value) with_directory_contents(dict(), early_result_grab)
def test_prepare_bad_provide_mode(): 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) with_directory_contents(dict(), prepare_bad_provide_mode)
def test_attempt_to_grab_statuses_early(): def early_status_grab(dirname): project = project_no_dedicated_env(dirname) first_stage = prepare_in_stages(project) with pytest.raises(RuntimeError) as excinfo: first_stage.statuses_after_execute assert "statuses_after_execute isn't available" in repr(excinfo.value) with_directory_contents(dict(), early_status_grab)
def _use_existing_project_file(relative_name): def check_file(dirname): filename = os.path.join(dirname, relative_name) assert os.path.exists(filename) project_file = ProjectFile.load_for_directory(dirname) value = project_file.get_value(["a", "b"]) assert "c" == value with_directory_contents({relative_name: "a:\n b: c"}, check_file)
def test_conda_create_no_packages(): def do_test(dirname): envdir = os.path.join(dirname, "myenv") with pytest.raises(TypeError) as excinfo: conda_api.create(prefix=envdir, pkgs=[]) assert 'must specify a list' in repr(excinfo.value) with_directory_contents(dict(), do_test)
def test_set_conda_env_in_path_unix(monkeypatch): import platform if platform.system() == 'Windows': def mock_system(): return 'Linux' monkeypatch.setattr('platform.system', mock_system) def mock_is_conda_bindir_unix(path): if path.endswith("\\"): path = path[:-1] if not path.endswith("\\bin"): return False possible_prefix = os.path.dirname(path) return os.path.isdir(os.path.join(possible_prefix, "conda-meta")) monkeypatch.setattr('conda_kapsel.internal.conda_api._is_conda_bindir_unix', mock_is_conda_bindir_unix) def check_conda_env_in_path_unix(dirname): env1 = os.path.join(dirname, "env1") os.makedirs(os.path.join(env1, "conda-meta")) env1bin = os.path.join(env1, "bin") os.makedirs(env1bin) env2 = os.path.join(dirname, "env2") os.makedirs(os.path.join(env2, "conda-meta")) env2bin = os.path.join(env2, "bin") os.makedirs(env2bin) notenv = os.path.join(dirname, "notenv") notenvbin = os.path.join(notenv, "bin") os.makedirs(notenvbin) # add env to empty path path = conda_api.set_conda_env_in_path("", env1) assert env1bin == path # add env that's already there path = conda_api.set_conda_env_in_path(env1bin, env1) assert env1bin == path # we can set a non-env because we don't waste time checking it path = conda_api.set_conda_env_in_path("", notenv) assert notenvbin == path # add an env to a non-env path = conda_api.set_conda_env_in_path(notenvbin, env1) assert (env1bin + os.pathsep + notenvbin) == path # add an env to another env path = conda_api.set_conda_env_in_path(env1bin, env2) assert env2bin == path # replace an env that wasn't at the front path = conda_api.set_conda_env_in_path(notenvbin + os.pathsep + env2bin, env1) assert (env1bin + os.pathsep + notenvbin) == path # keep a bunch of random stuff random_stuff = "foo:bar/:/baz/boo/" path = conda_api.set_conda_env_in_path(random_stuff, env1) assert (env1bin + os.pathsep + random_stuff) == path with_directory_contents(dict(), check_conda_env_in_path_unix)
def test_does_not_contain(): def check_does_not_contain(dirname): assert not directory_contains_subdirectory(dirname, "/") assert not dirname.endswith("/") common_prefix_not_subdir = dirname + "foobar" assert not directory_contains_subdirectory(dirname, common_prefix_not_subdir) # we don't contain ourselves assert not directory_contains_subdirectory(dirname, dirname) with_directory_contents(dict(), check_does_not_contain)
def test_does_contain(): def check_does_contain(dirname): subdir = os.path.join(dirname, "foo") # subdir doesn't have to actually exist, so don't create it assert directory_contains_subdirectory(dirname, subdir) subsubdir = os.path.join(subdir, "bar") assert directory_contains_subdirectory(dirname, subsubdir) assert directory_contains_subdirectory(subdir, subsubdir) with_directory_contents(dict(), check_does_contain)
def test_unprepare_empty_directory(): def unprepare_empty(dirname): project = project_no_dedicated_env(dirname) environ = minimal_environ() result = prepare_without_interaction(project, environ=environ) assert result status = unprepare(project, result) assert status with_directory_contents(dict(), unprepare_empty)