Esempio n. 1
0
class DataSetQualificationTestCase(DataSetTestCase):
    """
    Base class for dataset driver unit tests
    """
    def setUp(self):
        """
        Startup the container and start the agent.
        """
        super(DataSetQualificationTestCase, self).setUp()

        self.instrument_agent_manager = InstrumentAgentClient()
        self.instrument_agent_manager.start_container(
            deploy_file=self.test_config.container_deploy_file)

        self.container = self.instrument_agent_manager.container

        gevent.sleep(5)
        log.debug("Packet Config: %s", self.test_config.agent_packet_config)
        self.data_subscribers = InstrumentAgentDataSubscribers(
            packet_config=self.test_config.agent_packet_config, )
        self.event_subscribers = InstrumentAgentEventSubscribers(
            instrument_agent_resource_id=self.test_config.agent_resource_id)

        self.init_dataset_agent_client()

        self.event_subscribers.events_received = []
        self.data_subscribers.start_data_subscribers()

        log.debug("********* setUp complete.  Begin Testing *********")

        self.addCleanup(self._end_test)

    def _end_test(self):
        """
        Cleanup after the test completes or fails
        """
        self.assert_reset()
        self.event_subscribers.stop()
        self.data_subscribers.stop_data_subscribers()
        self.instrument_agent_manager.stop_container()

        log.debug("Test complete and all cleaned up.")

    def init_dataset_agent_client(self):
        log.info("Start Dataset Agent Client")

        # Start instrument agent client.
        self.instrument_agent_manager.start_client(
            name=self.test_config.agent_name,
            module=self.test_config.agent_module,
            cls=self.test_config.agent_class,
            config=self._agent_config(),
            resource_id=self.test_config.agent_resource_id,
            deploy_file=self.test_config.container_deploy_file,
            bootmode='reset')

        self.dataset_agent_client = self.instrument_agent_manager.instrument_agent_client

    def get_samples(self, stream_name, sample_count=1, timeout=10):
        """
        listen on a stream until 'sample_count' samples are read and return
        a list of all samples read.  If the required number of samples aren't
        read then throw an exception.

        Note that this method does not clear the sample queue for the stream.
        This should be done explicitly by the caller.  However, samples that
        are consumed by this method are removed.

        @raise SampleTimeout - if the required number of samples aren't read
        """
        result = []
        start_time = time.time()
        i = 1

        log.debug("Fetch %d sample(s) from stream '%s'" %
                  (sample_count, stream_name))
        while (len(result) < sample_count):
            if (self.data_subscribers.samples_received.has_key(stream_name)
                    and len(
                        self.data_subscribers.samples_received.get(
                            stream_name))):
                log.trace("get_samples() received sample #%d!", i)
                result.append(
                    self.data_subscribers.samples_received[stream_name].pop())
                i += 1

            # Check for timeout
            if (start_time + timeout < time.time()):
                raise SampleTimeout()

            if (not self.data_subscribers.samples_received.has_key(stream_name)
                    or len(
                        self.data_subscribers.samples_received.get(
                            stream_name)) == 0):
                log.debug(
                    "No samples in the queue, sleep for a bit to let the queue fill up"
                )
                gevent.sleep(.2)

        log.debug("get_samples() complete.  returning %d records",
                  sample_count)
        return result

    def assert_sample_queue_size(self, stream_name, size):
        """
        Verify that a queue has size samples in it.
        """
        if (not self.data_subscribers.samples_received.has_key(stream_name)
                and size == 0):
            return

        self.assertTrue(
            self.data_subscribers.samples_received.has_key(stream_name),
            msg="Sample queue does not exists")
        self.assertEqual(
            len(self.data_subscribers.samples_received.get(stream_name)), size)

    def assert_data_values(self, particles, dataset_definition_file):
        """
        Verify particles match the particles defined in the definition file
        """
        rs_file = self._get_source_data_file(dataset_definition_file)
        rs = ResultSet(rs_file)

        self.assertTrue(rs.verify(particles))

    def assert_initialize(self, final_state=ResourceAgentState.STREAMING):
        '''
        Walk through DSA states to get to streaming mode from uninitialized
        '''
        log.debug("Initialize DataSet agent")
        cmd = AgentCommand(command=ResourceAgentEvent.INITIALIZE)
        retval = self.dataset_agent_client.execute_agent(cmd)
        state = self.dataset_agent_client.get_agent_state()
        self.assertEqual(state, ResourceAgentState.INACTIVE)
        log.info("Sent INITIALIZE; DSA state = %s", state)

        log.debug("DataSet agent go active")
        cmd = AgentCommand(command=ResourceAgentEvent.GO_ACTIVE)
        retval = self.dataset_agent_client.execute_agent(cmd)
        state = self.dataset_agent_client.get_agent_state()
        log.info("Sent GO_ACTIVE; DSA state = %s", state)
        self.assertEqual(state, ResourceAgentState.IDLE)

        log.debug("DataSet agent run")
        cmd = AgentCommand(command=ResourceAgentEvent.RUN)
        retval = self.dataset_agent_client.execute_agent(cmd)
        state = self.dataset_agent_client.get_agent_state()
        log.info("Sent RUN; DSA state = %s", state)
        self.assertEqual(state, ResourceAgentState.COMMAND)

        if final_state == ResourceAgentState.STREAMING:
            self.assert_start_sampling()

    def assert_stop_sampling(self):
        '''
        transition to command.  Must be called from streaming
        '''
        state = self.dataset_agent_client.get_agent_state()
        self.assertEqual(state, ResourceAgentState.STREAMING)

        log.debug("DataSet agent stop sampling")
        cmd = AgentCommand(command=DriverEvent.STOP_AUTOSAMPLE)
        retval = self.dataset_agent_client.execute_resource(cmd)
        state = self.dataset_agent_client.get_agent_state()
        log.info("Sent START SAMPLING; DSA state = %s", state)
        self.assertEqual(state, ResourceAgentState.COMMAND)

    def assert_start_sampling(self):
        '''
        transition to sampling.  Must be called from command
        '''
        state = self.dataset_agent_client.get_agent_state()
        self.assertEqual(state, ResourceAgentState.COMMAND)

        log.debug("DataSet agent start sampling")
        cmd = AgentCommand(command=DriverEvent.START_AUTOSAMPLE)
        retval = self.dataset_agent_client.execute_resource(cmd)
        state = self.dataset_agent_client.get_agent_state()
        log.info("Sent START SAMPLING; DSA state = %s", state)
        self.assertEqual(state, ResourceAgentState.STREAMING)

    def assert_reset(self):
        '''
        Put the instrument back in uninitialized
        '''
        agent_state = self.dataset_agent_client.get_agent_state()

        if agent_state != ResourceAgentState.UNINITIALIZED:
            cmd = AgentCommand(command=ResourceAgentEvent.RESET)
            retval = self.dataset_agent_client.execute_agent(cmd)
            state = self.dataset_agent_client.get_agent_state()
            self.assertEqual(state, ResourceAgentState.UNINITIALIZED)

    def assert_agent_state(self, target_state):
        """
        Verify the current agent state
        @param target_state: What we expect the agent state to be
        """
        state = self.dataset_agent_client.get_agent_state()
        self.assertEqual(state, target_state)

    def assert_agent_command(self, command, args=None, timeout=None):
        """
        Verify an agent command
        @param command: driver command to execute
        @param args: kwargs to pass to the agent command object
        """
        cmd = AgentCommand(command=command, kwargs=args)
        retval = self.instrument_agent_client.execute_agent(cmd,
                                                            timeout=timeout)

    def assert_resource_command(self, command, args=None, timeout=None):
        """
        Verify a resource command
        @param command: driver command to execute
        @param args: kwargs to pass to the agent command object
        """
        cmd = AgentCommand(command=command, kwargs=args)
        retval = self.dataset_agent_client.execute_resource(cmd)

    def assert_state_change(self, target_agent_state, timeout=10):
        """
        Verify the agent and resource states change as expected within the timeout
        Fail if the state doesn't change to the expected state.
        @param target_agent_state: State we expect the agent to be in
        @param timeout: how long to wait for the driver to change states
        """
        to = gevent.Timeout(timeout)
        to.start()
        done = False
        agent_state = None

        try:
            while (not done):

                agent_state = self.dataset_agent_client.get_agent_state()
                log.error("Current agent state: %s", agent_state)

                if (agent_state == target_agent_state):
                    log.debug("Current state match: %s", agent_state)
                    done = True

                if not done:
                    log.debug(
                        "state mismatch, waiting for state to transition.")
                    gevent.sleep(1)
        except Timeout:
            log.error(
                "Failed to transition agent state to %s, current state: %s",
                target_agent_state, agent_state)
            self.fail("Failed to transition state.")
        finally:
            to.cancel()

    def assert_event_received(self, event_object_type, timeout=10):
        """
        Verify an event has been received of a sepecific type
        @param event_object_type: Event object we are looking for
        @param timeout: how long to wait
        """
        to = gevent.Timeout(timeout)
        to.start()
        done = False

        try:
            while (not done):
                for event in self.event_subscribers.events_received:
                    log.debug("Event: %s", event)

                    if isinstance(event, event_object_type):
                        done = True

                if not done:
                    log.debug(
                        "target event not detected, sleep a bit to let events happen"
                    )
                    gevent.sleep(1)
        except Timeout:
            log.error("Failed to find event in queue: %s", event_object_type)
            log.error("Current event queue: %s",
                      self.event_subscribers._events_received)
            self.fail("%s event not detected")
        finally:
            to.cancel()

        log.info("Expected event detected: %s", event)
