Implements Additional Logs and class Player Tests
This commit is contained in:
@@ -2,6 +2,7 @@ from diceplayer.shared.interface.dice_interface import DiceInterface
|
||||
from diceplayer.shared.environment.molecule import Molecule
|
||||
from diceplayer.shared.environment.atom import Atom
|
||||
from diceplayer.shared.config.step_dto import StepDTO
|
||||
from diceplayer import logger
|
||||
|
||||
import io
|
||||
|
||||
@@ -12,6 +13,9 @@ import unittest
|
||||
|
||||
|
||||
class TestDiceInterface(unittest.TestCase):
|
||||
def setUp(self):
|
||||
logger.set_logger(stream=io.StringIO())
|
||||
|
||||
def test_class_instantiation(self):
|
||||
dice = DiceInterface(
|
||||
{
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
from diceplayer.shared.utils.logger import Logger, valid_logger
|
||||
|
||||
import logging
|
||||
import io
|
||||
|
||||
from unittest import mock
|
||||
import unittest
|
||||
@@ -35,6 +36,23 @@ class TestLogger(unittest.TestCase):
|
||||
|
||||
self.assertIsInstance(logger, Logger)
|
||||
|
||||
@mock.patch('builtins.open', mock.mock_open())
|
||||
def test_set_logger_to_file(self):
|
||||
logger = Logger('test')
|
||||
|
||||
logger.set_logger(stream=io.StringIO())
|
||||
|
||||
self.assertIsNotNone(logger._logger)
|
||||
self.assertEqual(logger._logger.name, 'test')
|
||||
|
||||
def test_set_logger_to_stream(self):
|
||||
logger = Logger('test')
|
||||
|
||||
logger.set_logger(stream=io.StringIO())
|
||||
|
||||
self.assertIsNotNone(logger._logger)
|
||||
self.assertEqual(logger._logger.name, 'test')
|
||||
|
||||
@mock.patch('builtins.open', mock.mock_open())
|
||||
@mock.patch('diceplayer.shared.utils.logger.Path.exists')
|
||||
@mock.patch('diceplayer.shared.utils.logger.Path.rename')
|
||||
@@ -64,6 +82,7 @@ class TestLogger(unittest.TestCase):
|
||||
@mock.patch('builtins.open', mock.mock_open())
|
||||
def test_close(self):
|
||||
logger = Logger('test')
|
||||
|
||||
logger.set_logger()
|
||||
logger.close()
|
||||
|
||||
@@ -72,7 +91,7 @@ class TestLogger(unittest.TestCase):
|
||||
@mock.patch('builtins.open', mock.mock_open())
|
||||
def test_info(self):
|
||||
logger = Logger('test')
|
||||
logger.set_logger()
|
||||
logger.set_logger(stream=io.StringIO())
|
||||
|
||||
with self.assertLogs(level='INFO') as cm:
|
||||
logger.info('test')
|
||||
@@ -82,7 +101,7 @@ class TestLogger(unittest.TestCase):
|
||||
@mock.patch('builtins.open', mock.mock_open())
|
||||
def test_debug(self):
|
||||
logger = Logger('test')
|
||||
logger.set_logger(level=logging.DEBUG)
|
||||
logger.set_logger(stream=io.StringIO(), level=logging.DEBUG)
|
||||
|
||||
with self.assertLogs(level='DEBUG') as cm:
|
||||
logger.debug('test')
|
||||
@@ -92,7 +111,7 @@ class TestLogger(unittest.TestCase):
|
||||
@mock.patch('builtins.open', mock.mock_open())
|
||||
def test_warning(self):
|
||||
logger = Logger('test')
|
||||
logger.set_logger()
|
||||
logger.set_logger(stream=io.StringIO())
|
||||
|
||||
with self.assertLogs(level='WARNING') as cm:
|
||||
logger.warning('test')
|
||||
@@ -102,7 +121,7 @@ class TestLogger(unittest.TestCase):
|
||||
@mock.patch('builtins.open', mock.mock_open())
|
||||
def test_error(self):
|
||||
logger = Logger('test')
|
||||
logger.set_logger()
|
||||
logger.set_logger(stream=io.StringIO())
|
||||
|
||||
with self.assertLogs(level='ERROR') as cm:
|
||||
logger.error('test')
|
||||
|
||||
424
tests/test_player.py
Normal file
424
tests/test_player.py
Normal file
@@ -0,0 +1,424 @@
|
||||
from diceplayer.player import Player
|
||||
from diceplayer import logger
|
||||
|
||||
import io
|
||||
|
||||
from unittest import mock
|
||||
import unittest
|
||||
|
||||
|
||||
def get_config_example():
|
||||
return """
|
||||
diceplayer:
|
||||
maxcyc: 3
|
||||
opt: no
|
||||
ncores: 4
|
||||
nprocs: 4
|
||||
qmprog: 'g16'
|
||||
lps: no
|
||||
ghosts: no
|
||||
altsteps: 20000
|
||||
|
||||
dice:
|
||||
nmol: [1, 50]
|
||||
dens: 0.75
|
||||
nstep: [2000, 3000, 4000]
|
||||
isave: 1000
|
||||
outname: 'phb'
|
||||
progname: '~/.local/bin/dice'
|
||||
ljname: 'phb.ljc'
|
||||
randominit: 'first'
|
||||
|
||||
gaussian:
|
||||
qmprog: 'g16'
|
||||
level: 'MP2/aug-cc-pVDZ'
|
||||
keywords: 'freq'
|
||||
"""
|
||||
|
||||
|
||||
def get_potentials_exemple():
|
||||
return """\
|
||||
*
|
||||
2
|
||||
1 TEST
|
||||
1 1 0.000000 0.000000 0.000000 0.000000 0.0000 0.0000
|
||||
1 PLACEHOLDER
|
||||
1 1 0.000000 0.000000 0.000000 0.000000 0.0000 0.0000
|
||||
"""
|
||||
|
||||
|
||||
def get_potentials_error_combrule():
|
||||
return """\
|
||||
.
|
||||
2
|
||||
1 TEST
|
||||
1 1 0.000000 0.000000 0.000000 0.000000 0.0000 0.0000
|
||||
1 PLACEHOLDER
|
||||
1 1 0.000000 0.000000 0.000000 0.000000 0.0000 0.0000
|
||||
"""
|
||||
|
||||
|
||||
def get_potentials_error_ntypes():
|
||||
return """\
|
||||
*
|
||||
a
|
||||
1 TEST
|
||||
1 1 0.000000 0.000000 0.000000 0.000000 0.0000 0.0000
|
||||
1 PLACEHOLDER
|
||||
1 1 0.000000 0.000000 0.000000 0.000000 0.0000 0.0000
|
||||
"""
|
||||
|
||||
|
||||
def get_potentials_error_ntypes_config():
|
||||
return """\
|
||||
*
|
||||
3
|
||||
1 TEST
|
||||
1 1 0.000000 0.000000 0.000000 0.000000 0.0000 0.0000
|
||||
1 PLACEHOLDER
|
||||
1 1 0.000000 0.000000 0.000000 0.000000 0.0000 0.0000
|
||||
"""
|
||||
|
||||
|
||||
def get_potentials_error_nsites():
|
||||
return """\
|
||||
*
|
||||
2
|
||||
. TEST
|
||||
1 1 0.000000 0.000000 0.000000 0.000000 0.0000 0.0000
|
||||
1 PLACEHOLDER
|
||||
1 1 0.000000 0.000000 0.000000 0.000000 0.0000 0.0000
|
||||
"""
|
||||
|
||||
|
||||
def get_potentials_error_molname():
|
||||
return """\
|
||||
*
|
||||
2
|
||||
1
|
||||
1 1 0.000000 0.000000 0.000000 0.000000 0.0000 0.0000
|
||||
1 PLACEHOLDER
|
||||
1 1 0.000000 0.000000 0.000000 0.000000 0.0000 0.0000
|
||||
"""
|
||||
|
||||
|
||||
def mock_open(file, *args, **kwargs):
|
||||
values = {
|
||||
"control.test.yml": get_config_example(),
|
||||
"phb.ljc": get_potentials_exemple(),
|
||||
"phb.error.combrule.ljc": get_potentials_error_combrule(),
|
||||
"phb.error.ntypes.ljc": get_potentials_error_ntypes(),
|
||||
"phb.error.ntypes.config.ljc": get_potentials_error_ntypes_config(),
|
||||
"phb.error.nsites.ljc": get_potentials_error_nsites(),
|
||||
"phb.error.molname.ljc": get_potentials_error_molname(),
|
||||
}
|
||||
mock_file = mock.mock_open(read_data=values[file])
|
||||
return mock_file()
|
||||
|
||||
|
||||
class TestPlayer(unittest.TestCase):
|
||||
def setUp(self):
|
||||
logger.set_logger(stream=io.StringIO())
|
||||
|
||||
@mock.patch("builtins.open", mock_open)
|
||||
def test_class_instantiation(self):
|
||||
# This file does not exist and it will be mocked
|
||||
player = Player("control.test.yml")
|
||||
|
||||
self.assertIsInstance(player, Player)
|
||||
|
||||
@mock.patch("builtins.open", mock_open)
|
||||
def test_start(self):
|
||||
player = Player("control.test.yml")
|
||||
|
||||
player.print_keywords = mock.MagicMock()
|
||||
player.create_simulation_dir = mock.MagicMock()
|
||||
player.read_potentials = mock.MagicMock()
|
||||
player.print_potentials = mock.MagicMock()
|
||||
player.dice_start = mock.MagicMock()
|
||||
|
||||
player.start(1)
|
||||
|
||||
self.assertTrue(player.print_keywords.called)
|
||||
self.assertTrue(player.create_simulation_dir.called)
|
||||
self.assertTrue(player.read_potentials.called)
|
||||
self.assertTrue(player.print_potentials.called)
|
||||
self.assertEqual(player.dice_start.call_count, 3)
|
||||
|
||||
@mock.patch("builtins.open", mock_open)
|
||||
@mock.patch("diceplayer.player.Path")
|
||||
def test_create_simulation_dir_if_already_exists(self, mock_path):
|
||||
player = Player("control.test.yml")
|
||||
mock_path.return_value.exists.return_value = True
|
||||
|
||||
with self.assertRaises(FileExistsError):
|
||||
player.create_simulation_dir()
|
||||
|
||||
self.assertTrue(mock_path.called)
|
||||
|
||||
@mock.patch("builtins.open", mock_open)
|
||||
@mock.patch("diceplayer.player.Path")
|
||||
def test_create_simulation_dir_if_not_exists(self, mock_path):
|
||||
player = Player("control.test.yml")
|
||||
mock_path.return_value.exists.return_value = False
|
||||
|
||||
player.create_simulation_dir()
|
||||
|
||||
self.assertTrue(mock_path.called)
|
||||
|
||||
@mock.patch("diceplayer.player.sys")
|
||||
@mock.patch("diceplayer.player.weekday_date_time")
|
||||
@mock.patch("builtins.open", mock_open)
|
||||
def test_print_keywords(self, mock_date_func, mock_sys):
|
||||
player = Player("control.test.yml")
|
||||
|
||||
mock_sys.version = 'TEST'
|
||||
mock_date_func.return_value = '00 Test 0000 at 00:00:00'
|
||||
|
||||
with self.assertLogs() as cm:
|
||||
player.print_keywords()
|
||||
|
||||
expected_output = ['INFO:diceplayer:##########################################################################################\n############# Welcome to DICEPLAYER version 1.0 #############\n##########################################################################################\n\n', 'INFO:diceplayer:Your python version is TEST\n', 'INFO:diceplayer:\n', 'INFO:diceplayer:Program started on 00 Test 0000 at 00:00:00\n', 'INFO:diceplayer:\n', 'INFO:diceplayer:Environment variables:\n', 'INFO:diceplayer:OMP_STACKSIZE = Not set\n', 'INFO:diceplayer:\n==========================================================================================\n CONTROL variables being used in this run:\n------------------------------------------------------------------------------------------\n\n', 'INFO:diceplayer:\n', 'INFO:diceplayer:------------------------------------------------------------------------------------------\n DICE variables being used in this run:\n------------------------------------------------------------------------------------------\n\n', 'INFO:diceplayer:dens = 0.75', 'INFO:diceplayer:isave = 1000', 'INFO:diceplayer:ljname = phb.ljc', 'INFO:diceplayer:nmol = [ 1 50 ]', 'INFO:diceplayer:nstep = [ 2000 3000 4000 ]', 'INFO:diceplayer:outname = phb', 'INFO:diceplayer:press = 1.0', 'INFO:diceplayer:progname = ~/.local/bin/dice', 'INFO:diceplayer:randominit = first', 'INFO:diceplayer:temp = 300.0', 'INFO:diceplayer:\n', 'INFO:diceplayer:------------------------------------------------------------------------------------------\n GAUSSIAN variables being used in this run:\n------------------------------------------------------------------------------------------\n\n', 'INFO:diceplayer:keywords = freq', 'INFO:diceplayer:level = MP2/aug-cc-pVDZ', 'INFO:diceplayer:pop = chelpg', 'INFO:diceplayer:qmprog = g16', 'INFO:diceplayer:\n']
|
||||
|
||||
self.assertEqual(cm.output, expected_output)
|
||||
|
||||
def test_validate_atom_dict(self):
|
||||
with self.assertRaises(ValueError) as context:
|
||||
Player.validate_atom_dict(
|
||||
molecule_type=0,
|
||||
molecule_site=0,
|
||||
atom_dict={
|
||||
"lbl": 0, "na": 1, "rx": 1.0, "ry": 1.0, "rz": 1.0, "chg": 1.0, "eps": 1.0
|
||||
}
|
||||
)
|
||||
self.assertEqual(
|
||||
str(context.exception),
|
||||
"Invalid number of fields for site 1 for molecule type 1."
|
||||
)
|
||||
|
||||
with self.assertRaises(ValueError) as context:
|
||||
Player.validate_atom_dict(
|
||||
molecule_type=0,
|
||||
molecule_site=0,
|
||||
atom_dict={
|
||||
"lbl": '', "na": 1, "rx": 1.0, "ry": 1.0, "rz": 1.0, "chg": 1.0, "eps": 1.0, "sig": 1.0
|
||||
}
|
||||
)
|
||||
self.assertEqual(
|
||||
str(context.exception),
|
||||
"Invalid lbl fields for site 1 for molecule type 1."
|
||||
)
|
||||
|
||||
with self.assertRaises(ValueError) as context:
|
||||
Player.validate_atom_dict(
|
||||
molecule_type=0,
|
||||
molecule_site=0,
|
||||
atom_dict={
|
||||
"lbl": 1.0, "na": '', "rx": 1.0, "ry": 1.0, "rz": 1.0, "chg": 1.0, "eps": 1.0, "sig": 1.0
|
||||
}
|
||||
)
|
||||
self.assertEqual(
|
||||
str(context.exception),
|
||||
"Invalid na fields for site 1 for molecule type 1."
|
||||
)
|
||||
|
||||
with self.assertRaises(ValueError) as context:
|
||||
Player.validate_atom_dict(
|
||||
molecule_type=0,
|
||||
molecule_site=0,
|
||||
atom_dict={
|
||||
"lbl": 1.0, "na": 1, "rx": '', "ry": 1.0, "rz": 1.0, "chg": 1.0, "eps": 1.0, "sig": 1.0
|
||||
}
|
||||
)
|
||||
self.assertEqual(
|
||||
str(context.exception),
|
||||
"Invalid rx fields for site 1 for molecule type 1. Value must be a float."
|
||||
)
|
||||
|
||||
with self.assertRaises(ValueError) as context:
|
||||
Player.validate_atom_dict(
|
||||
molecule_type=0,
|
||||
molecule_site=0,
|
||||
atom_dict={
|
||||
"lbl": 1.0, "na": 1, "rx": 1.0, "ry": '', "rz": 1.0, "chg": 1.0, "eps": 1.0, "sig": 1.0
|
||||
}
|
||||
)
|
||||
self.assertEqual(
|
||||
str(context.exception),
|
||||
"Invalid ry fields for site 1 for molecule type 1. Value must be a float."
|
||||
)
|
||||
|
||||
with self.assertRaises(ValueError) as context:
|
||||
Player.validate_atom_dict(
|
||||
molecule_type=0,
|
||||
molecule_site=0,
|
||||
atom_dict={
|
||||
"lbl": 1.0, "na": 1, "rx": 1.0, "ry": 1.0, "rz": '', "chg": 1.0, "eps": 1.0, "sig": 1.0
|
||||
}
|
||||
)
|
||||
self.assertEqual(
|
||||
str(context.exception),
|
||||
"Invalid rz fields for site 1 for molecule type 1. Value must be a float."
|
||||
)
|
||||
|
||||
with self.assertRaises(ValueError) as context:
|
||||
Player.validate_atom_dict(
|
||||
molecule_type=0,
|
||||
molecule_site=0,
|
||||
atom_dict={
|
||||
"lbl": 1.0, "na": 1, "rx": 1.0, "ry": 1.0, "rz": 1.0, "chg": '', "eps": 1.0, "sig": 1.0
|
||||
}
|
||||
)
|
||||
self.assertEqual(
|
||||
str(context.exception),
|
||||
"Invalid chg fields for site 1 for molecule type 1. Value must be a float."
|
||||
)
|
||||
|
||||
with self.assertRaises(ValueError) as context:
|
||||
Player.validate_atom_dict(
|
||||
molecule_type=0,
|
||||
molecule_site=0,
|
||||
atom_dict={
|
||||
"lbl": 1.0, "na": 1, "rx": 1.0, "ry": 1.0, "rz": 1.0, "chg": 1.0, "eps": '', "sig": 1.0
|
||||
}
|
||||
)
|
||||
self.assertEqual(
|
||||
str(context.exception),
|
||||
"Invalid eps fields for site 1 for molecule type 1. Value must be a float."
|
||||
)
|
||||
|
||||
with self.assertRaises(ValueError) as context:
|
||||
Player.validate_atom_dict(
|
||||
molecule_type=0,
|
||||
molecule_site=0,
|
||||
atom_dict={
|
||||
"lbl": 1.0, "na": 1, "rx": 1.0, "ry": 1.0, "rz": 1.0, "chg": 1.0, "eps": 1.0, "sig": ''
|
||||
}
|
||||
)
|
||||
self.assertEqual(
|
||||
str(context.exception),
|
||||
"Invalid sig fields for site 1 for molecule type 1. Value must be a float."
|
||||
)
|
||||
|
||||
@mock.patch("builtins.open", mock_open)
|
||||
@mock.patch("diceplayer.player.Path.exists", return_value=True)
|
||||
def test_read_potentials(self, mock_path_exists):
|
||||
player = Player("control.test.yml")
|
||||
|
||||
player.read_potentials()
|
||||
|
||||
self.assertEqual(player.system.molecule[0].molname, "TEST")
|
||||
self.assertEqual(len(player.system.molecule[0].atom), 1)
|
||||
|
||||
self.assertEqual(player.system.molecule[1].molname, "PLACEHOLDER")
|
||||
self.assertEqual(len(player.system.molecule[1].atom), 1)
|
||||
|
||||
@mock.patch("builtins.open", mock_open)
|
||||
@mock.patch("diceplayer.player.Path.exists")
|
||||
def test_read_potentials_error(self, mock_path_exists):
|
||||
player = Player("control.test.yml")
|
||||
|
||||
# Testing file not found error
|
||||
mock_path_exists.return_value = False
|
||||
with self.assertRaises(RuntimeError) as context:
|
||||
player.read_potentials()
|
||||
|
||||
self.assertEqual(
|
||||
str(context.exception),
|
||||
"Potential file phb.ljc not found."
|
||||
)
|
||||
|
||||
# Enabling file found for next tests
|
||||
mock_path_exists.return_value = True
|
||||
|
||||
# Testing combrule error
|
||||
with self.assertRaises(SystemExit) as context:
|
||||
player.dice.config.ljname = "phb.error.combrule.ljc"
|
||||
player.read_potentials()
|
||||
|
||||
self.assertEqual(
|
||||
str(context.exception),
|
||||
"Error: expected a '*' or a '+' sign in 1st line of file phb.error.combrule.ljc"
|
||||
)
|
||||
|
||||
# Testing ntypes error
|
||||
with self.assertRaises(SystemExit) as context:
|
||||
player.dice.config.ljname = "phb.error.ntypes.ljc"
|
||||
player.read_potentials()
|
||||
|
||||
self.assertEqual(
|
||||
str(context.exception),
|
||||
"Error: expected an integer in the 2nd line of file phb.error.ntypes.ljc"
|
||||
)
|
||||
|
||||
# Testing ntypes error on config
|
||||
with self.assertRaises(SystemExit) as context:
|
||||
player.dice.config.ljname = "phb.error.ntypes.config.ljc"
|
||||
player.read_potentials()
|
||||
|
||||
self.assertEqual(
|
||||
str(context.exception),
|
||||
"Error: number of molecule types in file phb.error.ntypes.config.ljc "
|
||||
"must match that of 'nmol' keyword in config file"
|
||||
)
|
||||
|
||||
# Testing nsite error
|
||||
with self.assertRaises(ValueError) as context:
|
||||
player.dice.config.ljname = "phb.error.nsites.ljc"
|
||||
player.read_potentials()
|
||||
|
||||
self.assertEqual(
|
||||
str(context.exception),
|
||||
"Error: expected nsites to be an integer for molecule type 1"
|
||||
)
|
||||
|
||||
# Testing molname error
|
||||
with self.assertRaises(ValueError) as context:
|
||||
player.dice.config.ljname = "phb.error.molname.ljc"
|
||||
player.read_potentials()
|
||||
|
||||
self.assertEqual(
|
||||
str(context.exception),
|
||||
"Error: expected nsites and molname for the molecule type 1"
|
||||
)
|
||||
|
||||
@mock.patch("builtins.open", mock_open)
|
||||
@mock.patch("diceplayer.player.Path.exists", return_value=True)
|
||||
def test_print_potentials(self, mock_path_exists):
|
||||
player = Player("control.test.yml")
|
||||
player.read_potentials()
|
||||
|
||||
with self.assertLogs(level='INFO') as context:
|
||||
player.print_potentials()
|
||||
|
||||
expected_output = ['INFO:diceplayer:==========================================================================================\n', 'INFO:diceplayer: Potential parameters from file phb.ljc:', 'INFO:diceplayer:------------------------------------------------------------------------------------------\n', 'INFO:diceplayer:Combination rule: *', 'INFO:diceplayer:Types of molecules: 2\n', 'INFO:diceplayer:1 atoms in molecule type 1:', 'INFO:diceplayer:---------------------------------------------------------------------------------', 'INFO:diceplayer:Lbl AN X Y Z Charge Epsilon Sigma Mass', 'INFO:diceplayer:---------------------------------------------------------------------------------', 'INFO:diceplayer:1 1 0.00000 0.00000 0.00000 0.000000 0.00000 0.0000 1.0079', 'INFO:diceplayer:\n', 'INFO:diceplayer:1 atoms in molecule type 2:', 'INFO:diceplayer:---------------------------------------------------------------------------------', 'INFO:diceplayer:Lbl AN X Y Z Charge Epsilon Sigma Mass', 'INFO:diceplayer:---------------------------------------------------------------------------------', 'INFO:diceplayer:1 1 0.00000 0.00000 0.00000 0.000000 0.00000 0.0000 1.0079', 'INFO:diceplayer:\n', 'INFO:diceplayer:==========================================================================================']
|
||||
|
||||
self.assertEqual(
|
||||
context.output,
|
||||
expected_output
|
||||
)
|
||||
|
||||
@mock.patch("builtins.open", mock_open)
|
||||
def test_dice_start(self):
|
||||
player = Player("control.test.yml")
|
||||
player.dice = mock.MagicMock()
|
||||
player.dice.start = mock.MagicMock()
|
||||
|
||||
player.dice_start(1)
|
||||
|
||||
player.dice.start.assert_called_once()
|
||||
|
||||
@mock.patch("builtins.open", mock_open)
|
||||
def test_gaussian_start(self):
|
||||
player = Player("control.test.yml")
|
||||
player.gaussian = mock.MagicMock()
|
||||
player.gaussian.start = mock.MagicMock()
|
||||
|
||||
player.gaussian_start(1)
|
||||
|
||||
player.gaussian.start.assert_called_once()
|
||||
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
Reference in New Issue
Block a user