From e3472967630d9f3c1daf0749b8cc69724e5b3fe6 Mon Sep 17 00:00:00 2001
From: Chris Burr <christopher.burr@cern.ch>
Date: Sat, 13 Apr 2024 17:23:15 +0200
Subject: [PATCH] fix: Avoid relying on dictionary order in JSON output of
 dirac-production-request-submit

---
 .../dirac_production_request_submit.py        | 28 ++++++++++---------
 1 file changed, 15 insertions(+), 13 deletions(-)

diff --git a/src/LHCbDIRAC/ProductionManagementSystem/scripts/dirac_production_request_submit.py b/src/LHCbDIRAC/ProductionManagementSystem/scripts/dirac_production_request_submit.py
index feea9f25ee..2656046171 100644
--- a/src/LHCbDIRAC/ProductionManagementSystem/scripts/dirac_production_request_submit.py
+++ b/src/LHCbDIRAC/ProductionManagementSystem/scripts/dirac_production_request_submit.py
@@ -68,7 +68,7 @@ def main():
 
 def submitProductionRequests(
     productionRequests: list[ProductionBase], *, dryRun=True, createFiletypes
-) -> dict[int, list[int]]:
+) -> list[tuple[int, int | None, dict[str, int | None]]]:
     """Submit a collection of production requests
 
     :param productionRequests: List of production requests to submit
@@ -92,14 +92,15 @@ def submitProductionRequests(
                 returnValueOrRaise(BookkeepingClient().insertFileTypes(missingFileType.upper(), "", "1"))
 
     # Create steps and submit production requests
-    productionIDs = {}
-    for i, prod in enumerate(productionRequests, start=1):
-        gLogger.always("Considering production", f"{i} of {len(productionRequests)}: {prod.name}")
-        productionIDs.update(_submitProductionRequests(prod, dryRun=dryRun))
+    productionIDs = []
+    for i, prod in enumerate(productionRequests):
+        gLogger.always("Considering production", f"{i+1} of {len(productionRequests)}: {prod.name}")
+        prod_id, sub_prod_id = _submitProductionRequests(prod, dryRun=dryRun)
+        productionIDs.append([i, prod_id, sub_prod_id])
     return productionIDs
 
 
-def _submitProductionRequests(prod: ProductionBase, *, dryRun=True) -> dict[int, list[int]]:
+def _submitProductionRequests(prod: ProductionBase, *, dryRun=True) -> tuple[int | None, dict[str, int | None]]:
     from LHCbDIRAC.BookkeepingSystem.Client.BookkeepingClient import BookkeepingClient
     from LHCbDIRAC.ProductionManagementSystem.Client.ProductionRequestClient import ProductionRequestClient
     from LHCbDIRAC.ProductionManagementSystem.Utilities.Models import ProductionStates
@@ -134,23 +135,24 @@ def _submitProductionRequests(prod: ProductionBase, *, dryRun=True) -> dict[int,
     if not dryRun:
         prod.id = returnValueOrRaise(prc.createProductionRequest(request_info))
 
-    sub_prod_ids = []
+    sub_prod_ids = {}
     for sub_prod in sub_productions:
         if prod.state != ProductionStates.NEW:
             raise RuntimeError("Can only add sub productions to productions in state 'New'")
         sub_prod_info = make_subprod_legacy_dict(sub_prod, prod.id)
         gLogger.verbose("Creating production sub request with", request_info)
-        if not dryRun:
-            sub_prod_id = returnValueOrRaise(prc.createProductionRequest(sub_prod_info))
-            sub_prod_ids.append(sub_prod_id)
+        sub_prod_id = None if dryRun else returnValueOrRaise(prc.createProductionRequest(sub_prod_info))
+
+        event_type = sub_prod["EventType"]
+        if event_type in sub_prod_ids:
+            raise NotImplementedError(f"Duplicate event type {event_type} in sub productions")
+        sub_prod_ids[event_type] = sub_prod_id
 
     prod.state = ProductionStates.SUBMITTED
-    productionIDs = {}
     if not dryRun:
         returnValueOrRaise(prc.updateProductionRequest(prod.id, {"RequestState": prod.state.value}))
         gLogger.always(f"Submitted production {prod.id} with sub productions {sub_prod_ids}")
-        productionIDs[prod.id] = sub_prod_ids
-    return productionIDs
+    return prod.id, sub_prod_ids
 
 
 if __name__ == "__main__":
-- 
GitLab