Skip to content

Commit e34dc2e

Browse files
Bug fixes and update to tests
1 parent c99f304 commit e34dc2e

6 files changed

Lines changed: 54 additions & 37 deletions

File tree

frontend/calculation_unittest.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,10 @@ def setUp(self):
4747
self.profile.is_PI = True
4848
self.profile.save()
4949

50+
self.name_patcher = mock.patch.dict(os.environ, {"TEST_NAME": self.id()})
51+
self.name_patcher.start()
52+
53+
5054
def get_params(self, **modifications):
5155
params = self.params.copy()
5256

frontend/calcusliveserver.py

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,11 @@
2222
import time
2323
import sys
2424
import glob
25-
from django.contrib.staticfiles.testing import StaticLiveServerTestCase
2625
import selenium
2726
import datetime
2827
import pexpect
2928
import socket
29+
from unittest import mock
3030

3131
from selenium import webdriver
3232
from selenium.webdriver.common.alert import Alert
@@ -43,6 +43,7 @@
4343
from celery.contrib.testing.worker import start_worker
4444
from celery.contrib.abortable import AbortableAsyncResult
4545

46+
from django.contrib.staticfiles.testing import StaticLiveServerTestCase
4647
from django.core.management import call_command
4748
from django.contrib.auth.models import User, Group
4849
from .models import *
@@ -115,6 +116,7 @@ def tearDownClass(cls):
115116
super().tearDownClass()
116117

117118
def run(self, result=None):
119+
self.full_test_name = self.id()
118120
self.m_name = self._testMethodName
119121
self._testMethodName = "_test_wrapper"
120122
super(StaticLiveServerTestCase, self).run(result)
@@ -157,6 +159,10 @@ def setUp(self):
157159
self.profile = Profile.objects.get(user__username=self.username)
158160
time.sleep(0.1)#Reduces glitches (I think?)
159161

162+
self.name_patcher = mock.patch.dict(os.environ, {"TEST_NAME": self.full_test_name})
163+
self.name_patcher.start()
164+
165+
160166
def cleanupCalculations(self):
161167
for c in Calculation.objects.all():
162168
res = AbortableAsyncResult(c.task_id)
@@ -1137,6 +1143,7 @@ def get_calculation_statuses(self):
11371143

11381144
def apply_PI(self, group_name):
11391145
assert self.is_on_page_profile()
1146+
self.wait_for_ajax()
11401147
group_name = self.driver.find_element_by_name('group_name')
11411148
submit = self.driver.find_element_by_css_selector("button.button:nth-child(3)")
11421149
group_name.send_keys("Test group")
@@ -1163,6 +1170,7 @@ def accept_PI_request(self):
11631170

11641171
def wait_latest_calc_done(self, timeout):
11651172
assert self.is_on_page_calculations()
1173+
self.wait_for_ajax()
11661174
assert self.get_number_calc_orders() > 0
11671175

11681176
for i in range(0, timeout, 2):
@@ -1580,6 +1588,7 @@ def get_name_presets(self):
15801588
return names
15811589

15821590
def select_preset(self, name):
1591+
self.wait_for_ajax()
15831592
element = WebDriverWait(self.driver, 2).until(
15841593
EC.presence_of_element_located((By.XPATH, "//*[@id='presets']/option[text()='{}']".format(name)))
15851594
)

frontend/gen_calc.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ def gen_calc(params, profile):
114114

115115
proj = Project.objects.create()
116116
dummy = CalculationOrder.objects.create(project=proj, author=profile)
117-
calc = Calculation.objects.create(structure=s, step=step, parameters=p, order=dummy)
117+
calc = Calculation.objects.create(structure=s, step=step, parameters=p, order=dummy, task_id=1)
118118

119119
if step.creates_ensemble:
120120
calc.result_ensemble = Ensemble.objects.create(parent_molecule=mol)
@@ -123,8 +123,9 @@ def gen_calc(params, profile):
123123
calc.constraints = params['constraints']
124124

