class TestUnitInstrumentProtocol(IonUnitTestCase): """ Test cases for instrument protocol class. Functions in this class provide instrument protocol unit tests and provide a tutorial on use of the protocol interface. """ def setUp(self): """ """ self.callback_result = None def protocol_callback(self, arg): callback_result = arg self.protocol = InstrumentProtocol(protocol_callback) def test_extraction(self): sample_line = "SATPAR0229,10.01,2206748544,234" result = self.protocol._extract_sample(SatlanticPARDataParticle, SAMPLE_REGEX, sample_line, publish=False) self.assertTrue(result['parsed']) self.assertTrue(result['raw']) # Test the format of the result in the individual driver tests. Here, # just tests that the result is there. def test_publish_raw(self): """ Tests to see if raw data is appropriately published back out to the InstrumentAgent via the event callback. """ # build a packet # have it published by the protocol (force state if needed) # delay? # catch it in the callback # confirm it came back # compare response to original packet self.assertTrue(False) def test_publish_parsed_data(self): """ Tests to see if parsed data is appropriately published back to the InstrumentAgent via the event callback. """ # similar to above self.assertTrue(False) def test_publish_engineering_data(self): """ Tests to see if engineering data is appropriately published back to the InstrumentAgent via the event callback. """ # similar to above self.assertTrue(False)
class TestUnitInstrumentProtocol(MiUnitTestCase): """ Test cases for instrument protocol class. Functions in this class provide instrument protocol unit tests and provide a tutorial on use of the protocol interface. """ def setUp(self): """ """ self.callback_result = None self._trigger_count = 0 self._events = [] self.protocol = InstrumentProtocol(self.event_callback) def event_callback(self, event, value=None): log.debug("Test event callback: %s" % event) self._events.append(event) self._trigger_count += 1 def _scheduler_callback(self): """ Callback to test the scheduler """ self._trigger_count += 1 def assert_scheduled_event_triggered(self, event_count=1): count = 0 for i in range(0, 40): count = self._trigger_count log.debug("check for triggered event, count %d" % self._trigger_count) if(count >= event_count): break time.sleep(0.3) self.assertGreater(count, 0) def test_extraction(self): sample_line = "SATPAR0229,10.01,2206748544,234\r\n" ntptime = ntplib.system_to_ntp_time(time.time()) result = self.protocol._extract_sample(SatlanticPARDataParticle, SAMPLE_REGEX, sample_line, ntptime, publish=False) log.debug("R: %s" % result) self.assertEqual(result['stream_name'], SatlanticPARDataParticle(None, None).data_particle_type()) # Test the format of the result in the individual driver tests. Here, # just tests that the result is there. @unittest.skip('Not Written') def test_publish_raw(self): """ Tests to see if raw data is appropriately published back out to the InstrumentAgent via the event callback. """ # build a packet # have it published by the protocol (force state if needed) # delay? # catch it in the callback # confirm it came back # compare response to original packet self.assertTrue(False) @unittest.skip('Not Written') def test_publish_parsed_data(self): """ Tests to see if parsed data is appropriately published back to the InstrumentAgent via the event callback. """ # similar to above self.assertTrue(False) @unittest.skip('Not Written') def test_publish_engineering_data(self): """ Tests to see if engineering data is appropriately published back to the InstrumentAgent via the event callback. """ # similar to above self.assertTrue(False) def test_get_running_config(self): """ Checks to see that one can successfully get the running config from an instrument protocol. """ # set some values log.debug("First param_dict: %s", self.protocol._param_dict.get_config()) self.protocol._param_dict.add("foo", r'foo=(.*)', lambda match : int(match.group(1)), lambda x : str(x), direct_access=True, default_value=10) self.protocol._param_dict.set_default("foo") # test hack to set w/o fetch self.protocol._param_dict.add("bar", r'bar=(.*)', lambda match : int(match.group(1)), lambda x : str(x), direct_access=False, default_value=15) self.protocol._param_dict.set_default("bar") self.assertEquals(self.protocol._param_dict.get("foo"), 10) self.assertEquals(self.protocol._param_dict.get("bar"), 15) result = self.protocol.get_cached_config() self.assertEquals(result['foo'], 10) self.assertEquals(result['bar'], 15) self.protocol._param_dict.update("bar=20") result = self.protocol.get_cached_config() self.assertEquals(result['foo'], 10) self.assertEquals(result['bar'], 20) self.assertEquals(self.protocol._param_dict.get("bar"), 20) # get and check the running config result = self.protocol.get_cached_config() self.assertTrue(isinstance(result, dict)) self.assertEquals(result['foo'], 10) self.assertEquals(result['bar'], 20) def test_init_values(self): """ Test getting and setting the initialization value for a parameter """ # set an additional value for test self.protocol._param_dict.add("foo", r'foo=(.*)', lambda match : int(match.group(1)), lambda x : str(x), direct_access=True, startup_param=True, default_value=10) self.protocol._param_dict.add("bar", r'bar=(.*)', lambda match : int(match.group(1)), lambda x : str(x), direct_access=False, startup_param=True, default_value=0) self.protocol._param_dict.add("baz", r'baz=(.*)', lambda match : int(match.group(1)), lambda x : str(x), direct_access=True, default_value=20) self.protocol._param_dict.add("bat", r'bat=(.*)', lambda match : int(match.group(1)), lambda x : str(x), startup_param=False, default_value=20) self.protocol._param_dict.add("qux", r'qux=(.*)', lambda match : int(match.group(1)), lambda x : str(x), startup_param=True) self.protocol._param_dict.add("rok", r'rok=(.*)', lambda match : int(match.group(1)), lambda x : str(x)) self.protocol._param_dict.update("qux=6666") # mark init params self.assertRaises(InstrumentParameterException, self.protocol.set_init_params, []) self.protocol.set_init_params({DriverConfigKey.PARAMETERS: {"foo": 1111, "baz":2222}}) # get new startup config self.assertRaises(InstrumentProtocolException, self.protocol.get_startup_config) self.protocol.set_init_params({DriverConfigKey.PARAMETERS: {"foo": 1111, "baz":2222, "bat": 11, "qux": 22}}) result = self.protocol.get_startup_config() self.assertEquals(len(result), 5) self.assertEquals(result["foo"], 1111) # init param self.assertEquals(result["bar"], 0) # init param with default value self.assertEquals(result["baz"], 2222) # non-init param, but value specified self.assertEquals(result["bat"], 11) # set param self.assertEquals(result["qux"], 22) # set param self.assertIsNone(result.get("rok")) # defined in paramdict, no config def test_apply_startup_params(self): """ Test that the apply startup parameters method exists and throws a "not implemented" exception for the base class """ self.assertRaises(NotImplementedException, self.protocol.apply_startup_params) def test_scheduler(self): """ Test to see that the scheduler can add and remove jobs properly Jobs are just queued for adding unit we call initialize_scheduler then the jobs are actually created. """ dt = datetime.datetime.now() + datetime.timedelta(0,1) job_name = 'test_job' startup_config = { DriverConfigKey.SCHEDULER: { job_name: { DriverSchedulerConfigKey.TRIGGER: { DriverSchedulerConfigKey.TRIGGER_TYPE: TriggerType.ABSOLUTE, DriverSchedulerConfigKey.DATE: dt } } } } self.protocol.set_init_params(startup_config) # Verify we are initialized properly self.assertIsNone(self.protocol._scheduler) self.assertEqual(self.protocol._scheduler_config, {}) self.assertEqual(self.protocol._scheduler_callback, {}) # Verify the the scheduler is created self.protocol.initialize_scheduler() self.assertIsInstance(self.protocol._scheduler, DriverScheduler) self.assertEqual(self.protocol._scheduler_config, {}) self.assertEqual(self.protocol._scheduler_callback, {}) # Now lets see some magic happen. Lets add our schedulers. Generally # This would be done as part of the protocol init, but it can happen # anytime. If the scheduler has already been initialized the # job will be started right away self.protocol._add_scheduler(job_name, self._scheduler_callback) self.assertEqual(0, self._trigger_count) self.assert_scheduled_event_triggered() def test_scheduler_event(self): """ Test if we can add and trigger jobs using events instead of callbacks We will create two event triggers, foo and bar. They should come in that order. """ self.protocol._protocol_fsm = Mock() #self.protocol._fsm.on_event = Mock() dt = datetime.datetime.now() + datetime.timedelta(0,1) foo_scheduler = 'foo' bar_scheduler = 'bar' startup_config = { DriverConfigKey.SCHEDULER: { foo_scheduler: { DriverSchedulerConfigKey.TRIGGER: { DriverSchedulerConfigKey.TRIGGER_TYPE: TriggerType.INTERVAL, DriverSchedulerConfigKey.SECONDS: 1 } }, bar_scheduler: { DriverSchedulerConfigKey.TRIGGER: { DriverSchedulerConfigKey.TRIGGER_TYPE: TriggerType.INTERVAL, DriverSchedulerConfigKey.SECONDS: 2 } } } } self.protocol.set_init_params(startup_config) # Verify we are initialized properly self.assertIsNone(self.protocol._scheduler) self.assertEqual(self.protocol._scheduler_config, {}) self.assertEqual(self.protocol._scheduler_callback, {}) # Verify the the scheduler is created self.protocol.initialize_scheduler() self.assertIsInstance(self.protocol._scheduler, DriverScheduler) self.assertEqual(self.protocol._scheduler_config, {}) self.assertEqual(self.protocol._scheduler_callback, {}) # Now lets see some magic happen. Lets add our schedulers. Generally # This would be done as part of the protocol init, but it can happen # anytime. If the scheduler has already been initialized the # job will be started right away foo_event='foo' bar_event='bar' self.protocol._add_scheduler_event(foo_scheduler, foo_event) self.protocol._add_scheduler_event(bar_scheduler, bar_event) self.assertEqual(0, self._trigger_count)