Esempio n. 2
0
class DataSetQualificationTestCase(DataSetTestCase):
    """
    Base class for dataset driver unit tests
    """
    def setUp(self):
        """
        Startup the container and start the agent.
        """
        super(DataSetQualificationTestCase, self).setUp()

        self.instrument_agent_manager = InstrumentAgentClient()
        self.instrument_agent_manager.start_container(deploy_file=self.test_config.container_deploy_file)

        self.container = self.instrument_agent_manager.container

        log.debug("Packet Config: %s", self.test_config.agent_packet_config)
        self.data_subscribers = InstrumentAgentDataSubscribers(
            packet_config=self.test_config.agent_packet_config,
            )
        self.event_subscribers = InstrumentAgentEventSubscribers(instrument_agent_resource_id=self.test_config.agent_resource_id)

        self.init_dataset_agent_client()

        self.event_subscribers.events_received = []
        self.data_subscribers.start_data_subscribers()

        log.debug("********* setUp complete.  Begin Testing *********")

        self.addCleanup(self._end_test)

    def _end_test(self):
        """
        Cleanup after the test completes or fails
        """
        log.debug("Starting test cleanup")
        self.assert_reset()
        self.event_subscribers.stop()
        self.data_subscribers.stop_data_subscribers()
        self.instrument_agent_manager.stop_container()

        log.debug("Test complete and all cleaned up.")

    def init_dataset_agent_client(self):
        log.info("Start Dataset Agent Client")

        # Start instrument agent client.
        self.instrument_agent_manager.start_client(
            name=self.test_config.agent_name,
            module=self.test_config.agent_module,
            cls=self.test_config.agent_class,
            config=self._agent_config(),
            resource_id=self.test_config.agent_resource_id,
            deploy_file=self.test_config.container_deploy_file,
            bootmode='reset'
        )

        self.dataset_agent_client = self.instrument_agent_manager.instrument_agent_client

    def get_samples(self, stream_name, sample_count = 1, timeout = 10):
        """
        listen on a stream until 'sample_count' samples are read and return
        a list of all samples read.  If the required number of samples aren't
        read then throw an exception.

        Note that this method does not clear the sample queue for the stream.
        This should be done explicitly by the caller.  However, samples that
        are consumed by this method are removed.

        @raise SampleTimeout - if the required number of samples aren't read
        """
        result = []
        start_time = time.time()
        i = 1

        log.debug("Fetch %d sample(s) from stream '%s'" % (sample_count, stream_name))
        while(len(result) < sample_count):
            if(self.data_subscribers.samples_received.has_key(stream_name) and
               len(self.data_subscribers.samples_received.get(stream_name))):
                log.trace("get_samples() received sample #%d!", i)
                result.append(self.data_subscribers.samples_received[stream_name].pop(0))
                i += 1

            # Check for timeout
            if(start_time + timeout < time.time()):
                raise SampleTimeout()

            if(not self.data_subscribers.samples_received.has_key(stream_name) or
               len(self.data_subscribers.samples_received.get(stream_name)) == 0):
                log.debug("No samples in the queue, sleep for a bit to let the queue fill up")
                gevent.sleep(.2)

        log.debug("get_samples() complete.  returning %d records", sample_count)
        return result

    def assert_sample_queue_size(self, stream_name, size):
        """
        Verify that a queue has size samples in it.
        """
        if(not self.data_subscribers.samples_received.has_key(stream_name) and size == 0):
            return

        self.assertTrue(self.data_subscribers.samples_received.has_key(stream_name), msg="Sample queue does not exists")
        self.assertEqual(len(self.data_subscribers.samples_received.get(stream_name)), size)

    def assert_data_values(self, particles, dataset_definition_file):
        """
        Verify particles match the particles defined in the definition file
        """
        rs_file = self._get_source_data_file(dataset_definition_file)
        rs = ResultSet(rs_file)

        self.assertTrue(rs.verify(particles))

    def assert_initialize(self, final_state = ResourceAgentState.STREAMING):
        '''
        Walk through DSA states to get to streaming mode from uninitialized
        '''
        log.debug("Initialize DataSet agent")
        cmd = AgentCommand(command=ResourceAgentEvent.INITIALIZE)
        retval = self.dataset_agent_client.execute_agent(cmd)
        state = self.dataset_agent_client.get_agent_state()
        self.assertEqual(state, ResourceAgentState.INACTIVE)
        log.info("Sent INITIALIZE; DSA state = %s", state)

        log.debug("DataSet agent go active")
        cmd = AgentCommand(command=ResourceAgentEvent.GO_ACTIVE)
        retval = self.dataset_agent_client.execute_agent(cmd)
        state = self.dataset_agent_client.get_agent_state()
        log.info("Sent GO_ACTIVE; DSA state = %s", state)
        self.assertEqual(state, ResourceAgentState.IDLE)

        log.debug("DataSet agent run")
        cmd = AgentCommand(command=ResourceAgentEvent.RUN)
        retval = self.dataset_agent_client.execute_agent(cmd)
        state = self.dataset_agent_client.get_agent_state()
        log.info("Sent RUN; DSA state = %s", state)
        self.assertEqual(state, ResourceAgentState.COMMAND)

        if final_state == ResourceAgentState.STREAMING:
            self.assert_start_sampling()

    def assert_stop_sampling(self):
        '''
        transition to command.  Must be called from streaming
        '''
        state = self.dataset_agent_client.get_agent_state()
        self.assertEqual(state, ResourceAgentState.STREAMING)

        log.debug("DataSet agent stop sampling")
        cmd = AgentCommand(command=DriverEvent.STOP_AUTOSAMPLE)
        retval = self.dataset_agent_client.execute_resource(cmd)
        state = self.dataset_agent_client.get_agent_state()
        log.info("Sent START SAMPLING; DSA state = %s", state)
        self.assertEqual(state, ResourceAgentState.COMMAND)

    def assert_start_sampling(self):
        '''
        transition to sampling.  Must be called from command
        '''
        state = self.dataset_agent_client.get_agent_state()
        self.assertEqual(state, ResourceAgentState.COMMAND)

        log.debug("DataSet agent start sampling")
        cmd = AgentCommand(command=DriverEvent.START_AUTOSAMPLE)
        retval = self.dataset_agent_client.execute_resource(cmd)
        state = self.dataset_agent_client.get_agent_state()
        log.info("Sent START SAMPLING; DSA state = %s", state)
        self.assertEqual(state, ResourceAgentState.STREAMING)

    def assert_reset(self):
        '''
        Put the instrument back in uninitialized
        '''
        agent_state = self.dataset_agent_client.get_agent_state()
        log.debug("Resetting agent: current state: %s", agent_state)

        if agent_state != ResourceAgentState.UNINITIALIZED:
            cmd = AgentCommand(command=ResourceAgentEvent.RESET)
            retval = self.dataset_agent_client.execute_agent(cmd)
            state = self.dataset_agent_client.get_agent_state()
            log.debug("Resetting agent: final state: %s", state)

    def assert_agent_state(self, target_state):
        """
        Verify the current agent state
        @param target_state: What we expect the agent state to be
        """
        state = self.dataset_agent_client.get_agent_state()
        self.assertEqual(state, target_state)

    def assert_agent_command(self, command, args=None, timeout=None):
        """
        Verify an agent command
        @param command: driver command to execute
        @param args: kwargs to pass to the agent command object
        """
        cmd = AgentCommand(command=command, kwargs=args)
        retval = self.instrument_agent_client.execute_agent(cmd, timeout=timeout)

    def assert_resource_command(self, command, args=None, timeout=None):
        """
        Verify a resource command
        @param command: driver command to execute
        @param args: kwargs to pass to the agent command object
        """
        cmd = AgentCommand(command=command, kwargs=args)
        retval = self.dataset_agent_client.execute_resource(cmd)

    def assert_state_change(self, target_agent_state, timeout=10):
        """
        Verify the agent and resource states change as expected within the timeout
        Fail if the state doesn't change to the expected state.
        @param target_agent_state: State we expect the agent to be in
        @param timeout: how long to wait for the driver to change states
        """
        to = gevent.Timeout(timeout)
        to.start()
        done = False
        agent_state = None

        try:
            while(not done):

                agent_state = self.dataset_agent_client.get_agent_state()
                log.error("Current agent state: %s", agent_state)

                if(agent_state == target_agent_state):
                    log.debug("Current state match: %s", agent_state)
                    done = True

                if not done:
                    log.debug("state mismatch, waiting for state to transition.")
                    gevent.sleep(1)
        except Timeout:
            log.error("Failed to transition agent state to %s, current state: %s", target_agent_state, agent_state)
            self.fail("Failed to transition state.")
        finally:
            to.cancel()

    def assert_event_received(self, event_object_type, timeout=10):
        """
        Verify an event has been received of a sepecific type
        @param event_object_type: Event object we are looking for
        @param timeout: how long to wait
        """
        to = gevent.Timeout(timeout)
        to.start()
        done = False

        try:
            while(not done):
                for event in self.event_subscribers.events_received:
                    log.debug("Event: %s", event)

                    if isinstance(event, event_object_type):
                        done = True

                if not done:
                    log.debug("target event not detected, sleep a bit to let events happen")
                    gevent.sleep(1)
        except Timeout:
            log.error("Failed to find event in queue: %s", event_object_type)
            log.error("Current event queue: %s", self.event_subscribers._events_received)
            self.fail("%s event not detected")
        finally:
            to.cancel()

        log.info("Expected event detected: %s", event)

    def test_initialize(self):
        """
        Test that we can start the container and initialize the dataset agent.
        """
        self.assert_initialize()
        self.assert_stop_sampling()
        self.assert_reset()

    def test_resource_parameters(self):
        """
        verify we can get a resource parameter lists and get/set parameters.
        """
        def sort_capabilities(caps_list):
            '''
            sort a return value into capability buckets.
            @retval agt_cmds, agt_pars, res_cmds, res_iface, res_pars
            '''
            agt_cmds = []
            agt_pars = []
            res_cmds = []
            res_iface = []
            res_pars = []

            if len(caps_list)>0 and isinstance(caps_list[0], AgentCapability):
                agt_cmds = [x.name for x in caps_list if x.cap_type==CapabilityType.AGT_CMD]
                agt_pars = [x.name for x in caps_list if x.cap_type==CapabilityType.AGT_PAR]
                res_cmds = [x.name for x in caps_list if x.cap_type==CapabilityType.RES_CMD]
                #res_iface = [x.name for x in caps_list if x.cap_type==CapabilityType.RES_IFACE]
                res_pars = [x.name for x in caps_list if x.cap_type==CapabilityType.RES_PAR]

            elif len(caps_list)>0 and isinstance(caps_list[0], dict):
                agt_cmds = [x['name'] for x in caps_list if x['cap_type']==CapabilityType.AGT_CMD]
                agt_pars = [x['name'] for x in caps_list if x['cap_type']==CapabilityType.AGT_PAR]
                res_cmds = [x['name'] for x in caps_list if x['cap_type']==CapabilityType.RES_CMD]
                #res_iface = [x['name'] for x in caps_list if x['cap_type']==CapabilityType.RES_IFACE]
                res_pars = [x['name'] for x in caps_list if x['cap_type']==CapabilityType.RES_PAR]

            agt_cmds.sort()
            agt_pars.sort()
            res_cmds.sort()
            res_iface.sort()
            res_pars.sort()

            return agt_cmds, agt_pars, res_cmds, res_iface, res_pars

        log.debug("Initialize the agent")
        expected_params = [DriverParameter.BATCHED_PARTICLE_COUNT, DriverParameter.PUBLISHER_POLLING_INTERVAL, DriverParameter.RECORDS_PER_SECOND]
        self.assert_initialize(final_state=ResourceAgentState.COMMAND)

        log.debug("Call get capabilities")
        retval = self.dataset_agent_client.get_capabilities()
        log.debug("Capabilities: %s", retval)
        agt_cmds, agt_pars, res_cmds, res_iface, res_pars = sort_capabilities(retval)
        self.assertEqual(sorted(res_pars), sorted(expected_params))

        self.dataset_agent_client.set_resource({DriverParameter.RECORDS_PER_SECOND: 20})
        reply = self.dataset_agent_client.get_resource(DriverParameter.ALL)
        log.debug("Get Resource Result: %s", reply)

    def test_missing_directory(self):
        """
        Test starting the driver when the data directory doesn't exists.  This
        should prevent the driver from going into streaming mode.  When the
        directory is created then we should be able to transition into streaming.
        """
        self.remove_sample_dir()
        self.assert_initialize(final_state=ResourceAgentState.COMMAND)

        self.event_subscribers.clear_events()
        self.assert_resource_command(DriverEvent.START_AUTOSAMPLE)

        self.assert_state_change(ResourceAgentState.LOST_CONNECTION, 90)
        self.assert_event_received(ResourceAgentConnectionLostErrorEvent, 10)

        self.create_data_dir()

        # Should automatically retry connect and transition to streaming
        self.assert_state_change(ResourceAgentState.STREAMING, 90)

    def test_harvester_new_file_exception(self):
        """
        Test an exception raised after the driver is started during
        the file read.

        exception callback called.
        """
        config = self._driver_config()['startup_config']['harvester']['pattern']
        filename = config.replace("*", "foo")

        self.assert_new_file_exception(filename)

    def assert_new_file_exception(self, filename):

        self.clear_sample_data()
        self.create_sample_data(filename, mode=000)

        self.assert_initialize(final_state=ResourceAgentState.COMMAND)

        self.event_subscribers.clear_events()
        self.assert_resource_command(DriverEvent.START_AUTOSAMPLE)
        self.assert_state_change(ResourceAgentState.LOST_CONNECTION, 90)
        self.assert_event_received(ResourceAgentConnectionLostErrorEvent, 10)

        self.clear_sample_data()
        self.create_sample_data(filename)

        # Should automatically retry connect and transition to streaming
        self.assert_state_change(ResourceAgentState.STREAMING, 90)