125125
if 'aux_file' in params:
126-
aux_xyz = parse_xyz_from_file(os.path.join(TESTS_DIR, params['aux_file']))
127-
aux_s = Structure.objects.create(parent_ensemble=e, number=2)
126+
with open(os.path.join(TESTS_DIR, params['aux_file'])) as f:
127+
aux_xyz = ''.join(f.readlines())
128+
aux_s = Structure.objects.create(parent_ensemble=e, number=2, xyz_structure=aux_xyz)
128129
calc.aux_structure = aux_s
129130

130131
calc.save()

frontend/tasks.py

Lines changed: 34 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -315,6 +315,7 @@ def system(command, log_file="", force_local=False, software="xtb", calc_id=-1):
315315
return ErrorCodes.UNKNOWN_TERMINATION
316316

317317
if calc_id != -1 and res.is_aborted() == True:
318+
logger.info(f"Stopping calculation {calc_id}")
318319
signal_to_send = signal.SIGTERM
319320

320321
parent = psutil.Process(t.pid)
@@ -349,7 +350,7 @@ def get_cache_index(calc, cache_path):
349350
inputs = glob.glob(cache_path + '/*.input')
350351
for f in inputs:
351352
if files_are_equal(f, calc.input_file):
352-
ind = f.split('/')[-1].split('.')[0]
353+
ind = '.'.join(f.split('/')[-1].split('.')[:-1])
353354
return ind
354355
else:
355356
return -1
@@ -1031,6 +1032,7 @@ def orca_opt(in_file, calc):
10311032
calc.structure = s
10321033
calc.step = BasicStep.objects.get(name="Single-Point Energy")
10331034
calc.save()
1035+
add_input_to_calc(calc)
10341036
return orca_sp(in_file, calc)
10351037

10361038
local_folder = os.path.join(CALCUS_SCR_HOME, str(calc.id))
@@ -1168,9 +1170,10 @@ def orca_freq(in_file, calc):
11681170

11691171
with open(os.path.join(CALCUS_RESULTS_HOME, str(calc.id), "IR.csv"), 'w') as out:
11701172
out.write("Wavenumber,Intensity\n")
1171-
intensities = 1000*np.array(intensities)/max(intensities)
1172-
for _x, i in sorted((zip(list(x), spectrum)), reverse=True):
1173-
out.write("-{:.1f},{:.5f}\n".format(_x, i))
1173+
if len(intensities) > 0:
1174+
intensities = 1000*np.array(intensities)/max(intensities)
1175+
for _x, i in sorted((zip(list(x), spectrum)), reverse=True):
1176+
out.write("-{:.1f},{:.5f}\n".format(_x, i))
11741177

11751178
prop = get_or_create(calc.parameters, calc.structure)
11761179
prop.energy = E
@@ -1193,6 +1196,11 @@ def orca_freq(in_file, calc):
11931196
a, x, y, z = line.strip().split()
11941197
struct.append([a, float(x), float(y), float(z)])
11951198

1199+
parse_orca_charges(calc, calc.structure)
1200+
1201+
if num_atoms == 1:
1202+
return ErrorCodes.SUCCESS
1203+
11961204
while lines[ind].find("VIBRATIONAL FREQUENCIES") == -1 and ind > 0:
11971205
ind -= 1
11981206

@@ -1256,8 +1264,6 @@ def is_all_null(arr):
12561264
for ind2, (a, x, y, z) in enumerate(struct):
12571265
out.write("{} {:.4f} {:.4f} {:.4f} {} {} {}\n".format(a, x, y, z, *vibs[ind][3*ind2:3*ind2+3]))
12581266

1259-
parse_orca_charges(calc, calc.structure)
1260-
12611267
return ErrorCodes.SUCCESS
12621268

12631269
def orca_scan(in_file, calc):
@@ -1663,8 +1669,7 @@ def parse_default_orca_charges(calc, s):
16631669

16641670
def parse_gaussian_charges(calc, s):
16651671
parse_default_gaussian_charges(calc, s)
1666-
1667-
for spec in calc.parameters.specifications.split(' '):#The specifications have been cleaned/formatted already
1672+
for spec in calc.parameters.specifications.replace(', ', ',').split(' '):#The specifications have been cleaned/formatted already
16681673
if spec.strip() == '':
16691674
continue
16701675
if spec.find('(') != -1:
@@ -2796,6 +2801,24 @@ def dispatcher(drawing, order_id):
27962801
c.task_id = res
27972802
c.save()
27982803

