def test_to_lockfile_dict(): e = ev.create('test') e.add('mpileaks') e.concretize() context_dict = e._to_lockfile_dict() e_copy = ev.create('test_copy') e_copy._read_lockfile_dict(context_dict) assert e.specs_by_hash == e_copy.specs_by_hash
def test_to_lockfile_dict(): e = ev.create('test') e.add('mpileaks') e.concretize() context_dict = e._to_lockfile_dict() e_copy = ev.create('test_copy') e_copy._read_lockfile_dict(context_dict) assert e.specs_by_hash == e_copy.specs_by_hash
def test_config_add_to_env(mutable_empty_config, mutable_mock_env_path): ev.create('test') with ev.read('test'): config('add', 'config:dirty:true') output = config('get') expected = """ config: dirty: true """ assert expected in output
def test_get_spec_filter_list(mutable_mock_env_path, config, mutable_mock_repo): """Test that given an active environment and list of touched pkgs, we get the right list of possibly-changed env specs""" e1 = ev.create('test') e1.add('mpileaks') e1.add('hypre') e1.concretize() """ Concretizing the above environment results in the following graphs: mpileaks -> mpich (provides mpi virtual dep of mpileaks) -> callpath -> dyninst -> libelf -> libdwarf -> libelf -> mpich (provides mpi dep of callpath) hypre -> openblas-with-lapack (provides lapack and blas virtual deps of hypre) """ touched = ['libdwarf'] # traversing both directions from libdwarf in the graphs depicted # above results in the following possibly affected env specs: # mpileaks, callpath, dyninst, libdwarf, and libelf. Unaffected # specs are mpich, plus hypre and it's dependencies. affected_specs = ci.get_spec_filter_list(e1, touched) affected_pkg_names = set([s.name for s in affected_specs]) expected_affected_pkg_names = set( ['mpileaks', 'callpath', 'dyninst', 'libdwarf', 'libelf']) assert affected_pkg_names == expected_affected_pkg_names
def test_get_concrete_specs(config, mutable_mock_env_path, mock_packages): e = ev.create('test1') e.add('dyninst') e.concretize() dyninst_hash = None hash_dict = {} with e as active_env: for s in active_env.all_specs(): hash_dict[s.name] = s.build_hash() if s.name == 'dyninst': dyninst_hash = s.build_hash() assert (dyninst_hash) dep_builds = 'libdwarf;libelf' spec_map = ci.get_concrete_specs(active_env, dyninst_hash, 'dyninst', dep_builds, 'NONE') assert ('root' in spec_map and 'deps' in spec_map) concrete_root = spec_map['root'] assert (concrete_root.build_hash() == dyninst_hash) concrete_deps = spec_map['deps'] for key, obj in concrete_deps.items(): assert (obj.build_hash() == hash_dict[key]) s = spec.Spec('dyninst') print('nonconc spec name: {0}'.format(s.name)) spec_map = ci.get_concrete_specs(active_env, s.name, s.name, dep_builds, 'FIND_ANY') assert ('root' in spec_map and 'deps' in spec_map)
def test_user_removed_spec(): """Ensure a user can remove from any position in the spack.yaml file.""" initial_yaml = StringIO("""\ env: specs: - mpileaks - hypre - libelf """) before = ev.create('test', initial_yaml) before.concretize() before.write() # user modifies yaml externally to spack and removes hypre with open(before.manifest_path, 'w') as f: f.write("""\ env: specs: - mpileaks - libelf """) after = ev.read('test') after.concretize() after.write() env_specs = after._get_environment_specs() read = ev.read('test') env_specs = read._get_environment_specs() assert not any(x.name == 'hypre' for x in env_specs)
def test_get_concrete_specs(config, mutable_mock_env_path, mock_packages): e = ev.create('test1') e.add('dyninst') e.concretize() dyninst_hash = None hash_dict = {} with e as active_env: for s in active_env.all_specs(): hash_dict[s.name] = s.dag_hash() if s.name == 'dyninst': dyninst_hash = s.dag_hash() assert (dyninst_hash) spec_map = ci.get_concrete_specs(active_env, dyninst_hash, 'dyninst', 'NONE') assert 'root' in spec_map concrete_root = spec_map['root'] assert (concrete_root.dag_hash() == dyninst_hash) s = spec.Spec('dyninst') print('nonconc spec name: {0}'.format(s.name)) spec_map = ci.get_concrete_specs(active_env, s.name, s.name, 'FIND_ANY') assert 'root' in spec_map
def _env_create(name_or_path, init_file=None, dir=False, with_view=None, keep_relative=False): """Create a new environment, with an optional yaml description. Arguments: name_or_path (str): name of the environment to create, or path to it init_file (str or file): optional initialization file -- can be spack.yaml or spack.lock dir (bool): if True, create an environment in a directory instead of a named environment keep_relative (bool): if True, develop paths are copied verbatim into the new environment file, otherwise they may be made absolute if the new environment is in a different location """ if dir: env = ev.Environment(name_or_path, init_file, with_view, keep_relative) env.write() tty.msg("Created environment in %s" % env.path) tty.msg("You can activate this environment with:") tty.msg(" spack env activate %s" % env.path) else: env = ev.create(name_or_path, init_file, with_view, keep_relative) env.write() tty.msg("Created environment '%s' in %s" % (name_or_path, env.path)) tty.msg("You can activate this environment with:") tty.msg(" spack env activate %s" % (name_or_path)) return env
def test_concretize_user_specs_together(): e = ev.create('coconcretization') e.concretization = 'together' # Concretize a first time using 'mpich' as the MPI provider e.add('mpileaks') e.add('mpich') e.concretize() assert all('mpich' in spec for _, spec in e.concretized_specs()) assert all('mpich2' not in spec for _, spec in e.concretized_specs()) # Concretize a second time using 'mpich2' as the MPI provider e.remove('mpich') e.add('mpich2') e.concretize() assert all('mpich2' in spec for _, spec in e.concretized_specs()) assert all('mpich' not in spec for _, spec in e.concretized_specs()) # Concretize again without changing anything, check everything # stays the same e.concretize() assert all('mpich2' in spec for _, spec in e.concretized_specs()) assert all('mpich' not in spec for _, spec in e.concretized_specs())
def test_user_removed_spec(): """Ensure a user can remove from any position in the spack.yaml file.""" initial_yaml = StringIO("""\ env: specs: - mpileaks - hypre - libelf """) before = ev.create('test', initial_yaml) before.concretize() before.write() # user modifies yaml externally to spack and removes hypre with open(before.manifest_path, 'w') as f: f.write("""\ env: specs: - mpileaks - libelf """) after = ev.read('test') after.concretize() after.write() env_specs = after._get_environment_specs() read = ev.read('test') env_specs = read._get_environment_specs() assert not any(x.name == 'hypre' for x in env_specs)
def test_env_install_all(install_mockery, mock_fetch): e = ev.create('test') e.add('cmake-client') e.concretize() e.install_all() env_specs = e._get_environment_specs() spec = next(x for x in env_specs if x.name == 'cmake-client') assert spec.package.installed
def test_env_install_all(install_mockery, mock_fetch): e = ev.create('test') e.add('cmake-client') e.concretize() e.install_all() env_specs = e._get_environment_specs() spec = next(x for x in env_specs if x.name == 'cmake-client') assert spec.package.installed
def test_affected_specs_on_first_concretization(mutable_mock_env_path, config): e = ev.create('first_concretization') e.add('hdf5~mpi~szip') e.add('hdf5~mpi+szip') e.concretize() affected_specs = spack.ci.get_spec_filter_list(e, ['zlib']) hdf5_specs = [s for s in affected_specs if s.name == 'hdf5'] assert len(hdf5_specs) == 2
def test_relate_cdash_builds(config, mutable_mock_env_path, mock_packages, monkeypatch, capfd): e = ev.create('test1') e.add('dyninst') e.concretize() dyninst_hash = None hash_dict = {} with e as active_env: for s in active_env.all_specs(): hash_dict[s.name] = s.build_hash() if s.name == 'dyninst': dyninst_hash = s.build_hash() assert (dyninst_hash) dep_builds = 'libdwarf;libelf' spec_map = ci.get_concrete_specs(active_env, dyninst_hash, 'dyninst', dep_builds, 'NONE') assert ('root' in spec_map and 'deps' in spec_map) cdash_api_url = 'http://cdash.fake.org' job_build_id = '42' cdash_project = 'spack' cdashids_mirror_url = 'https://my.fake.mirror' dep_cdash_ids = {'libdwarf': 1, 'libelf': 2} monkeypatch.setattr(ci, 'read_cdashid_from_mirror', lambda s, u: dep_cdash_ids.pop(s.name)) fake_responder = FakeWebResponder( content_to_read=['libdwarf', 'libelf']) monkeypatch.setattr(ci, 'build_opener', lambda handler: fake_responder) ci.relate_cdash_builds(spec_map, cdash_api_url, job_build_id, cdash_project, [cdashids_mirror_url]) assert (not dep_cdash_ids) dep_cdash_ids = {'libdwarf': 1, 'libelf': 2} fake_responder._resp_code = 400 ci.relate_cdash_builds(spec_map, cdash_api_url, job_build_id, cdash_project, [cdashids_mirror_url]) out, err = capfd.readouterr() assert ('Warning: Relate builds' in err) assert ('failed' in err) dep_cdash_ids = {} # Just make sure passing None for build id doesn't result in any # calls to "read_cdashid_from_mirror" ci.relate_cdash_builds(spec_map, cdash_api_url, None, cdash_project, [cdashids_mirror_url])
def test_multiple_env_match_raises_error(mock_packages, mutable_mock_env_path): e = ev.create('test') e.add('a foobar=baz') e.add('a foobar=fee') e.concretize() with e: with pytest.raises(ev.SpackEnvironmentError) as exc_info: spack.cmd.matching_spec_from_env(spack.cmd.parse_specs(['a'])[0]) assert 'matches multiple specs' in exc_info.value.message
def test_duplicate_packages_raise_when_concretizing_together(): e = ev.create('coconcretization') e.concretization = 'together' e.add('mpileaks+opt') e.add('mpileaks~opt') e.add('mpich') with pytest.raises(ev.SpackEnvironmentError, match=r'cannot contain more'): e.concretize()
def test_env_repo(): e = ev.create('test') e.add('mpileaks') e.write() with ev.read('test'): concretize() package = e.repo.get('mpileaks') assert package.name == 'mpileaks' assert package.namespace == 'builtin.mock'
def test_env_repo(): e = ev.create('test') e.add('mpileaks') e.write() with ev.read('test'): concretize() package = e.repo.get('mpileaks') assert package.name == 'mpileaks' assert package.namespace == 'spack.pkg.builtin.mock'
def test_config_add_to_env(mutable_empty_config, mutable_mock_env_path): env = ev.create('test') with env: config('add', 'config:dirty:true') output = config('get') expected = ev.default_manifest_yaml expected += """ config: dirty: true """ assert output == expected
def test_env_aware_spec(mutable_mock_env_path): env = ev.create('test') env.add('mpileaks') with env: output = spec() assert '[email protected]' in output assert '[email protected]' in output assert '[email protected]' in output assert 'libdwarf@20130729' in output assert '[email protected]' in output assert '[email protected]' in output
def test_gc_with_environment(config, mutable_database, mutable_mock_env_path, capsys): s = spack.spec.Spec('simple-inheritance') s.concretize() s.package.do_install(fake=True, explicit=True) e = ev.create('test_gc') e.add('cmake') with e: with capsys.disabled(): output = gc('-y') assert 'Restricting the garbage collection' in output assert 'There are no unused specs' in output
def test_stage_with_env_inside_env(mutable_mock_env_path, monkeypatch): """Verify that stage filters specs in environment instead of reconcretizing.""" def fake_stage(pkg, mirror_only=False): assert pkg.name == 'mpileaks' assert pkg.version == Version('100.100') monkeypatch.setattr(spack.package.PackageBase, 'do_stage', fake_stage) e = ev.create('test') e.add('[email protected]') e.concretize() with e: stage('mpileaks')
def test_stage_with_env_outside_env(mutable_mock_env_path, monkeypatch): """Verify that stage concretizes specs not in environment instead of erroring.""" def fake_stage(pkg, mirror_only=False): assert pkg.name == 'trivial-install-test-package' assert pkg.path is None monkeypatch.setattr(spack.package.PackageBase, 'do_stage', fake_stage) e = ev.create('test') e.add('mpileaks') e.concretize() with e: stage('trivial-install-test-package')
def test_root_and_dep_match_returns_root(mock_packages, mutable_mock_env_path): e = ev.create('test') e.add('[email protected]') e.add('a foobar=bar') # Depends on b, should choose [email protected] e.concretize() with e: # This query matches the root b and b as a dependency of a. In that # case the root instance should be preferred. env_spec1 = spack.cmd.matching_spec_from_env( spack.cmd.parse_specs(['b'])[0]) assert env_spec1.satisfies('@0.9') env_spec2 = spack.cmd.matching_spec_from_env( spack.cmd.parse_specs(['[email protected]'])[0]) assert env_spec2
def test_environment_status(capfd, tmpdir): with capfd.disabled(): with tmpdir.as_cwd(): assert 'No active environment' in env('status') with ev.create('test'): assert 'In environment test' in env('status') with ev.Environment('local_dir'): assert os.path.join(os.getcwd(), 'local_dir') in env('status') e = ev.Environment('myproject') e.write() with tmpdir.join('myproject').as_cwd(): with e: assert 'in current directory' in env('status')
def test_environment_status(capfd, tmpdir): with capfd.disabled(): with tmpdir.as_cwd(): assert 'No active environment' in env('status') with ev.create('test'): assert 'In environment test' in env('status') with ev.Environment('local_dir'): assert os.path.join(os.getcwd(), 'local_dir') in env('status') e = ev.Environment('myproject') e.write() with tmpdir.join('myproject').as_cwd(): with e: assert 'in current directory' in env('status')
def test_config_get_gets_spack_yaml(mutable_mock_env_path): env = ev.create('test') config('get', fail_on_error=False) assert config.returncode == 1 with env: config('get', fail_on_error=False) assert config.returncode == 1 env.write() assert 'mpileaks' not in config('get') env.add('mpileaks') env.write() assert 'mpileaks' in config('get')
def test_env_view_external_prefix(tmpdir_factory, mutable_database, mock_packages): fake_prefix = tmpdir_factory.mktemp('a-prefix') fake_bin = fake_prefix.join('bin') fake_bin.ensure(dir=True) initial_yaml = StringIO("""\ env: specs: - a view: true """) external_config = StringIO("""\ packages: a: paths: a: {a_prefix} buildable: false """.format(a_prefix=str(fake_prefix))) external_config_dict = spack.util.spack_yaml.load_config(external_config) test_scope = spack.config.InternalConfigScope('env-external-test', data=external_config_dict) with spack.config.override(test_scope): e = ev.create('test', initial_yaml) e.concretize() # Note: normally installing specs in a test environment requires doing # a fake install, but not for external specs since no actions are # taken to install them. The installation commands also include # post-installation functions like DB-registration, so are important # to do (otherwise the package is not considered installed). e.install_all() e.write() env_modifications = e.add_default_view_to_shell('sh') individual_modifications = env_modifications.split('\n') def path_includes_fake_prefix(cmd): return 'export PATH' in cmd and str(fake_bin) in cmd assert any( path_includes_fake_prefix(cmd) for cmd in individual_modifications)
def _env_create(name_or_path, init_file=None, dir=False, with_view=None): """Create a new environment, with an optional yaml description. Arguments: name_or_path (str): name of the environment to create, or path to it init_file (str or file): optional initialization file -- can be spack.yaml or spack.lock dir (bool): if True, create an environment in a directory instead of a named environment """ if dir: env = ev.Environment(name_or_path, init_file, with_view) env.write() tty.msg("Created environment in %s" % env.path) else: env = ev.create(name_or_path, init_file, with_view) env.write() tty.msg("Created environment '%s' in %s" % (name_or_path, env.path)) return env
def test_match_spec_env(mock_packages, mutable_mock_env_path): """ Concretize a spec with non-default options in an environment. Make sure that when we ask for a matching spec when the environment is active that we get the instance concretized in the environment. """ # Initial sanity check: we are planning on choosing a non-default # value, so make sure that is in fact not the default. check_defaults = spack.cmd.parse_specs(['a'], concretize=True)[0] assert not check_defaults.satisfies('foobar=baz') e = ev.create('test') e.add('a foobar=baz') e.concretize() with e: env_spec = spack.cmd.matching_spec_from_env( spack.cmd.parse_specs(['a'])[0]) assert env_spec.satisfies('foobar=baz') assert env_spec.concrete
def _env_create(name_or_path, init_file=None, dir=False): """Create a new environment, with an optional yaml description. Arguments: name_or_path (str): name of the environment to create, or path to it init_file (str or file): optional initialization file -- can be spack.yaml or spack.lock dir (bool): if True, create an environment in a directory instead of a named environment """ if dir: env = ev.Environment(name_or_path, init_file) env.write() tty.msg("Created environment in %s" % env.path) else: env = ev.create(name_or_path, init_file) env.write() tty.msg("Created environment '%s' in %s" % (name_or_path, env.path)) return env
def test_remove_after_concretize(): e = ev.create('test') e.add('mpileaks') e.concretize() e.add('python') e.concretize() e.remove('mpileaks') assert Spec('mpileaks') not in e.user_specs env_specs = e._get_environment_specs() assert any(s.name == 'mpileaks' for s in env_specs) e.add('mpileaks') assert any(s.name == 'mpileaks' for s in e.user_specs) e.remove('mpileaks', force=True) assert Spec('mpileaks') not in e.user_specs env_specs = e._get_environment_specs() assert not any(s.name == 'mpileaks' for s in env_specs)
def test_remove_after_concretize(): e = ev.create('test') e.add('mpileaks') e.concretize() e.add('python') e.concretize() e.remove('mpileaks') assert Spec('mpileaks') not in e.user_specs env_specs = e._get_environment_specs() assert any(s.name == 'mpileaks' for s in env_specs) e.add('mpileaks') assert any(s.name == 'mpileaks' for s in e.user_specs) e.remove('mpileaks', force=True) assert Spec('mpileaks') not in e.user_specs env_specs = e._get_environment_specs() assert not any(s.name == 'mpileaks' for s in env_specs)
def test_init_from_yaml(tmpdir): """Test that an environment can be instantiated from a lockfile.""" initial_yaml = StringIO("""\ env: specs: - mpileaks - hypre - libelf """) e1 = ev.create('test', initial_yaml) e1.concretize() e1.write() e2 = ev.Environment(str(tmpdir), e1.manifest_path) for s1, s2 in zip(e1.user_specs, e2.user_specs): assert s1 == s2 assert not e2.concretized_order assert not e2.concretized_user_specs assert not e2.specs_by_hash
def test_init_from_yaml(tmpdir): """Test that an environment can be instantiated from a lockfile.""" initial_yaml = StringIO("""\ env: specs: - mpileaks - hypre - libelf """) e1 = ev.create('test', initial_yaml) e1.concretize() e1.write() e2 = ev.Environment(str(tmpdir), e1.manifest_path) for s1, s2 in zip(e1.user_specs, e2.user_specs): assert s1 == s2 assert not e2.concretized_order assert not e2.concretized_user_specs assert not e2.specs_by_hash
def test_stage_full_env(mutable_mock_env_path, monkeypatch): """Verify that stage filters specs in environment.""" e = ev.create('test') e.add('[email protected]') e.concretize() # list all the package names that should be staged expected = set() for spec in e.specs_by_hash.values(): for dep in spec.traverse(): expected.add(dep.name) # pop the package name from the list instead of actually staging def fake_stage(pkg, mirror_only=False): expected.remove(pkg.name) monkeypatch.setattr(spack.package.PackageBase, 'do_stage', fake_stage) with e: stage() # assert that all were staged assert len(expected) == 0
def test_install_no_add_in_env(tmpdir, mock_fetch, install_mockery, mutable_mock_env_path): # To test behavior of --no-add option, we create the following environment: # # mpileaks # ^callpath # ^dyninst # ^[email protected] # or latest, really # ^libdwarf # ^mpich # [email protected] # a~bvv # ^b # a # ^b e = ev.create('test') e.add('mpileaks') e.add('[email protected]') # so env has both root and dep libelf specs e.add('a') e.add('a ~bvv') e.concretize() env_specs = e.all_specs() a_spec = None b_spec = None mpi_spec = None # First find and remember some target concrete specs in the environment for e_spec in env_specs: if e_spec.satisfies(Spec('a ~bvv')): a_spec = e_spec elif e_spec.name == 'b': b_spec = e_spec elif e_spec.satisfies(Spec('mpi')): mpi_spec = e_spec assert (a_spec) assert (a_spec.concrete) assert (b_spec) assert (b_spec.concrete) assert (b_spec not in e.roots()) assert (mpi_spec) assert (mpi_spec.concrete) # Activate the environment with e: # Assert using --no-add with a spec not in the env fails inst_out = install('--no-add', 'boost', fail_on_error=False, output=str) assert ('no such spec exists in environment' in inst_out) # Ensure using --no-add with an ambiguous spec fails with pytest.raises(ev.SpackEnvironmentError) as err: inst_out = install('--no-add', 'a', output=str) assert ('a matches multiple specs in the env' in str(err)) # With "--no-add", install an unambiguous dependency spec (that already # exists as a dep in the environment) using --no-add and make sure it # gets installed (w/ deps), but is not added to the environment. install('--no-add', 'dyninst') find_output = find('-l', output=str) assert ('dyninst' in find_output) assert ('libdwarf' in find_output) assert ('libelf' in find_output) assert ('callpath' not in find_output) post_install_specs = e.all_specs() assert all([s in env_specs for s in post_install_specs]) # Make sure we can install a concrete dependency spec from a spec.yaml # file on disk, using the ``--no-add` option, and the spec is installed # but not added as a root mpi_spec_yaml_path = tmpdir.join('{0}.yaml'.format(mpi_spec.name)) with open(mpi_spec_yaml_path.strpath, 'w') as fd: fd.write(mpi_spec.to_yaml(hash=ht.full_hash)) install('--no-add', '-f', mpi_spec_yaml_path.strpath) assert (mpi_spec not in e.roots()) find_output = find('-l', output=str) assert (mpi_spec.name in find_output) # Without "--no-add", install an unambiguous depependency spec (that # already exists as a dep in the environment) without --no-add and make # sure it is added as a root of the environment as well as installed. assert (b_spec not in e.roots()) install('b') assert (b_spec in e.roots()) assert (b_spec not in e.uninstalled_specs()) # Without "--no-add", install a novel spec and make sure it is added # as a root and installed. install('bowtie') assert (any([s.name == 'bowtie' for s in e.roots()])) assert (not any([s.name == 'bowtie' for s in e.uninstalled_specs()]))
def test_add(): e = ev.create('test') e.add('mpileaks') assert Spec('mpileaks') in e.user_specs
def test_concretize(): e = ev.create('test') e.add('mpileaks') e.concretize() env_specs = e._get_environment_specs() assert any(x.name == 'mpileaks' for x in env_specs)
def test_config_edit_edits_spack_yaml(mutable_mock_env_path): env = ev.create('test') with env: assert config('edit', '--print-file').strip() == env.manifest_path