Esempio n. 3
0
class DataSetQualificationTestCase(DataSetTestCase):
    """
    Base class for dataset driver unit tests
    """
    def setUp(self):
        """
        Startup the container and start the agent.
        """
        super(DataSetQualificationTestCase, self).setUp()

        self.instrument_agent_manager = InstrumentAgentClient()
        self.instrument_agent_manager.start_container(
            deploy_file=self.test_config.container_deploy_file)

        self.container = self.instrument_agent_manager.container

        log.debug("Packet Config: %s", self.test_config.agent_packet_config)
        self.data_subscribers = InstrumentAgentDataSubscribers(
            packet_config=self.test_config.agent_packet_config, )
        self.event_subscribers = InstrumentAgentEventSubscribers(
            instrument_agent_resource_id=self.test_config.agent_resource_id)

        self.init_dataset_agent_client()

        self.event_subscribers.events_received = []
        self.data_subscribers.start_data_subscribers()

        log.debug("********* setUp complete.  Begin Testing *********")

        self.addCleanup(self._end_test)

    def _end_test(self):
        """
        Cleanup after the test completes or fails
        """
        log.debug("Starting test cleanup")
        self.assert_reset()
        self.event_subscribers.stop()
        self.data_subscribers.stop_data_subscribers()
        self.instrument_agent_manager.stop_container()

        log.debug("Test complete and all cleaned up.")

    def init_dataset_agent_client(self):
        log.info("Start Dataset Agent Client")

        # Start instrument agent client.
        self.instrument_agent_manager.start_client(
            name=self.test_config.agent_name,
            module=self.test_config.agent_module,
            cls=self.test_config.agent_class,
            config=self._agent_config(),
            resource_id=self.test_config.agent_resource_id,
            deploy_file=self.test_config.container_deploy_file,
            bootmode='reset')

        self.dataset_agent_client = self.instrument_agent_manager.instrument_agent_client

    def get_samples(self, stream_name, sample_count=1, timeout=10):
        """
        listen on a stream until 'sample_count' samples are read and return
        a list of all samples read.  If the required number of samples aren't
        read then throw an exception.

        Note that this method does not clear the sample queue for the stream.
        This should be done explicitly by the caller.  However, samples that
        are consumed by this method are removed.

        @raise SampleTimeout - if the required number of samples aren't read
        """
        result = []
        start_time = time.time()
        i = 1

        log.debug("Fetch %d sample(s) from stream '%s'" %
                  (sample_count, stream_name))
        while (len(result) < sample_count):
            if (self.data_subscribers.samples_received.has_key(stream_name)
                    and len(
                        self.data_subscribers.samples_received.get(
                            stream_name))):
                log.trace("get_samples() received sample #%d!", i)
                result.append(
                    self.data_subscribers.samples_received[stream_name].pop(0))
                i += 1

            # Check for timeout
            if (start_time + timeout < time.time()):
                raise SampleTimeout()

            if (not self.data_subscribers.samples_received.has_key(stream_name)
                    or len(
                        self.data_subscribers.samples_received.get(
                            stream_name)) == 0):
                log.debug(
                    "No samples in the queue, sleep for a bit to let the queue fill up"
                )
                gevent.sleep(.2)

        log.debug("get_samples() complete.  returning %d records",
                  sample_count)
        return result

    def assert_sample_queue_size(self, stream_name, size):
        """
        Verify that a queue has size samples in it.
        """
        if (not self.data_subscribers.samples_received.has_key(stream_name)
                and size == 0):
            return

        self.assertTrue(
            self.data_subscribers.samples_received.has_key(stream_name),
            msg="Sample queue does not exists")
        self.assertEqual(
            len(self.data_subscribers.samples_received.get(stream_name)), size)

    def assert_data_values(self, particles, dataset_definition_file):
        """
        Verify particles match the particles defined in the definition file
        """
        rs_file = self._get_source_data_file(dataset_definition_file)
        rs = ResultSet(rs_file)

        self.assertTrue(rs.verify(particles))

    def assert_initialize(self, final_state=ResourceAgentState.STREAMING):
        '''
        Walk through DSA states to get to streaming mode from uninitialized
        '''
        log.debug("Initialize DataSet agent")
        cmd = AgentCommand(command=ResourceAgentEvent.INITIALIZE)
        retval = self.dataset_agent_client.execute_agent(cmd)
        state = self.dataset_agent_client.get_agent_state()
        self.assertEqual(state, ResourceAgentState.INACTIVE)
        log.info("Sent INITIALIZE; DSA state = %s", state)

        log.debug("DataSet agent go active")
        cmd = AgentCommand(command=ResourceAgentEvent.GO_ACTIVE)
        retval = self.dataset_agent_client.execute_agent(cmd)
        state = self.dataset_agent_client.get_agent_state()
        log.info("Sent GO_ACTIVE; DSA state = %s", state)
        self.assertEqual(state, ResourceAgentState.IDLE)

        log.debug("DataSet agent run")
        cmd = AgentCommand(command=ResourceAgentEvent.RUN)
        retval = self.dataset_agent_client.execute_agent(cmd)
        state = self.dataset_agent_client.get_agent_state()
        log.info("Sent RUN; DSA state = %s", state)
        self.assertEqual(state, ResourceAgentState.COMMAND)

        if final_state == ResourceAgentState.STREAMING:
            self.assert_start_sampling()

    def assert_stop_sampling(self):
        '''
        transition to command.  Must be called from streaming
        '''
        state = self.dataset_agent_client.get_agent_state()
        self.assertEqual(state, ResourceAgentState.STREAMING)

        log.debug("DataSet agent stop sampling")
        cmd = AgentCommand(command=DriverEvent.STOP_AUTOSAMPLE)
        retval = self.dataset_agent_client.execute_resource(cmd)
        state = self.dataset_agent_client.get_agent_state()
        log.info("Sent START SAMPLING; DSA state = %s", state)
        self.assertEqual(state, ResourceAgentState.COMMAND)

    def assert_start_sampling(self):
        '''
        transition to sampling.  Must be called from command
        '''
        state = self.dataset_agent_client.get_agent_state()
        self.assertEqual(state, ResourceAgentState.COMMAND)

        log.debug("DataSet agent start sampling")
        cmd = AgentCommand(command=DriverEvent.START_AUTOSAMPLE)
        retval = self.dataset_agent_client.execute_resource(cmd)
        state = self.dataset_agent_client.get_agent_state()
        log.info("Sent START SAMPLING; DSA state = %s", state)
        self.assertEqual(state, ResourceAgentState.STREAMING)

    def assert_reset(self):
        '''
        Put the instrument back in uninitialized
        '''
        agent_state = self.dataset_agent_client.get_agent_state()
        log.debug("Resetting agent: current state: %s", agent_state)

        if agent_state != ResourceAgentState.UNINITIALIZED:
            cmd = AgentCommand(command=ResourceAgentEvent.RESET)
            retval = self.dataset_agent_client.execute_agent(cmd)
            state = self.dataset_agent_client.get_agent_state()
            log.debug("Resetting agent: final state: %s", state)

    def assert_agent_state(self, target_state):
        """
        Verify the current agent state
        @param target_state: What we expect the agent state to be
        """
        state = self.dataset_agent_client.get_agent_state()
        self.assertEqual(state, target_state)

    def assert_agent_command(self, command, args=None, timeout=None):
        """
        Verify an agent command
        @param command: driver command to execute
        @param args: kwargs to pass to the agent command object
        """
        cmd = AgentCommand(command=command, kwargs=args)
        retval = self.instrument_agent_client.execute_agent(cmd,
                                                            timeout=timeout)

    def assert_resource_command(self, command, args=None, timeout=None):
        """
        Verify a resource command
        @param command: driver command to execute
        @param args: kwargs to pass to the agent command object
        """
        cmd = AgentCommand(command=command, kwargs=args)
        retval = self.dataset_agent_client.execute_resource(cmd)

    def assert_state_change(self, target_agent_state, timeout=10):
        """
        Verify the agent and resource states change as expected within the timeout
        Fail if the state doesn't change to the expected state.
        @param target_agent_state: State we expect the agent to be in
        @param timeout: how long to wait for the driver to change states
        """
        to = gevent.Timeout(timeout)
        to.start()
        done = False
        agent_state = None

        try:
            while (not done):

                agent_state = self.dataset_agent_client.get_agent_state()
                log.error("Current agent state: %s", agent_state)

                if (agent_state == target_agent_state):
                    log.debug("Current state match: %s", agent_state)
                    done = True

                if not done:
                    log.debug(
                        "state mismatch, waiting for state to transition.")
                    gevent.sleep(1)
        except Timeout:
            log.error(
                "Failed to transition agent state to %s, current state: %s",
                target_agent_state, agent_state)
            self.fail("Failed to transition state.")
        finally:
            to.cancel()

    def assert_event_received(self, event_object_type, timeout=10):
        """
        Verify an event has been received of a sepecific type
        @param event_object_type: Event object we are looking for
        @param timeout: how long to wait
        """
        to = gevent.Timeout(timeout)
        to.start()
        done = False

        try:
            while (not done):
                for event in self.event_subscribers.events_received:
                    log.debug("Event: %s", event)

                    if isinstance(event, event_object_type):
                        done = True

                if not done:
                    log.debug(
                        "target event not detected, sleep a bit to let events happen"
                    )
                    gevent.sleep(1)
        except Timeout:
            log.error("Failed to find event in queue: %s", event_object_type)
            log.error("Current event queue: %s",
                      self.event_subscribers._events_received)
            self.fail("%s event not detected")
        finally:
            to.cancel()

        log.info("Expected event detected: %s", event)

    def test_initialize(self):
        """
        Test that we can start the container and initialize the dataset agent.
        """
        self.assert_initialize()
        self.assert_stop_sampling()
        self.assert_reset()

    def test_resource_parameters(self):
        """
        verify we can get a resource parameter lists and get/set parameters.
        """
        def sort_capabilities(caps_list):
            '''
            sort a return value into capability buckets.
            @retval agt_cmds, agt_pars, res_cmds, res_iface, res_pars
            '''
            agt_cmds = []
            agt_pars = []
            res_cmds = []
            res_iface = []
            res_pars = []

            if len(caps_list) > 0 and isinstance(caps_list[0],
                                                 AgentCapability):
                agt_cmds = [
                    x.name for x in caps_list
                    if x.cap_type == CapabilityType.AGT_CMD
                ]
                agt_pars = [
                    x.name for x in caps_list
                    if x.cap_type == CapabilityType.AGT_PAR
                ]
                res_cmds = [
                    x.name for x in caps_list
                    if x.cap_type == CapabilityType.RES_CMD
                ]
                #res_iface = [x.name for x in caps_list if x.cap_type==CapabilityType.RES_IFACE]
                res_pars = [
                    x.name for x in caps_list
                    if x.cap_type == CapabilityType.RES_PAR
                ]

            elif len(caps_list) > 0 and isinstance(caps_list[0], dict):
                agt_cmds = [
                    x['name'] for x in caps_list
                    if x['cap_type'] == CapabilityType.AGT_CMD
                ]
                agt_pars = [
                    x['name'] for x in caps_list
                    if x['cap_type'] == CapabilityType.AGT_PAR
                ]
                res_cmds = [
                    x['name'] for x in caps_list
                    if x['cap_type'] == CapabilityType.RES_CMD
                ]
                #res_iface = [x['name'] for x in caps_list if x['cap_type']==CapabilityType.RES_IFACE]
                res_pars = [
                    x['name'] for x in caps_list
                    if x['cap_type'] == CapabilityType.RES_PAR
                ]

            agt_cmds.sort()
            agt_pars.sort()
            res_cmds.sort()
            res_iface.sort()
            res_pars.sort()

            return agt_cmds, agt_pars, res_cmds, res_iface, res_pars

        log.debug("Initialize the agent")
        expected_params = [
            DriverParameter.BATCHED_PARTICLE_COUNT,
            DriverParameter.PUBLISHER_POLLING_INTERVAL,
            DriverParameter.RECORDS_PER_SECOND
        ]
        self.assert_initialize(final_state=ResourceAgentState.COMMAND)

        log.debug("Call get capabilities")
        retval = self.dataset_agent_client.get_capabilities()
        log.debug("Capabilities: %s", retval)
        agt_cmds, agt_pars, res_cmds, res_iface, res_pars = sort_capabilities(
            retval)
        self.assertEqual(sorted(res_pars), sorted(expected_params))

        self.dataset_agent_client.set_resource(
            {DriverParameter.RECORDS_PER_SECOND: 20})
        reply = self.dataset_agent_client.get_resource(DriverParameter.ALL)
        log.debug("Get Resource Result: %s", reply)

    def test_missing_directory(self):
        """
        Test starting the driver when the data directory doesn't exists.  This
        should prevent the driver from going into streaming mode.  When the
        directory is created then we should be able to transition into streaming.
        """
        self.remove_sample_dir()
        self.assert_initialize(final_state=ResourceAgentState.COMMAND)

        self.event_subscribers.clear_events()
        self.assert_resource_command(DriverEvent.START_AUTOSAMPLE)

        self.assert_state_change(ResourceAgentState.LOST_CONNECTION, 90)
        self.assert_event_received(ResourceAgentConnectionLostErrorEvent, 10)

        self.create_data_dir()

        # Should automatically retry connect and transition to streaming
        self.assert_state_change(ResourceAgentState.STREAMING, 90)

    def test_harvester_new_file_exception(self):
        """
        Test an exception raised after the driver is started during
        the file read.

        exception callback called.
        """
        config = self._driver_config(
        )['startup_config']['harvester']['pattern']
        filename = config.replace("*", "foo")

        self.assert_new_file_exception(filename)

    def assert_new_file_exception(self, filename):

        self.clear_sample_data()
        self.create_sample_data(filename, mode=000)

        self.assert_initialize(final_state=ResourceAgentState.COMMAND)

        self.event_subscribers.clear_events()
        self.assert_resource_command(DriverEvent.START_AUTOSAMPLE)
        self.assert_state_change(ResourceAgentState.LOST_CONNECTION, 90)
        self.assert_event_received(ResourceAgentConnectionLostErrorEvent, 10)

        self.clear_sample_data()
        self.create_sample_data(filename)

        # Should automatically retry connect and transition to streaming
        self.assert_state_change(ResourceAgentState.STREAMING, 90)
