Exemple #1
0
    def setUp(self):
        """Create a Controller, TriggerGate and PoolSynchronization objects from
        dummy configurations
        """
        unittest.TestCase.setUp(self)
        try:
            from mock import Mock
        except ImportError:
            self.skipTest("mock module is not available")
        pool = FakePool()
        dummy_tg_ctrl = createPoolController(pool, dummyPoolTGCtrlConf01)
        self.dummy_tg = createPoolTriggerGate(pool, dummy_tg_ctrl,
                                              dummyTriggerGateConf01)
        dummy_tg_ctrl.add_element(self.dummy_tg)
        pool.add_element(dummy_tg_ctrl)
        pool.add_element(self.dummy_tg)
        self.cfg = createPoolSynchronizationConfiguration(
            (dummy_tg_ctrl, ),
            ((self.dummy_tg, ), ),
        )
        # Create mock and define its functions
        ctrl_methods = [
            'PreStartAll', 'StartAll', 'PreStartOne', 'StartOne',
            'PreStateAll', 'StateAll', 'PreStateOne', 'StateOne',
            'PreSynchAll', 'PreSynchOne', 'SynchOne', 'SynchAll'
        ]
        self.mock_tg_ctrl = Mock(spec=ctrl_methods)
        self.mock_tg_ctrl.StateOne.return_value = (State.Moving, 'triggering')

        dummy_tg_ctrl.ctrl = self.mock_tg_ctrl
        self.tgaction = PoolSynchronization(self.dummy_tg)
        self.tgaction.add_element(self.dummy_tg)
    def __init__(self, main_element, name="Acquisition"):
        PoolAction.__init__(self, main_element, name)
        zerodname = name + ".0DAcquisition"
        hwname = name + ".HardwareAcquisition"
        swname = name + ".SoftwareAcquisition"
        synchname = name + ".Synchronization"

        self._sw_acq_config = None
        self._0d_config = None
        self._0d_acq = Pool0DAcquisition(main_element, name=zerodname)
        self._sw_acq = PoolAcquisitionSoftware(main_element, name=swname)
        self._hw_acq = PoolAcquisitionHardware(main_element, name=hwname)
        self._synch = PoolSynchronization(main_element, name=synchname)
    def setUp(self):
        """Create a Controller, TriggerGate and PoolSynchronization objects from
        dummy configurations
        """
        unittest.TestCase.setUp(self)
        try:
            from mock import Mock
        except ImportError:
            self.skipTest("mock module is not available")
        pool = FakePool()
        dummy_tg_ctrl = createPoolController(pool, dummyPoolTGCtrlConf01)
        self.dummy_tg = createPoolTriggerGate(pool, dummy_tg_ctrl,
                                              dummyTriggerGateConf01)
        dummy_tg_ctrl.add_element(self.dummy_tg)
        pool.add_element(dummy_tg_ctrl)
        pool.add_element(self.dummy_tg)
        self.conf_ctrl = createControllerConfiguration(dummy_tg_ctrl,
                                                       [self.dummy_tg])

        self.ctrls = get_acq_ctrls([self.conf_ctrl])
        # self.cfg = createPoolSynchronizationConfiguration((dummy_tg_ctrl,),
        #                                                   ((self.dummy_tg,),),)
        # Create mock and define its functions
        ctrl_methods = ['PreStartAll', 'StartAll', 'PreStartOne', 'StartOne',
                        'PreStateAll', 'StateAll', 'PreStateOne', 'StateOne',
                        'PreSynchAll', 'PreSynchOne', 'SynchOne', 'SynchAll']
        self.mock_tg_ctrl = Mock(spec=ctrl_methods)
        self.mock_tg_ctrl.StateOne.return_value = (State.Moving, 'triggering')

        dummy_tg_ctrl.ctrl = self.mock_tg_ctrl
        self.tgaction = PoolSynchronization(self.dummy_tg)
        self.tgaction.add_element(self.dummy_tg)
 def createElements(self, ctrl_klass, ctrl_lib, ctrl_props):
     # create controller and element
     ctrl_conf = createCtrlConf(self.pool, 'tgctrl01', ctrl_klass, ctrl_lib,
                                ctrl_props)
     elem_conf = createElemConf(self.pool, 1, 'tg01')
     self.tg_ctrl = createPoolController(self.pool, ctrl_conf)
     self.tg_elem = createPoolTriggerGate(self.pool, self.tg_ctrl,
                                          elem_conf)
     # add controller and elements to containers
     self.tg_ctrl.add_element(self.tg_elem)
     self.pool.add_element(self.tg_ctrl)
     self.pool.add_element(self.tg_elem)
     # create Synchronization action and its configuration
     self.conf_ctrl = createControllerConfiguration(self.tg_ctrl,
                                                    [self.tg_elem])
     self.ctrls = get_acq_ctrls([self.conf_ctrl])
     self.tgaction = PoolSynchronization(self.tg_elem)
     self.tgaction.add_element(self.tg_elem)
