class ProxyLife: def __init__(self, dBlite, path, dictSE, additionalParams={}, minim = 3600*36): self.proxiespath = path if minim < 3600*6: minim = 3600*6 self.minimumleft = minim self.bossCfgDB = dBlite self.dictSE = dictSE # stuff needed for glExec renewal technicalities self.useGlExecDelegation = additionalParams.get("glExecDelegation", 'false')=='true' # register self.ms = MessageService() self.ms.registerAs("TaskLifeManager") # preserv proxyes notified for expiring self.__allproxies = [] ## preserv proxy nitified for cleaning self.__cleanproxies = [] ## clean script #logging.info("Cleaning old script...") #self.delOldScript() ############################################### ###### SYSTEM INTERACTIONS ###### def executeCommand(self, command): import commands status, outp = commands.getstatusoutput(command) return outp def cleanFiles(self, files): self.executeCommand( "rm -f %s "% str(files) ) logging.debug("Executed command: %s "% str("rm -f " + str(files))) def delOldScript(self): workdir = os.getenv("PRODAGENT_WORKDIR") dirwk = os.path.join( workdir, "TaskLifeManager" ) try: files = os.listdir(dirwk) for filet in files: if filet == '.' or filet == '..' or \ not (filet.startswith("deleteSB_") and filet.endswith("_.py")): continue self.cleanFiles( os.path.join( dirwk, filet ) ) except Exception, ex: logging.info("Problem cleaning old script: %s"% str(ex))
def sendMessage(self, event, payload): """sendMessage Publishes a ProdAgent message in the ProdAgent DB. """ ms = MessageService() ms.registerAs("Test") if payload != None: ms.publish(event, payload) else: ms.publish(event, "") ms.commit()
def startComponent(self): """ _startComponent_ Start the component and subscribe to messages """ self.ms = MessageService() # register self.ms.registerAs("RelValInjector") # subscribe to messages self.ms.subscribeTo("RelValInjector:StartDebug") self.ms.subscribeTo("RelValInjector:EndDebug") self.ms.subscribeTo("RelValInjector:Inject") self.ms.subscribeTo("JobSuccess") self.ms.subscribeTo("GeneralJobFailure") self.ms.subscribeTo("RelValInjector:Poll") self.ms.publish("RelValInjector:Poll", "", self.args['PollInterval']) self.ms.commit() while True: Session.set_database(dbConfig) Session.connect() Session.start_transaction() type, payload = self.ms.get() self.ms.commit() logging.debug("RelValInjector: %s, %s" % (type, payload)) self.__call__(type, payload) Session.commit_all() Session.close_all()
def setUp(self): # we use this for event publication. self.ms=MessageService() self.ms.registerAs("TestComponent") self.ms.subscribeTo("SubmitJob") self.failedJobs=1000 self.successJobs=1000 self.maxRetries=2 self.outputPath=os.getenv('PRODAGENT_WORKDIR')
def run(self): """ JabberThread main loop: get task completion messages, sample time and evaluate the throughput. If the time exceeds too much the requirements (+10% to avoid fluctuations) then stop accepting new tasks. """ self.logsys.info("Starting JabberThread") self.ms = MessageService() self.ms.registerAs("CRAB_CmdMgr_jabber") # messages implying meaningful network load self.ms.subscribeTo("CRAB_Cmd_Mgr:NewTask") self.ms.subscribeTo("CRAB_Cmd_Mgr:NewCommand") import time tPre = time.time() if int(self.thr) == 0: self.go_on_accepting_load = 2 self.logsys.info("Stopping accepting load") count = 0 while True: # get messages type, payload = None, None try: type, payload = self.ms.get() self.ms.commit() except Exception, exc: self.logsys.error("ERROR: problem interacting with the message service") self.logsys.error(str(exc)) time.sleep(2) continue self.logsys.debug("JabberThread: %s %s" %(type, payload) ) tPost = time.time() deltaT = tPost - tPre if count%2000 == 0: self.logsys.info("AvgThroughput: %f s (%d connections / day)"%(deltaT, int(0.5+86400/(deltaT+1)) ) ) count = 0 count += 1 # jabber disabled if self.thr < 0.0: continue # alter the guard on the proxy service if int(self.thr) != 0: if deltaT > 1.1 * self.thr: self.go_on_accepting_load = 0 #False self.logsys.info("Stopping accepting load") else: self.go_on_accepting_load = 1 #True
def removePendingEvents(self, componentName): """ _removePendingEvents_ Remove all pending events from the message service for the component specified. Returns the number of events removed """ try: ms = MessageService() # remove messages for component by subscribing to them as # that component and pulling them all out ms.registerAs(componentName) count = 0 while True: type, payload = ms.get(wait = False) if type == None: break else: count += 1 ms.commit() return count except StandardError, ex: msg = "Error while removing pending messages for:\n" msg += "Component Name %s\n" % componentName msg += str(ex) return Fault(1, msg)
def publishRssItem(self, payload): """ Arguments: payload -- the message Return: none """ ms = MessageService() ms.registerAs("RssFeeder") ms.publish("RssFeeder:AddFile", payload) ms.commit() ms.close()
class TriggerUnitTests(unittest.TestCase): """ TestCase for TriggerAPI module """ _triggerSet = False def setUp(self): if not TriggerUnitTests._triggerSet: Session.set_database(dbConfig) Session.connect() Session.start_transaction() print "\n**************Start TriggerUnitTests**********" self.ms=MessageService() self.ms.registerAs("TriggerTest") self.trigger=TriggerAPI(self.ms) self.triggers=5 self.jobspecs=5 self.flags=5 TriggerUnitTests._triggerSet=True Session.commit_all() Session.close_all() def testA(self): Session.set_database(dbConfig) Session.connect() Session.start_transaction() try: print("\nCreate job spec ids") for j in xrange(0,self.jobspecs): JobStateChangeAPI.register("jobSpec"+str(j),"Processing",3,1) except StandardError, ex: msg = "Failed TestA:\n" msg += str(ex) self.fail(msg) Session.commit_all() Session.close_all()
def setUp(self): # we use this for event publication. self.ms=MessageService() self.ms.registerAs("TestComponent") # subscribe on the events this test produces # so we can verify this in the database self.ms.subscribeTo("CreateJob") self.requests=5 self.prodMgrUrl='https://localhost:8443/clarens/' self.jobReportDir='/tmp/prodAgent/ProdMgrInterface/jobReportDir' try: os.makedirs(self.jobReportDir) except: pass
def __init__(self, **args): self.ms = MessageService() self.ms.registerAs("Test") self.datasets = [] self.debug = False self.parameters = {} self.parameters['inputFile'] = None self.parameters.update(args) self.with_threads = False if self.parameters.get('dbsURL', None) is not None: self.dbs_url = self.parameters['dbsURL'] else: self.getLocalDBS() self.getGlobalDBS()
class ComponentServerTest(unittest.TestCase): """ TestCase implementation for ServerTest """ def setUp(self): # we use this for event publication. self.ms=MessageService() self.ms.registerAs("TestComponent") self.ms.subscribeTo("SubmitJob") self.failedJobs=1000 self.successJobs=1000 self.maxRetries=2 self.outputPath=os.getenv('PRODAGENT_WORKDIR') def testA(self): try: print("--->sending debug events") self.ms.publish("ErrorHandler:StartDebug", "none") self.ms.publish("JobCleanup:StartDebug", "none") self.ms.commit() except StandardError, ex: msg = "Failed testA\n" msg += str(ex) self.fail(msg)
def setUp(self): if not TriggerUnitTests._triggerSet: Session.set_database(dbConfig) Session.connect() Session.start_transaction() print "\n**************Start TriggerUnitTests**********" self.ms=MessageService() self.ms.registerAs("TriggerTest") self.trigger=TriggerAPI(self.ms) self.triggers=5 self.jobspecs=5 self.flags=5 TriggerUnitTests._triggerSet=True Session.commit_all() Session.close_all()
def setUp(self): print "******Start ComponentServerTest (ErrorHandler) ***********" print "\nThis test depends on data generated by the JobState_t.py" print " and FwkJobReport_t.py tests and should NOT be run" print " separately, but only in a test suite " print " Make sure ONLY the error handler component is running!" print " " # we use this for event publication. self.ms=MessageService() self.ms.registerAs("TestComponent") # subscribe on the events this test produces # so we can verify this in the database self.ms.subscribeTo("CreateJob") self.ms.subscribeTo("GeneralJobFailure") self.ms.subscribeTo("SubmitJob") self.outputPath=os.getenv('PRODAGENT_WORKDIR')
def __init__(self, dBlite, path, dictSE, additionalParams={}, minim = 3600*36): self.proxiespath = path if minim < 3600*6: minim = 3600*6 self.minimumleft = minim self.bossCfgDB = dBlite self.dictSE = dictSE # stuff needed for glExec renewal technicalities self.useGlExecDelegation = additionalParams.get("glExecDelegation", 'false')=='true' # register self.ms = MessageService() self.ms.registerAs("TaskLifeManager") # preserv proxyes notified for expiring self.__allproxies = [] ## preserv proxy nitified for cleaning self.__cleanproxies = []
def doSubmit(self): """ _doSubmit_ Perform bulk or single submission as needed based on the class data populated by the component that is invoking this plugin """ # create message service ms = MessageService() # register ms.registerAs("JobEmulatorBulkSubmitter") for jobSpec, cacheDir in self.toSubmit.items(): logging.debug("SpecFile = %s" % self.specFiles[jobSpec]) ms.publish("EmulateJob", self.specFiles[jobSpec]) ms.commit() logging.debug("EmulateJob message sent") return
def setUp(self): print """ Message Service test with connections closed and forced refreshed connections inside transactions. See logfile for more details""" # define logging # create log handler logHandler = RotatingFileHandler("logfile","a", 1000000, 3) logFormatter = logging.Formatter("%(asctime)s:%(message)s") logHandler.setFormatter(logFormatter) logging.getLogger().addHandler(logHandler) logging.getLogger().setLevel(logging.DEBUG) # create message service instance self.ms = MessageService() # create components self.ms.registerAs("Component1") self.ms.registerAs("Component2") # subscribe Component2 to messages of type MessageType1 self.ms.subscribeTo("MessageType1")
class AdminControlInterface: """ _AdminControlInterface_ AdminControl XMLRPC interface object Expose accessor methods to retrieve information from the MessageService and JobState DB tables, and allow users to publish events. Every method should return either simple type structures (value, lists, dicts etc) or an xmlrpclib.Fault if there is an error """ def __init__(self): self.ms = MessageService() self.ms.registerAs("AdminControlInterface") self.status = MessageServiceStatus() def publishEvent(self, eventName, payload = ""): """ _publishEvent_ Publish an event into the ProdAgent MessageService """ try: self.ms.publish(eventName, payload) self.ms.commit() return 0 except StandardError, ex: msg = "Error publishing Event: %s\n" msg += "Payload: %s\n" msg += "From AdminControl\n" msg += "Exception: %s" % str(ex) result = Fault(1, msg) return result
def setUp(self): Session.set_database(dbConfig) Session.connect() Session.start_transaction() if not ComponentServerTest._triggerSet: print "\n****Start ComponentServerTest (JobCleanup)*******" # we use this for event publication. self.ms=MessageService() self.ms.registerAs("JobCleanupTest") self.jobSpecs=1000 self.location='/tmp/prodagent/components/JobCleanup/cacheDirs' self.failureJobSpecs=1000 self.flags=5 self.trigger=TriggerAPI(self.ms) # create some directories in tmp print('\nCreating directories in the /tmp area to serve '+ \ 'as job cache dirs') for i in xrange(0,self.jobSpecs): try: os.makedirs(self.location+'/jobSpecDir_'+str(i)) # create some files (some of which should not be deleted, # by a partial cleanup) file1=open(self.location+'/jobSpecDir_'+str(i)+'/JobSpec.xml','w') file1.close() file2=open(self.location+'/jobSpecDir_'+str(i)+'/FrameworkJobReport.xml','w') file2.close() file3=open(self.location+'/jobSpecDir_'+str(i)+'/JobTarFile.tar.gz','w') file3.close() file4=open(self.location+'/jobSpecDir_'+str(i)+'/Pretend2BeADir1.txt','w') file4.close() file5=open(self.location+'/jobSpecDir_'+str(i)+'/Pretend2BeADir2.txt','w') file5.close() except: raise # create jobcaches that need to be tarred and then removed: for i in xrange(0,self.failureJobSpecs): try: os.makedirs(self.location+'/failureJobSpecDir_'+str(i)) file1=open(self.location+'/failureJobSpecDir_'+str(i)+'/JobSpec.xml','w') file1.close() file2=open(self.location+'/failureJobSpecDir_'+str(i)+'/FrameworkJobReport.xml','w') file2.close() file3=open(self.location+'/failureJobSpecDir_'+str(i)+'/JobTarFile.tar.gz','w') file3.close() file4=open(self.location+'/failureJobSpecDir_'+str(i)+'/aFile.txt','w') file4.close() os.makedirs(self.location+'/failureJobSpecDir_'+str(i)+'/aDir1') file5=open(self.location+'/failureJobSpecDir_'+str(i)+'/aDir1/File.txt','w') file5.close() os.makedirs(self.location+'/failureJobSpecDir_'+str(i)+'/aDir2') file6=open(self.location+'/failureJobSpecDir_'+str(i)+'/aDir2/aFile.txt','w') file6.close() os.makedirs(self.location+'/failureJobSpecDir_'+str(i)+'/aDir3') file7=open(self.location+'/failureJobSpecDir_'+str(i)+'/aDir3/aFile.txt','w') file7.close() except: raise ComponentServerTest._triggerSet=True Session.commit_all() Session.close_all()
try: opts, args = getopt.getopt(sys.argv[1:], "", valid) except getopt.GetoptError, ex: print usage print str(ex) sys.exit(1) workflow = None for opt, arg in opts: if opt == "--workflow": workflow = arg if workflow == None: print "--workflow option not provided" print usage sys.exit(1) if not os.path.exists(workflow): print "workflow not found: %s" % workflow sys.exit(1) ## use MessageService ms = MessageService() ## register message service instance as "Test" ms.registerAs("Test") ms.publish("DBSInterface:StartDebug",'') ms.commit() ms.publish("NewDataset",workflow) ms.commit()
if collect['Scenario'] is None: msg = 'Scenario not provided.' print usage print msg sys.exit(1) if collect['RunNumber'] is None: msg = 'You should provide --run.' print usage print msg sys.exit(1) if plugin is not None and plugin not in valid_plugins: msg = 'Invalid plugin.' print usage print msg sys.exit(1) ms = MessageService() ms.registerAs("CLI") if plugin is not None: print "Changing DQMinjector plugin to %s" % plugin ms.publish("DQMInjector:SetPlugin", str(plugin)) ms.commit() print "Publishing DQM workflow creation: %s" % str(collect) ms.publish("DQMInjector:Collect", str(collect)) ms.commit()
class JabberThread(Thread): def __init__(self, summoner, log, throughput): """ @ summoner: class that invoked the Jabber and that maintains the go_on_accepting_load attribute @ log: logging system @ throughput: avrerage number of seconds per task that must be granted @ ms: messageService class for listening completed tasks """ Thread.__init__(self) self.summoner = summoner self.logsys = log self.thr = throughput self.go_on_accepting_load = 1 self.start() pass def run(self): """ JabberThread main loop: get task completion messages, sample time and evaluate the throughput. If the time exceeds too much the requirements (+10% to avoid fluctuations) then stop accepting new tasks. """ self.logsys.info("Starting JabberThread") self.ms = MessageService() self.ms.registerAs("CRAB_CmdMgr_jabber") # messages implying meaningful network load self.ms.subscribeTo("CRAB_Cmd_Mgr:NewTask") self.ms.subscribeTo("CRAB_Cmd_Mgr:NewCommand") import time tPre = time.time() if int(self.thr) == 0: self.go_on_accepting_load = 2 self.logsys.info("Stopping accepting load") count = 0 while True: # get messages type, payload = None, None try: type, payload = self.ms.get() self.ms.commit() except Exception, exc: self.logsys.error("ERROR: problem interacting with the message service") self.logsys.error(str(exc)) time.sleep(2) continue self.logsys.debug("JabberThread: %s %s" %(type, payload) ) tPost = time.time() deltaT = tPost - tPre if count%2000 == 0: self.logsys.info("AvgThroughput: %f s (%d connections / day)"%(deltaT, int(0.5+86400/(deltaT+1)) ) ) count = 0 count += 1 # jabber disabled if self.thr < 0.0: continue # alter the guard on the proxy service if int(self.thr) != 0: if deltaT > 1.1 * self.thr: self.go_on_accepting_load = 0 #False self.logsys.info("Stopping accepting load") else: self.go_on_accepting_load = 1 #True pass
def recreateJob(jobspecFile, jobQueue): """ re-create the processing job """ # remove entries from tr_Trigger/Action tables to be on safer side clean_tr_tables(jobspecFile) # create job if not merge spec = JobSpec() spec.load(jobspecFile) # // # // clean spec id from the job queue #// No easy way to do this in JobQueueAPI so use nekkid SQL for now Session.set_database(dbConfig) Session.connect() sqlStr1 = "DELETE FROM jq_queue WHERE job_spec_id=\"%s\"; " % spec.parameters['JobName'] Session.execute(sqlStr1) Session.commit_all() if spec.parameters['JobType'] in ('Processing', 'CleanUp', 'LogCollect', 'Harvesting'): # publish CreateJob print "- Resubmit Processing job" print "--> Publishing CreateJob for %s"%jobspecFile ms = MessageService() ms.registerAs("Test") if jobQueue: ms.publish("QueueJob", jobspecFile) else: ms.publish("CreateJob", jobspecFile) ms.commit() elif spec.parameters['JobType']=="Merge" : try: jobname=spec.parameters['JobName'] except Exception,ex: msg = "Problem extracting jobspec name from JobSpec File: %s Details: %s"%(jobspecFile,str(ex)) print msg return print "- Resubmit Merge job" print "--> Publishing GeneralJobFailures for %s"%jobname ms = MessageService() ms.registerAs("TestMA") ms.publish("GeneralJobFailure", jobname) ms.commit() time.sleep(1) print "--> Publishing MergeSensor:ReSubmit for %s"%jobname ms = MessageService() ms.registerAs("Test") ms.publish("MergeSensor:ReSubmit", jobname) ms.commit()
__version__ = "$Revision$" __revision__ = "$Id$" import sys if len(sys.argv) not in ( 2, 3,): print "Usage: publish.py <event> <payload>" print " <event> - required - name of event to publish" print " <payload> - optional - content of event payload" sys.exit(0) event = sys.argv[1] payload = None if len(sys.argv) > 2: payload = sys.argv[2] from MessageService.MessageService import MessageService ms = MessageService() ms.registerAs("Test") if payload != None: ms.publish(event, payload) else: ms.publish(event, "") ms.commit()
report = arg for opt, arg in opts: if opt == "--reportFileList": reportFileList = arg if (report == None) and (reportFileList == None) : print "\n either --report or --reportFileList option has to be provided" print usage sys.exit(1) if (report != None) and (reportFileList != None) : print "\n options --report or --reportFileList are mutually exclusive" print usage sys.exit(1) ## use MessageService ms = MessageService() ## register message service instance as "Test" ms.registerAs("Test") ## set debug level ms.publish("DBSInterface:StartDebug",'') ms.commit() if (report != None): expand_report=os.path.expandvars(os.path.expanduser(report)) if not os.path.exists(expand_report): print "FrameWorkJobReport not found: %s" % expand_report sys.exit(1) if checkSuccess(expand_report): ## fire JobSuccess event print "** Send \"JobSuccess\" Event with : %s"%expand_report
def __init__(self): self.ms = MessageService() self.ms.registerAs("AdminControlInterface") self.status = MessageServiceStatus()
if not os.path.exists(workflowCache): msg = "Error: there is no WorkflowCache area ==> %s"%workflowCache print msg sys.exit(1) workflowCacheFile = os.path.join(workflowCache, "%s"%workflowBase) if os.path.exists(workflowCacheFile): WorkflowExists=True msg=" Workflow %s already exists"%(workflowBase,) print msg else: msg=" Workflow %s is NEW since the %s doesn't exist"%(workflowBase,workflowCacheFile) print msg return WorkflowExists,firstrun ## use MessageService ms = MessageService() ## register message service instance as "Test" ms.registerAs("Test") ## Debug level ms.publish("RequestInjector:StartDebug","none") ms.publish("JobCreator:StartDebug","none") ms.publish("JobSubmitter:StartDebug","none") ms.commit() ms.publish("TrackingComponent:StartDebug","none") ms.commit() ms.publish("ErrorHandler:StartDebug","none") ms.commit() ## Set Creator ms.publish("JobCreator:SetCreator","T0LSFCreator") ## Set Submitter
## check workflow existing on disk workflow=os.path.expandvars(os.path.expanduser(workflow)) if not os.path.exists(workflow): print "Workflow not found: %s" % workflow sys.exit(1) ## get the workflow name workflowSpec = WorkflowSpec() workflowSpec.load(workflow) workflowName = workflowSpec.workflowName() workflowBase=os.path.basename(workflow) ## use MessageService ms = MessageService() ## register message service instance as "Test" ms.registerAs("TestSkim") ## Debug level ms.publish("DatasetInjector:StartDebug","none") ms.publish("JobCreator:StartDebug","none") ms.publish("JobSubmitter:StartDebug","none") ms.publish("DBSInterface:StartDebug","none") ms.publish("ErrorHandler:StartDebug","none") ms.publish("TrackingComponent:StartDebug","none") ms.commit() ## Set Creator ms.publish("JobCreator:SetCreator","T0LSFCreator") ## Set Submitter ms.publish("JobSubmitter:SetSubmitter","T0LSFSubmitter")
def __init__(self, **args): self.args = {} self.args.setdefault('Logfile', None) self.args.setdefault('CacheDir', None) self.args.setdefault('ProxiesDir', None) self.args.setdefault('CopyTimeOut', '') # SE support parameters # Protocol = local cannot be the default. Any default allowd # for this parameter... it must be defined from config file. self.args.setdefault('Protocol', '') self.args.setdefault('storageName', 'localhost') self.args.setdefault('storagePort', '') self.args.setdefault('storagePath', self.args["CacheDir"]) # specific delegation strategy for glExex self.args.setdefault('glExecDelegation', 'false') self.args.setdefault('PollInterval',60) self.args.setdefault("HeartBeatDelay", "00:05:00") self.args.update(args) if len(self.args["HeartBeatDelay"]) != 8: self.HeartBeatDelay="00:05:00" else: self.HeartBeatDelay=self.args["HeartBeatDelay"] # define log file if self.args['Logfile'] == None: self.args['Logfile'] = os.path.join(self.args['ComponentDir'], "ComponentLog") # create log handler logHandler = RotatingFileHandler(self.args['Logfile'], "a", 1000000, 7) # define log format logFormatter = logging.Formatter("%(asctime)s:%(message)s") logHandler.setFormatter(logFormatter) logging.getLogger().addHandler(logHandler) logging.getLogger().setLevel(logging.INFO) ## volatile properties self.wdir = self.args['ComponentDir'] self.maxThreads = int( self.args.get('maxThreads', 5) ) self.timePoolDB = self.args['PollInterval'] # shared sessions self.blDBsession = BossLiteAPI('MySQL', dbConfig, makePool=True) self.sessionPool = self.blDBsession.bossLiteDB.getPool() self.workerPool = self.blDBsession.bossLiteDB.getPool() # Get configuration self.init = WMInit() self.init.setLogging() self.init.setDatabaseConnection(os.getenv("DATABASE"), \ os.getenv('DIALECT'), os.getenv("DBSOCK")) self.myThread = threading.currentThread() self.factory = WMFactory("msgService", "WMCore.MsgService."+ \ self.myThread.dialect) self.newMsgService = self.myThread.factory['msgService']\ .loadObject("MsgService") self.ms = MessageService() self.workerCfg = {} logging.info(" ") logging.info("Starting component...")
class ComponentServerTest(unittest.TestCase): """ TestCase implementation for ServerTest """ def setUp(self): print "******Start ComponentServerTest (ErrorHandler) ***********" print "\nThis test depends on data generated by the JobState_t.py" print " and FwkJobReport_t.py tests and should NOT be run" print " separately, but only in a test suite " print " Make sure ONLY the error handler component is running!" print " " # we use this for event publication. self.ms=MessageService() self.ms.registerAs("TestComponent") # subscribe on the events this test produces # so we can verify this in the database self.ms.subscribeTo("CreateJob") self.ms.subscribeTo("GeneralJobFailure") self.ms.subscribeTo("SubmitJob") self.outputPath=os.getenv('PRODAGENT_WORKDIR') def testA(self): print("""\nPublish events to turn ErrorHandler logging on""") try: self.ms.publish("ErrorHandler:StartDebug", "none") self.ms.publish("JobCleanup:StartDebug", "none") self.ms.commit() except StandardError, ex: msg = "Failed testA\n" msg += str(ex) self.fail(msg)
def testPublishUnique(self): """ Test the publishUnique function """ ms1 = MessageService() ms1.registerAs("uniqueComponent1") ms2 = MessageService() ms2.registerAs("uniqueComponent2") ms2.subscribeTo("uniqueMessage") ms1.publishUnique("uniqueMessage","1") ms1.publishUnique("uniqueMessage","2") ms1.commit() #first message sent should be only one retrieved type, payload = ms2.get(wait = False) self.assertEqual(type, "uniqueMessage") self.assertEqual(payload, "1") type, payload = ms2.get(wait = False) self.assertEqual(type, None) self.assertEqual(payload, None) ms2.commit() ms1.purgeMessages() ms2.purgeMessages()