def approveRequest(self, url,workflow): params = {"requestName": workflow, "status": "assignment-approved"} request = JSONRequests(url) headers = {"Content-type": "application/x-www-form-urlencoded", "Accept": "text/plain"} request.put("/reqmgr/reqMgr/request", params, headers) (data, status, reason, _) = request.getresponse() if status != 200: self.debugHttpError(data, status, reason) raise RuntimeError, "PUT failed with code %s" % status self.logger.info("Approved the workflow %s" % workflow)
class RequestManagerTest(RESTBaseUnitTest): """ Test RequestMgr Service client It will start RequestMgr RESTService Server DB is whatever env is set This checks whether DS call makes without error and return the results. This test only test service call returns without error. The correctness of each function is tested in test/python/RequestManager_t/RequestMgr_t.py """ def initialize(self): self.couchDBName = "reqmgr_t_0" self.config = RequestManagerConfig( 'WMCore.HTTPFrontEnd.RequestManager.ReqMgrRESTModel') dbUrl = os.environ.get("DATABASE", None) self.config.setDBUrl(dbUrl) self.config.setFormatter('WMCore.WebTools.RESTFormatter') self.config.setupRequestConfig() self.config.setupCouchDatabase(dbName = self.couchDBName) self.config.setPort(8888) self.schemaModules = ["WMCore.RequestManager.RequestDB"] def setUp(self): RESTBaseUnitTest.setUp(self) self.testInit.setupCouch("%s" % self.couchDBName, "GroupUser", "ConfigCache") self.params = {} self.params['endpoint'] = self.config.getServerUrl() self.reqService = RequestManagerDS(self.params) self.jsonSender = JSONRequests(self.config.getServerUrl()) self.jsonSender.put('user/[email protected]') self.jsonSender.put('group/PeopleLikeMe') self.jsonSender.put('group/PeopleLikeMe/me') self.jsonSender.put('version/CMSSW_3_5_8/slc5_ia32_gcc434') schema = ReReco.getTestArguments() schema['RequestName'] = 'TestReReco' schema['RequestType'] = 'ReReco' schema['CmsPath'] = "/uscmst1/prod/sw/cms" schema['Requestor'] = '%s' % "me" schema['Group'] = '%s' % "PeopleLikeMe" schema['BlockWhitelist'] = ['/dataset/dataset/dataset#alpha'] schema['BlockBlacklist'] = ['/dataset/dataset/dataset#beta'] schema['Campaign'] = 'MyTestCampaign' try: r = self.jsonSender.put('request/' + schema['RequestName'], schema) except Exception, ex: print "Exception during set up, investigate exception instance attributes:" print dir(ex) return self.requestName = r[0]['RequestName']
class RequestManagerTest(RESTBaseUnitTest): """ Test RequestMgr Service client It will start RequestMgr RESTService Server DB is whatever env is set This checks whether DS call makes without error and return the results. This test only test service call returns without error. The correctness of each function is tested in test/python/RequestManager_t/RequestMgr_t.py """ def initialize(self): self.couchDBName = "reqmgr_t_0" self.config = RequestManagerConfig( 'WMCore.HTTPFrontEnd.RequestManager.ReqMgrRESTModel') dbUrl = os.environ.get("DATABASE", None) self.config.setDBUrl(dbUrl) self.config.setFormatter('WMCore.WebTools.RESTFormatter') self.config.setupRequestConfig() self.config.setupCouchDatabase(dbName=self.couchDBName) self.config.setPort(8888) self.schemaModules = ["WMCore.RequestManager.RequestDB"] def setUp(self): RESTBaseUnitTest.setUp(self) self.testInit.setupCouch("%s" % self.couchDBName, "GroupUser", "ConfigCache", "ReqMgr") self.testInit.setupCouch("%s_wmstats" % self.couchDBName, "WMStats") # logging stuff from TestInit is broken, setting myself l = logging.getLogger() l.setLevel(logging.DEBUG) self.params = {} self.params['endpoint'] = self.config.getServerUrl() self.reqService = RequestManagerDS(self.params) self.jsonSender = JSONRequests(self.config.getServerUrl()) userName = '******' groupName = 'Li' teamName = 'Tang' schema = utils.getAndSetupSchema(self, userName=userName, groupName=groupName, teamName=teamName) schema['ConfigCacheID'] = self.createConfig() schema['CouchDBName'] = self.couchDBName try: r = self.jsonSender.put('request/' + schema['RequestName'], schema) self.requestName = r[0]['RequestName'] except Exception, ex: print "Exception during set up, reason: %s" % ex raise ex
class RequestManagerTest(RESTBaseUnitTest): """ Test RequestMgr Service client It will start RequestMgr RESTService Server DB is whatever env is set This checks whether DS call makes without error and return the results. This test only test service call returns without error. The correctness of each function is tested in test/python/RequestManager_t/RequestMgr_t.py """ def initialize(self): self.couchDBName = "reqmgr_t_0" self.config = RequestManagerConfig( 'WMCore.HTTPFrontEnd.RequestManager.ReqMgrRESTModel') dbUrl = os.environ.get("DATABASE", None) self.config.setDBUrl(dbUrl) self.config.setFormatter('WMCore.WebTools.RESTFormatter') self.config.setupRequestConfig() self.config.setupCouchDatabase(dbName = self.couchDBName) self.config.setPort(8888) self.schemaModules = ["WMCore.RequestManager.RequestDB"] def setUp(self): RESTBaseUnitTest.setUp(self) self.testInit.setupCouch("%s" % self.couchDBName, "GroupUser", "ConfigCache") self.testInit.setupCouch("%s_wmstats" % self.couchDBName, "WMStats") # logging stuff from TestInit is broken, setting myself l = logging.getLogger() l.setLevel(logging.DEBUG) self.params = {} self.params['endpoint'] = self.config.getServerUrl() self.reqService = RequestManagerDS(self.params) self.jsonSender = JSONRequests(self.config.getServerUrl()) userName = '******' groupName = 'Li' teamName = 'Tang' schema = utils.getAndSetupSchema(self, userName = userName, groupName = groupName, teamName = teamName) try: r = self.jsonSender.put('request/' + schema['RequestName'], schema) except Exception, ex: print "Exception during set up, reason: %s" % ex return self.requestName = r[0]['RequestName']
class TestReqMgr(RESTBaseUnitTest): """ _TestReqMgr_ Basic test for the ReqMgr services """ def initialize(self): self.config = RequestManagerConfig( 'WMCore.HTTPFrontEnd.RequestManager.ReqMgrRESTModel') dbUrl = os.environ.get("DATABASE", None) if dbUrl == None: raise RuntimeError, """The DATABASE environment is not set. WARNING: setting this variable will cause the database to be deleted during cleanup! """ self.config.setDBUrl(dbUrl) self.config.setFormatter('WMCore.WebTools.RESTFormatter') self.config.setupRequestConfig() # mysql example #self.config.setDBUrl('mysql://[email protected]:3306/TestDB') #self.config.setDBSocket('/var/lib/mysql/mysql.sock') self.schemaModules = ["WMCore.RequestManager.RequestDB"] # Do this is you don't want to remake and delete the schema #self.schemaModules = [] def setUp(self): """ setUP global values """ RESTBaseUnitTest.setUp(self) reqMgrHost = self.config.getServerUrl() self.requestSchema = getRequestSchema() print reqMgrHost self.jsonSender = JSONRequests(reqMgrHost) #self.requestTypes = ['ReReco', 'StoreResults', 'CmsGen', 'Reco'] #self.requestTypes = ['ReReco', 'MonteCarlo'] self.requestTypes = ['ReReco'] if 'me' in self.jsonSender.get('user')[0]: self.jsonSender.delete('user/me') self.assertFalse('me' in self.jsonSender.get('user')[0]) self.assertEqual(self.jsonSender.put('user/[email protected]')[1], 200) self.assertTrue('me' in self.jsonSender.get('user')[0]) if 'PeopleLikeMe' in self.jsonSender.get('group')[0]: self.jsonSender.delete('group/PeopleLikeMe') self.assertFalse('PeopleLikeMe' in self.jsonSender.get('group')[0]) self.assertEqual(self.jsonSender.put('group/PeopleLikeMe')[1], 200) self.assertTrue( 'PeopleLikeMe' in self.jsonSender.get('group')[0]) self.jsonSender.put('group/PeopleLikeMe/me') users = json.loads(self.jsonSender.get('group/PeopleLikeMe')[0])['users'] self.assertTrue('me' in users) groups = json.loads(self.jsonSender.get('user/me')[0])['groups'] self.assertTrue('PeopleLikeMe' in groups) groups2 = self.jsonSender.get('group?user=me')[0] self.assertTrue('PeopleLikeMe' in groups2) if 'White Sox' in self.jsonSender.get('team')[0]: self.jsonSender.delete(urllib.quote('team/White Sox')) self.assertFalse('White Sox' in self.jsonSender.get('team')[0]) self.assertEqual(self.jsonSender.put(urllib.quote('team/White Sox'))[1], 200) self.assertTrue('White Sox' in self.jsonSender.get('team')[0]) # some foreign key stuff to dealwith #self.assertFalse('CMSSW_X_Y_Z' in self.jsonSender.get('version')[0]) self.assertTrue(self.jsonSender.put('version/CMSSW_3_5_8')[1] == 200) self.assertTrue('CMSSW_3_5_8' in self.jsonSender.get('version')[0]) @attr("integration") def testReReco(self): schema = ReReco.getTestArguments() schema['RequestName'] = 'TestReReco' schema['RequestType'] = 'ReReco' schema['CmsPath'] = "/uscmst1/prod/sw/cms" self.doRequest(schema) def doRequest(self, schema): schema['CmsPath'] = "/uscmst1/prod/sw/cms" schema['Requestor'] = 'me' schema['Group'] = 'PeopleLikeMe' requestName = schema['RequestName'] self.assertRaises(HTTPException, self.jsonSender.delete, 'request/%s' % requestName) self.assertEqual(self.jsonSender.put('request/%s' % requestName, schema)[1], 200) self.assertEqual(self.jsonSender.get('request/%s' % requestName)[0]['RequestName'], requestName) self.assertTrue(requestName in self.jsonSender.get('user/me')[0]) self.jsonSender.put('request/%s?status=assignment-approved' % requestName) meJSON = self.jsonSender.get('user/me')[0] me = json.loads(meJSON) self.assertTrue(requestName in me['requests']) self.assertEqual(self.jsonSender.put('request/%s?priority=5' % requestName)[1], 200) self.assertEqual(self.jsonSender.post('user/me?priority=6')[1], 200) self.assertEqual(self.jsonSender.post('group/PeopleLikeMe?priority=7')[1], 200) # default priority of group and user of 1 request = self.jsonSender.get('request/%s' % requestName)[0] self.assertEqual(request['ReqMgrRequestBasePriority'], 5) self.assertEqual(request['ReqMgrRequestorBasePriority'], 6) self.assertEqual(request['ReqMgrGroupBasePriority'], 7) self.assertEqual(request['RequestPriority'], 5+6+7) # only certain transitions allowed #self.assertEqual(self.jsonSender.put('request/%s?status=running' % requestName)[1], 400) self.assertRaises(HTTPException, self.jsonSender.put,'request/%s?status=running' % requestName) request = self.jsonSender.get('request/%s' % requestName)[0] self.assertEqual(request['RequestStatus'], 'assignment-approved') self.assertTrue(self.jsonSender.put(urllib.quote('assignment/White Sox/%s' % requestName))[1] == 200) requestsAndSpecs = self.jsonSender.get(urllib.quote('assignment/White Sox'))[0] self.assertTrue(requestName in requestsAndSpecs.keys()) #workloadHelper = WMWorkloadCache.loadFromURL(requestsAndSpecs[requestName]) workloadHelper = WMWorkloadHelper() workloadHelper.load(requestsAndSpecs[requestName]) self.assertEqual(workloadHelper.getOwner()['Requestor'], "me") self.assertTrue(self.jsonSender.get('assignment?request=%s'% requestName)[0] == ['White Sox']) agentUrl = 'http://cmssrv96.fnal.gov/workqueue' self.jsonSender.put('workQueue/%s?url=%s'% (requestName, urllib.quote(agentUrl)) ) self.assertEqual(self.jsonSender.get('workQueue/%s' % requestName)[0][0], agentUrl) request = self.jsonSender.get('request/%s' % requestName)[0] self.assertEqual(request['RequestStatus'], 'acquired') self.jsonSender.post('request/%s?events_written=10&files_merged=1' % requestName) self.jsonSender.post('request/%s?events_written=20&files_merged=2&percent_success=99.9' % requestName) request = self.jsonSender.get('request/%s' % requestName)[0] self.assertEqual(len(request['RequestUpdates']), 2) self.assertEqual(request['RequestUpdates'][0]['files_merged'], 1) self.assertEqual(request['RequestUpdates'][1]['events_written'], 20) self.assertEqual(request['RequestUpdates'][1]['percent_success'], 99.9) message = "The sheriff is near" jsonMessage = json.dumps(message) self.jsonSender.put('message/%s' % requestName, message) messages = self.jsonSender.get('message/%s' % requestName) #self.assertEqual(messages[0][0][0], message) for status in ['running', 'completed']: self.jsonSender.put('request/%s?status=%s' % (requestName, status)) # campaign self.jsonSender.put('campaign/%s' % 'TestCampaign') campaigns = self.jsonSender.get('campaign')[0] self.assertTrue('TestCampaign' in campaigns.keys()) self.jsonSender.put('campaign/%s/%s' % ('TestCampaign', requestName)) requestsInCampaign = self.jsonSender.get('campaign/%s' % 'TestCampaign')[0] self.assertTrue(requestName in requestsInCampaign.keys()) self.jsonSender.delete('request/%s' % requestName)
class ReqMgrPriorityTest(RESTBaseUnitTest): """ _ReqMgrPriorityTest_ Basic test for setting the priority in ReqMgr Services """ def setUp(self): """ setUP global values Database setUp is done in base class """ self.couchDBName = "reqmgr_t_0" RESTBaseUnitTest.setUp(self) self.testInit.setupCouch("%s" % self.couchDBName, "GroupUser", "ConfigCache") self.testInit.setupCouch("%s_wmstats" % self.couchDBName, "WMStats") reqMgrHost = self.config.getServerUrl() self.jsonSender = JSONRequests(reqMgrHost) def initialize(self): self.config = RequestManagerConfig( 'WMCore.HTTPFrontEnd.RequestManager.ReqMgrRESTModel') self.config.setFormatter('WMCore.WebTools.RESTFormatter') self.config.setupRequestConfig() self.config.setupCouchDatabase(dbName=self.couchDBName) self.config.setPort(8888) self.schemaModules = ["WMCore.RequestManager.RequestDB"] def tearDown(self): """ _tearDown_ Basic tear down of database """ RESTBaseUnitTest.tearDown(self) self.testInit.tearDownCouch() def loadWorkload(self, requestName): """ _loadWorkload_ Load the workload from couch after we've saved it there. """ workload = WMWorkloadHelper() url = '%s/%s/%s/spec' % (os.environ['COUCHURL'], self.couchDBName, requestName) workload.load(url) return workload def changeStatusAndCheck(self, requestName, statusName): """ _changeStatusAndCheck_ Change the status of a request and make sure that the request actually did it. """ self.jsonSender.put('request/%s?status=%s' % (requestName, statusName)) result = self.jsonSender.get('request/%s' % requestName) self.assertEqual(result[0]['RequestStatus'], statusName) def testA_RequestPriority(self): """ _priorityChanges_ Do some fairly standard priority changes to the Request and see how things react """ userName = '******' groupName = 'Li' teamName = 'Tang' schema = utils.getAndSetupSchema(self, userName=userName, groupName=groupName, teamName=teamName) result = self.jsonSender.put('request/testRequest', schema) self.assertEqual(result[1], 200) requestName = result[0]['RequestName'] workload = self.loadWorkload(requestName=requestName) self.assertEqual(workload.priority(), 0) # Reset user, group priorities to 0 self.jsonSender.post('user/%s?priority=0' % userName) self.jsonSender.post('group/%s?priority=0' % groupName) # Set priority == 5 priority = 5 self.jsonSender.put('request/%s?priority=%s' % (requestName, priority)) request = self.jsonSender.get('request/%s' % requestName)[0] self.assertEqual(request['ReqMgrRequestBasePriority'], priority) workload = self.loadWorkload(requestName=requestName) self.assertEqual(workload.priority(), priority) # Set priority == 100 priority = 100 self.jsonSender.put('request/%s?priority=%s' % (requestName, priority)) request = self.jsonSender.get('request/%s' % requestName)[0] self.assertEqual(request['ReqMgrRequestBasePriority'], priority) workload = self.loadWorkload(requestName=requestName) self.assertEqual(workload.priority(), priority) # Set priority == -1 priority = -1 self.jsonSender.put('request/%s?priority=%s' % (requestName, priority)) request = self.jsonSender.get('request/%s' % requestName)[0] self.assertEqual(request['ReqMgrRequestBasePriority'], priority) workload = self.loadWorkload(requestName=requestName) self.assertEqual(workload.priority(), priority) # Let's move the request around a bit self.changeStatusAndCheck(requestName=requestName, statusName='testing-approved') self.changeStatusAndCheck(requestName=requestName, statusName='testing') self.changeStatusAndCheck(requestName=requestName, statusName='tested') self.changeStatusAndCheck(requestName=requestName, statusName='assignment-approved') self.jsonSender.put( urllib.quote('assignment/%s/%s' % (teamName, requestName))) # Set priority == 99 priority = 99 self.jsonSender.put('request/%s?priority=%s' % (requestName, priority)) request = self.jsonSender.get('request/%s' % requestName)[0] self.assertEqual(request['ReqMgrRequestBasePriority'], priority) workload = self.loadWorkload(requestName=requestName) self.assertEqual(workload.priority(), priority) def testB_InvalidPriority(self): """ _InvalidPriority_ Put in a bunch of invalid values for priorities and see what the code makes of them. """ userName = '******' groupName = 'Li' teamName = 'Tang' schema = utils.getAndSetupSchema(self, userName=userName, groupName=groupName, teamName=teamName) result = self.jsonSender.put('request/testRequest', schema) self.assertEqual(result[1], 200) requestName = result[0]['RequestName'] raises = False try: priority = sys.maxint + 1 self.jsonSender.put('request/%s?priority=%s' % (requestName, priority)) except HTTPException, ex: raises = True self.assertEqual(ex.status, 400) self.assertTrue( "Priority must have abs() less then MAXINT!" in ex.result) self.assertTrue(raises) raises = False try: priority = -1 - sys.maxint self.jsonSender.put('request/%s?priority=%s' % (requestName, priority)) except HTTPException, ex: raises = True self.assertEqual(ex.status, 400) print ex.result self.assertTrue( "Priority must have abs() less then MAXINT!" in ex.result)
class ReqMgrPriorityTest(RESTBaseUnitTest): """ Basic test for setting the priority in ReqMgr Services """ def setUp(self): """ setUP global values Database setUp is done in base class """ self.couchDBName = "reqmgr_t_0" RESTBaseUnitTest.setUp(self) self.testInit.setupCouch("%s" % self.couchDBName, "ConfigCache", "ReqMgr") self.testInit.setupCouch("%s_wmstats" % self.couchDBName, "WMStats") self.testInit.setupCouch("%s_acdc" % self.couchDBName, "ACDC") reqMgrHost = self.config.getServerUrl() self.jsonSender = JSONRequests(reqMgrHost) def initialize(self): self.config = RequestManagerConfig( 'WMCore.HTTPFrontEnd.RequestManager.ReqMgrRESTModel') self.config.setFormatter('WMCore.WebTools.RESTFormatter') self.config.setupRequestConfig() self.config.setupCouchDatabase(dbName=self.couchDBName) self.config.setPort(8888) self.schemaModules = ["WMCore.RequestManager.RequestDB"] def tearDown(self): """ _tearDown_ Basic tear down of database """ RESTBaseUnitTest.tearDown(self) self.testInit.tearDownCouch() def loadWorkload(self, requestName): """ _loadWorkload_ Load the workload from couch after we've saved it there. """ workload = WMWorkloadHelper() url = '%s/%s/%s/spec' % (os.environ['COUCHURL'], self.couchDBName, requestName) workload.load(url) return workload def createConfig(self, bad=False): """ _createConfig_ Create a config of some sort that we can load out of ConfigCache """ PSetTweak = { 'process': { 'outputModules_': ['ThisIsAName'], 'ThisIsAName': { 'dataset': { 'dataTier': 'RECO', 'filterName': 'Filter' } } } } BadTweak = { 'process': { 'outputModules_': ['ThisIsAName1', 'ThisIsAName2'], 'ThisIsAName1': { 'dataset': { 'dataTier': 'RECO', 'filterName': 'Filter' } }, 'ThisIsAName2': { 'dataset': { 'dataTier': 'RECO', 'filterName': 'Filter' } } } } configCache = ConfigCache(os.environ["COUCHURL"], couchDBName=self.couchDBName) configCache.createUserGroup(groupname="testGroup", username='******') if bad: configCache.setPSetTweaks(PSetTweak=BadTweak) else: configCache.setPSetTweaks(PSetTweak=PSetTweak) configCache.save() return configCache.getCouchID() def changeStatusAndCheck(self, requestName, statusName): """ _changeStatusAndCheck_ Change the status of a request and make sure that the request actually did it. """ self.jsonSender.put('request/%s?status=%s' % (requestName, statusName)) result = self.jsonSender.get('request/%s' % requestName) self.assertEqual(result[0]['RequestStatus'], statusName) def testA_RequestPriority(self): """ _priorityChanges_ Do some fairly standard priority changes to the Request and see how things react """ userName = '******' groupName = 'Li' teamName = 'Tang' schema = utils.getAndSetupSchema(self, userName=userName, groupName=groupName, teamName=teamName) configID = self.createConfig() schema["ConfigCacheID"] = configID schema["CouchDBName"] = self.couchDBName schema["CouchURL"] = os.environ.get("COUCHURL") result = self.jsonSender.put('request/testRequest', schema) self.assertEqual(result[1], 200) requestName = result[0]['RequestName'] workload = self.loadWorkload(requestName=requestName) self.assertEqual(workload.priority(), 0) # Set priority == 5 priority = 5 self.jsonSender.put('request/%s?priority=%s' % (requestName, priority)) request = self.jsonSender.get('request/%s' % requestName)[0] self.assertEqual(request['RequestPriority'], priority) workload = self.loadWorkload(requestName=requestName) self.assertEqual(workload.priority(), priority) # Set priority == 100 priority = 100 self.jsonSender.put('request/%s?priority=%s' % (requestName, priority)) request = self.jsonSender.get('request/%s' % requestName)[0] self.assertEqual(request['RequestPriority'], priority) workload = self.loadWorkload(requestName=requestName) self.assertEqual(workload.priority(), priority) # Set priority == -1 priority = -1 self.jsonSender.put('request/%s?priority=%s' % (requestName, priority)) request = self.jsonSender.get('request/%s' % requestName)[0] self.assertEqual(request['RequestPriority'], priority) workload = self.loadWorkload(requestName=requestName) self.assertEqual(workload.priority(), priority) # Let's move the request around a bit self.changeStatusAndCheck(requestName=requestName, statusName='testing-approved') self.changeStatusAndCheck(requestName=requestName, statusName='testing') self.changeStatusAndCheck(requestName=requestName, statusName='tested') self.changeStatusAndCheck(requestName=requestName, statusName='assignment-approved') self.jsonSender.put( urllib.quote('assignment/%s/%s' % (teamName, requestName))) # Set priority == 99 priority = 99 self.jsonSender.put('request/%s?priority=%s' % (requestName, priority)) request = self.jsonSender.get('request/%s' % requestName)[0] self.assertEqual(request['RequestPriority'], priority) workload = self.loadWorkload(requestName=requestName) self.assertEqual(workload.priority(), priority) def testB_InvalidPriority(self): """ _InvalidPriority_ Put in a bunch of invalid values for priorities and see what the code makes of them. """ userName = '******' groupName = 'Li' teamName = 'Tang' schema = utils.getAndSetupSchema(self, userName=userName, groupName=groupName, teamName=teamName) configID = self.createConfig() schema["ConfigCacheID"] = configID schema["CouchDBName"] = self.couchDBName schema["CouchURL"] = os.environ.get("COUCHURL") result = self.jsonSender.put('request/testRequest', schema) self.assertEqual(result[1], 200) requestName = result[0]['RequestName'] raises = False try: priority = sys.maxint + 1 self.jsonSender.put('request/%s?priority=%s' % (requestName, priority)) except HTTPException, ex: raises = True self.assertEqual(ex.status, 400) self.assertTrue( "Priority must have abs() less then MAXINT!" in ex.result) self.assertTrue(raises) raises = False try: priority = -1 - sys.maxint self.jsonSender.put('request/%s?priority=%s' % (requestName, priority)) except HTTPException, ex: raises = True self.assertEqual(ex.status, 400) print ex.result self.assertTrue( "Priority must have abs() less then MAXINT!" in ex.result)
class ReqMgrWorkloadTest(RESTBaseUnitTest): """ _ReqMgrWorkloadTest_ Test that sets up and checks the validations of the various main WMSpec.StdSpecs This is mostly a simple set of tests which can be very repetitive. """ def setUp(self): """ setUP global values Database setUp is done in base class """ self.couchDBName = "reqmgr_t_0" RESTBaseUnitTest.setUp(self) self.testInit.setupCouch("%s" % self.couchDBName, "GroupUser", "ConfigCache") reqMgrHost = self.config.getServerUrl() self.jsonSender = JSONRequests(reqMgrHost) return def initialize(self): self.config = RequestManagerConfig( 'WMCore.HTTPFrontEnd.RequestManager.ReqMgrRESTModel') self.config.setFormatter('WMCore.WebTools.RESTFormatter') self.config.setupRequestConfig() self.config.setupCouchDatabase(dbName = self.couchDBName) self.config.setPort(12888) self.schemaModules = ["WMCore.RequestManager.RequestDB"] return def tearDown(self): """ _tearDown_ Basic tear down of database """ RESTBaseUnitTest.tearDown(self) self.testInit.tearDownCouch() return def createConfig(self, bad = False): """ _createConfig_ Create a config of some sort that we can load out of ConfigCache """ PSetTweak = {'process': {'outputModules_': ['ThisIsAName'], 'ThisIsAName': {'dataset': {'dataTier': 'RECO', 'filterName': 'Filter'}}}} BadTweak = {'process': {'outputModules_': ['ThisIsAName1', 'ThisIsAName2'], 'ThisIsAName1': {'dataset': {'dataTier': 'RECO', 'filterName': 'Filter'}}, 'ThisIsAName2': {'dataset': {'dataTier': 'RECO', 'filterName': 'Filter'}}}} configCache = ConfigCache(os.environ["COUCHURL"], couchDBName = self.couchDBName) configCache.createUserGroup(groupname = "testGroup", username = '******') if bad: configCache.setPSetTweaks(PSetTweak = BadTweak) else: configCache.setPSetTweaks(PSetTweak = PSetTweak) configCache.save() return configCache.getCouchID() def setupSchema(self, groupName = 'PeopleLikeMe', userName = '******', teamName = 'White Sox', CMSSWVersion = 'CMSSW_3_5_8', typename = 'ReReco', setupDB = True, scramArch = 'slc5_ia32_gcc434'): """ _setupSchema_ Set up a test schema so that we can run a test request. Standardization! """ if setupDB: self.jsonSender.put('user/%[email protected]' % userName) self.jsonSender.put('group/%s' % groupName) try: self.jsonSender.put('group/%s/%s' % (groupName, userName)) except: # Done this already pass self.jsonSender.put(urllib.quote('team/%s' % teamName)) self.jsonSender.put('version/%s/%s' % (CMSSWVersion, scramArch)) schema = ReReco.getTestArguments() schema['RequestName'] = 'TestReReco' schema['RequestType'] = typename schema['CmsPath'] = "/uscmst1/prod/sw/cms" schema['Requestor'] = '%s' % userName schema['Group'] = '%s' % groupName return schema def loadWorkload(self, requestName): """ _loadWorkload_ Load the workload from couch after we've saved it there. """ workload = WMWorkloadHelper() url = '%s/%s/%s/spec' % (os.environ['COUCHURL'], self.couchDBName, requestName) workload.load(url) return workload @attr('integration') def testA_makeReRecoWorkload(self): """ _makeReRecoWorkload_ Check that you can make a basic ReReco workload """ userName = '******' groupName = 'Li' teamName = 'Tang' CMSSWVersion = 'CMSSW_3_5_8' # Okay, we can make one. Shouldn't surprise us. Let's try # and make a bad one. schema = self.setupSchema(userName = userName, groupName = groupName, teamName = teamName, CMSSWVersion = CMSSWVersion, setupDB = True) del schema['GlobalTag'] raises = False try: self.jsonSender.put('request/testRequest', schema) except HTTPException, ex: raises = True self.assertEqual(ex.status, 400) self.assertTrue("Missing required field GlobalTag in workload validation" in ex.result) self.assertTrue(raises) schema = self.setupSchema(userName = userName, groupName = groupName, teamName = teamName, CMSSWVersion = CMSSWVersion, setupDB = False) schema['InputDataset'] = '/Nothing' raises = False try: self.jsonSender.put('request/testRequest', schema) except HTTPException, ex: raises = True self.assertEqual(ex.status, 400) self.assertTrue("Bad value for InputDataset" in ex.result)
class ReqMgrPriorityTest(RESTBaseUnitTest): """ Basic test for setting the priority in ReqMgr Services """ def setUp(self): """ setUP global values Database setUp is done in base class """ self.couchDBName = "reqmgr_t_0" RESTBaseUnitTest.setUp(self) self.testInit.setupCouch("%s" % self.couchDBName, "ConfigCache", "ReqMgr") self.testInit.setupCouch("%s_wmstats" % self.couchDBName, "WMStats") self.testInit.setupCouch("%s_acdc" % self.couchDBName, "ACDC") reqMgrHost = self.config.getServerUrl() self.jsonSender = JSONRequests(reqMgrHost) def initialize(self): self.config = RequestManagerConfig("WMCore.HTTPFrontEnd.RequestManager.ReqMgrRESTModel") self.config.setFormatter("WMCore.WebTools.RESTFormatter") self.config.setupRequestConfig() self.config.setupCouchDatabase(dbName=self.couchDBName) self.config.setPort(8888) self.schemaModules = ["WMCore.RequestManager.RequestDB"] def tearDown(self): """ _tearDown_ Basic tear down of database """ RESTBaseUnitTest.tearDown(self) self.testInit.tearDownCouch() def loadWorkload(self, requestName): """ _loadWorkload_ Load the workload from couch after we've saved it there. """ workload = WMWorkloadHelper() url = "%s/%s/%s/spec" % (os.environ["COUCHURL"], self.couchDBName, requestName) workload.load(url) return workload def createConfig(self, bad=False): """ _createConfig_ Create a config of some sort that we can load out of ConfigCache """ PSetTweak = { "process": { "outputModules_": ["ThisIsAName"], "ThisIsAName": {"dataset": {"dataTier": "RECO", "filterName": "Filter"}}, } } BadTweak = { "process": { "outputModules_": ["ThisIsAName1", "ThisIsAName2"], "ThisIsAName1": {"dataset": {"dataTier": "RECO", "filterName": "Filter"}}, "ThisIsAName2": {"dataset": {"dataTier": "RECO", "filterName": "Filter"}}, } } configCache = ConfigCache(os.environ["COUCHURL"], couchDBName=self.couchDBName) configCache.createUserGroup(groupname="testGroup", username="******") if bad: configCache.setPSetTweaks(PSetTweak=BadTweak) else: configCache.setPSetTweaks(PSetTweak=PSetTweak) configCache.save() return configCache.getCouchID() def changeStatusAndCheck(self, requestName, statusName): """ _changeStatusAndCheck_ Change the status of a request and make sure that the request actually did it. """ self.jsonSender.put("request/%s?status=%s" % (requestName, statusName)) result = self.jsonSender.get("request/%s" % requestName) self.assertEqual(result[0]["RequestStatus"], statusName) def testA_RequestPriority(self): """ _priorityChanges_ Do some fairly standard priority changes to the Request and see how things react """ userName = "******" groupName = "Li" teamName = "Tang" schema = utils.getAndSetupSchema(self, userName=userName, groupName=groupName, teamName=teamName) configID = self.createConfig() schema["ConfigCacheID"] = configID schema["CouchDBName"] = self.couchDBName schema["CouchURL"] = os.environ.get("COUCHURL") result = self.jsonSender.put("request/testRequest", schema) self.assertEqual(result[1], 200) requestName = result[0]["RequestName"] workload = self.loadWorkload(requestName=requestName) self.assertEqual(workload.priority(), 0) # Set priority == 5 priority = 5 self.jsonSender.put("request/%s?priority=%s" % (requestName, priority)) request = self.jsonSender.get("request/%s" % requestName)[0] self.assertEqual(request["RequestPriority"], priority) workload = self.loadWorkload(requestName=requestName) self.assertEqual(workload.priority(), priority) # Set priority == 100 priority = 100 self.jsonSender.put("request/%s?priority=%s" % (requestName, priority)) request = self.jsonSender.get("request/%s" % requestName)[0] self.assertEqual(request["RequestPriority"], priority) workload = self.loadWorkload(requestName=requestName) self.assertEqual(workload.priority(), priority) # Set priority == -1 priority = -1 self.jsonSender.put("request/%s?priority=%s" % (requestName, priority)) request = self.jsonSender.get("request/%s" % requestName)[0] self.assertEqual(request["RequestPriority"], priority) workload = self.loadWorkload(requestName=requestName) self.assertEqual(workload.priority(), priority) # Let's move the request around a bit self.changeStatusAndCheck(requestName=requestName, statusName="testing-approved") self.changeStatusAndCheck(requestName=requestName, statusName="testing") self.changeStatusAndCheck(requestName=requestName, statusName="tested") self.changeStatusAndCheck(requestName=requestName, statusName="assignment-approved") self.jsonSender.put(urllib.quote("assignment/%s/%s" % (teamName, requestName))) # Set priority == 99 priority = 99 self.jsonSender.put("request/%s?priority=%s" % (requestName, priority)) request = self.jsonSender.get("request/%s" % requestName)[0] self.assertEqual(request["RequestPriority"], priority) workload = self.loadWorkload(requestName=requestName) self.assertEqual(workload.priority(), priority) def testB_InvalidPriority(self): """ _InvalidPriority_ Put in a bunch of invalid values for priorities and see what the code makes of them. """ userName = "******" groupName = "Li" teamName = "Tang" schema = utils.getAndSetupSchema(self, userName=userName, groupName=groupName, teamName=teamName) configID = self.createConfig() schema["ConfigCacheID"] = configID schema["CouchDBName"] = self.couchDBName schema["CouchURL"] = os.environ.get("COUCHURL") result = self.jsonSender.put("request/testRequest", schema) self.assertEqual(result[1], 200) requestName = result[0]["RequestName"] raises = False try: priority = sys.maxsize + 1 self.jsonSender.put("request/%s?priority=%s" % (requestName, priority)) except HTTPException as ex: raises = True self.assertEqual(ex.status, 400) self.assertTrue("Priority must have abs() less then MAXINT!" in ex.result) self.assertTrue(raises) raises = False try: priority = -1 - sys.maxsize self.jsonSender.put("request/%s?priority=%s" % (requestName, priority)) except HTTPException as ex: raises = True self.assertEqual(ex.status, 400) print(ex.result) self.assertTrue("Priority must have abs() less then MAXINT!" in ex.result) self.assertTrue(raises)
class ReqMgrTester(object): def __init__(self, reqMgrUrl): self.reqMgrUrl = reqMgrUrl self.restSender = JSONRequests(reqMgrUrl) d = dict(endpoint = self.reqMgrUrl) self.reqMgrService = RequestManager(d) def queryAllRequests(self): """ Returns all requests stored at ReqMgr instance. """ logging.info("Querying all requests at ReqMgr instance ...") r = self.reqMgrService.getRequestNames() print "Found %s requests:" % len(r) for req in r: print req def queryRequest(self, requestName): """ Query a specific request according to the input argument. """ urlQuery = "request/%s" % requestName logging.info("Querying request '%s'" % requestName) logging.info("Query: '%s':" % urlQuery) r = self.restSender.get(urlQuery) print str(r) def createRequests(self, numRequests): """ Inject new numRequests into ReqMgr instance. (see ReqMgr_t testE how to create a request) """ logging.info("Creating %s new requests ..." % numRequests) schema = ReReco.getTestArguments() schema['RequestName'] = 'TestReReco' schema['RequestType'] = 'ReReco' schema['CmsPath'] = "/uscmst1/prod/sw/cms" schema['Requestor'] = '%s' % "zmaxa" schema['Group'] = '%s' % "DATAOPS" schema['BlockWhitelist'] = ['/dataset/dataset/dataset#alpha'] schema['BlockBlacklist'] = ['/dataset/dataset/dataset#beta'] schema['Campaign'] = 'MyTestCampaign' for i in range(numRequests): urlQuery = "request/testRequest" print "Query: '%s':" % urlQuery print "Schema (request): '%s'" % schema r = self.restSender.put(urlQuery, schema) # print "request creating response: ", r print "created: ", r[0]["RequestName"] def deleteRequest(self, requestNames): """ Delete requests specified in the input, more request names are comma-separated. """ logging.info("Deleting requests ...") for reqName in requestNames.split(','): reqName = reqName.strip() urlQuery = "request/%s" % reqName logging.info("Deleting request (request_name): '%s'" % reqName) logging.info("Query: '%s':" % urlQuery) r = self.restSender.delete(urlQuery) def requestChangeStates(self, reqName): """ Route the request (spec. by the request name) in the input through a series of possible request states. """ logging.info("Changing state of request %s ..." % reqName) def changeState(requestName, urlQuery): logging.info("Query: '%s' ..." % urlQuery) r = self.restSender.put(urlQuery) r = self.restSender.get("request/%s" % requestName) #assert r[0]["RequestStatus"] == statusName logging.info("Querying modified request, new state: %s" % r[0]["RequestStatus"]) # once a request is created, it's in 'new' state # states transition has to be an allowed one as defined here: # WMCore/RequestManager/RequestDB/Settings/RequestStatus.py statesQueries = ["request/%s?status=%s" % (reqName, "testing-approved"), "request/%s?status=%s" % (reqName, "testing"), "request/%s?status=%s" % (reqName, "tested"), "request/%s?status=%s" % (reqName, "assignment-approved"), # create an assignment now # need quote because of space in the team name # (previous name - White Sox) urllib.quote("assignment/%s/%s" % (TEAM_NAME, reqName))] for query in statesQueries: changeState(reqName, query) def setup(self): """ Setup ReqMgr instance for dealing with requests - needs to create a user, group, SW releases entries, etc. as done in test/python/WMCore_t/RequestManager_t/ReqMgr_t.py """ logging.info("ReqMgr setup ...") def doQuery(urlQuery): logging.info("Query: '%s' ..." % urlQuery) r = None try: r = self.restSender.put(urlQuery) except Exception as ex: print "exception" print str(ex) print "response:", r queries = ["user/[email protected]", "group/DATAOPS", "group/DATAOPS/zmaxa", urllib.quote("team/" + TEAM_NAME), "version/%s" % "CMSSW_3_5_8"] for q in queries: doQuery(q) logging.info("ReqMgr setup finished, listing known users ...") q = "user/" r = self.restSender.get(q) print r
class ReqMgrTest(RESTBaseUnitTest): """ Basic test for the ReqMgr services. Setup is done off-screen in RESTBaseUnitTest - this makes things confusing """ def setUp(self): """ setUP global values Database setUp is done in base class """ self.couchDBName = "reqmgr_t_0" RESTBaseUnitTest.setUp(self) self.testInit.setupCouch("%s" % self.couchDBName, "ConfigCache", "ReqMgr") self.testInit.setupCouch("%s_wmstats" % self.couchDBName, "WMStats") self.testInit.setupCouch("%s_acdc" % self.couchDBName, "ACDC", "GroupUser") reqMgrHost = self.config.getServerUrl() self.jsonSender = JSONRequests(reqMgrHost) self.params = {} self.params['endpoint'] = reqMgrHost self.reqService = RequestManager(self.params) def initialize(self): self.config = RequestManagerConfig( 'WMCore.HTTPFrontEnd.RequestManager.ReqMgrRESTModel') self.config.setFormatter('WMCore.WebTools.RESTFormatter') self.config.setupRequestConfig() self.config.setupCouchDatabase(dbName = self.couchDBName) self.config.setPort(12888) self.schemaModules = ["WMCore.RequestManager.RequestDB"] def tearDown(self): """ tearDown Tear down everything """ RESTBaseUnitTest.tearDown(self) self.testInit.tearDownCouch() def createConfig(self, bad = False): """ _createConfig_ Create a config of some sort that we can load out of ConfigCache """ PSetTweak = {'process': {'outputModules_': ['ThisIsAName'], 'ThisIsAName': {'dataset': {'dataTier': 'RECO', 'filterName': 'Filter'}}}} BadTweak = {'process': {'outputModules_': ['ThisIsAName1', 'ThisIsAName2'], 'ThisIsAName1': {'dataset': {'dataTier': 'RECO', 'filterName': 'Filter'}}, 'ThisIsAName2': {'dataset': {'dataTier': 'RECO', 'filterName': 'Filter'}}}} configCache = ConfigCache(os.environ["COUCHURL"], couchDBName = self.couchDBName) configCache.createUserGroup(groupname = "testGroup", username = '******') if bad: configCache.setPSetTweaks(PSetTweak = BadTweak) else: configCache.setPSetTweaks(PSetTweak = PSetTweak) configCache.save() return configCache.getCouchID() @attr("integration") def testA_testBasicSetUp(self): """ _testBasicSetUp_ Moving the tests that were in the setUp category out of it, mostly because I want to make sure that they don't fail inside the setUp statement. """ if 'me' in self.jsonSender.get('user')[0]: self.jsonSender.delete('user/me') self.assertFalse('me' in self.jsonSender.get('user')[0]) self.assertEqual(self.jsonSender.put('user/[email protected]')[1], 200) self.assertTrue('me' in self.jsonSender.get('user')[0]) if 'PeopleLikeMe' in self.jsonSender.get('group')[0]: self.jsonSender.delete('group/PeopleLikeMe') self.assertFalse('PeopleLikeMe' in self.jsonSender.get('group')[0]) self.assertEqual(self.jsonSender.put('group/PeopleLikeMe')[1], 200) self.assertTrue( 'PeopleLikeMe' in self.jsonSender.get('group')[0]) self.jsonSender.put('group/PeopleLikeMe/me') users = self.jsonSender.get('group/PeopleLikeMe')[0]['users'] self.assertTrue('me' in users) groups = self.jsonSender.get('user/me')[0]['groups'] self.assertTrue('PeopleLikeMe' in groups) groups2 = self.jsonSender.get('group?user=me')[0] self.assertTrue('PeopleLikeMe' in groups2) if 'White Sox' in self.jsonSender.get('team')[0]: self.jsonSender.delete(urllib.quote('team/White Sox')) self.assertFalse('White Sox' in self.jsonSender.get('team')[0]) self.assertEqual(self.jsonSender.put(urllib.quote('team/White Sox'))[1], 200) self.assertTrue('White Sox' in self.jsonSender.get('team')[0]) # some foreign key stuff to deal with schema = utils.getSchema() version = "version/" + schema["CMSSWVersion"] self.assertTrue(self.jsonSender.put(version)[1] == 200) self.assertTrue(schema["CMSSWVersion"] in self.jsonSender.get('version')[0]) @attr("integration") def testB_ReReco(self): """ _ReReco_ Try a basic ReReco workflow """ schema = utils.getAndSetupSchema(self) schema['RequestNumEvents'] = 100 schema['SizePerEvent'] = 101 configID = self.createConfig() schema["ConfigCacheID"] = configID schema["CouchDBName"] = self.couchDBName schema["CouchURL"] = os.environ.get("COUCHURL") self.doRequest(schema) def doRequest(self, schema): """ _doRequest_ Run all tests on a basic ReReco workflow """ requestName = schema['RequestName'] self.assertRaises(HTTPException, self.jsonSender.delete, 'request/%s' % requestName) result = self.jsonSender.put('request/%s' % (requestName), schema) self.assertEqual(result[1], 200) requestName = result[0]['RequestName'] self.assertEqual(self.jsonSender.get('request/%s' % requestName)[0]['RequestName'], requestName) self.jsonSender.put('request/%s?status=assignment-approved' % requestName) me = self.jsonSender.get('user/me')[0] self.assertTrue(requestName in me['requests']) self.assertEqual(self.jsonSender.put('request/%s?priority=5' % requestName)[1], 200) request = self.jsonSender.get('request/%s' % requestName)[0] self.assertEqual(request['RequestPriority'], 5) # Check LFN Bases self.assertEqual(request['UnmergedLFNBase'], '/store/unmerged') self.assertEqual(request['MergedLFNBase'], '/store/data') # Check Num events self.assertEqual(request['RequestNumEvents'], 100) self.assertEqual(request['SizePerEvent'], 101) # only certain transitions allowed #self.assertEqual(self.jsonSender.put('request/%s?status=running' % requestName)[1], 400) self.assertRaises(HTTPException, self.jsonSender.put,'request/%s?status=running' % requestName) request = self.jsonSender.get('request/%s' % requestName)[0] self.assertEqual(request['RequestStatus'], 'assignment-approved') self.assertTrue(self.jsonSender.put(urllib.quote('assignment/White Sox/%s' % requestName))[1] == 200) requestsAndSpecs = self.jsonSender.get(urllib.quote('assignment/White Sox'))[0] self.assertTrue(requestName in requestsAndSpecs[0]) workloadHelper = WMWorkloadHelper() workloadHelper.load(requestsAndSpecs[0][1]) self.assertEqual(workloadHelper.getOwner()['Requestor'], "me") self.assertEqual(self.jsonSender.get('assignment?request=%s'% requestName)[0], ['White Sox']) self.assertEqual(self.jsonSender.get('request/%s' % requestName)[0]['teams'], ['White Sox']) agentUrl = 'http://cmssrv96.fnal.gov/workqueue' self.jsonSender.put('workQueue/%s?url=%s'% (requestName, urllib.quote(agentUrl)) ) self.assertEqual(self.jsonSender.get('workQueue/%s' % requestName)[0][0], agentUrl) request = self.jsonSender.get('request/%s' % requestName)[0] self.assertEqual(request['RequestStatus'], 'acquired') self.jsonSender.post('request/%s?events_written=10&files_merged=1' % requestName) self.jsonSender.post('request/%s?events_written=20&files_merged=2&percent_success=99.9' % requestName) request = self.jsonSender.get('request/%s' % requestName)[0] self.assertEqual(len(request['RequestUpdates']), 2) self.assertEqual(request['RequestUpdates'][0]['files_merged'], 1) self.assertEqual(request['RequestUpdates'][1]['events_written'], 20) self.assertEqual(request['RequestUpdates'][1]['percent_success'], 99.9) message = "The sheriff is near" jsonMessage = json.dumps(message) self.jsonSender.put('message/%s' % requestName, message) messages = self.jsonSender.get('message/%s' % requestName) #self.assertEqual(messages[0][0][0], message) for status in ['running-open', 'running-closed', 'completed']: self.jsonSender.put('request/%s?status=%s' % (requestName, status)) # campaign self.jsonSender.put('campaign/%s' % 'TestCampaign') campaigns = self.jsonSender.get('campaign')[0] self.assertTrue('TestCampaign' in campaigns.keys()) self.jsonSender.put('campaign/%s/%s' % ('TestCampaign', requestName)) requestsInCampaign = self.jsonSender.get('campaign/%s' % 'TestCampaign')[0] self.assertTrue(requestName in requestsInCampaign.keys()) req = self.jsonSender.get('request/%s' % requestName)[0] self.assertEqual(req['Campaign'], 'TestCampaign') self.jsonSender.delete('request/%s' % requestName) @attr("integration") def testC_404Errors(self): """ _404Errors_ Do some things that generate 404 errors. This should be limited to requests for objects that do not exist. """ badName = 'ThereIsNoWayThisNameShouldExist' # First, try to find a non-existent request # This should throw a 404 error. # The request name should not be in it self.checkForError(cls = 'request', badName = badName, exitCode = 404, message = 'Given requestName not found') # Now look for non-existent user self.checkForError(cls = 'user', badName = badName, exitCode = 404, message = 'Cannot find user') # Now try non-existent campaign self.checkForError(cls = 'campaign', badName = badName, exitCode = 404, message = "Cannot find campaign") # Now try invalid message # This raises a requestName error because it searches for the request self.checkForError(cls = 'message', badName = badName, exitCode = 404, message = "Given requestName not found", testEmpty = False) # Check for assignments (no teams or requests) # This raises a team error because it tries to load teams out first self.checkForError(cls = 'assignment', badName = badName, exitCode = 404, message = 'Cannot find team') @attr("integration") def testD_400Errors(self): """ _400Errors_ These are failures created by invalid input, such as sending args to a request when it doesn't accept any. They should generatore 400 Errors """ badName = 'ThereIsNoWayThisNameShouldExist' # Attempt to send arguments to a function that doesn't accept them. self.checkForError(cls = 'team', badName = badName, exitCode = 400, message = "Invalid input: Arguments added where none allowed") # Recheck for versions self.checkForError(cls = 'version', badName = badName, exitCode = 400, message = "Invalid input: Arguments added where none allowed") # Break the validation self.checkForError(cls = 'user', badName = '!', exitCode = 400, message = 'Invalid input: Input data failed validation') def checkForError(self, cls, badName, exitCode, message, testEmpty = True): """ _checkForError_ Generic function for checking for errors in JSON commands Does a basic check on type cls searching for name badName which hopefull does not exist. Checks to make sure that it exits with code exitCode, and that the error contains the string message. Also checks to make sure that name badName is NOT in the output testEmpty for those that don't handle calls to the main (i.e., who require an argument) """ raises = False # First assert that the test to be tested is empty if testEmpty: result = self.jsonSender.get(cls) self.assertTrue(type(result[0]) in [type([]), type({})]) # Next, test try: result = self.jsonSender.get('%s/%s' % (cls, badName)) except HTTPException as ex: raises = True self.assertEqual(ex.status, exitCode) self.assertTrue(message in ex.result) self.assertFalse(badName in ex.result) self.assertTrue(raises) @attr("integration") def testE_CheckStatusChanges(self): """ _CheckStatusChanges_ Check status changes for a single request. See whether we can move the request through the proper chain. Figure out what happens when we fail. """ myThread = threading.currentThread() userName = '******' groupName = 'Li' teamName = 'Tang' schema = utils.getAndSetupSchema(self, userName = userName, groupName = groupName, teamName = teamName) configID = self.createConfig() schema["ConfigCacheID"] = configID schema["CouchDBName"] = self.couchDBName schema["CouchURL"] = os.environ.get("COUCHURL") result = self.jsonSender.put('request/testRequest', schema) self.assertEqual(result[1], 200) requestName = result[0]['RequestName'] # There should only be one request in the DB result = GetRequest.requestID(requestName = requestName) self.assertEqual(result, 1) result = self.jsonSender.get('request/%s' % requestName) self.assertEqual(result[0]['Group'], groupName) self.assertEqual(result[0]['Requestor'], userName) # Let's see what we can do in terms of setting status self.changeStatusAndCheck(requestName = requestName, statusName = 'new') # Let's try an illegal status change, just for the hell of it raises = False try: self.jsonSender.put('request/%s?status=assigned' % requestName) except HTTPException as ex: raises = True self.assertEqual(ex.status, 403) self.assertTrue('Failed to change status' in ex.result) self.assertFalse(requestName in ex.result) self.assertTrue(raises) # Now, let's try a totally bogus status raises = False try: self.jsonSender.put('request/%s?status=bogus' % requestName) except HTTPException as ex: raises = True self.assertEqual(ex.status, 403) self.assertTrue('Failed to change status' in ex.result) self.assertFalse(requestName in ex.result) self.assertTrue(raises) # We should still be in new result = self.jsonSender.get('request/%s' % requestName) self.assertEqual(result[0]['RequestStatus'], 'new') # Let's go on in a full loop self.changeStatusAndCheck(requestName = requestName, statusName = 'testing-approved') self.changeStatusAndCheck(requestName = requestName, statusName = 'testing') self.changeStatusAndCheck(requestName = requestName, statusName = 'tested') self.changeStatusAndCheck(requestName = requestName, statusName = 'assignment-approved') # This should fail, as you cannot assign a request without a team raises = False try: self.changeStatusAndCheck(requestName = requestName, statusName = 'assigned') except HTTPException as ex: raises = True self.assertTrue('Cannot change status without a team' in ex.result) self.assertTrue(raises) self.jsonSender.put(urllib.quote('assignment/%s/%s' % (teamName, requestName))) self.changeStatusAndCheck(requestName = requestName, statusName = 'acquired') self.changeStatusAndCheck(requestName = requestName, statusName = 'running-open') self.changeStatusAndCheck(requestName = requestName, statusName = 'running-closed') self.changeStatusAndCheck(requestName = requestName, statusName = 'completed') self.changeStatusAndCheck(requestName = requestName, statusName = 'closed-out') def changeStatusAndCheck(self, requestName, statusName): """ _changeStatusAndCheck_ Change the status of a request and make sure that the request actually did it. """ self.jsonSender.put('request/%s?status=%s' % (requestName, statusName)) result = self.jsonSender.get('request/%s' % requestName) self.assertEqual(result[0]['RequestStatus'], statusName) def loadWorkload(self, requestName): """ _loadWorkload_ Load the workload from couch after we've saved it there. """ workload = WMWorkloadHelper() url = '%s/%s/%s/spec' % (os.environ['COUCHURL'], self.couchDBName, requestName) workload.load(url) return workload def testF_TestWhitelistBlacklist(self): """ _TestWhitelistBlacklist_ Test whether or not we can assign the block/run blacklist/whitelist """ userName = '******' groupName = 'Li' teamName = 'Tang' schema = utils.getAndSetupSchema(self, userName = userName, groupName = groupName, teamName = teamName) schema['RunWhitelist'] = [1, 2, 3] schema['RunBlacklist'] = [4, 5, 6] schema['BlockWhitelist'] = ['/dataset/dataset/dataset#alpha'] schema['BlockBlacklist'] = ['/dataset/dataset/dataset#beta'] configID = self.createConfig() schema["ConfigCacheID"] = configID schema["CouchDBName"] = self.couchDBName schema["CouchURL"] = os.environ.get("COUCHURL") result = self.jsonSender.put('request/testRequest', schema) self.assertEqual(result[1], 200) requestName = result[0]['RequestName'] workload = self.loadWorkload(requestName = requestName) self.assertEqual(workload.data.tasks.DataProcessing.input.dataset.runs.whitelist, schema['RunWhitelist']) self.assertEqual(workload.data.tasks.DataProcessing.input.dataset.runs.blacklist, schema['RunBlacklist']) self.assertEqual(workload.data.tasks.DataProcessing.input.dataset.blocks.whitelist, schema['BlockWhitelist']) self.assertEqual(workload.data.tasks.DataProcessing.input.dataset.blocks.blacklist, schema['BlockBlacklist']) req = self.jsonSender.get('request/%s' % requestName) self.assertTrue('Site Blacklist' in req[0]) self.assertTrue('Site Whitelist' in req[0]) schema['BlockBlacklist'] = {'1': '/dataset/dataset/dataset#beta'} try: raises = False result = self.jsonSender.put('request/testRequest', schema) except HTTPException as ex: raises = True self.assertEqual(ex.status, 400) print(ex.result) self.assertTrue("Error in Workload Validation: Argument BlockBlacklist type is incorrect in schema." in ex.result) pass self.assertTrue(raises) schema['BlockBlacklist'] = ['/dataset/dataset/dataset#beta'] schema['RunWhitelist'] = {'1': '/dataset/dataset/dataset#beta'} try: raises = False result = self.jsonSender.put('request/testRequest', schema) except HTTPException as ex: raises = True self.assertEqual(ex.status, 400) self.assertTrue("Error in Workload Validation: Argument RunWhitelist type is incorrect in schema." in ex.result) pass self.assertTrue(raises) schema['RunWhitelist'] = ['hello', 'how', 'are', 'you'] try: raises = True result = self.jsonSender.put('request/testRequest', schema) except HTTPException as ex: raises = True self.assertEqual(ex.status, 400) self.assertTrue("Error in Workload Validation: Argument RunWhitelist doesn't pass validation." in ex.result) pass self.assertTrue(raises) def testG_AddDuplicateUser(self): """ _AddDuplicateUser_ Test and see if we get a sensible error when adding a duplicate user. """ userName = '******' groupName = 'Li' teamName = 'Tang' schema = utils.getAndSetupSchema(self, userName = userName, groupName = groupName, teamName = teamName) raises = False try: self.jsonSender.put('group/%s/%s' % (groupName, userName)) except HTTPException as ex: self.assertTrue("User/Group Already Linked in DB" in ex.result) self.assertEqual(ex.status, 400) raises = True self.assertTrue(raises) def testH_RemoveSoftwareVersion(self): """ _RemoveSoftwareVersion_ Remove the software version after submitting the request. See what that does. """ myThread = threading.currentThread() userName = '******' groupName = 'Li' teamName = 'Tang' schema = utils.getAndSetupSchema(self, userName = userName, groupName = groupName, teamName = teamName) configID = self.createConfig() schema["ConfigCacheID"] = configID schema["CouchDBName"] = self.couchDBName schema["CouchURL"] = os.environ.get("COUCHURL") result = self.jsonSender.put('request/testRequest', schema) self.assertEqual(result[1], 200) requestName = result[0]['RequestName'] req = self.jsonSender.get('request/%s' % requestName)[0] self.assertEqual(req['SoftwareVersions'], [schema["CMSSWVersion"]]) # Delete software versions and make sure they're gone from the DB SoftwareManagement.removeSoftware(softwareName = schema["CMSSWVersion"], scramArch = schema["ScramArch"]) versions = myThread.dbi.processData("SELECT * FROM reqmgr_software")[0].fetchall() self.assertEqual(versions, []) assocs = myThread.dbi.processData("SELECT * FROM reqmgr_software_dependency")[0].fetchall() self.assertEqual(assocs, []) req = self.jsonSender.get('request/%s' % requestName)[0] self.assertEqual(req['SoftwareVersions'], [schema["CMSSWVersion"]]) def testI_CheckConfigIDs(self): """ _CheckConfigIDs_ Check to see if we can pull out the ConfigIDs by request """ userName = '******' groupName = 'Li' teamName = 'Tang' schema = utils.getAndSetupSchema(self, userName = userName, groupName = groupName, teamName = teamName) # Set some versions schema['ProcessingVersion'] = '2012' schema['AcquisitionEra'] = 'ae2012' schema["PrimaryDataset"] = "ReallyFake" schema["RequestNumEvents"] = 100 configID = self.createConfig() schema["CouchDBName"] = self.couchDBName schema["CouchURL"] = os.environ.get("COUCHURL") schema["ConfigCacheID"] = configID schema["InputDataset"] = '/MinimumBias/Run2010B-RelValRawSkim-v1/RAW' result = self.jsonSender.put('request/testRequest', schema) self.assertEqual(result[1], 200) requestName = result[0]['RequestName'] result = self.jsonSender.get('configIDs?prim=MinimumBias&proc=Run2010B-RelValRawSkim-v1&tier=RAW')[0] print(result) self.assertTrue(requestName in result.keys()) self.assertTrue(configID in result[requestName][0]) def testJ_CheckRequestCloning(self): myThread = threading.currentThread() userName = '******' groupName = 'Li' teamName = 'Tang' schema = utils.getAndSetupSchema(self, userName = userName, groupName = groupName, teamName = teamName) configID = self.createConfig() schema["ConfigCacheID"] = configID schema["CouchDBName"] = self.couchDBName schema["CouchURL"] = os.environ.get("COUCHURL") schema["AcquisitionEra"] = "NewEra" result = self.jsonSender.put("request", schema) self.assertEqual(result[1], 200) requestName = result[0]["RequestName"] acquisitionEra = result[0]["AcquisitionEra"] self.assertTrue(schema["AcquisitionEra"], acquisitionEra) # set some non-default priority # when cloning a request which had some non default priority, # the priority values were lost when creating a cloned request, the # default values were lost. Change it here to specifically catch this case. priority = 300 result = self.jsonSender.put("request/%s?priority=%s" % (requestName, priority)) self.assertEqual(result[1], 200) # get the original request from the server, although the variable result # shall have the same stuff in response = self.jsonSender.get("request/%s" % requestName) origRequest = response[0] self.assertEqual(origRequest["AcquisitionEra"], acquisitionEra) # test that the priority was correctly set in the brand-new request self.assertEqual(origRequest["RequestPriority"], priority) # test cloning not existing request self.assertRaises(HTTPException, self.jsonSender.put, "clone/%s" % "NotExistingRequestName") # correct attempt to clone the request # this is the new request, it'll have different name result = self.jsonSender.put("clone/%s" % requestName) # get the cloned request from the server respose = self.jsonSender.get("request/%s" % result[0]["RequestName"]) clonedRequest = respose[0] # these request arguments shall differ in the cloned request: toDiffer = ["RequestName", "RequestStatus"] for differ in toDiffer: self.assertNotEqual(origRequest[differ], clonedRequest[differ]) # check the desired status of the cloned request self.assertEqual(clonedRequest["RequestStatus"], "assignment-approved", "Cloned request status should be 'assignment-approved', not '%s'." % clonedRequest["RequestStatus"]) # don't care about these two (they will likely be the same in the unittest # since the brand new request injection as well as the cloning probably # happen at roughly the same time) toDiffer.extend(["RequestDate", "timeStamp", "RequestWorkflow"]) for differ in toDiffer: del origRequest[differ] del clonedRequest[differ] # check the request dictionaries self.assertEqual(len(origRequest), len(clonedRequest)) for k1, k2 in zip(sorted(origRequest.keys()), sorted(clonedRequest.keys())): msg = ("Request values: original: %s: %s cloned: %s: %s differ" % (k1, origRequest[k1], k2, clonedRequest[k2])) self.assertEqual(origRequest[k1], clonedRequest[k2], msg) def testK_CheckRequestFailsInjectionForbiddenInputArg(self): myThread = threading.currentThread() userName = '******' groupName = 'Li' teamName = 'Tang' schema = utils.getAndSetupSchema(self, userName = userName, groupName = groupName, teamName = teamName) from WMCore.HTTPFrontEnd.RequestManager.ReqMgrRESTModel import deprecatedRequestArgs for deprec in deprecatedRequestArgs: schema = utils.getSchema(groupName=groupName, userName=userName) schema[deprec] = "something" self.assertRaises(HTTPException, self.jsonSender.put, "request", schema) def setupACDCDatabase(self, collectionName, taskPath, user, group): """ _setupACDCDatabase_ Populate an ACDC database with bogus records associated to certain collection name, user and task path. """ acdcServer = CouchService(url = self.testInit.couchUrl, database = "%s_acdc" % self.couchDBName) owner = acdcServer.newOwner(group, user) testCollection = CouchCollection(database = self.testInit.couchDbName, url = self.testInit.couchUrl, name = collectionName) testCollection.setOwner(owner) testFileset = CouchFileset(database = self.testInit.couchDbName, url = self.testInit.couchUrl, name = taskPath) testCollection.addFileset(testFileset) testFiles = [] for _ in range(5): testFile = File(lfn = makeUUID(), size = random.randint(1024, 4096), events = random.randint(1024, 4096)) testFiles.append(testFile) testFileset.add(testFiles) def testL_CascadeCloseOutAnnnouncement(self): """ _testL_CascadeCloseOutAnnouncement_ Test the cascade closeout REST call, also check that when announced a request deletes all ACDC records in the system. """ userName = '******' groupName = 'Li' teamName = 'Tang' schema = utils.getAndSetupSchema(self, userName = userName, groupName = groupName, teamName = teamName) configID = self.createConfig() schema["ConfigCacheID"] = configID schema["CouchDBName"] = self.couchDBName schema["CouchURL"] = os.environ.get("COUCHURL") result = self.jsonSender.put("request", schema)[0] originalRequest = result['RequestName'] self.setupACDCDatabase(originalRequest, "/%s/DataProcessing" % originalRequest, result['Requestor'], result['Group']) depth = 2 nReq = 3 requests = [originalRequest] def createChildrenRequest(parentRequest, i, nReq): createdRequests = [] resubSchema = utils.getResubmissionSchema(parentRequest, "/%s/DataProcessing" % parentRequest, groupName, userName) result = self.jsonSender.put("request", resubSchema)[0] requestName = result['RequestName'] self.setupACDCDatabase(requestName, "/%s/DataProcessing" % requestName, result['Requestor'], result['Group']) createdRequests.append(requestName) if i: for _ in range(nReq): createdRequests.extend(createChildrenRequest(requestName, i - 1, nReq)) return createdRequests requests.extend(createChildrenRequest(originalRequest, depth, nReq)) for request in requests: self.changeStatusAndCheck(request, 'assignment-approved') for request in requests: self.jsonSender.put("assignment?team=%s&requestName=%s" % (teamName, request)) for status in ['acquired', 'running-open', 'running-closed', 'completed']: for request in requests: self.changeStatusAndCheck(request, status) self.jsonSender.post('closeout?requestName=%s&cascade=True' % originalRequest) svc = CouchService(url = self.testInit.couchUrl, database = "%s_acdc" % self.couchDBName) owner = svc.newOwner(groupName, userName) for request in requests: result = self.jsonSender.get('request/%s' % request) self.assertEqual(result[0]['RequestStatus'], 'closed-out') testCollection = CouchCollection(database = self.testInit.couchDbName, url = self.testInit.couchUrl, name = request) testCollection.setOwner(owner) testCollection.populate() self.assertNotEqual(len(testCollection["filesets"]), 0) self.jsonSender.post('announce?requestName=%s&cascade=True' % originalRequest) for request in requests: result = self.jsonSender.get('request/%s' % request) self.assertEqual(result[0]['RequestStatus'], 'announced') testCollection = CouchCollection(database = self.testInit.couchDbName, url = self.testInit.couchUrl, name = request) testCollection.setOwner(owner) testCollection.populate() self.assertEqual(len(testCollection["filesets"]), 0) def testM_PutRequestStats(self): userName = '******' groupName = 'Bryant' teamName = 'Lakers' schema = utils.getAndSetupSchema(self, userName = userName, groupName = groupName, teamName = teamName) configID = self.createConfig() schema["ConfigCacheID"] = configID schema["CouchDBName"] = self.couchDBName schema["CouchURL"] = os.environ.get("COUCHURL") result = self.jsonSender.put("request", schema)[0] originalRequest = result['RequestName'] stats = {'total_jobs': 100, 'input_events': 100, 'input_lumis': 100, 'input_num_files': 100} result = self.reqService.putRequestStats(originalRequest, stats) self.assertEqual(result['RequestName'], originalRequest)
class ReqMgrPriorityTest(RESTBaseUnitTest): """ Basic test for setting the priority in ReqMgr Services """ def setUp(self): """ setUP global values Database setUp is done in base class """ self.couchDBName = "reqmgr_t_0" RESTBaseUnitTest.setUp(self) self.testInit.setupCouch("%s" % self.couchDBName, "ConfigCache", "ReqMgr") self.testInit.setupCouch("%s_wmstats" % self.couchDBName, "WMStats") self.testInit.setupCouch("%s_acdc" % self.couchDBName, "ACDC") reqMgrHost = self.config.getServerUrl() self.jsonSender = JSONRequests(reqMgrHost) def initialize(self): self.config = RequestManagerConfig( 'WMCore.HTTPFrontEnd.RequestManager.ReqMgrRESTModel') self.config.setFormatter('WMCore.WebTools.RESTFormatter') self.config.setupRequestConfig() self.config.setupCouchDatabase(dbName = self.couchDBName) self.config.setPort(8888) self.schemaModules = ["WMCore.RequestManager.RequestDB"] def tearDown(self): """ _tearDown_ Basic tear down of database """ RESTBaseUnitTest.tearDown(self) self.testInit.tearDownCouch() def loadWorkload(self, requestName): """ _loadWorkload_ Load the workload from couch after we've saved it there. """ workload = WMWorkloadHelper() url = '%s/%s/%s/spec' % (os.environ['COUCHURL'], self.couchDBName, requestName) workload.load(url) return workload def changeStatusAndCheck(self, requestName, statusName): """ _changeStatusAndCheck_ Change the status of a request and make sure that the request actually did it. """ self.jsonSender.put('request/%s?status=%s' % (requestName, statusName)) result = self.jsonSender.get('request/%s' % requestName) self.assertEqual(result[0]['RequestStatus'], statusName) def testA_RequestPriority(self): """ _priorityChanges_ Do some fairly standard priority changes to the Request and see how things react """ userName = '******' groupName = 'Li' teamName = 'Tang' schema = utils.getAndSetupSchema(self, userName = userName, groupName = groupName, teamName = teamName) result = self.jsonSender.put('request/testRequest', schema) self.assertEqual(result[1], 200) requestName = result[0]['RequestName'] workload = self.loadWorkload(requestName = requestName) self.assertEqual(workload.priority(), 0) # Set priority == 5 priority = 5 self.jsonSender.put('request/%s?priority=%s' % (requestName, priority)) request = self.jsonSender.get('request/%s' % requestName)[0] self.assertEqual(request['RequestPriority'], priority) workload = self.loadWorkload(requestName = requestName) self.assertEqual(workload.priority(), priority) # Set priority == 100 priority = 100 self.jsonSender.put('request/%s?priority=%s' % (requestName, priority)) request = self.jsonSender.get('request/%s' % requestName)[0] self.assertEqual(request['RequestPriority'], priority) workload = self.loadWorkload(requestName = requestName) self.assertEqual(workload.priority(), priority) # Set priority == -1 priority = -1 self.jsonSender.put('request/%s?priority=%s' % (requestName, priority)) request = self.jsonSender.get('request/%s' % requestName)[0] self.assertEqual(request['RequestPriority'], priority) workload = self.loadWorkload(requestName = requestName) self.assertEqual(workload.priority(), priority) # Let's move the request around a bit self.changeStatusAndCheck(requestName = requestName, statusName = 'testing-approved') self.changeStatusAndCheck(requestName = requestName, statusName = 'testing') self.changeStatusAndCheck(requestName = requestName, statusName = 'tested') self.changeStatusAndCheck(requestName = requestName, statusName = 'assignment-approved') self.jsonSender.put(urllib.quote('assignment/%s/%s' % (teamName, requestName))) # Set priority == 99 priority = 99 self.jsonSender.put('request/%s?priority=%s' % (requestName, priority)) request = self.jsonSender.get('request/%s' % requestName)[0] self.assertEqual(request['RequestPriority'], priority) workload = self.loadWorkload(requestName = requestName) self.assertEqual(workload.priority(), priority) def testB_InvalidPriority(self): """ _InvalidPriority_ Put in a bunch of invalid values for priorities and see what the code makes of them. """ userName = '******' groupName = 'Li' teamName = 'Tang' schema = utils.getAndSetupSchema(self, userName = userName, groupName = groupName, teamName = teamName) result = self.jsonSender.put('request/testRequest', schema) self.assertEqual(result[1], 200) requestName = result[0]['RequestName'] raises = False try: priority = sys.maxint + 1 self.jsonSender.put('request/%s?priority=%s' % (requestName, priority)) except HTTPException, ex: raises = True self.assertEqual(ex.status, 400) self.assertTrue("Priority must have abs() less then MAXINT!" in ex.result) self.assertTrue(raises) raises = False try: priority = -1 - sys.maxint self.jsonSender.put('request/%s?priority=%s' % (requestName, priority)) except HTTPException, ex: raises = True self.assertEqual(ex.status, 400) print ex.result self.assertTrue("Priority must have abs() less then MAXINT!" in ex.result)
class ReqMgrWorkloadTest(RESTBaseUnitTest): """ Test that sets up and checks the validations of the various main WMSpec.StdSpecs This is mostly a simple set of tests which can be very repetitive. """ def setUp(self): """ setUP global values Database setUp is done in base class """ self.couchDBName = "reqmgr_t_0" RESTBaseUnitTest.setUp(self) self.testInit.setupCouch("%s" % self.couchDBName, "ConfigCache", "ReqMgr") self.testInit.setupCouch("%s_wmstats" % self.couchDBName, "WMStats") reqMgrHost = self.config.getServerUrl() self.jsonSender = JSONRequests(reqMgrHost) def initialize(self): self.config = RequestManagerConfig( 'WMCore.HTTPFrontEnd.RequestManager.ReqMgrRESTModel') self.config.setFormatter('WMCore.WebTools.RESTFormatter') self.config.setupRequestConfig() self.config.setupCouchDatabase(dbName=self.couchDBName) self.config.setPort(12888) self.schemaModules = ["WMCore.RequestManager.RequestDB"] def tearDown(self): """ _tearDown_ Basic tear down of database """ RESTBaseUnitTest.tearDown(self) self.testInit.tearDownCouch() def createConfig(self, bad=False): """ _createConfig_ Create a config of some sort that we can load out of ConfigCache """ PSetTweak = { 'process': { 'outputModules_': ['ThisIsAName'], 'ThisIsAName': { 'dataset': { 'dataTier': 'RECO', 'filterName': 'Filter' } } } } BadTweak = { 'process': { 'outputModules_': ['ThisIsAName1', 'ThisIsAName2'], 'ThisIsAName1': { 'dataset': { 'dataTier': 'RECO', 'filterName': 'Filter' } }, 'ThisIsAName2': { 'dataset': { 'dataTier': 'RECO', 'filterName': 'Filter' } } } } configCache = ConfigCache(os.environ["COUCHURL"], couchDBName=self.couchDBName) configCache.createUserGroup(groupname="testGroup", username='******') if bad: configCache.setPSetTweaks(PSetTweak=BadTweak) else: configCache.setPSetTweaks(PSetTweak=PSetTweak) configCache.save() return configCache.getCouchID() def loadWorkload(self, requestName): """ _loadWorkload_ Load the workload from couch after we've saved it there. """ workload = WMWorkloadHelper() url = '%s/%s/%s/spec' % (os.environ['COUCHURL'], self.couchDBName, requestName) workload.load(url) return workload @attr('integration') def testA_makeReRecoWorkload(self): """ _makeReRecoWorkload_ Check that you can make a basic ReReco workload """ userName = '******' groupName = 'Li' teamName = 'Tang' schema = utils.getAndSetupSchema(self, userName=userName, groupName=groupName, teamName=teamName) del schema['GlobalTag'] configID = self.createConfig(bad=False) schema['ConfigCacheID'] = configID raises = False try: self.jsonSender.put('request/testRequest', schema) except HTTPException, ex: raises = True self.assertEqual(ex.status, 400) self.assertTrue( "Error in Workload Validation: Argument GlobalTag is required." in ex.result) self.assertTrue(raises) schema = utils.getSchema(groupName=groupName, userName=userName) schema['InputDataset'] = '/Nothing' raises = False try: self.jsonSender.put('request/testRequest', schema) except HTTPException, ex: raises = True self.assertEqual(ex.status, 400) print ex.result
class ReqMgrTester(object): def __init__(self, reqMgrUrl): self.reqMgrUrl = reqMgrUrl self.restSender = JSONRequests(reqMgrUrl) d = dict(endpoint = self.reqMgrUrl) self.reqMgrService = RequestManager(d) def queryAllRequests(self): """ Returns all requests stored at ReqMgr instance. """ logging.info("Querying all requests at ReqMgr instance ...") r = self.reqMgrService.getRequestNames() print "Found %s requests:" % len(r) for req in r: print req def queryRequest(self, requestName): """ Query a specific request according to the input argument. """ urlQuery = "request/%s" % requestName logging.info("Querying request '%s'" % requestName) logging.info("Query: '%s':" % urlQuery) r = self.restSender.get(urlQuery) print str(r) def createRequests(self, numRequests): """ Inject new numRequests into ReqMgr instance. (see ReqMgr_t testE how to create a request) """ logging.info("Creating %s new requests ..." % numRequests) schema = ReReco.getTestArguments() schema['RequestName'] = 'TestReReco' schema['RequestType'] = 'ReReco' schema['CmsPath'] = "/uscmst1/prod/sw/cms" schema['Requestor'] = '%s' % "testinguser" schema['Group'] = '%s' % "PeopleLikeMe" schema['BlockWhitelist'] = ['/dataset/dataset/dataset#alpha'] schema['BlockBlacklist'] = ['/dataset/dataset/dataset#beta'] schema['Campaign'] = 'MyTestCampaign' for i in range(numRequests): urlQuery = "request/testRequest" logging.info("Query: '%s':" % urlQuery) r = self.restSender.put(urlQuery, schema) # print "request creating response: ", r print "created: ", r[0]["RequestName"] def deleteRequest(self, requestNames): """ Delete requests specified in the input, more request names are comma-separated. """ logging.info("Deleting requests ...") for reqName in requestNames.split(','): reqName = reqName.strip() urlQuery = "request/%s" % reqName logging.info("Deleting request (request_name): '%s'" % reqName) logging.info("Query: '%s':" % urlQuery) r = self.restSender.delete(urlQuery) def injectOpsClipboard(self, reqName, couchUrl, couchDbName): """ Once a request reaches "ops-hold" state, it can be injected into CouchDB, application OpsClipboard, for further manipulation. Do this here with the reqName request. OpsClipboard.inject() method which does in the CouchDB injection is called from WMCore/HTTPFrontEnd/RequestManager/Assign.py handleAssignmentPage method (which currently, 2012-01, doesn't have any unittest nor REST API) (used only from the Assignment webpage) Works when running locally accessing CouchDB behind frontend: py test/data/ReqMgr/reqmgr-load_example_data.py -u https://localhost:2000/reqmgr/reqMgr/ \ -t testinguser_120131_213320_2161 -i -o https://localhost:2000/couchdb/ \ -a ops_clipboard """ # find out campaign name associated with this request r = self.restSender.get("request/%s" % reqName) campaign = r[0]["Campaign"] logging.info("Campaign: %s" % campaign) requests = [{u"RequestName": reqName, u"CampaignName": campaign}] OpsClipboard.inject(couchUrl, couchDbName, *requests) def requestChangeStates(self, reqName, injectOpsClipboard, couchUrl, couchDbName): """ Route the request (spec. by the request name) in the input through a series of possible request states. """ logging.info("Changing state of request %s ..." % reqName) def changeState(requestName, urlQuery): logging.info("Query: '%s' ..." % urlQuery) r = self.restSender.put(urlQuery) r = self.restSender.get("request/%s" % requestName) #assert r[0]["RequestStatus"] == statusName logging.info("Querying modified request, new state: %s" % r[0]["RequestStatus"]) # once a request is created, it's in 'new' state # states transition has to be an allowed one as defined here: # WMCore/RequestManager/RequestDB/Settings/RequestStatus.py statesQueries = ["request/%s?status=%s" % (reqName, "testing-approved"), "request/%s?status=%s" % (reqName, "testing"), "request/%s?status=%s" % (reqName, "tested"), "request/%s?status=%s" % (reqName, "assignment-approved"), # create an assignment now # need quote because of space in the team name urllib.quote("assignment/%s/%s" % (TEAM_NAME, reqName)), "request/%s?status=%s" % (reqName, "ops-hold")] for query in statesQueries: changeState(reqName, query) if injectOpsClipboard: self.injectOpsClipboard(reqName, couchUrl, couchDbName) def setup(self): """ Setup ReqMgr instance for dealing with requests - needs to create a user, group, SW releases entries, etc. as done in test/python/WMCore_t/RequestManager_t/ReqMgr_t.py """ logging.info("ReqMgr setup ...") def doQuery(urlQuery): logging.info("Query: '%s' ..." % urlQuery) r = None try: r = self.restSender.put(urlQuery) except Exception as ex: print "exception" print str(ex) print "response:", r queries = ["user/[email protected]", "group/PeopleLikeMe", "group/PeopleLikeMe/testinguser", urllib.quote("team/" + TEAM_NAME), "version/%s" % "CMSSW_3_5_8"] for q in queries: doQuery(q) logging.info("ReqMgr setup finished, listing known users ...") q = "user/" r = self.restSender.get(q) print r
class AssignTest(RESTBaseUnitTest): """ _AssignTest_ """ def setUp(self): """ setUP global values Database setUp is done in base class """ self.couchDBName = "reqmgr_t_0" RESTBaseUnitTest.setUp(self, initRoot = False) self.testInit.setupCouch("%s" % self.couchDBName, "GroupUser", "ConfigCache") reqMgrHost = self.config.getServerUrl() self.jsonSender = JSONRequests(reqMgrHost) return def initialize(self): self.config = RequestManagerConfig( 'WMCore.HTTPFrontEnd.RequestManager.Assign') self.config.setFormatter('WMCore.WebTools.RESTFormatter') self.config.setupRequestConfig() self.config.setupCouchDatabase(dbName = self.couchDBName) self.config.setPort(12888) self.schemaModules = ["WMCore.RequestManager.RequestDB"] return def tearDown(self): """ _tearDown_ Basic tear down of database """ RESTBaseUnitTest.tearDown(self) self.testInit.tearDownCouch() return def setupSchema(self, groupName = 'PeopleLikeMe', userName = '******', teamName = 'White Sox', CMSSWVersion = 'CMSSW_3_5_8'): """ _setupSchema_ Set up a test schema so that we can run a test request. Standardization! """ self.jsonSender.put('user/%[email protected]' % userName) self.jsonSender.put('group/%s' % groupName) self.jsonSender.put('group/%s/%s' % (groupName, userName)) self.jsonSender.put(urllib.quote('team/%s' % teamName)) self.jsonSender.put('version/%s' % CMSSWVersion) schema = ReReco.getTestArguments() schema['RequestName'] = 'TestReReco' schema['RequestType'] = 'ReReco' schema['CmsPath'] = "/uscmst1/prod/sw/cms" schema['Requestor'] = '%s' % userName schema['Group'] = '%s' % groupName return schema def loadWorkload(self, requestName): """ _loadWorkload_ Load the workload from couch after we've saved it there. """ workload = WMWorkloadHelper() url = '%s/%s/%s/spec' % (os.environ['COUCHURL'], self.couchDBName, requestName) workload.load(url) return workload def testA_SiteWhitelist(self): """ _SiteWhitelist_ Test to see if we can get the siteWhitelist to work properly. """ secconfig = getattr(self.config, "SecurityModule") cherrypy.server.environment = 'test' cherrypy.tools.secmodv2 = NullAuth(secconfig) self.config.UnitTests.views.active.rest.templates = 'templateDir' self.config.UnitTests.views.active.rest.yuiroot = 'yuiroot' self.config.UnitTests.views.active.rest.wildcardKeys = {'T1*': 'T1_*', 'T2*': 'T2_*', 'T3*': 'T3_*', 'US*': '_US_'} from WMCore.HTTPFrontEnd.RequestManager.Assign import Assign assign = Assign(config = self.config.UnitTests.views.active.rest, noSiteDB = True) siteList = ['T1_US_FNAL', 'T1_CH_CERN', 'T1_UK_RAL', 'T2_US_UCSD', 'T2_US_UNL', 'T2_US_CIT'] self.assertEqual(assign.sites, []) assign.sites.extend(siteList) Utilities.addSiteWildcards(assign.wildcardKeys,assign.sites,assign.wildcardSites) for s in siteList: self.assertTrue(s in assign.sites) self.assertTrue('T1*' in assign.sites) self.assertTrue('T2*' in assign.sites) self.assertFalse('T3*' in assign.sites) self.assertTrue('US*' in assign.sites) self.assertEqual(assign.wildcardSites['T1*'], ['T1_US_FNAL', 'T1_CH_CERN', 'T1_UK_RAL']) self.assertEqual(assign.wildcardSites['T2*'], ['T2_US_UCSD', 'T2_US_UNL', 'T2_US_CIT']) self.assertEqual(assign.wildcardSites['US*'], ['T1_US_FNAL', 'T2_US_UCSD', 'T2_US_UNL', 'T2_US_CIT']) return
class ReqMgrTest(RESTBaseUnitTest): """ Basic test for the ReqMgr services. Setup is done off-screen in RESTBaseUnitTest - this makes things confusing """ def setUp(self): """ setUP global values Database setUp is done in base class """ self.couchDBName = "reqmgr_t_0" RESTBaseUnitTest.setUp(self) self.testInit.setupCouch("%s" % self.couchDBName, "ConfigCache", "ReqMgr") self.testInit.setupCouch("%s_wmstats" % self.couchDBName, "WMStats") self.testInit.setupCouch("%s_acdc" % self.couchDBName, "ACDC", "GroupUser") reqMgrHost = self.config.getServerUrl() self.jsonSender = JSONRequests(reqMgrHost) self.params = {} self.params['endpoint'] = reqMgrHost self.reqService = RequestManager(self.params) def initialize(self): self.config = RequestManagerConfig( 'WMCore.HTTPFrontEnd.RequestManager.ReqMgrRESTModel') self.config.setFormatter('WMCore.WebTools.RESTFormatter') self.config.setupRequestConfig() self.config.setupCouchDatabase(dbName = self.couchDBName) self.config.setPort(12888) self.schemaModules = ["WMCore.RequestManager.RequestDB"] def tearDown(self): """ tearDown Tear down everything """ RESTBaseUnitTest.tearDown(self) self.testInit.tearDownCouch() def createConfig(self, bad = False): """ _createConfig_ Create a config of some sort that we can load out of ConfigCache """ PSetTweak = {'process': {'outputModules_': ['ThisIsAName'], 'ThisIsAName': {'dataset': {'dataTier': 'RECO', 'filterName': 'Filter'}}}} BadTweak = {'process': {'outputModules_': ['ThisIsAName1', 'ThisIsAName2'], 'ThisIsAName1': {'dataset': {'dataTier': 'RECO', 'filterName': 'Filter'}}, 'ThisIsAName2': {'dataset': {'dataTier': 'RECO', 'filterName': 'Filter'}}}} configCache = ConfigCache(os.environ["COUCHURL"], couchDBName = self.couchDBName) configCache.createUserGroup(groupname = "testGroup", username = '******') if bad: configCache.setPSetTweaks(PSetTweak = BadTweak) else: configCache.setPSetTweaks(PSetTweak = PSetTweak) configCache.save() return configCache.getCouchID() @attr("integration") def testA_testBasicSetUp(self): """ _testBasicSetUp_ Moving the tests that were in the setUp category out of it, mostly because I want to make sure that they don't fail inside the setUp statement. """ if 'me' in self.jsonSender.get('user')[0]: self.jsonSender.delete('user/me') self.assertFalse('me' in self.jsonSender.get('user')[0]) self.assertEqual(self.jsonSender.put('user/[email protected]')[1], 200) self.assertTrue('me' in self.jsonSender.get('user')[0]) if 'PeopleLikeMe' in self.jsonSender.get('group')[0]: self.jsonSender.delete('group/PeopleLikeMe') self.assertFalse('PeopleLikeMe' in self.jsonSender.get('group')[0]) self.assertEqual(self.jsonSender.put('group/PeopleLikeMe')[1], 200) self.assertTrue( 'PeopleLikeMe' in self.jsonSender.get('group')[0]) self.jsonSender.put('group/PeopleLikeMe/me') users = self.jsonSender.get('group/PeopleLikeMe')[0]['users'] self.assertTrue('me' in users) groups = self.jsonSender.get('user/me')[0]['groups'] self.assertTrue('PeopleLikeMe' in groups) groups2 = self.jsonSender.get('group?user=me')[0] self.assertTrue('PeopleLikeMe' in groups2) if 'White Sox' in self.jsonSender.get('team')[0]: self.jsonSender.delete(urllib.quote('team/White Sox')) self.assertFalse('White Sox' in self.jsonSender.get('team')[0]) self.assertEqual(self.jsonSender.put(urllib.quote('team/White Sox'))[1], 200) self.assertTrue('White Sox' in self.jsonSender.get('team')[0]) # some foreign key stuff to deal with schema = utils.getSchema() version = "version/" + schema["CMSSWVersion"] self.assertTrue(self.jsonSender.put(version)[1] == 200) self.assertTrue(schema["CMSSWVersion"] in self.jsonSender.get('version')[0]) @attr("integration") def testB_ReReco(self): """ _ReReco_ Try a basic ReReco workflow """ schema = utils.getAndSetupSchema(self) schema['RequestNumEvents'] = 100 schema['SizePerEvent'] = 101 configID = self.createConfig() schema["ConfigCacheID"] = configID schema["CouchDBName"] = self.couchDBName schema["CouchURL"] = os.environ.get("COUCHURL") self.doRequest(schema) def doRequest(self, schema): """ _doRequest_ Run all tests on a basic ReReco workflow """ requestName = schema['RequestName'] self.assertRaises(HTTPException, self.jsonSender.delete, 'request/%s' % requestName) result = self.jsonSender.put('request/%s' % (requestName), schema) self.assertEqual(result[1], 200) requestName = result[0]['RequestName'] self.assertEqual(self.jsonSender.get('request/%s' % requestName)[0]['RequestName'], requestName) self.jsonSender.put('request/%s?status=assignment-approved' % requestName) me = self.jsonSender.get('user/me')[0] self.assertTrue(requestName in me['requests']) self.assertEqual(self.jsonSender.put('request/%s?priority=5' % requestName)[1], 200) request = self.jsonSender.get('request/%s' % requestName)[0] self.assertEqual(request['RequestPriority'], 5) # Check LFN Bases self.assertEqual(request['UnmergedLFNBase'], '/store/unmerged') self.assertEqual(request['MergedLFNBase'], '/store/data') # Check Num events self.assertEqual(request['RequestNumEvents'], 100) self.assertEqual(request['SizePerEvent'], 101) # only certain transitions allowed #self.assertEqual(self.jsonSender.put('request/%s?status=running' % requestName)[1], 400) self.assertRaises(HTTPException, self.jsonSender.put,'request/%s?status=running' % requestName) request = self.jsonSender.get('request/%s' % requestName)[0] self.assertEqual(request['RequestStatus'], 'assignment-approved') self.assertTrue(self.jsonSender.put(urllib.quote('assignment/White Sox/%s' % requestName))[1] == 200) requestsAndSpecs = self.jsonSender.get(urllib.quote('assignment/White Sox'))[0] self.assertTrue(requestName in requestsAndSpecs[0]) workloadHelper = WMWorkloadHelper() workloadHelper.load(requestsAndSpecs[0][1]) self.assertEqual(workloadHelper.getOwner()['Requestor'], "me") self.assertEqual(self.jsonSender.get('assignment?request=%s'% requestName)[0], ['White Sox']) self.assertEqual(self.jsonSender.get('request/%s' % requestName)[0]['teams'], ['White Sox']) agentUrl = 'http://cmssrv96.fnal.gov/workqueue' self.jsonSender.put('workQueue/%s?url=%s'% (requestName, urllib.quote(agentUrl)) ) self.assertEqual(self.jsonSender.get('workQueue/%s' % requestName)[0][0], agentUrl) request = self.jsonSender.get('request/%s' % requestName)[0] self.assertEqual(request['RequestStatus'], 'acquired') self.jsonSender.post('request/%s?events_written=10&files_merged=1' % requestName) self.jsonSender.post('request/%s?events_written=20&files_merged=2&percent_success=99.9' % requestName) request = self.jsonSender.get('request/%s' % requestName)[0] self.assertEqual(len(request['RequestUpdates']), 2) self.assertEqual(request['RequestUpdates'][0]['files_merged'], 1) self.assertEqual(request['RequestUpdates'][1]['events_written'], 20) self.assertEqual(request['RequestUpdates'][1]['percent_success'], 99.9) message = "The sheriff is near" jsonMessage = json.dumps(message) self.jsonSender.put('message/%s' % requestName, message) messages = self.jsonSender.get('message/%s' % requestName) #self.assertEqual(messages[0][0][0], message) for status in ['running-open', 'running-closed', 'completed']: self.jsonSender.put('request/%s?status=%s' % (requestName, status)) # campaign self.jsonSender.put('campaign/%s' % 'TestCampaign') campaigns = self.jsonSender.get('campaign')[0] self.assertTrue('TestCampaign' in campaigns.keys()) self.jsonSender.put('campaign/%s/%s' % ('TestCampaign', requestName)) requestsInCampaign = self.jsonSender.get('campaign/%s' % 'TestCampaign')[0] self.assertTrue(requestName in requestsInCampaign.keys()) req = self.jsonSender.get('request/%s' % requestName)[0] self.assertEqual(req['Campaign'], 'TestCampaign') self.jsonSender.delete('request/%s' % requestName) @attr("integration") def testC_404Errors(self): """ _404Errors_ Do some things that generate 404 errors. This should be limited to requests for objects that do not exist. """ badName = 'ThereIsNoWayThisNameShouldExist' # First, try to find a non-existent request # This should throw a 404 error. # The request name should not be in it self.checkForError(cls = 'request', badName = badName, exitCode = 404, message = 'Given requestName not found') # Now look for non-existent user self.checkForError(cls = 'user', badName = badName, exitCode = 404, message = 'Cannot find user') # Now try non-existent campaign self.checkForError(cls = 'campaign', badName = badName, exitCode = 404, message = "Cannot find campaign") # Now try invalid message # This raises a requestName error because it searches for the request self.checkForError(cls = 'message', badName = badName, exitCode = 404, message = "Given requestName not found", testEmpty = False) # Check for assignments (no teams or requests) # This raises a team error because it tries to load teams out first self.checkForError(cls = 'assignment', badName = badName, exitCode = 404, message = 'Cannot find team') @attr("integration") def testD_400Errors(self): """ _400Errors_ These are failures created by invalid input, such as sending args to a request when it doesn't accept any. They should generatore 400 Errors """ badName = 'ThereIsNoWayThisNameShouldExist' # Attempt to send arguments to a function that doesn't accept them. self.checkForError(cls = 'team', badName = badName, exitCode = 400, message = "Invalid input: Arguments added where none allowed") # Recheck for versions self.checkForError(cls = 'version', badName = badName, exitCode = 400, message = "Invalid input: Arguments added where none allowed") # Break the validation self.checkForError(cls = 'user', badName = '!', exitCode = 400, message = 'Invalid input: Input data failed validation') def checkForError(self, cls, badName, exitCode, message, testEmpty = True): """ _checkForError_ Generic function for checking for errors in JSON commands Does a basic check on type cls searching for name badName which hopefull does not exist. Checks to make sure that it exits with code exitCode, and that the error contains the string message. Also checks to make sure that name badName is NOT in the output testEmpty for those that don't handle calls to the main (i.e., who require an argument) """ raises = False # First assert that the test to be tested is empty if testEmpty: result = self.jsonSender.get(cls) self.assertTrue(type(result[0]) in [type([]), type({})]) # Next, test try: result = self.jsonSender.get('%s/%s' % (cls, badName)) except HTTPException as ex: raises = True self.assertEqual(ex.status, exitCode) self.assertTrue(message in ex.result) self.assertFalse(badName in ex.result) self.assertTrue(raises) @attr("integration") def testE_CheckStatusChanges(self): """ _CheckStatusChanges_ Check status changes for a single request. See whether we can move the request through the proper chain. Figure out what happens when we fail. """ myThread = threading.currentThread() userName = '******' groupName = 'Li' teamName = 'Tang' schema = utils.getAndSetupSchema(self, userName = userName, groupName = groupName, teamName = teamName) configID = self.createConfig() schema["ConfigCacheID"] = configID schema["CouchDBName"] = self.couchDBName schema["CouchURL"] = os.environ.get("COUCHURL") result = self.jsonSender.put('request/testRequest', schema) self.assertEqual(result[1], 200) requestName = result[0]['RequestName'] # There should only be one request in the DB result = GetRequest.requestID(requestName = requestName) self.assertEqual(result, 1) result = self.jsonSender.get('request/%s' % requestName) self.assertEqual(result[0]['Group'], groupName) self.assertEqual(result[0]['Requestor'], userName) # Let's see what we can do in terms of setting status self.changeStatusAndCheck(requestName = requestName, statusName = 'new') # Let's try an illegal status change, just for the hell of it raises = False try: self.jsonSender.put('request/%s?status=negotiating' % requestName) except HTTPException as ex: raises = True self.assertEqual(ex.status, 403) self.assertTrue('Failed to change status' in ex.result) self.assertFalse(requestName in ex.result) self.assertTrue(raises) # Now, let's try a totally bogus status raises = False try: self.jsonSender.put('request/%s?status=bogus' % requestName) except HTTPException as ex: raises = True self.assertEqual(ex.status, 403) self.assertTrue('Failed to change status' in ex.result) self.assertFalse(requestName in ex.result) self.assertTrue(raises) # We should still be in new result = self.jsonSender.get('request/%s' % requestName) self.assertEqual(result[0]['RequestStatus'], 'new') # Let's go on in a full loop self.changeStatusAndCheck(requestName = requestName, statusName = 'testing-approved') self.changeStatusAndCheck(requestName = requestName, statusName = 'testing') self.changeStatusAndCheck(requestName = requestName, statusName = 'tested') self.changeStatusAndCheck(requestName = requestName, statusName = 'assignment-approved') # This should fail, as you cannot assign a request without a team raises = False try: self.changeStatusAndCheck(requestName = requestName, statusName = 'assigned') except HTTPException as ex: raises = True self.assertTrue('Cannot change status without a team' in ex.result) self.assertTrue(raises) self.jsonSender.put(urllib.quote('assignment/%s/%s' % (teamName, requestName))) self.changeStatusAndCheck(requestName = requestName, statusName = 'negotiating') self.changeStatusAndCheck(requestName = requestName, statusName = 'acquired') self.changeStatusAndCheck(requestName = requestName, statusName = 'running-open') self.changeStatusAndCheck(requestName = requestName, statusName = 'running-closed') self.changeStatusAndCheck(requestName = requestName, statusName = 'completed') self.changeStatusAndCheck(requestName = requestName, statusName = 'closed-out') def changeStatusAndCheck(self, requestName, statusName): """ _changeStatusAndCheck_ Change the status of a request and make sure that the request actually did it. """ self.jsonSender.put('request/%s?status=%s' % (requestName, statusName)) result = self.jsonSender.get('request/%s' % requestName) self.assertEqual(result[0]['RequestStatus'], statusName) def loadWorkload(self, requestName): """ _loadWorkload_ Load the workload from couch after we've saved it there. """ workload = WMWorkloadHelper() url = '%s/%s/%s/spec' % (os.environ['COUCHURL'], self.couchDBName, requestName) workload.load(url) return workload def testF_TestWhitelistBlacklist(self): """ _TestWhitelistBlacklist_ Test whether or not we can assign the block/run blacklist/whitelist """ userName = '******' groupName = 'Li' teamName = 'Tang' schema = utils.getAndSetupSchema(self, userName = userName, groupName = groupName, teamName = teamName) schema['RunWhitelist'] = [1, 2, 3] schema['RunBlacklist'] = [4, 5, 6] schema['BlockWhitelist'] = ['/dataset/dataset/dataset#alpha'] schema['BlockBlacklist'] = ['/dataset/dataset/dataset#beta'] configID = self.createConfig() schema["ConfigCacheID"] = configID schema["CouchDBName"] = self.couchDBName schema["CouchURL"] = os.environ.get("COUCHURL") result = self.jsonSender.put('request/testRequest', schema) self.assertEqual(result[1], 200) requestName = result[0]['RequestName'] workload = self.loadWorkload(requestName = requestName) self.assertEqual(workload.data.tasks.DataProcessing.input.dataset.runs.whitelist, schema['RunWhitelist']) self.assertEqual(workload.data.tasks.DataProcessing.input.dataset.runs.blacklist, schema['RunBlacklist']) self.assertEqual(workload.data.tasks.DataProcessing.input.dataset.blocks.whitelist, schema['BlockWhitelist']) self.assertEqual(workload.data.tasks.DataProcessing.input.dataset.blocks.blacklist, schema['BlockBlacklist']) req = self.jsonSender.get('request/%s' % requestName) self.assertTrue('Site Blacklist' in req[0]) self.assertTrue('Site Whitelist' in req[0]) schema['BlockBlacklist'] = {'1': '/dataset/dataset/dataset#beta'} try: raises = False result = self.jsonSender.put('request/testRequest', schema) except HTTPException as ex: raises = True self.assertEqual(ex.status, 400) print ex.result self.assertTrue("Error in Workload Validation: Argument BlockBlacklist type is incorrect in schema." in ex.result) pass self.assertTrue(raises) schema['BlockBlacklist'] = ['/dataset/dataset/dataset#beta'] schema['RunWhitelist'] = {'1': '/dataset/dataset/dataset#beta'} try: raises = False result = self.jsonSender.put('request/testRequest', schema) except HTTPException as ex: raises = True self.assertEqual(ex.status, 400) self.assertTrue("Error in Workload Validation: Argument RunWhitelist type is incorrect in schema." in ex.result) pass self.assertTrue(raises) schema['RunWhitelist'] = ['hello', 'how', 'are', 'you'] try: raises = True result = self.jsonSender.put('request/testRequest', schema) except HTTPException as ex: raises = True self.assertEqual(ex.status, 400) self.assertTrue("Error in Workload Validation: Argument RunWhitelist doesn't pass validation." in ex.result) pass self.assertTrue(raises) def testG_AddDuplicateUser(self): """ _AddDuplicateUser_ Test and see if we get a sensible error when adding a duplicate user. """ userName = '******' groupName = 'Li' teamName = 'Tang' schema = utils.getAndSetupSchema(self, userName = userName, groupName = groupName, teamName = teamName) raises = False try: self.jsonSender.put('group/%s/%s' % (groupName, userName)) except HTTPException as ex: self.assertTrue("User/Group Already Linked in DB" in ex.result) self.assertEqual(ex.status, 400) raises = True self.assertTrue(raises) def testH_RemoveSoftwareVersion(self): """ _RemoveSoftwareVersion_ Remove the software version after submitting the request. See what that does. """ myThread = threading.currentThread() userName = '******' groupName = 'Li' teamName = 'Tang' schema = utils.getAndSetupSchema(self, userName = userName, groupName = groupName, teamName = teamName) configID = self.createConfig() schema["ConfigCacheID"] = configID schema["CouchDBName"] = self.couchDBName schema["CouchURL"] = os.environ.get("COUCHURL") result = self.jsonSender.put('request/testRequest', schema) self.assertEqual(result[1], 200) requestName = result[0]['RequestName'] req = self.jsonSender.get('request/%s' % requestName)[0] self.assertEqual(req['SoftwareVersions'], [schema["CMSSWVersion"]]) # Delete software versions and make sure they're gone from the DB SoftwareManagement.removeSoftware(softwareName = schema["CMSSWVersion"], scramArch = schema["ScramArch"]) versions = myThread.dbi.processData("SELECT * FROM reqmgr_software")[0].fetchall() self.assertEqual(versions, []) assocs = myThread.dbi.processData("SELECT * FROM reqmgr_software_dependency")[0].fetchall() self.assertEqual(assocs, []) req = self.jsonSender.get('request/%s' % requestName)[0] self.assertEqual(req['SoftwareVersions'], [schema["CMSSWVersion"]]) def testI_CheckConfigIDs(self): """ _CheckConfigIDs_ Check to see if we can pull out the ConfigIDs by request """ userName = '******' groupName = 'Li' teamName = 'Tang' schema = utils.getAndSetupSchema(self, userName = userName, groupName = groupName, teamName = teamName) # Set some versions schema['ProcessingVersion'] = '2012' schema['AcquisitionEra'] = 'ae2012' schema["PrimaryDataset"] = "ReallyFake" schema["RequestNumEvents"] = 100 configID = self.createConfig() schema["CouchDBName"] = self.couchDBName schema["CouchURL"] = os.environ.get("COUCHURL") schema["ConfigCacheID"] = configID schema["InputDataset"] = '/MinimumBias/Run2010B-RelValRawSkim-v1/RAW' result = self.jsonSender.put('request/testRequest', schema) self.assertEqual(result[1], 200) requestName = result[0]['RequestName'] result = self.jsonSender.get('configIDs?prim=MinimumBias&proc=Run2010B-RelValRawSkim-v1&tier=RAW')[0] print result self.assertTrue(requestName in result.keys()) self.assertTrue(configID in result[requestName][0]) def testJ_CheckRequestCloning(self): myThread = threading.currentThread() userName = '******' groupName = 'Li' teamName = 'Tang' schema = utils.getAndSetupSchema(self, userName = userName, groupName = groupName, teamName = teamName) configID = self.createConfig() schema["ConfigCacheID"] = configID schema["CouchDBName"] = self.couchDBName schema["CouchURL"] = os.environ.get("COUCHURL") schema["AcquisitionEra"] = "NewEra" result = self.jsonSender.put("request", schema) self.assertEqual(result[1], 200) requestName = result[0]["RequestName"] acquisitionEra = result[0]["AcquisitionEra"] self.assertTrue(schema["AcquisitionEra"], acquisitionEra) # set some non-default priority # when cloning a request which had some non default priority, # the priority values were lost when creating a cloned request, the # default values were lost. Change it here to specifically catch this case. priority = 300 result = self.jsonSender.put("request/%s?priority=%s" % (requestName, priority)) self.assertEqual(result[1], 200) # get the original request from the server, although the variable result # shall have the same stuff in response = self.jsonSender.get("request/%s" % requestName) origRequest = response[0] self.assertEquals(origRequest["AcquisitionEra"], acquisitionEra) # test that the priority was correctly set in the brand-new request self.assertEquals(origRequest["RequestPriority"], priority) # test cloning not existing request self.assertRaises(HTTPException, self.jsonSender.put, "clone/%s" % "NotExistingRequestName") # correct attempt to clone the request # this is the new request, it'll have different name result = self.jsonSender.put("clone/%s" % requestName) # get the cloned request from the server respose = self.jsonSender.get("request/%s" % result[0]["RequestName"]) clonedRequest = respose[0] # these request arguments shall differ in the cloned request: toDiffer = ["RequestName", "RequestStatus"] for differ in toDiffer: self.assertNotEqual(origRequest[differ], clonedRequest[differ]) # check the desired status of the cloned request self.assertEquals(clonedRequest["RequestStatus"], "assignment-approved", "Cloned request status should be 'assignment-approved', not '%s'." % clonedRequest["RequestStatus"]) # don't care about these two (they will likely be the same in the unittest # since the brand new request injection as well as the cloning probably # happen at roughly the same time) toDiffer.extend(["RequestDate", "timeStamp", "RequestWorkflow"]) for differ in toDiffer: del origRequest[differ] del clonedRequest[differ] # check the request dictionaries self.assertEquals(len(origRequest), len(clonedRequest)) for k1, k2 in zip(sorted(origRequest.keys()), sorted(clonedRequest.keys())): msg = ("Request values: original: %s: %s cloned: %s: %s differ" % (k1, origRequest[k1], k2, clonedRequest[k2])) self.assertEqual(origRequest[k1], clonedRequest[k2], msg) def testK_CheckRequestFailsInjectionForbiddenInputArg(self): myThread = threading.currentThread() userName = '******' groupName = 'Li' teamName = 'Tang' schema = utils.getAndSetupSchema(self, userName = userName, groupName = groupName, teamName = teamName) from WMCore.HTTPFrontEnd.RequestManager.ReqMgrRESTModel import deprecatedRequestArgs for deprec in deprecatedRequestArgs: schema = utils.getSchema(groupName=groupName, userName=userName) schema[deprec] = "something" self.assertRaises(HTTPException, self.jsonSender.put, "request", schema) def setupACDCDatabase(self, collectionName, taskPath, user, group): """ _setupACDCDatabase_ Populate an ACDC database with bogus records associated to certain collection name, user and task path. """ acdcServer = CouchService(url = self.testInit.couchUrl, database = "%s_acdc" % self.couchDBName) owner = acdcServer.newOwner(group, user) testCollection = CouchCollection(database = self.testInit.couchDbName, url = self.testInit.couchUrl, name = collectionName) testCollection.setOwner(owner) testFileset = CouchFileset(database = self.testInit.couchDbName, url = self.testInit.couchUrl, name = taskPath) testCollection.addFileset(testFileset) testFiles = [] for _ in range(5): testFile = File(lfn = makeUUID(), size = random.randint(1024, 4096), events = random.randint(1024, 4096)) testFiles.append(testFile) testFileset.add(testFiles) def testL_CascadeCloseOutAnnnouncement(self): """ _testL_CascadeCloseOutAnnouncement_ Test the cascade closeout REST call, also check that when announced a request deletes all ACDC records in the system. """ userName = '******' groupName = 'Li' teamName = 'Tang' schema = utils.getAndSetupSchema(self, userName = userName, groupName = groupName, teamName = teamName) configID = self.createConfig() schema["ConfigCacheID"] = configID schema["CouchDBName"] = self.couchDBName schema["CouchURL"] = os.environ.get("COUCHURL") result = self.jsonSender.put("request", schema)[0] originalRequest = result['RequestName'] self.setupACDCDatabase(originalRequest, "/%s/DataProcessing" % originalRequest, result['Requestor'], result['Group']) depth = 2 nReq = 3 requests = [originalRequest] def createChildrenRequest(parentRequest, i, nReq): createdRequests = [] resubSchema = utils.getResubmissionSchema(parentRequest, "/%s/DataProcessing" % parentRequest, groupName, userName) result = self.jsonSender.put("request", resubSchema)[0] requestName = result['RequestName'] self.setupACDCDatabase(requestName, "/%s/DataProcessing" % requestName, result['Requestor'], result['Group']) createdRequests.append(requestName) if i: for _ in range(nReq): createdRequests.extend(createChildrenRequest(requestName, i - 1, nReq)) return createdRequests requests.extend(createChildrenRequest(originalRequest, depth, nReq)) for request in requests: self.changeStatusAndCheck(request, 'assignment-approved') for request in requests: self.jsonSender.put("assignment?team=%s&requestName=%s" % (teamName, request)) for status in ['acquired', 'running-open', 'running-closed', 'completed']: for request in requests: self.changeStatusAndCheck(request, status) self.jsonSender.post('closeout?requestName=%s&cascade=True' % originalRequest) svc = CouchService(url = self.testInit.couchUrl, database = "%s_acdc" % self.couchDBName) owner = svc.newOwner(groupName, userName) for request in requests: result = self.jsonSender.get('request/%s' % request) self.assertEqual(result[0]['RequestStatus'], 'closed-out') testCollection = CouchCollection(database = self.testInit.couchDbName, url = self.testInit.couchUrl, name = request) testCollection.setOwner(owner) testCollection.populate() self.assertNotEqual(len(testCollection["filesets"]), 0) self.jsonSender.post('announce?requestName=%s&cascade=True' % originalRequest) for request in requests: result = self.jsonSender.get('request/%s' % request) self.assertEqual(result[0]['RequestStatus'], 'announced') testCollection = CouchCollection(database = self.testInit.couchDbName, url = self.testInit.couchUrl, name = request) testCollection.setOwner(owner) testCollection.populate() self.assertEqual(len(testCollection["filesets"]), 0) def testM_PutRequestStats(self): userName = '******' groupName = 'Bryant' teamName = 'Lakers' schema = utils.getAndSetupSchema(self, userName = userName, groupName = groupName, teamName = teamName) configID = self.createConfig() schema["ConfigCacheID"] = configID schema["CouchDBName"] = self.couchDBName schema["CouchURL"] = os.environ.get("COUCHURL") result = self.jsonSender.put("request", schema)[0] originalRequest = result['RequestName'] stats = {'total_jobs': 100, 'input_events': 100, 'input_lumis': 100, 'input_num_files': 100} result = self.reqService.putRequestStats(originalRequest, stats) self.assertEqual(result['RequestName'], originalRequest)
class ReqMgrTest(RESTBaseUnitTest): """ _ReqMgrTest_ Basic test for the ReqMgr services. Setup is done off-screen in RESTBaseUnitTest - this makes things confusing """ def setUp(self): """ setUP global values Database setUp is done in base class """ self.couchDBName = "reqmgr_t_0" RESTBaseUnitTest.setUp(self) self.testInit.setupCouch("%s" % self.couchDBName, "GroupUser", "ConfigCache") self.testInit.setupCouch("%s_wmstats" % self.couchDBName, "WMStats") reqMgrHost = self.config.getServerUrl() self.jsonSender = JSONRequests(reqMgrHost) def initialize(self): self.config = RequestManagerConfig( 'WMCore.HTTPFrontEnd.RequestManager.ReqMgrRESTModel') self.config.setFormatter('WMCore.WebTools.RESTFormatter') self.config.setupRequestConfig() self.config.setupCouchDatabase(dbName=self.couchDBName) self.config.setPort(12888) self.schemaModules = ["WMCore.RequestManager.RequestDB"] def tearDown(self): """ tearDown Tear down everything """ RESTBaseUnitTest.tearDown(self) self.testInit.tearDownCouch() def createConfig(self, bad=False): """ _createConfig_ Create a config of some sort that we can load out of ConfigCache """ PSetTweak = { 'process': { 'outputModules_': ['ThisIsAName'], 'ThisIsAName': { 'dataset': { 'dataTier': 'RECO', 'filterName': 'Filter' } } } } BadTweak = { 'process': { 'outputModules_': ['ThisIsAName1', 'ThisIsAName2'], 'ThisIsAName1': { 'dataset': { 'dataTier': 'RECO', 'filterName': 'Filter' } }, 'ThisIsAName2': { 'dataset': { 'dataTier': 'RECO', 'filterName': 'Filter' } } } } configCache = ConfigCache(os.environ["COUCHURL"], couchDBName=self.couchDBName) configCache.createUserGroup(groupname="testGroup", username='******') if bad: configCache.setPSetTweaks(PSetTweak=BadTweak) else: configCache.setPSetTweaks(PSetTweak=PSetTweak) configCache.save() return configCache.getCouchID() @attr("integration") def testA_testBasicSetUp(self): """ _testBasicSetUp_ Moving the tests that were in the setUp category out of it, mostly because I want to make sure that they don't fail inside the setUp statement. """ if 'me' in self.jsonSender.get('user')[0]: self.jsonSender.delete('user/me') self.assertFalse('me' in self.jsonSender.get('user')[0]) self.assertEqual( self.jsonSender.put('user/[email protected]')[1], 200) self.assertTrue('me' in self.jsonSender.get('user')[0]) if 'PeopleLikeMe' in self.jsonSender.get('group')[0]: self.jsonSender.delete('group/PeopleLikeMe') self.assertFalse('PeopleLikeMe' in self.jsonSender.get('group')[0]) self.assertEqual(self.jsonSender.put('group/PeopleLikeMe')[1], 200) self.assertTrue('PeopleLikeMe' in self.jsonSender.get('group')[0]) self.jsonSender.put('group/PeopleLikeMe/me') users = self.jsonSender.get('group/PeopleLikeMe')[0]['users'] self.assertTrue('me' in users) groups = self.jsonSender.get('user/me')[0]['groups'] self.assertTrue('PeopleLikeMe' in groups) groups2 = self.jsonSender.get('group?user=me')[0] self.assertTrue('PeopleLikeMe' in groups2) if 'White Sox' in self.jsonSender.get('team')[0]: self.jsonSender.delete(urllib.quote('team/White Sox')) self.assertFalse('White Sox' in self.jsonSender.get('team')[0]) self.assertEqual( self.jsonSender.put(urllib.quote('team/White Sox'))[1], 200) self.assertTrue('White Sox' in self.jsonSender.get('team')[0]) # some foreign key stuff to dealwith schema = utils.getSchema() version = "version/" + schema["CMSSWVersion"] self.assertTrue(self.jsonSender.put(version)[1] == 200) self.assertTrue( schema["CMSSWVersion"] in self.jsonSender.get('version')[0]) @attr("integration") def testB_ReReco(self): """ _ReReco_ Try a basic ReReco workflow """ schema = utils.getAndSetupSchema(self) schema['RequestNumEvents'] = 100 schema['RequestEventSize'] = 101 self.doRequest(schema) def doRequest(self, schema): """ _doRequest_ Run all tests on a basic ReReco workflow """ requestName = schema['RequestName'] self.assertRaises(HTTPException, self.jsonSender.delete, 'request/%s' % requestName) result = self.jsonSender.put('request/%s' % (requestName), schema) self.assertEqual(result[1], 200) requestName = result[0]['RequestName'] self.assertEqual( self.jsonSender.get('request/%s' % requestName)[0]['RequestName'], requestName) self.jsonSender.put('request/%s?status=assignment-approved' % requestName) me = self.jsonSender.get('user/me')[0] self.assertTrue(requestName in me['requests']) self.assertEqual( self.jsonSender.put('request/%s?priority=5' % requestName)[1], 200) self.assertEqual(self.jsonSender.post('user/me?priority=6')[1], 200) self.assertEqual( self.jsonSender.post('group/PeopleLikeMe?priority=7')[1], 200) # default priority of group and user of 1 request = self.jsonSender.get('request/%s' % requestName)[0] self.assertEqual(request['ReqMgrRequestBasePriority'], 5) self.assertEqual(request['ReqMgrRequestorBasePriority'], 6) self.assertEqual(request['ReqMgrGroupBasePriority'], 7) self.assertEqual(request['RequestPriority'], 5 + 6 + 7) # Check LFN Bases self.assertEqual(request['UnmergedLFNBase'], '/store/unmerged') self.assertEqual(request['MergedLFNBase'], '/store/data') # Check random other self.assertEqual(request['CustodialSite'], 'US_T1_FNAL') # Check Num events self.assertEqual(request['RequestNumEvents'], 100) self.assertEqual(request['RequestEventSize'], 101) # only certain transitions allowed #self.assertEqual(self.jsonSender.put('request/%s?status=running' % requestName)[1], 400) self.assertRaises(HTTPException, self.jsonSender.put, 'request/%s?status=running' % requestName) request = self.jsonSender.get('request/%s' % requestName)[0] self.assertEqual(request['RequestStatus'], 'assignment-approved') self.assertTrue( self.jsonSender.put( urllib.quote('assignment/White Sox/%s' % requestName))[1] == 200) requestsAndSpecs = self.jsonSender.get( urllib.quote('assignment/White Sox'))[0] self.assertTrue(requestName in requestsAndSpecs[0]) workloadHelper = WMWorkloadHelper() workloadHelper.load(requestsAndSpecs[0][1]) self.assertEqual(workloadHelper.getOwner()['Requestor'], "me") self.assertEqual( self.jsonSender.get('assignment?request=%s' % requestName)[0], ['White Sox']) self.assertEqual( self.jsonSender.get('request/%s' % requestName)[0]['teams'], ['White Sox']) agentUrl = 'http://cmssrv96.fnal.gov/workqueue' self.jsonSender.put('workQueue/%s?url=%s' % (requestName, urllib.quote(agentUrl))) self.assertEqual( self.jsonSender.get('workQueue/%s' % requestName)[0][0], agentUrl) request = self.jsonSender.get('request/%s' % requestName)[0] self.assertEqual(request['RequestStatus'], 'acquired') self.jsonSender.post('request/%s?events_written=10&files_merged=1' % requestName) self.jsonSender.post( 'request/%s?events_written=20&files_merged=2&percent_success=99.9' % requestName) request = self.jsonSender.get('request/%s' % requestName)[0] self.assertEqual(len(request['RequestUpdates']), 2) self.assertEqual(request['RequestUpdates'][0]['files_merged'], 1) self.assertEqual(request['RequestUpdates'][1]['events_written'], 20) self.assertEqual(request['RequestUpdates'][1]['percent_success'], 99.9) message = "The sheriff is near" jsonMessage = json.dumps(message) self.jsonSender.put('message/%s' % requestName, message) messages = self.jsonSender.get('message/%s' % requestName) #self.assertEqual(messages[0][0][0], message) for status in ['running', 'completed']: self.jsonSender.put('request/%s?status=%s' % (requestName, status)) # campaign self.jsonSender.put('campaign/%s' % 'TestCampaign') campaigns = self.jsonSender.get('campaign')[0] self.assertTrue('TestCampaign' in campaigns.keys()) self.jsonSender.put('campaign/%s/%s' % ('TestCampaign', requestName)) requestsInCampaign = self.jsonSender.get('campaign/%s' % 'TestCampaign')[0] self.assertTrue(requestName in requestsInCampaign.keys()) req = self.jsonSender.get('request/%s' % requestName)[0] self.assertEqual(req['Campaign'], 'TestCampaign') self.jsonSender.delete('request/%s' % requestName) @attr("integration") def testC_404Errors(self): """ _404Errors_ Do some things that generate 404 errors. This should be limited to requests for objects that do not exist. """ badName = 'ThereIsNoWayThisNameShouldExist' # First, try to find a non-existant request # This should throw a 404 error. # The request name should not be in it self.checkForError(cls='request', badName=badName, exitCode=404, message='Given requestName not found') # Now look for non-existant user self.checkForError(cls='user', badName=badName, exitCode=404, message='Cannot find user') # Now try non-existant group self.checkForError(cls='group', badName=badName, exitCode=404, message="Cannot find group/group priority") # Now try non-existant campaign self.checkForError(cls='campaign', badName=badName, exitCode=404, message="Cannot find campaign") # Now try invalid message # This raises a requestName error becuase it searches for the request self.checkForError(cls='message', badName=badName, exitCode=404, message="Given requestName not found", testEmpty=False) # Check for assignments (no teams or requests) # This raises a team error because it tries to load teams out first self.checkForError(cls='assignment', badName=badName, exitCode=404, message='Cannot find team') @attr("integration") def testD_400Errors(self): """ _400Errors_ These are failures created by invalid input, such as sending args to a request when it doesn't accept any. They should generatore 400 Errors """ badName = 'ThereIsNoWayThisNameShouldExist' # Attempt to send arguments to a function that doesn't accept them. self.checkForError( cls='team', badName=badName, exitCode=400, message="Invalid input: Arguments added where none allowed") # Recheck for versions self.checkForError( cls='version', badName=badName, exitCode=400, message="Invalid input: Arguments added where none allowed") # Break the validation self.checkForError( cls='user', badName='!', exitCode=400, message='Invalid input: Input data failed validation') def checkForError(self, cls, badName, exitCode, message, testEmpty=True): """ _checkForError_ Generic function for checking for errors in JSON commands Does a basic check on type cls searching for name badName which hopefull does not exist. Checks to make sure that it exits with code exitCode, and that the error contains the string message. Also checks to make sure that name badName is NOT in the output testEmpty for those that don't handle calls to the main (i.e., who require an argument) """ raises = False # First assert that the test to be tested is empty if testEmpty: result = self.jsonSender.get(cls) self.assertTrue(type(result[0]) in [type([]), type({})]) # Next, test try: result = self.jsonSender.get('%s/%s' % (cls, badName)) except HTTPException, ex: raises = True self.assertEqual(ex.status, exitCode) self.assertTrue(message in ex.result) self.assertFalse(badName in ex.result) self.assertTrue(raises)
class RequestManagerTest(RESTBaseUnitTest): """ Test RequestMgr Service client It will start RequestMgr RESTService Server DB is whatever env is set This checks whether DS call makes without error and return the results. This test only test service call returns without error. The correctness of each function is tested in test/python/RequestManager_t/RequestMgr_t.py """ def initialize(self): self.couchDBName = "reqmgr_t_0" self.config = RequestManagerConfig( 'WMCore.HTTPFrontEnd.RequestManager.ReqMgrRESTModel') dbUrl = os.environ.get("DATABASE", None) self.config.setDBUrl(dbUrl) self.config.setFormatter('WMCore.WebTools.RESTFormatter') self.config.setupRequestConfig() self.config.setupCouchDatabase(dbName=self.couchDBName) self.config.setPort(8899) self.schemaModules = ["WMCore.RequestManager.RequestDB"] def setUp(self): RESTBaseUnitTest.setUp(self) self.testInit.setupCouch("%s" % self.couchDBName, "GroupUser", "ConfigCache", "ReqMgr") self.testInit.setupCouch("%s_wmstats" % self.couchDBName, "WMStats") # logging stuff from TestInit is broken, setting myself l = logging.getLogger() l.setLevel(logging.DEBUG) self.params = {} self.params['endpoint'] = self.config.getServerUrl() self.reqService = RequestManagerDS(self.params) self.jsonSender = JSONRequests(self.config.getServerUrl()) userName = '******' groupName = 'Li' teamName = 'Tang' schema = utils.getAndSetupSchema(self, userName=userName, groupName=groupName, teamName=teamName) schema['ConfigCacheID'] = self.createConfig() schema['CouchDBName'] = self.couchDBName schema['CouchWorkloadDBName'] = self.couchDBName try: r = self.jsonSender.put('request', schema) try: self.requestName = r[0]['RequestName'] except: self.requestName = r[0].values()[0]['RequestName'] except Exception as ex: msg = traceback.format_exc() print "Exception during set up, reason: %s" % msg raise ex def tearDown(self): self.config.deleteWorkloadCache() RESTBaseUnitTest.tearDown(self) self.testInit.tearDownCouch() def createConfig(self, bad=False): """ _createConfig_ Create a config of some sort that we can load out of ConfigCache """ PSetTweak = { 'process': { 'outputModules_': ['ThisIsAName'], 'ThisIsAName': { 'dataset': { 'dataTier': 'RECO', 'filterName': 'Filter' } } } } BadTweak = { 'process': { 'outputModules_': ['ThisIsAName1', 'ThisIsAName2'], 'ThisIsAName1': { 'dataset': { 'dataTier': 'RECO', 'filterName': 'Filter' } }, 'ThisIsAName2': { 'dataset': { 'dataTier': 'RECO', 'filterName': 'Filter' } } } } configCache = ConfigCache(os.environ["COUCHURL"], couchDBName=self.couchDBName) configCache.createUserGroup(groupname="testGroup", username='******') if bad: configCache.setPSetTweaks(PSetTweak=BadTweak) else: configCache.setPSetTweaks(PSetTweak=PSetTweak) configCache.save() return configCache.getCouchID() @attr("integration") def testA_RequestManagerService(self): requestName = self.requestName request = self.reqService.getRequest(requestName) # minimal test : it's return type and the some value inside self.assertEqual(type(request), dict) self.assertTrue(len(request) > 0) # Test putTeam self.reqService.putTeam("team_usa") self.assertTrue('team_usa' in self.jsonSender.get('team')[0]) self.jsonSender.put('assignment/%s/%s' % ("team_usa", requestName)) request = self.reqService.getAssignment(teamName="team_usa") self.assertEqual(type(request), list) self.assertTrue(len(request) > 0) request = self.reqService.getAssignment(request=requestName) self.assertEqual(type(request), list) self.assertTrue(len(request) > 0) self.reqService.sendMessage(requestName, "error") self.reqService.putWorkQueue(requestName, "http://test_url") self.reqService.reportRequestProgress(requestName, percent_complete=100, percent_success=90) self.reqService.updateRequestStatus(requestName, "running-open")
class RequestManagerTest(RESTBaseUnitTest): """ Test RequestMgr Service client It will start RequestMgr RESTService Server DB is whatever env is set This checks whether DS call makes without error and return the results. This test only test service call returns without error. The correctness of each function is tested in test/python/RequestManager_t/RequestMgr_t.py """ def initialize(self): self.couchDBName = "reqmgr_t_0" self.config = RequestManagerConfig( 'WMCore.HTTPFrontEnd.RequestManager.ReqMgrRESTModel') dbUrl = os.environ.get("DATABASE", None) self.config.setDBUrl(dbUrl) self.config.setFormatter('WMCore.WebTools.RESTFormatter') self.config.setupRequestConfig() self.config.setupCouchDatabase(dbName = self.couchDBName) self.config.setPort(8899) self.schemaModules = ["WMCore.RequestManager.RequestDB"] def setUp(self): RESTBaseUnitTest.setUp(self) self.testInit.setupCouch("%s" % self.couchDBName, "GroupUser", "ConfigCache", "ReqMgr") self.testInit.setupCouch("%s_wmstats" % self.couchDBName, "WMStats") # logging stuff from TestInit is broken, setting myself l = logging.getLogger() l.setLevel(logging.DEBUG) self.params = {} self.params['endpoint'] = self.config.getServerUrl() self.reqService = RequestManagerDS(self.params) self.jsonSender = JSONRequests(self.config.getServerUrl()) userName = '******' groupName = 'Li' teamName = 'Tang' schema = utils.getAndSetupSchema(self, userName = userName, groupName = groupName, teamName = teamName) schema['ConfigCacheID'] = self.createConfig() schema['CouchDBName'] = self.couchDBName schema['CouchWorkloadDBName'] = self.couchDBName try: r = self.jsonSender.put('request', schema) try: self.requestName = r[0]['RequestName'] except: self.requestName = r[0].values()[0]['RequestName'] except Exception as ex: msg = traceback.format_exc() print("Exception during set up, reason: %s" % msg) raise ex def tearDown(self): self.config.deleteWorkloadCache() RESTBaseUnitTest.tearDown(self) self.testInit.tearDownCouch() def createConfig(self, bad = False): """ _createConfig_ Create a config of some sort that we can load out of ConfigCache """ PSetTweak = {'process': {'outputModules_': ['ThisIsAName'], 'ThisIsAName': {'dataset': {'dataTier': 'RECO', 'filterName': 'Filter'}}}} BadTweak = {'process': {'outputModules_': ['ThisIsAName1', 'ThisIsAName2'], 'ThisIsAName1': {'dataset': {'dataTier': 'RECO', 'filterName': 'Filter'}}, 'ThisIsAName2': {'dataset': {'dataTier': 'RECO', 'filterName': 'Filter'}}}} configCache = ConfigCache(os.environ["COUCHURL"], couchDBName = self.couchDBName) configCache.createUserGroup(groupname = "testGroup", username = '******') if bad: configCache.setPSetTweaks(PSetTweak = BadTweak) else: configCache.setPSetTweaks(PSetTweak = PSetTweak) configCache.save() return configCache.getCouchID() @attr("integration") def testA_RequestManagerService(self): requestName = self.requestName request = self.reqService.getRequest(requestName) # minimal test : it's return type and the some value inside self.assertEqual(type(request), dict) self.assertTrue(len(request) > 0) # Test putTeam self.reqService.putTeam("team_usa") self.assertTrue('team_usa' in self.jsonSender.get('team')[0]) self.jsonSender.put('assignment/%s/%s' % ("team_usa", requestName)) request = self.reqService.getAssignment(teamName = "team_usa") self.assertEqual(type(request), list) self.assertTrue(len(request) > 0) request = self.reqService.getAssignment(request = requestName) self.assertEqual(type(request), list) self.assertTrue(len(request) > 0) self.reqService.sendMessage(requestName,"error") self.reqService.putWorkQueue(requestName, "http://test_url") self.reqService.reportRequestProgress(requestName, percent_complete = 100, percent_success = 90) self.reqService.updateRequestStatus(requestName, "running-open")
class ReqMgrWorkloadTest(RESTBaseUnitTest): """ Test that sets up and checks the validations of the various main WMSpec.StdSpecs This is mostly a simple set of tests which can be very repetitive. """ def setUp(self): """ setUP global values Database setUp is done in base class """ self.couchDBName = "reqmgr_t_0" RESTBaseUnitTest.setUp(self) self.testInit.setupCouch("%s" % self.couchDBName, "ConfigCache", "ReqMgr") self.testInit.setupCouch("%s_wmstats" % self.couchDBName, "WMStats") reqMgrHost = self.config.getServerUrl() self.jsonSender = JSONRequests(reqMgrHost) def initialize(self): self.config = RequestManagerConfig( 'WMCore.HTTPFrontEnd.RequestManager.ReqMgrRESTModel') self.config.setFormatter('WMCore.WebTools.RESTFormatter') self.config.setupRequestConfig() self.config.setupCouchDatabase(dbName = self.couchDBName) self.config.setPort(12888) self.schemaModules = ["WMCore.RequestManager.RequestDB"] def tearDown(self): """ _tearDown_ Basic tear down of database """ RESTBaseUnitTest.tearDown(self) self.testInit.tearDownCouch() def createConfig(self, bad = False): """ _createConfig_ Create a config of some sort that we can load out of ConfigCache """ PSetTweak = {'process': {'outputModules_': ['ThisIsAName'], 'ThisIsAName': {'dataset': {'dataTier': 'RECO', 'filterName': 'Filter'}}}} BadTweak = {'process': {'outputModules_': ['ThisIsAName1', 'ThisIsAName2'], 'ThisIsAName1': {'dataset': {'dataTier': 'RECO', 'filterName': 'Filter'}}, 'ThisIsAName2': {'dataset': {'dataTier': 'RECO', 'filterName': 'Filter'}}}} configCache = ConfigCache(os.environ["COUCHURL"], couchDBName = self.couchDBName) configCache.createUserGroup(groupname = "testGroup", username = '******') if bad: configCache.setPSetTweaks(PSetTweak = BadTweak) else: configCache.setPSetTweaks(PSetTweak = PSetTweak) configCache.save() return configCache.getCouchID() def loadWorkload(self, requestName): """ _loadWorkload_ Load the workload from couch after we've saved it there. """ workload = WMWorkloadHelper() url = '%s/%s/%s/spec' % (os.environ['COUCHURL'], self.couchDBName, requestName) workload.load(url) return workload @attr('integration') def testA_makeReRecoWorkload(self): """ _makeReRecoWorkload_ Check that you can make a basic ReReco workload """ userName = '******' groupName = 'Li' teamName = 'Tang' schema = utils.getAndSetupSchema(self, userName = userName, groupName = groupName, teamName = teamName) del schema['GlobalTag'] raises = False try: self.jsonSender.put('request/testRequest', schema) except HTTPException, ex: raises = True self.assertEqual(ex.status, 400) self.assertTrue("Error in Workload Validation: Missing required " "field 'GlobalTag' in workload validation!" in ex.result) self.assertTrue(raises) schema = utils.getSchema(groupName = groupName, userName = userName) schema['InputDataset'] = '/Nothing' raises = False try: self.jsonSender.put('request/testRequest', schema) except HTTPException, ex: raises = True self.assertEqual(ex.status, 400) print ex.result
class ReqMgrTest(RESTBaseUnitTest): """ _ReqMgrTest_ Basic test for the ReqMgr services. Setup is done off-screen in RESTBaseUnitTest - this makes things confusing """ def setUp(self): """ setUP global values Database setUp is done in base class """ self.couchDBName = "reqmgr_t_0" RESTBaseUnitTest.setUp(self) self.testInit.setupCouch("%s" % self.couchDBName, "GroupUser", "ConfigCache") self.testInit.setupCouch("%s_wmstats" % self.couchDBName, "WMStats") reqMgrHost = self.config.getServerUrl() self.jsonSender = JSONRequests(reqMgrHost) return def initialize(self): self.config = RequestManagerConfig("WMCore.HTTPFrontEnd.RequestManager.ReqMgrRESTModel") self.config.setFormatter("WMCore.WebTools.RESTFormatter") self.config.setupRequestConfig() self.config.setupCouchDatabase(dbName=self.couchDBName) self.config.setPort(12888) self.schemaModules = ["WMCore.RequestManager.RequestDB"] return def tearDown(self): """ tearDown Tear down everything """ RESTBaseUnitTest.tearDown(self) self.testInit.tearDownCouch() return def setupSchema( self, groupName="PeopleLikeMe", userName="******", teamName="White Sox", CMSSWVersion="CMSSW_3_5_8", scramArch="slc5_ia32_gcc434", ): """ _setupSchema_ Set up a test schema so that we can run a test request. Standardization! """ self.jsonSender.put("user/%[email protected]" % userName) self.jsonSender.put("group/%s" % groupName) self.jsonSender.put("group/%s/%s" % (groupName, userName)) self.jsonSender.put(urllib.quote("team/%s" % teamName)) self.jsonSender.put("version/%s/%s" % (CMSSWVersion, scramArch)) schema = ReReco.getTestArguments() schema["RequestName"] = "TestReReco" schema["RequestType"] = "ReReco" schema["CmsPath"] = "/uscmst1/prod/sw/cms" schema["Requestor"] = "%s" % userName schema["Group"] = "%s" % groupName schema["CustodialSite"] = "US_T1_FNAL" schema["TimePerEvent"] = "12" schema["Memory"] = 3000 schema["SizePerEvent"] = 512 return schema def createConfig(self, bad=False): """ _createConfig_ Create a config of some sort that we can load out of ConfigCache """ PSetTweak = { "process": { "outputModules_": ["ThisIsAName"], "ThisIsAName": {"dataset": {"dataTier": "RECO", "filterName": "Filter"}}, } } BadTweak = { "process": { "outputModules_": ["ThisIsAName1", "ThisIsAName2"], "ThisIsAName1": {"dataset": {"dataTier": "RECO", "filterName": "Filter"}}, "ThisIsAName2": {"dataset": {"dataTier": "RECO", "filterName": "Filter"}}, } } configCache = ConfigCache(os.environ["COUCHURL"], couchDBName=self.couchDBName) configCache.createUserGroup(groupname="testGroup", username="******") if bad: configCache.setPSetTweaks(PSetTweak=BadTweak) else: configCache.setPSetTweaks(PSetTweak=PSetTweak) configCache.save() return configCache.getCouchID() @attr("integration") def testA_testBasicSetUp(self): """ _testBasicSetUp_ Moving the tests that were in the setUp category out of it, mostly because I want to make sure that they don't fail inside the setUp statement. """ if "me" in self.jsonSender.get("user")[0]: self.jsonSender.delete("user/me") self.assertFalse("me" in self.jsonSender.get("user")[0]) self.assertEqual(self.jsonSender.put("user/[email protected]")[1], 200) self.assertTrue("me" in self.jsonSender.get("user")[0]) if "PeopleLikeMe" in self.jsonSender.get("group")[0]: self.jsonSender.delete("group/PeopleLikeMe") self.assertFalse("PeopleLikeMe" in self.jsonSender.get("group")[0]) self.assertEqual(self.jsonSender.put("group/PeopleLikeMe")[1], 200) self.assertTrue("PeopleLikeMe" in self.jsonSender.get("group")[0]) self.jsonSender.put("group/PeopleLikeMe/me") users = self.jsonSender.get("group/PeopleLikeMe")[0]["users"] self.assertTrue("me" in users) groups = self.jsonSender.get("user/me")[0]["groups"] self.assertTrue("PeopleLikeMe" in groups) groups2 = self.jsonSender.get("group?user=me")[0] self.assertTrue("PeopleLikeMe" in groups2) if "White Sox" in self.jsonSender.get("team")[0]: self.jsonSender.delete(urllib.quote("team/White Sox")) self.assertFalse("White Sox" in self.jsonSender.get("team")[0]) self.assertEqual(self.jsonSender.put(urllib.quote("team/White Sox"))[1], 200) self.assertTrue("White Sox" in self.jsonSender.get("team")[0]) # some foreign key stuff to dealwith self.assertTrue(self.jsonSender.put("version/CMSSW_3_5_8")[1] == 200) self.assertTrue("CMSSW_3_5_8" in self.jsonSender.get("version")[0]) return @attr("integration") def testB_ReReco(self): """ _ReReco_ Try a basic ReReco workflow """ schema = self.setupSchema() schema["RequestNumEvents"] = 100 schema["RequestEventSize"] = 101 self.doRequest(schema) return def doRequest(self, schema): """ _doRequest_ Run all tests on a basic ReReco workflow """ requestName = schema["RequestName"] self.assertRaises(HTTPException, self.jsonSender.delete, "request/%s" % requestName) result = self.jsonSender.put("request/%s" % (requestName), schema) self.assertEqual(result[1], 200) requestName = result[0]["RequestName"] self.assertEqual(self.jsonSender.get("request/%s" % requestName)[0]["RequestName"], requestName) self.jsonSender.put("request/%s?status=assignment-approved" % requestName) me = self.jsonSender.get("user/me")[0] self.assertTrue(requestName in me["requests"]) self.assertEqual(self.jsonSender.put("request/%s?priority=5" % requestName)[1], 200) self.assertEqual(self.jsonSender.post("user/me?priority=6")[1], 200) self.assertEqual(self.jsonSender.post("group/PeopleLikeMe?priority=7")[1], 200) # default priority of group and user of 1 request = self.jsonSender.get("request/%s" % requestName)[0] self.assertEqual(request["ReqMgrRequestBasePriority"], 5) self.assertEqual(request["ReqMgrRequestorBasePriority"], 6) self.assertEqual(request["ReqMgrGroupBasePriority"], 7) self.assertEqual(request["RequestPriority"], 5 + 6 + 7) # Check LFN Bases self.assertEqual(request["UnmergedLFNBase"], "/store/unmerged") self.assertEqual(request["MergedLFNBase"], "/store/data") # Check random other self.assertEqual(request["CustodialSite"], "US_T1_FNAL") # Check Num events self.assertEqual(request["RequestNumEvents"], 100) self.assertEqual(request["RequestEventSize"], 101) # only certain transitions allowed # self.assertEqual(self.jsonSender.put('request/%s?status=running' % requestName)[1], 400) self.assertRaises(HTTPException, self.jsonSender.put, "request/%s?status=running" % requestName) request = self.jsonSender.get("request/%s" % requestName)[0] self.assertEqual(request["RequestStatus"], "assignment-approved") self.assertTrue(self.jsonSender.put(urllib.quote("assignment/White Sox/%s" % requestName))[1] == 200) requestsAndSpecs = self.jsonSender.get(urllib.quote("assignment/White Sox"))[0] self.assertTrue(requestName in requestsAndSpecs[0]) workloadHelper = WMWorkloadHelper() workloadHelper.load(requestsAndSpecs[0][1]) self.assertEqual(workloadHelper.getOwner()["Requestor"], "me") self.assertEqual(self.jsonSender.get("assignment?request=%s" % requestName)[0], ["White Sox"]) self.assertEqual(self.jsonSender.get("request/%s" % requestName)[0]["teams"], ["White Sox"]) agentUrl = "http://cmssrv96.fnal.gov/workqueue" self.jsonSender.put("workQueue/%s?url=%s" % (requestName, urllib.quote(agentUrl))) self.assertEqual(self.jsonSender.get("workQueue/%s" % requestName)[0][0], agentUrl) request = self.jsonSender.get("request/%s" % requestName)[0] self.assertEqual(request["RequestStatus"], "acquired") self.jsonSender.post("request/%s?events_written=10&files_merged=1" % requestName) self.jsonSender.post("request/%s?events_written=20&files_merged=2&percent_success=99.9" % requestName) request = self.jsonSender.get("request/%s" % requestName)[0] self.assertEqual(len(request["RequestUpdates"]), 2) self.assertEqual(request["RequestUpdates"][0]["files_merged"], 1) self.assertEqual(request["RequestUpdates"][1]["events_written"], 20) self.assertEqual(request["RequestUpdates"][1]["percent_success"], 99.9) message = "The sheriff is near" jsonMessage = json.dumps(message) self.jsonSender.put("message/%s" % requestName, message) messages = self.jsonSender.get("message/%s" % requestName) # self.assertEqual(messages[0][0][0], message) for status in ["running", "completed"]: self.jsonSender.put("request/%s?status=%s" % (requestName, status)) # campaign self.jsonSender.put("campaign/%s" % "TestCampaign") campaigns = self.jsonSender.get("campaign")[0] self.assertTrue("TestCampaign" in campaigns.keys()) self.jsonSender.put("campaign/%s/%s" % ("TestCampaign", requestName)) requestsInCampaign = self.jsonSender.get("campaign/%s" % "TestCampaign")[0] self.assertTrue(requestName in requestsInCampaign.keys()) req = self.jsonSender.get("request/%s" % requestName)[0] self.assertEqual(req["Campaign"], "TestCampaign") self.jsonSender.delete("request/%s" % requestName) return @attr("integration") def testC_404Errors(self): """ _404Errors_ Do some things that generate 404 errors. This should be limited to requests for objects that do not exist. """ badName = "ThereIsNoWayThisNameShouldExist" # First, try to find a non-existant request # This should throw a 404 error. # The request name should not be in it self.checkForError(cls="request", badName=badName, exitCode=404, message="Given requestName not found") # Now look for non-existant user self.checkForError(cls="user", badName=badName, exitCode=404, message="Cannot find user") # Now try non-existant group self.checkForError(cls="group", badName=badName, exitCode=404, message="Cannot find group/group priority") # Now try non-existant campaign self.checkForError(cls="campaign", badName=badName, exitCode=404, message="Cannot find campaign") # Now try invalid message # This raises a requestName error becuase it searches for the request self.checkForError( cls="message", badName=badName, exitCode=404, message="Given requestName not found", testEmpty=False ) # Check for assignments (no teams or requests) # This raises a team error because it tries to load teams out first self.checkForError(cls="assignment", badName=badName, exitCode=404, message="Cannot find team") return @attr("integration") def testD_400Errors(self): """ _400Errors_ These are failures created by invalid input, such as sending args to a request when it doesn't accept any. They should generatore 400 Errors """ badName = "ThereIsNoWayThisNameShouldExist" # Attempt to send arguments to a function that doesn't accept them. self.checkForError( cls="team", badName=badName, exitCode=400, message="Invalid input: Arguments added where none allowed" ) # Recheck for versions self.checkForError( cls="version", badName=badName, exitCode=400, message="Invalid input: Arguments added where none allowed" ) # Break the validation self.checkForError(cls="user", badName="!", exitCode=400, message="Invalid input: Input data failed validation") return def checkForError(self, cls, badName, exitCode, message, testEmpty=True): """ _checkForError_ Generic function for checking for errors in JSON commands Does a basic check on type cls searching for name badName which hopefull does not exist. Checks to make sure that it exits with code exitCode, and that the error contains the string message. Also checks to make sure that name badName is NOT in the output testEmpty for those that don't handle calls to the main (i.e., who require an argument) """ raises = False # First assert that the test to be tested is empty if testEmpty: result = self.jsonSender.get(cls) self.assertTrue(type(result[0]) in [type([]), type({})]) # Next, test try: result = self.jsonSender.get("%s/%s" % (cls, badName)) except HTTPException, ex: raises = True self.assertEqual(ex.status, exitCode) self.assertTrue(message in ex.result) self.assertFalse(badName in ex.result) self.assertTrue(raises) return
class ReqMgrWorkloadTest(RESTBaseUnitTest): """ Test that sets up and checks the validations of the various main WMSpec.StdSpecs This is mostly a simple set of tests which can be very repetitive. """ def setUp(self): """ setUP global values Database setUp is done in base class """ self.couchDBName = "reqmgr_t_0" RESTBaseUnitTest.setUp(self) self.testInit.setupCouch("%s" % self.couchDBName, "ConfigCache", "ReqMgr") self.testInit.setupCouch("%s_wmstats" % self.couchDBName, "WMStats") reqMgrHost = self.config.getServerUrl() self.jsonSender = JSONRequests(reqMgrHost) def initialize(self): self.config = RequestManagerConfig( 'WMCore.HTTPFrontEnd.RequestManager.ReqMgrRESTModel') self.config.setFormatter('WMCore.WebTools.RESTFormatter') self.config.setupRequestConfig() self.config.setupCouchDatabase(dbName=self.couchDBName) self.config.setPort(12888) self.schemaModules = ["WMCore.RequestManager.RequestDB"] def tearDown(self): """ _tearDown_ Basic tear down of database """ RESTBaseUnitTest.tearDown(self) self.testInit.tearDownCouch() def createConfig(self, bad=False): """ _createConfig_ Create a config of some sort that we can load out of ConfigCache """ PSetTweak = { 'process': { 'outputModules_': ['ThisIsAName'], 'ThisIsAName': { 'dataset': { 'dataTier': 'RECO', 'filterName': 'Filter' } } } } BadTweak = { 'process': { 'outputModules_': ['ThisIsAName1', 'ThisIsAName2'], 'ThisIsAName1': { 'dataset': { 'dataTier': 'RECO', 'filterName': 'Filter' } }, 'ThisIsAName2': { 'dataset': { 'dataTier': 'RECO', 'filterName': 'Filter' } } } } configCache = ConfigCache(os.environ["COUCHURL"], couchDBName=self.couchDBName) configCache.createUserGroup(groupname="testGroup", username='******') if bad: configCache.setPSetTweaks(PSetTweak=BadTweak) else: configCache.setPSetTweaks(PSetTweak=PSetTweak) configCache.save() return configCache.getCouchID() def loadWorkload(self, requestName): """ _loadWorkload_ Load the workload from couch after we've saved it there. """ workload = WMWorkloadHelper() url = '%s/%s/%s/spec' % (os.environ['COUCHURL'], self.couchDBName, requestName) workload.load(url) return workload @attr('integration') def testA_makeReRecoWorkload(self): """ _makeReRecoWorkload_ Check that you can make a basic ReReco workload """ userName = '******' groupName = 'Li' teamName = 'Tang' schema = utils.getAndSetupSchema(self, userName=userName, groupName=groupName, teamName=teamName) del schema['GlobalTag'] configID = self.createConfig(bad=False) schema['ConfigCacheID'] = configID schema["CouchDBName"] = self.couchDBName schema["CouchURL"] = os.environ.get("COUCHURL") schema["CouchWorkloadDBName"] = self.couchDBName raises = False try: self.jsonSender.put('request', schema) except HTTPException as ex: raises = True self.assertEqual(ex.status, 400) self.assertTrue( "Error in Workload Validation: Argument GlobalTag is required." in ex.result) self.assertTrue(raises) schema = utils.getSchema(groupName=groupName, userName=userName) schema['InputDataset'] = '/Nothing' raises = False try: self.jsonSender.put('request', schema) except HTTPException as ex: raises = True self.assertEqual(ex.status, 400) self.assertTrue(raises) schema = utils.getSchema(groupName=groupName, userName=userName) raises = False del schema['ConfigCacheID'] try: self.jsonSender.put('request', schema) except HTTPException as ex: raises = True self.assertEqual(ex.status, 400) self.assertTrue( "Create request failed, 'ConfigCacheID'" in ex.result) self.assertTrue(raises) configID = self.createConfig(bad=True) schema = utils.getSchema(groupName=groupName, userName=userName) schema["ConfigCacheID"] = configID schema["CouchDBName"] = self.couchDBName schema["CouchURL"] = os.environ.get("COUCHURL") schema["CouchWorkloadDBName"] = self.couchDBName raises = False try: self.jsonSender.put('request', schema) except HTTPException as ex: raises = True self.assertEqual(ex.status, 400) self.assertTrue( "Error in Workload Validation: " "Duplicate dataTier/filterName combination" in ex.result) self.assertTrue(raises) schema = utils.getSchema(groupName=groupName, userName=userName) configID = self.createConfig(bad=False) schema['ConfigCacheID'] = configID schema["CouchDBName"] = self.couchDBName schema["CouchURL"] = os.environ.get("COUCHURL") schema["CouchWorkloadDBName"] = self.couchDBName try: result = self.jsonSender.put('request', schema) except Exception as ex: raise self.assertEqual(result[1], 200) requestName = result[0]['RequestName'] result = self.jsonSender.get('request/%s' % requestName) request = result[0] self.assertEqual(request['CMSSWVersion'], schema['CMSSWVersion']) self.assertEqual(request['Group'], groupName) self.assertEqual(request['Requestor'], userName) @attr('integration') def testB_Analysis(self): """ _Analysis_ Test Analysis workflows """ userName = '******' groupName = 'Li' teamName = 'Tang' schema = utils.getAndSetupSchema(self, userName=userName, groupName=groupName, teamName=teamName) schema['RequestType'] = "Analysis" try: raises = False result = self.jsonSender.put('request', schema) except HTTPException as ex: raises = True self.assertEqual(ex.status, 400) self.assertTrue(raises) # Put the right things in the schema # And watch it fail, because we can't open a secure connection to CERN # in a unittest well schema['RequestorDN'] = 'SomeDN' #result = self.jsonSender.put('request/testRequest', schema) #requestName = result[0]['RequestName'] #result = self.jsonSender.get('request/%s' % requestName) #request = result[0] #self.assertEqual(request['CMSSWVersion'], CMSSWVersion) #self.assertEqual(request['Group'], groupName) #self.assertEqual(request['Requestor'], userName) @attr('integration') def testD_ReDigi(self): """ _ReDigi_ Test ReDigi workflows """ userName = '******' groupName = 'Li' teamName = 'Tang' schema = utils.getAndSetupSchema(self, userName=userName, groupName=groupName, teamName=teamName) schema['RequestType'] = "ReDigi" try: raises = False result = self.jsonSender.put('request', schema) except HTTPException as ex: raises = True self.assertEqual(ex.status, 400) self.assertTrue( "Create request failed, 'StepOneConfigCacheID'" in ex.result) self.assertTrue(raises) schema["StepOneConfigCacheID"] = "fakeID" schema["CouchDBName"] = self.couchDBName schema["CouchURL"] = os.environ.get("COUCHURL") schema["CouchWorkloadDBName"] = self.couchDBName try: raises = False result = self.jsonSender.put('request', schema) except HTTPException as ex: raises = True self.assertEqual(ex.status, 400) self.assertTrue( "Failure to load ConfigCache while validating workload" in ex.result) self.assertTrue(raises) configID = self.createConfig() schema["StepOneConfigCacheID"] = configID result = self.jsonSender.put('request', schema) requestName = result[0]['RequestName'] result = self.jsonSender.get('request/%s' % requestName) request = result[0] self.assertEqual(request['CMSSWVersion'], schema['CMSSWVersion']) self.assertEqual(request['Group'], groupName) self.assertEqual(request['Requestor'], userName) self.assertEqual(request['SizePerEvent'], 512) self.assertEqual(request['RequestNumEvents'], 0) self.assertEqual(request['RequestSizeFiles'], 0) @attr('integration') def testE_StoreResults(self): """ _StoreResults_ Test StoreResults workflows """ userName = '******' groupName = 'Li' teamName = 'Tang' schema = utils.getAndSetupSchema(self, userName=userName, groupName=groupName, teamName=teamName) schema['RequestType'] = "StoreResults" schema["CouchWorkloadDBName"] = self.couchDBName try: raises = False result = self.jsonSender.put('request', schema) except HTTPException as ex: raises = True self.assertEqual(ex.status, 400) self.assertTrue( "Error in Workload Validation: Argument CmsPath is required." in ex.result) self.assertTrue(raises) schema['DbsUrl'] = 'http://fake.dbs.url/dbs' schema['CmsPath'] = '/fake/tmp/path' schema['AcquisitionEra'] = 'era' schema['ProcessingVersion'] = 1 result = self.jsonSender.put('request', schema) requestName = result[0]['RequestName'] result = self.jsonSender.get('request/%s' % requestName) request = result[0] self.assertEqual(request['CMSSWVersion'], schema['CMSSWVersion']) self.assertEqual(request['Group'], groupName) self.assertEqual(request['Requestor'], userName) self.assertEqual(request['DbsUrl'], schema['DbsUrl']) @attr('integration') def testF_TaskChain(self): """ _TaskChain_ Test the monstrous TaskChain workflow This will be a long one NOTE: This test is so complicated that all I do is take code from TaskChain_t and make sure it still produces and actual request """ couchServer = CouchServer(os.environ["COUCHURL"]) configDatabase = couchServer.connectDatabase(self.couchDBName) generatorDoc = makeGeneratorConfig(configDatabase) processorDocs = makeProcessingConfigs(configDatabase) userName = '******' groupName = 'Li' teamName = 'Tang' schema = utils.getSchema(userName=userName) schema["CouchURL"] = os.environ["COUCHURL"] schema["CouchDBName"] = self.couchDBName schema["CouchWorkloadDBName"] = self.couchDBName schema["SiteWhitelist"] = ["T1_CH_CERN", "T1_US_FNAL"] schema["TaskChain"] = 5 chains = { "Task1": { "TaskName": "GenSim", "ConfigCacheID": generatorDoc, "SplittingAlgo": "EventBased", "EventsPerJob": 250, "RequestNumEvents": 10000, "PrimaryDataset": "RelValTTBar" }, "Task2": { "TaskName": "DigiHLT", "InputTask": "GenSim", "InputFromOutputModule": "writeGENSIM", "ConfigCacheID": processorDocs['DigiHLT'], "SplittingAlgo": "FileBased" }, "Task3": { "TaskName": "Reco", "InputTask": "DigiHLT", "InputFromOutputModule": "writeRAWDIGI", "ConfigCacheID": processorDocs['Reco'], "SplittingAlgo": "FileBased" }, "Task4": { "TaskName": "ALCAReco", "InputTask": "Reco", "InputFromOutputModule": "writeALCA", "ConfigCacheID": processorDocs['ALCAReco'], "SplittingAlgo": "FileBased" }, "Task5": { "TaskName": "Skims", "InputTask": "Reco", "InputFromOutputModule": "writeRECO", "ConfigCacheID": processorDocs['Skims'], "SplittingAlgo": "FileBased", "FilesPerJob": 10 } } schema.update(chains) args = utils.getAndSetupSchema(self, userName=userName, groupName=groupName, teamName=teamName) schema.update(args) # this is necessary and after all updates to the schema are made, # otherwise this item will get overwritten schema['RequestType'] = "TaskChain" schema["CouchDBName"] = self.couchDBName schema["CouchURL"] = os.environ.get("COUCHURL") schema["CouchWorkloadDBName"] = self.couchDBName result = self.jsonSender.put('request', schema) requestName = result[0]['RequestName'] result = self.jsonSender.get('request/%s' % requestName) request = result[0] self.assertEqual(request['CMSSWVersion'], schema['CMSSWVersion']) self.assertEqual(request['Group'], groupName) self.assertEqual(request['Requestor'], userName) workload = self.loadWorkload(requestName) self.assertEqual(workload.data.request.schema.Task1["EventsPerJob"], 250) @attr('integration') def testG_MonteCarloFromGEN(self): """ _MonteCarloFromGEN_ Test MonteCarloFromGEN workflows """ userName = '******' groupName = 'Li' teamName = 'Tang' schema = utils.getAndSetupSchema(self, userName=userName, groupName=groupName, teamName=teamName) schema['RequestType'] = "MonteCarloFromGEN" try: raises = False result = self.jsonSender.put('request', schema) except HTTPException as ex: raises = True self.assertEqual(ex.status, 400) self.assertTrue( "Error in Workload Validation: Failure to load ConfigCache while validating workload" in ex.result) self.assertTrue(raises) schema["ConfigCacheID"] = "fakeID" schema["CouchDBName"] = self.couchDBName schema["CouchURL"] = os.environ.get("COUCHURL") schema["CouchWorkloadDBName"] = self.couchDBName try: raises = False result = self.jsonSender.put('request', schema) except HTTPException as ex: raises = True self.assertEqual(ex.status, 400) self.assertTrue( "Failure to load ConfigCache while validating workload" in ex.result) self.assertTrue(raises) configID = self.createConfig() schema["ConfigCacheID"] = configID result = self.jsonSender.put('request', schema) requestName = result[0]['RequestName'] result = self.jsonSender.get('request/%s' % requestName) request = result[0] self.assertEqual(request['CMSSWVersion'], schema['CMSSWVersion']) self.assertEqual(request['Group'], groupName) self.assertEqual(request['Requestor'], userName) self.assertEqual(request['SizePerEvent'], 512) self.assertEqual(request['RequestNumEvents'], 0) self.assertEqual(request['RequestSizeFiles'], 0) def testH_MonteCarlo(self): """ _MonteCarlo_ Test MonteCarlo workflows """ userName = '******' groupName = 'Li' teamName = 'Tang' schema = utils.getAndSetupSchema(self, userName=userName, groupName=groupName, teamName=teamName) schema['RequestType'] = "MonteCarlo" schema['DbsUrl'] = 'https://cmsweb.cern.ch/dbs/prod/global/DBSReader' # Set some versions schema['ProcessingVersion'] = '2012' schema['AcquisitionEra'] = 'ae2012' try: raises = False result = self.jsonSender.put('request', schema) except HTTPException as ex: raises = True self.assertEqual(ex.status, 400) self.assertTrue( "Error in Workload Validation: Failure to load ConfigCache while validating workload" in ex.result) self.assertTrue(raises) schema["ConfigCacheID"] = "fakeID" schema["CouchDBName"] = self.couchDBName schema["CouchURL"] = os.environ.get("COUCHURL") schema["CouchWorkloadDBName"] = self.couchDBName schema["PrimaryDataset"] = "ReallyFake" schema["RequestNumEvents"] = 100 try: raises = False result = self.jsonSender.put('request', schema) except HTTPException as ex: raises = True self.assertEqual(ex.status, 400) self.assertTrue(raises) configID = self.createConfig() schema["ConfigCacheID"] = configID schema["FilterEfficiency"] = -0.5 try: raises = False result = self.jsonSender.put('request', schema) except HTTPException as ex: raises = True self.assertEqual(ex.status, 400) # until exception handling is redone (New REST API) #self.assertTrue("Negative filter efficiency for MC workflow" in ex.result) self.assertTrue(raises) schema["FilterEfficiency"] = 1.0 result = self.jsonSender.put('request', schema) requestName = result[0]['RequestName'] result = self.jsonSender.get('request/%s' % requestName) request = result[0] self.assertEqual(request['CMSSWVersion'], schema['CMSSWVersion']) self.assertEqual(request['Group'], groupName) self.assertEqual(request['Requestor'], userName) self.assertEqual(request['DbsUrl'], schema['DbsUrl']) self.assertEqual(request['SizePerEvent'], 512) self.assertEqual(request['RequestNumEvents'], 100) self.assertEqual(request['RequestSizeFiles'], 0) def testJ_Resubmission(self): """ _Resubmission_ Test Resubmission """ userName = '******' groupName = 'Li' teamName = 'Tang' schema = utils.getAndSetupSchema(self, userName=userName, groupName=groupName, teamName=teamName) schema['RequestType'] = "ReReco" configID = self.createConfig() schema["ConfigCacheID"] = configID schema["CouchDBName"] = self.couchDBName schema["CouchURL"] = os.environ.get("COUCHURL") schema["CouchWorkloadDBName"] = self.couchDBName result = self.jsonSender.put('request', schema) requestName = result[0]['RequestName'] # user, group schema already set up schema = utils.getSchema(groupName=groupName, userName=userName) schema['RequestType'] = "Resubmission" schema["CouchWorkloadDBName"] = self.couchDBName try: raises = False result = self.jsonSender.put('request', schema) except HTTPException as ex: raises = True self.assertEqual(ex.status, 400) self.assertTrue( "Error in Workload Validation: Validation failed: InitialTaskPath is mendatory" in ex.result) self.assertTrue(raises) schema["InitialTaskPath"] = '/%s/DataProcessing' % requestName schema["ACDCServer"] = os.environ.get("COUCHURL") schema["ACDCDatabase"] = self.couchDBName schema["CollectionName"] = "SomeOtherName" # Here we just make sure that real result goes through result = self.jsonSender.put('request', schema) resubmitName = result[0]['RequestName'] result = self.jsonSender.get('request/%s' % resubmitName) couchServer = CouchServer(self.testInit.couchUrl) reqmgrCouch = couchServer.connectDatabase(self.couchDBName) result = reqmgrCouch.loadView('ReqMgr', 'childresubmissionrequests', {}, [requestName])['rows'] self.assertEqual(len(result), 1) self.assertEqual(result[0]['key'], requestName) self.assertEqual(result[0]['id'], resubmitName)
class RequestManagerTest(RESTBaseUnitTest): """ Test RequestMgr Service client It will start RequestMgr RESTService Server DB is whatever env is set This checks whether DS call makes without error and return the results. This test only test service call returns without error. The correctness of each function is tested in test/python/RequestManager_t/RequestMgr_t.py """ def initialize(self): self.couchDBName = "reqmgr_t_0" self.config = RequestManagerConfig( 'WMCore.HTTPFrontEnd.RequestManager.ReqMgrRESTModel') dbUrl = os.environ.get("DATABASE", None) self.config.setDBUrl(dbUrl) self.config.setFormatter('WMCore.WebTools.RESTFormatter') self.config.setupRequestConfig() self.config.setupCouchDatabase(dbName = self.couchDBName) self.config.setPort(8888) self.schemaModules = ["WMCore.RequestManager.RequestDB"] return def setUp(self): """ setUP global values """ RESTBaseUnitTest.setUp(self) self.testInit.setupCouch("%s" % self.couchDBName, "GroupUser", "ConfigCache") self.params = {} self.params['endpoint'] = self.config.getServerUrl() self.reqService = RequestManagerDS(self.params) self.jsonSender = JSONRequests(self.config.getServerUrl()) self.requestSchema = getRequestSchema() self.jsonSender.put('group/PeopleLikeMe') self.jsonSender.put('user/[email protected]') self.jsonSender.put('group/PeopleLikeMe/me') self.jsonSender.put('version/CMSSW_3_5_8') r = self.jsonSender.put('request/' + self.requestSchema['RequestName'], self.requestSchema) self.requestName = r[0]['RequestName'] def tearDown(self): self.config.deleteWorkloadCache() RESTBaseUnitTest.tearDown(self) self.testInit.tearDownCouch() @attr("integration") def testA_RequestManagerService(self): requestName = self.requestName request = self.reqService.getRequest(requestName) # minimal test : it's return type and the some value inside self.assertEqual(type(request), dict) self.assertTrue(len(request) > 0) # Test putTeam self.reqService.putTeam("team_usa") self.assertTrue('team_usa' in self.jsonSender.get('team')[0]) self.jsonSender.put('assignment/%s/%s' % ("team_usa", requestName)) request = self.reqService.getAssignment(teamName = "team_usa") self.assertEqual(type(request), list) self.assertTrue(len(request) > 0) request = self.reqService.getAssignment(request = requestName) self.assertEqual(type(request), list) self.assertTrue(len(request) > 0) self.reqService.sendMessage(requestName,"error") self.reqService.putWorkQueue(requestName, "http://test_url") self.reqService.reportRequestProgress(requestName) self.reqService.reportRequestProgress(requestName, percent_complete = 100, percent_success = 90) self.reqService.reportRequestStatus(requestName, "running") return
class ReqMgrTest(RESTBaseUnitTest): """ _ReqMgrTest_ Basic test for the ReqMgr services. Setup is done off-screen in RESTBaseUnitTest - this makes things confusing """ def setUp(self): """ setUP global values Database setUp is done in base class """ self.couchDBName = "reqmgr_t_0" RESTBaseUnitTest.setUp(self) self.testInit.setupCouch("%s" % self.couchDBName, "GroupUser", "ConfigCache") self.testInit.setupCouch("%s_wmstats" % self.couchDBName, "WMStats") reqMgrHost = self.config.getServerUrl() self.jsonSender = JSONRequests(reqMgrHost) def initialize(self): self.config = RequestManagerConfig( 'WMCore.HTTPFrontEnd.RequestManager.ReqMgrRESTModel') self.config.setFormatter('WMCore.WebTools.RESTFormatter') self.config.setupRequestConfig() self.config.setupCouchDatabase(dbName = self.couchDBName) self.config.setPort(12888) self.schemaModules = ["WMCore.RequestManager.RequestDB"] def tearDown(self): """ tearDown Tear down everything """ RESTBaseUnitTest.tearDown(self) self.testInit.tearDownCouch() def createConfig(self, bad = False): """ _createConfig_ Create a config of some sort that we can load out of ConfigCache """ PSetTweak = {'process': {'outputModules_': ['ThisIsAName'], 'ThisIsAName': {'dataset': {'dataTier': 'RECO', 'filterName': 'Filter'}}}} BadTweak = {'process': {'outputModules_': ['ThisIsAName1', 'ThisIsAName2'], 'ThisIsAName1': {'dataset': {'dataTier': 'RECO', 'filterName': 'Filter'}}, 'ThisIsAName2': {'dataset': {'dataTier': 'RECO', 'filterName': 'Filter'}}}} configCache = ConfigCache(os.environ["COUCHURL"], couchDBName = self.couchDBName) configCache.createUserGroup(groupname = "testGroup", username = '******') if bad: configCache.setPSetTweaks(PSetTweak = BadTweak) else: configCache.setPSetTweaks(PSetTweak = PSetTweak) configCache.save() return configCache.getCouchID() @attr("integration") def testA_testBasicSetUp(self): """ _testBasicSetUp_ Moving the tests that were in the setUp category out of it, mostly because I want to make sure that they don't fail inside the setUp statement. """ if 'me' in self.jsonSender.get('user')[0]: self.jsonSender.delete('user/me') self.assertFalse('me' in self.jsonSender.get('user')[0]) self.assertEqual(self.jsonSender.put('user/[email protected]')[1], 200) self.assertTrue('me' in self.jsonSender.get('user')[0]) if 'PeopleLikeMe' in self.jsonSender.get('group')[0]: self.jsonSender.delete('group/PeopleLikeMe') self.assertFalse('PeopleLikeMe' in self.jsonSender.get('group')[0]) self.assertEqual(self.jsonSender.put('group/PeopleLikeMe')[1], 200) self.assertTrue( 'PeopleLikeMe' in self.jsonSender.get('group')[0]) self.jsonSender.put('group/PeopleLikeMe/me') users = self.jsonSender.get('group/PeopleLikeMe')[0]['users'] self.assertTrue('me' in users) groups = self.jsonSender.get('user/me')[0]['groups'] self.assertTrue('PeopleLikeMe' in groups) groups2 = self.jsonSender.get('group?user=me')[0] self.assertTrue('PeopleLikeMe' in groups2) if 'White Sox' in self.jsonSender.get('team')[0]: self.jsonSender.delete(urllib.quote('team/White Sox')) self.assertFalse('White Sox' in self.jsonSender.get('team')[0]) self.assertEqual(self.jsonSender.put(urllib.quote('team/White Sox'))[1], 200) self.assertTrue('White Sox' in self.jsonSender.get('team')[0]) # some foreign key stuff to dealwith schema = utils.getSchema() version = "version/" + schema["CMSSWVersion"] self.assertTrue(self.jsonSender.put(version)[1] == 200) self.assertTrue(schema["CMSSWVersion"] in self.jsonSender.get('version')[0]) @attr("integration") def testB_ReReco(self): """ _ReReco_ Try a basic ReReco workflow """ schema = utils.getAndSetupSchema(self) schema['RequestNumEvents'] = 100 schema['RequestEventSize'] = 101 self.doRequest(schema) def doRequest(self, schema): """ _doRequest_ Run all tests on a basic ReReco workflow """ requestName = schema['RequestName'] self.assertRaises(HTTPException, self.jsonSender.delete, 'request/%s' % requestName) result = self.jsonSender.put('request/%s' % (requestName), schema) self.assertEqual(result[1], 200) requestName = result[0]['RequestName'] self.assertEqual(self.jsonSender.get('request/%s' % requestName)[0]['RequestName'], requestName) self.jsonSender.put('request/%s?status=assignment-approved' % requestName) me = self.jsonSender.get('user/me')[0] self.assertTrue(requestName in me['requests']) self.assertEqual(self.jsonSender.put('request/%s?priority=5' % requestName)[1], 200) self.assertEqual(self.jsonSender.post('user/me?priority=6')[1], 200) self.assertEqual(self.jsonSender.post('group/PeopleLikeMe?priority=7')[1], 200) # default priority of group and user of 1 request = self.jsonSender.get('request/%s' % requestName)[0] self.assertEqual(request['ReqMgrRequestBasePriority'], 5) self.assertEqual(request['ReqMgrRequestorBasePriority'], 6) self.assertEqual(request['ReqMgrGroupBasePriority'], 7) self.assertEqual(request['RequestPriority'], 5+6+7) # Check LFN Bases self.assertEqual(request['UnmergedLFNBase'], '/store/unmerged') self.assertEqual(request['MergedLFNBase'], '/store/data') # Check random other self.assertEqual(request['CustodialSite'], 'US_T1_FNAL') # Check Num events self.assertEqual(request['RequestNumEvents'], 100) self.assertEqual(request['RequestEventSize'], 101) # only certain transitions allowed #self.assertEqual(self.jsonSender.put('request/%s?status=running' % requestName)[1], 400) self.assertRaises(HTTPException, self.jsonSender.put,'request/%s?status=running' % requestName) request = self.jsonSender.get('request/%s' % requestName)[0] self.assertEqual(request['RequestStatus'], 'assignment-approved') self.assertTrue(self.jsonSender.put(urllib.quote('assignment/White Sox/%s' % requestName))[1] == 200) requestsAndSpecs = self.jsonSender.get(urllib.quote('assignment/White Sox'))[0] self.assertTrue(requestName in requestsAndSpecs[0]) workloadHelper = WMWorkloadHelper() workloadHelper.load(requestsAndSpecs[0][1]) self.assertEqual(workloadHelper.getOwner()['Requestor'], "me") self.assertEqual(self.jsonSender.get('assignment?request=%s'% requestName)[0], ['White Sox']) self.assertEqual(self.jsonSender.get('request/%s' % requestName)[0]['teams'], ['White Sox']) agentUrl = 'http://cmssrv96.fnal.gov/workqueue' self.jsonSender.put('workQueue/%s?url=%s'% (requestName, urllib.quote(agentUrl)) ) self.assertEqual(self.jsonSender.get('workQueue/%s' % requestName)[0][0], agentUrl) request = self.jsonSender.get('request/%s' % requestName)[0] self.assertEqual(request['RequestStatus'], 'acquired') self.jsonSender.post('request/%s?events_written=10&files_merged=1' % requestName) self.jsonSender.post('request/%s?events_written=20&files_merged=2&percent_success=99.9' % requestName) request = self.jsonSender.get('request/%s' % requestName)[0] self.assertEqual(len(request['RequestUpdates']), 2) self.assertEqual(request['RequestUpdates'][0]['files_merged'], 1) self.assertEqual(request['RequestUpdates'][1]['events_written'], 20) self.assertEqual(request['RequestUpdates'][1]['percent_success'], 99.9) message = "The sheriff is near" jsonMessage = json.dumps(message) self.jsonSender.put('message/%s' % requestName, message) messages = self.jsonSender.get('message/%s' % requestName) #self.assertEqual(messages[0][0][0], message) for status in ['running', 'completed']: self.jsonSender.put('request/%s?status=%s' % (requestName, status)) # campaign self.jsonSender.put('campaign/%s' % 'TestCampaign') campaigns = self.jsonSender.get('campaign')[0] self.assertTrue('TestCampaign' in campaigns.keys()) self.jsonSender.put('campaign/%s/%s' % ('TestCampaign', requestName)) requestsInCampaign = self.jsonSender.get('campaign/%s' % 'TestCampaign')[0] self.assertTrue(requestName in requestsInCampaign.keys()) req = self.jsonSender.get('request/%s' % requestName)[0] self.assertEqual(req['Campaign'], 'TestCampaign') self.jsonSender.delete('request/%s' % requestName) @attr("integration") def testC_404Errors(self): """ _404Errors_ Do some things that generate 404 errors. This should be limited to requests for objects that do not exist. """ badName = 'ThereIsNoWayThisNameShouldExist' # First, try to find a non-existant request # This should throw a 404 error. # The request name should not be in it self.checkForError(cls = 'request', badName = badName, exitCode = 404, message = 'Given requestName not found') # Now look for non-existant user self.checkForError(cls = 'user', badName = badName, exitCode = 404, message = 'Cannot find user') # Now try non-existant group self.checkForError(cls = 'group', badName = badName, exitCode = 404, message = "Cannot find group/group priority") # Now try non-existant campaign self.checkForError(cls = 'campaign', badName = badName, exitCode = 404, message = "Cannot find campaign") # Now try invalid message # This raises a requestName error becuase it searches for the request self.checkForError(cls = 'message', badName = badName, exitCode = 404, message = "Given requestName not found", testEmpty = False) # Check for assignments (no teams or requests) # This raises a team error because it tries to load teams out first self.checkForError(cls = 'assignment', badName = badName, exitCode = 404, message = 'Cannot find team') @attr("integration") def testD_400Errors(self): """ _400Errors_ These are failures created by invalid input, such as sending args to a request when it doesn't accept any. They should generatore 400 Errors """ badName = 'ThereIsNoWayThisNameShouldExist' # Attempt to send arguments to a function that doesn't accept them. self.checkForError(cls = 'team', badName = badName, exitCode = 400, message = "Invalid input: Arguments added where none allowed") # Recheck for versions self.checkForError(cls = 'version', badName = badName, exitCode = 400, message = "Invalid input: Arguments added where none allowed") # Break the validation self.checkForError(cls = 'user', badName = '!', exitCode = 400, message = 'Invalid input: Input data failed validation') def checkForError(self, cls, badName, exitCode, message, testEmpty = True): """ _checkForError_ Generic function for checking for errors in JSON commands Does a basic check on type cls searching for name badName which hopefull does not exist. Checks to make sure that it exits with code exitCode, and that the error contains the string message. Also checks to make sure that name badName is NOT in the output testEmpty for those that don't handle calls to the main (i.e., who require an argument) """ raises = False # First assert that the test to be tested is empty if testEmpty: result = self.jsonSender.get(cls) self.assertTrue(type(result[0]) in [type([]), type({})]) # Next, test try: result = self.jsonSender.get('%s/%s' % (cls, badName)) except HTTPException, ex: raises = True self.assertEqual(ex.status, exitCode) self.assertTrue(message in ex.result) self.assertFalse(badName in ex.result) self.assertTrue(raises)
class ReqMgrWorkloadTest(RESTBaseUnitTest): """ Test that sets up and checks the validations of the various main WMSpec.StdSpecs This is mostly a simple set of tests which can be very repetitive. """ def setUp(self): """ setUP global values Database setUp is done in base class """ self.couchDBName = "reqmgr_t_0" RESTBaseUnitTest.setUp(self) self.testInit.setupCouch("%s" % self.couchDBName, "ConfigCache", "ReqMgr") self.testInit.setupCouch("%s_wmstats" % self.couchDBName, "WMStats") reqMgrHost = self.config.getServerUrl() self.jsonSender = JSONRequests(reqMgrHost) def initialize(self): self.config = RequestManagerConfig( 'WMCore.HTTPFrontEnd.RequestManager.ReqMgrRESTModel') self.config.setFormatter('WMCore.WebTools.RESTFormatter') self.config.setupRequestConfig() self.config.setupCouchDatabase(dbName = self.couchDBName) self.config.setPort(12888) self.schemaModules = ["WMCore.RequestManager.RequestDB"] def tearDown(self): """ _tearDown_ Basic tear down of database """ RESTBaseUnitTest.tearDown(self) self.testInit.tearDownCouch() def createConfig(self, bad = False): """ _createConfig_ Create a config of some sort that we can load out of ConfigCache """ PSetTweak = {'process': {'outputModules_': ['ThisIsAName'], 'ThisIsAName': {'dataset': {'dataTier': 'RECO', 'filterName': 'Filter'}}}} BadTweak = {'process': {'outputModules_': ['ThisIsAName1', 'ThisIsAName2'], 'ThisIsAName1': {'dataset': {'dataTier': 'RECO', 'filterName': 'Filter'}}, 'ThisIsAName2': {'dataset': {'dataTier': 'RECO', 'filterName': 'Filter'}}}} configCache = ConfigCache(os.environ["COUCHURL"], couchDBName = self.couchDBName) configCache.createUserGroup(groupname = "testGroup", username = '******') if bad: configCache.setPSetTweaks(PSetTweak = BadTweak) else: configCache.setPSetTweaks(PSetTweak = PSetTweak) configCache.save() return configCache.getCouchID() def loadWorkload(self, requestName): """ _loadWorkload_ Load the workload from couch after we've saved it there. """ workload = WMWorkloadHelper() url = '%s/%s/%s/spec' % (os.environ['COUCHURL'], self.couchDBName, requestName) workload.load(url) return workload @attr('integration') def testA_makeReRecoWorkload(self): """ _makeReRecoWorkload_ Check that you can make a basic ReReco workload """ userName = '******' groupName = 'Li' teamName = 'Tang' schema = utils.getAndSetupSchema(self, userName = userName, groupName = groupName, teamName = teamName) del schema['GlobalTag'] configID = self.createConfig(bad = False) schema['ConfigCacheID'] = configID schema["CouchDBName"] = self.couchDBName schema["CouchURL"] = os.environ.get("COUCHURL") schema["CouchWorkloadDBName"] = self.couchDBName raises = False try: self.jsonSender.put('request', schema) except HTTPException as ex: raises = True self.assertEqual(ex.status, 400) self.assertTrue("Error in Workload Validation: Argument GlobalTag is required." in ex.result) self.assertTrue(raises) schema = utils.getSchema(groupName = groupName, userName = userName) schema['InputDataset'] = '/Nothing' raises = False try: self.jsonSender.put('request', schema) except HTTPException as ex: raises = True self.assertEqual(ex.status, 400) self.assertTrue(raises) schema = utils.getSchema(groupName = groupName, userName = userName) raises = False del schema['ConfigCacheID'] try: self.jsonSender.put('request', schema) except HTTPException as ex: raises = True self.assertEqual(ex.status, 400) self.assertTrue("Create request failed, 'ConfigCacheID'" in ex.result) self.assertTrue(raises) configID = self.createConfig(bad = True) schema = utils.getSchema(groupName = groupName, userName = userName) schema["ConfigCacheID"] = configID schema["CouchDBName"] = self.couchDBName schema["CouchURL"] = os.environ.get("COUCHURL") schema["CouchWorkloadDBName"] = self.couchDBName raises = False try: self.jsonSender.put('request', schema) except HTTPException as ex: raises = True self.assertEqual(ex.status, 400) self.assertTrue("Error in Workload Validation: " "Duplicate dataTier/filterName combination" in ex.result) self.assertTrue(raises) schema = utils.getSchema(groupName = groupName, userName = userName) configID = self.createConfig(bad = False) schema['ConfigCacheID'] = configID schema["CouchDBName"] = self.couchDBName schema["CouchURL"] = os.environ.get("COUCHURL") schema["CouchWorkloadDBName"] = self.couchDBName try: result = self.jsonSender.put('request', schema) except Exception as ex: raise self.assertEqual(result[1], 200) requestName = result[0]['RequestName'] result = self.jsonSender.get('request/%s' % requestName) request = result[0] self.assertEqual(request['CMSSWVersion'], schema['CMSSWVersion']) self.assertEqual(request['Group'], groupName) self.assertEqual(request['Requestor'], userName) @attr('integration') def testB_Analysis(self): """ _Analysis_ Test Analysis workflows """ userName = '******' groupName = 'Li' teamName = 'Tang' schema = utils.getAndSetupSchema(self, userName = userName, groupName = groupName, teamName = teamName) schema['RequestType'] = "Analysis" try: raises = False result = self.jsonSender.put('request', schema) except HTTPException as ex: raises = True self.assertEqual(ex.status, 400) self.assertTrue(raises) # Put the right things in the schema # And watch it fail, because we can't open a secure connection to CERN # in a unittest well schema['RequestorDN'] = 'SomeDN' #result = self.jsonSender.put('request/testRequest', schema) #requestName = result[0]['RequestName'] #result = self.jsonSender.get('request/%s' % requestName) #request = result[0] #self.assertEqual(request['CMSSWVersion'], CMSSWVersion) #self.assertEqual(request['Group'], groupName) #self.assertEqual(request['Requestor'], userName) @attr('integration') def testD_ReDigi(self): """ _ReDigi_ Test ReDigi workflows """ userName = '******' groupName = 'Li' teamName = 'Tang' schema = utils.getAndSetupSchema(self, userName = userName, groupName = groupName, teamName = teamName) schema['RequestType'] = "ReDigi" try: raises = False result = self.jsonSender.put('request', schema) except HTTPException as ex: raises = True self.assertEqual(ex.status, 400) self.assertTrue("Create request failed, 'StepOneConfigCacheID'" in ex.result) self.assertTrue(raises) schema["StepOneConfigCacheID"] = "fakeID" schema["CouchDBName"] = self.couchDBName schema["CouchURL"] = os.environ.get("COUCHURL") schema["CouchWorkloadDBName"] = self.couchDBName try: raises = False result = self.jsonSender.put('request', schema) except HTTPException as ex: raises = True self.assertEqual(ex.status, 400) self.assertTrue("Failure to load ConfigCache while validating workload" in ex.result) self.assertTrue(raises) configID = self.createConfig() schema["StepOneConfigCacheID"] = configID result = self.jsonSender.put('request', schema) requestName = result[0]['RequestName'] result = self.jsonSender.get('request/%s' % requestName) request = result[0] self.assertEqual(request['CMSSWVersion'], schema['CMSSWVersion']) self.assertEqual(request['Group'], groupName) self.assertEqual(request['Requestor'], userName) self.assertEqual(request['SizePerEvent'], 512) self.assertEqual(request['RequestNumEvents'], 0) self.assertEqual(request['RequestSizeFiles'], 0) @attr('integration') def testE_StoreResults(self): """ _StoreResults_ Test StoreResults workflows """ userName = '******' groupName = 'Li' teamName = 'Tang' schema = utils.getAndSetupSchema(self, userName = userName, groupName = groupName, teamName = teamName) schema['RequestType'] = "StoreResults" schema["CouchWorkloadDBName"] = self.couchDBName try: raises = False result = self.jsonSender.put('request', schema) except HTTPException as ex: raises = True self.assertEqual(ex.status, 400) self.assertTrue("Error in Workload Validation: Argument CmsPath is required." in ex.result) self.assertTrue(raises) schema['DbsUrl'] = 'http://fake.dbs.url/dbs' schema['CmsPath'] = '/fake/tmp/path' schema['AcquisitionEra'] = 'era' schema['ProcessingVersion'] = 1 result = self.jsonSender.put('request', schema) requestName = result[0]['RequestName'] result = self.jsonSender.get('request/%s' % requestName) request = result[0] self.assertEqual(request['CMSSWVersion'], schema['CMSSWVersion']) self.assertEqual(request['Group'], groupName) self.assertEqual(request['Requestor'], userName) self.assertEqual(request['DbsUrl'], schema['DbsUrl']) @attr('integration') def testF_TaskChain(self): """ _TaskChain_ Test the monstrous TaskChain workflow This will be a long one NOTE: This test is so complicated that all I do is take code from TaskChain_t and make sure it still produces and actual request """ couchServer = CouchServer(os.environ["COUCHURL"]) configDatabase = couchServer.connectDatabase(self.couchDBName) generatorDoc = makeGeneratorConfig(configDatabase) processorDocs = makeProcessingConfigs(configDatabase) userName = '******' groupName = 'Li' teamName = 'Tang' schema = utils.getSchema(userName = userName) schema["CouchURL"] = os.environ["COUCHURL"] schema["CouchDBName"] = self.couchDBName schema["CouchWorkloadDBName"] = self.couchDBName schema["SiteWhitelist"] = ["T1_CH_CERN", "T1_US_FNAL"] schema["TaskChain"] = 5 chains = {"Task1" : {"TaskName" : "GenSim", "ConfigCacheID" : generatorDoc, "SplittingAlgo" : "EventBased", "EventsPerJob" : 250, "RequestNumEvents" : 10000, "PrimaryDataset" : "RelValTTBar"}, "Task2" : {"TaskName" : "DigiHLT", "InputTask" : "GenSim", "InputFromOutputModule" : "writeGENSIM", "ConfigCacheID" : processorDocs['DigiHLT'], "SplittingAlgo" : "FileBased"}, "Task3" : {"TaskName" : "Reco", "InputTask" : "DigiHLT", "InputFromOutputModule" : "writeRAWDIGI", "ConfigCacheID" : processorDocs['Reco'], "SplittingAlgo" : "FileBased"}, "Task4" : {"TaskName" : "ALCAReco", "InputTask" : "Reco", "InputFromOutputModule" : "writeALCA", "ConfigCacheID" : processorDocs['ALCAReco'], "SplittingAlgo" : "FileBased"}, "Task5" : {"TaskName" : "Skims", "InputTask" : "Reco", "InputFromOutputModule" : "writeRECO", "ConfigCacheID" : processorDocs['Skims'], "SplittingAlgo" : "FileBased", "FilesPerJob" : 10 } } schema.update(chains) args = utils.getAndSetupSchema(self, userName = userName, groupName = groupName, teamName = teamName) schema.update(args) # this is necessary and after all updates to the schema are made, # otherwise this item will get overwritten schema['RequestType'] = "TaskChain" schema["CouchDBName"] = self.couchDBName schema["CouchURL"] = os.environ.get("COUCHURL") schema["CouchWorkloadDBName"] = self.couchDBName result = self.jsonSender.put('request', schema) requestName = result[0]['RequestName'] result = self.jsonSender.get('request/%s' % requestName) request = result[0] self.assertEqual(request['CMSSWVersion'], schema['CMSSWVersion']) self.assertEqual(request['Group'], groupName) self.assertEqual(request['Requestor'], userName) workload = self.loadWorkload(requestName) self.assertEqual(workload.data.request.schema.Task1["EventsPerJob"], 250) @attr('integration') def testG_MonteCarloFromGEN(self): """ _MonteCarloFromGEN_ Test MonteCarloFromGEN workflows """ userName = '******' groupName = 'Li' teamName = 'Tang' schema = utils.getAndSetupSchema(self, userName = userName, groupName = groupName, teamName = teamName) schema['RequestType'] = "MonteCarloFromGEN" try: raises = False result = self.jsonSender.put('request', schema) except HTTPException as ex: raises = True self.assertEqual(ex.status, 400) self.assertTrue("Error in Workload Validation: Failure to load ConfigCache while validating workload" in ex.result) self.assertTrue(raises) schema["ConfigCacheID"] = "fakeID" schema["CouchDBName"] = self.couchDBName schema["CouchURL"] = os.environ.get("COUCHURL") schema["CouchWorkloadDBName"] = self.couchDBName try: raises = False result = self.jsonSender.put('request', schema) except HTTPException as ex: raises = True self.assertEqual(ex.status, 400) self.assertTrue("Failure to load ConfigCache while validating workload" in ex.result) self.assertTrue(raises) configID = self.createConfig() schema["ConfigCacheID"] = configID result = self.jsonSender.put('request', schema) requestName = result[0]['RequestName'] result = self.jsonSender.get('request/%s' % requestName) request = result[0] self.assertEqual(request['CMSSWVersion'], schema['CMSSWVersion']) self.assertEqual(request['Group'], groupName) self.assertEqual(request['Requestor'], userName) self.assertEqual(request['SizePerEvent'], 512) self.assertEqual(request['RequestNumEvents'], 0) self.assertEqual(request['RequestSizeFiles'], 0) def testH_MonteCarlo(self): """ _MonteCarlo_ Test MonteCarlo workflows """ userName = '******' groupName = 'Li' teamName = 'Tang' schema = utils.getAndSetupSchema(self, userName = userName, groupName = groupName, teamName = teamName) schema['RequestType'] = "MonteCarlo" schema['DbsUrl'] = 'https://cmsweb.cern.ch/dbs/prod/global/DBSReader' # Set some versions schema['ProcessingVersion'] = '2012' schema['AcquisitionEra'] = 'ae2012' try: raises = False result = self.jsonSender.put('request', schema) except HTTPException as ex: raises = True self.assertEqual(ex.status, 400) self.assertTrue("Error in Workload Validation: Failure to load ConfigCache while validating workload" in ex.result) self.assertTrue(raises) schema["ConfigCacheID"] = "fakeID" schema["CouchDBName"] = self.couchDBName schema["CouchURL"] = os.environ.get("COUCHURL") schema["CouchWorkloadDBName"] = self.couchDBName schema["PrimaryDataset"] = "ReallyFake" schema["RequestNumEvents"] = 100 try: raises = False result = self.jsonSender.put('request', schema) except HTTPException as ex: raises = True self.assertEqual(ex.status, 400) self.assertTrue(raises) configID = self.createConfig() schema["ConfigCacheID"] = configID schema["FilterEfficiency"] = -0.5 try: raises = False result = self.jsonSender.put('request', schema) except HTTPException as ex: raises = True self.assertEqual(ex.status, 400) # until exception handling is redone (New REST API) #self.assertTrue("Negative filter efficiency for MC workflow" in ex.result) self.assertTrue(raises) schema["FilterEfficiency"] = 1.0 result = self.jsonSender.put('request', schema) requestName = result[0]['RequestName'] result = self.jsonSender.get('request/%s' % requestName) request = result[0] self.assertEqual(request['CMSSWVersion'], schema['CMSSWVersion']) self.assertEqual(request['Group'], groupName) self.assertEqual(request['Requestor'], userName) self.assertEqual(request['DbsUrl'], schema['DbsUrl']) self.assertEqual(request['SizePerEvent'], 512) self.assertEqual(request['RequestNumEvents'], 100) self.assertEqual(request['RequestSizeFiles'], 0) def testJ_Resubmission(self): """ _Resubmission_ Test Resubmission """ userName = '******' groupName = 'Li' teamName = 'Tang' schema = utils.getAndSetupSchema(self, userName = userName, groupName = groupName, teamName = teamName) schema['RequestType'] = "ReReco" configID = self.createConfig() schema["ConfigCacheID"] = configID schema["CouchDBName"] = self.couchDBName schema["CouchURL"] = os.environ.get("COUCHURL") schema["CouchWorkloadDBName"] = self.couchDBName result = self.jsonSender.put('request', schema) requestName = result[0]['RequestName'] # user, group schema already set up schema = utils.getSchema(groupName = groupName, userName = userName) schema['RequestType'] = "Resubmission" schema["CouchWorkloadDBName"] = self.couchDBName try: raises = False result = self.jsonSender.put('request', schema) except HTTPException as ex: raises = True self.assertEqual(ex.status, 400) self.assertTrue("Error in Workload Validation: Validation failed: InitialTaskPath is mendatory" in ex.result) self.assertTrue(raises) schema["InitialTaskPath"] = '/%s/DataProcessing' % requestName schema["ACDCServer"] = os.environ.get("COUCHURL") schema["ACDCDatabase"] = self.couchDBName schema["CollectionName"] = "SomeOtherName" # Here we just make sure that real result goes through result = self.jsonSender.put('request', schema) resubmitName = result[0]['RequestName'] result = self.jsonSender.get('request/%s' % resubmitName) couchServer = CouchServer(self.testInit.couchUrl) reqmgrCouch = couchServer.connectDatabase(self.couchDBName) result = reqmgrCouch.loadView('ReqMgr', 'childresubmissionrequests', {}, [requestName])['rows'] self.assertEqual(len(result), 1) self.assertEqual(result[0]['key'], requestName) self.assertEqual(result[0]['id'], resubmitName)
class ReqMgrPriorityTest(RESTBaseUnitTest): """ _ReqMgrPriorityTest_ Basic test for setting the priority in ReqMgr Services """ def setUp(self): """ setUP global values Database setUp is done in base class """ self.couchDBName = "reqmgr_t_0" RESTBaseUnitTest.setUp(self) self.testInit.setupCouch("%s" % self.couchDBName, "GroupUser", "ConfigCache") reqMgrHost = self.config.getServerUrl() self.jsonSender = JSONRequests(reqMgrHost) return def initialize(self): self.config = RequestManagerConfig( 'WMCore.HTTPFrontEnd.RequestManager.ReqMgrRESTModel') self.config.setFormatter('WMCore.WebTools.RESTFormatter') self.config.setupRequestConfig() self.config.setupCouchDatabase(dbName = self.couchDBName) self.config.setPort(8888) self.schemaModules = ["WMCore.RequestManager.RequestDB"] return def tearDown(self): """ _tearDown_ Basic tear down of database """ RESTBaseUnitTest.tearDown(self) self.testInit.tearDownCouch() return def setupSchema(self, groupName = 'PeopleLikeMe', userName = '******', teamName = 'White Sox', CMSSWVersion = 'CMSSW_3_5_8', scramArch = 'slc5_ia32_gcc434'): """ _setupSchema_ Set up a test schema so that we can run a test request. Standardization! """ self.jsonSender.put('user/%[email protected]' % userName) self.jsonSender.put('group/%s' % groupName) self.jsonSender.put('group/%s/%s' % (groupName, userName)) self.jsonSender.put(urllib.quote('team/%s' % teamName)) self.jsonSender.put('version/%s/%s' % (CMSSWVersion, scramArch)) schema = ReReco.getTestArguments() schema['RequestName'] = 'TestReReco' schema['RequestType'] = 'ReReco' schema['CmsPath'] = "/uscmst1/prod/sw/cms" schema['Requestor'] = '%s' % userName schema['Group'] = '%s' % groupName return schema def loadWorkload(self, requestName): """ _loadWorkload_ Load the workload from couch after we've saved it there. """ workload = WMWorkloadHelper() url = '%s/%s/%s/spec' % (os.environ['COUCHURL'], self.couchDBName, requestName) workload.load(url) return workload def changeStatusAndCheck(self, requestName, statusName): """ _changeStatusAndCheck_ Change the status of a request and make sure that the request actually did it. """ self.jsonSender.put('request/%s?status=%s' % (requestName, statusName)) result = self.jsonSender.get('request/%s' % requestName) self.assertEqual(result[0]['RequestStatus'], statusName) return def testA_RequestPriority(self): """ _priorityChanges_ Do some fairly standard priority changes to the Request and see how things react """ userName = '******' groupName = 'Li' teamName = 'Tang' CMSSWVersion = 'CMSSW_3_5_8' schema = self.setupSchema(userName = userName, groupName = groupName, teamName = teamName, CMSSWVersion = CMSSWVersion) result = self.jsonSender.put('request/testRequest', schema) self.assertEqual(result[1], 200) requestName = result[0]['RequestName'] workload = self.loadWorkload(requestName = requestName) self.assertEqual(workload.priority(), 0) # Reset user, group priorities to 0 self.jsonSender.post('user/%s?priority=0' % userName) self.jsonSender.post('group/%s?priority=0' % groupName) # Set priority == 5 priority = 5 self.jsonSender.put('request/%s?priority=%s' % (requestName, priority)) request = self.jsonSender.get('request/%s' % requestName)[0] self.assertEqual(request['ReqMgrRequestBasePriority'], priority) workload = self.loadWorkload(requestName = requestName) self.assertEqual(workload.priority(), priority) # Set priority == 100 priority = 100 self.jsonSender.put('request/%s?priority=%s' % (requestName, priority)) request = self.jsonSender.get('request/%s' % requestName)[0] self.assertEqual(request['ReqMgrRequestBasePriority'], priority) workload = self.loadWorkload(requestName = requestName) self.assertEqual(workload.priority(), priority) # Set priority == -1 priority = -1 self.jsonSender.put('request/%s?priority=%s' % (requestName, priority)) request = self.jsonSender.get('request/%s' % requestName)[0] self.assertEqual(request['ReqMgrRequestBasePriority'], priority) workload = self.loadWorkload(requestName = requestName) self.assertEqual(workload.priority(), priority) # Let's move the request around a bit self.changeStatusAndCheck(requestName = requestName, statusName = 'testing-approved') self.changeStatusAndCheck(requestName = requestName, statusName = 'testing') self.changeStatusAndCheck(requestName = requestName, statusName = 'tested') self.changeStatusAndCheck(requestName = requestName, statusName = 'assignment-approved') self.jsonSender.put(urllib.quote('assignment/%s/%s' % (teamName, requestName))) # Set priority == 99 priority = 99 self.jsonSender.put('request/%s?priority=%s' % (requestName, priority)) request = self.jsonSender.get('request/%s' % requestName)[0] self.assertEqual(request['ReqMgrRequestBasePriority'], priority) workload = self.loadWorkload(requestName = requestName) self.assertEqual(workload.priority(), priority) return def testB_InvalidPriority(self): """ _InvalidPriority_ Put in a bunch of invalid values for priorities and see what the code makes of them. """ userName = '******' groupName = 'Li' teamName = 'Tang' CMSSWVersion = 'CMSSW_3_5_8' schema = self.setupSchema(userName = userName, groupName = groupName, teamName = teamName, CMSSWVersion = CMSSWVersion) result = self.jsonSender.put('request/testRequest', schema) self.assertEqual(result[1], 200) requestName = result[0]['RequestName'] raises = False try: priority = sys.maxint + 1 self.jsonSender.put('request/%s?priority=%s' % (requestName, priority)) except HTTPException, ex: raises = True self.assertEqual(ex.status, 400) self.assertTrue("Priority must have abs() less then MAXINT!" in ex.result) self.assertTrue(raises) raises = False try: priority = -1 - sys.maxint self.jsonSender.put('request/%s?priority=%s' % (requestName, priority)) except HTTPException, ex: raises = True self.assertEqual(ex.status, 400) print ex.result self.assertTrue("Priority must have abs() less then MAXINT!" in ex.result)
class ReqMgrTester(object): def __init__(self, reqMgrUrl): self.reqMgrUrl = reqMgrUrl self.restSender = JSONRequests(reqMgrUrl) d = dict(endpoint=self.reqMgrUrl) self.reqMgrService = RequestManager(d) def queryAllRequests(self): """ Returns all requests stored at ReqMgr instance. """ logging.info("Querying all requests at ReqMgr instance ...") r = self.reqMgrService.getRequestNames() print "Found %s requests:" % len(r) for req in r: print req def queryRequest(self, requestName): """ Query a specific request according to the input argument. """ urlQuery = "request/%s" % requestName logging.info("Querying request '%s'" % requestName) logging.info("Query: '%s':" % urlQuery) r = self.restSender.get(urlQuery) print str(r) def createRequests(self, numRequests): """ Inject new numRequests into ReqMgr instance. (see ReqMgr_t testE how to create a request) """ logging.info("Creating %s new requests ..." % numRequests) schema = ReReco.getTestArguments() schema['RequestName'] = 'TestReReco' schema['RequestType'] = 'ReReco' schema['CmsPath'] = "/uscmst1/prod/sw/cms" schema['Requestor'] = '%s' % "zmaxa" schema['Group'] = '%s' % "DATAOPS" schema['BlockWhitelist'] = ['/dataset/dataset/dataset#alpha'] schema['BlockBlacklist'] = ['/dataset/dataset/dataset#beta'] schema['Campaign'] = 'MyTestCampaign' for i in range(numRequests): urlQuery = "request/testRequest" print "Query: '%s':" % urlQuery print "Schema (request): '%s'" % schema r = self.restSender.put(urlQuery, schema) # print "request creating response: ", r print "created: ", r[0]["RequestName"] def deleteRequest(self, requestNames): """ Delete requests specified in the input, more request names are comma-separated. """ logging.info("Deleting requests ...") for reqName in requestNames.split(','): reqName = reqName.strip() urlQuery = "request/%s" % reqName logging.info("Deleting request (request_name): '%s'" % reqName) logging.info("Query: '%s':" % urlQuery) r = self.restSender.delete(urlQuery) def requestChangeStates(self, reqName): """ Route the request (spec. by the request name) in the input through a series of possible request states. """ logging.info("Changing state of request %s ..." % reqName) def changeState(requestName, urlQuery): logging.info("Query: '%s' ..." % urlQuery) r = self.restSender.put(urlQuery) r = self.restSender.get("request/%s" % requestName) #assert r[0]["RequestStatus"] == statusName logging.info("Querying modified request, new state: %s" % r[0]["RequestStatus"]) # once a request is created, it's in 'new' state # states transition has to be an allowed one as defined here: # WMCore/RequestManager/RequestDB/Settings/RequestStatus.py statesQueries = [ "request/%s?status=%s" % (reqName, "testing-approved"), "request/%s?status=%s" % (reqName, "testing"), "request/%s?status=%s" % (reqName, "tested"), "request/%s?status=%s" % (reqName, "assignment-approved"), # create an assignment now # need quote because of space in the team name # (previous name - White Sox) urllib.quote("assignment/%s/%s" % (TEAM_NAME, reqName)) ] for query in statesQueries: changeState(reqName, query) def setup(self): """ Setup ReqMgr instance for dealing with requests - needs to create a user, group, SW releases entries, etc. as done in test/python/WMCore_t/RequestManager_t/ReqMgr_t.py """ logging.info("ReqMgr setup ...") def doQuery(urlQuery): logging.info("Query: '%s' ..." % urlQuery) r = None try: r = self.restSender.put(urlQuery) except Exception as ex: print "exception" print str(ex) print "response:", r queries = [ "user/[email protected]", "group/DATAOPS", "group/DATAOPS/zmaxa", urllib.quote("team/" + TEAM_NAME), "version/%s" % "CMSSW_3_5_8" ] for q in queries: doQuery(q) logging.info("ReqMgr setup finished, listing known users ...") q = "user/" r = self.restSender.get(q) print r