Exemple #5
0
    def setUp(self):
        """Create a Controller, TriggerGate and PoolSynchronization objects from
        dummy configurations
        """
        unittest.TestCase.setUp(self)
        pool = FakePool()

        dummy_tg_ctrl = createPoolController(pool, dummyPoolTGCtrlConf01)
        self.dummy_tg = createPoolTriggerGate(pool, dummy_tg_ctrl,
                                              dummyTriggerGateConf01)
        # marrying the element with the controller
        dummy_tg_ctrl.add_element(self.dummy_tg)

        self.ctrl_conf = createControllerConfiguration(dummy_tg_ctrl,
                                                       [self.dummy_tg])

        # marrying the element with the action
        self.tg_action = PoolSynchronization(self.dummy_tg)
        self.tg_action.add_element(self.dummy_tg)
 def createElements(self, ctrl_klass, ctrl_lib, ctrl_props):
     # create controller and element
     ctrl_conf = createCtrlConf(self.pool, 'tgctrl01', ctrl_klass,
                                ctrl_lib, ctrl_props)
     elem_conf = createElemConf(self.pool, 1, 'tg01')
     self.tg_ctrl = createPoolController(self.pool, ctrl_conf)
     self.tg_elem = createPoolTriggerGate(self.pool, self.tg_ctrl,
                                          elem_conf)
     # add controller and elements to containers
     self.tg_ctrl.add_element(self.tg_elem)
     self.pool.add_element(self.tg_ctrl)
     self.pool.add_element(self.tg_elem)
     # create Synchronization action and its configuration
     self.conf_ctrl = createControllerConfiguration(self.tg_ctrl,
                                                    [self.tg_elem])
     self.ctrls = get_acq_ctrls([self.conf_ctrl])
     self.tgaction = PoolSynchronization(self.tg_elem)
     self.tgaction.add_element(self.tg_elem)
Exemple #7
0
class PoolDummyTriggerGateTestCase(unittest.TestCase):
    """Parameterizable integration test of the PoolSynchronization action and
    the DummTriggerGateController.

    Using insertTest decorator, one can add tests of a particular trigger/gate
    characteristic.
    """

    def setUp(self):
        """Create a Controller, TriggerGate and PoolSynchronization objects from
        dummy configurations
        """
        unittest.TestCase.setUp(self)
        pool = FakePool()

        dummy_tg_ctrl = createPoolController(pool, dummyPoolTGCtrlConf01)
        self.dummy_tg = createPoolTriggerGate(pool, dummy_tg_ctrl,
                                              dummyTriggerGateConf01)
        # marrying the element with the controller
        dummy_tg_ctrl.add_element(self.dummy_tg)

        self.ctrl_conf = createControllerConfiguration(dummy_tg_ctrl,
                                                       [self.dummy_tg])

        # marrying the element with the action
        self.tg_action = PoolSynchronization(self.dummy_tg)
        self.tg_action.add_element(self.dummy_tg)

    def generation(self, synchronization):
        """Verify that the created PoolTGAction start_action starts correctly
        the involved controller."""
        args = ([self.ctrl_conf], synchronization)
        self.tg_action.start_action(*args)
        self.tg_action.action_loop()
        # TODO: add asserts applicable to a dummy controller e.g. listen to
        # state changes and verify if the change ON->MOVING-ON was emitted

    def tearDown(self):
        unittest.TestCase.tearDown(self)
