@@ -37,6 +37,40 @@ def print_vals(vals, name="Values"):
3737
3838class TestCase :
3939
40+ class Command :
41+ """ Split a command into launch part, the executable itself and parameters.
42+
43+ Attributes
44+ ----------
45+ launch : str
46+ e.g. "mpirun -n 2", possibly empty
47+ exec : str
48+ e.g. "SU2_CFD", must be suitable to identify the processes started by the command
49+ param : str
50+ e.g. "-t 2", possibly empty
51+ """
52+
53+ def __init__ (self , launch = "" , exec = "" , param = "" ):
54+ self .launch = launch
55+ self .exec = exec
56+ self .param = param
57+
58+ def empty (self ):
59+ return self .launch == "" and self .exec == "" and self .param == ""
60+
61+ def assemble (self ):
62+ assert self .exec != ""
63+ return " " .join ([part for part in [self .launch , self .exec , self .param ] if part != "" ])
64+
65+ def allow_mpi_as_root (self ):
66+ if os .geteuid () == 0 :
67+ if self .launch .startswith ('mpirun' ):
68+ self .launch = self .launch .replace ('mpirun' , 'mpirun --allow-run-as-root' )
69+
70+ def killall (self ):
71+ """ Issues a shell command that kills all processes matching self.exec, except this process. """
72+ os .system ('pgrep %s | grep -vx %d | xargs kill -9' % (self .exec , os .getpid ()))
73+
4074 def __init__ (self ,tag_in ):
4175
4276 self .tag = tag_in # Input, string tag that identifies this run
@@ -67,11 +101,9 @@ def __init__(self,tag_in):
67101 self .test_vals_aarch64 = []
68102 self .cpu_arch = platform .processor ()
69103 self .enabled_on_cpu_arch = ["x86_64" , "aarch64" ]
70-
71- # These can be optionally varied
72- self .su2_exec = "SU2_CFD"
73- self .timeout = 300
74- self .tol = 0.001
104+ self .command = self .Command ()
105+ self .timeout = 0
106+ self .tol = 0.0
75107
76108 # Options for file-comparison tests
77109 self .reference_file = "of_grad.dat.ref"
@@ -91,9 +123,7 @@ def run_test(self):
91123 start_solver = True
92124
93125 # if root, add flag to mpirun
94- if os .geteuid ()== 0 :
95- if self .su2_exec .startswith ('mpirun' ):
96- self .su2_exec = self .su2_exec .replace ('mpirun' , 'mpirun --allow-run-as-root' )
126+ self .command .allow_mpi_as_root ()
97127
98128 # Adjust the number of iterations in the config file
99129 if len (self .test_vals ) != 0 :
@@ -111,11 +141,9 @@ def run_test(self):
111141
112142 # Check for polar calls
113143 if self .polar :
114- command = "%s > %s" % (self .su2_exec , logfilename )
144+ shell_command = "%s > %s" % (self .command . assemble () , logfilename )
115145 else :
116- command = "%s %s > %s 2>&1" % (self .su2_exec ,
117- self .cfg_file ,
118- logfilename )
146+ shell_command = "%s %s > %s 2>&1" % (self .command .assemble (), self .cfg_file , logfilename )
119147
120148 self .adjust_test_data ()
121149
@@ -124,7 +152,7 @@ def run_test(self):
124152 os .chdir (self .cfg_dir )
125153 print (os .getcwd ())
126154 start = datetime .datetime .now ()
127- process = subprocess .Popen (command , shell = True ) # This line launches SU2
155+ process = subprocess .Popen (shell_command , shell = True ) # This line launches SU2
128156
129157 # check for timeout
130158 while process .poll () is None :
@@ -134,7 +162,7 @@ def run_test(self):
134162 if running_time > self .timeout :
135163 try :
136164 process .kill ()
137- os . system ( 'killall %s' % self .su2_exec ) # In case of parallel execution
165+ self .command . killall () # In case of parallel execution
138166 except AttributeError : # popen.kill apparently fails on some versions of subprocess... the killall command should take care of things!
139167 pass
140168 timed_out = True
@@ -204,7 +232,7 @@ def run_test(self):
204232 print ('Output for the failed case' )
205233 subprocess .call (['cat' , logfilename ])
206234
207- print ('execution command: %s' % command )
235+ print ('execution command: %s' % shell_command )
208236
209237 if timed_out :
210238 print ('ERROR: Execution timed out. timeout=%d' % self .timeout )
@@ -251,20 +279,18 @@ def run_filediff(self):
251279 self .adjust_test_data ()
252280
253281 # if root, add flag to mpirun
254- if os .geteuid ()== 0 :
255- if self .su2_exec .startswith ('mpirun' ):
256- self .su2_exec = self .su2_exec .replace ('mpirun' , 'mpirun --allow-run-as-root' )
282+ self .command .allow_mpi_as_root ()
257283
258284 # Assemble the shell command to run
259285 logfilename = '%s.log' % os .path .splitext (self .cfg_file )[0 ]
260- command = "%s %s > %s 2>&1" % (self .su2_exec , self .cfg_file , logfilename )
286+ shell_command = "%s %s > %s 2>&1" % (self .command . assemble () , self .cfg_file , logfilename )
261287
262288 # Run SU2
263289 workdir = os .getcwd ()
264290 os .chdir (self .cfg_dir )
265291 print (os .getcwd ())
266292 start = datetime .datetime .now ()
267- process = subprocess .Popen (command , shell = True ) # This line launches SU2
293+ process = subprocess .Popen (shell_command , shell = True ) # This line launches SU2
268294
269295 # check for timeout
270296 while process .poll () is None :
@@ -274,7 +300,7 @@ def run_filediff(self):
274300 if running_time > self .timeout :
275301 try :
276302 process .kill ()
277- os . system ( 'killall %s' % self .su2_exec ) # In case of parallel execution
303+ self .command . killall () # In case of parallel execution
278304 except AttributeError : # popen.kill apparently fails on some versions of subprocess... the killall command should take care of things!
279305 pass
280306 timed_out = True
@@ -350,14 +376,14 @@ def run_opt(self):
350376
351377 # Assemble the shell command to run SU2
352378 logfilename = '%s.log' % os .path .splitext (self .cfg_file )[0 ]
353- command = "%s %s > %s 2>&1" % (self .su2_exec , self .cfg_file , logfilename )
379+ shell_command = "%s %s > %s 2>&1" % (self .command . assemble () , self .cfg_file , logfilename )
354380
355381 # Run SU2
356382 workdir = os .getcwd ()
357383 os .chdir (self .cfg_dir )
358384 print (os .getcwd ())
359385 start = datetime .datetime .now ()
360- process = subprocess .Popen (command , shell = True ) # This line launches SU2
386+ process = subprocess .Popen (shell_command , shell = True ) # This line launches SU2
361387
362388 # check for timeout
363389 while process .poll () is None :
@@ -367,7 +393,7 @@ def run_opt(self):
367393 if running_time > self .timeout :
368394 try :
369395 process .kill ()
370- os . system ( 'killall %s' % self .su2_exec ) # In case of parallel execution
396+ self .command . killall () # In case of parallel execution
371397 except AttributeError : # popen.kill apparently fails on some versions of subprocess... the killall command should take care of things!
372398 pass
373399 timed_out = True
@@ -427,7 +453,7 @@ def run_opt(self):
427453 print ('Output for the failed case' )
428454 subprocess .call (['cat' , logfilename ])
429455
430- print ('execution command: %s' % command )
456+ print ('execution command: %s' % shell_command )
431457
432458 if timed_out :
433459 print ('ERROR: Execution timed out. timeout=%d' % self .timeout )
@@ -476,20 +502,18 @@ def run_geo(self):
476502 self .adjust_test_data ()
477503
478504 # if root, add flag to mpirun
479- if os .geteuid ()== 0 :
480- if self .su2_exec .startswith ('mpirun' ):
481- self .su2_exec = self .su2_exec .replace ('mpirun' , 'mpirun --allow-run-as-root' )
505+ self .command .allow_mpi_as_root ()
482506
483507 # Assemble the shell command to run SU2
484508 logfilename = '%s.log' % os .path .splitext (self .cfg_file )[0 ]
485- command = "%s %s > %s 2>&1" % (self .su2_exec , self .cfg_file , logfilename )
509+ shell_command = "%s %s > %s 2>&1" % (self .command . assemble () , self .cfg_file , logfilename )
486510
487511 # Run SU2
488512 workdir = os .getcwd ()
489513 os .chdir (self .cfg_dir )
490514 print (os .getcwd ())
491515 start = datetime .datetime .now ()
492- process = subprocess .Popen (command , shell = True ) # This line launches SU2
516+ process = subprocess .Popen (shell_command , shell = True ) # This line launches SU2
493517
494518 # check for timeout
495519 while process .poll () is None :
@@ -499,7 +523,7 @@ def run_geo(self):
499523 if running_time > self .timeout :
500524 try :
501525 process .kill ()
502- os . system ( 'killall %s' % self .su2_exec ) # In case of parallel execution
526+ self .command . killall () # In case of parallel execution
503527 except AttributeError : # popen.kill apparently fails on some versions of subprocess... the killall command should take care of things!
504528 pass
505529 timed_out = True
@@ -563,7 +587,7 @@ def run_geo(self):
563587 print ('Output for the failed case' )
564588 subprocess .call (['cat' , logfilename ])
565589
566- print ('execution command: %s' % command )
590+ print ('execution command: %s' % shell_command )
567591
568592 if timed_out :
569593 print ('ERROR: Execution timed out. timeout=%d' % self .timeout )
@@ -605,20 +629,18 @@ def run_def(self):
605629 self .adjust_test_data ()
606630
607631 # if root, add flag to mpirun
608- if os .geteuid ()== 0 :
609- if self .su2_exec .startswith ('mpirun' ):
610- self .su2_exec = self .su2_exec .replace ('mpirun' , 'mpirun --allow-run-as-root' )
632+ self .command .allow_mpi_as_root ()
611633
612634 # Assemble the shell command to run SU2
613635 logfilename = '%s.log' % os .path .splitext (self .cfg_file )[0 ]
614- command = "%s %s > %s 2>&1" % (self .su2_exec , self .cfg_file , logfilename )
636+ shell_command = "%s %s > %s 2>&1" % (self .command . assemble () , self .cfg_file , logfilename )
615637
616638 # Run SU2
617639 workdir = os .getcwd ()
618640 os .chdir (self .cfg_dir )
619641 print (os .getcwd ())
620642 start = datetime .datetime .now ()
621- process = subprocess .Popen (command , shell = True ) # This line launches SU2
643+ process = subprocess .Popen (shell_command , shell = True ) # This line launches SU2
622644
623645 # check for timeout
624646 while process .poll () is None :
@@ -628,7 +650,7 @@ def run_def(self):
628650 if running_time > self .timeout :
629651 try :
630652 process .kill ()
631- os . system ( 'killall %s' % self .su2_exec ) # In case of parallel execution
653+ self .command . killall () # In case of parallel execution
632654 except AttributeError : # popen.kill apparently fails on some versions of subprocess... the killall command should take care of things!
633655 pass
634656 timed_out = True
@@ -688,7 +710,7 @@ def run_def(self):
688710 print ('Output for the failed case' )
689711 subprocess .call (['cat' , logfilename ])
690712
691- print ('execution command: %s' % command )
713+ print ('execution command: %s' % shell_command )
692714
693715 if timed_out :
694716 print ('ERROR: Execution timed out. timeout=%d sec' % self .timeout )
0 commit comments