diff --git a/arc/checks/nmd_test.py b/arc/checks/nmd_test.py index 5fcd89bcfc..7616a592df 100644 --- a/arc/checks/nmd_test.py +++ b/arc/checks/nmd_test.py @@ -12,7 +12,7 @@ import numpy as np import arc.checks.nmd as nmd -from arc.common import ARC_PATH, ARC_TESTING_PATH, almost_equal_coords +from arc.common import ARC_PATH, ARC_TESTING_PATH, almost_equal_coords, get_test_project_directory from arc.job.factory import job_factory from arc.level import Level from arc.molecule import Molecule @@ -32,12 +32,13 @@ def setUpClass(cls): A method that is run before all unit tests in this class. """ cls.maxDiff = None + cls.project_directory = get_test_project_directory('tmp_nmd_project') cls.generic_job = job_factory(job_adapter='gaussian', species=[ARCSpecies(label='SPC', smiles='C')], job_type='composite', level=Level(method='CBS-QB3'), project='test_project', - project_directory=os.path.join(ARC_PATH, 'Projects', 'tmp_nmd_project'), + project_directory=cls.project_directory, ) cls.xyz_1 = {'symbols': ('C', 'N', 'H', 'H', 'H', 'H'), 'isotopes': (13, 14, 1, 1, 1, 1), @@ -941,10 +942,7 @@ def tearDownClass(cls): A function that is run ONCE after all unit tests in this class. Delete all project directories created during these unit tests """ - projects = ['tmp_nmd_project'] - for project in projects: - project_directory = os.path.join(ARC_PATH, 'Projects', project) - shutil.rmtree(project_directory, ignore_errors=True) + shutil.rmtree(cls.project_directory, ignore_errors=True) file_paths = [os.path.join(ARC_PATH, 'arc', 'checks', 'nul'), os.path.join(ARC_PATH, 'arc', 'checks', 'run.out')] for file_path in file_paths: if os.path.isfile(file_path): diff --git a/arc/checks/ts_test.py b/arc/checks/ts_test.py index f53c561840..2f558d5d20 100644 --- a/arc/checks/ts_test.py +++ b/arc/checks/ts_test.py @@ -12,7 +12,7 @@ import numpy as np import arc.checks.ts as ts -from arc.common import ARC_PATH, ARC_TESTING_PATH, almost_equal_lists +from arc.common import ARC_PATH, ARC_TESTING_PATH, almost_equal_lists, get_test_project_directory from arc.job.factory import job_factory from arc.level import Level from arc.parser.parser import parse_normal_mode_displacement, parse_geometry @@ -103,9 +103,7 @@ def setUpClass(cls): job_type='composite', level=Level(method='CBS-QB3'), project='test_project', - project_directory=os.path.join(ARC_PATH, - 'Projects', - 'arc_project_for_testing_delete_after_usage4'), + project_directory=get_test_project_directory('arc_project_for_testing_delete_after_usage4'), ) cls.rxn_3 = ARCReaction(r_species=[ARCSpecies(label='NH3', smiles='N'), ARCSpecies(label='H', smiles='[H]')], @@ -213,7 +211,7 @@ def setUpClass(cls): (-1.1265684046717404, -0.2344009055503307, -1.0127644068816903))} cls.species_dict_8 = {spc.label: spc for spc in cls.rxn_8.r_species + cls.rxn_8.p_species + [cls.rxn_8.ts_species]} - cls.project_directory_8 = os.path.join(ts.ARC_PATH, 'Projects', 'arc_project_for_testing_delete_after_usage5') + cls.project_directory_5 = get_test_project_directory('arc_project_for_testing_delete_after_usage5') cls.output_dict_8 = {'iC3H7': {'paths': {'freq': os.path.join(ARC_TESTING_PATH, 'freq', 'iC3H7.out'), 'sp': os.path.join(ARC_TESTING_PATH, 'opt', 'iC3H7.out'), 'opt': os.path.join(ARC_TESTING_PATH, 'opt', 'iC3H7.out'), @@ -331,9 +329,9 @@ def test_compute_rxn_e0(self): """Test the compute_rxn_e0() function.""" for spc_label in self.rxn_8.reactants + self.rxn_8.products + [self.rxn_8.ts_label]: folder = 'rxns' if self.species_dict_8[spc_label].is_ts else 'Species' - base_path = os.path.join(self.project_directory_8, 'output', folder, spc_label, 'geometry') + base_path = os.path.join(self.project_directory_5, 'output', folder, spc_label, 'geometry') os.makedirs(base_path, exist_ok=True) - freq_path = os.path.join(self.project_directory_8, 'output', folder, spc_label, 'geometry', 'freq.out') + freq_path = os.path.join(self.project_directory_5, 'output', folder, spc_label, 'geometry', 'freq.out') shutil.copy(src=self.output_dict_8[spc_label]['paths']['freq'], dst=freq_path) self.assertIsNone(self.rxn_8.r_species[0].e0) @@ -342,7 +340,7 @@ def test_compute_rxn_e0(self): rxn_copy = ts.compute_rxn_e0(reaction=self.rxn_8, species_dict=self.species_dict_8, - project_directory=self.project_directory_8, + project_directory=self.project_directory_5, kinetics_adapter='arkane', output=self.output_dict_8, sp_level=Level(repr='cbs-qb3'), @@ -356,13 +354,13 @@ def test_check_rxn_e0(self): """Test the check_rxn_e0() function.""" for spc_label in self.rxn_8.reactants + self.rxn_8.products + [self.rxn_8.ts_label]: folder = 'rxns' if self.species_dict_8[spc_label].is_ts else 'Species' - base_path = os.path.join(self.project_directory_8, 'output', folder, spc_label, 'geometry') + base_path = os.path.join(self.project_directory_5, 'output', folder, spc_label, 'geometry') os.makedirs(base_path, exist_ok=True) - freq_path = os.path.join(self.project_directory_8, 'output', folder, spc_label, 'geometry', 'freq.out') + freq_path = os.path.join(self.project_directory_5, 'output', folder, spc_label, 'geometry', 'freq.out') shutil.copy(src=self.output_dict_8[spc_label]['paths']['freq'], dst=freq_path) rxn_copy = ts.compute_rxn_e0(reaction=self.rxn_8, species_dict=self.species_dict_8, - project_directory=self.project_directory_8, + project_directory=self.project_directory_5, kinetics_adapter='arkane', output=self.output_dict_8, sp_level=Level(repr='CBS-QB3'), @@ -858,9 +856,8 @@ def tearDownClass(cls): A function that is run ONCE after all unit tests in this class. Delete all project directories created during these unit tests """ - projects = ['arc_project_for_testing_delete_after_usage4', 'arc_project_for_testing_delete_after_usage5'] - for project in projects: - project_directory = os.path.join(ARC_PATH, 'Projects', project) + for project_directory in [get_test_project_directory('arc_project_for_testing_delete_after_usage4'), + cls.project_directory_5]: shutil.rmtree(project_directory, ignore_errors=True) file_paths = [os.path.join(ARC_PATH, 'arc', 'checks', 'nul'), os.path.join(ARC_PATH, 'arc', 'checks', 'run.out')] for file_path in file_paths: diff --git a/arc/common.py b/arc/common.py index 534139fa77..3e334c6c2c 100644 --- a/arc/common.py +++ b/arc/common.py @@ -508,6 +508,35 @@ def globalize_path(string: str, return string +def get_test_project_name(base_name: str) -> str: + """ + Get a project name for a unit test that is unique per pytest-xdist worker. + + Args: + base_name (str): The base project name. + + Returns: + str: ``base_name`` suffixed by the pytest-xdist worker ID when running under pytest-xdist, + otherwise ``base_name`` unchanged. + """ + worker_id = os.environ.get('PYTEST_XDIST_WORKER') + return f'{base_name}_{worker_id}' if worker_id else base_name + + +def get_test_project_directory(base_name: str) -> str: + """ + Get a path to a project directory for a unit test that is unique per pytest-xdist worker. + + Args: + base_name (str): The base project name. + + Returns: + str: The path under ARC's ``Projects`` folder to a directory named ``base_name`` suffixed by the + pytest-xdist worker ID when running under pytest-xdist, and named ``base_name`` otherwise. + """ + return os.path.join(ARC_PATH, 'Projects', get_test_project_name(base_name)) + + def delete_check_files(project_directory: str): """ Delete local ESS checkfiles. They usually take up lots of space and are not needed after ARC terminates. diff --git a/arc/common_test.py b/arc/common_test.py index f9a0a28293..fbc9f7502d 100644 --- a/arc/common_test.py +++ b/arc/common_test.py @@ -1023,6 +1023,34 @@ def test_globalize_path(self): globalized_string = common.globalize_path(string=string, project_directory='~/Code/runs/run_1/') self.assertEqual(globalized_string, ' project_directory: ~/Code/runs/run_1/') + def test_get_test_project_name(self): + """Test getting a pytest-xdist worker scoped project name""" + original = os.environ.get('PYTEST_XDIST_WORKER') + self.addCleanup(self._restore_xdist_worker_env, original) + os.environ.pop('PYTEST_XDIST_WORKER', None) + self.assertEqual(common.get_test_project_name('project_1'), 'project_1') + os.environ['PYTEST_XDIST_WORKER'] = 'gw3' + self.assertEqual(common.get_test_project_name('project_1'), 'project_1_gw3') + + def test_get_test_project_directory(self): + """Test getting a pytest-xdist worker scoped project directory""" + original = os.environ.get('PYTEST_XDIST_WORKER') + self.addCleanup(self._restore_xdist_worker_env, original) + os.environ['PYTEST_XDIST_WORKER'] = 'gw5' + self.assertEqual(common.get_test_project_directory('project_2'), + os.path.join(common.ARC_PATH, 'Projects', 'project_2_gw5')) + os.environ.pop('PYTEST_XDIST_WORKER', None) + self.assertEqual(common.get_test_project_directory('project_2'), + os.path.join(common.ARC_PATH, 'Projects', 'project_2')) + + @staticmethod + def _restore_xdist_worker_env(original: str | None): + """Restore the PYTEST_XDIST_WORKER environment variable to its original value""" + if original is None: + os.environ.pop('PYTEST_XDIST_WORKER', None) + else: + os.environ['PYTEST_XDIST_WORKER'] = original + def test_estimate_orca_mem_cpu_requirement(self): """Test estimating memory and cpu requirements for an Orca job.""" num_heavy_atoms_0 = 0 diff --git a/arc/job/adapter_test.py b/arc/job/adapter_test.py index 2691aa129a..feded5a059 100644 --- a/arc/job/adapter_test.py +++ b/arc/job/adapter_test.py @@ -15,7 +15,7 @@ import unittest from unittest.mock import patch -from arc.common import ARC_TESTING_PATH +from arc.common import ARC_TESTING_PATH, get_test_project_name from arc.imports import settings from arc.job.adapter import JobAdapter, JobEnum, JobTypeEnum, JobExecutionTypeEnum from arc.job.adapters.gaussian import GaussianAdapter @@ -24,6 +24,10 @@ servers, submit_filenames = settings['servers'], settings['submit_filenames'] +JOB_ADAPTER_DIRS = tuple(os.path.join(ARC_TESTING_PATH, get_test_project_name(f'test_JobAdapter{suffix}')) + for suffix in ('', '_scan', '_ServerTimeLimit')) +JOB_ADAPTER_DIR, JOB_ADAPTER_SCAN_DIR, JOB_ADAPTER_STL_DIR = JOB_ADAPTER_DIRS + class TestEnumerationClasses(unittest.TestCase): """ @@ -89,13 +93,13 @@ def setUpClass(cls): A method that is run before all unit tests in this class. """ cls.maxDiff = None - for dir_name in ('test_JobAdapter', 'test_JobAdapter_scan', 'test_JobAdapter_ServerTimeLimit'): - cls.addClassCleanup(shutil.rmtree, os.path.join(ARC_TESTING_PATH, dir_name), ignore_errors=True) + for dir_path in JOB_ADAPTER_DIRS: + cls.addClassCleanup(shutil.rmtree, dir_path, ignore_errors=True) cls.job_1 = GaussianAdapter(execution_type='queue', job_type='conf_opt', level=Level(method='cbs-qb3'), project='test', - project_directory=os.path.join(ARC_TESTING_PATH, 'test_JobAdapter'), + project_directory=JOB_ADAPTER_DIR, species=[ARCSpecies(label='spc1', xyz=['O 0 0 1', 'O 0 0 2', @@ -124,7 +128,7 @@ def setUpClass(cls): job_type='opt', level=Level(method='cbs-qb3'), project='test', - project_directory=os.path.join(ARC_TESTING_PATH, 'test_JobAdapter'), + project_directory=JOB_ADAPTER_DIR, species=[ARCSpecies(label='spc1', xyz=['O 0 0 1'])], testing=True, ) @@ -151,7 +155,7 @@ def setUpClass(cls): torsions=[[1, 2, 3, 4]], level=Level(method='wb97xd', basis='def2-tzvp'), project='test_scans', - project_directory=os.path.join(ARC_TESTING_PATH, 'test_JobAdapter_scan'), + project_directory=JOB_ADAPTER_SCAN_DIR, species=[cls.spc_3a, cls.spc_3b, cls.spc_3c, cls.spc_3d, cls.spc_3e, cls.spc_3f], testing=True, ) @@ -159,12 +163,12 @@ def setUpClass(cls): job_type='opt', level=Level(method='cbs-qb3'), project='test', - project_directory=os.path.join(ARC_TESTING_PATH, 'test_JobAdapter'), + project_directory=JOB_ADAPTER_DIR, species=[ARCSpecies(label='spc1', xyz=['O 0 0 1'])], testing=True, ) # Copy the PBS time limit fixture into the directory structure the adapter expects. - stl_dir = os.path.join(ARC_TESTING_PATH, 'test_JobAdapter_ServerTimeLimit') + stl_dir = JOB_ADAPTER_STL_DIR err_dest = os.path.join(stl_dir, 'calcs', 'Species', 'spc1', 'opt_101') os.makedirs(err_dest, exist_ok=True) shutil.copy(os.path.join(ARC_TESTING_PATH, 'server', 'pbs', 'timelimit', 'err.txt'), @@ -288,7 +292,7 @@ def test_add_to_args(self): job_type='opt', level=Level(method='cbs-qb3'), project='test', - project_directory=os.path.join(ARC_TESTING_PATH, 'test_JobAdapter'), + project_directory=JOB_ADAPTER_DIR, species=[ARCSpecies(label='spc1', xyz=['O 0 0 1'])], testing=True, args={'keyword': {'general': 'val_tst_1 val_tst_2 val_tst_3'}, diff --git a/arc/job/adapters/common_test.py b/arc/job/adapters/common_test.py index c66f412df3..8cfcae161f 100644 --- a/arc/job/adapters/common_test.py +++ b/arc/job/adapters/common_test.py @@ -10,12 +10,15 @@ import unittest import arc.job.adapters.common as common -from arc.common import ARC_TESTING_PATH +from arc.common import ARC_TESTING_PATH, get_test_project_name from arc.job.adapters.gaussian import GaussianAdapter from arc.job.adapters.molpro import MolproAdapter from arc.level import Level from arc.species import ARCSpecies +GAUSSIAN_PROJECT_DIR = os.path.join(ARC_TESTING_PATH, get_test_project_name('test_GaussianAdapter_common')) +MOLPRO_PROJECT_DIR = os.path.join(ARC_TESTING_PATH, get_test_project_name('test_MolproAdapter_common')) + class TestJobCommon(unittest.TestCase): """ @@ -31,7 +34,7 @@ def setUpClass(cls): job_type='composite', level=Level(method='cbs-qb3-paraskevas'), project='test', - project_directory=os.path.join(ARC_TESTING_PATH, 'test_GaussianAdapter'), + project_directory=GAUSSIAN_PROJECT_DIR, species=[ARCSpecies(label='spc1', xyz=['O 0 0 1'], multiplicity=1)], testing=True, args={'keyword': {'general': 'IOp(1/12=5,3/44=0)'}}, @@ -41,7 +44,7 @@ def setUpClass(cls): torsions=[[1, 2, 3, 4]], level=Level(method='wb97xd', basis='def2tzvp'), project='test', - project_directory=os.path.join(ARC_TESTING_PATH, 'test_GaussianAdapter'), + project_directory=GAUSSIAN_PROJECT_DIR, species=[ARCSpecies(label='spc1', xyz=['O 0 0 1'], multiplicity=3)], testing=True, args={'keyword': {'general': 'IOp(1/12=5,3/44=0)'}}, @@ -51,7 +54,7 @@ def setUpClass(cls): torsions=[[1, 2, 3, 4]], level=Level(method='wb97xd', basis='def2tzvp'), project='test', - project_directory=os.path.join(ARC_TESTING_PATH, 'test_GaussianAdapter'), + project_directory=GAUSSIAN_PROJECT_DIR, species=[ARCSpecies(label='spc1', xyz=['O 0 0 1'], multiplicity=1, number_of_radicals=2)], testing=True, args={'keyword': {'general': 'IOp(1/12=5,3/44=0)'}}, @@ -61,7 +64,7 @@ def setUpClass(cls): torsions=[[1, 2, 3, 4]], level=Level(method='wb97xd', basis='def2tzvp'), project='test', - project_directory=os.path.join(ARC_TESTING_PATH, 'test_GaussianAdapter'), + project_directory=GAUSSIAN_PROJECT_DIR, species=[ARCSpecies(label='spc1', xyz=['O 0 0 1'], multiplicity=1, number_of_radicals=2, multi_species='mltspc1'), ARCSpecies(label='spc1', xyz=['O 0 0 1'], multiplicity=1, number_of_radicals=1, multi_species='mltspc1')], testing=True, @@ -86,7 +89,7 @@ def test_check_argument_consistency(self): job_type='irc', level=Level(method='ccsd(t)', basis='cc-pvtz'), project='test', - project_directory=os.path.join(ARC_TESTING_PATH, 'test_MolproAdapter'), + project_directory=MOLPRO_PROJECT_DIR, species=[ARCSpecies(label='spc1', xyz=['O 0 0 1'], multiplicity=1)], testing=True, ) @@ -95,7 +98,7 @@ def test_check_argument_consistency(self): job_type='irc', level=Level(method='b3lyp', basis='def2svp'), project='test', - project_directory=os.path.join(ARC_TESTING_PATH, 'test_GaussianAdapter'), + project_directory=GAUSSIAN_PROJECT_DIR, species=[ARCSpecies(label='spc1', xyz=['O 0 0 1'], multiplicity=1)], testing=True, args={'keyword': {'general': 'IOp(1/12=5,3/44=0)'}}, @@ -109,7 +112,7 @@ def test_check_argument_consistency(self): torsions=[[1, 2, 3, 4]], level=Level(method='ccsd(t)', basis='cc-pvtz'), project='test', - project_directory=os.path.join(ARC_TESTING_PATH, 'test_MolproAdapter'), + project_directory=MOLPRO_PROJECT_DIR, species=[spc], testing=True, ) @@ -336,8 +339,8 @@ def tearDownClass(cls): A function that is run ONCE after all unit tests in this class. Delete all project directories created during these unit tests """ - shutil.rmtree(os.path.join(ARC_TESTING_PATH, 'test_GaussianAdapter'), ignore_errors=True) - shutil.rmtree(os.path.join(ARC_TESTING_PATH, 'test_MolproAdapter'), ignore_errors=True) + shutil.rmtree(GAUSSIAN_PROJECT_DIR, ignore_errors=True) + shutil.rmtree(MOLPRO_PROJECT_DIR, ignore_errors=True) if __name__ == '__main__': diff --git a/arc/job/adapters/gaussian_test.py b/arc/job/adapters/gaussian_test.py index 96f65af276..da491ab431 100644 --- a/arc/job/adapters/gaussian_test.py +++ b/arc/job/adapters/gaussian_test.py @@ -10,13 +10,15 @@ import shutil import unittest -from arc.common import ARC_TESTING_PATH +from arc.common import ARC_TESTING_PATH, get_test_project_name from arc.job.adapters.gaussian import GaussianAdapter, get_memory_headroom_fraction from arc.level import Level from arc.settings.settings import input_filenames, output_filenames, servers, submit_filenames from arc.species import ARCSpecies import arc.job.trsh as trsh +PROJECT_DIR = os.path.join(ARC_TESTING_PATH, get_test_project_name('test_GaussianAdapter')) + class TestGaussianAdapter(unittest.TestCase): """ @@ -32,7 +34,7 @@ def setUpClass(cls): job_type='composite', level=Level(method='cbs-qb3-paraskevas'), project='test', - project_directory=os.path.join(ARC_TESTING_PATH, 'test_GaussianAdapter'), + project_directory=PROJECT_DIR, species=[ARCSpecies(label='spc1', xyz=['O 0 0 1'], multiplicity=3)], testing=True, args={'keyword': {'general': 'IOp(1/12=5,3/44=0)'}}, @@ -44,7 +46,7 @@ def setUpClass(cls): solvation_method='SMD', solvent='Water'), project='test', - project_directory=os.path.join(ARC_TESTING_PATH, 'test_GaussianAdapter'), + project_directory=PROJECT_DIR, species=[ARCSpecies(label='spc1', xyz=['O 0 0 1'], multiplicity=3), ARCSpecies(label='spc2', xyz=['O 0 0 2'], multiplicity=3)], testing=True, @@ -56,7 +58,7 @@ def setUpClass(cls): solvation_method='SMD', solvent='Water'), project='test', - project_directory=os.path.join(ARC_TESTING_PATH, 'test_GaussianAdapter'), + project_directory=PROJECT_DIR, species=[ARCSpecies(label='spc1', xyz=['O 0 0 1'], multiplicity=3)], testing=True, ) @@ -76,7 +78,7 @@ def setUpClass(cls): level=Level(method='wb97xd', basis='def2-TZVP'), project='test', - project_directory=os.path.join(ARC_TESTING_PATH, 'test_GaussianAdapter'), + project_directory=PROJECT_DIR, species=[spc_4], rotor_index=0, testing=True, @@ -87,7 +89,7 @@ def setUpClass(cls): level=Level(method='wb97xd', basis='def2-TZVP'), project='test', - project_directory=os.path.join(ARC_TESTING_PATH, 'test_GaussianAdapter'), + project_directory=PROJECT_DIR, species=[ARCSpecies(label='birad singlet', xyz=['O 0 0 1'], multiplicity=1, @@ -99,7 +101,7 @@ def setUpClass(cls): level=Level(method='wb97xd', basis='def2-TZVP'), project='test', - project_directory=os.path.join(ARC_TESTING_PATH, 'test_GaussianAdapter'), + project_directory=PROJECT_DIR, species=[ARCSpecies(label='anion', xyz=['O 0 0 1'], charge=-1, is_ts=False)], testing=True, ) @@ -108,7 +110,7 @@ def setUpClass(cls): level=Level(method='wb97xd', basis='def2-TZVP'), project='test', - project_directory=os.path.join(ARC_TESTING_PATH, 'test_GaussianAdapter'), + project_directory=PROJECT_DIR, species=[ARCSpecies(label='IRC', xyz=['O 0 0 1'], is_ts=True, multiplicity=3)], irc_direction='reverse', testing=True, @@ -117,7 +119,7 @@ def setUpClass(cls): job_type='composite', level=Level(method='cbs-qb3-paraskevas'), project='test', - project_directory=os.path.join(ARC_TESTING_PATH, 'test_GaussianAdapter'), + project_directory=PROJECT_DIR, species=[ARCSpecies(label='spc1', xyz=['O 0 0 1'], multiplicity=3)], testing=True, args={'keyword': {'general': 'IOp(1/12=5,3/44=0)'}}, @@ -127,7 +129,7 @@ def setUpClass(cls): level=Level(method='wb97xd', basis='def2-TZVP'), project='test', - project_directory=os.path.join(ARC_TESTING_PATH, 'test_GaussianAdapter'), + project_directory=PROJECT_DIR, species=[ARCSpecies(label='anion', xyz=['O 0 0 1'], charge=-1, is_ts=False)], testing=True, ) @@ -136,7 +138,7 @@ def setUpClass(cls): level=Level(method='wb97xd'), fine=True, project='test', - project_directory=os.path.join(ARC_TESTING_PATH, 'test_GaussianAdapter'), + project_directory=PROJECT_DIR, species=[ARCSpecies(label='anion', xyz=['O 0 0 1'], charge=-1, is_ts=False)], testing=True, args={'trsh': {'trsh': ['int=(Acc2E=14)']}}, @@ -145,7 +147,7 @@ def setUpClass(cls): job_type='opt', level=Level(method='uff'), project='test', - project_directory=os.path.join(ARC_TESTING_PATH, 'test_GaussianAdapter'), + project_directory=PROJECT_DIR, species=[ARCSpecies(label='spc1', xyz=['O 0 0 1'], multiplicity=3)], testing=True, ) @@ -156,7 +158,7 @@ def setUpClass(cls): solvation_method='SMD', solvent='Water'), project='test', - project_directory=os.path.join(ARC_TESTING_PATH, 'test_GaussianAdapter'), + project_directory=PROJECT_DIR, species=[ARCSpecies(label='spc1', xyz=['O 0 0 1'], multi_species='mltspc1', multiplicity=3), ARCSpecies(label='spc2', xyz=['O 0 0 2'], multi_species='mltspc1', multiplicity=3), ARCSpecies(label='ethanol', xyz=["""C 1.1658210 -0.4043550 0.0000000 @@ -212,7 +214,7 @@ def setUpClass(cls): fine=True, ess_trsh_methods=ess_trsh_methods, project='test', - project_directory=os.path.join(ARC_TESTING_PATH, 'test_GaussianAdapter'), + project_directory=PROJECT_DIR, species=[spc_11], testing=True, args=args @@ -234,7 +236,7 @@ def setUpClass(cls): fine=True, ess_trsh_methods=ess_trsh_methods, project='test', - project_directory=os.path.join(ARC_TESTING_PATH, 'test_GaussianAdapter'), + project_directory=PROJECT_DIR, species=[spc_11], testing=True, args=args @@ -256,7 +258,7 @@ def setUpClass(cls): fine=True, ess_trsh_methods=ess_trsh_methods, project='test', - project_directory=os.path.join(ARC_TESTING_PATH, 'test_GaussianAdapter'), + project_directory=PROJECT_DIR, species=[spc_11], testing=True, args=args @@ -278,7 +280,7 @@ def setUpClass(cls): fine=True, ess_trsh_methods=ess_trsh_methods, project='test', - project_directory=os.path.join(ARC_TESTING_PATH, 'test_GaussianAdapter'), + project_directory=PROJECT_DIR, species=[spc_11], testing=True, args=args @@ -301,7 +303,7 @@ def setUpClass(cls): fine=True, ess_trsh_methods=ess_trsh_methods, project='test', - project_directory=os.path.join(ARC_TESTING_PATH, 'test_GaussianAdapter'), + project_directory=PROJECT_DIR, species=[spc_11], testing=True, args=args @@ -323,7 +325,7 @@ def setUpClass(cls): fine=True, ess_trsh_methods=ess_trsh_methods, project='test', - project_directory=os.path.join(ARC_TESTING_PATH, 'test_GaussianAdapter'), + project_directory=PROJECT_DIR, species=[spc_11], testing=True, args=args @@ -346,7 +348,7 @@ def setUpClass(cls): fine=True, ess_trsh_methods=ess_trsh_methods, project='test', - project_directory=os.path.join(ARC_TESTING_PATH, 'test_GaussianAdapter'), + project_directory=PROJECT_DIR, species=[spc_11], testing=True, args=args @@ -368,7 +370,7 @@ def setUpClass(cls): fine=True, ess_trsh_methods=ess_trsh_methods, project='test', - project_directory=os.path.join(ARC_TESTING_PATH, 'test_GaussianAdapter'), + project_directory=PROJECT_DIR, species=[spc_11], testing=True, args=args @@ -390,7 +392,7 @@ def setUpClass(cls): fine=True, ess_trsh_methods=ess_trsh_methods, project='test', - project_directory=os.path.join(ARC_TESTING_PATH, 'test_GaussianAdapter'), + project_directory=PROJECT_DIR, species=[spc_11], testing=True, args=args @@ -412,7 +414,7 @@ def setUpClass(cls): fine=True, ess_trsh_methods=ess_trsh_methods, project='test', - project_directory=os.path.join(ARC_TESTING_PATH, 'test_GaussianAdapter'), + project_directory=PROJECT_DIR, species=[spc_11], testing=True, args=args @@ -434,7 +436,7 @@ def setUpClass(cls): fine=True, ess_trsh_methods=ess_trsh_methods, project='test', - project_directory=os.path.join(ARC_TESTING_PATH, 'test_GaussianAdapter'), + project_directory=PROJECT_DIR, species=[spc_11], testing=True, args=args @@ -457,7 +459,7 @@ def setUpClass(cls): fine=True, ess_trsh_methods=ess_trsh_methods, project='test', - project_directory=os.path.join(ARC_TESTING_PATH, 'test_GaussianAdapter'), + project_directory=PROJECT_DIR, species=[spc_11], testing=True, args=args @@ -480,7 +482,7 @@ def setUpClass(cls): fine=True, ess_trsh_methods=ess_trsh_methods, project='test', - project_directory=os.path.join(ARC_TESTING_PATH, 'test_GaussianAdapter'), + project_directory=PROJECT_DIR, species=[spc_11], testing=True, args=args @@ -504,7 +506,7 @@ def setUpClass(cls): fine=True, ess_trsh_methods=ess_trsh_methods, project='test', - project_directory=os.path.join(ARC_TESTING_PATH, 'test_GaussianAdapter'), + project_directory=PROJECT_DIR, species=[spc_11], testing=True, args=args @@ -537,7 +539,7 @@ def test_set_input_file_memory_with_headroom_marker(self): job_type='opt', level=Level(method='wb97xd', basis='def2tzvp'), project='test', - project_directory=os.path.join(ARC_TESTING_PATH, 'test_GaussianAdapter'), + project_directory=PROJECT_DIR, species=[ARCSpecies(label='spc_headroom', xyz=['O 0 0 1'], multiplicity=3)], testing=True, ess_trsh_methods=ess_trsh_methods, @@ -553,7 +555,7 @@ def test_memory_headroom_marker_not_in_trsh_keyword(self): job_type='opt', level=Level(method='wb97xd', basis='def2tzvp'), project='test', - project_directory=os.path.join(ARC_TESTING_PATH, 'test_GaussianAdapter'), + project_directory=PROJECT_DIR, species=[ARCSpecies(label='spc_headroom_marker', xyz=['O 0 0 1'], multiplicity=3)], testing=True, ess_trsh_methods=['memory_headroom_0.6'], @@ -1214,7 +1216,7 @@ def test_user_keyword_args_survive_a_level_round_trip(self): job_type='opt', level=rebuilt_level, project='test', - project_directory=os.path.join(ARC_TESTING_PATH, 'test_GaussianAdapter'), + project_directory=PROJECT_DIR, species=[ARCSpecies(label='spc1', xyz=['O 0 0 1'], multiplicity=3)], testing=True, ) @@ -1231,7 +1233,7 @@ def tearDownClass(cls): A function that is run ONCE after all unit tests in this class. Delete all project directories created during these unit tests. """ - shutil.rmtree(os.path.join(ARC_TESTING_PATH, 'test_GaussianAdapter'), ignore_errors=True) + shutil.rmtree(PROJECT_DIR, ignore_errors=True) class TestGetMemoryHeadroomFraction(unittest.TestCase): diff --git a/arc/job/adapters/molpro_test.py b/arc/job/adapters/molpro_test.py index 9649875558..c08fecdf0b 100644 --- a/arc/job/adapters/molpro_test.py +++ b/arc/job/adapters/molpro_test.py @@ -9,7 +9,7 @@ import shutil import unittest -from arc.common import ARC_TESTING_PATH +from arc.common import ARC_TESTING_PATH, get_test_project_name from arc.job.adapters.molpro import MolproAdapter from arc.level import Level from arc.settings.settings import input_filenames, output_filenames @@ -30,7 +30,8 @@ def setUpClass(cls): job_type='sp', level=Level(method='CCSD(T)-F12', basis='cc-pVTZ-f12'), project='test', - project_directory=os.path.join(ARC_TESTING_PATH, 'test_MolproAdapter_1'), + project_directory=os.path.join( + ARC_TESTING_PATH, get_test_project_name('test_MolproAdapter_1')), species=[ARCSpecies(label='spc1', xyz=['O 0 0 1'], multiplicity=3)], testing=True, ) @@ -38,7 +39,8 @@ def setUpClass(cls): job_type='opt', level=Level(method='CCSD(T)', basis='cc-pVQZ'), project='test', - project_directory=os.path.join(ARC_TESTING_PATH, 'test_MolproAdapter_2'), + project_directory=os.path.join( + ARC_TESTING_PATH, get_test_project_name('test_MolproAdapter_2')), species=[ARCSpecies(label='spc1', xyz=['O 0 0 1'], multiplicity=3)], testing=True, ) @@ -46,7 +48,8 @@ def setUpClass(cls): job_type='sp', level=Level(method='MRCI', basis='aug-cc-pvtz-f12'), project='test', - project_directory=os.path.join(ARC_TESTING_PATH, 'test_MolproAdapter_3'), + project_directory=os.path.join( + ARC_TESTING_PATH, get_test_project_name('test_MolproAdapter_3')), species=[ARCSpecies(label='HNO_t', xyz=["""N -0.08142 0.37454 0.00000 O 1.01258 -0.17285 0.00000 H -0.93116 -0.20169 0.00000"""], @@ -57,7 +60,8 @@ def setUpClass(cls): job_type='sp', level=Level(method='MRCI-F12', basis='aug-cc-pvtz-f12'), project='test', - project_directory=os.path.join(ARC_TESTING_PATH, 'test_MolproAdapter_4'), + project_directory=os.path.join( + ARC_TESTING_PATH, get_test_project_name('test_MolproAdapter_4')), species=[ARCSpecies(label='HNO_t', xyz=["""N -0.08142 0.37454 0.00000 O 1.01258 -0.17285 0.00000 H -0.93116 -0.20169 0.00000"""], @@ -68,7 +72,8 @@ def setUpClass(cls): job_type='sp', level=Level(method='MP2_CASSCF_MRCI-F12', basis='aug-cc-pVTZ-F12'), project='test', - project_directory=os.path.join(ARC_TESTING_PATH, 'test_MolproAdapter_5'), + project_directory=os.path.join( + ARC_TESTING_PATH, get_test_project_name('test_MolproAdapter_5')), species=[ARCSpecies(label='HNO_t', xyz=["""N -0.08142 0.37454 0.00000 O 1.01258 -0.17285 0.00000 H -0.93116 -0.20169 0.00000"""], @@ -79,7 +84,8 @@ def setUpClass(cls): job_type='sp', level=Level(method='MP2_CASSCF_RS2C', basis='aug-cc-pVTZ'), # CASPT2 project='test', - project_directory=os.path.join(ARC_TESTING_PATH, 'test_MolproAdapter_6'), + project_directory=os.path.join( + ARC_TESTING_PATH, get_test_project_name('test_MolproAdapter_6')), species=[ARCSpecies(label='HNO_t', xyz=["""N -0.08142 0.37454 0.00000 O 1.01258 -0.17285 0.00000 H -0.93116 -0.20169 0.00000"""], @@ -90,7 +96,8 @@ def setUpClass(cls): job_type='sp', level=Level(method='MP2_CASSCF_RS2C', basis='aug-cc-pVTZ'), # CASPT2 project='test', - project_directory=os.path.join(ARC_TESTING_PATH, 'test_MolproAdapter_7'), + project_directory=os.path.join( + ARC_TESTING_PATH, get_test_project_name('test_MolproAdapter_7')), species=[ARCSpecies(label='N', xyz=["""N 0.0 0.0 0.0"""], multiplicity=4, active={'occ': [3, 1, 1, 0, 1, 0, 0, 0], diff --git a/arc/job/adapters/orca_test.py b/arc/job/adapters/orca_test.py index c0ce422c89..c4c485beb0 100644 --- a/arc/job/adapters/orca_test.py +++ b/arc/job/adapters/orca_test.py @@ -11,7 +11,7 @@ import shutil import unittest -from arc.common import ARC_TESTING_PATH +from arc.common import ARC_TESTING_PATH, get_test_project_name from arc.job.adapters.orca import (OrcaAdapter, _format_orca_basis, _format_orca_basis_token, @@ -21,6 +21,8 @@ from arc.settings.settings import input_filenames, output_filenames from arc.species import ARCSpecies +PROJECT_DIR = os.path.join(ARC_TESTING_PATH, get_test_project_name('test_OrcaAdapter')) + class TestOrcaAdapter(unittest.TestCase): """ @@ -36,7 +38,7 @@ def setUpClass(cls): job_type='sp', level=Level(method='DLPNO-CCSD(T)', basis='def2-tzvp', auxiliary_basis='def2-tzvp/c'), project='test', - project_directory=os.path.join(ARC_TESTING_PATH, 'test_OrcaAdapter'), + project_directory=PROJECT_DIR, species=[ARCSpecies(label='CH3O', xyz="""C 0.03807240 0.00035621 -0.00484242 O 1.35198769 0.01264937 -0.17195885 @@ -50,7 +52,7 @@ def setUpClass(cls): level=Level(method='DLPNO-CCSD(T)', basis='def2-tzvp', auxiliary_basis='def2-tzvp/c', solvation_method='SMD', solvent='DMSO'), project='test', - project_directory=os.path.join(ARC_TESTING_PATH, 'test_OrcaAdapter'), + project_directory=PROJECT_DIR, species=[ARCSpecies(label='CH3O', xyz="""C 0.03807240 0.00035621 -0.00484242 O 1.35198769 0.01264937 -0.17195885 @@ -64,7 +66,7 @@ def setUpClass(cls): level=Level(method='DLPNO-CCSD(T)', basis='def2-tzvp', auxiliary_basis='def2-tzvp/c', solvation_method='cpcm', solvent='water'), project='test', - project_directory=os.path.join(ARC_TESTING_PATH, 'test_OrcaAdapter'), + project_directory=PROJECT_DIR, species=[ARCSpecies(label='CH3O', xyz="""C 0.03807240 0.00035621 -0.00484242 O 1.35198769 0.01264937 -0.17195885 @@ -77,7 +79,7 @@ def setUpClass(cls): job_type='sp', level=Level(method='MP2_CASSCF_MRCI', basis='aug-cc-pVTZ'), project='test4', - project_directory=os.path.join(ARC_TESTING_PATH, 'test_OrcaAdapter'), + project_directory=PROJECT_DIR, species=[ARCSpecies(label='CH3O', active=(14, 7), xyz="""C 0.03807240 0.00035621 -0.00484242 @@ -197,7 +199,7 @@ def test_write_input_file_f12_with_cabs(self): auxiliary_basis='aug-cc-pVTZ/C', cabs='cc-pVTZ-F12-CABS'), project='test_f12', - project_directory=os.path.join(ARC_TESTING_PATH, 'test_OrcaAdapter'), + project_directory=PROJECT_DIR, species=[ARCSpecies(label='O_atom', smiles='[O]', xyz='O 0.0 0.0 0.0')], testing=True, @@ -223,7 +225,7 @@ def test_write_input_file_f12_without_cabs_raises(self): basis='cc-pVTZ-F12', auxiliary_basis='aug-cc-pVTZ/C'), project='test_f12_bad', - project_directory=os.path.join(ARC_TESTING_PATH, 'test_OrcaAdapter'), + project_directory=PROJECT_DIR, species=[ARCSpecies(label='O_atom', smiles='[O]', xyz='O 0.0 0.0 0.0')], testing=True, @@ -321,7 +323,7 @@ def test_dft_grid_regular_opt(self): job_type='opt', level=Level(method='wb97x-d3', basis='def2-tzvp'), project='test_dft_grid', - project_directory=os.path.join(ARC_TESTING_PATH, 'test_OrcaAdapter'), + project_directory=PROJECT_DIR, species=[ARCSpecies(label='CH3O', xyz="""C 0.03807240 0.00035621 -0.00484242 O 1.35198769 0.01264937 -0.17195885 @@ -343,7 +345,7 @@ def test_dft_grid_fine_opt(self): job_type='opt', level=Level(method='wb97x-d3', basis='def2-tzvp'), project='test_dft_grid_fine', - project_directory=os.path.join(ARC_TESTING_PATH, 'test_OrcaAdapter'), + project_directory=PROJECT_DIR, species=[ARCSpecies(label='CH3O', xyz="""C 0.03807240 0.00035621 -0.00484242 O 1.35198769 0.01264937 -0.17195885 @@ -364,7 +366,7 @@ def test_dft_grid_freq(self): job_type='freq', level=Level(method='wb97x-d3', basis='def2-tzvp'), project='test_dft_grid_freq', - project_directory=os.path.join(ARC_TESTING_PATH, 'test_OrcaAdapter'), + project_directory=PROJECT_DIR, species=[ARCSpecies(label='CH3O', xyz="""C 0.03807240 0.00035621 -0.00484242 O 1.35198769 0.01264937 -0.17195885 @@ -385,7 +387,7 @@ def test_dft_grid_optfreq(self): job_type='optfreq', level=Level(method='wb97x-d3', basis='def2-tzvp'), project='test_dft_grid_optfreq', - project_directory=os.path.join(ARC_TESTING_PATH, 'test_OrcaAdapter'), + project_directory=PROJECT_DIR, species=[ARCSpecies(label='CH3O', xyz="""C 0.03807240 0.00035621 -0.00484242 O 1.35198769 0.01264937 -0.17195885 @@ -406,7 +408,7 @@ def test_fine_opt_convergence_tightopt(self): job_type='opt', level=Level(method='wb97x-d3', basis='def2-tzvp'), project='test_fine_opt_conv', - project_directory=os.path.join(ARC_TESTING_PATH, 'test_OrcaAdapter'), + project_directory=PROJECT_DIR, species=[ARCSpecies(label='CH3O', xyz="""C 0.03807240 0.00035621 -0.00484242 O 1.35198769 0.01264937 -0.17195885 @@ -428,7 +430,7 @@ def test_recalc_hess_in_optts(self): job_type='opt', level=Level(method='wb97x-d3', basis='def2-tzvp'), project='test_optts_hess', - project_directory=os.path.join(ARC_TESTING_PATH, 'test_OrcaAdapter'), + project_directory=PROJECT_DIR, species=[ARCSpecies(label='TS_example', xyz="""C 0.03807240 0.00035621 -0.00484242 O 1.35198769 0.01264937 -0.17195885 @@ -454,7 +456,7 @@ def test_recalc_hess_not_in_regular_opt(self): job_type='opt', level=Level(method='wb97x-d3', basis='def2-tzvp'), project='test_opt_no_hess', - project_directory=os.path.join(ARC_TESTING_PATH, 'test_OrcaAdapter'), + project_directory=PROJECT_DIR, species=[ARCSpecies(label='CH3O', xyz="""C 0.03807240 0.00035621 -0.00484242 O 1.35198769 0.01264937 -0.17195885 @@ -483,7 +485,7 @@ def test_writing_input_does_not_pollute_level_args(self): job_type='opt', level=level, project='test', - project_directory=os.path.join(ARC_TESTING_PATH, 'test_OrcaAdapter'), + project_directory=PROJECT_DIR, species=[ARCSpecies(label='CH3O', xyz="""C 0.03807240 0.00035621 -0.00484242 O 1.35198769 0.01264937 -0.17195885 @@ -503,7 +505,7 @@ def tearDownClass(cls): A function that is run ONCE after all unit tests in this class. Delete all project directories created during these unit tests """ - shutil.rmtree(os.path.join(ARC_TESTING_PATH, 'test_OrcaAdapter'), ignore_errors=True) + shutil.rmtree(PROJECT_DIR, ignore_errors=True) if __name__ == '__main__': diff --git a/arc/job/adapters/ts/orca_neb_test.py b/arc/job/adapters/ts/orca_neb_test.py index 1930c58dc6..0cafd2bab2 100644 --- a/arc/job/adapters/ts/orca_neb_test.py +++ b/arc/job/adapters/ts/orca_neb_test.py @@ -12,7 +12,7 @@ import unittest.mock import pytest -from arc.common import ARC_TESTING_PATH +from arc.common import ARC_TESTING_PATH, get_test_project_name from arc.job.adapters.ts.orca_neb import OrcaNEBAdapter from arc.level import Level from arc.reaction import ARCReaction @@ -31,11 +31,12 @@ def setUpClass(cls): """ cls.maxDiff = None - cls.project_directory = os.path.join(ARC_TESTING_PATH, 'test_OrcaNEBAdapter') + cls.project_directory = os.path.join(ARC_TESTING_PATH, + get_test_project_name('test_OrcaNEBAdapter')) if os.path.exists(cls.project_directory): - shutil.rmtree(cls.project_directory) + shutil.rmtree(cls.project_directory, ignore_errors=True) cls.addClassCleanup(shutil.rmtree, cls.project_directory, ignore_errors=True) - os.makedirs(cls.project_directory) + os.makedirs(cls.project_directory, exist_ok=True) # Mock objects for both orca_neb and orca/adapter modules mock_input_filenames = {'orca_neb': 'input.in', 'orca': 'input.in'} diff --git a/arc/main_test.py b/arc/main_test.py index 64282cc7fc..dcd241a431 100644 --- a/arc/main_test.py +++ b/arc/main_test.py @@ -13,7 +13,7 @@ import unittest from unittest import mock -from arc.common import ARC_PATH, get_logger +from arc.common import get_logger, get_test_project_directory, get_test_project_name from arc.exceptions import InputError from arc.imports import settings from arc.job.adapters.gaussian import GaussianAdapter @@ -51,7 +51,7 @@ def setUpClass(cls): projects = ['arc_project_for_testing_delete_after_usage_test_from_dict', 'arc_model_chemistry_test', 'arc_test', 'test', 'unit_test_specific_job', 'wrong'] for project in projects: - project_directory = os.path.join(ARC_PATH, 'Projects', project) + project_directory = get_test_project_directory(project) if os.path.isdir(project_directory): shutil.rmtree(project_directory, ignore_errors=True) @@ -61,7 +61,7 @@ def test_as_dict(self): smiles='CC', compute_thermo=False, ) - arc0 = ARC(project='arc_test', + arc0 = ARC(project=get_test_project_name('arc_test'), job_types=self.job_types1, species=[spc1], level_of_theory='ccsd(t)-f12/cc-pvdz-f12//b3lyp/6-311+g(3df,2p)', @@ -129,7 +129,7 @@ def test_as_dict(self): 'method': 'b3lyp', 'method_type': 'dft', 'software': 'gaussian'}, - 'project': 'arc_test', + 'project': get_test_project_name('arc_test'), 'sp_level': {'basis': 'cc-pvdz-f12', 'method': 'ccsd(t)-f12', 'method_type': 'wavefunction', @@ -178,10 +178,10 @@ def test_from_dict(self): 'optical_isomers': 1, 'rotors_dict': {}, 'xyzs': []}], - 'project_directory': os.path.join(ARC_PATH, 'Projects', - 'arc_project_for_testing_delete_after_usage_test_from_dict'), + 'project_directory': get_test_project_directory( + 'arc_project_for_testing_delete_after_usage_test_from_dict'), } - arc1 = ARC(project='wrong', freq_scale_factor=0.95) + arc1 = ARC(project=get_test_project_name('wrong'), freq_scale_factor=0.95) self.assertEqual(arc1.freq_scale_factor, 0.95) # user input arc2 = ARC(**restart_dict) self.assertEqual(arc2.freq_scale_factor, 0.96) # loaded from the restart dict @@ -198,8 +198,8 @@ def test_from_dict(self): def test_from_dict_specific_job(self): """Test the from_dict() method of ARC""" restart_dict = {'specific_job_type': 'bde', - 'project': 'unit_test_specific_job', - 'project_directory': os.path.join(ARC_PATH, 'Projects', 'unit_test_specific_job'), + 'project': get_test_project_name('unit_test_specific_job'), + 'project_directory': get_test_project_directory('unit_test_specific_job'), } arc1 = ARC(**restart_dict) job_type_expected = {'conf_opt': False, 'conf_sp': False, 'opt': True, 'freq': True, 'sp': True, 'rotors': False, @@ -219,21 +219,21 @@ def test_check_project_name(self): def test_determine_model_chemistry_and_freq_scale_factor(self): """Test determining the model chemistry and the frequency scaling factor""" - arc0 = ARC(project='arc_model_chemistry_test', level_of_theory='CBS-QB3') + arc0 = ARC(project=get_test_project_name('arc_model_chemistry_test'), level_of_theory='CBS-QB3') self.assertEqual(str(arc0.arkane_level_of_theory), "cbs-qb3, software: gaussian") self.assertEqual(arc0.freq_scale_factor, 1.004) - arc1 = ARC(project='arc_model_chemistry_test', level_of_theory='cbs-qb3-paraskevas') + arc1 = ARC(project=get_test_project_name('arc_model_chemistry_test'), level_of_theory='cbs-qb3-paraskevas') self.assertEqual(str(arc1.arkane_level_of_theory), 'cbs-qb3-paraskevas, software: gaussian') self.assertEqual(arc1.freq_scale_factor, 1.004) self.assertEqual(arc1.bac_type, 'p') - arc2 = ARC(project='arc_model_chemistry_test', + arc2 = ARC(project=get_test_project_name('arc_model_chemistry_test'), level_of_theory='ccsd(t)-f12/cc-pvtz-f12//m062x/cc-pvtz') self.assertEqual(str(arc2.arkane_level_of_theory), 'ccsd(t)-f12/cc-pvtz-f12, software: molpro') self.assertEqual(arc2.freq_scale_factor, 0.955) - arc3 = ARC(project='arc_model_chemistry_test', + arc3 = ARC(project=get_test_project_name('arc_model_chemistry_test'), sp_level='ccsd(t)-f12/cc-pvtz-f12', opt_level='wb97xd/def2tzvp') self.assertEqual(str(arc3.arkane_level_of_theory), 'ccsd(t)-f12/cc-pvtz-f12, software: molpro') self.assertEqual(arc3.freq_scale_factor, 0.988) @@ -242,33 +242,33 @@ def test_determine_model_chemistry_for_job_types(self): """Test determining the model chemistry specification dictionary for job types""" # Test conflicted inputs: specify both level_of_theory and composite_method with self.assertRaises(InputError): - ARC(project='test', level_of_theory='ccsd(t)-f12/cc-pvtz-f12//wb97x-d/aug-cc-pvtz', + ARC(project=get_test_project_name('test'), level_of_theory='ccsd(t)-f12/cc-pvtz-f12//wb97x-d/aug-cc-pvtz', composite_method='cbs-qb3') # Test illegal level of theory specification (method contains multiple slashes) with self.assertRaises(ValueError): - ARC(project='test', level_of_theory='dlpno-mp2-f12/D/cc-pVDZ(fi/sf/fw)//b3lyp/G/def2svp') + ARC(project=get_test_project_name('test'), level_of_theory='dlpno-mp2-f12/D/cc-pVDZ(fi/sf/fw)//b3lyp/G/def2svp') # Test illegal job level specification (method contains multiple slashes) with self.assertRaises(ValueError): - ARC(project='test', opt_level='b3lyp/d/def2tzvp/def2tzvp/c') + ARC(project=get_test_project_name('test'), opt_level='b3lyp/d/def2tzvp/def2tzvp/c') # Test illegal job level specification (method contains empty space) with self.assertRaises(ValueError): - ARC(project='test', opt_level='b3lyp/def2tzvp def2tzvp/c') + ARC(project=get_test_project_name('test'), opt_level='b3lyp/def2tzvp def2tzvp/c') # Test direct job level specification conflicts with level of theory specification with self.assertRaises(InputError): - ARC(project='test', level_of_theory='b3lyp/sto-3g', opt_level='wb97xd/def2tzvp') + ARC(project=get_test_project_name('test'), level_of_theory='b3lyp/sto-3g', opt_level='wb97xd/def2tzvp') # Test deduce levels from default method from settings.py - arc1 = ARC(project='test') + arc1 = ARC(project=get_test_project_name('test')) self.assertEqual(arc1.opt_level.simple(), 'wb97xd/def2tzvp') self.assertEqual(arc1.freq_level.simple(), 'wb97xd/def2tzvp') self.assertEqual(arc1.sp_level.simple(), 'ccsd(t)-f12/cc-pvtz-f12') # Test deduce levels from composite method specification - arc2 = ARC(project='test', composite_method='cbs-qb3') + arc2 = ARC(project=get_test_project_name('test'), composite_method='cbs-qb3') self.assertIsNotNone(arc2.opt_level) self.assertIsNone(arc2.sp_level) self.assertIsNone(arc2.orbitals_level) @@ -277,35 +277,37 @@ def test_determine_model_chemistry_for_job_types(self): self.assertEqual(arc2.composite_method.simple(), 'cbs-qb3') # Test deduce levels from level of theory specification - arc3 = ARC(project='test', level_of_theory='ccsd(t)-f12/cc-pvtz-f12//wb97m-v/def2tzvpd', freq_scale_factor=1) + arc3 = ARC(project=get_test_project_name('test'), freq_scale_factor=1, + level_of_theory='ccsd(t)-f12/cc-pvtz-f12//wb97m-v/def2tzvpd') self.assertEqual(arc3.opt_level.simple(), 'wb97m-v/def2tzvpd') self.assertEqual(arc3.freq_level.simple(), 'wb97m-v/def2tzvpd') self.assertEqual(arc3.sp_level.simple(), 'ccsd(t)-f12/cc-pvtz-f12') self.assertEqual(arc3.scan_level.simple(), 'wb97m-v/def2tzvpd') self.assertIsNone(arc3.orbitals_level) - arc4 = ARC(project='test', opt_level='wb97x-d3/6-311++G(3df,3pd)', freq_level='m062x/def2-tzvpp', + arc4 = ARC(project=get_test_project_name('test'), opt_level='wb97x-d3/6-311++G(3df,3pd)', freq_level='m062x/def2-tzvpp', sp_level='ccsd(t)f12/aug-cc-pvqz', calc_freq_factor=False, compute_thermo=False) self.assertEqual(arc4.opt_level.simple(), 'wb97x-d3/6-311++g(3df,3pd)') self.assertEqual(arc4.freq_level.simple(), 'm062x/def2-tzvpp') self.assertEqual(arc4.sp_level.simple(), 'ccsd(t)f12/aug-cc-pvqz') # Test deduce freq level from opt level - arc7 = ARC(project='test', opt_level='wb97xd/aug-cc-pvtz', calc_freq_factor=False) + arc7 = ARC(project=get_test_project_name('test'), opt_level='wb97xd/aug-cc-pvtz', calc_freq_factor=False) self.assertEqual(arc7.opt_level.simple(), 'wb97xd/aug-cc-pvtz') self.assertEqual(arc7.freq_level.simple(), 'wb97xd/aug-cc-pvtz') # Test a level not supported by Arkane does not raise error if compute_thermo is False - arc8 = ARC(project='test', sp_level='method/unsupported', calc_freq_factor=False, compute_thermo=False) + arc8 = ARC(project=get_test_project_name('test'), sp_level='method/unsupported', + calc_freq_factor=False, compute_thermo=False) self.assertEqual(arc8.sp_level.simple(), 'method/unsupported') self.assertEqual(arc8.freq_level.simple(), 'wb97xd/def2tzvp') # Test that a level not supported by Arkane does raise an error if compute_thermo is True (default) with self.assertRaises(ValueError): - ARC(project='test', sp_level='method/unsupported', calc_freq_factor=False) + ARC(project=get_test_project_name('test'), sp_level='method/unsupported', calc_freq_factor=False) # Test dictionary format specification with auxiliary basis and DFT dispersion - arc9 = ARC(project='test', opt_level={}, + arc9 = ARC(project=get_test_project_name('test'), opt_level={}, freq_level={'method': 'B3LYP/G', 'basis': 'cc-pVDZ(fi/sf/fw)', 'auxiliary_basis': 'def2-svp/C', 'dispersion': 'DEF2-tzvp/c'}, sp_level={'method': 'DLPNO-CCSD(T)-F12', 'basis': 'cc-pVTZ-F12', @@ -319,40 +321,42 @@ def test_determine_model_chemistry_for_job_types(self): 'cabs: cc-pvtz-f12-cabs, software: orca') # Test using default frequency and orbital level for composite job, also forbid rotors job - arc10 = ARC(project='test', composite_method='cbs-qb3', calc_freq_factor=False, + arc10 = ARC(project=get_test_project_name('test'), composite_method='cbs-qb3', calc_freq_factor=False, job_types={'rotors': False, 'orbitals': True}) self.assertEqual(arc10.freq_level.simple(), 'b3lyp/cbsb7') self.assertIsNone(arc10.scan_level) self.assertEqual(arc10.orbitals_level.simple(), 'b3lyp/cbsb7') # Test using specified frequency, scan, and orbital for composite job - arc11 = ARC(project='test', composite_method='cbs-qb3', freq_level='wb97xd/6-311g', scan_level='apfd/def2svp', + arc11 = ARC(project=get_test_project_name('test'), composite_method='cbs-qb3', + freq_level='wb97xd/6-311g', scan_level='apfd/def2svp', orbitals_level='hf/sto-3g', job_types={'orbitals': True}, calc_freq_factor=False) self.assertEqual(arc11.scan_level.simple(), 'apfd/def2svp') self.assertEqual(arc11.freq_level.simple(), 'wb97xd/6-311g') self.assertEqual(arc11.orbitals_level.simple(), 'hf/sto-3g') # Test using default frequency and orbital level for job specified from level of theory, also forbid rotors job - arc12 = ARC(project='test', level_of_theory='b3lyp/sto-3g', calc_freq_factor=False, + arc12 = ARC(project=get_test_project_name('test'), level_of_theory='b3lyp/sto-3g', calc_freq_factor=False, job_types={'rotors': False, 'orbitals': True}, compute_thermo=False) self.assertIsNone(arc12.scan_level) self.assertEqual(arc12.freq_level.simple(), 'b3lyp/sto-3g') self.assertEqual(arc12.orbitals_level.simple(), 'wb97x-d3/def2tzvp') # Test using specified scan level - arc13 = ARC(project='test', level_of_theory='b3lyp/sto-3g', calc_freq_factor=False, scan_level='apfd/def2svp', + arc13 = ARC(project=get_test_project_name('test'), level_of_theory='b3lyp/sto-3g', + calc_freq_factor=False, scan_level='apfd/def2svp', job_types={'rotors': True}, compute_thermo=False) self.assertEqual(arc13.scan_level.simple(), 'apfd/def2svp') # Test specifying semi-empirical and force-field methods using dictionary - arc14 = ARC(project='test', opt_level={'method': 'AM1'}, freq_level={'method': 'PM6'}, + arc14 = ARC(project=get_test_project_name('test'), opt_level={'method': 'AM1'}, freq_level={'method': 'PM6'}, sp_level={'method': 'AMBER'}, calc_freq_factor=False, compute_thermo=False) self.assertEqual(arc14.opt_level.simple(), 'am1') self.assertEqual(arc14.freq_level.simple(), 'pm6') self.assertEqual(arc14.sp_level.simple(), 'amber') # Test explicit year in arkane_level_of_theory dictionary - arc15 = ARC(project='test', + arc15 = ARC(project=get_test_project_name('test'), sp_level='wb97xd/def2tzvp', opt_level='wb97xd/def2tzvp', arkane_level_of_theory={'method': 'wb97xd', 'basis': 'def2tzvp', 'year': 2023}, @@ -361,7 +365,7 @@ def test_determine_model_chemistry_for_job_types(self): self.assertEqual(arc15.arkane_level_of_theory.year, 2023) # Test warning when year is specified on sp_level instead of arkane_level_of_theory - arc16 = ARC(project='test', + arc16 = ARC(project=get_test_project_name('test'), sp_level={'method': 'wb97xd', 'basis': 'def2tzvp', 'year': 2023}, opt_level='wb97xd/def2tzvp', calc_freq_factor=False, compute_thermo=False) @@ -374,7 +378,7 @@ def test_determine_unique_species_labels(self): spc0 = ARCSpecies(label='spc0', smiles='CC', compute_thermo=False) spc1 = ARCSpecies(label='spc1', smiles='CC', compute_thermo=False) spc2 = ARCSpecies(label='spc2', smiles='CC', compute_thermo=False) - arc0 = ARC(project='arc_test', job_types=self.job_types1, species=[spc0, spc1, spc2], + arc0 = ARC(project=get_test_project_name('arc_test'), job_types=self.job_types1, species=[spc0, spc1, spc2], level_of_theory='ccsd(t)-f12/cc-pvdz-f12//b3lyp/6-311+g(3df,2p)') self.assertEqual(arc0.unique_species_labels, ['spc0', 'spc1', 'spc2']) spc3 = ARCSpecies(label='spc0', smiles='CC', compute_thermo=False) @@ -385,13 +389,13 @@ def test_determine_unique_species_labels(self): def test_add_hydrogen_for_bde(self): """Test the add_hydrogen_for_bde method""" spc0 = ARCSpecies(label='spc0', smiles='CC', compute_thermo=False) - arc0 = ARC(project='arc_test', job_types=self.job_types1, species=[spc0], + arc0 = ARC(project=get_test_project_name('arc_test'), job_types=self.job_types1, species=[spc0], level_of_theory='ccsd(t)-f12/cc-pvdz-f12//b3lyp/6-311+g(3df,2p)') arc0.add_hydrogen_for_bde() self.assertEqual(len(arc0.species), 1) spc1 = ARCSpecies(label='spc1', smiles='CC', compute_thermo=False, bdes=['all_h']) - arc1 = ARC(project='arc_test', job_types=self.job_types1, species=[spc1], + arc1 = ARC(project=get_test_project_name('arc_test'), job_types=self.job_types1, species=[spc1], level_of_theory='ccsd(t)-f12/cc-pvdz-f12//b3lyp/6-311+g(3df,2p)') arc1.add_hydrogen_for_bde() self.assertEqual(len(arc1.species), 2) @@ -512,12 +516,12 @@ def test_unknown_ts_adapter(self): compute_thermo=False, ) with self.assertRaises(InputError): - arc0 = ARC(project='arc_test', - job_types=self.job_types1, - species=[spc1], - level_of_theory='ccsd(t)-f12/cc-pvdz-f12//b3lyp/6-311+g(3df,2p)', - ts_adapters=['WRONG ADAPTER', 'AutoTST', 'GCN', 'xtb_gsm'], - ) + ARC(project=get_test_project_name('arc_test'), + job_types=self.job_types1, + species=[spc1], + level_of_theory='ccsd(t)-f12/cc-pvdz-f12//b3lyp/6-311+g(3df,2p)', + ts_adapters=['WRONG ADAPTER', 'AutoTST', 'GCN', 'xtb_gsm'], + ) @classmethod def tearDownClass(cls): @@ -528,7 +532,7 @@ def tearDownClass(cls): projects = ['arc_project_for_testing_delete_after_usage_test_from_dict', 'arc_model_chemistry_test', 'arc_test', 'test', 'unit_test_specific_job', 'wrong'] for project in projects: - project_directory = os.path.join(ARC_PATH, 'Projects', project) + project_directory = get_test_project_directory(project) if os.path.isdir(project_directory): shutil.rmtree(project_directory, ignore_errors=True) diff --git a/arc/plotter_test.py b/arc/plotter_test.py index ba6984dae4..cc341a4152 100644 --- a/arc/plotter_test.py +++ b/arc/plotter_test.py @@ -10,7 +10,7 @@ import unittest import arc.plotter as plotter -from arc.common import ARC_PATH, ARC_TESTING_PATH, read_yaml_file, safe_copy_file +from arc.common import ARC_TESTING_PATH, get_test_project_directory, read_yaml_file, safe_copy_file from arc.species.converter import str_to_xyz from arc.species.species import ARCSpecies @@ -31,8 +31,7 @@ def test_save_geo(self): H -1.16115119 0.31478894 0.81506145 H -1.16115119 0.31478894 -0.81506145""") spc.opt_level = 'opt/level' - project = 'arc_project_for_testing_delete_after_usage' - project_directory = os.path.join(ARC_PATH, 'Projects', project) + project_directory = get_test_project_directory('arc_project_for_testing_delete_after_usage') xyz_path = os.path.join(project_directory, 'output', 'Species', spc.label, 'geometry', 'methylamine.xyz') gjf_path = os.path.join(project_directory, 'output', 'Species', spc.label, 'geometry', 'methylamine.gjf') plotter.save_geo(species=spc, project_directory=project_directory) @@ -68,8 +67,7 @@ def test_save_geo(self): def test_augment_arkane_yml_file_with_mol_repr(self): """Test the augment_arkane_yml_file_with_mol_repr() function""" - project = 'arc_project_for_testing_delete_after_usage' - project_directory = os.path.join(ARC_PATH, 'Projects', project) + project_directory = get_test_project_directory('arc_project_for_testing_delete_after_usage') n4h6_yml_path = os.path.join(ARC_TESTING_PATH, 'yml_testing', 'N4H6.yml') n4h6_yml_path_copy = os.path.join(project_directory, 'Species', 'N4H6', 'N4H6.yml') os.makedirs(os.path.join(project_directory, 'Species', 'N4H6'), exist_ok=True) @@ -83,8 +81,7 @@ def test_augment_arkane_yml_file_with_mol_repr(self): def test_save_conformers_file(self): """test the save_conformers_file function""" - project = 'arc_project_for_testing_delete_after_usage' - project_directory = os.path.join(ARC_PATH, 'Projects', project) + project_directory = get_test_project_directory('arc_project_for_testing_delete_after_usage') label = 'butanol' spc1 = ARCSpecies(label=label, smiles='CCCCO') spc1.generate_conformers(n_confs=3) @@ -100,11 +97,11 @@ def test_save_conformers_file(self): def test_save_rotor_text_file(self): """Test the save_rotor_text_file function""" - project = 'arc_project_for_testing_delete_after_usage' + project_directory = get_test_project_directory('arc_project_for_testing_delete_after_usage') angles = [0, 90, 180, 270, 360] energies = [0, 10, 0, 10, 0] pivots = [1, 2] - path = os.path.join(ARC_PATH, 'Projects', project, 'rotors', '{0}_directed_scan.txt'.format(pivots)) + path = os.path.join(project_directory, 'rotors', '{0}_directed_scan.txt'.format(pivots)) plotter.save_rotor_text_file(angles, energies, path) self.assertTrue(os.path.isfile(path)) with open(path, 'r') as f: @@ -113,7 +110,9 @@ def test_save_rotor_text_file(self): def test_log_bde_report(self): """Test the log_bde_report() function""" - path = os.path.join(ARC_TESTING_PATH, 'bde_report_test.txt') + project_directory = get_test_project_directory('arc_project_for_testing_delete_after_usage') + os.makedirs(project_directory, exist_ok=True) + path = os.path.join(project_directory, 'bde_report_test.txt') bde_report = {'aniline': {(1, 2): 431.43, (5, 8): 465.36, (6, 9): 458.70, (3, 10): 463.16, (4, 11): 463.16, (7, 12): 458.70, (1, 13): 372.31, (1, 14): 372.31, (5, 6): 'N/A'}} xyz = """N 2.28116100 -0.20275000 -0.29653100 @@ -178,42 +177,52 @@ def test_clean_scan_results(self): def test_make_multi_species_output_file(self): """Test the make_multi_species_output_file function""" # The xyzs used in the ARCSpecies are dummy xyzs, they are not the actual xyzs used in the output file + output_folder = os.path.join(get_test_project_directory('arc_project_for_testing_delete_after_usage'), 'mltspc') + os.makedirs(output_folder, exist_ok=True) + path = os.path.join(output_folder, 'mltspc_output.out') + safe_copy_file(source=os.path.join(ARC_TESTING_PATH, 'mltspc_output.out'), destination=path) plotter.make_multi_species_output_file(species_list=[ARCSpecies(label='water', smiles='O', multi_species='mltspc1'), ARCSpecies(label='acetylene', smiles='C#C', multi_species='mltspc1'), ARCSpecies(label='N-Valeric_Acid', smiles='CCCCC(O)=O', multi_species='mltspc1')], label='mltspc1', - path=os.path.join(ARC_TESTING_PATH, 'mltspc_output.out'), + path=path, ) - self.assertTrue(os.path.isfile(os.path.join(ARC_TESTING_PATH, 'water.log'))) - self.assertTrue(os.path.isfile(os.path.join(ARC_TESTING_PATH, 'acetylene.log'))) - self.assertTrue(os.path.isfile(os.path.join(ARC_TESTING_PATH, 'N-Valeric_Acid.log'))) + self.assertTrue(os.path.isfile(os.path.join(output_folder, 'water.log'))) + self.assertTrue(os.path.isfile(os.path.join(output_folder, 'acetylene.log'))) + self.assertTrue(os.path.isfile(os.path.join(output_folder, 'N-Valeric_Acid.log'))) def test_delete_multi_species_output_file(self): """Test the delete_multi_species_output_file function""" # The xyzs used in the ARCSpecies are dummy xyzs, they are not the actual xyzs used in the output file + output_folder = os.path.join(get_test_project_directory('arc_project_for_testing_delete_after_usage'), 'mltspc') + os.makedirs(output_folder, exist_ok=True) + path = os.path.join(output_folder, 'mltspc_output.out') + safe_copy_file(source=os.path.join(ARC_TESTING_PATH, 'mltspc_output.out'), destination=path) species_list = [ARCSpecies(label='water', smiles='O', multi_species='mltspc1'), ARCSpecies(label='acetylene', smiles='C#C', multi_species='mltspc1'), ARCSpecies(label='N-Valeric_Acid', smiles='CCCCC(O)=O', multi_species='mltspc1')] multi_species_path_dict = plotter.make_multi_species_output_file(species_list=species_list, label='mltspc1', - path=os.path.join(ARC_TESTING_PATH, 'mltspc_output.out'), + path=path, ) - self.assertTrue(os.path.isfile(os.path.join(ARC_TESTING_PATH, 'water.log'))) - self.assertTrue(os.path.isfile(os.path.join(ARC_TESTING_PATH, 'acetylene.log'))) - self.assertTrue(os.path.isfile(os.path.join(ARC_TESTING_PATH, 'N-Valeric_Acid.log'))) + self.assertTrue(os.path.isfile(os.path.join(output_folder, 'water.log'))) + self.assertTrue(os.path.isfile(os.path.join(output_folder, 'acetylene.log'))) + self.assertTrue(os.path.isfile(os.path.join(output_folder, 'N-Valeric_Acid.log'))) plotter.delete_multi_species_output_file(species_list=species_list, label='mltspc1', multi_species_path_dict=multi_species_path_dict, ) - self.assertFalse(os.path.isfile(os.path.join(ARC_TESTING_PATH, 'water.log'))) - self.assertFalse(os.path.isfile(os.path.join(ARC_TESTING_PATH, 'acetylene.log'))) - self.assertFalse(os.path.isfile(os.path.join(ARC_TESTING_PATH, 'N-Valeric_Acid.log'))) + self.assertFalse(os.path.isfile(os.path.join(output_folder, 'water.log'))) + self.assertFalse(os.path.isfile(os.path.join(output_folder, 'acetylene.log'))) + self.assertFalse(os.path.isfile(os.path.join(output_folder, 'N-Valeric_Acid.log'))) def test_save_irc_traj_animation(self): """Test the save_irc_traj_animation function""" + project_directory = get_test_project_directory('arc_project_for_testing_delete_after_usage') irc_f_path = os.path.join(ARC_TESTING_PATH, 'irc', 'rxn_1_irc_1.out') irc_r_path = os.path.join(ARC_TESTING_PATH, 'irc', 'rxn_1_irc_2.out') - out_path = os.path.join(ARC_TESTING_PATH, 'irc', 'rxn_1_irc_animation.out') + out_path = os.path.join(project_directory, 'irc', 'rxn_1_irc_animation.out') + os.makedirs(os.path.dirname(out_path), exist_ok=True) self.assertFalse(os.path.isfile(out_path)) plotter.save_irc_traj_animation(irc_f_path, irc_r_path, out_path) self.assertTrue(os.path.isfile(out_path)) @@ -222,18 +231,8 @@ def test_save_irc_traj_animation(self): @classmethod def tearDownClass(cls): """A function that is run ONCE after all unit tests in this class.""" - project = 'arc_project_for_testing_delete_after_usage' - project_directory = os.path.join(ARC_PATH, 'Projects', project) + project_directory = get_test_project_directory('arc_project_for_testing_delete_after_usage') shutil.rmtree(project_directory, ignore_errors=True) - files_to_remove = [os.path.join(ARC_TESTING_PATH, 'bde_report_test.txt'), - os.path.join(ARC_TESTING_PATH, 'water.log'), - os.path.join(ARC_TESTING_PATH, 'acetylene.log'), - os.path.join(ARC_TESTING_PATH, 'N-Valeric_Acid.log'), - os.path.join(ARC_TESTING_PATH, 'irc', 'rxn_1_irc_animation.out'), - ] - for file_path in files_to_remove: - if os.path.isfile(file_path): - os.remove(file_path) if __name__ == '__main__': diff --git a/arc/scheduler_test.py b/arc/scheduler_test.py index d241ebf06e..032d34dcaf 100644 --- a/arc/scheduler_test.py +++ b/arc/scheduler_test.py @@ -14,7 +14,13 @@ import arc.parser.parser as parser from arc.checks.ts import check_ts -from arc.common import ARC_PATH, ARC_TESTING_PATH, almost_equal_coords_lists, initialize_job_types, read_yaml_file +from arc.common import (ARC_PATH, + ARC_TESTING_PATH, + almost_equal_coords_lists, + get_test_project_directory, + initialize_job_types, + read_yaml_file, + ) from arc.job.adapters.common import default_incore_adapters, ts_adapters_by_rmg_family, ts_adapters_for_unknown_unimolecular from arc.job.factory import job_factory from arc.level import Level @@ -82,7 +88,7 @@ def setUpClass(cls): """ cls.maxDiff = None cls.ess_settings = {'gaussian': ['server1'], 'molpro': ['server2', 'server1'], 'qchem': ['server1']} - cls.project_directory = os.path.join(ARC_PATH, 'Projects', 'arc_project_for_testing_delete_after_usage3') + cls.project_directory = get_test_project_directory('arc_project_for_testing_delete_after_usage3') xyz1 = str_to_xyz("""C -0.57422867 -0.01669771 0.01229213 N 0.82084044 0.08279104 -0.37769346 H -1.05737005 -0.84067772 -0.52007494 @@ -745,7 +751,7 @@ def test_check_rxn_e0_by_spc(self): 'job_types': {'conf_opt': True, 'conf_sp': False, 'opt': True, 'freq': True, 'sp': True, 'rotors': True, 'irc': True, 'fine': True}, }, } - project_directory = os.path.join(ARC_PATH, 'Projects', 'arc_project_for_testing_delete_after_usage6') + project_directory = get_test_project_directory('arc_project_for_testing_delete_after_usage6') os.makedirs(os.path.join(project_directory, 'output', 'Species', 'nC3H7', 'geometry'), exist_ok=True) os.makedirs(os.path.join(project_directory, 'output', 'Species', 'iC3H7', 'geometry'), exist_ok=True) os.makedirs(os.path.join(project_directory, 'output', 'rxns', 'TS0', 'geometry'), exist_ok=True) @@ -757,7 +763,7 @@ def test_check_rxn_e0_by_spc(self): dst=os.path.join(project_directory, 'output', 'rxns', 'TS0', 'geometry', 'freq.out')) sched = Scheduler(project='test_rxn_e0_check', ess_settings=self.ess_settings, - project_directory=os.path.join(ARC_PATH, 'Projects', 'arc_project_for_testing_delete_after_usage6'), + project_directory=get_test_project_directory('arc_project_for_testing_delete_after_usage6'), rxn_list=[rxn], species_list=rxn.r_species + rxn.p_species + [rxn.ts_species], kinetics_adapter='arkane', @@ -774,9 +780,7 @@ def test_check_rxn_e0_by_spc(self): job_type='freq', level=Level(repr='B3LYP/6-31G(d,p)'), project='test_project', - project_directory=os.path.join(ARC_PATH, - 'Projects', - 'arc_project_for_testing_delete_after_usage6'), + project_directory=get_test_project_directory('arc_project_for_testing_delete_after_usage6'), ) job_1.local_path_to_output_file = os.path.join(ARC_TESTING_PATH, 'freq', 'TS_nC3H7-iC3H7.out') check_ts(reaction=rxn, verbose=True, job=job_1, checks=['NMD']) @@ -903,7 +907,7 @@ def test_record_tsg_job_error(self): ts_spc.ts_guesses = [TSGuess(index=0, method='GCN', success=False), TSGuess(index=1, method='xTB-GSM', success=False), ] - project_directory = os.path.join(ARC_PATH, 'Projects', 'arc_project_for_testing_delete_after_usage_tsg_err') + project_directory = get_test_project_directory('arc_project_for_testing_delete_after_usage_tsg_err') self.addCleanup(shutil.rmtree, project_directory, ignore_errors=True) sched = Scheduler(project='project_test_tsg_err', ess_settings=self.ess_settings, species_list=[ts_spc], @@ -946,7 +950,7 @@ def test_troubleshoot_ess_tsg_job_number_is_not_a_guess_position(self, mock_run_ ts_spc.ts_guesses = [TSGuess(index=0, method='GCN', success=False), TSGuess(index=1, method='xTB-GSM', success=False), ] - project_directory = os.path.join(ARC_PATH, 'Projects', 'arc_project_for_testing_delete_after_usage_trsh_tsg') + project_directory = get_test_project_directory('arc_project_for_testing_delete_after_usage_trsh_tsg') self.addCleanup(shutil.rmtree, project_directory, ignore_errors=True) sched = Scheduler(project='project_test_trsh_tsg', ess_settings=self.ess_settings, species_list=[ts_spc], @@ -984,7 +988,7 @@ def test_run_ts_conformer_jobs_single_success_provenance(self, mock_run_opt): failed = TSGuess(index=0, method='qst2', success=False) good = TSGuess(index=1, method='xTB-GSM', success=True, xyz=ts_xyz) ts_spc.ts_guesses = [failed, good] - project_directory = os.path.join(ARC_PATH, 'Projects', 'arc_project_for_testing_delete_after_usage_tsg_single') + project_directory = get_test_project_directory('arc_project_for_testing_delete_after_usage_tsg_single') self.addCleanup(shutil.rmtree, project_directory, ignore_errors=True) good.log_path = os.path.join(project_directory, 'stringfile.xyz0000') sched = Scheduler(project='project_test_tsg_single', ess_settings=self.ess_settings, @@ -1031,8 +1035,7 @@ def test_switch_ts_cleanup(self, mock_run_opt): ts_spc.chosen_ts_list = [0] ts_spc.ts_guesses_exhausted = False - project_directory = os.path.join(ARC_PATH, 'Projects', - 'arc_project_for_testing_delete_after_usage4') + project_directory = get_test_project_directory('arc_project_for_testing_delete_after_usage4') self.addCleanup(shutil.rmtree, project_directory, ignore_errors=True) sched = Scheduler(project='test_switch_ts', ess_settings=self.ess_settings, species_list=[ts_spc], @@ -1146,8 +1149,7 @@ def test_switch_ts_rotors_reset(self, mock_run_opt): ts_spc.rotors_dict = {0: {'pivots': [1, 2], 'scan_path': '', 'success': True}} ts_spc.number_of_rotors = 1 - project_directory = os.path.join(ARC_PATH, 'Projects', - 'arc_project_for_testing_delete_after_usage5') + project_directory = get_test_project_directory('arc_project_for_testing_delete_after_usage5') self.addCleanup(shutil.rmtree, project_directory, ignore_errors=True) sched = Scheduler(project='test_switch_ts_rot', ess_settings=self.ess_settings, species_list=[ts_spc], @@ -1190,8 +1192,7 @@ def test_switch_ts_rotors_reset(self, mock_run_opt): ts_spc2.ts_guesses_exhausted = False ts_spc2.rotors_dict = None # Sentinel: skip rotor scans. - project_directory2 = os.path.join(ARC_PATH, 'Projects', - 'arc_project_for_testing_delete_after_usage6') + project_directory2 = get_test_project_directory('arc_project_for_testing_delete_after_usage6') self.addCleanup(shutil.rmtree, project_directory2, ignore_errors=True) sched2 = Scheduler(project='test_switch_ts_norot', ess_settings=self.ess_settings, species_list=[ts_spc2], @@ -1771,8 +1772,7 @@ def tearDownClass(cls): """ projects = ['arc_project_for_testing_delete_after_usage3', 'arc_project_for_testing_delete_after_usage6'] for project in projects: - project_directory = os.path.join(ARC_PATH, 'Projects', project) - shutil.rmtree(project_directory, ignore_errors=True) + shutil.rmtree(get_test_project_directory(project), ignore_errors=True) class TestSpawnTsJobsAdmission(unittest.TestCase): diff --git a/arc/species/species_test.py b/arc/species/species_test.py index ef48c7efc3..d7f310ef6d 100644 --- a/arc/species/species_test.py +++ b/arc/species/species_test.py @@ -14,6 +14,7 @@ ARC_TESTING_PATH, almost_equal_coords_lists, check_that_all_entries_are_in_list, + get_test_project_directory, save_yaml_file, ) from arc.species.converter import check_xyz_dict @@ -1821,7 +1822,7 @@ def test_preserving_multiplicity(self): def test_append_conformers(self): """Test that ARC correctly parses its own conformer files""" - project_directory = os.path.join(ARC_PATH, 'Projects', 'arc_project_for_testing_delete_after_usage4') + project_directory = get_test_project_directory('arc_project_for_testing_delete_after_usage4') xyzs = [{'symbols': ('O', 'C', 'C', 'H', 'H', 'H'), 'isotopes': (16, 12, 12, 1, 1, 1), 'coords': ((1.090687, 0.265168, -0.167063), (2.922041, -1.183357, -0.388849), (2.276555, -0.003739, 0.085435), (2.365448, -1.88781, -0.999146), @@ -3350,10 +3351,9 @@ def tearDownClass(cls): A function that is run ONCE after all unit tests in this class. Delete all project directories created during these unit tests """ - projects = ['arc_project_for_testing_delete_after_usage4', - os.path.join(ARC_TESTING_PATH, 'gcn_tst')] - for project in projects: - project_directory = os.path.join(ARC_PATH, 'Projects', project) + project_directories = [get_test_project_directory('arc_project_for_testing_delete_after_usage4'), + os.path.join(ARC_TESTING_PATH, 'gcn_tst')] + for project_directory in project_directories: shutil.rmtree(project_directory, ignore_errors=True) file_paths = [os.path.join(ARC_PATH, 'nul'), os.path.join(ARC_PATH, 'run.out'), diff --git a/arc/utils/scale_test.py b/arc/utils/scale_test.py index fb8f1b9602..3982171cea 100644 --- a/arc/utils/scale_test.py +++ b/arc/utils/scale_test.py @@ -9,7 +9,7 @@ import shutil import unittest -from arc.common import almost_equal_coords_lists, ARC_PATH +from arc.common import almost_equal_coords_lists, get_test_project_directory from arc.level import Level from arc.utils.scale import (calculate_truhlar_scaling_factors, get_species_list, @@ -71,7 +71,7 @@ def test_summarize_results(self): ] times = ['3', '5'] overall_time = '8.5' - base_path = os.path.join(ARC_PATH, 'Projects', 'scaling_factors_arc_testing_delete_after_usage') + base_path = get_test_project_directory('scaling_factors_arc_testing_delete_after_usage') summarize_results(lambda_zpes=lambda_zpes, levels=levels_of_theory, @@ -126,8 +126,8 @@ def tearDownClass(cls): A function that is run ONCE after all unit tests in this class. Delete all directories created during these unit tests """ - path = os.path.join(ARC_PATH, 'Projects', 'scaling_factors_arc_testing_delete_after_usage') - shutil.rmtree(path, ignore_errors=True) + shutil.rmtree(get_test_project_directory('scaling_factors_arc_testing_delete_after_usage'), + ignore_errors=True) if __name__ == '__main__': diff --git a/functional/restart_test.py b/functional/restart_test.py index 35594910b8..721e4be9c8 100644 --- a/functional/restart_test.py +++ b/functional/restart_test.py @@ -12,18 +12,10 @@ from arc.molecule.molecule import Molecule -from arc.common import ARC_PATH, read_yaml_file +from arc.common import ARC_PATH, get_test_project_name, read_yaml_file from arc.main import ARC -def _project_name(base: str) -> str: - """Return a per-xdist-worker project name to avoid parallel cleanup collisions.""" - worker_id = os.environ.get('PYTEST_XDIST_WORKER') - if worker_id: - return f'{base}_{worker_id}' - return base - - class TestRestart(unittest.TestCase): """ Contains unit tests for restarting ARC. @@ -44,7 +36,7 @@ def test_restart_thermo(self): """ restart_dir = os.path.join(ARC_PATH, 'arc', 'testing', 'restart', '1_restart_thermo') restart_path = os.path.join(restart_dir, 'restart.yml') - project = _project_name('arc_project_for_testing_delete_after_usage_restart_thermo') + project = get_test_project_name('arc_project_for_testing_delete_after_usage_restart_thermo') project_directory = os.path.join(ARC_PATH, 'Projects', project) os.makedirs(os.path.dirname(project_directory), exist_ok=True) shutil.copytree(os.path.join(restart_dir, 'calcs'), os.path.join(project_directory, 'calcs', 'Species'), dirs_exist_ok=True) @@ -141,7 +133,7 @@ def test_restart_rate_1(self): """Test restarting ARC and attaining a reaction rate coefficient""" restart_dir = os.path.join(ARC_PATH, 'arc', 'testing', 'restart', '2_restart_rate') restart_path = os.path.join(restart_dir, 'restart.yml') - project = _project_name('arc_project_for_testing_delete_after_usage_restart_rate_1') + project = get_test_project_name('arc_project_for_testing_delete_after_usage_restart_rate_1') project_directory = os.path.join(ARC_PATH, 'Projects', project) os.makedirs(os.path.dirname(project_directory), exist_ok=True) shutil.copytree(os.path.join(restart_dir, 'calcs'), os.path.join(project_directory, 'calcs'), dirs_exist_ok=True) @@ -162,7 +154,7 @@ def test_restart_rate_1(self): def test_restart_rate_2(self): """Test restarting ARC and attaining a reaction rate coefficient""" - project = _project_name('arc_project_for_testing_delete_after_usage_restart_rate_2') + project = get_test_project_name('arc_project_for_testing_delete_after_usage_restart_rate_2') project_directory = os.path.join(ARC_PATH, 'Projects', project) base_path = os.path.join(ARC_PATH, 'arc', 'testing', 'restart', '5_TS1') restart_path = os.path.join(base_path, 'restart.yml') @@ -191,7 +183,7 @@ def test_restart_bde (self): """Test restarting ARC and attaining a BDE for anilino_radical.""" restart_dir = os.path.join(ARC_PATH, 'arc', 'testing', 'restart', '3_restart_bde') restart_path = os.path.join(restart_dir, 'restart.yml') - project = _project_name('test_restart_bde') + project = get_test_project_name('test_restart_bde') project_directory = os.path.join(ARC_PATH, 'Projects', project) os.makedirs(os.path.dirname(project_directory), exist_ok=True) shutil.copytree(os.path.join(restart_dir, 'calcs'), os.path.join(project_directory, 'calcs'), dirs_exist_ok=True) @@ -226,10 +218,10 @@ def tearDownClass(cls): A function that is run ONCE after all unit tests in this class. Delete all project directories created during these unit tests """ - projects = [_project_name('arc_project_for_testing_delete_after_usage_restart_thermo'), - _project_name('arc_project_for_testing_delete_after_usage_restart_rate_1'), - _project_name('arc_project_for_testing_delete_after_usage_restart_rate_2'), - _project_name('test_restart_bde'), + projects = [get_test_project_name('arc_project_for_testing_delete_after_usage_restart_thermo'), + get_test_project_name('arc_project_for_testing_delete_after_usage_restart_rate_1'), + get_test_project_name('arc_project_for_testing_delete_after_usage_restart_rate_2'), + get_test_project_name('test_restart_bde'), ] for project in projects: project_directory = os.path.join(ARC_PATH, 'Projects', project)