wmglobalqueue 2.4.5.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (347) hide show
  1. Utils/CPMetrics.py +270 -0
  2. Utils/CertTools.py +100 -0
  3. Utils/EmailAlert.py +50 -0
  4. Utils/ExtendedUnitTestCase.py +62 -0
  5. Utils/FileTools.py +182 -0
  6. Utils/IteratorTools.py +80 -0
  7. Utils/MathUtils.py +31 -0
  8. Utils/MemoryCache.py +119 -0
  9. Utils/Patterns.py +24 -0
  10. Utils/Pipeline.py +137 -0
  11. Utils/PortForward.py +97 -0
  12. Utils/ProcFS.py +112 -0
  13. Utils/ProcessStats.py +194 -0
  14. Utils/PythonVersion.py +17 -0
  15. Utils/Signals.py +36 -0
  16. Utils/TemporaryEnvironment.py +27 -0
  17. Utils/Throttled.py +227 -0
  18. Utils/Timers.py +130 -0
  19. Utils/Timestamps.py +86 -0
  20. Utils/TokenManager.py +143 -0
  21. Utils/Tracing.py +60 -0
  22. Utils/TwPrint.py +98 -0
  23. Utils/Utilities.py +318 -0
  24. Utils/__init__.py +11 -0
  25. Utils/wmcoreDTools.py +707 -0
  26. WMCore/ACDC/Collection.py +57 -0
  27. WMCore/ACDC/CollectionTypes.py +12 -0
  28. WMCore/ACDC/CouchCollection.py +67 -0
  29. WMCore/ACDC/CouchFileset.py +238 -0
  30. WMCore/ACDC/CouchService.py +73 -0
  31. WMCore/ACDC/DataCollectionService.py +485 -0
  32. WMCore/ACDC/Fileset.py +94 -0
  33. WMCore/ACDC/__init__.py +11 -0
  34. WMCore/Algorithms/Alarm.py +39 -0
  35. WMCore/Algorithms/MathAlgos.py +274 -0
  36. WMCore/Algorithms/MiscAlgos.py +67 -0
  37. WMCore/Algorithms/ParseXMLFile.py +115 -0
  38. WMCore/Algorithms/Permissions.py +27 -0
  39. WMCore/Algorithms/Singleton.py +58 -0
  40. WMCore/Algorithms/SubprocessAlgos.py +129 -0
  41. WMCore/Algorithms/__init__.py +7 -0
  42. WMCore/Cache/GenericDataCache.py +98 -0
  43. WMCore/Cache/WMConfigCache.py +572 -0
  44. WMCore/Cache/__init__.py +0 -0
  45. WMCore/Configuration.py +659 -0
  46. WMCore/DAOFactory.py +47 -0
  47. WMCore/DataStructs/File.py +177 -0
  48. WMCore/DataStructs/Fileset.py +140 -0
  49. WMCore/DataStructs/Job.py +182 -0
  50. WMCore/DataStructs/JobGroup.py +142 -0
  51. WMCore/DataStructs/JobPackage.py +49 -0
  52. WMCore/DataStructs/LumiList.py +734 -0
  53. WMCore/DataStructs/Mask.py +219 -0
  54. WMCore/DataStructs/MathStructs/ContinuousSummaryHistogram.py +197 -0
  55. WMCore/DataStructs/MathStructs/DiscreteSummaryHistogram.py +92 -0
  56. WMCore/DataStructs/MathStructs/SummaryHistogram.py +117 -0
  57. WMCore/DataStructs/MathStructs/__init__.py +0 -0
  58. WMCore/DataStructs/Pickleable.py +24 -0
  59. WMCore/DataStructs/Run.py +256 -0
  60. WMCore/DataStructs/Subscription.py +175 -0
  61. WMCore/DataStructs/WMObject.py +47 -0
  62. WMCore/DataStructs/WorkUnit.py +112 -0
  63. WMCore/DataStructs/Workflow.py +60 -0
  64. WMCore/DataStructs/__init__.py +8 -0
  65. WMCore/Database/CMSCouch.py +1430 -0
  66. WMCore/Database/ConfigDBMap.py +29 -0
  67. WMCore/Database/CouchMonitoring.py +450 -0
  68. WMCore/Database/CouchUtils.py +118 -0
  69. WMCore/Database/DBCore.py +198 -0
  70. WMCore/Database/DBCreator.py +113 -0
  71. WMCore/Database/DBExceptionHandler.py +59 -0
  72. WMCore/Database/DBFactory.py +117 -0
  73. WMCore/Database/DBFormatter.py +177 -0
  74. WMCore/Database/Dialects.py +13 -0
  75. WMCore/Database/ExecuteDAO.py +327 -0
  76. WMCore/Database/MongoDB.py +241 -0
  77. WMCore/Database/MySQL/Destroy.py +42 -0
  78. WMCore/Database/MySQL/ListUserContent.py +20 -0
  79. WMCore/Database/MySQL/__init__.py +9 -0
  80. WMCore/Database/MySQLCore.py +132 -0
  81. WMCore/Database/Oracle/Destroy.py +56 -0
  82. WMCore/Database/Oracle/ListUserContent.py +19 -0
  83. WMCore/Database/Oracle/__init__.py +9 -0
  84. WMCore/Database/ResultSet.py +44 -0
  85. WMCore/Database/Transaction.py +91 -0
  86. WMCore/Database/__init__.py +9 -0
  87. WMCore/Database/ipy_profile_couch.py +438 -0
  88. WMCore/GlobalWorkQueue/CherryPyThreads/CleanUpTask.py +29 -0
  89. WMCore/GlobalWorkQueue/CherryPyThreads/HeartbeatMonitor.py +105 -0
  90. WMCore/GlobalWorkQueue/CherryPyThreads/LocationUpdateTask.py +28 -0
  91. WMCore/GlobalWorkQueue/CherryPyThreads/ReqMgrInteractionTask.py +35 -0
  92. WMCore/GlobalWorkQueue/CherryPyThreads/__init__.py +0 -0
  93. WMCore/GlobalWorkQueue/__init__.py +0 -0
  94. WMCore/GroupUser/CouchObject.py +127 -0
  95. WMCore/GroupUser/Decorators.py +51 -0
  96. WMCore/GroupUser/Group.py +33 -0
  97. WMCore/GroupUser/Interface.py +73 -0
  98. WMCore/GroupUser/User.py +96 -0
  99. WMCore/GroupUser/__init__.py +11 -0
  100. WMCore/Lexicon.py +836 -0
  101. WMCore/REST/Auth.py +202 -0
  102. WMCore/REST/CherryPyPeriodicTask.py +166 -0
  103. WMCore/REST/Error.py +333 -0
  104. WMCore/REST/Format.py +642 -0
  105. WMCore/REST/HeartbeatMonitorBase.py +90 -0
  106. WMCore/REST/Main.py +636 -0
  107. WMCore/REST/Server.py +2435 -0
  108. WMCore/REST/Services.py +24 -0
  109. WMCore/REST/Test.py +120 -0
  110. WMCore/REST/Tools.py +38 -0
  111. WMCore/REST/Validation.py +250 -0
  112. WMCore/REST/__init__.py +1 -0
  113. WMCore/ReqMgr/DataStructs/RequestStatus.py +209 -0
  114. WMCore/ReqMgr/DataStructs/RequestType.py +13 -0
  115. WMCore/ReqMgr/DataStructs/__init__.py +0 -0
  116. WMCore/ReqMgr/__init__.py +1 -0
  117. WMCore/Services/AlertManager/AlertManagerAPI.py +111 -0
  118. WMCore/Services/AlertManager/__init__.py +0 -0
  119. WMCore/Services/CRIC/CRIC.py +238 -0
  120. WMCore/Services/CRIC/__init__.py +0 -0
  121. WMCore/Services/DBS/DBS3Reader.py +1044 -0
  122. WMCore/Services/DBS/DBSConcurrency.py +44 -0
  123. WMCore/Services/DBS/DBSErrors.py +112 -0
  124. WMCore/Services/DBS/DBSReader.py +23 -0
  125. WMCore/Services/DBS/DBSUtils.py +166 -0
  126. WMCore/Services/DBS/DBSWriterObjects.py +381 -0
  127. WMCore/Services/DBS/ProdException.py +133 -0
  128. WMCore/Services/DBS/__init__.py +8 -0
  129. WMCore/Services/FWJRDB/FWJRDBAPI.py +118 -0
  130. WMCore/Services/FWJRDB/__init__.py +0 -0
  131. WMCore/Services/HTTPS/HTTPSAuthHandler.py +66 -0
  132. WMCore/Services/HTTPS/__init__.py +0 -0
  133. WMCore/Services/LogDB/LogDB.py +201 -0
  134. WMCore/Services/LogDB/LogDBBackend.py +191 -0
  135. WMCore/Services/LogDB/LogDBExceptions.py +11 -0
  136. WMCore/Services/LogDB/LogDBReport.py +85 -0
  137. WMCore/Services/LogDB/__init__.py +0 -0
  138. WMCore/Services/MSPileup/__init__.py +0 -0
  139. WMCore/Services/MSUtils/MSUtils.py +54 -0
  140. WMCore/Services/MSUtils/__init__.py +0 -0
  141. WMCore/Services/McM/McM.py +173 -0
  142. WMCore/Services/McM/__init__.py +8 -0
  143. WMCore/Services/MonIT/Grafana.py +133 -0
  144. WMCore/Services/MonIT/__init__.py +0 -0
  145. WMCore/Services/PyCondor/PyCondorAPI.py +154 -0
  146. WMCore/Services/PyCondor/__init__.py +0 -0
  147. WMCore/Services/ReqMgr/ReqMgr.py +261 -0
  148. WMCore/Services/ReqMgr/__init__.py +0 -0
  149. WMCore/Services/ReqMgrAux/ReqMgrAux.py +419 -0
  150. WMCore/Services/ReqMgrAux/__init__.py +0 -0
  151. WMCore/Services/RequestDB/RequestDBReader.py +267 -0
  152. WMCore/Services/RequestDB/RequestDBWriter.py +39 -0
  153. WMCore/Services/RequestDB/__init__.py +0 -0
  154. WMCore/Services/Requests.py +624 -0
  155. WMCore/Services/Rucio/Rucio.py +1290 -0
  156. WMCore/Services/Rucio/RucioUtils.py +74 -0
  157. WMCore/Services/Rucio/__init__.py +0 -0
  158. WMCore/Services/RucioConMon/RucioConMon.py +121 -0
  159. WMCore/Services/RucioConMon/__init__.py +0 -0
  160. WMCore/Services/Service.py +400 -0
  161. WMCore/Services/StompAMQ/__init__.py +0 -0
  162. WMCore/Services/TagCollector/TagCollector.py +155 -0
  163. WMCore/Services/TagCollector/XMLUtils.py +98 -0
  164. WMCore/Services/TagCollector/__init__.py +0 -0
  165. WMCore/Services/UUIDLib.py +13 -0
  166. WMCore/Services/UserFileCache/UserFileCache.py +160 -0
  167. WMCore/Services/UserFileCache/__init__.py +8 -0
  168. WMCore/Services/WMAgent/WMAgent.py +63 -0
  169. WMCore/Services/WMAgent/__init__.py +0 -0
  170. WMCore/Services/WMArchive/CMSSWMetrics.py +526 -0
  171. WMCore/Services/WMArchive/DataMap.py +463 -0
  172. WMCore/Services/WMArchive/WMArchive.py +33 -0
  173. WMCore/Services/WMArchive/__init__.py +0 -0
  174. WMCore/Services/WMBS/WMBS.py +97 -0
  175. WMCore/Services/WMBS/__init__.py +0 -0
  176. WMCore/Services/WMStats/DataStruct/RequestInfoCollection.py +300 -0
  177. WMCore/Services/WMStats/DataStruct/__init__.py +0 -0
  178. WMCore/Services/WMStats/WMStatsPycurl.py +145 -0
  179. WMCore/Services/WMStats/WMStatsReader.py +445 -0
  180. WMCore/Services/WMStats/WMStatsWriter.py +273 -0
  181. WMCore/Services/WMStats/__init__.py +0 -0
  182. WMCore/Services/WMStatsServer/WMStatsServer.py +134 -0
  183. WMCore/Services/WMStatsServer/__init__.py +0 -0
  184. WMCore/Services/WorkQueue/WorkQueue.py +492 -0
  185. WMCore/Services/WorkQueue/__init__.py +0 -0
  186. WMCore/Services/__init__.py +8 -0
  187. WMCore/Services/pycurl_manager.py +574 -0
  188. WMCore/WMBase.py +50 -0
  189. WMCore/WMConnectionBase.py +164 -0
  190. WMCore/WMException.py +183 -0
  191. WMCore/WMExceptions.py +269 -0
  192. WMCore/WMFactory.py +76 -0
  193. WMCore/WMInit.py +377 -0
  194. WMCore/WMLogging.py +104 -0
  195. WMCore/WMSpec/ConfigSectionTree.py +442 -0
  196. WMCore/WMSpec/Persistency.py +135 -0
  197. WMCore/WMSpec/Steps/BuildMaster.py +87 -0
  198. WMCore/WMSpec/Steps/BuildTools.py +201 -0
  199. WMCore/WMSpec/Steps/Builder.py +97 -0
  200. WMCore/WMSpec/Steps/Diagnostic.py +89 -0
  201. WMCore/WMSpec/Steps/Emulator.py +62 -0
  202. WMCore/WMSpec/Steps/ExecuteMaster.py +208 -0
  203. WMCore/WMSpec/Steps/Executor.py +210 -0
  204. WMCore/WMSpec/Steps/StepFactory.py +213 -0
  205. WMCore/WMSpec/Steps/TaskEmulator.py +75 -0
  206. WMCore/WMSpec/Steps/Template.py +204 -0
  207. WMCore/WMSpec/Steps/Templates/AlcaHarvest.py +76 -0
  208. WMCore/WMSpec/Steps/Templates/CMSSW.py +613 -0
  209. WMCore/WMSpec/Steps/Templates/DQMUpload.py +59 -0
  210. WMCore/WMSpec/Steps/Templates/DeleteFiles.py +70 -0
  211. WMCore/WMSpec/Steps/Templates/LogArchive.py +84 -0
  212. WMCore/WMSpec/Steps/Templates/LogCollect.py +105 -0
  213. WMCore/WMSpec/Steps/Templates/StageOut.py +105 -0
  214. WMCore/WMSpec/Steps/Templates/__init__.py +10 -0
  215. WMCore/WMSpec/Steps/WMExecutionFailure.py +21 -0
  216. WMCore/WMSpec/Steps/__init__.py +8 -0
  217. WMCore/WMSpec/Utilities.py +63 -0
  218. WMCore/WMSpec/WMSpecErrors.py +12 -0
  219. WMCore/WMSpec/WMStep.py +347 -0
  220. WMCore/WMSpec/WMTask.py +1997 -0
  221. WMCore/WMSpec/WMWorkload.py +2288 -0
  222. WMCore/WMSpec/WMWorkloadTools.py +382 -0
  223. WMCore/WMSpec/__init__.py +9 -0
  224. WMCore/WorkQueue/DataLocationMapper.py +273 -0
  225. WMCore/WorkQueue/DataStructs/ACDCBlock.py +47 -0
  226. WMCore/WorkQueue/DataStructs/Block.py +48 -0
  227. WMCore/WorkQueue/DataStructs/CouchWorkQueueElement.py +148 -0
  228. WMCore/WorkQueue/DataStructs/WorkQueueElement.py +274 -0
  229. WMCore/WorkQueue/DataStructs/WorkQueueElementResult.py +152 -0
  230. WMCore/WorkQueue/DataStructs/WorkQueueElementsSummary.py +185 -0
  231. WMCore/WorkQueue/DataStructs/__init__.py +0 -0
  232. WMCore/WorkQueue/Policy/End/EndPolicyInterface.py +44 -0
  233. WMCore/WorkQueue/Policy/End/SingleShot.py +22 -0
  234. WMCore/WorkQueue/Policy/End/__init__.py +32 -0
  235. WMCore/WorkQueue/Policy/PolicyInterface.py +17 -0
  236. WMCore/WorkQueue/Policy/Start/Block.py +258 -0
  237. WMCore/WorkQueue/Policy/Start/Dataset.py +180 -0
  238. WMCore/WorkQueue/Policy/Start/MonteCarlo.py +131 -0
  239. WMCore/WorkQueue/Policy/Start/ResubmitBlock.py +171 -0
  240. WMCore/WorkQueue/Policy/Start/StartPolicyInterface.py +316 -0
  241. WMCore/WorkQueue/Policy/Start/__init__.py +34 -0
  242. WMCore/WorkQueue/Policy/__init__.py +57 -0
  243. WMCore/WorkQueue/WMBSHelper.py +772 -0
  244. WMCore/WorkQueue/WorkQueue.py +1237 -0
  245. WMCore/WorkQueue/WorkQueueBackend.py +750 -0
  246. WMCore/WorkQueue/WorkQueueBase.py +39 -0
  247. WMCore/WorkQueue/WorkQueueExceptions.py +44 -0
  248. WMCore/WorkQueue/WorkQueueReqMgrInterface.py +278 -0
  249. WMCore/WorkQueue/WorkQueueUtils.py +130 -0
  250. WMCore/WorkQueue/__init__.py +13 -0
  251. WMCore/Wrappers/JsonWrapper/JSONThunker.py +342 -0
  252. WMCore/Wrappers/JsonWrapper/__init__.py +7 -0
  253. WMCore/Wrappers/__init__.py +6 -0
  254. WMCore/__init__.py +10 -0
  255. wmglobalqueue-2.4.5.1.data/data/bin/wmc-dist-patch +15 -0
  256. wmglobalqueue-2.4.5.1.data/data/bin/wmc-dist-unpatch +8 -0
  257. wmglobalqueue-2.4.5.1.data/data/bin/wmc-httpd +3 -0
  258. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/.couchapprc +1 -0
  259. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/README.md +40 -0
  260. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/_attachments/index.html +264 -0
  261. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/_attachments/js/ElementInfoByWorkflow.js +96 -0
  262. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/_attachments/js/StuckElementInfo.js +57 -0
  263. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/_attachments/js/WorkloadInfoTable.js +80 -0
  264. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/_attachments/js/dataTable.js +70 -0
  265. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/_attachments/js/namespace.js +23 -0
  266. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/_attachments/style/main.css +75 -0
  267. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/couchapp.json +4 -0
  268. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/filters/childQueueFilter.js +13 -0
  269. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/filters/filterDeletedDocs.js +3 -0
  270. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/filters/queueFilter.js +11 -0
  271. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/language +1 -0
  272. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/lib/mustache.js +333 -0
  273. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/lib/validate.js +27 -0
  274. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/lib/workqueue_utils.js +61 -0
  275. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/lists/elementsDetail.js +28 -0
  276. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/lists/filter.js +86 -0
  277. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/lists/stuckElements.js +38 -0
  278. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/lists/workRestrictions.js +153 -0
  279. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/lists/workflowSummary.js +28 -0
  280. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/rewrites.json +73 -0
  281. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/shows/redirect.js +23 -0
  282. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/shows/status.js +40 -0
  283. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/templates/ElementSummaryByWorkflow.html +27 -0
  284. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/templates/StuckElementSummary.html +26 -0
  285. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/templates/TaskStatus.html +23 -0
  286. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/templates/WorkflowSummary.html +27 -0
  287. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/templates/partials/workqueue-common-lib.html +2 -0
  288. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/templates/partials/yui-lib-remote.html +16 -0
  289. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/templates/partials/yui-lib.html +18 -0
  290. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/updates/in-place.js +50 -0
  291. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/validate_doc_update.js +8 -0
  292. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/vendor/couchapp/_attachments/jquery.couch.app.js +235 -0
  293. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/vendor/couchapp/_attachments/jquery.pathbinder.js +173 -0
  294. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/activeData/map.js +8 -0
  295. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/activeData/reduce.js +2 -0
  296. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/activeParentData/map.js +8 -0
  297. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/activeParentData/reduce.js +2 -0
  298. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/activePileupData/map.js +8 -0
  299. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/activePileupData/reduce.js +2 -0
  300. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/analyticsData/map.js +11 -0
  301. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/analyticsData/reduce.js +1 -0
  302. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/availableByPriority/map.js +6 -0
  303. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/conflicts/map.js +5 -0
  304. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/elements/map.js +5 -0
  305. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/elementsByData/map.js +8 -0
  306. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/elementsByParent/map.js +8 -0
  307. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/elementsByParentData/map.js +8 -0
  308. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/elementsByPileupData/map.js +8 -0
  309. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/elementsByStatus/map.js +8 -0
  310. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/elementsBySubscription/map.js +6 -0
  311. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/elementsByWorkflow/map.js +8 -0
  312. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/elementsByWorkflow/reduce.js +3 -0
  313. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/elementsDetailByWorkflowAndStatus/map.js +26 -0
  314. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/jobInjectStatusByRequest/map.js +10 -0
  315. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/jobInjectStatusByRequest/reduce.js +1 -0
  316. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/jobStatusByRequest/map.js +6 -0
  317. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/jobStatusByRequest/reduce.js +1 -0
  318. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/jobsByChildQueueAndPriority/map.js +6 -0
  319. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/jobsByChildQueueAndPriority/reduce.js +1 -0
  320. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/jobsByChildQueueAndStatus/map.js +6 -0
  321. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/jobsByChildQueueAndStatus/reduce.js +1 -0
  322. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/jobsByRequest/map.js +6 -0
  323. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/jobsByRequest/reduce.js +1 -0
  324. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/jobsByStatus/map.js +6 -0
  325. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/jobsByStatus/reduce.js +1 -0
  326. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/jobsByStatusAndPriority/map.js +6 -0
  327. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/jobsByStatusAndPriority/reduce.js +1 -0
  328. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/openRequests/map.js +6 -0
  329. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/recent-items/map.js +5 -0
  330. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/siteWhitelistByRequest/map.js +6 -0
  331. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/siteWhitelistByRequest/reduce.js +1 -0
  332. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/specsByWorkflow/map.js +5 -0
  333. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/stuckElements/map.js +38 -0
  334. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/wmbsInjectStatusByRequest/map.js +12 -0
  335. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/wmbsInjectStatusByRequest/reduce.js +3 -0
  336. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/wmbsUrl/map.js +6 -0
  337. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/wmbsUrl/reduce.js +2 -0
  338. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/wmbsUrlByRequest/map.js +6 -0
  339. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/wmbsUrlByRequest/reduce.js +2 -0
  340. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/workflowSummary/map.js +9 -0
  341. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/workflowSummary/reduce.js +10 -0
  342. wmglobalqueue-2.4.5.1.dist-info/METADATA +26 -0
  343. wmglobalqueue-2.4.5.1.dist-info/RECORD +347 -0
  344. wmglobalqueue-2.4.5.1.dist-info/WHEEL +5 -0
  345. wmglobalqueue-2.4.5.1.dist-info/licenses/LICENSE +202 -0
  346. wmglobalqueue-2.4.5.1.dist-info/licenses/NOTICE +16 -0
  347. wmglobalqueue-2.4.5.1.dist-info/top_level.txt +2 -0