Exemple #8
0
class SynchronizationTestCase(object):
    """Base class for integration tests of PoolSynchronization class and any
    PoolTriggerGateController. Test is parameterized using trigger parameters.

    .. seealso:: :meth:`taurus.test.base.insertTest`"""
    def createElements(self, ctrl_klass, ctrl_lib, ctrl_props):
        # create controller and element
        ctrl_conf = createCtrlConf(self.pool, 'tgctrl01', ctrl_klass, ctrl_lib,
                                   ctrl_props)
        elem_conf = createElemConf(self.pool, 1, 'tg01')
        self.tg_ctrl = createPoolController(self.pool, ctrl_conf)
        self.tg_elem = createPoolTriggerGate(self.pool, self.tg_ctrl,
                                             elem_conf)
        # add controller and elements to containers
        self.tg_ctrl.add_element(self.tg_elem)
        self.pool.add_element(self.tg_ctrl)
        self.pool.add_element(self.tg_elem)
        # create Synchronization action and its configuration
        self.tg_cfg = createPoolSynchronizationConfiguration(
            (self.tg_ctrl, ),
            ((self.tg_elem, ), ),
        )
        self.tgaction = PoolSynchronization(self.tg_elem)
        self.tgaction.add_element(self.tg_elem)

    def setUp(self):
        """Create a FakePool object.
        """
        self.pool = FakePool()

    def tggeneration(self, ctrl_lib, ctrl_klass, ctrl_props, synchronization):
        """Helper method to verify trigger element states before and after
        trigger/gate generation.

       :param ctrl_lib: controller library used for the test
       :type ctrl_lib: :obj:`str`
       :param ctrl_klass: controller class used for the test
       :type ctrl_klass: :obj:`str`
       :param offset: temporal offset before beginning the trigger generation
       :type offset: float
       :param active_interval: signal at which triggers will be generated
       :type active_interval: float
       :param passive_interval: temporal passive period between two active periods
       :type passive_interval: float
       :param repetitions: number of generated triggers
       :type repetitions: int
        """

        # create controller and trigger element
        self.createElements(ctrl_klass, ctrl_lib, ctrl_props)

        # create start_action arguments
        args = ()
        kwargs = {'config': self.tg_cfg, 'synchronization': synchronization}
        # starting action
        self.tgaction.start_action(*args, **kwargs)
        # verifying that the elements involved in action changed its state
        element_state = self.tg_elem.get_state()
        msg = ("State after start_action is '%s'. (Expected: '%s')" %
               (State.get(element_state), "Moving"))
        self.assertEqual(element_state, State.Moving, msg)
        # entering action loop
        self.tgaction.action_loop()
        # verifying that the elements involved in action changed its state
        element_state = self.tg_elem.get_state()
        msg = ("State after action_loop shall be different than Moving")
        self.assertNotEqual(element_state, State.Moving, msg)

    def stopGeneration(self):
        """Method used to change the controller (mock) state"""
        self.tgaction.stop_action()

    def abort_tggeneration(self, ctrl_lib, ctrl_klass, ctrl_props,
                           synchronization, abort_time):
        """Helper method to verify trigger element states before and after
        trigger/gate generation when aborting the trigger generation.

       :param ctrl_lib: controller library used for the test
       :type ctrl_lib: :obj:`str`
       :param ctrl_klass: controller class used for the test
       :type ctrl_klass: :obj:`str`
       :param offset: temporal offset before beginning the trigger generation
       :type offset: float
       :param active_interval: signal at which triggers will be generated
       :type active_interval: float
       :param passive_interval: temporal passive period between two active periods
       :type passive_interval: float
       :param repetitions: number of generated triggers
       :type repetitions: int
       :param abort_time: wait this time before stopping the trigger generation.
       :type abort_time: float
        """

        # create controller and trigger element
        self.createElements(ctrl_klass, ctrl_lib, ctrl_props)

        # create start_action arguments
        args = ()
        kwargs = {'config': self.tg_cfg, 'synchronization': synchronization}
        # starting action
        self.tgaction.start_action(*args, **kwargs)
        # verifying that the elements involved in action changed its state
        element_state = self.tg_elem.get_state()
        msg = ("State after start_action is '%s'. (Expected: '%s')" %
               (State.get(element_state), "Moving"))
        self.assertEqual(element_state, State.Moving, msg)

        # starting timer (abort_time) stop the trigger generation
        threading.Timer(abort_time, self.stopGeneration).start()

        # entering action loop
        self.tgaction.action_loop()
        # verifying that the elements involved in action changed its state
        element_state = self.tg_elem.get_state()
        msg = ("State after action_loop shall be different than Moving")
        self.assertNotEqual(element_state, State.Moving, msg)

    def tearDown(self):
        self.tgaction = None
        self.tg_ctrl = None
        self.tg_cfg = None
        self.tg_elem = None
