tests: add framework to mock targets
This commit is contained in:
parent
43e7255e19
commit
51cb49743e
5 changed files with 530 additions and 7 deletions
|
@ -14,9 +14,9 @@ class Test(Platform):
|
||||||
if platform.system().lower() == 'darwin':
|
if platform.system().lower() == 'darwin':
|
||||||
binary_formats = ['macho']
|
binary_formats = ['macho']
|
||||||
|
|
||||||
front_end = 'x86'
|
front_end = 'x86_64'
|
||||||
back_end = 'x86_64'
|
back_end = 'core2'
|
||||||
default = 'x86_64'
|
default = 'core2'
|
||||||
|
|
||||||
front_os = 'redhat6'
|
front_os = 'redhat6'
|
||||||
back_os = 'debian6'
|
back_os = 'debian6'
|
||||||
|
|
|
@ -230,7 +230,7 @@ def test_architecture_inheritance(self):
|
||||||
spec.concretize()
|
spec.concretize()
|
||||||
assert spec['cmake'].architecture == spec.architecture
|
assert spec['cmake'].architecture == spec.architecture
|
||||||
|
|
||||||
def test_architecture_deep_inheritance(self):
|
def test_architecture_deep_inheritance(self, mock_targets):
|
||||||
"""Make sure that indirect dependencies receive architecture
|
"""Make sure that indirect dependencies receive architecture
|
||||||
information from the root even when partial architecture information
|
information from the root even when partial architecture information
|
||||||
is provided by an intermediate dependency.
|
is provided by an intermediate dependency.
|
||||||
|
@ -243,7 +243,7 @@ def test_architecture_deep_inheritance(self):
|
||||||
mock_repo.add_package('foopkg', [barpkg], [default_dep])
|
mock_repo.add_package('foopkg', [barpkg], [default_dep])
|
||||||
|
|
||||||
with spack.repo.swap(mock_repo):
|
with spack.repo.swap(mock_repo):
|
||||||
spec = Spec('foopkg %clang@3.3 os=CNL target=footar' +
|
spec = Spec('foopkg %gcc@4.5.0 os=CNL target=nocona' +
|
||||||
' ^barpkg os=SuSE11 ^bazpkg os=be')
|
' ^barpkg os=SuSE11 ^bazpkg os=be')
|
||||||
spec.concretize()
|
spec.concretize()
|
||||||
|
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
import errno
|
import errno
|
||||||
import inspect
|
import inspect
|
||||||
import itertools
|
import itertools
|
||||||
|
import json
|
||||||
import os
|
import os
|
||||||
import os.path
|
import os.path
|
||||||
import shutil
|
import shutil
|
||||||
|
@ -17,6 +18,8 @@
|
||||||
import py
|
import py
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
|
import llnl.util.cpu.microarchitecture
|
||||||
|
import llnl.util.cpu.schema
|
||||||
from llnl.util.filesystem import mkdirp, remove_linked_tree
|
from llnl.util.filesystem import mkdirp, remove_linked_tree
|
||||||
|
|
||||||
import spack.architecture
|
import spack.architecture
|
||||||
|
@ -448,6 +451,40 @@ def default_config():
|
||||||
yield defaults_config
|
yield defaults_config
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture(scope='session')
|
||||||
|
def mock_uarch_json(tmpdir_factory):
|
||||||
|
"""Mock microarchitectures.json with test architecture descriptions."""
|
||||||
|
tmpdir = tmpdir_factory.mktemp('microarchitectures')
|
||||||
|
|
||||||
|
uarch_json = py.path.local(spack.paths.test_path).join(
|
||||||
|
"data", "microarchitectures", "microarchitectures.json")
|
||||||
|
uarch_json.copy(tmpdir)
|
||||||
|
yield str(tmpdir.join("microarchitectures.json"))
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture(scope='session')
|
||||||
|
def mock_uarch_configuration(mock_uarch_json):
|
||||||
|
"""Create mock dictionaries for the llnl.util.cpu."""
|
||||||
|
def load_json():
|
||||||
|
with open(mock_uarch_json) as f:
|
||||||
|
return json.load(f)
|
||||||
|
|
||||||
|
targets_json = llnl.util.cpu.schema.LazyDictionary(load_json)
|
||||||
|
targets = llnl.util.cpu.microarchitecture.LazyDictionary(
|
||||||
|
llnl.util.cpu.microarchitecture._known_microarchitectures)
|
||||||
|
|
||||||
|
yield targets_json, targets
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture(scope='function')
|
||||||
|
def mock_targets(mock_uarch_configuration, monkeypatch):
|
||||||
|
"""Use this fixture to enable mock uarch targets for testing."""
|
||||||
|
targets_json, targets = mock_uarch_configuration
|
||||||
|
|
||||||
|
monkeypatch.setattr(llnl.util.cpu.schema, "targets_json", targets_json)
|
||||||
|
monkeypatch.setattr(llnl.util.cpu.microarchitecture, "targets", targets)
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture(scope='session')
|
@pytest.fixture(scope='session')
|
||||||
def configuration_dir(tmpdir_factory, linux_os):
|
def configuration_dir(tmpdir_factory, linux_os):
|
||||||
"""Copies mock configuration files in a temporary directory. Returns the
|
"""Copies mock configuration files in a temporary directory. Returns the
|
||||||
|
|
|
@ -0,0 +1,486 @@
|
||||||
|
{
|
||||||
|
"microarchitectures": {
|
||||||
|
"x86": {
|
||||||
|
"from": null,
|
||||||
|
"vendor": "generic",
|
||||||
|
"features": []
|
||||||
|
},
|
||||||
|
"i686": {
|
||||||
|
"from": "x86",
|
||||||
|
"vendor": "GenuineIntel",
|
||||||
|
"features": []
|
||||||
|
},
|
||||||
|
"pentium2": {
|
||||||
|
"from": "i686",
|
||||||
|
"vendor": "GenuineIntel",
|
||||||
|
"features": [
|
||||||
|
"mmx"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"pentium3": {
|
||||||
|
"from": "pentium2",
|
||||||
|
"vendor": "GenuineIntel",
|
||||||
|
"features": [
|
||||||
|
"mmx",
|
||||||
|
"sse"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"pentium4": {
|
||||||
|
"from": "pentium3",
|
||||||
|
"vendor": "GenuineIntel",
|
||||||
|
"features": [
|
||||||
|
"mmx",
|
||||||
|
"sse",
|
||||||
|
"sse2"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"prescott": {
|
||||||
|
"from": "pentium4",
|
||||||
|
"vendor": "GenuineIntel",
|
||||||
|
"features": [
|
||||||
|
"mmx",
|
||||||
|
"sse",
|
||||||
|
"sse2",
|
||||||
|
"sse3"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"x86_64": {
|
||||||
|
"from": null,
|
||||||
|
"vendor": "generic",
|
||||||
|
"features": [],
|
||||||
|
"compilers": {
|
||||||
|
"gcc": [
|
||||||
|
{
|
||||||
|
"versions": "4.2.0:",
|
||||||
|
"name": "x86-64",
|
||||||
|
"flags": "-march={name} -mtune=generic"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"versions": ":4.1.2",
|
||||||
|
"name": "x86-64",
|
||||||
|
"flags": "-march={name} -mtune={name}"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"clang": [
|
||||||
|
{
|
||||||
|
"versions": "0.0.0-apple:",
|
||||||
|
"name": "x86-64",
|
||||||
|
"flags": "-march={name}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"versions": ":",
|
||||||
|
"name": "x86-64",
|
||||||
|
"flags": "-march={name} -mtune=generic"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"intel": {
|
||||||
|
"versions": ":",
|
||||||
|
"name": "pentium4",
|
||||||
|
"flags": "-march={name} -mtune=generic"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"nocona": {
|
||||||
|
"from": "x86_64",
|
||||||
|
"vendor": "GenuineIntel",
|
||||||
|
"features": [
|
||||||
|
"mmx",
|
||||||
|
"sse",
|
||||||
|
"sse2",
|
||||||
|
"sse3"
|
||||||
|
],
|
||||||
|
"compilers": {
|
||||||
|
"gcc": {
|
||||||
|
"versions": "4.0.4:",
|
||||||
|
"flags": "-march={name} -mtune={name}"
|
||||||
|
},
|
||||||
|
"clang": {
|
||||||
|
"versions": "3.9:",
|
||||||
|
"flags": "-march={name} -mtune={name}"
|
||||||
|
},
|
||||||
|
"intel": {
|
||||||
|
"versions": "16.0:",
|
||||||
|
"name": "pentium4",
|
||||||
|
"flags": "-march={name} -mtune=generic"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"core2": {
|
||||||
|
"from": "nocona",
|
||||||
|
"vendor": "GenuineIntel",
|
||||||
|
"features": [
|
||||||
|
"mmx",
|
||||||
|
"sse",
|
||||||
|
"sse2",
|
||||||
|
"ssse3"
|
||||||
|
],
|
||||||
|
"compilers": {
|
||||||
|
"gcc": {
|
||||||
|
"versions": "4.3.0:",
|
||||||
|
"flags": "-march={name} -mtune={name}"
|
||||||
|
},
|
||||||
|
"clang": {
|
||||||
|
"versions": "3.9:",
|
||||||
|
"flags": "-march={name} -mtune={name}"
|
||||||
|
},
|
||||||
|
"intel": {
|
||||||
|
"versions": "16.0:",
|
||||||
|
"flags": "-march={name} -mtune={name}}"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"nehalem": {
|
||||||
|
"from": "core2",
|
||||||
|
"vendor": "GenuineIntel",
|
||||||
|
"features": [
|
||||||
|
"mmx",
|
||||||
|
"sse",
|
||||||
|
"sse2",
|
||||||
|
"ssse3",
|
||||||
|
"sse4_1",
|
||||||
|
"sse4_2",
|
||||||
|
"popcnt"
|
||||||
|
],
|
||||||
|
"compilers": {
|
||||||
|
"gcc": [
|
||||||
|
{
|
||||||
|
"versions": "4.9:",
|
||||||
|
"flags": "-march={name} -mtune={name}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"versions": "4.6:4.8.5",
|
||||||
|
"name": "corei7",
|
||||||
|
"flags": "-march={name} -mtune={name}"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"clang": {
|
||||||
|
"versions": "3.9:",
|
||||||
|
"flags": "-march={name} -mtune={name}"
|
||||||
|
},
|
||||||
|
"intel": {
|
||||||
|
"versions": "16.0:",
|
||||||
|
"name": "corei7",
|
||||||
|
"flags": "-march={name} -mtune={name}"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"westmere": {
|
||||||
|
"from": "nehalem",
|
||||||
|
"vendor": "GenuineIntel",
|
||||||
|
"features": [
|
||||||
|
"mmx",
|
||||||
|
"sse",
|
||||||
|
"sse2",
|
||||||
|
"ssse3",
|
||||||
|
"sse4_1",
|
||||||
|
"sse4_2",
|
||||||
|
"popcnt",
|
||||||
|
"aes",
|
||||||
|
"pclmulqdq"
|
||||||
|
],
|
||||||
|
"compilers": {
|
||||||
|
"gcc": {
|
||||||
|
"versions": "4.9:",
|
||||||
|
"flags": "-march={name} -mtune={name}"
|
||||||
|
},
|
||||||
|
"clang": {
|
||||||
|
"versions": "3.9:",
|
||||||
|
"flags": "-march={name} -mtune={name}"
|
||||||
|
},
|
||||||
|
"intel": {
|
||||||
|
"versions": "16.0:",
|
||||||
|
"name": "corei7",
|
||||||
|
"flags": "-march={name} -mtune={name}"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"sandybridge": {
|
||||||
|
"from": "westmere",
|
||||||
|
"vendor": "GenuineIntel",
|
||||||
|
"features": [
|
||||||
|
"mmx",
|
||||||
|
"sse",
|
||||||
|
"sse2",
|
||||||
|
"ssse3",
|
||||||
|
"sse4_1",
|
||||||
|
"sse4_2",
|
||||||
|
"popcnt",
|
||||||
|
"aes",
|
||||||
|
"pclmulqdq",
|
||||||
|
"avx"
|
||||||
|
],
|
||||||
|
"compilers": {
|
||||||
|
"gcc": [
|
||||||
|
{
|
||||||
|
"versions": "4.9:",
|
||||||
|
"flags": "-march={name} -mtune={name}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"versions": "4.6:4.8.5",
|
||||||
|
"name": "corei7-avx",
|
||||||
|
"flags": "-march={name} -mtune={name}"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"clang": {
|
||||||
|
"versions": "3.9:",
|
||||||
|
"flags": "-march={name} -mtune={name}"
|
||||||
|
},
|
||||||
|
"intel": [
|
||||||
|
{
|
||||||
|
"versions": "16.0:17.9.0",
|
||||||
|
"name": "corei7-avx",
|
||||||
|
"flags": "-march={name} -mtune={name}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"versions": "18.0:",
|
||||||
|
"flags": "-march={name} -mtune={name}"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"ivybridge": {
|
||||||
|
"from": "sandybridge",
|
||||||
|
"vendor": "GenuineIntel",
|
||||||
|
"features": [
|
||||||
|
"mmx",
|
||||||
|
"sse",
|
||||||
|
"sse2",
|
||||||
|
"ssse3",
|
||||||
|
"sse4_1",
|
||||||
|
"sse4_2",
|
||||||
|
"popcnt",
|
||||||
|
"aes",
|
||||||
|
"pclmulqdq",
|
||||||
|
"avx",
|
||||||
|
"rdrand",
|
||||||
|
"f16c"
|
||||||
|
],
|
||||||
|
"compilers": {
|
||||||
|
"gcc": [
|
||||||
|
{
|
||||||
|
"versions": "4.9:",
|
||||||
|
"flags": "-march={name} -mtune={name}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"versions": "4.6:4.8.5",
|
||||||
|
"name": "core-avx-i",
|
||||||
|
"flags": "-march={name} -mtune={name}"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"clang": {
|
||||||
|
"versions": "3.9:",
|
||||||
|
"flags": "-march={name} -mtune={name}"
|
||||||
|
},
|
||||||
|
"intel": [
|
||||||
|
{
|
||||||
|
"versions": "16.0:17.9.0",
|
||||||
|
"name": "core-avx-i",
|
||||||
|
"flags": "-march={name} -mtune={name}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"versions": "18.0:",
|
||||||
|
"flags": "-march={name} -mtune={name}"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"haswell": {
|
||||||
|
"from": "ivybridge",
|
||||||
|
"vendor": "GenuineIntel",
|
||||||
|
"features": [
|
||||||
|
"mmx",
|
||||||
|
"sse",
|
||||||
|
"sse2",
|
||||||
|
"ssse3",
|
||||||
|
"sse4_1",
|
||||||
|
"sse4_2",
|
||||||
|
"popcnt",
|
||||||
|
"aes",
|
||||||
|
"pclmulqdq",
|
||||||
|
"avx",
|
||||||
|
"rdrand",
|
||||||
|
"f16c",
|
||||||
|
"movbe",
|
||||||
|
"fma",
|
||||||
|
"avx2",
|
||||||
|
"bmi1",
|
||||||
|
"bmi2"
|
||||||
|
],
|
||||||
|
"compilers": {
|
||||||
|
"gcc": [
|
||||||
|
{
|
||||||
|
"versions": "4.9:",
|
||||||
|
"flags": "-march={name} -mtune={name}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"versions": "4.8:4.8.5",
|
||||||
|
"name": "core-avx2",
|
||||||
|
"flags": "-march={name} -mtune={name}"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"clang": {
|
||||||
|
"versions": "3.9:",
|
||||||
|
"flags": "-march={name} -mtune={name}"
|
||||||
|
},
|
||||||
|
"intel": [
|
||||||
|
{
|
||||||
|
"versions": "16.0:17.9.0",
|
||||||
|
"name": "core-avx2",
|
||||||
|
"flags": "-march={name} -mtune={name}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"versions": "18.0:",
|
||||||
|
"flags": "-march={name} -mtune={name}"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"broadwell": {
|
||||||
|
"from": "haswell",
|
||||||
|
"vendor": "GenuineIntel",
|
||||||
|
"features": [
|
||||||
|
"mmx",
|
||||||
|
"sse",
|
||||||
|
"sse2",
|
||||||
|
"ssse3",
|
||||||
|
"sse4_1",
|
||||||
|
"sse4_2",
|
||||||
|
"popcnt",
|
||||||
|
"aes",
|
||||||
|
"pclmulqdq",
|
||||||
|
"avx",
|
||||||
|
"rdrand",
|
||||||
|
"f16c",
|
||||||
|
"movbe",
|
||||||
|
"fma",
|
||||||
|
"avx2",
|
||||||
|
"bmi1",
|
||||||
|
"bmi2",
|
||||||
|
"rdseed",
|
||||||
|
"adx"
|
||||||
|
],
|
||||||
|
"compilers": {
|
||||||
|
"gcc": {
|
||||||
|
"versions": "4.9:",
|
||||||
|
"flags": "-march={name} -mtune={name}"
|
||||||
|
},
|
||||||
|
"clang": {
|
||||||
|
"versions": "3.9:",
|
||||||
|
"flags": "-march={name} -mtune={name}"
|
||||||
|
},
|
||||||
|
"intel": {
|
||||||
|
"versions": "18.0:",
|
||||||
|
"flags": "-march={name} -mtune={name}"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"skylake": {
|
||||||
|
"from": "broadwell",
|
||||||
|
"vendor": "GenuineIntel",
|
||||||
|
"features": [
|
||||||
|
"mmx",
|
||||||
|
"sse",
|
||||||
|
"sse2",
|
||||||
|
"ssse3",
|
||||||
|
"sse4_1",
|
||||||
|
"sse4_2",
|
||||||
|
"popcnt",
|
||||||
|
"aes",
|
||||||
|
"pclmulqdq",
|
||||||
|
"avx",
|
||||||
|
"rdrand",
|
||||||
|
"f16c",
|
||||||
|
"movbe",
|
||||||
|
"fma",
|
||||||
|
"avx2",
|
||||||
|
"bmi1",
|
||||||
|
"bmi2",
|
||||||
|
"rdseed",
|
||||||
|
"adx",
|
||||||
|
"clflushopt",
|
||||||
|
"xsavec",
|
||||||
|
"xsaveopt"
|
||||||
|
],
|
||||||
|
"compilers": {
|
||||||
|
"gcc": {
|
||||||
|
"versions": "6.0:",
|
||||||
|
"flags": "-march={name} -mtune={name}"
|
||||||
|
},
|
||||||
|
"clang": {
|
||||||
|
"versions": "3.9:",
|
||||||
|
"flags": "-march={name} -mtune={name}"
|
||||||
|
},
|
||||||
|
"intel": {
|
||||||
|
"versions": "18.0:",
|
||||||
|
"flags": "-march={name} -mtune={name}"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"feature_aliases": {
|
||||||
|
"sse3": {
|
||||||
|
"reason": "ssse3 is a superset of sse3 and might be the only one listed",
|
||||||
|
"any_of": [
|
||||||
|
"ssse3"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"avx512": {
|
||||||
|
"reason": "avx512 indicates generic support for any of the avx512 instruction sets",
|
||||||
|
"any_of": [
|
||||||
|
"avx512f",
|
||||||
|
"avx512vl",
|
||||||
|
"avx512bw",
|
||||||
|
"avx512dq",
|
||||||
|
"avx512cd"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"fma": {
|
||||||
|
"reason": "FMA has been supported by PowerISA since Power1, but might not be listed in features",
|
||||||
|
"families": [
|
||||||
|
"ppc64le",
|
||||||
|
"ppc64"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"sse4.1": {
|
||||||
|
"reason": "permits to refer to sse4_1 also as sse4.1",
|
||||||
|
"any_of": [
|
||||||
|
"sse4_1"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"sse4.2": {
|
||||||
|
"reason": "permits to refer to sse4_2 also as sse4.2",
|
||||||
|
"any_of": [
|
||||||
|
"sse4_2"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"conversions": {
|
||||||
|
"description": "Conversions that map some platform specific values to canonical values",
|
||||||
|
"arm_vendors": {
|
||||||
|
"0x41": "ARM",
|
||||||
|
"0x42": "Broadcom",
|
||||||
|
"0x43": "Cavium",
|
||||||
|
"0x44": "DEC",
|
||||||
|
"0x46": "Fujitsu",
|
||||||
|
"0x48": "HiSilicon",
|
||||||
|
"0x49": "Infineon Technologies AG",
|
||||||
|
"0x4d": "Motorola",
|
||||||
|
"0x4e": "Nvidia",
|
||||||
|
"0x50": "APM",
|
||||||
|
"0x51": "Qualcomm",
|
||||||
|
"0x53": "Samsung",
|
||||||
|
"0x56": "Marvell",
|
||||||
|
"0x61": "Apple",
|
||||||
|
"0x66": "Faraday",
|
||||||
|
"0x68": "HXT",
|
||||||
|
"0x69": "Intel"
|
||||||
|
},
|
||||||
|
"darwin_flags": {
|
||||||
|
"sse4.1": "sse4_1",
|
||||||
|
"sse4.2": "sse4_2",
|
||||||
|
"avx1.0": "avx",
|
||||||
|
"clfsopt": "clflushopt",
|
||||||
|
"xsave": "xsavec xsaveopt"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -965,8 +965,8 @@ def test_abstract_spec_prefix_error(self):
|
||||||
with pytest.raises(SpecError):
|
with pytest.raises(SpecError):
|
||||||
spec.prefix
|
spec.prefix
|
||||||
|
|
||||||
def test_forwarding_of_architecture_attributes(self):
|
def test_forwarding_of_architecture_attributes(self, mock_targets):
|
||||||
spec = Spec('libelf').concretized()
|
spec = Spec('libelf target=x86_64').concretized()
|
||||||
|
|
||||||
# Check that we can still access each member through
|
# Check that we can still access each member through
|
||||||
# the architecture attribute
|
# the architecture attribute
|
||||||
|
|
Loading…
Reference in a new issue