2804+
def add_input_to_calc(calc):
2805+
inp = calc_to_ccinput(calc)
2806+
if isinstance(inp, CCInputException):
2807+
msg = f"CCInput error: {str(inp)}"
2808+
if is_test:
2809+
print(msg)
2810+
calc.error_message = msg
2811+
calc.status = 3
2812+
calc.save()
2813+
return ErrorCodes.FAILED_TO_CREATE_INPUT
2814+
2815+
calc.input_file = inp.input_file
2816+
2817+
calc.parameters.specifications = inp.confirmed_specifications
2818+
2819+
calc.save()
2820+
calc.parameters.save()
2821+
27992822
@app.task(base=AbortableTask)
28002823
def run_calc(calc_id):
28012824
if not is_test:
@@ -2829,25 +2852,6 @@ def get_calc(calc_id):
28292852
logger.info(f"Calc {calc_id} already revoked")
28302853
return ErrorCodes.JOB_CANCELLED
28312854

2832-
def add_input_to_calc(calc):
2833-
inp = calc_to_ccinput(calc)
2834-
if isinstance(inp, CCInputException):
2835-
msg = f"CCInput error: {str(inp)}"
2836-
if is_test:
2837-
print(msg)
2838-
calc.error_message = msg
2839-
calc.status = 3
2840-
calc.save()
2841-
return ErrorCodes.FAILED_TO_CREATE_INPUT
2842-
2843-
calc.input_file = inp.input_file
2844-
2845-
if inp.confirmed_specifications != '':
2846-
calc.parameters.specifications = inp.confirmed_specifications
2847-
2848-
calc.save()
2849-
calc.parameters.save()
2850-
28512855
if calc.parameters.software != "xtb": # xtb currently not directly supported by ccinput
28522856
ret = add_input_to_calc(calc)
28532857
if isinstance(ret, ErrorCodes):
@@ -2946,9 +2950,9 @@ def add_input_to_calc(calc):
29462950
analyse_opt(calc.id)
29472951

29482952
if is_test and os.getenv("CAN_USE_CACHED_LOGS") == "true" and os.getenv("USE_CACHED_LOGS") == "true" and not calc_is_cached(calc):
2949-
index = str(time()).replace('.', '_')
2950-
shutil.copytree(os.path.join(tests_dir, "scr", str(calc.id)), os.path.join(tests_dir, "cache", index))
2951-
with open(os.path.join(tests_dir, "cache", index+'.input'), 'w') as out:
2953+
test_name = os.environ['TEST_NAME']
2954+
shutil.copytree(os.path.join(tests_dir, "scr", str(calc.id)), os.path.join(tests_dir, "cache", test_name), dirs_exist_ok=True)
2955+
with open(os.path.join(tests_dir, "cache", test_name+'.input'), 'w') as out:
29522956
out.write(calc.input_file)
29532957

29542958
return ret

frontend/test_calculations.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -207,8 +207,7 @@ def test_freq_DFT(self):
207207

208208
def test_freq_DFT_single_atom(self):
209209
self.assertTrue(self.run_test(type="Frequency Calculation", theory_level="DFT",
210-
method="M062X", in_file="Cl.xyz", charge=-1,
211-
callback=partial(self.cb_has_n_conformers, 1)))
210+
method="M062X", in_file="Cl.xyz", charge=-1))
212211

213212
def test_ts_SE(self):
214213
self.assertTrue(self.run_test(theory_level="Semi-empirical", method="AM1",

frontend/test_selenium.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -954,7 +954,7 @@ def test_duplicate_project_preset(self):
954954
param_count = Parameters.objects.count()
955955
self.assertEqual(param_count, 2)
956956

957-
def test_project_preset_independance(self):
957+
def test_project_preset_independence(self):
958958
proj = Project.objects.create(name="My Project", author=self.profile)
959959
proj.save()
960960

0 commit comments

Comments
 (0)