class SynchronizationTestCase(object):
    """Base class for integration tests of PoolSynchronization class and any
    PoolTriggerGateController. Test is parameterized using trigger parameters.

    .. seealso:: :meth:`taurus.test.base.insertTest`"""

    def createElements(self, ctrl_klass, ctrl_lib, ctrl_props):
        # create controller and element
        ctrl_conf = createCtrlConf(self.pool, 'tgctrl01', ctrl_klass,
                                   ctrl_lib, ctrl_props)
        elem_conf = createElemConf(self.pool, 1, 'tg01')
        self.tg_ctrl = createPoolController(self.pool, ctrl_conf)
        self.tg_elem = createPoolTriggerGate(self.pool, self.tg_ctrl,
                                             elem_conf)
        # add controller and elements to containers
        self.tg_ctrl.add_element(self.tg_elem)
        self.pool.add_element(self.tg_ctrl)
        self.pool.add_element(self.tg_elem)
        # create Synchronization action and its configuration
        self.conf_ctrl = createControllerConfiguration(self.tg_ctrl,
                                                       [self.tg_elem])
        self.ctrls = get_acq_ctrls([self.conf_ctrl])
        self.tgaction = PoolSynchronization(self.tg_elem)
        self.tgaction.add_element(self.tg_elem)

    def setUp(self):
        """Create a FakePool object.
        """
        self.pool = FakePool()

    def tggeneration(self, ctrl_lib, ctrl_klass, ctrl_props,
                     synchronization):
        """Helper method to verify trigger element states before and after
        trigger/gate generation.

       :param ctrl_lib: controller library used for the test
       :type ctrl_lib: :obj:`str`
       :param ctrl_klass: controller class used for the test
       :type ctrl_klass: :obj:`str`
       :param offset: temporal offset before beginning the trigger generation
       :type offset: float
       :param active_interval: signal at which triggers will be generated
       :type active_interval: float
       :param passive_interval: temporal passive period between two active
                                periods
       :type passive_interval: float
       :param repetitions: number of generated triggers
       :type repetitions: int
        """

        # create controller and trigger element
        self.createElements(ctrl_klass, ctrl_lib, ctrl_props)

        # create start_action arguments
        args = (self.ctrls, synchronization)
        kwargs = {}
        # starting action
        self.tgaction.start_action(*args, **kwargs)
        # verifying that the elements involved in action changed its state
        element_state = self.tg_elem.get_state()
        msg = ("State after start_action is '%s'. (Expected: '%s')" %
               (State.get(element_state), "Moving"))
        self.assertEqual(element_state, State.Moving, msg)
        # entering action loop
        self.tgaction.action_loop()
        # verifying that the elements involved in action changed its state
        element_state = self.tg_elem.get_state()
        msg = ("State after action_loop shall be different than Moving")
        self.assertNotEqual(element_state, State.Moving, msg)

    def stopGeneration(self):
        """Method used to change the controller (mock) state"""
        self.tgaction.stop_action()

    def abort_tggeneration(self, ctrl_lib, ctrl_klass, ctrl_props,
                           synchronization, abort_time):
        """Helper method to verify trigger element states before and after
        trigger/gate generation when aborting the trigger generation.

       :param ctrl_lib: controller library used for the test
       :type ctrl_lib: :obj:`str`
       :param ctrl_klass: controller class used for the test
       :type ctrl_klass: :obj:`str`
       :param offset: temporal offset before beginning the trigger generation
       :type offset: float
       :param active_interval: signal at which triggers will be generated
       :type active_interval: float
       :param passive_interval: temporal passive period between two active
                                periods
       :type passive_interval: float
       :param repetitions: number of generated triggers
       :type repetitions: int
       :param abort_time: wait this time before stopping the trigger generation
       :type abort_time: float
        """

        # create controller and trigger element
        self.createElements(ctrl_klass, ctrl_lib, ctrl_props)

        # create start_action arguments
        args = (self.ctrls, synchronization)
        kwargs = {}
        # starting action
        self.tgaction.start_action(*args, **kwargs)
        # verifying that the elements involved in action changed its state
        element_state = self.tg_elem.get_state()
        msg = ("State after start_action is '%s'. (Expected: '%s')" %
               (State.get(element_state), "Moving"))
        self.assertEqual(element_state, State.Moving, msg)

        # starting timer (abort_time) stop the trigger generation
        threading.Timer(abort_time, self.stopGeneration).start()

        # entering action loop
        self.tgaction.action_loop()
        # verifying that the elements involved in action changed its state
        element_state = self.tg_elem.get_state()
        msg = ("State after action_loop shall be different than Moving")
        self.assertNotEqual(element_state, State.Moving, msg)

    def tearDown(self):
        self.tgaction = None
        self.tg_ctrl = None
        self.tg_cfg = None
        self.tg_elem = None
