Skip to content

Commit 0d22e14

Browse files
authored
Merge branch 'master' into fix/remove_kesch
2 parents c7e46f5 + b1f3183 commit 0d22e14

File tree

13 files changed

+135
-109
lines changed

13 files changed

+135
-109
lines changed

Jenkinsfile

Lines changed: 5 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ def uniqueID
1010

1111
stage('Initialization') {
1212
node('master') {
13-
try {
13+
catchError(stageResult: 'FAILURE') {
1414
uniqueID = "${env.ghprbActualCommit[0..6]}-${env.BUILD_ID}"
1515
echo 'Environment Variables:'
1616
echo sh(script: 'env|sort', returnStdout: true)
@@ -55,19 +55,7 @@ stage('Initialization') {
5555
currentBuild.result = 'ABORTED'
5656
return
5757
}
58-
5958
currentBuild.result = 'SUCCESS'
60-
} catch(err) {
61-
println err.toString()
62-
if (err.toString().contains('exit code 143')) {
63-
currentBuild.result = "ABORTED"
64-
}
65-
else if (err.toString().contains('Queue task was cancelled')) {
66-
currentBuild.result = "ABORTED"
67-
}
68-
else {
69-
currentBuild.result = "FAILURE"
70-
}
7159
}
7260
}
7361
}
@@ -101,22 +89,8 @@ stage('Unittest') {
10189
}
10290
}
10391

104-
try {
92+
catchError(stageResult: 'FAILURE') {
10593
parallel builds
106-
currentBuild.result = "SUCCESS"
107-
} catch(err) {
108-
if (err.toString().contains('exit code 143')) {
109-
currentBuild.result = "ABORTED"
110-
println "The Unittest was cancelled. Aborting....."
111-
}
112-
else if (err.toString().contains('Queue task was cancelled')) {
113-
currentBuild.result = "ABORTED"
114-
println "The Queue task was cancelled. Aborting....."
115-
}
116-
else {
117-
currentBuild.result = "FAILURE"
118-
println "The Unittest failed. Exiting....."
119-
}
12094
}
12195
}
12296

