Skip to content
This repository was archived by the owner on Nov 14, 2022. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
[
{
[{
"model": "reduction_viewer.reductionrun",
"pk": 1,
"fields": {
Expand All @@ -14,7 +13,8 @@
"hidden_in_failviewer": 0,
"experiment_id": 1,
"instrument_id": 1,
"started_by": -1
"started_by": -1,
"reduction_host": "test-host-123"
}
},
{
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Generated by Django 3.1.2 on 2021-03-29 09:39

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('reduction_viewer', '0005_auto_20210326_1628'),
]

operations = [
migrations.AddField(
model_name='reductionrun',
name='reduction_host',
field=models.TextField(blank=True, default='', verbose_name='Reduction hostname'),
),
]
1 change: 1 addition & 0 deletions WebApp/autoreduce_webapp/reduction_viewer/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@ class ReductionRun(models.Model):
graph = models.TextField(null=True, blank=True)
message = models.TextField(null=True, blank=True)
reduction_log = models.TextField(blank=True)
reduction_host = models.TextField(default="", blank=True, verbose_name="Reduction hostname")
# Scripts should be 100,000 chars or less. The DB supports up to 4GB strings here
script = models.TextField(blank=False, validators=[MaxLengthValidator(100000)])

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,12 @@ def last_updated_text(self) -> str:
"""
return self.driver.find_element_by_id("last_updated").text

def reduction_host_text(self) -> WebElement:
"""
Returns the reduction host text
"""
return self.driver.find_element_by_id("reduction_host").text

def images(self) -> List[WebElement]:
"""
Returns all image elements on the page.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ def test_reduction_job_panel_displayed(self):
assert self.page.instrument_text() == f"Instrument: {run.instrument.name}"
assert self.page.rb_number_text() == f"RB Number: {run.experiment.reference_number}"
assert self.page.last_updated_text() == "Last Updated: 19 Oct 2020, 6:35 p.m."
assert self.page.reduction_host_text() == "Host:test-host-123"

def test_reduction_job_panel_reset_to_values_first_used_for_run(self):
"""Test that the button to reset the variables to the values first used for the run works"""
Expand Down
1 change: 1 addition & 0 deletions WebApp/autoreduce_webapp/templates/run_summary.html
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,7 @@ <h2>Reduction Job #{{ run.title }}</h2>
<em>No software data found</em>
{% endif %}
</div>
<div id="reduction_host"><strong>Host:</strong>{{ run.reduction_host }}</div>
</div>
</div>
<div class="row">
Expand Down
17 changes: 11 additions & 6 deletions model/database/records.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,18 +9,22 @@
Contains various helper methods for managing or creating ORM records
"""

import datetime
import model.database.access
import socket
from django.utils import timezone


def create_reduction_run_record(experiment, instrument, message, run_version, script_text, status):
def create_reduction_run_record(experiment, instrument, message, run_version, script_text, status, db_handle=None):
"""
Creates an ORM record for the given reduction run and returns
this record without saving it to the DB
"""
db_handle = model.database.access.start_database()
if not db_handle:
# pylint:disable=import-outside-toplevel
import model.database.access
db_handle = model.database.access.start_database()

data_model = db_handle.data_model
time_now = datetime.datetime.utcnow()
time_now = timezone.now()
reduction_run = data_model.ReductionRun(run_number=message.run_number,
run_version=run_version,
run_description=message.description,
Expand All @@ -33,5 +37,6 @@ def create_reduction_run_record(experiment, instrument, message, run_version, sc
instrument=instrument,
status_id=status.id,
script=script_text,
started_by=message.started_by)
started_by=message.started_by,
reduction_host=socket.getfqdn())
return reduction_run
28 changes: 15 additions & 13 deletions model/database/tests/test_records.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
Unit tests for the record helper module
"""

import socket
from unittest import TestCase, mock
import model.database.records as records

Expand All @@ -32,9 +33,8 @@ def test_create_reduction_record_starts_db(db_layer):
db_layer.start_database.return_value.data_model\
.ReductionRun.assert_called_once()

@mock.patch("model.database.access")
@mock.patch("datetime.datetime")
def test_create_reduction_record_forwards_correctly(self, datetime_patch, db_layer):
@mock.patch("model.database.records.timezone")
def test_create_reduction_record_forwards_correctly(self, timezone_mock):
"""
Test: Reduction Record uses args correctly.
Any fields which are hard-coded are mocked with ANY to prevent
Expand All @@ -50,22 +50,23 @@ def test_create_reduction_record_forwards_correctly(self, datetime_patch, db_lay
mock_script_text = mock.NonCallableMock()
mock_status = mock.NonCallableMock()

returned = records.create_reduction_run_record(experiment=mock_experiment,
instrument=mock_inst,
message=mock_msg,
run_version=mock_run_version,
script_text=mock_script_text,
status=mock_status)
with mock.patch("model.database") as db_layer:
returned = records.create_reduction_run_record(experiment=mock_experiment,
instrument=mock_inst,
message=mock_msg,
run_version=mock_run_version,
script_text=mock_script_text,
status=mock_status)

mock_record_orm = db_layer.start_database.return_value.data_model
mock_record_orm = db_layer.access.start_database.return_value.data_model

self.assertEqual(mock_record_orm.ReductionRun.return_value, returned)

mock_record_orm.ReductionRun.assert_called_once_with(
run_number=mock_msg.run_number,
run_version=mock_run_version,
created=datetime_patch.utcnow.return_value,
last_updated=datetime_patch.utcnow.return_value,
created=timezone_mock.now.return_value,
last_updated=timezone_mock.now.return_value,
experiment=mock_experiment,
instrument=mock_inst,
status_id=mock_status.id,
Expand All @@ -75,4 +76,5 @@ def test_create_reduction_record_forwards_correctly(self, datetime_patch, db_lay
run_description=mock.ANY,
hidden_in_failviewer=mock.ANY,
admin_log=mock.ANY,
reduction_log=mock.ANY)
reduction_log=mock.ANY,
reduction_host=socket.getfqdn())
5 changes: 2 additions & 3 deletions queue_processors/queue_processor/handle_message.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
update relevant DB fields or logging out the status.
"""
import logging
import socket
from contextlib import contextmanager
from typing import Optional
from django.db import transaction
Expand Down Expand Up @@ -133,7 +132,8 @@ def do_create_reduction_record(self, message: Message, experiment, instrument):
message=message,
run_version=message.run_version,
script_text=script_text,
status=self.status.get_queued())
status=self.status.get_queued(),
db_handle=self.database)
reduction_run.save()

# Create a new data location entry which has a foreign key linking it to the current
Expand Down Expand Up @@ -277,7 +277,6 @@ def _common_reduction_run_update(reduction_run, status, message):
reduction_run.finished = timezone.now()
reduction_run.message = message.message
reduction_run.reduction_log = message.reduction_log
message.admin_log += "Running on host: %s" % socket.getfqdn()
reduction_run.admin_log = message.admin_log

@staticmethod
Expand Down
2 changes: 0 additions & 2 deletions queue_processors/queue_processor/reduction/runner.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@

import io
import logging
import socket
import sys
import traceback

Expand Down Expand Up @@ -61,7 +60,6 @@ def reduce(self):
def _do_reduce(self):
"""Actually do the reduction job."""
self.message.software = self._get_mantid_version()
logger.info("Running on host: %s", socket.gethostname())
if self.message.description is not None:
logger.info("DESCRIPTION: %s", self.message.description)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ def test_reduce_bad_datafile(self, _get_mantid_version: Mock, mock_logger_info:
self.message.description = "testdescription"
runner = ReductionRunner(self.message)
runner.reduce()
assert mock_logger_info.call_count == 2
mock_logger_info.assert_called_once()
assert mock_logger_info.call_args[0][1] == "testdescription"
_get_mantid_version.assert_called_once()
assert runner.message.message == 'Error encountered when trying to access the datafile /isis/data.nxs'
Expand Down
3 changes: 0 additions & 3 deletions queue_processors/queue_processor/tests/test_handle_message.py
Original file line number Diff line number Diff line change
Expand Up @@ -270,7 +270,6 @@ def test_send_message_onwards_skip_run(self, rpm):
assert self.reduction_run.status == STATUS.get_skipped()
assert "Validation error" in self.reduction_run.message
assert "Validation error" in self.reduction_run.reduction_log
assert "Running on host" in self.reduction_run.admin_log

@patch("queue_processors.queue_processor.handle_message.ReductionScript")
def test_create_run_records_multiple_versions(self, reduction_script: Mock):
Expand Down Expand Up @@ -339,7 +338,6 @@ def test_data_ready_variable_integrity_error_marks_reduction_error(self):
self.mocked_logger.error.assert_called_once()
assert self.reduction_run.status == STATUS.get_error()
assert "Encountered error when saving run variables" in self.reduction_run.message
assert "Running on host" in self.reduction_run.admin_log

def test_data_ready_no_reduce_vars(self):
"Test data_ready when the reduce_vars script does not exist and throws a FileNotFoundError"
Expand All @@ -350,7 +348,6 @@ def test_data_ready_no_reduce_vars(self):
self.mocked_logger.error.assert_called_once()
assert self.reduction_run.status == STATUS.get_error()
assert "Encountered error when saving run variables" in self.reduction_run.message
assert "Running on host" in self.reduction_run.admin_log

@patch('queue_processors.queue_processor.reduction.service.ReductionScript.load', return_value=FakeModule())
@patch("queue_processors.queue_processor.handle_message.ReductionProcessManager")
Expand Down