@@ -56,7 +56,7 @@ class RegressionTest(object):
5656 use_multithreading = BooleanField ('use_multithreading' , allow_none = True )
5757 local = BooleanField ('local' )
5858 prefix = StringField ('prefix' )
59- sourcesdir = StringField ('sourcesdir' )
59+ sourcesdir = StringField ('sourcesdir' , allow_none = True )
6060 stagedir = StringField ('stagedir' , allow_none = True )
6161 stdout = StringField ('stdout' , allow_none = True )
6262 stderr = StringField ('stderr' , allow_none = True )
@@ -171,6 +171,13 @@ def is_local(self):
171171 return self .local or self .current_partition .scheduler == 'local'
172172
173173
174+ def _sanitize_basename (self , name ):
175+ """Create a basename safe to be used as path component
176+
177+ Replace all path separator characters in `name` with underscores."""
178+ return name .replace (os .sep , '_' )
179+
180+
174181 def _setup_environ (self , environ ):
175182 """Setup the current environment and load it."""
176183
@@ -196,10 +203,17 @@ def _setup_environ(self, environ):
196203 def _setup_paths (self ):
197204 """Setup the check's dynamic paths."""
198205 self .logger .debug ('setting up paths' )
206+
199207 self .stagedir = self ._resources .stagedir (
200- self .current_partition .name , self .name , self .current_environ .name )
208+ self ._sanitize_basename (self .current_partition .name ),
209+ self .name ,
210+ self ._sanitize_basename (self .current_environ .name )
211+ )
201212 self .outputdir = self ._resources .outputdir (
202- self .current_partition .name , self .name , self .current_environ .name )
213+ self ._sanitize_basename (self .current_partition .name ),
214+ self .name ,
215+ self ._sanitize_basename (self .current_environ .name )
216+ )
203217 self .stdout = os .path .join (self .stagedir , '%s.out' % self .name )
204218 self .stderr = os .path .join (self .stagedir , '%s.err' % self .name )
205219
@@ -230,10 +244,13 @@ def _setup_job(self, **job_opts):
230244 raise ReframeFatalError ('Oops: unsupported launcher: %s' %
231245 self .current_partition .scheduler )
232246
233- job_name = '%s_%s_%s_%s' % (self .name ,
234- self .current_system .name ,
235- self .current_partition .name ,
236- self .current_environ .name )
247+ job_name = '%s_%s_%s_%s' % (
248+ self .name ,
249+ self ._sanitize_basename (self .current_system .name ),
250+ self ._sanitize_basename (self .current_partition .name ),
251+ self ._sanitize_basename (self .current_environ .name )
252+ )
253+
237254 if self .is_local ():
238255 self .job = LocalJob (
239256 job_name = job_name ,
@@ -342,6 +359,9 @@ def compile(self, **compile_opts):
342359 if not self .current_environ :
343360 raise ReframeError ('no programming environment set' )
344361
362+ if not self .sourcesdir :
363+ raise ReframeError ('sourcesdir is not set' )
364+
345365 # if self.sourcepath refers to a directory, stage it first
346366 target_sourcepath = os .path .join (self .sourcesdir , self .sourcepath )
347367 if os .path .isdir (target_sourcepath ):
@@ -420,8 +440,8 @@ def check_performance(self):
420440 return self ._match_patterns (self .perf_patterns , self .reference )
421441
422442
423- def cleanup (self , remove_files = False , unload_env = True ):
424- # Copy stdout/stderr and job script
443+ def _copy_to_outputdir (self ):
444+ """ Copy checks interesting files to the output directory."""
425445 self .logger .debug ('copying interesting files to output directory' )
426446 shutil .copy (self .stdout , self .outputdir )
427447 shutil .copy (self .stderr , self .outputdir )
@@ -434,6 +454,15 @@ def cleanup(self, remove_files=False, unload_env=True):
434454 f = os .path .join (self .stagedir , f )
435455 shutil .copy (f , self .outputdir )
436456
457+
458+ def cleanup (self , remove_files = False , unload_env = True ):
459+ aliased = os .path .samefile (self .stagedir , self .outputdir )
460+ if aliased :
461+ self .logger .debug ('skipping copy to output dir '
462+ 'since they alias each other' )
463+ else :
464+ self ._copy_to_outputdir ()
465+
437466 if remove_files :
438467 self .logger .debug ('removing stage directory' )
439468 shutil .rmtree (self .stagedir )
@@ -550,7 +579,11 @@ def compile(self, **compile_opts):
550579
551580
552581 def run (self ):
553- self ._copy_to_stagedir (os .path .join (self .sourcesdir , self .sourcepath ))
582+ # The sourcesdir can be set to None by the user; then we don't copy.
583+ if self .sourcesdir :
584+ self ._copy_to_stagedir (os .path .join (self .sourcesdir ,
585+ self .sourcepath ))
586+
554587 super ().run ()
555588
556589
0 commit comments