Beispiel #1
0
    def validate_ioc_test_func(
            self,
            device_name,
            record_func,
            child_conn,
            validate_pass: bool):
        """Start the IOC with the specified validate method"""

        builder.SetDeviceName(device_name)

        kwarg = {}
        if record_func in [builder.WaveformIn, builder.WaveformOut]:
            kwarg = {"length": WAVEFORM_LENGTH}  # Must specify when no value

        kwarg["validate"] = (
            self.validate_always_pass
            if validate_pass
            else self.validate_always_fail
        )

        record_func("VALIDATE-RECORD", **kwarg)

        dispatcher = asyncio_dispatcher.AsyncioDispatcher()
        builder.LoadDatabase()
        softioc.iocInit(dispatcher)

        child_conn.send("R")

        # Keep process alive while main thread runs CAGET
        if child_conn.poll(TIMEOUT):
            val = child_conn.recv()
            assert val == "D", "Did not receive expected Done character"
    def none_value_test_func(self, record_func, queue):
        """Start the IOC and catch the expected exception"""
        kwarg = {}
        if record_func in [builder.WaveformIn, builder.WaveformOut]:
            kwarg = {"length": WAVEFORM_LENGTH}  # Must specify when no value

        record = record_func("SOME-NAME", **kwarg)

        log("CHILD: About to start IOC")

        dispatcher = asyncio_dispatcher.AsyncioDispatcher()
        builder.LoadDatabase()
        softioc.iocInit(dispatcher)

        log("CHILD: Soft IOC started, about to .set(None)")

        try:
            record.set(None)
            log("CHILD: Uh-OH! No exception thrown when setting None!")
        except Exception as e:
            log("CHILD: Putting exception into queue %s", e)
            queue.put(e)
        else:
            log("CHILD: No exception raised when using None as value!")
            queue.put(Exception("FAIL: No exception raised during .set()"))
Beispiel #3
0
    def on_update_test_func(
        self, device_name, record_func, conn, always_update
    ):

        builder.SetDeviceName(device_name)

        li = builder.longIn("ON-UPDATE-COUNTER-RECORD", initial_value=0)

        def on_update_func(new_val):
            """Increments li record each time main out record receives caput"""
            li.set(li.get() + 1)

        kwarg = {}
        if record_func is builder.WaveformOut:
            kwarg = {"length": WAVEFORM_LENGTH}  # Must specify when no value

        record_func(
            "ON-UPDATE-RECORD",
            on_update=on_update_func,
            always_update=always_update,
            **kwarg)

        def on_update_done(_):
            conn.send("C")  # "Complete"
        # Put to the action record after we've done all other Puts, so we know
        # all the callbacks have finished processing
        builder.Action("ON-UPDATE-DONE", on_update=on_update_done)

        dispatcher = asyncio_dispatcher.AsyncioDispatcher()
        builder.LoadDatabase()
        softioc.iocInit(dispatcher)

        conn.send("R")  # "Ready"

        log("CHILD: Sent R over Connection to Parent")

        # Keep process alive while main thread runs CAGET
        if conn.poll(TIMEOUT):
            val = conn.recv()
            assert val == "D", "Did not receive expected Done character"

        log("CHILD: Received exit command, child exiting")
Beispiel #4
0
    def blocking_test_func(self, device_name, conn):

        builder.SetDeviceName(device_name)

        count_rec = builder.longIn("BLOCKING-COUNTER", initial_value=0)

        async def blocking_update_func(new_val):
            """A function that will block for some time"""
            log("CHILD: blocking_update_func starting")
            await asyncio.sleep(0.5)
            log("CHILD: Finished sleep!")
            completed_count = count_rec.get() + 1
            count_rec.set(completed_count)
            log(
                "CHILD: blocking_update_func finished, completed ",
                completed_count
            )

        builder.longOut(
            "BLOCKING-REC",
            on_update=blocking_update_func,
            always_update=True,
            blocking=True
        )


        dispatcher = asyncio_dispatcher.AsyncioDispatcher()
        builder.LoadDatabase()
        softioc.iocInit(dispatcher)

        conn.send("R")  # "Ready"

        log("CHILD: Sent R over Connection to Parent")

        # Keep process alive while main thread runs CAGET
        if conn.poll(TIMEOUT):
            val = conn.recv()
            assert val == "D", "Did not receive expected Done character"

        log("CHILD: Received exit command, child exiting")
Beispiel #5
0
def main():
    if "-v" in sys.argv:
        logging.basicConfig(level=logging.DEBUG, format=LOG_FORMAT)
        sys.argv.remove("-v")
    else:
        logging.basicConfig(level=logging.INFO, format=LOG_FORMAT)

    # Determine the ring mode
    if sys.argv[1:]:
        ring_mode = sys.argv[1]
    else:
        try:
            ring_mode = str(os.environ["RINGMODE"])
        except KeyError:
            try:
                value = caget("SR-CS-RING-01:MODE", format=2)
                ring_mode = value.enums[int(value)]
            except ca_nothing:
                ring_mode = "DIAD"

    # Create PVs.
    server = atip_server.ATIPServer(
        ring_mode,
        DATADIR / "limits.csv",
        DATADIR / "feedback.csv",
        DATADIR / "mirrored.csv",
        DATADIR / "tunefb.csv",
    )

    # Add special case out record for SOFB to write to.
    builder.SetDeviceName("CS-CS-MSTAT-01")
    builder.aOut("FBHEART", initial_value=10)

    # Start the IOC.
    builder.LoadDatabase()
    softioc.iocInit()
    server.monitor_mirrored_pvs()
    server.setup_tune_feedback()

    softioc.interactive_ioc(globals())