Exemple #10
0
class AcquisitionTestCase(BasePoolTestCase):

    def setUp(self):
        """Create a Controller, TriggerGate and PoolSynchronization objects from
        dummy configurations.
        """
        BasePoolTestCase.setUp(self)
        self.l = AttributeListener()
        self.channel_names = []

    def createPoolSynchronization(self, tg_list):
        self.main_element = FakeElement(self.pool)
        self.tggeneration = PoolSynchronization(self.main_element)
        for tg in tg_list:
            self.tggeneration.add_element(tg)
        self.tggeneration.add_listener(self)

    def hw_continuous_acquisition(self, offset, active_interval,
                                  passive_interval, repetitions, integ_time):
        """Executes measurement running the TGGeneration and Acquisition
        actions according the test parameters. Checks the lengths of the
        acquired data.
        """
        # obtaining elements created in the BasePoolTestCase.setUp
        tg = self.tgs[self.tg_elem_name]
        tg_ctrl = tg.get_controller()
        # crating configuration for TGGeneration
        tg_cfg = createPoolSynchronizationConfiguration((tg_ctrl,),
                                                        ((tg,),))
        # creating PoolSynchronization action
        self.createPoolSynchronization([tg])

        channels = []
        for name in self.channel_names:
            channels.append(self.cts[name])

        ct_ctrl = self.ctrls[self.chn_ctrl_name]

        # add_listeners
        self.addListeners(channels)
        # creating acquisition configurations
        self.hw_acq_cfg = createCTAcquisitionConfiguration((ct_ctrl,),
                                                           (channels,))
        # creating acquisition actions
        self.hw_acq = PoolAcquisitionHardware(channels[0])
        for channel in channels:
            self.hw_acq.add_element(channel)

        # get the current number of jobs
        jobs_before = get_thread_pool().qsize

        ct_ctrl.set_ctrl_par('synchronization', AcqSynch.HardwareTrigger)

        hw_acq_args = ()
        hw_acq_kwargs = {
            'integ_time': integ_time,
            'repetitions': repetitions,
            'config': self.hw_acq_cfg,
        }
        self.hw_acq.run(hw_acq_args, **hw_acq_kwargs)
        tg_args = ()
        tg_kwargs = {
            'offset': offset,
            'active_interval': active_interval,
            'passive_interval': passive_interval,
            'repetitions': repetitions,
            'config': tg_cfg
        }
        self.tggeneration.run(*tg_args, **tg_kwargs)
        # waiting for acquisition and tggeneration to finish
        while self.hw_acq.is_running() or self.tggeneration.is_running():
            time.sleep(1)

        self.do_asserts(self.channel_names, repetitions, jobs_before)

    def hw_step_acquisition(self, repetitions, integ_time):
        """Executes measurement running the TGGeneration and Acquisition
        actions according the test parameters. Checks the lengths of the
        acquired data.
        """

        channels = []
        for name in self.channel_names:
            channels.append(self.cts[name])

        ct_ctrl = self.ctrls[self.chn_ctrl_name]

        # creating acquisition configurations
        self.acq_cfg = createCTAcquisitionConfiguration((ct_ctrl,),
                                                        (channels,))
        # creating acquisition actions
        main_element = FakeElement(self.pool)
        self.ct_acq = PoolAcquisitionSoftware(main_element)
        for channel in channels:
            self.ct_acq.add_element(channel)

        ct_ctrl.set_ctrl_par('synchronization', AcqSynch.SoftwareTrigger)

        ct_acq_args = ()
        ct_acq_kwargs = {
            'integ_time': integ_time,
            'repetitions': repetitions,
            'config': self.acq_cfg,
        }
        self.ct_acq.run(ct_acq_args, **ct_acq_kwargs)
        # waiting for acquisition
        while self.ct_acq.is_running():
            time.sleep(0.02)

        for channel in channels:
            name = channel.name
            value = channel.value.value
            print 'channel: %s = %s' % (name, value)
            msg = ('Value for channel %s is of type %s, should be <float>' %
                   (name, type(value)))
            self.assertIsInstance(value, float, msg)

    def addListeners(self, chn_list):
        for chn in chn_list:
            chn.add_listener(self.l)

    def do_asserts(self, channel_names, repetitions, jobs_before):
        # print acquisition records
        table = self.l.get_table()
        header = table.dtype.names
        print header
        n_rows = table.shape[0]
        for row in xrange(n_rows):
            print row, table[row]
        # checking if all channels produced data
        for channel in channel_names:
            msg = 'data from channel %s were not acquired' % channel
            self.assertIn(channel, header, msg)
        # checking if all the data were acquired
        for ch_name in header:
            ch_data_len = len(table[ch_name])
            msg = 'length of data for channel %s is %d and should be %d' %\
                (ch_name, ch_data_len, repetitions)
            self.assertEqual(ch_data_len, repetitions, msg)
        # checking if there are no pending jobs
        jobs_after = get_thread_pool().qsize
        msg = ('there are %d jobs pending to be done after the acquisition ' +
               '(before: %d)') % (jobs_after, jobs_before)
        self.assertEqual(jobs_before, jobs_after, msg)

    def tearDown(self):
        BasePoolTestCase.tearDown(self)
        self.l = None
        self.channel_names = None
Exemple #11
0
 def createPoolSynchronization(self, tg_list):
     self.main_element = FakeElement(self.pool)
     self.tggeneration = PoolSynchronization(self.main_element)
     for tg in tg_list:
         self.tggeneration.add_element(tg)
     self.tggeneration.add_listener(self)
 def __init__(self, **kwargs):
     kwargs['elem_type'] = ElementType.TriggerGate
     PoolElement.__init__(self, **kwargs)
     tggen_name = "%s.TGGeneration" % self._name
     self.set_action_cache(PoolSynchronization(self, name=tggen_name))
     self._index = Index(self)
