diff --git a/Script/UnitTests/InfoServiceThread_Test.py b/Script/UnitTests/InfoServiceThread_Test.py index 625314110b075a1a2add313152c796550fb809d9..5f67dc7465d29c114fe3a0a912c6ccb81f9b3353 100644 --- a/Script/UnitTests/InfoServiceThread_Test.py +++ b/Script/UnitTests/InfoServiceThread_Test.py @@ -23,22 +23,28 @@ class TestInfoServiceThread(unittest.TestCase): ## we mock the configuration self.mock_cfg = mock.create_autospec(ConfigHolder) - self.mock_cfg.configure_mock(partition="initial", LogDir="", LogLevel="") + self.mock_cfg.configure_mock(partition="initial", LogDir="", LogLevel="", FileName="Conf_test.cfg") + + ## we're not interested in any logging for this test + with mock.patch("cs.Threads.InfoServiceThread.enable_file_logging"): + self.info_thread = InfoServiceThread(self.mock_cfg, self.mock_event) class TestInfoServiceExit(TestInfoServiceThread): def test_it_should_stop_thread_execution(self): - ## we're not interested in any logging for this test - with mock.patch("cs.Threads.InfoServiceThread.enable_file_logging"): - # I run the thread - info_thread = InfoServiceThread(self.mock_cfg, self.mock_event) - info_thread.start() + # I run the thread + self.info_thread.start() # and shut it down - info_thread.info_service_exit() - info_thread.join(3.0) + self.info_thread.info_service_exit() + self.info_thread.join(3.0) # and I see that the thread has been killed - self.assertFalse(info_thread.is_alive(), msg="InfoService Thread didn't die") + self.assertFalse(self.info_thread.is_alive(), msg="InfoService Thread didn't die") + +class TestGetProcessUptime(TestInfoServiceThread): + + def test_uptime_should_be_positive(self): + self.assertGreaterEqual(self.info_thread.get_process_uptime_in_seconds(), 0) if __name__ == "__main__": unittest.main() diff --git a/Script/cs/Threads/InfoServiceThread.py b/Script/cs/Threads/InfoServiceThread.py index db12d5132a08c7b71f6ad03cf48ad8880932cdfb..94b589431e497b917246b7f716168fb2b3345b89 100644 --- a/Script/cs/Threads/InfoServiceThread.py +++ b/Script/cs/Threads/InfoServiceThread.py @@ -1,17 +1,25 @@ -#!/bin/env python - +#!/usr/bin/env tdaq_python +import logging import threading -import psutil, datetime +import psutil +from datetime import datetime + +#partition libraries +from ipc import IPCPartition #pylint: disable=no-name-in-module +import ispy from cs.Tools.utils import thread_id_string -from cs.Tools.LogConfig import enable_file_logging +from cs.Tools.LogConfig import enable_file_logging, make_tdaq_app_name class InfoServiceThread(threading.Thread): - def __init__(self,conf,event): - - + # get partition and IS dictionary + self.ipc_partition = IPCPartition(conf.partition) + self.is_info_dictionary = ispy.ISInfoDictionary(self.ipc_partition) #pylint: disable=no-member + # state fields + self.tdaq_app_name = make_tdaq_app_name(conf) + self.uptime_seconds = self.get_process_uptime_in_seconds() threading.Thread.__init__(self, name="InfoServiceThread") @@ -31,8 +39,16 @@ class InfoServiceThread(threading.Thread): self.logger.info(thread_id_string()) while not self.exit_flag: - - + #update parameters + self.uptime_seconds = self.get_process_uptime_in_seconds() + + #send to IS + if(self.ipc_partition.isValid()): + self.logger.debug("Provided Partition is Valid") + self.send_update() + else: + self.logger.warning("Provided Partition not Valid, IS Service disabled") + #wait for next update self.event.wait(5) # end while self.logger.info('InfoServiceThread exited') @@ -42,8 +58,23 @@ class InfoServiceThread(threading.Thread): self.exit_flag = 1 self.logger.info('Exit signal received') - def calculate_process_uptime(self): - cs_process = psutil.Process() - time_created = datetime.cs_process.create_time() - datetime.timedelta(time_created, datetime.today()) - datetime.time() + def get_process_uptime_in_seconds(self): + time_created = psutil.Process().create_time() + return (datetime.utcnow() - datetime.utcfromtimestamp(time_created)).total_seconds() + + def send_update(self): + try: + self.logger.debug("Getting state from IS") + + cs_state = ispy.ISInfoDynAny() + self.is_info_dictionary.getValue("{}.CastorScriptState".format(self.conf.partition), cs_state) + + cs_state.tdaq_app_name = self.tdaq_app_name + cs_state.uptime_seconds = self.uptime_seconds + + keep_history = True + self.is_info_dictionary.checkin(data_identifier, self.cs_state, keep_history) + + self.logger.debug("Update sent: {}".format(cs_state)) + except Exception as ex: + self.logger.warning("Error occured while trying to change cs_state to tdaq_app_name={} uptime_seconds={}. Error was: {}".format(self.tdaq_app_name, self.uptime_seconds, ex))