def test_ses_get_subarray_id_for_requested_pid(self, ses):
        """
        Verify that the private method _get_subarray_id returns
        subarray id correctly
        """
        subarray_id = 123
        process_pid = 456

        init_args = ArgCapture(fn="init",
                               fn_args=ProcedureInput(subarray_id=subarray_id),
                               time=1)
        process_summary = ProcedureSummary(
            id=process_pid,
            script=FileSystemScript("file://a"),
            script_args=[init_args],
            history=mock.MagicMock(),
            state=ProcedureState.IDLE,
        )
        expected = [process_summary]

        with patch.object(ScriptExecutionService,
                          "_summarise",
                          return_value=process_summary) as method:
            returned = ses._get_subarray_id(process_pid)

            assert method.called_with(process_pid)
            assert returned == expected[0].script_args[0].fn_args.kwargs[
                "subarray_id"]
    def test_run_args_are_captured_in_history(self, ses):
        """
        Verify that arguments to start() are captured and stored
        """
        timestamp = 12345
        pid = 456
        fn_name = "foo"
        run_args = ProcedureInput(5, 6, 7, kw3="c", kw4="d")

        # must create process for history entries to be present
        script = FileSystemScript("file://test.py")
        cmd = PrepareProcessCommand(script=script, init_args=ProcedureInput())
        with patch.object(ProcessManager, "create", return_value=pid):
            with patch.object(ScriptExecutionService, "_summarise"):
                _ = ses.prepare(cmd)

        # now we can test when method invocation args are recorded
        cmd = StartProcessCommand(pid, fn_name=fn_name, run_args=run_args)
        expected = ArgCapture(fn=fn_name, fn_args=run_args, time=timestamp)

        with patch("time.time", MagicMock(return_value=timestamp)):
            with patch.object(ScriptExecutionService, "_summarise"):
                with patch.object(ProcessManager, "run"):
                    _ = ses.start(cmd)

        assert len(ses.script_args[pid]) == 2
        assert ses.script_args[pid][1] == expected
Example #3
0
def fixture_script(tmpdir):
    """
    Pytest fixture to return a path to a script file
    """
    script_path = tmpdir.join("script.py")
    script_path.write("def main(*args, **kwargs):\n\tpass")
    return FileSystemScript(f"file://{str(script_path)}")
Example #4
0
    def test_get_module_calls_file_load_function(self, mock_file_load):
        mock_file_load.side_effect = [
            MagicMock(importlib.machinery.SourceFileLoader)
        ]

        file_script = FileSystemScript("file://test/script.py")
        _ = ModuleFactory.get_module(file_script)
        mock_file_load.assert_called_once_with(file_script.script_uri)
Example #5
0
def fixture_fail_script(tmpdir):
    """
    Pytest fixture to return a path to a script file
    """
    script_path = tmpdir.join("fail.py")
    script_path.write("""
def main(msg):
    raise Exception(msg)
""")
    return FileSystemScript(f"file://{str(script_path)}")
Example #6
0
def fixture_init_hang_script(tmpdir):
    """
    Pytest fixture to return a path to a script that sets an event
    """
    script_path = tmpdir.join("script.py")
    script_path.write("""
def init(init_running):
    init_running.wait()
    while True:
        pass
""")
    return FileSystemScript(f"file://{str(script_path)}")
def fixture_sleep_script(tmpdir):
    """
    Pytest fixture to return a path to a script that sleeps a user-defined
    amount of time.
    """
    script_path = tmpdir.join("sleep_script.py")
    script_path.write("""
import time

def init(subarray_id):
    pass

def main(secs):
    time.sleep(secs)
""")
    return FileSystemScript(f"file://{str(script_path)}")
Example #8
0
 def test_create_sends_load_and_run_messages_for_filesystemscript(
         self, manager):
     """
     Verify that a call to ProcessManager.create() sends the load and run init
     messages to ScriptWorker when filesystem script is created.
     """
     manager.ctx.Proc = MagicMock()
     script = FileSystemScript(script_uri="file://test-script.py")
     manager.create(script, init_args=ProcedureInput())
     q = manager.script_queues[1]
     load_msg = q.safe_get()
     run_msg = q.safe_get()
     assert load_msg.msg_type == "LOAD"
     assert load_msg.msg == script
     assert run_msg.msg_type == "RUN"
     assert run_msg.msg == ("init", None)
Example #9
0
def fixture_main_hang_script(tmpdir):
    """
    Pytest fixture to return a path to a script that sets an event
    """
    script_path = tmpdir.join("script.py")
    script_path.write("""
MAIN_RUNNING = None

def init(main_running):
    global MAIN_RUNNING
    MAIN_RUNNING = main_running

def main():
    MAIN_RUNNING.wait()
    while True:
        pass
""")
    return FileSystemScript(f"file://{str(script_path)}")
