diff --git a/requirements.txt b/requirements.txt index 97412438dc..cf32784e0a 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,3 +1,4 @@ +jsonschema pytest>=3.5.0 coverage setuptools diff --git a/schemas/config.json b/schemas/config.json new file mode 100644 index 0000000000..c837c2aea4 --- /dev/null +++ b/schemas/config.json @@ -0,0 +1,367 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://raw.githubusercontent.com/eth-cscs/reframe/master/schemas/config.json", + "title": "Validation schema for ReFrame's configuration file", + "defs": { + "alphanum_string": { + "type": "string", + "pattern": "([a-zA-Z0-9_]|-)+" + }, + "system_ref": { + "type": "array", + "items": {"type": "string"} + }, + "envvar_list": { + "type": "array", + "items": { + "type": "array", + "items": [ + { + "type": "string", + "pattern": "([a-zA-Z_][a-zA-Z0-9_]*)" + }, + {"type": "string"} + ], + "additionalProperties": false + } + }, + "modules_list": { + "type": "array", + "items": {"type": "string"} + }, + "loglevel": { + "type": "string", + "enum": ["critical", "error", "warning", + "info", "verbose", "debug"] + }, + "handler_common": { + "type": "object", + "properties": { + "type": {"type": "string"}, + "level": {"$ref": "#/defs/loglevel"}, + "format": {"type": "string"}, + "datefmt": {"type": "string"} + }, + "required": ["type"] + }, + "file_handler": { + "allOf": [ + {"$ref": "#/defs/handler_common"}, + { + "properties": { + "name": {"type": "string"}, + "append": {"type": "boolean"}, + "timestamp": { + "anyOf": [ + {"type": "boolean"}, + {"type": "string"} + ] + } + }, + "required": ["name"] + } + ] + }, + "filelog_handler": { + "allOf": [ + {"$ref": "#/defs/handler_common"}, + { + "properties": { + "prefix": {"type": "string"} + } + } + ] + }, + "graylog_handler": { + "allOf": [ + {"$ref": "#/defs/handler_common"}, + { + "properties": { + "address": {"type": "string"}, + "extras": {"type": "object"} + }, + "required": ["address"] + } + ] + }, + "stream_handler": { + "allOf": [ + {"$ref": "#/defs/handler_common"}, + { + "properties": { + "name": { + "type": "string", + "enum": ["stdout", "stderr"] + } + } + } + ] + }, + "syslog_handler": { + "allOf": [ + {"$ref": "#/defs/handler_common"}, + { + "properties": { + "socktype": { + "type": "string", + "enum": ["tcp", "udp"] + }, + "facility": {"type": "string"}, + "address": {"type": "string"} + }, + "required": ["address"] + } + ] + } + }, + "type": "object", + "properties": { + "systems": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": {"$ref": "#/defs/alphanum_string"}, + "descr": {"type": "string"}, + "hostnames": { + "type": "array", + "items": {"type": "string"} + }, + "modules_system": { + "type": "string", + "enum": ["tmod", "tmod31", "tmod32", "tmod4", "lmod"] + }, + "modules": {"$ref": "#/defs/modules_list"}, + "variables": {"$ref": "#/defs/envvar_list"}, + "prefix": {"type": "string"}, + "stagedir": {"type": "string"}, + "outputdir": {"type": "string"}, + "perflogdir": {"type": "string"}, + "resourcesdir": {"type": "string"}, + "partitions": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": {"$ref": "#/defs/alphanum_string"}, + "descr": {"type": "string"}, + "scheduler": { + "type": "string", + "enum": ["local", "pbs", "slurm", "squeue"] + }, + "launcher": { + "type": "string", + "enum": [ + "alps", "ibrun", "local", "mpirun", + "mpiexec", "srun", "srunalloc", "ssh" + ] + }, + "access": { + "type": "array", + "items": {"type": "string"} + }, + "environs": { + "type": "array", + "items": {"type": "string"} + }, + "container_platforms": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string", + "enum": ["Docker", "Sarus", + "Singularity"] + }, + "modules": { + "$ref": "#/defs/modules_list" + }, + "variables": { + "$ref": "#/defs/envvar_list" + } + }, + "required": ["name"] + } + }, + "modules": {"$ref": "#/defs/modules_list"}, + "variables": {"$ref": "#/defs/envvar_list"}, + "max_jobs": {"type": "number"}, + "resources": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": {"type": "string"}, + "options": { + "type": "array", + "items": {"type": "string"} + }, + "additionalProperties": false + } + } + } + }, + "required": ["name", "scheduler", "launcher"], + "additionalProperties": false + } + } + }, + "required": ["name"], + "additionalProperties": false + } + }, + "environments": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": {"type": "string"}, + "modules": {"$ref": "#/defs/modules_list"}, + "variables": {"$ref": "#/defs/envvar_list"}, + "cc": {"type": "string"}, + "cxx": {"type": "string"}, + "ftn": {"type": "string"}, + "cppflags": { + "type": "array", + "items": {"type": "string"} + }, + "cflags": { + "type": "array", + "items": {"type": "string"} + }, + "cxxflags": { + "type": "array", + "items": {"type": "string"} + }, + "fflags": { + "type": "array", + "items": {"type": "string"} + }, + "ldflags": { + "type": "array", + "items": {"type": "string"} + }, + "target_systems": {"$ref": "#/defs/system_ref"} + }, + "required": ["name"], + "additionalProperties": false + } + }, + "schedulers": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": {"type": "string"}, + "job_submit_timeout": {"type": "number"}, + "target_systems": {"$ref": "#/defs/system_ref"} + }, + "required": ["name"], + "additionalProperties": false + } + }, + "logging": { + "type": "array", + "items": { + "type": "object", + "properties": { + "level": {"$ref": "#/defs/loglevel"}, + "handlers": { + "type": "array", + "items": { + "anyOf": [ + {"$ref": "#/defs/file_handler"}, + {"$ref": "#/defs/filelog_handler"}, + {"$ref": "#/defs/graylog_handler"}, + {"$ref": "#/defs/stream_handler"}, + {"$ref": "#/defs/syslog_handler"} + ] + } + }, + "target_systems": {"$ref": "#/defs/system_ref"} + }, + "additionalProperties": false + } + }, + "perf_logging": { + "type": "array", + "items": { + "type": "object", + "properties": { + "level": {"$ref": "#/defs/loglevel"}, + "handlers": { + "type": "array", + "items": { + "anyOf": [ + {"$ref": "#/defs/file_handler"}, + {"$ref": "#/defs/filelog_handler"}, + {"$ref": "#/defs/graylog_handler"}, + {"$ref": "#/defs/stream_handler"}, + {"$ref": "#/defs/syslog_handler"} + ] + } + }, + "target_systems": {"$ref": "#/defs/system_ref"} + }, + "additionalProperties": false + } + }, + "modes": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": {"type": "string"}, + "options": { + "type": "array", + "items": {"type": "string"} + }, + "target_systems": {"$ref": "#/defs/system_ref"} + }, + "required": ["name"], + "additionalProperties": false + } + }, + "general": { + "type": "array", + "items": { + "type": "object", + "properties": { + "check_search_path": { + "type": "array", + "items": {"type": "string"} + }, + "check_search_recursive": {"type": "boolean"}, + "target_systems": {"$ref": "#/defs/system_ref"} + }, + "additionalProperties": false + } + } + }, + "required": ["systems", "environments", "logging", "perf_logging"], + "additionalProperties": false, + "defaults": { + "environments/cc": "cc", + "environments/cxx": "CC", + "environments/ftn": "ftn", + "environments/target_systems": ["*"], + "general/check_search_path": ["checks/"], + "general/check_search_recursive": "true", + "general/target_systems": ["*"], + "perf_logging/target_systems": ["*"], + "logging/handlers/level": "DEBUG", + "logging/handlers/file/append": false, + "logging/handlers/file/timestamp": false, + "logging/handlers/stream/name": "stdout", + "logging/handlers/syslog/socktype": "udp", + "logging/handlers/syslog/facility": "user", + "logging/level": "INFO", + "logging/target_systems": ["*"], + "modes/target_systems": ["*"], + "schedulers/job_submit_timeout": 60, + "schedulers/target_systems": ["*"], + "systems/prefix": ".", + "systems/resourcesdir": "." + } +} diff --git a/schemas/settings.py b/schemas/settings.py new file mode 100644 index 0000000000..f56283b103 --- /dev/null +++ b/schemas/settings.py @@ -0,0 +1,177 @@ +# +# New style configuration +# +# This corresponds to the current unittests/resources/settings.py +# + +site_configuration = { + 'systems': [ + { + 'name': 'generic', + 'descr': 'Generic example system', + 'hostnames': ['localhost'], + 'partitions': [ + { + 'name': 'login', + 'descr': 'Login nodes', + 'scheduler': 'local', + 'launcher': 'local', + 'environs': ['builtin-gcc'] + } + ] + }, + { + 'name': 'testsys', + 'descr': 'Fake system for unit tests', + 'hostnames': ['testsys'], + 'prefix': '.rfm_testing', + 'resourcesdir': '.rfm_testing/resources', + 'perflogdir': '.rfm_testing/perflogs', + 'modules': ['foo/1.0'], + 'variables': [['FOO_CMD', 'foobar']], + 'partitions': [ + { + 'name': 'login', + 'scheduler': 'local', + 'launcher': 'local', + 'environs': ['PrgEnv-cray', 'PrgEnv-gnu', 'builtin-gcc'], + 'descr': 'Login nodes' + }, + { + 'name': 'gpu', + 'descr': 'GPU partition', + 'scheduler': 'slurm', + 'launcher': 'srun', + 'modules': ['foogpu'], + 'variables': [['FOO_GPU', 'yes']], + 'resources': [ + { + 'name': 'gpu', + 'options': ['--gres=gpu:{num_gpus_per_node}'], + }, + { + 'name': 'datawarp', + 'options': [ + '#DW jobdw capacity={capacity}', + '#DW stage_in source={stagein_src}' + ] + } + ], + 'environs': ['PrgEnv-gnu', 'builtin-gcc'], + } + ] + }, + { + 'name': 'sys0', + 'descr': 'System for testing check dependencies', + 'hostnames': [r'sys\d+'], + 'partitions': [ + { + 'name': 'p0', + 'scheduler': 'local', + 'launcher': 'local', + 'environs': ['e0', 'e1'] + }, + { + 'name': 'p1', + 'scheduler': 'local', + 'launcher': 'local', + 'environs': ['e0', 'e1'] + } + + ] + } + ], + 'environments': [ + { + 'name': 'PrgEnv-gnu', + 'modules': ['PrgEnv-gnu'], + 'cc': 'gcc', + 'cxx': 'g++', + 'ftn': 'gfortran', + 'target_systems': ['testsys:login'] + }, + { + 'name': 'PrgEnv-gnu', + 'modules': ['PrgEnv-gnu'], + }, + { + 'name': 'PrgEnv-cray', + 'modules': ['PrgEnv-cray'], + }, + { + 'name': 'builtin', + 'cc': 'cc', + 'cxx': '', + 'ftn': '' + }, + { + 'name': 'builtin-gcc', + 'cc': 'gcc', + 'cxx': 'g++', + 'ftn': 'gfortran' + }, + { + 'name': 'e0', + 'modules': ['m0'] + }, + { + 'name': 'e1', + 'modules': ['m1'] + } + ], + 'modes': [ + { + 'name': 'unittest', + 'options': [ + '-c', 'unittests/resources/checks/hellocheck.py', + '-p', 'builtin-gcc', + '--force-local' + ] + } + ], + 'logging': [ + { + 'level': 'debug', + 'handlers': [ + { + 'type': 'file', + 'name': '.rfm_unittest.log', + 'level': 'debug', + 'format': ('[%(asctime)s] %(levelname)s: ' + '%(check_name)s: %(message)s'), + 'datefmt': '%FT%T', + 'append': False, + }, + { + 'type': 'stream', + 'name': 'stdout', + 'level': 'info', + 'format': '%(message)s' + } + ] + } + ], + 'perf_logging': [ + { + 'level': 'debug', + 'handlers': [ + { + 'type': 'filelog', + 'prefix': '%(check_system)s/%(check_partition)s', + 'level': 'info', + 'format': ( + '%(asctime)s|reframe %(version)s|' + '%(check_info)s|jobid=%(check_jobid)s|' + '%(check_perf_var)s=%(check_perf_value)s|' + 'ref=%(check_perf_ref)s ' + '(l=%(check_perf_lower_thres)s, ' + 'u=%(check_perf_upper_thres)s)|' + '%(check_perf_unit)s' + ), + 'append': True + } + ] + } + ] +}