Esempio n. 4
0
class DataSetQualificationTestCase(DataSetTestCase):
    """
    Base class for dataset driver unit tests
    """
    def setUp(self):
        """
        Startup the container and start the agent.
        """
        super(DataSetQualificationTestCase, self).setUp()

        self.instrument_agent_manager = InstrumentAgentClient()
        self.instrument_agent_manager.start_container(deploy_file=self.test_config.container_deploy_file)

        self.container = self.instrument_agent_manager.container

        gevent.sleep(5)
        log.debug("Packet Config: %s", self.test_config.agent_packet_config)
        self.data_subscribers = InstrumentAgentDataSubscribers(
            packet_config=self.test_config.agent_packet_config,
            )
        self.event_subscribers = InstrumentAgentEventSubscribers(instrument_agent_resource_id=self.test_config.agent_resource_id)

        self.init_dataset_agent_client()

        self.event_subscribers.events_received = []
        self.data_subscribers.start_data_subscribers()

        log.debug("********* setUp complete.  Begin Testing *********")

        self.addCleanup(self._end_test)

    def _end_test(self):
        """
        Cleanup after the test completes or fails
        """
        self.assert_reset()
        self.event_subscribers.stop()
        self.data_subscribers.stop_data_subscribers()
        self.instrument_agent_manager.stop_container()

        log.debug("Test complete and all cleaned up.")

    def init_dataset_agent_client(self):
        log.info("Start Dataset Agent Client")

        # Start instrument agent client.
        self.instrument_agent_manager.start_client(
            name=self.test_config.agent_name,
            module=self.test_config.agent_module,
            cls=self.test_config.agent_class,
            config=self._agent_config(),
            resource_id=self.test_config.agent_resource_id,
            deploy_file=self.test_config.container_deploy_file,
            bootmode='reset'
        )

        self.dataset_agent_client = self.instrument_agent_manager.instrument_agent_client

    def get_samples(self, stream_name, sample_count = 1, timeout = 10):
        """
        listen on a stream until 'sample_count' samples are read and return
        a list of all samples read.  If the required number of samples aren't
        read then throw an exception.

        Note that this method does not clear the sample queue for the stream.
        This should be done explicitly by the caller.  However, samples that
        are consumed by this method are removed.

        @raise SampleTimeout - if the required number of samples aren't read
        """
        result = []
        start_time = time.time()
        i = 1

        log.debug("Fetch %d sample(s) from stream '%s'" % (sample_count, stream_name))
        while(len(result) < sample_count):
            if(self.data_subscribers.samples_received.has_key(stream_name) and
               len(self.data_subscribers.samples_received.get(stream_name))):
                log.trace("get_samples() received sample #%d!", i)
                result.append(self.data_subscribers.samples_received[stream_name].pop())
                i += 1

            # Check for timeout
            if(start_time + timeout < time.time()):
                raise SampleTimeout()

            if(not self.data_subscribers.samples_received.has_key(stream_name) or
               len(self.data_subscribers.samples_received.get(stream_name)) == 0):
                log.debug("No samples in the queue, sleep for a bit to let the queue fill up")
                gevent.sleep(.2)

        log.debug("get_samples() complete.  returning %d records", sample_count)
        return result

    def assert_sample_queue_size(self, stream_name, size):
        """
        Verify that a queue has size samples in it.
        """
        if(not self.data_subscribers.samples_received.has_key(stream_name) and size == 0):
            return

        self.assertTrue(self.data_subscribers.samples_received.has_key(stream_name), msg="Sample queue does not exists")
        self.assertEqual(len(self.data_subscribers.samples_received.get(stream_name)), size)

    def assert_data_values(self, particles, dataset_definition_file):
        """
        Verify particles match the particles defined in the definition file
        """
        rs_file = self._get_source_data_file(dataset_definition_file)
        rs = ResultSet(rs_file)

        self.assertTrue(rs.verify(particles))

    def assert_initialize(self, final_state = ResourceAgentState.STREAMING):
        '''
        Walk through DSA states to get to streaming mode from uninitialized
        '''
        log.debug("Initialize DataSet agent")
        cmd = AgentCommand(command=ResourceAgentEvent.INITIALIZE)
        retval = self.dataset_agent_client.execute_agent(cmd)
        state = self.dataset_agent_client.get_agent_state()
        self.assertEqual(state, ResourceAgentState.INACTIVE)
        log.info("Sent INITIALIZE; DSA state = %s", state)

        log.debug("DataSet agent go active")
        cmd = AgentCommand(command=ResourceAgentEvent.GO_ACTIVE)
        retval = self.dataset_agent_client.execute_agent(cmd)
        state = self.dataset_agent_client.get_agent_state()
        log.info("Sent GO_ACTIVE; DSA state = %s", state)
        self.assertEqual(state, ResourceAgentState.IDLE)

        log.debug("DataSet agent run")
        cmd = AgentCommand(command=ResourceAgentEvent.RUN)
        retval = self.dataset_agent_client.execute_agent(cmd)
        state = self.dataset_agent_client.get_agent_state()
        log.info("Sent RUN; DSA state = %s", state)
        self.assertEqual(state, ResourceAgentState.COMMAND)

        if final_state == ResourceAgentState.STREAMING:
            self.assert_start_sampling()

    def assert_stop_sampling(self):
        '''
        transition to command.  Must be called from streaming
        '''
        state = self.dataset_agent_client.get_agent_state()
        self.assertEqual(state, ResourceAgentState.STREAMING)

        log.debug("DataSet agent stop sampling")
        cmd = AgentCommand(command=DriverEvent.STOP_AUTOSAMPLE)
        retval = self.dataset_agent_client.execute_resource(cmd)
        state = self.dataset_agent_client.get_agent_state()
        log.info("Sent START SAMPLING; DSA state = %s", state)
        self.assertEqual(state, ResourceAgentState.COMMAND)

    def assert_start_sampling(self):
        '''
        transition to sampling.  Must be called from command
        '''
        state = self.dataset_agent_client.get_agent_state()
        self.assertEqual(state, ResourceAgentState.COMMAND)

        log.debug("DataSet agent start sampling")
        cmd = AgentCommand(command=DriverEvent.START_AUTOSAMPLE)
        retval = self.dataset_agent_client.execute_resource(cmd)
        state = self.dataset_agent_client.get_agent_state()
        log.info("Sent START SAMPLING; DSA state = %s", state)
        self.assertEqual(state, ResourceAgentState.STREAMING)

    def assert_reset(self):
        '''
        Put the instrument back in uninitialized
        '''
        agent_state = self.dataset_agent_client.get_agent_state()

        if agent_state != ResourceAgentState.UNINITIALIZED:
            cmd = AgentCommand(command=ResourceAgentEvent.RESET)
            retval = self.dataset_agent_client.execute_agent(cmd)
            state = self.dataset_agent_client.get_agent_state()
            self.assertEqual(state, ResourceAgentState.UNINITIALIZED)

    def assert_agent_state(self, target_state):
        """
        Verify the current agent state
        @param target_state: What we expect the agent state to be
        """
        state = self.dataset_agent_client.get_agent_state()
        self.assertEqual(state, target_state)

    def assert_agent_command(self, command, args=None, timeout=None):
        """
        Verify an agent command
        @param command: driver command to execute
        @param args: kwargs to pass to the agent command object
        """
        cmd = AgentCommand(command=command, kwargs=args)
        retval = self.instrument_agent_client.execute_agent(cmd, timeout=timeout)

    def assert_resource_command(self, command, args=None, timeout=None):
        """
        Verify a resource command
        @param command: driver command to execute
        @param args: kwargs to pass to the agent command object
        """
        cmd = AgentCommand(command=command, kwargs=args)
        retval = self.dataset_agent_client.execute_resource(cmd)

    def assert_state_change(self, target_agent_state, timeout=10):
        """
        Verify the agent and resource states change as expected within the timeout
        Fail if the state doesn't change to the expected state.
        @param target_agent_state: State we expect the agent to be in
        @param timeout: how long to wait for the driver to change states
        """
        to = gevent.Timeout(timeout)
        to.start()
        done = False
        agent_state = None

        try:
            while(not done):

                agent_state = self.dataset_agent_client.get_agent_state()
                log.error("Current agent state: %s", agent_state)

                if(agent_state == target_agent_state):
                    log.debug("Current state match: %s", agent_state)
                    done = True

                if not done:
                    log.debug("state mismatch, waiting for state to transition.")
                    gevent.sleep(1)
        except Timeout:
            log.error("Failed to transition agent state to %s, current state: %s", target_agent_state, agent_state)
            self.fail("Failed to transition state.")
        finally:
            to.cancel()

    def assert_event_received(self, event_object_type, timeout=10):
        """
        Verify an event has been received of a sepecific type
        @param event_object_type: Event object we are looking for
        @param timeout: how long to wait
        """
        to = gevent.Timeout(timeout)
        to.start()
        done = False

        try:
            while(not done):
                for event in self.event_subscribers.events_received:
                    log.debug("Event: %s", event)

                    if isinstance(event, event_object_type):
                        done = True

                if not done:
                    log.debug("target event not detected, sleep a bit to let events happen")
                    gevent.sleep(1)
        except Timeout:
            log.error("Failed to find event in queue: %s", event_object_type)
            log.error("Current event queue: %s", self.event_subscribers._events_received)
            self.fail("%s event not detected")
        finally:
            to.cancel()

        log.info("Expected event detected: %s", event)