PRISMS-PF  v2.1
run_automatic_tests.py
Go to the documentation of this file.
1 import subprocess
2 import shutil
3 import glob
4 import math
5 import os
6 import datetime
7 import time
8 import sys
9 
10 # ----------------------------------------------------------------------------------------
11 # Function that compiles and runs the unit tests.
12 # ----------------------------------------------------------------------------------------
13 def run_unit_tests():
14  # Open file where output is redirected to
15  if os.path.exists("output.txt") == True:
16  os.remove("output.txt")
17  f = open("output.txt",'w+')
18 
19  # Remove old files
20  if os.path.exists("main") == True:
21  os.remove("main")
22  if os.path.exists("CMakeCache.txt") == True:
23  os.remove("CMakeCache.txt")
24  if os.path.exists("unit_test_results.txt") == True:
25  os.remove("unit_test_results.txt")
26 
27  # Compile and run
28  subprocess.call(["cmake", "."],stdout=f,stderr=f)
29  subprocess.call(["make", "release"],stdout=f)
30  subprocess.call(["mpirun", "-n", "2", "main"],stdout=f)
31  f.close()
32 
33  result_file = open("unit_test_results.txt","r")
34  test_results = result_file.read().splitlines()
35  result_file.close()
36 
37  return test_results
38 
39 
40 # ----------------------------------------------------------------------------------------
41 # Function that compiles the PRISMS-PF code and runs the executable.
42 # ----------------------------------------------------------------------------------------
43 def run_simulation(run_name,dir_path):
44  # Delete any pre-existing executables or results
45  if os.path.exists(run_name) == True:
46  shutil.rmtree(run_name)
47 
48  # Open file where output is redirected to
49  if os.path.exists("output.txt") == True:
50  os.remove("output.txt")
51  f = open("output.txt",'w+')
52 
53  # Remove old files
54  if os.path.exists("main") == True:
55  os.remove("main")
56  if os.path.exists("CMakeCache.txt") == True:
57  os.remove("CMakeCache.txt")
58 
59  subprocess.call(["rm", "*vtu"],stdout=f,stderr=f)
60 
61  # Compile and run
62  subprocess.call(["cmake", "."]) # print to the screen to prevent a timeout on Travis
63  subprocess.call(["make", "release","-j9"],stdout=f)
64  print("Compiling complete, running the regression test...")
65  sys.stdout.flush()
66  start = time.time()
67  subprocess.call(["mpirun", "-n", "1", "main"],stdout=f)
68  end = time.time()
69  f.close()
70 
71  # Group the files
72  subprocess.call(["mkdir",run_name])
73  for output_files in glob.glob('*vtu'):
74  shutil.move(output_files,run_name)
75  if os.path.exists("integratedFields.txt") == True:
76  shutil.move("integratedFields.txt",run_name)
77 
78  test_time = end-start
79  return test_time
80 
81 # ----------------------------------------------------------------------------------------
82 # Function that runs a regression test
83 # ----------------------------------------------------------------------------------------
84 def run_regression_test(applicationName,getNewGoldStandard,dir_path):
85 
86  if (getNewGoldStandard == False):
87  testName = "test_"+applicationName
88 
89  else:
90  testName = "gold_"+applicationName
91 
92  if os.path.exists(testName) == True:
93  shutil.rmtree(testName)
94 
95  # Move to the application directory
96  r_test_dir = dir_path
97  os.chdir("../../applications/"+applicationName)
98 
99  # Run the simulation and move the results to the test directory
100  test_time = run_simulation(testName,dir_path)
101 
102  shutil.move(testName,r_test_dir)
103 
104  # Compare the result against the gold standard, if it exists
105  os.chdir(r_test_dir)
106 
107  if (getNewGoldStandard == False):
108  # Read the gold standard free energies
109  os.chdir("gold_"+applicationName)
110  gold_standard_file = open("integratedFields.txt","r")
111  gold_energy = gold_standard_file.readlines()
112  gold_standard_file.close()
113 
114  last_energy_index = len(gold_energy)-1
115  split_last_line = gold_energy[-1].split()
116  for index, entry in enumerate(split_last_line):
117  if entry == "f_tot":
118  gold_last_energy = split_last_line[index+1]
119 
120  # Read the test free energies
121  os.chdir("../"+testName)
122  test_file = open("integratedFields.txt","r")
123  test_energy = test_file.readlines()
124  test_file.close()
125 
126  last_energy_index = len(test_energy)-1
127  split_last_line = test_energy[-1].split()
128  for index, entry in enumerate(split_last_line):
129  if entry == "f_tot":
130  last_energy = split_last_line[index+1]
131 
132  rel_diff = (float(gold_last_energy)-float(last_energy))/float(gold_last_energy)
133  rel_diff = abs(rel_diff)
134 
135  if (rel_diff < 1.0e-9):
136  test_passed = True
137  else:
138  test_passed = False
139 
140  else:
141  test_passed = True
142 
143  # Print the results to the screen
144  print("Regression Test: ", applicationName)
145 
146  if test_passed:
147  if getNewGoldStandard == False:
148  print("Result: Pass")
149  else:
150  print("Result: New Gold Standard")
151  else:
152  print("Result: Fail")
153 
154  print("Time taken:", test_time)
155 
156  sys.stdout.flush()
157 
158  # Write the results to a file
159  os.chdir(r_test_dir)
160  text_file = open("test_results.txt","a")
161  now = datetime.datetime.now()
162  text_file.write("Application: " + applicationName +" \n")
163  if test_passed:
164  if getNewGoldStandard == False:
165  text_file.write("Result: Pass \n")
166  else:
167  text_file.write("Result: New Gold Standard \n")
168  else:
169  text_file.write("Result: Fail \n")
170  text_file.write("Time: "+str(test_time)+" \n \n")
171  text_file.close()
172 
173  return (test_passed,test_time)
174 
175 # ----------------------------------------------------------------------------------------
176 # Test Script
177 # ----------------------------------------------------------------------------------------
178 
179 # Initialize
180 dir_path = os.path.dirname(os.path.realpath(__file__))
181 os.chdir(dir_path)
182 
183 text_file = open("test_results.txt","a")
184 now = datetime.datetime.now()
185 
186 # ------------------------------------
187 # Start the unit tests
188 # ------------------------------------
189 
190 
191 os.chdir("../unit_tests/")
192 unit_test_results = run_unit_tests()
193 unit_tests_passed = unit_test_results[0]
194 unit_test_counter = unit_test_results[1]
195 
196 print()
197 print("Unit Tests Passed: "+str(unit_tests_passed)+"/"+str(unit_test_counter)+"\n")
198 
199 sys.stdout.flush()
200 
201 text_file.write("--------------------------------------------------------- \n")
202 text_file.write("Unit test on " + now.strftime("%Y-%m-%d %H:%M") + "\n")
203 text_file.write("--------------------------------------------------------- \n")
204 text_file.write("Unit Tests Passed: "+str(unit_tests_passed)+"/"+str(unit_test_counter)+"\n")
205 
206 os.chdir(dir_path)
207 
208 # ------------------------------------
209 # Start the regression tests
210 # ------------------------------------
211 
212 regression_test_counter = 0
213 regression_tests_passed = 0
214 
215 text_file.write("--------------------------------------------------------- \n")
216 text_file.write("Regression test on " + now.strftime("%Y-%m-%d %H:%M") + "\n")
217 text_file.write("--------------------------------------------------------- \n")
218 text_file.close()
219 
220 #applicationList = ["allenCahn","cahnHilliard","cahnHilliard","CHAC_anisotropy","CHAC_anisotropyRegularized","coupledCahnHilliardAllenCahn","mechanics","precipitateEvolution"]
221 #getNewGoldStandardList = [False, False, False, False, False, False, False, False]
222 
223 # Shorter list of applications so that it completes on Travis
224 applicationList = ["allenCahn","cahnHilliard","CHAC_anisotropyRegularized","coupledCahnHilliardAllenCahn","precipitateEvolution"]
225 getNewGoldStandardList = [False, False, False, False, False]
226 #applicationList = ["allenCahn"]
227 #getNewGoldStandardList = [False]
228 
229 
230 
231 for applicationName in applicationList:
232  test_result = run_regression_test(applicationName,getNewGoldStandardList[regression_test_counter],dir_path)
233 
234  regression_test_counter += 1
235  regression_tests_passed += int(test_result[0])
236 
237 print()
238 print("Regression Tests Passed: "+str(regression_tests_passed)+"/"+str(regression_test_counter)+"\n")
239 
240 
241 # Output the overall test results
242 text_file = open("test_results.txt","a")
243 text_file.write("Tests Passed: "+str(regression_tests_passed)+"/"+str(regression_test_counter)+"\n")
244 text_file.write("--------------------------------------------------------- \n")
245 text_file.close()
246 
247 # Set exit code (passed to Travis CI)
248 if ((regression_tests_passed < regression_test_counter) or (unit_tests_passed < unit_test_counter)):
249  sys.exit(1)
250 else:
251  sys.exit(0)