summaryrefslogblamecommitdiff
path: root/lib/spack/spack/test/cmd/common/arguments.py
blob: c1f75e99f3bdbd79d5c1d02d068fc144e76df565 (plain) (tree)
1
2
3
4
5
6
7
8
9
                                                                         




                                                                         


             
                

                                              
                              
                 


                 


                                                                               
                                 

                                                                               
 

                                                 
 
 
                                       
                                                   
                               
                                                                            

 
                                      
                                         
                                 
                                                        


                                                                     
                                               
                                           
 
                                                               

 
                         
                                                
     

                                                                           

                                                                            
                                                                     


                                
                                                                                    




                                            




                                                                              

                                                      
                                    

 
                                  







                                                                      

                                                                     
 

                         

                  

                                                                                    


                                
                                  
                                                                               


                         

                  
                                                                 
                                                                             
 
                                                             

 
                                  
                                                                               


                                                              



                                                                           

                                                                                     
 
                                                                                         
                        

 



                                                                                           




                                                               
                     
 
                                                                















                                                                                           
# Copyright 2013-2024 Lawrence Livermore National Security, LLC and other
# Spack Project Developers. See the top-level COPYRIGHT file for details.
#
# SPDX-License-Identifier: (Apache-2.0 OR MIT)

import argparse

import pytest

import spack.cmd
import spack.cmd.common.arguments as arguments
import spack.config
import spack.environment as ev
import spack.main


@pytest.fixture()
def job_parser():
    # --jobs needs to write to a command_line config scope, so this is the only
    # scope we create.
    p = argparse.ArgumentParser()
    arguments.add_common_arguments(p, ["jobs"])
    scopes = [spack.config.InternalConfigScope("command_line", {"config": {}})]

    with spack.config.use_configuration(*scopes):
        yield p


def test_setting_jobs_flag(job_parser):
    namespace = job_parser.parse_args(["-j", "24"])
    assert namespace.jobs == 24
    assert spack.config.get("config:build_jobs", scope="command_line") == 24


def test_omitted_job_flag(job_parser):
    namespace = job_parser.parse_args([])
    assert namespace.jobs is None
    assert spack.config.get("config:build_jobs") is None


def test_negative_integers_not_allowed_for_parallel_jobs(job_parser):
    with pytest.raises(ValueError) as exc_info:
        job_parser.parse_args(["-j", "-2"])

    assert "expected a positive integer" in str(exc_info.value)


@pytest.mark.parametrize(
    "specs,cflags,propagation,negated_variants",
    [
        (['coreutils cflags="-O3 -g"'], ["-O3", "-g"], [False, False], []),
        (['coreutils cflags=="-O3 -g"'], ["-O3", "-g"], [True, True], []),
        (["coreutils", "cflags=-O3 -g"], ["-O3", "-g"], [False, False], []),
        (["coreutils", "cflags==-O3 -g"], ["-O3", "-g"], [True, True], []),
        (["coreutils", "cflags=-O3", "-g"], ["-O3"], [False], ["g"]),
    ],
)
@pytest.mark.regression("12951")
def test_parse_spec_flags_with_spaces(specs, cflags, propagation, negated_variants):
    spec_list = spack.cmd.parse_specs(specs)
    assert len(spec_list) == 1

    s = spec_list.pop()

    compiler_flags = [flag for flag in s.compiler_flags["cflags"]]
    flag_propagation = [flag.propagate for flag in s.compiler_flags["cflags"]]

    assert compiler_flags == cflags
    assert flag_propagation == propagation
    assert list(s.variants.keys()) == negated_variants
    for v in negated_variants:
        assert "~{0}".format(v) in s


@pytest.mark.usefixtures("config")
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


@pytest.mark.usefixtures("config")
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


@pytest.mark.usefixtures("config")
def test_root_and_dep_match_returns_root(mock_packages, mutable_mock_env_path):
    e = ev.create("test")
    e.add("b@0.9")
    e.add("a foobar=bar")  # Depends on b, should choose b@1.0
    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(["b@1.0"])[0])
        assert env_spec2


@pytest.mark.parametrize(
    "arg,config", [("--reuse", True), ("--fresh", False), ("--reuse-deps", "dependencies")]
)
def test_concretizer_arguments(mutable_config, mock_packages, arg, config):
    """Ensure that ConfigSetAction is doing the right thing."""
    spec = spack.main.SpackCommand("spec")

    assert spack.config.get("concretizer:reuse", None) is None

    spec(arg, "zlib")

    assert spack.config.get("concretizer:reuse", None) == config


def test_use_buildcache_type():
    assert arguments.use_buildcache("only") == ("only", "only")
    assert arguments.use_buildcache("never") == ("never", "never")
    assert arguments.use_buildcache("auto") == ("auto", "auto")
    assert arguments.use_buildcache("package:never,dependencies:only") == ("never", "only")
    assert arguments.use_buildcache("only,package:never") == ("never", "only")
    assert arguments.use_buildcache("package:only,package:never") == ("never", "auto")
    assert arguments.use_buildcache("auto , package: only") == ("only", "auto")

    with pytest.raises(argparse.ArgumentTypeError):
        assert arguments.use_buildcache("pkg:only,deps:never")

    with pytest.raises(argparse.ArgumentTypeError):
        assert arguments.use_buildcache("sometimes")