Beispiel #6
0
    def target_function(self):
        while True:
            if self.flag.is_set() is True:
                pass


# Create PVs.
pvs1 = ['PV-{0}-PC-01'.format(i + 1) for i in range(4000)]
pvs2 = ['PV-{0}-PC-02'.format(i + 1) for i in range(4000)]

# Create 4000 aIn and 4000 aOut records without background thread running.
print("Without thread:")
start = time.time()
svr = server.ATIPServer(pvs1)
print('    Total time: {0}'.format(time.time() - start))

# Start background thread
th = thread_test()

# Create 4000 aIn and 4000 aOut records with background thread running.
print("With thread:")
start = time.time()
svr = server.ATIPServer(pvs2)
print('    Total time: {0}'.format(time.time() - start))

# Start the IOC.
builder.LoadDatabase()
softioc.iocInit()

softioc.interactive_ioc(globals())
def run_ioc(record_configurations: list, conn, set_enum, get_enum):
    """Creates a record and starts the IOC. `initial_value` will be set on
    the record at different times based on the `set_enum` parameter."""

    builder.SetDeviceName(DEVICE_NAME)

    records: List[RecordWrapper] = []

    # Create records from the given list
    for configuration in record_configurations:
        kwarg = {}

        (
            record_name,
            creation_func,
            initial_value,
            expected_value,
            expected_type,
        ) = configuration

        if set_enum == SetValueEnum.INITIAL_VALUE:
            kwarg["initial_value"] = initial_value
        elif creation_func in [builder.WaveformIn, builder.WaveformOut]:
            kwarg["length"] = WAVEFORM_LENGTH  # Must specify when no value
            # Related to this issue:
            # https://github.com/dls-controls/pythonSoftIOC/issues/37

        out_rec = creation_func(record_name, **kwarg)

        if set_enum == SetValueEnum.SET_BEFORE_INIT:
            out_rec.set(initial_value)

        records.append(out_rec)

    dispatcher = asyncio_dispatcher.AsyncioDispatcher()
    builder.LoadDatabase()
    softioc.iocInit(dispatcher)
    conn.send("R")  # "Ready"

    # Record list and record config list should always be in line
    for record, configuration in zip(records, record_configurations):
        (
            record_name,
            creation_func,
            initial_value,
            expected_value,
            expected_type,
        ) = configuration

        if set_enum == SetValueEnum.SET_AFTER_INIT:
            record.set(initial_value)

    for record in records:
        if get_enum == GetValueEnum.GET:
            conn.send(record.get())
            # Some tests do a caput and require another .get()
            if set_enum == SetValueEnum.CAPUT:
                if conn.poll(TIMEOUT):
                    val = conn.recv()
                    if val == "G":
                        conn.send(record.get())
                    else:
                        pytest.fail(f"Received unexpected character {val}")

    # Keep process alive while main thread works.
    # This is most applicable to CAGET tests.
    while (True):
        if conn.poll(TIMEOUT):
            val = conn.recv()
            if val == "D":  # "Done"
                break
Beispiel #8
0
# Simple example script for building an example soft IOC.

import versions

import cothread
from softioc import softioc, builder, pvlog

from testing import *

softioc.devIocStats('TS-DI-TEST-01')

builder.LoadDatabase()
softioc.iocInit()

softioc.interactive_ioc(globals())
Beispiel #9
0
# Import the basic framework components.
from softioc import softioc, builder, asyncio_dispatcher
import asyncio

# Create an asyncio dispatcher, the event loop is now running
dispatcher = asyncio_dispatcher.AsyncioDispatcher()

# Set the record prefix
builder.SetDeviceName("MY-DEVICE-PREFIX")

# Create some records
ai = builder.aIn('AI', initial_value=5)
ao = builder.aOut('AO', initial_value=12.45, always_update=True,
                  on_update=lambda v: ai.set(v))

# Boilerplate get the IOC started
builder.LoadDatabase()
softioc.iocInit(dispatcher)

# Start processes required to be run after iocInit
async def update():
    while True:
        ai.set(ai.get() + 1)
        await asyncio.sleep(1)

asyncio.run_coroutine_threadsafe(update(), dispatcher.loop)

# Finally leave the IOC running with an interactive shell.
softioc.interactive_ioc(globals())
        t_ao = builder.aOut('ALARM', on_update=callback)

        async def on_update_name_callback(value, name):
            print(name, "value", value)

        builder.longOut(
            "NAME-CALLBACK",
            initial_value = 3,
            always_update=True,
            on_update_name=on_update_name_callback,
            blocking=True
        )

        # Run the IOC
        builder.LoadDatabase()
        softioc.iocInit(asyncio_dispatcher.AsyncioDispatcher())

        conn.send("R")  # "Ready"

        # Make sure coverage is written on epicsExit
        from pytest_cov.embed import cleanup
        sys._run_exitfuncs = cleanup

        select_and_recv(conn, "D")  # "Done"
        # Attempt to ensure all buffers flushed - C code (from `import pvlog`)
        # may not be affected by these calls...
        sys.stdout.flush()
        sys.stderr.flush()

        conn.send("D")  # "Done"