From a1b9eb8dc88f3e6d951f54dd0ac89bbfc71f3b70 Mon Sep 17 00:00:00 2001 From: XingY Date: Sun, 26 Oct 2025 15:03:42 -0700 Subject: [PATCH 1/5] Add test --- src/org/labkey/test/util/AuditLogHelper.java | 76 +++++++++++++++++++- 1 file changed, 75 insertions(+), 1 deletion(-) diff --git a/src/org/labkey/test/util/AuditLogHelper.java b/src/org/labkey/test/util/AuditLogHelper.java index a5483f2793..927ebb7ae0 100644 --- a/src/org/labkey/test/util/AuditLogHelper.java +++ b/src/org/labkey/test/util/AuditLogHelper.java @@ -4,6 +4,7 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.json.JSONException; +import org.json.JSONObject; import org.labkey.api.collections.CaseInsensitiveHashMap; import org.labkey.remoteapi.CommandException; import org.labkey.remoteapi.Connection; @@ -101,7 +102,8 @@ public enum AuditEvent QUERY_UPDATE_AUDIT_EVENT("QueryUpdateAuditEvent"), SAMPLE_TIMELINE_EVENT("SampleTimelineEvent"), SAMPLE_WORKFLOW_AUDIT_EVENT("SamplesWorkflowAuditEvent"), - SOURCES_AUDIT_EVENT("SourcesAuditEvent"); // available with SampleManagement module + SOURCES_AUDIT_EVENT("SourcesAuditEvent"), + TRANSACTION_AUDIT_EVENT("TransactionAuditEvent"); // available with SampleManagement module private final String _name; @@ -116,6 +118,22 @@ public String getName() } } + public enum TransactionDetail + { + AuditEvents(), + ImportFileName(), + ClientLibrary, + Product, + Action, + QueryCommand, + DataIteratorUsed, + ImportOptions, + EditMethod, + RequestSource, + ETL, + FileWatcher; + } + public Integer getLatestAuditRowId(String auditTable) throws IOException, CommandException { String rowId = "rowId"; @@ -233,6 +251,49 @@ public void checkAuditEventValuesForTransactionId(String containerPath, AuditEve } } + public Map getTransactionAuditLogDetails(Integer transactionAuditId) + { + Connection cn = WebTestHelper.getRemoteApiConnection(); + SelectRowsCommand cmd = new SelectRowsCommand("auditLog", "TransactionAuditEvent"); + cmd.setRequiredVersion(9.1); + cmd.setColumns(Arrays.asList("TransactionDetails")); + cmd.addFilter("RowId", transactionAuditId, Filter.Operator.EQUAL); + cmd.setContainerFilter(ContainerFilter.AllFolders); + + Map event = executeSelectCommand(cn, cmd).get(0); + String detailJSON = getLogColumnValue(event, "TransactionDetails"); + log("TransactionAuditEvent Details: " + detailJSON); + if (detailJSON == null || detailJSON.isEmpty()) + return Collections.emptyMap(); + + return new JSONObject(detailJSON).toMap(); + } + + public void checkLastTransactionAuditLogDetails(String containerPath, Map expectedDetails) + { + Integer transactionAuditId = getLastTransactionId(containerPath); + if (transactionAuditId == null) + fail("No TransactionAuditEvent found in container: " + containerPath); + checkTransactionAuditLogDetails(transactionAuditId, expectedDetails); + } + + public void checkTransactionAuditLogDetails(Integer transactionAuditId, Map expectedDetails) + { + Map actualDetails = getTransactionAuditLogDetails(transactionAuditId); + assertEquals("Unexpected number of events for transactionId " + transactionAuditId, expectedDetails.size(), actualDetails.size()); + for (TransactionDetail key : expectedDetails.keySet()) + { + assertTrue("Expected detail key not found: " + key, actualDetails.containsKey(key.name())); + if (TransactionDetail.RequestSource.name().equals(key.name())) + { + String expectedValue = expectedDetails.get(key).toString(); + String actualValue = actualDetails.get(key.name()) != null ? actualDetails.get(key.name()).toString() : null; + assertTrue("Detail value for key " + key + " not as expected", actualValue != null && actualValue.startsWith(expectedValue)); + } + else + assertEquals("Detail value for key " + key + " not as expected", expectedDetails.get(key), actualDetails.get(key.name())); + } + } /** * Check the number of diffs in the audit event. This is a helper function to check the number of diffs in the * newRecordMap for an audit entry. If a transactionId is provided, it will check all rows for that @@ -308,6 +369,19 @@ public Integer getLastTransactionId(String containerPath, AuditEvent auditEventN } } + public Integer getLastTransactionId(String containerPath) + { + try + { + List> events = getAuditLogsFromLKS(containerPath, AuditEvent.TRANSACTION_AUDIT_EVENT, List.of("RowId"), Collections.emptyList(), 1, ContainerFilter.CurrentAndSubfolders).getRows(); + return events.size() == 1 ? (Integer) events.get(0).get("RowId") : null; + } + catch (Exception e) + { + throw new RuntimeException(e); + } + } + public Integer getLastEventId(String containerPath, AuditEvent auditEventName) { try From 0b3071c82854c3a5eb1d020ccec78a404a954abe Mon Sep 17 00:00:00 2001 From: XingY Date: Wed, 29 Oct 2025 15:57:04 -0700 Subject: [PATCH 2/5] add test for ETL and file watcher --- src/org/labkey/test/util/AuditLogHelper.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/org/labkey/test/util/AuditLogHelper.java b/src/org/labkey/test/util/AuditLogHelper.java index 927ebb7ae0..48bb9f900b 100644 --- a/src/org/labkey/test/util/AuditLogHelper.java +++ b/src/org/labkey/test/util/AuditLogHelper.java @@ -100,6 +100,7 @@ public enum AuditEvent PLATE_DATA_AUDIT_EVENT("PlateDataAuditEvent"), // available in Biologics module PLATE_SET_AUDIT_EVENT("PlateSetEvent"), // available in Biologics module QUERY_UPDATE_AUDIT_EVENT("QueryUpdateAuditEvent"), + SAMPLE_SET_AUDIT_EVENT("SampleSetAuditEvent"), SAMPLE_TIMELINE_EVENT("SampleTimelineEvent"), SAMPLE_WORKFLOW_AUDIT_EVENT("SamplesWorkflowAuditEvent"), SOURCES_AUDIT_EVENT("SourcesAuditEvent"), From d9daffaaf0a3e8b539ce8d6eb0cf5e483a15c7af Mon Sep 17 00:00:00 2001 From: XingY Date: Sat, 1 Nov 2025 20:22:16 -0700 Subject: [PATCH 3/5] wire up addSamples action --- src/org/labkey/test/util/AuditLogHelper.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/org/labkey/test/util/AuditLogHelper.java b/src/org/labkey/test/util/AuditLogHelper.java index 48bb9f900b..47991f3411 100644 --- a/src/org/labkey/test/util/AuditLogHelper.java +++ b/src/org/labkey/test/util/AuditLogHelper.java @@ -289,7 +289,7 @@ public void checkTransactionAuditLogDetails(Integer transactionAuditId, Map Date: Sun, 2 Nov 2025 07:28:15 -0800 Subject: [PATCH 4/5] fix comment --- src/org/labkey/test/util/AuditLogHelper.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/org/labkey/test/util/AuditLogHelper.java b/src/org/labkey/test/util/AuditLogHelper.java index 47991f3411..5bfb838f46 100644 --- a/src/org/labkey/test/util/AuditLogHelper.java +++ b/src/org/labkey/test/util/AuditLogHelper.java @@ -103,8 +103,8 @@ public enum AuditEvent SAMPLE_SET_AUDIT_EVENT("SampleSetAuditEvent"), SAMPLE_TIMELINE_EVENT("SampleTimelineEvent"), SAMPLE_WORKFLOW_AUDIT_EVENT("SamplesWorkflowAuditEvent"), - SOURCES_AUDIT_EVENT("SourcesAuditEvent"), - TRANSACTION_AUDIT_EVENT("TransactionAuditEvent"); // available with SampleManagement module + SOURCES_AUDIT_EVENT("SourcesAuditEvent"), // available with SampleManagement module + TRANSACTION_AUDIT_EVENT("TransactionAuditEvent"); private final String _name; From 166e4a6d346ed5b046aaee7ae9da87e29dd5dfa0 Mon Sep 17 00:00:00 2001 From: XingY Date: Sun, 2 Nov 2025 07:30:18 -0800 Subject: [PATCH 5/5] fix comment --- src/org/labkey/test/util/AuditLogHelper.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/org/labkey/test/util/AuditLogHelper.java b/src/org/labkey/test/util/AuditLogHelper.java index 5bfb838f46..82c01a8f64 100644 --- a/src/org/labkey/test/util/AuditLogHelper.java +++ b/src/org/labkey/test/util/AuditLogHelper.java @@ -121,8 +121,8 @@ public String getName() public enum TransactionDetail { - AuditEvents(), - ImportFileName(), + AuditEvents, + ImportFileName, ClientLibrary, Product, Action,