Unit tests for cflags PR
This commit is contained in:
		| @@ -385,18 +385,12 @@ def __init__(self, spec): | |||||||
|  |  | ||||||
|  |  | ||||||
|     def satisfies(self, other, strict=False): |     def satisfies(self, other, strict=False): | ||||||
|         #"strict" makes no sense if this works, but it matches how we need it. Maybe |         if strict or (self.spec and self.spec._concrete): | ||||||
|         #strict=True |             return all(f in self and set(self[f]) <= set(other[f]) | ||||||
|         if strict: |  | ||||||
| #            if other.spec and other.spec.concrete: |  | ||||||
|             return all(f in self and set(self[f]) == set(other[f]) |  | ||||||
|                        for f in other) |                        for f in other) | ||||||
| #            else: |  | ||||||
| #                return all(f in self and set(self[f]) >= set(other[f]) |  | ||||||
| #                           for f in other) |  | ||||||
|         else: |         else: | ||||||
|             return all(f in self and set(self[f]) == set(other[f]) |             return all(set(self[f]) <= set(other[f]) | ||||||
|                        for f in other if other[f] != []) |                    for f in other if (other[f] != [] and f in self)) | ||||||
|  |  | ||||||
|  |  | ||||||
|     def constrain(self, other): |     def constrain(self, other): | ||||||
| @@ -404,14 +398,16 @@ def constrain(self, other): | |||||||
|  |  | ||||||
|         Return whether the spec changed. |         Return whether the spec changed. | ||||||
|         """ |         """ | ||||||
|         changed = False |         if other.spec and other.spec._concrete: | ||||||
|  |             for k in self: | ||||||
|  |                 if k not in other: | ||||||
|  |                     raise UnsatisfiableCompilerFlagSpecError(self[k], '<absent>') | ||||||
|  |  | ||||||
|         # Others_set removes flags set to '' from the comparison |         changed = False | ||||||
|         others_set = (k for k in other if other[k] != []) |         for k in other: | ||||||
|         for k in others_set: |             if k in self and not set(self[k]) <= set(other[k]): | ||||||
|             if k in self and not set(self[k]) >= set(other[k]): |                 raise UnsatisfiableCompilerFlagSpecError( | ||||||
|                 self[k] = list(set(self[k]) | set(other[k])) |                     ' '.join(f for f in self[k]), ' '.join( f for f in other[k])) | ||||||
|                 changed = True |  | ||||||
|             elif k not in self: |             elif k not in self: | ||||||
|                 self[k] = other[k] |                 self[k] = other[k] | ||||||
|                 changed = True |                 changed = True | ||||||
| @@ -485,6 +481,7 @@ def __init__(self, spec_like, *dep_like, **kwargs): | |||||||
|         self.architecture = other.architecture |         self.architecture = other.architecture | ||||||
|         self.compiler = other.compiler |         self.compiler = other.compiler | ||||||
|         self.compiler_flags = other.compiler_flags |         self.compiler_flags = other.compiler_flags | ||||||
|  |         self.compiler_flags.spec = self | ||||||
|         self.dependencies = other.dependencies |         self.dependencies = other.dependencies | ||||||
|         self.variants = other.variants |         self.variants = other.variants | ||||||
|         self.variants.spec = self |         self.variants.spec = self | ||||||
| @@ -520,6 +517,10 @@ def _add_variant(self, name, value): | |||||||
|         """Called by the parser to add a variant.""" |         """Called by the parser to add a variant.""" | ||||||
|         if name in self.variants: raise DuplicateVariantError( |         if name in self.variants: raise DuplicateVariantError( | ||||||
|                 "Cannot specify variant '%s' twice" % name) |                 "Cannot specify variant '%s' twice" % name) | ||||||
|  |         if isinstance(value, basestring) and value.upper() == 'TRUE': | ||||||
|  |             value = True | ||||||
|  |         elif isinstance(value, basestring) and value.upper() == 'FALSE': | ||||||
|  |             value = False | ||||||
|         self.variants[name] = VariantSpec(name, value) |         self.variants[name] = VariantSpec(name, value) | ||||||
|  |  | ||||||
|  |  | ||||||
| @@ -2416,6 +2417,11 @@ def __init__(self, provided, required): | |||||||
|         super(UnsatisfiableVariantSpecError, self).__init__( |         super(UnsatisfiableVariantSpecError, self).__init__( | ||||||
|             provided, required, "variant") |             provided, required, "variant") | ||||||
|  |  | ||||||
|  | class UnsatisfiableCompilerFlagSpecError(UnsatisfiableSpecError): | ||||||
|  |     """Raised when a spec variant conflicts with package constraints.""" | ||||||
|  |     def __init__(self, provided, required): | ||||||
|  |         super(UnsatisfiableCompilerFlagSpecError, self).__init__( | ||||||
|  |             provided, required, "compiler_flags") | ||||||
|  |  | ||||||
| class UnsatisfiableArchitectureSpecError(UnsatisfiableSpecError): | class UnsatisfiableArchitectureSpecError(UnsatisfiableSpecError): | ||||||
|     """Raised when a spec architecture conflicts with package constraints.""" |     """Raised when a spec architecture conflicts with package constraints.""" | ||||||
|   | |||||||
| @@ -40,9 +40,18 @@ def check_spec(self, abstract, concrete): | |||||||
|                 cvariant = concrete.variants[name] |                 cvariant = concrete.variants[name] | ||||||
|                 self.assertEqual(avariant.value, cvariant.value) |                 self.assertEqual(avariant.value, cvariant.value) | ||||||
|  |  | ||||||
|  |         if abstract.compiler_flags: | ||||||
|  |             for flag in abstract.compiler_flags: | ||||||
|  |                 aflag = abstract.compiler_flags[flag] | ||||||
|  |                 cflag = concrete.compiler_flags[flag] | ||||||
|  |                 self.assertTrue(set(aflag) <= set(cflag)) | ||||||
|  |  | ||||||
|         for name in abstract.package.variants: |         for name in abstract.package.variants: | ||||||
|             self.assertTrue(name in concrete.variants) |             self.assertTrue(name in concrete.variants) | ||||||
|  |  | ||||||
|  |         for flag in concrete.compiler_flags.valid_compiler_flags(): | ||||||
|  |             self.assertTrue(flag in concrete.compiler_flags) | ||||||
|  |  | ||||||
|         if abstract.compiler and abstract.compiler.concrete: |         if abstract.compiler and abstract.compiler.concrete: | ||||||
|             self.assertEqual(abstract.compiler, concrete.compiler) |             self.assertEqual(abstract.compiler, concrete.compiler) | ||||||
|  |  | ||||||
| @@ -75,9 +84,14 @@ def test_concretize_dag(self): | |||||||
|     def test_concretize_variant(self): |     def test_concretize_variant(self): | ||||||
|         self.check_concretize('mpich+debug') |         self.check_concretize('mpich+debug') | ||||||
|         self.check_concretize('mpich~debug') |         self.check_concretize('mpich~debug') | ||||||
|  |         self.check_concretize('mpich debug=2') | ||||||
|         self.check_concretize('mpich') |         self.check_concretize('mpich') | ||||||
|  |  | ||||||
|  |  | ||||||
|  |     def test_conretize_compiler_flags(self): | ||||||
|  |         self.check_concretize('mpich cppflags="-O3"') | ||||||
|  |  | ||||||
|  |  | ||||||
|     def test_concretize_preferred_version(self): |     def test_concretize_preferred_version(self): | ||||||
|         spec = self.check_concretize('python') |         spec = self.check_concretize('python') | ||||||
|         self.assertEqual(spec.versions, ver('2.7.11')) |         self.assertEqual(spec.versions, ver('2.7.11')) | ||||||
|   | |||||||
| @@ -42,6 +42,13 @@ def test_normalize_simple_conditionals(self): | |||||||
|         self.check_normalize('optional-dep-test+a', |         self.check_normalize('optional-dep-test+a', | ||||||
|                              Spec('optional-dep-test+a', Spec('a'))) |                              Spec('optional-dep-test+a', Spec('a'))) | ||||||
|  |  | ||||||
|  |         self.check_normalize('optional-dep-test a=true', | ||||||
|  |                              Spec('optional-dep-test a=true', Spec('a'))) | ||||||
|  |  | ||||||
|  |  | ||||||
|  |         self.check_normalize('optional-dep-test a=true', | ||||||
|  |                              Spec('optional-dep-test+a', Spec('a'))) | ||||||
|  |  | ||||||
|         self.check_normalize('optional-dep-test@1.1', |         self.check_normalize('optional-dep-test@1.1', | ||||||
|                              Spec('optional-dep-test@1.1', Spec('b'))) |                              Spec('optional-dep-test@1.1', Spec('b'))) | ||||||
|  |  | ||||||
|   | |||||||
| @@ -191,12 +191,20 @@ def test_satisfies_virtual_dependency_versions(self): | |||||||
|     def test_satisfies_matching_variant(self): |     def test_satisfies_matching_variant(self): | ||||||
|         self.check_satisfies('mpich+foo', 'mpich+foo') |         self.check_satisfies('mpich+foo', 'mpich+foo') | ||||||
|         self.check_satisfies('mpich~foo', 'mpich~foo') |         self.check_satisfies('mpich~foo', 'mpich~foo') | ||||||
|  |         self.check_satisfies('mpich foo=1', 'mpich foo=1') | ||||||
|  |  | ||||||
|  |         #confirm that synonymous syntax works correctly | ||||||
|  |         self.check_satisfies('mpich+foo', 'mpich foo=True') | ||||||
|  |         self.check_satisfies('mpich foo=true', 'mpich+foo') | ||||||
|  |         self.check_satisfies('mpich~foo', 'mpich foo=FALSE') | ||||||
|  |         self.check_satisfies('mpich foo=False', 'mpich~foo') | ||||||
|  |  | ||||||
|  |  | ||||||
|     def test_satisfies_unconstrained_variant(self): |     def test_satisfies_unconstrained_variant(self): | ||||||
|         # only asked for mpich, no constraints.  Either will do. |         # only asked for mpich, no constraints.  Either will do. | ||||||
|         self.check_satisfies('mpich+foo', 'mpich') |         self.check_satisfies('mpich+foo', 'mpich') | ||||||
|         self.check_satisfies('mpich~foo', 'mpich') |         self.check_satisfies('mpich~foo', 'mpich') | ||||||
|  |         self.check_satisfies('mpich foo=1', 'mpich') | ||||||
|  |  | ||||||
|  |  | ||||||
|     def test_unsatisfiable_variants(self): |     def test_unsatisfiable_variants(self): | ||||||
| @@ -205,16 +213,44 @@ def test_unsatisfiable_variants(self): | |||||||
|         # 'mpich' is not concrete: |         # 'mpich' is not concrete: | ||||||
|         self.check_satisfies('mpich', 'mpich+foo', False) |         self.check_satisfies('mpich', 'mpich+foo', False) | ||||||
|         self.check_satisfies('mpich', 'mpich~foo', False) |         self.check_satisfies('mpich', 'mpich~foo', False) | ||||||
|  |         self.check_satisfies('mpich', 'mpich foo=1', False) | ||||||
|  |  | ||||||
|         # 'mpich' is concrete: |         # 'mpich' is concrete: | ||||||
|         self.check_unsatisfiable('mpich', 'mpich+foo', True) |         self.check_unsatisfiable('mpich', 'mpich+foo', True) | ||||||
|         self.check_unsatisfiable('mpich', 'mpich~foo', True) |         self.check_unsatisfiable('mpich', 'mpich~foo', True) | ||||||
|  |         self.check_unsatisfiable('mpich', 'mpich foo=1', True) | ||||||
|  |  | ||||||
|  |  | ||||||
|     def test_unsatisfiable_variant_mismatch(self): |     def test_unsatisfiable_variant_mismatch(self): | ||||||
|         # No matchi in specs |         # No matchi in specs | ||||||
|         self.check_unsatisfiable('mpich~foo', 'mpich+foo') |         self.check_unsatisfiable('mpich~foo', 'mpich+foo') | ||||||
|         self.check_unsatisfiable('mpich+foo', 'mpich~foo') |         self.check_unsatisfiable('mpich+foo', 'mpich~foo') | ||||||
|  |         self.check_unsatisfiable('mpich foo=1', 'mpich foo=2') | ||||||
|  |  | ||||||
|  |  | ||||||
|  |     def test_satisfies_matching_compiler_flag(self): | ||||||
|  |         self.check_satisfies('mpich cppflags="-O3"', 'mpich cppflags="-O3"') | ||||||
|  |         self.check_satisfies('mpich cppflags="-O3 -Wall"', 'mpich cppflags="-O3 -Wall"') | ||||||
|  |  | ||||||
|  |  | ||||||
|  |     def test_satisfies_unconstrained_compiler_flag(self): | ||||||
|  |         # only asked for mpich, no constraints.  Any will do. | ||||||
|  |         self.check_satisfies('mpich cppflags="-O3"', 'mpich') | ||||||
|  |  | ||||||
|  |  | ||||||
|  |     def test_unsatisfiable_compiler_flag(self): | ||||||
|  |         # This case is different depending on whether the specs are concrete. | ||||||
|  |  | ||||||
|  |         # 'mpich' is not concrete: | ||||||
|  |         self.check_satisfies('mpich', 'mpich cppflags="-O3"', False) | ||||||
|  |  | ||||||
|  |         # 'mpich' is concrete: | ||||||
|  |         self.check_unsatisfiable('mpich', 'mpich cppflags="-O3"', True) | ||||||
|  |  | ||||||
|  |  | ||||||
|  |     def test_unsatisfiable_compiler_flag_mismatch(self): | ||||||
|  |         # No matchi in specs | ||||||
|  |         self.check_unsatisfiable('mpich cppflags="-O3"', 'mpich cppflags="-O2"') | ||||||
|  |  | ||||||
|  |  | ||||||
|     def test_satisfies_virtual(self): |     def test_satisfies_virtual(self): | ||||||
| @@ -302,18 +338,26 @@ def test_constrain_variants(self): | |||||||
|         self.check_constrain('libelf+debug+foo', 'libelf+debug', 'libelf+foo') |         self.check_constrain('libelf+debug+foo', 'libelf+debug', 'libelf+foo') | ||||||
|         self.check_constrain('libelf+debug+foo', 'libelf+debug', 'libelf+debug+foo') |         self.check_constrain('libelf+debug+foo', 'libelf+debug', 'libelf+debug+foo') | ||||||
|  |  | ||||||
|  |         self.check_constrain('libelf debug=2 foo=1', 'libelf debug=2', 'libelf foo=1') | ||||||
|  |         self.check_constrain('libelf debug=2 foo=1', 'libelf debug=2', 'libelf debug=2 foo=1') | ||||||
|  |  | ||||||
|         self.check_constrain('libelf+debug~foo', 'libelf+debug', 'libelf~foo') |         self.check_constrain('libelf+debug~foo', 'libelf+debug', 'libelf~foo') | ||||||
|         self.check_constrain('libelf+debug~foo', 'libelf+debug', 'libelf+debug~foo') |         self.check_constrain('libelf+debug~foo', 'libelf+debug', 'libelf+debug~foo') | ||||||
|  |  | ||||||
|  |  | ||||||
|  |     def test_constrain_compiler_flags(self): | ||||||
|  |         self.check_constrain('libelf cflags="-O3" cppflags="-Wall"', 'libelf cflags="-O3"', 'libelf cppflags="-Wall"') | ||||||
|  |         self.check_constrain('libelf cflags="-O3" cppflags="-Wall"', 'libelf cflags="-O3"', 'libelf cflags="-O3" cppflags="-Wall"') | ||||||
|  |  | ||||||
|  |  | ||||||
|     def test_constrain_arch(self): |     def test_constrain_arch(self): | ||||||
|         self.check_constrain('libelf arch=bgqos_0', 'libelf arch=bgqos_0', 'libelf arch=bgqos_0') |         self.check_constrain('libelf arch=bgqos_0', 'libelf arch=bgqos_0', 'libelf arch=bgqos_0') | ||||||
|         self.check_constrain('libelf arch=bgqos_0', 'libelf', 'libelf arch=bgqos_0') |         self.check_constrain('libelf arch=bgqos_0', 'libelf', 'libelf arch=bgqos_0') | ||||||
|  |  | ||||||
|  |  | ||||||
|     def test_constrain_compiler(self): |     def test_constrain_compiler(self): | ||||||
|         self.check_constrain('libelf arch=bgqos_0', 'libelf arch=bgqos_0', 'libelf arch=bgqos_0') |         self.check_constrain('libelf %gcc@4.4.7', 'libelf %gcc@4.4.7', 'libelf %gcc@4.4.7') | ||||||
|         self.check_constrain('libelf arch=bgqos_0', 'libelf', 'libelf arch=bgqos_0') |         self.check_constrain('libelf %gcc@4.4.7', 'libelf', 'libelf %gcc@4.4.7') | ||||||
|  |  | ||||||
|  |  | ||||||
|     def test_invalid_constraint(self): |     def test_invalid_constraint(self): | ||||||
| @@ -322,6 +366,9 @@ def test_invalid_constraint(self): | |||||||
|  |  | ||||||
|         self.check_invalid_constraint('libelf+debug', 'libelf~debug') |         self.check_invalid_constraint('libelf+debug', 'libelf~debug') | ||||||
|         self.check_invalid_constraint('libelf+debug~foo', 'libelf+debug+foo') |         self.check_invalid_constraint('libelf+debug~foo', 'libelf+debug+foo') | ||||||
|  |         self.check_invalid_constraint('libelf debug=2', 'libelf debug=1') | ||||||
|  |  | ||||||
|  |         self.check_invalid_constraint('libelf cppflags="-O3"', 'libelf cppflags="-O2"') | ||||||
|  |  | ||||||
|         self.check_invalid_constraint('libelf arch=bgqos_0', 'libelf arch=x86_54') |         self.check_invalid_constraint('libelf arch=bgqos_0', 'libelf arch=x86_54') | ||||||
|  |  | ||||||
| @@ -333,6 +380,8 @@ def test_constrain_changed(self): | |||||||
|         self.check_constrain_changed('libelf%gcc', '%gcc@4.5') |         self.check_constrain_changed('libelf%gcc', '%gcc@4.5') | ||||||
|         self.check_constrain_changed('libelf', '+debug') |         self.check_constrain_changed('libelf', '+debug') | ||||||
|         self.check_constrain_changed('libelf', '~debug') |         self.check_constrain_changed('libelf', '~debug') | ||||||
|  |         self.check_constrain_changed('libelf', 'debug=2') | ||||||
|  |         self.check_constrain_changed('libelf', 'cppflags="-O3"') | ||||||
|         self.check_constrain_changed('libelf', ' arch=bgqos_0') |         self.check_constrain_changed('libelf', ' arch=bgqos_0') | ||||||
|  |  | ||||||
|  |  | ||||||
| @@ -344,6 +393,8 @@ def test_constrain_not_changed(self): | |||||||
|         self.check_constrain_not_changed('libelf%gcc@4.5', '%gcc@4.5') |         self.check_constrain_not_changed('libelf%gcc@4.5', '%gcc@4.5') | ||||||
|         self.check_constrain_not_changed('libelf+debug', '+debug') |         self.check_constrain_not_changed('libelf+debug', '+debug') | ||||||
|         self.check_constrain_not_changed('libelf~debug', '~debug') |         self.check_constrain_not_changed('libelf~debug', '~debug') | ||||||
|  |         self.check_constrain_not_changed('libelf debug=2', 'debug=2') | ||||||
|  |         self.check_constrain_not_changed('libelf cppflags="-O3"', 'cppflags="-O3"') | ||||||
|         self.check_constrain_not_changed('libelf arch=bgqos_0', ' arch=bgqos_0') |         self.check_constrain_not_changed('libelf arch=bgqos_0', ' arch=bgqos_0') | ||||||
|         self.check_constrain_not_changed('libelf^foo', 'libelf^foo') |         self.check_constrain_not_changed('libelf^foo', 'libelf^foo') | ||||||
|         self.check_constrain_not_changed('libelf^foo^bar', 'libelf^foo^bar') |         self.check_constrain_not_changed('libelf^foo^bar', 'libelf^foo^bar') | ||||||
| @@ -356,6 +407,7 @@ def test_constrain_dependency_changed(self): | |||||||
|         self.check_constrain_changed('libelf^foo%gcc', 'libelf^foo%gcc@4.5') |         self.check_constrain_changed('libelf^foo%gcc', 'libelf^foo%gcc@4.5') | ||||||
|         self.check_constrain_changed('libelf^foo', 'libelf^foo+debug') |         self.check_constrain_changed('libelf^foo', 'libelf^foo+debug') | ||||||
|         self.check_constrain_changed('libelf^foo', 'libelf^foo~debug') |         self.check_constrain_changed('libelf^foo', 'libelf^foo~debug') | ||||||
|  |         self.check_constrain_changed('libelf^foo', 'libelf^foo cppflags="-O3"') | ||||||
|         self.check_constrain_changed('libelf^foo', 'libelf^foo arch=bgqos_0') |         self.check_constrain_changed('libelf^foo', 'libelf^foo arch=bgqos_0') | ||||||
|  |  | ||||||
|  |  | ||||||
| @@ -366,5 +418,6 @@ def test_constrain_dependency_not_changed(self): | |||||||
|         self.check_constrain_not_changed('libelf^foo%gcc@4.5', 'libelf^foo%gcc@4.5') |         self.check_constrain_not_changed('libelf^foo%gcc@4.5', 'libelf^foo%gcc@4.5') | ||||||
|         self.check_constrain_not_changed('libelf^foo+debug', 'libelf^foo+debug') |         self.check_constrain_not_changed('libelf^foo+debug', 'libelf^foo+debug') | ||||||
|         self.check_constrain_not_changed('libelf^foo~debug', 'libelf^foo~debug') |         self.check_constrain_not_changed('libelf^foo~debug', 'libelf^foo~debug') | ||||||
|  |         self.check_constrain_not_changed('libelf^foo cppflags="-O3"', 'libelf^foo cppflags="-O3"') | ||||||
|         self.check_constrain_not_changed('libelf^foo arch=bgqos_0', 'libelf^foo arch=bgqos_0') |         self.check_constrain_not_changed('libelf^foo arch=bgqos_0', 'libelf^foo arch=bgqos_0') | ||||||
|  |  | ||||||
|   | |||||||
| @@ -104,6 +104,8 @@ def test_dependencies_with_versions(self): | |||||||
|  |  | ||||||
|     def test_full_specs(self): |     def test_full_specs(self): | ||||||
|         self.check_parse("mvapich_foo^_openmpi@1.2:1.4,1.6%intel@12.1+debug~qt_4^stackwalker@8.1_1e") |         self.check_parse("mvapich_foo^_openmpi@1.2:1.4,1.6%intel@12.1+debug~qt_4^stackwalker@8.1_1e") | ||||||
|  |         self.check_parse("mvapich_foo^_openmpi@1.2:1.4,1.6%intel@12.1 debug=2~qt_4^stackwalker@8.1_1e") | ||||||
|  |         self.check_parse('mvapich_foo^_openmpi@1.2:1.4,1.6%intel@12.1 cppflags="-O3"+debug~qt_4^stackwalker@8.1_1e') | ||||||
|  |  | ||||||
|     def test_canonicalize(self): |     def test_canonicalize(self): | ||||||
|         self.check_parse( |         self.check_parse( | ||||||
| @@ -128,7 +130,10 @@ def test_parse_errors(self): | |||||||
|  |  | ||||||
|     def test_duplicate_variant(self): |     def test_duplicate_variant(self): | ||||||
|         self.assertRaises(DuplicateVariantError, self.check_parse, "x@1.2+debug+debug") |         self.assertRaises(DuplicateVariantError, self.check_parse, "x@1.2+debug+debug") | ||||||
|         self.assertRaises(DuplicateVariantError, self.check_parse, "x ^y@1.2+debug+debug") |         self.assertRaises(DuplicateVariantError, self.check_parse, "x ^y@1.2+debug debug=true") | ||||||
|  |         self.assertRaises(DuplicateVariantError, self.check_parse, "x ^y@1.2 debug=false debug=true") | ||||||
|  |         self.assertRaises(DuplicateVariantError, self.check_parse, "x ^y@1.2 debug=false~debug") | ||||||
|  |  | ||||||
|  |  | ||||||
|     def test_duplicate_depdendence(self): |     def test_duplicate_depdendence(self): | ||||||
|         self.assertRaises(DuplicateDependencyError, self.check_parse, "x ^y ^y") |         self.assertRaises(DuplicateDependencyError, self.check_parse, "x ^y ^y") | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Gregory Becker
					Gregory Becker