Implements Better Tests and Logging
This commit is contained in:
@@ -12,10 +12,44 @@ class TestConfig(unittest.TestCase):
|
||||
)
|
||||
self.assertIsInstance(config, Config)
|
||||
|
||||
def test_config_raises_exception(self):
|
||||
def test_config_raises_exception_on_mem_none(self):
|
||||
with self.assertRaises(ValueError):
|
||||
Config(
|
||||
mem="1",
|
||||
mem=None,
|
||||
level="b3lyp/aug-cc-pVDZ",
|
||||
n_atoms=10
|
||||
)
|
||||
|
||||
def test_config_raises_exception_on_mem_zero_or_negative(self):
|
||||
|
||||
with self.assertRaises(ValueError):
|
||||
Config(
|
||||
mem=0,
|
||||
level="b3lyp/aug-cc-pVDZ",
|
||||
n_atoms=10
|
||||
)
|
||||
|
||||
with self.assertRaises(ValueError):
|
||||
Config(
|
||||
mem=-1,
|
||||
level="b3lyp/aug-cc-pVDZ",
|
||||
n_atoms=10
|
||||
)
|
||||
|
||||
def test_config_raises_exception_on_level_none(self):
|
||||
|
||||
with self.assertRaises(ValueError):
|
||||
Config(
|
||||
mem=1,
|
||||
level=None,
|
||||
n_atoms=10
|
||||
)
|
||||
|
||||
def test_config_raises_exception_on_n_atoms_zero(self):
|
||||
|
||||
with self.assertRaises(ValueError):
|
||||
Config(
|
||||
mem=1,
|
||||
level="b3lyp/aug-cc-pVDZ",
|
||||
n_atoms=0
|
||||
)
|
||||
|
||||
@@ -1,209 +0,0 @@
|
||||
from crystalpol.shared.system.molecule import Molecule
|
||||
from crystalpol.shared.system.crystal import Crystal
|
||||
from crystalpol.shared.system.atom import Atom
|
||||
from crystalpol.shared.config import Config
|
||||
from crystalpol.gaussian import Gaussian
|
||||
|
||||
from pathlib import Path
|
||||
from io import StringIO
|
||||
|
||||
from unittest import mock, TestCase
|
||||
import unittest
|
||||
|
||||
|
||||
class TestGaussian(TestCase):
|
||||
|
||||
def test_class_instantiation(self):
|
||||
gaussian = Gaussian(
|
||||
Config(
|
||||
mem=1,
|
||||
level="b3lyp/aug-cc-pVDZ",
|
||||
n_atoms=10
|
||||
)
|
||||
)
|
||||
|
||||
self.assertIsInstance(gaussian, Gaussian)
|
||||
|
||||
def test_check_keyword(self):
|
||||
gaussian = Gaussian(
|
||||
Config(
|
||||
mem=1,
|
||||
level="b3lyp/aug-cc-pVDZ",
|
||||
n_atoms=10,
|
||||
pop="lorota"
|
||||
)
|
||||
)
|
||||
|
||||
self.assertEqual(gaussian.config.pop, "chelpg")
|
||||
|
||||
@mock.patch('crystalpol.gaussian.os')
|
||||
def test_create_simulation_dir(self, os_mock):
|
||||
os_mock.path.exists.return_value = False
|
||||
os_mock.makedirs = mock.MagicMock()
|
||||
|
||||
gaussian = Gaussian(
|
||||
Config(
|
||||
mem=1,
|
||||
level="b3lyp/aug-cc-pVDZ",
|
||||
n_atoms=10
|
||||
)
|
||||
)
|
||||
gaussian.create_simulation_dir()
|
||||
|
||||
self.assertTrue(os_mock.makedirs.called)
|
||||
|
||||
@mock.patch('crystalpol.gaussian.os')
|
||||
def test_create_simulation_dir_raises_exception(self, os_mock):
|
||||
os_mock.path.exists.return_value = True
|
||||
os_mock.makedirs = mock.MagicMock()
|
||||
gaussian = Gaussian(
|
||||
Config(
|
||||
mem=1,
|
||||
level="b3lyp/aug-cc-pVDZ",
|
||||
n_atoms=10
|
||||
)
|
||||
)
|
||||
|
||||
with self.assertRaises(RuntimeError):
|
||||
gaussian.create_simulation_dir()
|
||||
|
||||
# @mock.patch('crystalpol.gaussian.os')
|
||||
@mock.patch('crystalpol.gaussian.open')
|
||||
def test_make_gaussian_input_cycle_1(self, open_mock):
|
||||
|
||||
open_mock.return_value = StringIO()
|
||||
|
||||
crystal = self.create_crystal()
|
||||
|
||||
gaussian = Gaussian(
|
||||
Config(
|
||||
mem=1,
|
||||
level="b3lyp/aug-cc-pVDZ",
|
||||
n_atoms=10
|
||||
)
|
||||
)
|
||||
gaussian_input = gaussian.make_gaussian_input(1, Path(), crystal)
|
||||
expected_output = """\
|
||||
%Mem=1Gb
|
||||
%Nprocs=1
|
||||
#P b3lyp/aug-cc-pVDZ Pop=chelpg Density=Current NoSymm
|
||||
|
||||
crystalpol - Cycle number 1
|
||||
|
||||
0 1
|
||||
H 0.00000 0.00000 0.00000
|
||||
|
||||
"""
|
||||
self.assertEqual(gaussian_input, expected_output)
|
||||
|
||||
@mock.patch('crystalpol.gaussian.open')
|
||||
def test_make_gaussian_input_cycle_2(self, open_mock):
|
||||
|
||||
open_mock.return_value = StringIO()
|
||||
|
||||
crystal = self.create_crystal()
|
||||
|
||||
gaussian = Gaussian(
|
||||
Config(
|
||||
mem=1,
|
||||
level="b3lyp/aug-cc-pVDZ",
|
||||
n_atoms=10
|
||||
)
|
||||
)
|
||||
gaussian_input = gaussian.make_gaussian_input(2, "test", crystal)
|
||||
expected_output = """\
|
||||
%Mem=1Gb
|
||||
%Nprocs=1
|
||||
#P b3lyp/aug-cc-pVDZ Pop=chelpg Density=Current NoSymm charge
|
||||
|
||||
crystalpol - Cycle number 2
|
||||
|
||||
0 1
|
||||
H 0.00000 0.00000 0.00000
|
||||
|
||||
H 0.00000 0.00000 0.00000
|
||||
|
||||
"""
|
||||
self.assertEqual(gaussian_input, expected_output)
|
||||
|
||||
def test_make_gaussian_charges(self):
|
||||
|
||||
file = StringIO()
|
||||
crystal = self.create_crystal()
|
||||
|
||||
gaussian = Gaussian(
|
||||
Config(
|
||||
mem=1,
|
||||
level="b3lyp/aug-cc-pVDZ",
|
||||
n_atoms=10
|
||||
)
|
||||
)
|
||||
gaussian.make_gaussian_charges(file, crystal)
|
||||
file.seek(0)
|
||||
|
||||
charges_string = file.read()
|
||||
expected_charges = 'H 0.00000 0.00000 0.00000\n\n'
|
||||
|
||||
self.assertEqual(charges_string, expected_charges)
|
||||
|
||||
@mock.patch('crystalpol.gaussian.os')
|
||||
@mock.patch('crystalpol.gaussian.subprocess.call', autospec=True, return_value=0)
|
||||
@mock.patch('crystalpol.gaussian.Gaussian.make_gaussian_input')
|
||||
def test_run(self, make_gaussian_input_mock, subprocess_call_mock, os_mock):
|
||||
os_mock.path.exists.return_value = False
|
||||
|
||||
gaussian = Gaussian(
|
||||
Config(
|
||||
mem=1,
|
||||
level="b3lyp/aug-cc-pVDZ",
|
||||
n_atoms=10
|
||||
)
|
||||
)
|
||||
gaussian.run(1, self.create_crystal())
|
||||
|
||||
self.assertTrue(subprocess_call_mock.called)
|
||||
|
||||
@mock.patch('crystalpol.gaussian.os')
|
||||
@mock.patch('crystalpol.gaussian.subprocess.call', autospec=True, return_value=1)
|
||||
@mock.patch('crystalpol.gaussian.Gaussian.make_gaussian_input')
|
||||
def test_run_raises_exception(self, subprocess_call_mock, make_gaussian_input_mock, os_mock):
|
||||
os_mock.path.exists.return_value = False
|
||||
|
||||
gaussian = Gaussian(
|
||||
Config(
|
||||
mem=1,
|
||||
level="b3lyp/aug-cc-pVDZ",
|
||||
n_atoms=10
|
||||
)
|
||||
)
|
||||
|
||||
with self.assertRaises(RuntimeError):
|
||||
gaussian.run(1, self.create_crystal())
|
||||
|
||||
@staticmethod
|
||||
def create_crystal():
|
||||
|
||||
crystal_structure = [
|
||||
['H ']
|
||||
]
|
||||
|
||||
crystal = Crystal(crystal_structure)
|
||||
|
||||
molecule = Molecule("TESTE")
|
||||
molecule.add_atom(
|
||||
Atom(
|
||||
na=1,
|
||||
rx=0,
|
||||
ry=0,
|
||||
rz=0,
|
||||
)
|
||||
)
|
||||
|
||||
crystal.add_cell([molecule])
|
||||
crystal.add_cell([molecule])
|
||||
|
||||
return crystal
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
0
tests/shared/utils/__init__.py
Normal file
0
tests/shared/utils/__init__.py
Normal file
111
tests/shared/utils/test_log.py
Normal file
111
tests/shared/utils/test_log.py
Normal file
@@ -0,0 +1,111 @@
|
||||
from crystalpol.shared.system.molecule import Molecule
|
||||
from crystalpol.shared.system.crystal import Crystal
|
||||
from crystalpol.shared.system.atom import Atom
|
||||
from crystalpol.shared.config import Config
|
||||
from crystalpol.shared.utils.log import Log
|
||||
|
||||
from io import StringIO
|
||||
import logging
|
||||
|
||||
from unittest import TestCase, mock
|
||||
|
||||
|
||||
class TestLog(TestCase):
|
||||
|
||||
def setUp(self):
|
||||
|
||||
self.log_stream = StringIO()
|
||||
logging.basicConfig(
|
||||
stream=self.log_stream,
|
||||
format='%(message)s',
|
||||
level=logging.INFO
|
||||
)
|
||||
self.logger = logging.getLogger()
|
||||
|
||||
def tearDown(self):
|
||||
logging.getLogger().removeHandler(
|
||||
logging.getLogger().handlers[0]
|
||||
)
|
||||
del self.logger
|
||||
del self.log_stream
|
||||
|
||||
@mock.patch('crystalpol.shared.utils.log.sys')
|
||||
@mock.patch('crystalpol.shared.utils.log.weekday_date_time')
|
||||
def test_make_header(self, weekday_date_time_mock, sys_mock):
|
||||
weekday_date_time_mock.return_value = 'Test Day'
|
||||
sys_mock.version = 'Test Version'
|
||||
|
||||
config = Config(
|
||||
mem=1,
|
||||
level="b3lyp/aug-cc-pVDZ",
|
||||
n_atoms=10
|
||||
)
|
||||
Log.make_header('test', config.to_dict(), logger=self.logger)
|
||||
|
||||
expected_log_stream = [
|
||||
'##########################################################################################\n',
|
||||
'############## Welcome to CRYSTALPOL version test ##############\n',
|
||||
'##########################################################################################\n', '\n',
|
||||
'Your python version is Test Version\n', '\n',
|
||||
'Program started on Test Day\n', '\n',
|
||||
'------------------------------------------------------------------------------------------\n',
|
||||
' CRYSTALPOL variables being used in this run: \n',
|
||||
'------------------------------------------------------------------------------------------\n', '\n',
|
||||
'\tmem = 1\n',
|
||||
'\tlevel = b3lyp/aug-cc-pVDZ\n',
|
||||
'\tn_atoms = 10\n',
|
||||
'\tn_procs = 1\n',
|
||||
'\tpop = chelpg\n',
|
||||
'\tcomment = crystalpol\n',
|
||||
'\tmult = [0, 1]\n',
|
||||
'------------------------------------------------------------------------------------------\n',
|
||||
' RUN Results: \n',
|
||||
'------------------------------------------------------------------------------------------\n', '\n'
|
||||
]
|
||||
|
||||
self.log_stream.seek(0)
|
||||
|
||||
self.assertEqual(self.log_stream.readlines(), expected_log_stream)
|
||||
|
||||
def test_make_run(self):
|
||||
|
||||
Log.make_run(1, 0.000000, [], self.create_crystal(), logger=self.logger)
|
||||
|
||||
expected_log_stream = [
|
||||
'cycle: 1\n', '\n',
|
||||
'Max charge diff: 0.00000\n',
|
||||
'Charge Diff: []\n', '\n',
|
||||
'------------------------------------------------------------------------------------------\n',
|
||||
' S rx ry rz chg \n',
|
||||
'------------------------------------------------------------------------------------------\n',
|
||||
' H 0.000000 0.000000 0.000000 0.000000 \n', '\n',
|
||||
'------------------------------------------------------------------------------------------\n', '\n'
|
||||
]
|
||||
|
||||
self.log_stream.seek(0)
|
||||
|
||||
self.assertEqual(self.log_stream.readlines(), expected_log_stream)
|
||||
|
||||
@staticmethod
|
||||
def create_crystal():
|
||||
crystal_structure = [
|
||||
['H ']
|
||||
]
|
||||
|
||||
crystal = Crystal(crystal_structure)
|
||||
|
||||
molecule = Molecule("TESTE")
|
||||
molecule.add_atom(
|
||||
Atom(
|
||||
na=1,
|
||||
rx=0.000000,
|
||||
ry=0.000000,
|
||||
rz=0.000000,
|
||||
chg=0.000000
|
||||
)
|
||||
)
|
||||
|
||||
crystal.add_cell([molecule])
|
||||
crystal.add_cell([molecule])
|
||||
|
||||
return crystal
|
||||
Reference in New Issue
Block a user