@@ -0,0 +1,445 @@
1
+ from __future__ import division, print_function
2
+
3
+ import time
4
+
5
+ from builtins import object
6
+ from future.utils import viewitems
7
+
8
+ import logging
9
+
10
+ from Utils.IteratorTools import nestedDictUpdate, grouper
11
+ from WMCore.Database.CMSCouch import CouchServer
12
+ from WMCore.Lexicon import splitCouchServiceURL, sanitizeURL
13
+ from WMCore.Services.RequestDB.RequestDBReader import RequestDBReader
14
+ from WMCore.Services.WMStats.DataStruct.RequestInfoCollection import RequestInfo
15
+ from WMCore.ReqMgr.DataStructs.RequestStatus import T0_ACTIVE_STATUS
16
+ from WMCore.Services.WMStats.WMStatsPycurl import getTaskJobSummaryByRequestPycurl
17
+
18
+
19
+ REQUEST_PROPERTY_MAP = {
20
+ "_id": "_id",
21
+ "InputDataset": "inputdataset",
22
+ "PrepID": "prep_id",
23
+ "Group": "group",
24
+ "RequestDate": "request_date",
25
+ "Campaign": "campaign",
26
+ "RequestName": "workflow",
27
+ "RequestorDN": "user_dn",
28
+ "RequestPriority": "priority",
29
+ "Requestor": "requestor",
30
+ "RequestType": "request_type",
31
+ "DbsUrl": "dbs_url",
32
+ "CMSSWVersion": "cmssw",
33
+ "OutputDatasets": "outputdatasets",
34
+ "RequestTransition": "request_status", # Status: status, UpdateTime: update_time
35
+ "SiteWhitelist": "site_white_list",
36
+ "Team": "team",
37
+ "TotalEstimatedJobs": "total_jobs",
38
+ "TotalInputEvents": "input_events",
39
+ "TotalInputLumis": "input_lumis",
40
+ "TotalInputFiles": "input_num_files",
41
+ "Run": "run",
42
+ # Status and UpdateTime is under "RequestTransition"
43
+ "Status": "status",
44
+ "UpdateTime": "update_time"
45
+ }
46
+
47
+
48
+ def convertToLegacyFormat(requestDoc):
49
+ converted = {}
50
+ for key, value in viewitems(requestDoc):
51
+
52
+ if key == "RequestTransition":
53
+ newValue = []
54
+ for transDict in value:
55
+ newItem = {}
56
+ for transKey, transValue in viewitems(transDict):
57
+ newItem[REQUEST_PROPERTY_MAP.get(transKey, transKey)] = transValue
58
+ newValue.append(newItem)
59
+ value = newValue
60
+
61
+ converted[REQUEST_PROPERTY_MAP.get(key, key)] = value
62
+
63
+ return converted
64
+
65
+
66
+ class WMStatsReader(object):
67
+
68
+ def __init__(self, couchURL, appName="WMStats", reqdbURL=None,
69
+ reqdbCouchApp="ReqMgr", logger=None):
70
+ self._sanitizeURL(couchURL)
71
+ # set the connection for local couchDB call
72
+ self._commonInit(couchURL, appName)
73
+ if reqdbURL:
74
+ self.reqDB = RequestDBReader(reqdbURL, reqdbCouchApp)
75
+ else:
76
+ self.reqDB = None
77
+ self.logger = logger if logger else logging.getLogger()
78
+ self.serviceOpts = {"couchURL": self.couchURL,
79
+ "dbName": self.dbName,
80
+ "couchapp": self.couchapp}
81
+
82
+ def _sanitizeURL(self, couchURL):
83
+ return sanitizeURL(couchURL)['url']
84
+
85
+ def _commonInit(self, couchURL, appName="WMStats"):
86
+ """
87
+ setting up comon variables for inherited class.
88
+ inherited class should call this in their init function
89
+ """
90
+
91
+ self.couchURL, self.dbName = splitCouchServiceURL(couchURL)
92
+ self.couchServer = CouchServer(self.couchURL)
93
+ self.couchDB = self.couchServer.connectDatabase(self.dbName, False)
94
+ self.couchapp = appName
95
+ self.defaultStale = {"stale": "update_after"}
96
+
97
+ def setDefaultStaleOptions(self, options):
98
+ if not options:
99
+ options = {}
100
+ if 'stale' not in options:
101
+ options.update(self.defaultStale)
102
+ return options
103
+
104
+ def getLatestJobInfoByRequests(self, requestNames):
105
+ jobInfoByRequestAndAgent = {}
106
+
107
+ if len(requestNames) > 0:
108
+ requestAndAgentKey = self._getRequestAndAgent(requestNames)
109
+ jobInfoByRequestAndAgent = self._getLatestJobInfo(requestAndAgentKey)
110
+ return jobInfoByRequestAndAgent
111
+
112
+ def _updateRequestInfoWithJobInfo(self, requestInfo):
113
+ if requestInfo:
114
+ jobInfoByRequestAndAgent = self.getLatestJobInfoByRequests(list(requestInfo))
115
+ self._combineRequestAndJobData(requestInfo, jobInfoByRequestAndAgent)
116
+
117
+ def _getCouchView(self, view, options, keys=None):
118
+ keys = keys or []
119
+ options = self.setDefaultStaleOptions(options)
120
+
121
+ if keys and isinstance(keys, str):
122
+ keys = [keys]
123
+ return self.couchDB.loadView(self.couchapp, view, options, keys)
124
+
125
+ def _formatCouchData(self, data, key="id"):
126
+ result = {}
127
+ for row in data['rows']:
128
+ if 'error' in row:
129
+ continue
130
+ if "doc" in row:
131
+ result[row[key]] = row["doc"]
132
+ else:
133
+ result[row[key]] = None
134
+ return result
135
+
136
+ def _combineRequestAndJobData(self, requestData, jobData):
137
+ """
138
+ update the request data with job info
139
+ requestData['AgentJobInfo'] = {'vocms234.cern.ch:9999': {"_id":"d1d11dfcb30e0ab47db42007cb6fb847",
140
+ "_rev":"1-8abfaa2de822ed081cb8d174e3e2c003",
141
+ "status":{"inWMBS":334,"success":381,"submitted":{"retry":2,"pending":2},"failure":{"exception":3}},
142
+ "agent_team":"testbed-integration","workflow":"amaltaro_OracleUpgrade_TEST_HG1401_140220_090116_6731",
143
+ "timestamp":1394738860,"sites":{"T2_CH_CERN_AI":{"submitted":{"retry":1,"pending":1}},
144
+ "T2_CH_CERN":{"success":6,"submitted":{"retry":1,"pending":1}},
145
+ "T2_DE_DESY":{"failure":{"exception":3},"success":375}},
146
+ "agent":"WMAgent",
147
+ "tasks":
148
+ {"/amaltaro_OracleUpgrade_TEST_HG1401_140220_090116_6731/Production":
149
+ {"status":{"failure":{"exception":3},"success":331},
150
+ "sites":{"T2_DE_DESY": {"success":325,"wrappedTotalJobTime":11305908,
151
+ "dataset":{},"failure":{"exception":3},
152
+ "cmsRunCPUPerformance":{"totalJobCPU":10869688.8,
153
+ "totalEventCPU":10832426.7,
154
+ "totalJobTime":11255865.9},
155
+ "inputEvents":0},
156
+ "T2_CH_CERN":{"success":6,"wrappedTotalJobTime":176573,
157
+ "dataset":{},
158
+ "cmsRunCPUPerformance":{"totalJobCPU":167324.8,
159
+ "totalEventCPU":166652.1,
160
+ "totalJobTime":174975.7},
161
+ "inputEvents":0}},
162
+ "subscription_status":{"updated":1393108089, "finished":2, "total":2,"open":0},
163
+ "jobtype":"Production"},
164
+ "/amaltaro_OracleUpgrade_TEST_HG1401_140220_090116_6731/Production/ProductionMergeRAWSIMoutput/ProductionRAWSIMoutputMergeLogCollect":
165
+ {"jobtype":"LogCollect",
166
+ "subscription_status":{"updated":1392885768,
167
+ "finished":0,
168
+ "total":1,"open":1}},
169
+ "/amaltaro_OracleUpgrade_TEST_HG1401_140220_090116_6731/Production/ProductionMergeRAWSIMoutput":
170
+ {"status":{"success":41,"submitted":{"retry":1,"pending":1}},
171
+ "sites":{"T2_DE_DESY":{"datasetStat":{"totalLumis":973,"events":97300,"size":105698406915},
172
+ "success":41,"wrappedTotalJobTime":9190,
173
+ "dataset":{"/GluGluToHTohhTo4B_mH-350_mh-125_8TeV-pythia6-tauola/Summer12-OracleUpgrade_TEST_ALAN_HG1401-v1/GEN-SIM":
174
+ {"totalLumis":973,"events":97300,"size":105698406915}},
175
+ "cmsRunCPUPerformance":{"totalJobCPU":548.92532,"totalEventCPU":27.449808,"totalJobTime":2909.92125},
176
+ "inputEvents":97300},
177
+ "T2_CH_CERN":{"submitted":{"retry":1,"pending":1}}},
178
+ "subscription_status":{"updated":1392885768,"finished":0,"total":1,"open":1},
179
+ "jobtype":"Merge"},
180
+ "agent_url":"vocms231.cern.ch:9999",
181
+ "type":"agent_request"}}
182
+ """
183
+ if jobData:
184
+ for row in jobData["rows"]:
185
+ # condition checks if documents are deleted between calls.
186
+ # just ignore in that case
187
+ if row["doc"]:
188
+ jobInfo = requestData[row["doc"]["workflow"]]
189
+ jobInfo.setdefault("AgentJobInfo", {})
190
+ jobInfo["AgentJobInfo"][row["doc"]["agent_url"]] = row["doc"]
191
+
192
+ def _getRequestAndAgent(self, filterRequest=None):
193
+ """
194
+ returns the [['request_name', 'agent_url'], ....]
195
+ """
196
+ options = {}
197
+ options["reduce"] = True
198
+ options["group"] = True
199
+ result = self._getCouchView("requestAgentUrl", options)
200
+
201
+ if filterRequest is None:
202
+ keys = [row['key'] for row in result["rows"]]
203
+ else:
204
+ keys = [row['key'] for row in result["rows"] if row['key'][0] in filterRequest]
205
+ return keys
206
+
207
+ def _getLatestJobInfo(self, keys):
208
+ """
209
+ Given a list of lists as keys, in the format of:
210
+ [['request_name', 'agent_url'], ['request_name2', 'agent_url2'], ....]
211
+ The result format from the latestRequest view is:
212
+ {u'offset': 527,
213
+ u'rows': [{u'doc': {u'_rev': u'32-6027014210',
214
+ ...
215
+ u'id': u'cmsgwms-submit6.fnal.gov-cmsunified_ACDC0_task_BTV-RunIISummer19UL18wmLHEGEN-00004__v1_T_200507_162125_3670',
216
+ u'key': [u'cmsunified_ACDC0_task_BTV-RunIISummer19UL18wmLHEGEN-00004__v1_T_200507_162125_3670',
217
+ u'cmsgwms-submit6.fnal.gov'],
218
+ u'value': None}],
219
+ u'total_rows': 49606}
220
+ """
221
+ if not keys:
222
+ return []
223
+ options = {}
224
+ options["include_docs"] = True
225
+ options["reduce"] = False
226
+ finalResults = {}
227
+ # magic number: 5000 keys (need to check which number is optimal)
228
+ for sliceKeys in grouper(keys, 5000):
229
+ self.logger.info("Querying latestRequest with %d keys", len(sliceKeys))
230
+ result = self._getCouchView("latestRequest", options, sliceKeys)
231
+ if not finalResults and result:
232
+ finalResults = result
233
+ elif result.get('rows'):
234
+ finalResults['rows'].extend(result['rows'])
235
+ return finalResults
236
+
237
+ def _getAllDocsByIDs(self, ids, include_docs=True):
238
+ """
239
+ keys is [id, ....]
240
+ returns document
241
+ """
242
+ if len(ids) == 0:
243
+ return None
244
+ options = {}
245
+ options["include_docs"] = include_docs
246
+ result = self.couchDB.allDocs(options, ids)
247
+
248
+ return result
249
+
250
+ def _getAgentInfo(self):
251
+ """
252
+ returns all the agents status on wmstats
253
+ """
254
+ options = {}
255
+ result = self._getCouchView("agentInfo", options)
256
+
257
+ return result
258
+
259
+ def agentsByTeam(self, filterDrain=False):
260
+ """
261
+ return a dictionary like {team:#agents,...}
262
+ """
263
+ result = self._getAgentInfo()
264
+ response = dict()
265
+
266
+ for agentInfo in result["rows"]:
267
+ #filtering empty string
268
+ team = agentInfo['value']['agent_team']
269
+ if not team:
270
+ continue
271
+
272
+ response.setdefault(team, 0)
273
+ if filterDrain:
274
+ if not agentInfo['value'].get('drain_mode', False):
275
+ response[team] += 1
276
+ else:
277
+ response[team] += 1
278
+
279
+ return response
280
+
281
+ def getServerInstance(self):
282
+ return self.couchServer
283
+
284
+ def getDBInstance(self):
285
+ return self.couchDB
286
+
287
+ def getRequestDBInstance(self):
288
+ return self.reqDB
289
+
290
+ def getHeartbeat(self):
291
+ try:
292
+ return self.couchDB.info()
293
+ except Exception as ex:
294
+ return {'error_message': str(ex)}
295
+
296
+ def getRequestByNames(self, requestNames, jobInfoFlag=False):
297
+ """
298
+ To use this function reqDBURL need to be set when wmstats initialized.
299
+ This will be deplicated so please don use this.
300
+ """
301
+ requestInfo = self.reqDB.getRequestByNames(requestNames, True)
302
+
303
+ if jobInfoFlag:
304
+ # get request and agent info
305
+ self._updateRequestInfoWithJobInfo(requestInfo)
306
+ return requestInfo
307
+
308
+ def getActiveData(self, listStatuses, jobInfoFlag=False):
309
+ return self.getRequestByStatus(listStatuses, jobInfoFlag)
310
+
311
+ def getT0ActiveData(self, jobInfoFlag=False):
312
+
313
+ return self.getRequestByStatus(T0_ACTIVE_STATUS, jobInfoFlag)
314
+
315
+ def getRequestByStatus(self, statusList, jobInfoFlag=False, limit=None, skip=None,
316
+ legacyFormat=False):
317
+
318
+ """
319
+ To use this function reqDBURL need to be set when wmstats initialized.
320
+ This will be deplicated so please don use this.
321
+ If legacyFormat is True convert data to old wmstats format from current reqmgr format.
322
+ Shouldn't be set to True unless existing code breaks
323
+ """
324
+ results = dict()
325
+ for status in statusList:
326
+ self.logger.info("Fetching workflows by status from ReqMgr2, status: %s", status)
327
+ requestInfo = self.reqDB.getRequestByStatus(status, True, limit, skip)
328
+ self.logger.info("Found %d workflows in status: %s", len(requestInfo), status)
329
+
330
+ if legacyFormat:
331
+ # convert the format to wmstats old format
332
+ for requestName, doc in viewitems(requestInfo):
333
+ requestInfo[requestName] = convertToLegacyFormat(doc)
334
+ results.update(requestInfo)
335
+
336
+ # now update these requests with agent information too
337
+ if results and jobInfoFlag:
338
+ self.logger.info("Now updating these requests with job info...")
339
+ self._updateRequestInfoWithJobInfo(results)
340
+
341
+ return results
342
+
343
+ def getRequestSummaryWithJobInfo(self, requestName):
344
+ """
345
+ get request info with job status
346
+ """
347
+ requestInfo = self.reqDB.getRequestByNames(requestName)
348
+ self._updateRequestInfoWithJobInfo(requestInfo)
349
+ return requestInfo
350
+
351
+ def getArchivedRequests(self):
352
+ """
353
+ get list of archived workflow in wmstats db.
354
+ """
355
+
356
+ options = {"group_level": 1, "reduce": True}
357
+
358
+ results = self._getCouchView("allWorkflows", options)['rows']
359
+ requestNames = [x['key'] for x in results]
360
+
361
+ workflowDict = self.reqDB.getStatusAndTypeByRequest(requestNames)
362
+ archivedRequests = []
363
+ for request, value in viewitems(workflowDict):
364
+ if value[0].endswith("-archived"):
365
+ archivedRequests.append(request)
366
+
367
+ return archivedRequests
368
+
369
+ def isWorkflowCompletedWithLogCollectAndCleanUp(self, requestName):
370
+ """
371
+ check whether workflow is completed including LogCollect and CleanUp tasks
372
+ TODO: If the parent task all failed and next task are not created at all,
373
+ It can't detect complete status.
374
+ If the one of the task doesn't contain any jobs, it will return False
375
+ """
376
+
377
+ requestInfo = self.getRequestSummaryWithJobInfo(requestName)
378
+ reqInfoInstance = RequestInfo(requestInfo[requestName])
379
+ return reqInfoInstance.isWorkflowFinished()
380
+
381
+ def getTaskJobSummaryByRequest(self, requestName, sampleSize=1, usePycurl=True):
382
+ reqStart = time.time()
383
+ options = {'reduce': True, 'group_level': 5, 'startkey': [requestName],
384
+ 'endkey': [requestName, {}]}
385
+ results = self._getCouchView("jobsByStatusWorkflow", options)
386
+
387
+ jobDetails = {}
388
+ if usePycurl is True:
389
+ jobDetails = getTaskJobSummaryByRequestPycurl(results, sampleSize, self.serviceOpts)
390
+ else:
391
+ # then it is sequential
392
+ for row in results['rows']:
393
+ # row["key"] = ['workflow', 'task', 'jobstatus', 'exitCode', 'site']
394
+ startKey = row["key"][:4]
395
+ endKey = []
396
+ site = row["key"][4]
397
+ if site:
398
+ startKey.append(site)
399
+
400
+ endKey.extend(startKey)
401
+ endKey.append({})
402
+ numOfError = row["value"]
403
+
404
+ jobInfo = self.jobDetailByTasks(startKey, endKey, numOfError, sampleSize)
405
+ jobDetails = nestedDictUpdate(jobDetails, jobInfo)
406
+ callRuntime = round((time.time() - reqStart), 3)
407
+ msg = f"Retrieved job details (pycurl mode: {usePycurl}) for {requestName} in "
408
+ msg += f"{callRuntime} seconds, with a total of {len(results['rows']) + 1} CouchDB calls"
409
+ print(msg)
410
+ return jobDetails
411
+
412
+ def jobDetailByTasks(self, startKey, endKey, numOfError, limit=1):
413
+ options = {'include_docs': True, 'reduce': False,
414
+ 'startkey': startKey, 'endkey': endKey,
415
+ 'limit': limit}
416
+ result = self._getCouchView("jobsByStatusWorkflow", options)
417
+ jobInfoDoc = {}
418
+ for row in result['rows']:
419
+ keys = row['key']
420
+ workflow = keys[0]
421
+ task = keys[1]
422
+ jobStatus = keys[2]
423
+ exitCode = keys[3]
424
+ site = keys[4]
425
+
426
+ jobInfoDoc.setdefault(workflow, {})
427
+ jobInfoDoc[workflow].setdefault(task, {})
428
+ jobInfoDoc[workflow][task].setdefault(jobStatus, {})
429
+ jobInfoDoc[workflow][task][jobStatus].setdefault(exitCode, {})
430
+ jobInfoDoc[workflow][task][jobStatus][exitCode].setdefault(site, {})
431
+ finalStruct = jobInfoDoc[workflow][task][jobStatus][exitCode][site]
432
+ finalStruct["errorCount"] = numOfError
433
+ finalStruct.setdefault("samples", [])
434
+ finalStruct["samples"].append(row["doc"])
435
+
436
+ return jobInfoDoc
437
+
438
+ def getAllAgentRequestRevByID(self, agentURL):
439
+ options = {"reduce": False}
440
+ results = self._getCouchView("byAgentURL", options, keys=[agentURL])
441
+ idRevMap = {}
442
+ for row in results['rows']:
443
+ idRevMap[row['id']] = row['value']['rev']
444
+
445
+ return idRevMap