@@ -127,7 +101,7 @@ stage('Tutorial Check') {
127101
return
128102
}
129103
else {
130-
try {
104+
catchError(stageResult: 'FAILURE') {
131105
if (!('daint' in machinesToRun)) {
132106
return
133107
}
@@ -141,20 +115,6 @@ stage('Tutorial Check') {
141115
bash ${reframeDir}/${bashScript} -f ${reframeDir} -i '' -t""")
142116
}
143117
}
144-
currentBuild.result = "SUCCESS"
145-
} catch(err) {
146-
if (err.toString().contains('exit code 143')) {
147-
currentBuild.result = "ABORTED"
148-
println "The Tutorial Check was cancelled. Aborting....."
149-
}
150-
else if (err.toString().contains('Queue task was cancelled')) {
151-
currentBuild.result = "ABORTED"
152-
println "The Queue task was cancelled. Aborting....."
153-
}
154-
else {
155-
currentBuild.result = "FAILURE"
156-
println "The Tutorial Check failed. Exiting....."
157-
}
158118
}
159119
}
160120
}
@@ -181,22 +141,8 @@ stage('Cleanup') {
181141
}
182142
}
183143
}
184-
try {
144+
catchError(stageResult: 'FAILURE') {
185145
parallel builds
186-
currentBuild.result = "SUCCESS"
187-
} catch(err) {
188-
if (err.toString().contains('exit code 143')) {
189-
currentBuild.result = "ABORTED"
190-
println "The Cleanup was cancelled. Aborting....."
191-
}
192-
else if (err.toString().contains('Queue task was cancelled')) {
193-
currentBuild.result = "ABORTED"
194-
println "The Queue task was cancelled. Aborting....."
195-
}
196-
else {
197-
currentBuild.result = "FAILURE"
198-
println "The Cleanup failed. Exiting....."
199-
}
200146
}
201147
}
202148
}
@@ -218,21 +164,7 @@ stage('Cleanup Stale') {
218164
}
219165
}
220166

221-
try {
167+
catchError(stageResult: 'FAILURE') {
222168
parallel builds
223-
currentBuild.result = "SUCCESS"
224-
} catch(err) {
225-
if (err.toString().contains('exit code 143')) {
226-
currentBuild.result = "ABORTED"
227-
println "The Build step was cancelled. Aborting....."
228-
}
229-
else if (err.toString().contains('Queue task was cancelled')) {
230-
currentBuild.result = "ABORTED"
231-
println "The Queue task was cancelled. Aborting....."
232-
}
233-
else {
234-
currentBuild.result = "FAILURE"
235-
println "The Build step failed. Exiting....."
236-
}
237169
}
238170
}

ci-scripts/dockerfiles/Lmod.dockerfile

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ RUN useradd -ms /bin/bash rfmuser
1414
# ReFrame requirements
1515
RUN \
1616
apt-get -y update && \
17+
apt-get -y install ca-certificates && \
18+
update-ca-certificates && \
1719
apt-get -y install gcc && \
1820
apt-get -y install make && \
1921
apt-get -y install git && \

ci-scripts/dockerfiles/Tmod4.dockerfile

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ RUN useradd -ms /bin/bash rfmuser
1414
# ReFrame requirements
1515
RUN \
1616
apt-get -y update && \
17+
apt-get -y install ca-certificates && \
18+
update-ca-certificates && \
1719
apt-get -y install gcc && \
1820
apt-get -y install make && \
1921
apt-get -y install git && \

docs/started.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ Requirements
1515
Optional Requirements
1616
---------------------
1717

18-
If you want to run the framework's unit tests, you will also need a C compiler that is able to compile a "Hello, World!" program and recognize the ``-O3`` option.
18+
If you want to run the framework's unit tests, you will need a C compiler available through `cc` that is able to compile a "Hello, World!" program and recognize the ``-O3`` option, as well as the `GNU Make <https://www.gnu.org/software/make/>`__ build tool.
1919

2020

2121
.. note::

reframe/core/pipeline.py

Lines changed: 68 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -709,6 +709,21 @@ def disable_hook(cls, hook_name):
709709
extra_resources = fields.TypedField('extra_resources',
710710
typ.Dict[str, typ.Dict[str, object]])
711711

712+
#: .. versionadded:: 3.3
713+
#:
714+
#: Always build the source code for this test locally. If set to
715+
#: :class:`False`, ReFrame will spawn a build job on the partition where
716+
#: the test will run. Setting this to :class:`False` is useful when
717+
#: cross-compilation is not supported on the system where ReFrame is run.
718+
#: Normally, ReFrame will mark the test as a failure if the spawned job
719+
#: exits with a non-zero exit code. However, certain scheduler backends,
720+
#: such as the ``squeue`` do not set it. In such cases, it is the user's
721+
#: responsibility to check whether the build phase failed by adding an
722+
#: appropriate sanity check.
723+
#:
724+
#: :type: boolean : :default: :class:`True`
725+
build_locally = fields.TypedField('build_locally', bool)
726+
712727
def __new__(cls, *args, **kwargs):
713728
obj = super().__new__(cls)
714729

@@ -727,7 +742,12 @@ def __new__(cls, *args, **kwargs):
727742
if osext.is_interactive():
728743
prefix = os.getcwd()
729744
else:
730-
prefix = os.path.abspath(os.path.dirname(inspect.getfile(cls)))
745+
try:
746+
prefix = cls._rfm_pinned_prefix
747+
except AttributeError:
748+
prefix = os.path.abspath(
749+
os.path.dirname(inspect.getfile(cls))
750+
)
731751

732752
obj._rfm_init(name, prefix)
733753
return obj
@@ -736,10 +756,17 @@ def __init__(self):
736756
pass
737757

738758
@classmethod
739-
def __init_subclass__(cls, *, special=False, **kwargs):
759+
def __init_subclass__(cls, *, special=False, pin_prefix=False, **kwargs):
740760
super().__init_subclass__(**kwargs)
741761
cls._rfm_special_test = special
742762

763+
# Insert the prefix to pin the test to if the test lives in a test
764+
# library with resources in it.
765+
if pin_prefix:
766+
cls._rfm_pinned_prefix = os.path.abspath(
767+
os.path.dirname(inspect.getfile(cls))
768+
)
769+
743770
def _rfm_init(self, name=None, prefix=None):
744771
if name is not None:
745772
self.name = name
@@ -777,6 +804,7 @@ def _rfm_init(self, name=None, prefix=None):
777804

778805
# True only if check is to be run locally
779806
self.local = False
807+
self.build_locally = True
780808

781809
# Static directories of the regression check
782810
self._prefix = os.path.abspath(prefix)
@@ -1038,29 +1066,29 @@ def _setup_paths(self):
10381066
except OSError as e:
10391067
raise PipelineError('failed to set up paths') from e
10401068

1041-
def _setup_job(self, **job_opts):
1069+
def _setup_job(self, name, force_local=False, **job_opts):
10421070
'''Setup the job related to this check.'''
10431071

1044-
if self.local:
1072+
if force_local:
10451073
scheduler = getscheduler('local')()
10461074
launcher = getlauncher('local')()
10471075
else:
10481076
scheduler = self._current_partition.scheduler
10491077
launcher = self._current_partition.launcher_type()
10501078

10511079
self.logger.debug(
1052-
f'Setting up run job descriptor '
1080+
f'Setting up job {name!r} '
10531081
f'(scheduler: {scheduler.registered_name!r}, '
10541082
f'launcher: {launcher.registered_name!r})'
10551083
)
1056-
self._job = Job.create(scheduler,
1057-
launcher,
1058-
name='rfm_%s_job' % self.name,
1059-
workdir=self._stagedir,
1060-
max_pending_time=self.max_pending_time,
1061-
sched_access=self._current_partition.access,
1062-
sched_exclusive_access=self.exclusive_access,
1063-
**job_opts)
1084+
return Job.create(scheduler,
1085+
launcher,
1086+
name=name,
1087+
workdir=self._stagedir,
1088+
max_pending_time=self.max_pending_time,
1089+
sched_access=self._current_partition.access,
1090+
sched_exclusive_access=self.exclusive_access,
1091+
**job_opts)
10641092

10651093
def _setup_perf_logging(self):
10661094
self._perf_logger = logging.getperflogger(self)
@@ -1089,7 +1117,12 @@ def setup(self, partition, environ, **job_opts):
10891117
self._current_partition = partition
10901118
self._current_environ = environ
10911119
self._setup_paths()
1092-
self._setup_job(**job_opts)
1120+
self._job = self._setup_job(f'rfm_{self.name}_job',
1121+
self.local,
1122+
**job_opts)
1123+
self._build_job = self._setup_job(f'rfm_{self.name}_build',
1124+
self.local or self.build_locally,
1125+
**job_opts)
10931126

10941127
def _copy_to_stagedir(self, path):
10951128
self.logger.debug(f'Copying {path} to stage directory')
@@ -1191,10 +1224,6 @@ def compile(self):
11911224
environs = [self._current_partition.local_env, self._current_environ,
11921225
user_environ, self._cdt_environ]
11931226

1194-
self._build_job = Job.create(getscheduler('local')(),
1195-
launcher=getlauncher('local')(),
1196-
name='rfm_%s_build' % self.name,
1197-
workdir=self._stagedir)
11981227
with osext.change_dir(self._stagedir):
11991228
try:
12001229
self._build_job.prepare(
@@ -1225,8 +1254,8 @@ def compile_wait(self):
12251254
'''
12261255
self._build_job.wait()
12271256

1228-
# FIXME: this check is not reliable for certain scheduler backends
1229-
if self._build_job.exitcode != 0:
1257+
# We raise a BuildError when we an exit code and it is non zero
1258+
if self._build_job.exitcode:
12301259
raise BuildError(self._build_job.stdout, self._build_job.stderr)
12311260

12321261
@_run_hooks('pre_run')
@@ -1760,6 +1789,20 @@ class RunOnlyRegressionTest(RegressionTest, special=True):
17601789
module.
17611790
'''
17621791

1792+
@_run_hooks()
1793+
def setup(self, partition, environ, **job_opts):
1794+
'''The setup stage of the regression test pipeline.
1795+
1796+
Similar to the :func:`RegressionTest.setup`, except that no build job
1797+
is created for this test.
1798+
'''
1799+
self._current_partition = partition
1800+
self._current_environ = environ
1801+
self._setup_paths()
1802+
self._job = self._setup_job(f'rfm_{self.name}_job',
1803+
self.local,
1804+
**job_opts)
1805+
17631806
def compile(self):
17641807
'''The compilation phase of the regression test pipeline.
17651808
@@ -1802,21 +1845,20 @@ class CompileOnlyRegressionTest(RegressionTest, special=True):
18021845
module.
18031846
'''
18041847

1805-
def _rfm_init(self, *args, **kwargs):
1806-
super()._rfm_init(*args, **kwargs)
1807-
self.local = True
1808-
18091848
@_run_hooks()
18101849
def setup(self, partition, environ, **job_opts):
18111850
'''The setup stage of the regression test pipeline.
18121851
1813-
Similar to the :func:`RegressionTest.setup`, except that no job
1814-
descriptor is set up for this test.
1852+
Similar to the :func:`RegressionTest.setup`, except that no run job
1853+
is created for this test.
18151854
'''
18161855
# No need to setup the job for compile-only checks
18171856
self._current_partition = partition
18181857
self._current_environ = environ
18191858
self._setup_paths()
1859+
self._build_job = self._setup_job(f'rfm_{self.name}_build',
1860+
self.local or self.build_locally,
1861+
**job_opts)
18201862

18211863
@property
18221864
@sn.sanity_function

reframe/core/schedulers/slurm.py

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -562,9 +562,6 @@ def poll(self, *jobs):
562562
job_match = jobinfo[job.jobid]
563563
except KeyError:
564564
job._state = 'CANCELLED' if job.is_cancelling else 'COMPLETED'
565-
if job.exitcode is None:
566-
job._exitcode = 0
567-
568565
continue
569566

570567
# Join the states with ',' in case of job arrays

reframe/frontend/cli.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -594,7 +594,7 @@ def print_infoline(param, value):
594594
session_info = {
595595
'cmdline': ' '.join(sys.argv),
596596
'config_file': rt.site_config.filename,
597-
'data_version': '1.0',
597+
'data_version': '1.1',
598598
'hostname': socket.gethostname(),
599599
'prefix_output': rt.output_prefix,
600600
'prefix_stage': rt.stage_prefix,

reframe/frontend/statistics.py

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -82,15 +82,22 @@ def json(self, force=False):
8282
entry = {
8383
'build_stderr': None,
8484
'build_stdout': None,
85+
'dependencies_actual': [
86+
(d.check.name, d.partition.fullname, d.environ.name)
87+
for d in t.testcase.deps
88+
],
89+
'dependencies_conceptual': [
90+
d[0] for d in t.check.user_deps()
91+
],
8592
'description': check.descr,
8693
'environment': None,
87-
'fail_reason': None,
8894
'fail_phase': None,
95+
'fail_reason': None,
8996
'jobid': None,
9097
'job_stderr': None,
9198
'job_stdout': None,
92-
'name': check.name,
9399
'maintainers': check.maintainers,
100+
'name': check.name,
94101
'nodelist': [],
95102
'outputdir': None,
96103
'perfvars': None,
@@ -192,6 +199,10 @@ def print_failure_report(self, printer):
192199
job_type = 'local' if r['scheduler'] == 'local' else 'batch job'
193200
jobid = r['jobid']
194201
printer.info(f" * Job type: {job_type} (id={r['jobid']})")
202+
printer.info(f" * Dependencies (conceptual): "
203+
f"{r['dependencies_conceptual']}")
204+
printer.info(f" * Dependencies (actual): "
205+
f"{r['dependencies_actual']}")
195206
printer.info(f" * Maintainers: {r['maintainers']}")
196207
printer.info(f" * Failing phase: {r['fail_phase']}")
197208
printer.info(f" * Rerun with '-n {r['name']}"

0 commit comments

Comments
 (0)