Example #10
0
def fixture_pubsub_script(tmpdir):
    """
    Pytest fixture to return a path to a script that emits OET events
    """
    script_path = tmpdir.join("script.py")
    script_path.write("""
import threading
from pubsub import pub
from ska_oso_oet.event import topics

def main(msg):
    pub.sendMessage(
        topics.user.script.announce,
        msg_src=threading.current_thread().name,
        msg=msg
    )
""")
    return FileSystemScript(f"file://{str(script_path)}")
    def test_ses_get_subarray_id_fails_on_missing_subarray_id(self, ses):
        """
        Verify that an exception is raised when subarray ID is missing for requested
        PID
        """
        init_args = ArgCapture(fn="init", fn_args=ProcedureInput(), time=1)
        process_summary = ProcedureSummary(
            id=1,
            script=FileSystemScript("file://a"),
            script_args=[init_args],
            history=mock.MagicMock(),
            state=ProcedureState.IDLE,
        )

        with patch.object(ScriptExecutionService,
                          "_summarise",
                          return_value=process_summary):
            with pytest.raises(ValueError):
                ses._get_subarray_id(1)  # pylint: disable=protected-access
Example #12
0
def fixture_script_that_increments_and_returns_scan_id(tmpdir):
    """
    Pytest fixture to return a path to a script with main() that increments
    the scan ID and adds the value to a queue.
    """
    path = tmpdir.join("script_for_scan_id.py")

    path.write("""
from ska_oso_oet.command import SCAN_ID_GENERATOR

Q = None

def init(q):
    global Q
    Q = q

def main():
    Q.put(SCAN_ID_GENERATOR.next())
""")
    return FileSystemScript(f"file://{str(path)}")
    def test_init_args_are_captured_in_history(self, ses):
        """
        Verify that arguments to prepare() are captured and stored.
        """
        script = FileSystemScript("file://test.py")
        init_args = ProcedureInput(5, 6, 7, kw3="c", kw4="d")
        now = time.time()
        pid = 567

        # sending this command...
        cmd = PrepareProcessCommand(script=script, init_args=init_args)
        # ... should record this in the script_args
        expected = ArgCapture(fn="init", fn_args=init_args, time=now)

        with patch("time.time", MagicMock(return_value=now)):
            with patch.object(ProcessManager, "create", return_value=pid):
                with patch.object(ScriptExecutionService, "_summarise"):
                    _ = ses.prepare(cmd)

        assert len(ses.script_args[pid]) == 1
        assert ses.script_args[pid] == [expected]
Example #14
0
def fixture_abort_script(tmpdir):
    """
    Pytest fixture to return a path to a script file
    """
    script_path = tmpdir.join("abort.py")
    script_path.write("""
import time

Q = None
MAIN_RUNNING = None

def init(q, running):
    global Q, MAIN_RUNNING
    Q, MAIN_RUNNING = q, running

def main():
    MAIN_RUNNING.wait()
    time.sleep(2)
    Q.put('foo')
""")
    return FileSystemScript(f"file://{str(script_path)}")
Example #15
0
def fixture_barrier_script(tmpdir):
    """
    Pytest fixture to return a path to a script that sets an event
    """
    script_path = tmpdir.join("script.py")
    script_path.write("""
INIT_RUNNING = None
MAIN_RUNNING = None
RESUME = None

def init(evt1, evt2, evt3):
    global INIT_RUNNING, MAIN_RUNNING, RESUME
    INIT_RUNNING, MAIN_RUNNING, RESUME = evt1, evt2, evt3

    INIT_RUNNING.wait()
    RESUME.wait()

def main():
    MAIN_RUNNING.wait()
    RESUME.wait()
""")
    return FileSystemScript(f"file://{str(script_path)}")
    ProcedureState,
)

# Endpoint for the REST API
ENDPOINT = "api/v1.0/procedures"

# Valid JSON struct for creating a new procedure
CREATE_JSON = dict(
    script={"script_type": "filesystem", "script_uri": "file:///test.py"},
    script_args={"init": dict(args=(1, 2, 3), kwargs=dict(kw1="a", kw2="b"))},
)

# object expected to be returned when creating the Procedure defined above
CREATE_SUMMARY = ProcedureSummary(
    id=1,
    script=FileSystemScript("file:///test.py"),
    script_args=[
        ArgCapture(fn="init", fn_args=ProcedureInput(1, 2, 3, kw1="a", kw2="b"), time=1)
    ],
    history=ProcedureHistory(
        process_states=[
            (ProcedureState.CREATING, 1.0),  # process starting
            (ProcedureState.IDLE, 2.0),  # process created
            (ProcedureState.LOADING, 3.0),  # user script loading
            (ProcedureState.IDLE, 4.0),  # user script loaded
            (ProcedureState.RUNNING, 5.0),  # init called
            (ProcedureState.READY, 6.0),  # init complete
        ],
        stacktrace=None,
    ),
    state=ProcedureState.READY,
Example #17
0
 def test_filesystem_script_raises_error_on_incorrect_prefix(self):
     with pytest.raises(ValueError) as e:
         _ = FileSystemScript("incorrectprefix://script.py")
     assert (
         "Incorrect prefix for FileSystemScript: incorrectprefix://script.py"
         in str(e))
Example #18
0
 def test_filesystem_script_object_creation(self):
     script = FileSystemScript("file://script.py")
     assert isinstance(script, FileSystemScript)
     assert script.script_uri == "file://script.py"