Exemple #13
0
class PoolTriggerGateTestCase(unittest.TestCase):
    """Unittest of PoolSynchronization class"""
    def setUp(self):
        """Create a Controller, TriggerGate and PoolSynchronization objects from
        dummy configurations
        """
        unittest.TestCase.setUp(self)
        try:
            from mock import Mock
        except ImportError:
            self.skipTest("mock module is not available")
        pool = FakePool()
        dummy_tg_ctrl = createPoolController(pool, dummyPoolTGCtrlConf01)
        self.dummy_tg = createPoolTriggerGate(pool, dummy_tg_ctrl,
                                              dummyTriggerGateConf01)
        dummy_tg_ctrl.add_element(self.dummy_tg)
        pool.add_element(dummy_tg_ctrl)
        pool.add_element(self.dummy_tg)
        self.cfg = createPoolSynchronizationConfiguration(
            (dummy_tg_ctrl, ),
            ((self.dummy_tg, ), ),
        )
        # Create mock and define its functions
        ctrl_methods = [
            'PreStartAll', 'StartAll', 'PreStartOne', 'StartOne',
            'PreStateAll', 'StateAll', 'PreStateOne', 'StateOne',
            'PreSynchAll', 'PreSynchOne', 'SynchOne', 'SynchAll'
        ]
        self.mock_tg_ctrl = Mock(spec=ctrl_methods)
        self.mock_tg_ctrl.StateOne.return_value = (State.Moving, 'triggering')

        dummy_tg_ctrl.ctrl = self.mock_tg_ctrl
        self.tgaction = PoolSynchronization(self.dummy_tg)
        self.tgaction.add_element(self.dummy_tg)

    def stopGeneration(self):
        """Method used to change the controller (mock) state"""
        self.mock_tg_ctrl.StateOne.return_value = (State.On, 'On')

    def test_tggeneration(self):
        """Verify trigger element states before and after action_loop."""
        from mock import call
        args = ()
        kwargs = {'config': self.cfg}
        # starting action
        self.tgaction.start_action(*args, **kwargs)
        # verifying that the action correctly started the involved controller
        self.mock_tg_ctrl.assert_has_calls([
            call.PreStartAll(), (call.PreStartOne(1, )), (call.StartOne(1, )),
            (call.StartAll())
        ])
        # verifying that the elements involved in action changed its state
        element_state = self.dummy_tg.get_state()
        msg = ("State after start_action is '%s'. (Expected: '%s')" %
               (State.get(element_state), "Moving"))
        self.assertEqual(element_state, State.Moving, msg)
        # starting timer (1 s) which will change the controller state
        threading.Timer(1, self.stopGeneration).start()
        # entering action loop
        self.tgaction.action_loop()
        # verifying that the action checked the controller states
        self.mock_tg_ctrl.assert_has_calls([
            call.PreStateAll(),
            call.PreStateOne(1, ),
            call.StateAll(),
            call.StateOne(1, )
        ])
        # verifying that the elements involved in action changed its state
        element_state = self.dummy_tg.get_state()
        msg = ("State after action_loop shall be different than Moving")
        self.assertNotEqual(element_state, State.Moving, msg)

    def tearDown(self):
        self.tgaction = None
        self.mock_tg_ctrl = None
        self.cfg = None
        self.dummy_tg = None
        unittest.TestCase.tearDown(self)
class PoolTriggerGateTestCase(unittest.TestCase):
    """Unittest of PoolSynchronization class"""

    def setUp(self):
        """Create a Controller, TriggerGate and PoolSynchronization objects from
        dummy configurations
        """
        unittest.TestCase.setUp(self)
        try:
            from mock import Mock
        except ImportError:
            self.skipTest("mock module is not available")
        pool = FakePool()
        dummy_tg_ctrl = createPoolController(pool, dummyPoolTGCtrlConf01)
        self.dummy_tg = createPoolTriggerGate(pool, dummy_tg_ctrl,
                                              dummyTriggerGateConf01)
        dummy_tg_ctrl.add_element(self.dummy_tg)
        pool.add_element(dummy_tg_ctrl)
        pool.add_element(self.dummy_tg)
        self.conf_ctrl = createControllerConfiguration(dummy_tg_ctrl,
                                                       [self.dummy_tg])

        self.ctrls = get_acq_ctrls([self.conf_ctrl])
        # self.cfg = createPoolSynchronizationConfiguration((dummy_tg_ctrl,),
        #                                                   ((self.dummy_tg,),),)
        # Create mock and define its functions
        ctrl_methods = ['PreStartAll', 'StartAll', 'PreStartOne', 'StartOne',
                        'PreStateAll', 'StateAll', 'PreStateOne', 'StateOne',
                        'PreSynchAll', 'PreSynchOne', 'SynchOne', 'SynchAll']
        self.mock_tg_ctrl = Mock(spec=ctrl_methods)
        self.mock_tg_ctrl.StateOne.return_value = (State.Moving, 'triggering')

        dummy_tg_ctrl.ctrl = self.mock_tg_ctrl
        self.tgaction = PoolSynchronization(self.dummy_tg)
        self.tgaction.add_element(self.dummy_tg)

    def stopGeneration(self):
        """Method used to change the controller (mock) state"""
        self.mock_tg_ctrl.StateOne.return_value = (State.On, 'On')

    def test_tggeneration(self):
        """Verify trigger element states before and after action_loop."""
        from mock import call, MagicMock
        # starting action
        synchronization = MagicMock()
        self.tgaction.start_action(self.ctrls, synchronization)
        # verifying that the action correctly started the involved controller
        self.mock_tg_ctrl.assert_has_calls([call.PreStartAll(),
                                            (call.PreStartOne(1,)),
                                            (call.StartOne(1,)),
                                            (call.StartAll())])
        # verifying that the elements involved in action changed its state
        element_state = self.dummy_tg.get_state()
        msg = ("State after start_action is '%s'. (Expected: '%s')" %
               (State.get(element_state), "Moving"))
        self.assertEqual(element_state, State.Moving, msg)
        # starting timer (1 s) which will change the controller state
        threading.Timer(1, self.stopGeneration).start()
        # entering action loop
        self.tgaction.action_loop()
        # verifying that the action checked the controller states
        self.mock_tg_ctrl.assert_has_calls([call.PreStateAll(),
                                            call.PreStateOne(1,),
                                            call.StateAll(),
                                            call.StateOne(1,)])
        # verifying that the elements involved in action changed its state
        element_state = self.dummy_tg.get_state()
        msg = ("State after action_loop shall be different than Moving")
        self.assertNotEqual(element_state, State.Moving, msg)

    def tearDown(self):
        self.tgaction = None
        self.mock_tg_ctrl = None
        self.cfg = None
        self.dummy_tg = None
        unittest.TestCase.tearDown(self)
