Commit eca7feb6 authored by Michael Salim's avatar Michael Salim
Browse files

Job PK and version are properly updated with sqlite_client save method. test...

Job PK and version are properly updated with sqlite_client save method. test runner works with both save methods
parent 74502f8e
......@@ -2,9 +2,11 @@ from io import StringIO
from traceback import print_exc
import json
import os
import uuid
import zmq
from django.db.utils import OperationalError
from concurrency.exceptions import RecordModifiedError
REQ_TIMEOUT = 10000 # 10 seconds
REQ_RETRY = 3
......@@ -73,4 +75,12 @@ class Client:
self.logger.info(f"client: sending request for save of {job.cute_id}")
response = self.send_request(serial_data)
assert response == 'ACK_SAVE'
if response == 'ACK_RECORD_MODIFIED':
raise RecordModifiedError(target=job)
else:
assert response.startswith('ACK_SAVE')
job_id = uuid.UUID(response.split()[1])
if job.job_id is None:
job.job_id = job_id
else:
assert job.job_id == job_id
......@@ -16,6 +16,7 @@ django.setup()
from balsam.service.models import BalsamJob
from balsam.django_config import serverinfo
from concurrency.exceptions import RecordModifiedError
logger = logging.getLogger('balsam.django_config.sqlite_server')
......@@ -60,7 +61,7 @@ class ZMQServer:
update_fields = d['update_fields']
job.save(force_insert, force_update, using, update_fields)
logger.info(f"db_writer Saved {job.cute_id}")
return time.time()
return time.time(), job.pk
def server_main(db_path):
......@@ -89,9 +90,14 @@ def server_main(db_path):
logger.info("detected parent died; server quitting soon")
terminate = True
elif 'job_id' in message:
logger.debug("sending ACK_SAVE")
last_save_time = server.save(message)
server.send_reply("ACK_SAVE")
try:
last_save_time, job_id = server.save(message)
except RecordModifiedError:
server.send_reply("ACK_RECORD_MODIFIED")
logger.debug("sending ACK_RECORD_MODIFIED")
else:
server.send_reply(f"ACK_SAVE {job_id}")
logger.debug("sending ACK_SAVE")
else:
logger.debug("sending ACK")
server.send_reply("ACK")
......
......@@ -11,8 +11,8 @@ from django.conf import settings
db_path = db.connection.settings_dict['NAME']
print(f"Setting up new balsam database: {db_path}")
call_command('makemigrations', interactive=False, verbosity=2)
call_command('migrate', interactive=False, verbosity=2)
call_command('makemigrations', interactive=False, verbosity=0)
call_command('migrate', interactive=False, verbosity=0)
new_path = settings.DATABASES['default']['NAME']
if os.path.exists(new_path):
......
......@@ -256,12 +256,13 @@ class BalsamJob(models.Model):
else:
logger.info(f"sending request for save of {self.cute_id}")
settings.SAVE_CLIENT.save(self, force_insert, force_update, using, update_fields)
self.refresh_from_db()
@staticmethod
def from_dict(d):
job = BalsamJob()
SERIAL_FIELDS = [f for f in job.__dict__ if f not in
'_state version force_insert force_update using update_fields'.split()
'_state force_insert force_update using update_fields'.split()
]
if type(d['job_id']) is str:
......@@ -488,7 +489,7 @@ auto timeout retry: {self.auto_timeout_retry}
return path
def to_dict(self):
SERIAL_FIELDS = [f for f in self.__dict__ if f not in ['_state', 'version']]
SERIAL_FIELDS = [f for f in self.__dict__ if f not in ['_state']]
d = {field : self.__dict__[field] for field in SERIAL_FIELDS}
return d
......
......@@ -5,6 +5,7 @@ import tempfile
import unittest
import balsam
import subprocess
def set_permissions(top):
os.chmod(top, 0o755)
......@@ -16,20 +17,27 @@ def set_permissions(top):
def main():
test_dir = os.path.abspath(os.path.dirname(balsam.__file__))
tempdir = tempfile.TemporaryDirectory(dir=test_dir, prefix="testdata_")
test_directory = tempdir.name
if '--temp' in ' '.join(sys.argv[1:]):
test_dir = os.path.abspath(os.path.dirname(__file__))
tempdir = tempfile.TemporaryDirectory(dir=test_dir, prefix="testdata_")
test_directory = tempdir.name
set_permissions(test_directory)
os.environ['BALSAM_DB_PATH'] = os.path.expanduser(test_directory)
p = subprocess.Popen(f'balsam init {test_directory}', shell=True)
p.wait()
else:
db_path = os.environ.get('BALSAM_DB_PATH')
if not db_path or 'test' not in db_path:
print("Please set env BALSAM_DB_PATH to a balsam DB directory containing substring 'test'")
sys.exit(1)
os.environ['BALSAM_TEST_DIRECTORY'] = test_directory
os.environ['BALSAM_TEST']='1'
os.environ['DJANGO_SETTINGS_MODULE'] = 'balsam.django_config.settings'
django.setup()
set_permissions(test_directory)
loader = unittest.defaultTestLoader
if len(sys.argv) > 1:
names = sys.argv[1:]
names = [n for n in sys.argv[1:] if '--' not in n]
suite = loader.loadTestsFromNames(names)
else:
suite = loader.discover('tests')
......
......@@ -12,9 +12,14 @@ from balsam.service.models import BalsamJob, ApplicationDefinition
class BalsamTestCase(unittest.TestCase):
@classmethod
def setUpClass(cls):
assert db.connection.settings_dict['NAME'].endswith('test_db.sqlite3')
test_db_path = os.environ['BALSAM_DB_PATH']
assert test_db_path in db.connection.settings_dict['NAME']
assert 'test' in test_db_path
call_command('makemigrations',interactive=False,verbosity=0)
call_command('migrate',interactive=False,verbosity=0)
call_command('flush',interactive=False,verbosity=0)
assert os.path.exists(settings.DATABASES['default']['NAME'])
@classmethod
......@@ -25,7 +30,8 @@ class BalsamTestCase(unittest.TestCase):
pass # to be implemented by test cases
def tearDown(self):
if not db.connection.settings_dict['NAME'].endswith('test_db.sqlite3'):
test_db_path = os.environ['BALSAM_DB_PATH']
if not test_db_path in db.connection.settings_dict['NAME']:
raise RuntimeError("Test DB not configured")
call_command('flush',interactive=False,verbosity=0)
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment