diff --git a/.gitattributes b/.gitattributes index 095be245ab0851640ac286ca379eaa938e5294dd..2ca68313e2b2de80121a1af13a74047ba29fe8a3 100644 --- a/.gitattributes +++ b/.gitattributes @@ -4832,6 +4832,9 @@ SAS/OTDB_Services/test/CMakeLists.txt -text SAS/OTDB_Services/test/t_TreeService.py -text SAS/OTDB_Services/test/t_TreeService.run -text svneol=unset#application/x-shellscript SAS/OTDB_Services/test/t_TreeService.sh -text svneol=unset#application/x-shellscript +SAS/OTDB_Services/test/t_TreeStatusEvents.py -text +SAS/OTDB_Services/test/t_TreeStatusEvents.run -text svneol=unset#application/x-shellscript +SAS/OTDB_Services/test/t_TreeStatusEvents.sh -text svneol=unset#application/x-shellscript SAS/OTDB_Services/test/unittest_db.dump.gz -text svneol=unset#application/x-gzip SAS/Scheduler/src/.default_settings.set -text SAS/Scheduler/src/LOFAR_libScheduler.pro -text diff --git a/MAC/APL/MainCU/src/MACScheduler/MACScheduler.cc b/MAC/APL/MainCU/src/MACScheduler/MACScheduler.cc index 9a81480094e613fa4e1318cce2aa003475d01a4f..268a664f815bdd046c72c783ba3a28f8f5019560 100644 --- a/MAC/APL/MainCU/src/MACScheduler/MACScheduler.cc +++ b/MAC/APL/MainCU/src/MACScheduler/MACScheduler.cc @@ -99,6 +99,14 @@ MACScheduler::MACScheduler() : itsFinishedPeriod= globalParameterSet()->getTime("finishedPeriod", 86400) / 60; // in minutes itsMaxPlanned = globalParameterSet()->getTime("maxPlannedList", 30); itsMaxFinished = globalParameterSet()->getTime("maxFinishedList", 40); + itsExclPLcluster = globalParameterSet()->getString("excludePipelinesOnThisCluster", ""); + if (itsExclPLcluster.length() > 0) { + LOG_INFO_STR("NOT running the pipelines on cluster: " << itsExclPLcluster); + // We need to exclude this cluster for pipelines so make sure the name begins with the 'not'-sign. + if (itsExclPLcluster[0] != '!') { + itsExclPLcluster.insert(0, 1, '!'); + } + } ASSERTSTR(itsMaxPlanned + itsMaxFinished < MAX_CONCURRENT_OBSERVATIONS, "maxPlannedList + maxFinishedList should be less than " << MAX_CONCURRENT_OBSERVATIONS); @@ -623,8 +631,8 @@ void MACScheduler::_updatePlannedList() ptime currentTime = from_time_t(now); ASSERTSTR (currentTime != not_a_date_time, "Can't determine systemtime, bailing out"); - // get new list (list is ordered on starttime) - vector<OTDBtree> plannedDBlist = itsOTDBconnection->getTreeGroup(1, itsPlannedPeriod); // planned observations + // get new list (list is ordered on starttime) of planned observations + vector<OTDBtree> plannedDBlist = itsOTDBconnection->getTreeGroup(1, itsPlannedPeriod, itsExclPLcluster); if (!plannedDBlist.empty()) { LOG_DEBUG(formatString("OTDBCheck:First planned observation (%d) is at %s (active over %d seconds)", @@ -754,7 +762,7 @@ void MACScheduler::_updateActiveList() LOG_DEBUG("_updateActiveList()"); // get new list (list is ordered on starttime) - vector<OTDBtree> activeDBlist = itsOTDBconnection->getTreeGroup(2, 0); + vector<OTDBtree> activeDBlist = itsOTDBconnection->getTreeGroup(2, 0, itsExclPLcluster); if (activeDBlist.empty()) { LOG_DEBUG ("No active Observations"); // NOTE: do not exit routine on emptylist: we need to write an empty list to clear the DB @@ -797,7 +805,7 @@ void MACScheduler::_updateFinishedList() LOG_DEBUG("_updateFinishedList()"); // get new list (list is ordered on starttime) - vector<OTDBtree> finishedDBlist = itsOTDBconnection->getTreeGroup(3, itsFinishedPeriod); + vector<OTDBtree> finishedDBlist = itsOTDBconnection->getTreeGroup(3, itsFinishedPeriod, itsExclPLcluster); if (finishedDBlist.empty()) { LOG_DEBUG ("No finished Observations"); // NOTE: do not exit routine on emptylist: we need to write an empty list to clear the DB diff --git a/MAC/APL/MainCU/src/MACScheduler/MACScheduler.conf.in b/MAC/APL/MainCU/src/MACScheduler/MACScheduler.conf.in index 911f75463162324556fcb8d03141d9aece3381b6..ed9c486a187ff5e142c65ff6fd5a39ac561f72e8 100644 --- a/MAC/APL/MainCU/src/MACScheduler/MACScheduler.conf.in +++ b/MAC/APL/MainCU/src/MACScheduler/MACScheduler.conf.in @@ -30,3 +30,7 @@ maxFinishedList = 40 # Never show more finished observations #ChildControl.MaxStartupRetry = 5 ParsetQueuename = lofar.task.specification.system + +# Pipelines on cluster X can be ignored by the MACScheduler with this key. +# use e.g. 'CEP2' or 'CEP4' +excludePipelinesOnThisCluster = '' diff --git a/MAC/APL/MainCU/src/MACScheduler/MACScheduler.h b/MAC/APL/MainCU/src/MACScheduler/MACScheduler.h index 5654ea1434ea58adf785ddd095daf398e81aac09..188d01364883ed3649aa4a234e3233eda771c34c 100644 --- a/MAC/APL/MainCU/src/MACScheduler/MACScheduler.h +++ b/MAC/APL/MainCU/src/MACScheduler/MACScheduler.h @@ -168,6 +168,9 @@ private: // OTDB related variables. OTDB::OTDBconnection* itsOTDBconnection; // connection to the database + // Cluster to exclude for pipelines. Key is used in the getTreeGroup stored-procedure in OTDB. + string itsExclPLcluster; // like !CEP2 or !CEP4 + // Messagebus related variables ToBus* itsMsgQueue; // Bus used for sending }; diff --git a/MAC/APL/MainCU/src/MACScheduler/MACSchedulerMain.cc b/MAC/APL/MainCU/src/MACScheduler/MACSchedulerMain.cc index 79ede7d94fe484fececff88c7e8db6692cf2d601..6d8caa91d240823ee307ba586b453bf28ae0091a 100644 --- a/MAC/APL/MainCU/src/MACScheduler/MACSchedulerMain.cc +++ b/MAC/APL/MainCU/src/MACScheduler/MACSchedulerMain.cc @@ -39,7 +39,7 @@ int main(int argc, char* argv[]) { GCFScheduler::instance()->init(argc, argv, "MACScheduler"); - MessageBus::init(); + MessageBus::init(); ChildControl* cc = ChildControl::instance(); cc->start(); // make initial transition diff --git a/SAS/OTDB_Services/TreeStatusEvents.py b/SAS/OTDB_Services/TreeStatusEvents.py index 918cc3e4803538e00f15354fd99ecf54f7e87763..2362825ed0ca7398462ea553fa636e87a9fcbb50 100755 --- a/SAS/OTDB_Services/TreeStatusEvents.py +++ b/SAS/OTDB_Services/TreeStatusEvents.py @@ -137,7 +137,7 @@ if __name__ == "__main__": else: for (treeid, state, modtime, creation) in record_list: content = { "treeID" : treeid, "state" : state, "time_of_change" : modtime } - msg = EventMessage("otdb.treestatus", content) + msg = EventMessage(context="otdb.treestatus", content=content) print treeid, state, modtime, creation send_bus.send(msg) open('time_save.txt', 'wb').write(creation) diff --git a/SAS/OTDB_Services/test/CMakeLists.txt b/SAS/OTDB_Services/test/CMakeLists.txt index edf67b38ccac54ec38b9061da1ae04c1cff3a2bc..f5796145f0c26c0dfdf4d61b0b7efa3ab4f7f524 100644 --- a/SAS/OTDB_Services/test/CMakeLists.txt +++ b/SAS/OTDB_Services/test/CMakeLists.txt @@ -3,4 +3,5 @@ include(LofarCTest) lofar_add_test(t_TreeService) +lofar_add_test(t_TreeStatusEvents) diff --git a/SAS/OTDB_Services/test/t_TreeService.run b/SAS/OTDB_Services/test/t_TreeService.run index 37a63124c93466758d77378bdd874591bcef92a4..14cc7a3968eb5a1f300a595e24721b6109db21a5 100755 --- a/SAS/OTDB_Services/test/t_TreeService.run +++ b/SAS/OTDB_Services/test/t_TreeService.run @@ -1,4 +1,4 @@ -#!/bin/sh -ex +#!/bin/sh -x # constants DBHOST=sas099.control.lofar diff --git a/SAS/OTDB_Services/test/t_TreeStatusEvents.py b/SAS/OTDB_Services/test/t_TreeStatusEvents.py new file mode 100644 index 0000000000000000000000000000000000000000..b1acc0634a92c8ff9d28e2fa452c725b9c8b1096 --- /dev/null +++ b/SAS/OTDB_Services/test/t_TreeStatusEvents.py @@ -0,0 +1,91 @@ +#!/usr/bin/env python +#coding: iso-8859-15 +# +# Copyright (C) 2015 +# ASTRON (Netherlands Institute for Radio Astronomy) +# P.O.Box 2, 7990 AA Dwingeloo, The Netherlands +# +# This file is part of the LOFAR software suite. +# The LOFAR software suite is free software: you can redistribute it and/or +# modify it under the terms of the GNU General Public License as published +# by the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# The LOFAR software suite is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with the LOFAR software suite. If not, see <http://www.gnu.org/licenses/>. +# +# $Id: Backtrace.cc 31468 2015-04-13 23:26:52Z amesfoort $ +""" +RPC functions that allow access to (VIC) trees in OTDB. + +TaskSpecificationRequest: get the specification(parset) of a tree as dict. +KeyUpdateCommand : function to update the value of multiple (existing) keys. +StatusUpdateCommand : finction to update the status of a tree. +""" + +import sys, pg +import logging +from optparse import OptionParser +from lofar.messaging import FromBus + +logging.basicConfig(stream=sys.stdout, level=logging.INFO) +logger = logging.getLogger(__name__) + +if __name__ == "__main__": + # Check the invocation arguments + parser = OptionParser("%prog [options]") + parser.add_option("-D", "--database", dest="dbName", type="string", default="", + help="Name of the database") + parser.add_option("-H", "--hostname", dest="dbHost", type="string", default="sasdb", + help="Hostname of database server") + parser.add_option("-B", "--busname", dest="busname", type="string", default="", + help="Busname or queue-name the status changes are published on") + (options, args) = parser.parse_args() + + if not options.dbName: + print "Missing database name" + parser.print_help() + sys.exit(1) + + if not options.dbHost: + print "Missing database server name" + parser.print_help() + sys.exit(1) + + if not options.busname: + print "Missing busname" + parser.print_help() + sys.exit(1) + + try: + print "user=postgres, host=", options.dbHost, "dbname=", options.dbName + otdb_connection = pg.connect(user="postgres", host=options.dbHost, dbname=options.dbName) + except (TypeError, SyntaxError, pg.InternalError): + print "DatabaseError: Connection to database could not be made" + sys.exit(77) + + with FromBus(options.busname) as frombus: + # First drain the queue + no_exception = True + while no_exception: + try: + msg = frombus.receive(timeout=1) + frombus.ack(msg) + except Exception: + no_exception = False + + otdb_connection.query("select setTreeState(1, %d, %d::INT2,'%s')" % (1099266, 500, False)) + msg = frombus.receive(timeout=5) # TreeStateEVent are send every 2 seconds + frombus.ack(msg) + msg.show() + try: + ok = (msg.content['treeID'] == 1099266 and msg.content['state'] == 500) + except IndexError: + ok = False + + sys.exit(not(ok)) # 0 = success diff --git a/SAS/OTDB_Services/test/t_TreeStatusEvents.run b/SAS/OTDB_Services/test/t_TreeStatusEvents.run new file mode 100755 index 0000000000000000000000000000000000000000..22148b99324eeabc1c49ec8f3b56edb082a8df64 --- /dev/null +++ b/SAS/OTDB_Services/test/t_TreeStatusEvents.run @@ -0,0 +1,49 @@ +#!/bin/sh -x +# constants +DBHOST=sas099.control.lofar + +#cleanup on normal exit and on SIGHUP, SIGINT, SIGQUIT, and SIGTERM +trap 'qpid-config del exchange --force $queue ; kill ${SERVICE_PID}' 0 1 2 3 15 + +# Generate randome queue name +queue=$(< /dev/urandom tr -dc [:alnum:] | head -c16) + +# Create the queue +qpid-config add exchange topic $queue + +# Setup a clean database with predefined content +dropdb -U postgres -h ${DBHOST} unittest_db +gzip -dc $srcdir/unittest_db.dump.gz | psql -U postgres -h ${DBHOST} -f - +TreeStatusEvents.py -B $queue -D unittest_db -H ${DBHOST} & +SERVICE_PID=$! +# Starting up takes a while +sleep 3 + +# Run the unit test +# either with or without code coverage measurements, +# depending wheter coverage has been installed + +if type "coverage" > /dev/null; then + #run test using python coverage tool + + #erase previous results + coverage erase + + #setup coverage config file + printf "[report]\nexclude_lines = \n if __name__ == .__main__.\n def main\n" > .coveragerc + + coverage run --branch --include=*Messaging/python* t_TreeStatusEvents.py -D unittest_db -H ${DBHOST} -B $queue + RESULT=$? + if [ $RESULT -eq 0 ]; then + echo " *** Code coverage results *** " + coverage report -m + echo " *** End coverage results *** " + fi + exit $RESULT +else + #coverage not available + echo "Please run: 'pip install coverage' to enable code coverage reporting of the unit tests" + #run plain test script + python t_TreeStatusEvents.py -D unittest_db -H ${DBHOST} -B $queue +fi + diff --git a/SAS/OTDB_Services/test/t_TreeStatusEvents.sh b/SAS/OTDB_Services/test/t_TreeStatusEvents.sh new file mode 100755 index 0000000000000000000000000000000000000000..63d2326f4d9a556cfd978b626fa5429f6a8bd597 --- /dev/null +++ b/SAS/OTDB_Services/test/t_TreeStatusEvents.sh @@ -0,0 +1,2 @@ +#!/bin/sh +./runctest.sh t_TreeStatusEvents diff --git a/SAS/OTDB_Services/test/unittest_db.dump.gz b/SAS/OTDB_Services/test/unittest_db.dump.gz index b0320fb84f5f3d3ab2febf76c4fe591c7d92397f..145e5613516d3e0018a1e15fbe82124d27d98832 100644 Binary files a/SAS/OTDB_Services/test/unittest_db.dump.gz and b/SAS/OTDB_Services/test/unittest_db.dump.gz differ