Exemple #15
0
class PoolAcquisition(PoolAction):
    def __init__(self, main_element, name="Acquisition"):
        PoolAction.__init__(self, main_element, name)
        zerodname = name + ".0DAcquisition"
        hwname = name + ".HardwareAcquisition"
        swname = name + ".SoftwareAcquisition"
        synchname = name + ".Synchronization"

        self._sw_acq_config = None
        self._0d_config = None
        self._0d_acq = Pool0DAcquisition(main_element, name=zerodname)
        self._sw_acq = PoolAcquisitionSoftware(main_element, name=swname)
        self._hw_acq = PoolAcquisitionHardware(main_element, name=hwname)
        self._synch = PoolSynchronization(main_element, name=synchname)

    def set_sw_config(self, config):
        self._sw_acq_config = config

    def set_0d_config(self, config):
        self._0d_config = config

    def event_received(self, *args, **kwargs):
        timestamp = time.time()
        _, type_, value = args
        name = type_.name
        if name == "state":
            return
        t_fmt = '%Y-%m-%d %H:%M:%S.%f'
        t_str = datetime.datetime.fromtimestamp(timestamp).strftime(t_fmt)
        msg = '%s event with id: %d received at: %s' % (name, value, t_str)
        self.debug(msg)
        if name == "active":
            # this code is not thread safe, but for the moment we assume that
            # only one EventGenerator will work at the same time
            if self._sw_acq_config:
                if self._sw_acq._is_started() or self._sw_acq.is_running():
                    msg = ('Skipping trigger: software acquisition is still'
                           ' in progress.')
                    self.debug(msg)
                    return
                else:
                    self.debug('Executing software acquisition.')
                    args = ()
                    kwargs = self._sw_acq_config
                    kwargs['synch'] = True
                    kwargs['idx'] = value
                    self._sw_acq._started = True
                    get_thread_pool().add(self._sw_acq.run, *args, **kwargs)
            if self._0d_config:
                if self._0d_acq._is_started() or self._0d_acq.is_running():
                    msg = ('Skipping trigger: ZeroD acquisition is still in'
                           ' progress.')
                    self.debug(msg)
                    return
                else:
                    self.debug('Executing ZeroD acquisition.')
                    args = ()
                    kwargs = self._0d_config
                    kwargs['synch'] = True
                    kwargs['idx'] = value
                    self._0d_acq._started = True
                    self._0d_acq._stopped = False
                    self._0d_acq._aborted = False
                    get_thread_pool().add(self._0d_acq.run, *args, **kwargs)
        elif name == "passive":
            if self._0d_config and (self._0d_acq._is_started()
                                    or self._0d_acq.is_running()):
                self.debug('Stopping ZeroD acquisition.')
                self._0d_acq.stop_action()

    def is_running(self):
        return self._0d_acq.is_running() or\
            self._sw_acq.is_running() or\
            self._hw_acq.is_running() or\
            self._synch.is_running()

    def run(self, *args, **kwargs):
        for elem in self.get_elements():
            elem.put_state(None)
            # TODO: temporarily clear value buffers at the beginning of the
            # acquisition instead of doing it in the finish hook of each
            # acquisition sub-actions. See extensive explanation in the
            # constructor of PoolAcquisitionBase.
            try:
                elem.clear_value_buffer()
            except AttributeError:
                continue
            # clean also the pseudo counters, even the ones that do not
            # participate directly in the acquisition
            for pseudo_elem in elem.get_pseudo_elements():
                pseudo_elem.clear_value_buffer()
        config = kwargs['config']
        synchronization = kwargs["synchronization"]
        integ_time = extract_integ_time(synchronization)
        repetitions = extract_repetitions(synchronization)
        # TODO: this code splits the global mg configuration into
        # experimental channels triggered by hw and experimental channels
        # triggered by sw. Refactor it!!!!
        (hw_acq_cfg, sw_acq_cfg,
         zerod_acq_cfg) = split_MGConfigurations(config)
        synch_cfg, _ = getTGConfiguration(config)
        # starting continuous acquisition only if there are any controllers
        if len(hw_acq_cfg['controllers']):
            cont_acq_kwargs = dict(kwargs)
            cont_acq_kwargs['config'] = hw_acq_cfg
            cont_acq_kwargs['integ_time'] = integ_time
            cont_acq_kwargs['repetitions'] = repetitions
            self._hw_acq.run(*args, **cont_acq_kwargs)
        if len(sw_acq_cfg['controllers']) or len(zerod_acq_cfg['controllers']):
            self._synch.add_listener(self)
            if len(sw_acq_cfg['controllers']):
                sw_acq_kwargs = dict(kwargs)
                sw_acq_kwargs['config'] = sw_acq_cfg
                sw_acq_kwargs['integ_time'] = integ_time
                sw_acq_kwargs['repetitions'] = 1
                self.set_sw_config(sw_acq_kwargs)
            if len(zerod_acq_cfg['controllers']):
                zerod_acq_kwargs = dict(kwargs)
                zerod_acq_kwargs['config'] = zerod_acq_cfg
                self.set_0d_config(zerod_acq_kwargs)
        synch_kwargs = dict(kwargs)
        synch_kwargs['config'] = synch_cfg
        self._synch.run(*args, **synch_kwargs)

    def _get_action_for_element(self, element):
        elem_type = element.get_type()
        if elem_type in TYPE_TIMERABLE_ELEMENTS:
            main_element = self.main_element
            channel_to_acq_synch = main_element._channel_to_acq_synch
            acq_synch = channel_to_acq_synch.get(element)
            if acq_synch in (AcqSynch.SoftwareTrigger, AcqSynch.SoftwareGate):
                return self._sw_acq
            elif acq_synch in (AcqSynch.HardwareTrigger,
                               AcqSynch.HardwareGate):
                return self._hw_acq
            else:
                # by default software synchronization is in use
                return self._sw_acq
        elif elem_type == ElementType.ZeroDExpChannel:
            return self._0d_acq
        elif elem_type == ElementType.TriggerGate:
            return self._synch
        else:
            raise RuntimeError("Could not determine action for element %s" %
                               element)

    def clear_elements(self):
        """Clears all elements from this action"""

    def add_element(self, element):
        """Adds a new element to this action.

        :param element: the new element to be added
        :type element: sardana.pool.poolelement.PoolElement"""
        action = self._get_action_for_element(element)
        action.add_element(element)

    def remove_element(self, element):
        """Removes an element from this action. If the element is not part of
        this action, a ValueError is raised.

        :param element: the new element to be removed
        :type element: sardana.pool.poolelement.PoolElement

        :raises: ValueError"""
        for action in self._get_acq_for_element(element):
            action.remove_element(element)

    def get_elements(self, copy_of=False):
        """Returns a sequence of all elements involved in this action.

        :param copy_of: If False (default) the internal container of
                        elements is returned. If True, a copy of the
                        internal container is returned instead
        :type copy_of: bool
        :return: a sequence of all elements involved in this action.
        :rtype: seq<sardana.pool.poolelement.PoolElement>"""
        return (self._hw_acq.get_elements() + self._sw_acq.get_elements() +
                self._0d_acq.get_elements() + self._synch.get_elements())

    def get_pool_controller_list(self):
        """Returns a list of all controller elements involved in this action.

        :return: a list of all controller elements involved in this action.
        :rtype: list<sardana.pool.poolelement.PoolController>"""
        return self._pool_ctrl_list

    def get_pool_controllers(self):
        """Returns a dict of all controller elements involved in this action.

        :return: a dict of all controller elements involved in this action.
        :rtype: dict<sardana.pool.poolelement.PoolController,
                seq<sardana.pool.poolelement.PoolElement>>"""
        ret = {}
        ret.update(self._hw_acq.get_pool_controllers())
        ret.update(self._sw_acq.get_pool_controllers())
        ret.update(self._0d_acq.get_pool_controllers())
        return ret

    def read_value(self, ret=None, serial=False):
        """Reads value information of all elements involved in this action

        :param ret: output map parameter that should be filled with value
                    information. If None is given (default), a new map is
                    created an returned
        :type ret: dict
        :param serial: If False (default) perform controller HW value requests
                       in parallel. If True, access is serialized.
        :type serial: bool
        :return: a map containing value information per element
        :rtype: dict<:class:~`sardana.pool.poolelement.PoolElement`,
                     :class:~`sardana.sardanavalue.SardanaValue`>"""
        # TODO: this is broken now - fix it
        ret = self._ct_acq.read_value(ret=ret, serial=serial)
        ret.update(self._0d_acq.read_value(ret=ret, serial=serial))
        return ret