From fa82d387a25922e635e29162e4e6a50e5a00c861 Mon Sep 17 00:00:00 2001 From: Edward Neal <55035479+edwardneal@users.noreply.github.com> Date: Fri, 27 Jun 2025 22:09:34 +0100 Subject: [PATCH 1/2] Account for MAX_DISPATCH_LATENCY in XEvents tests XEvents are asynchronous, and are written to the target within MAX_DISPATCH_LATENCY seconds. We therefore need to wait that long before querying the target. --- .../tests/ManualTests/DataCommon/DataTestUtility.cs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/Microsoft.Data.SqlClient/tests/ManualTests/DataCommon/DataTestUtility.cs b/src/Microsoft.Data.SqlClient/tests/ManualTests/DataCommon/DataTestUtility.cs index aacc723453..8f6a3e71a4 100644 --- a/src/Microsoft.Data.SqlClient/tests/ManualTests/DataCommon/DataTestUtility.cs +++ b/src/Microsoft.Data.SqlClient/tests/ManualTests/DataCommon/DataTestUtility.cs @@ -1092,6 +1092,8 @@ protected virtual void OnMatchingEventWritten(EventWrittenEventArgs eventData) public readonly ref struct XEventScope // : IDisposable { + private const int MaxXEventsLatencyS = 5; + private readonly SqlConnection _connection; private readonly bool _useDatabaseSession; @@ -1126,6 +1128,8 @@ INNER JOIN sys.dm_xe_sessions AS xe using (SqlCommand command = new SqlCommand(xEventQuery, _connection)) { + Thread.Sleep(MaxXEventsLatencyS * 1000); + if (_connection.State == ConnectionState.Closed) { _connection.Open(); @@ -1148,7 +1152,7 @@ private void SetupXEvent(string eventSpecification, string targetSpecification) WITH ( MAX_MEMORY=4096 KB, EVENT_RETENTION_MODE=ALLOW_SINGLE_EVENT_LOSS, - MAX_DISPATCH_LATENCY=30 SECONDS, + MAX_DISPATCH_LATENCY={MaxXEventsLatencyS} SECONDS, MAX_EVENT_SIZE=0 KB, MEMORY_PARTITION_MODE=NONE, TRACK_CAUSALITY=ON, From cd3fdbae0f125a60c5220c9a92687425f10bd70b Mon Sep 17 00:00:00 2001 From: Edward Neal <55035479+edwardneal@users.noreply.github.com> Date: Sun, 29 Jun 2025 14:54:50 +0100 Subject: [PATCH 2/2] Filter XEvent session by client_connection_id --- .../ManualTests/DataCommon/DataTestUtility.cs | 2 +- .../TracingTests/XEventsTracingTest.cs | 48 +++++++++---------- 2 files changed, 24 insertions(+), 26 deletions(-) diff --git a/src/Microsoft.Data.SqlClient/tests/ManualTests/DataCommon/DataTestUtility.cs b/src/Microsoft.Data.SqlClient/tests/ManualTests/DataCommon/DataTestUtility.cs index 8f6a3e71a4..b3f90cd34e 100644 --- a/src/Microsoft.Data.SqlClient/tests/ManualTests/DataCommon/DataTestUtility.cs +++ b/src/Microsoft.Data.SqlClient/tests/ManualTests/DataCommon/DataTestUtility.cs @@ -1150,7 +1150,7 @@ private void SetupXEvent(string eventSpecification, string targetSpecification) {eventSpecification} {targetSpecification} WITH ( - MAX_MEMORY=4096 KB, + MAX_MEMORY=16 MB, EVENT_RETENTION_MODE=ALLOW_SINGLE_EVENT_LOSS, MAX_DISPATCH_LATENCY={MaxXEventsLatencyS} SECONDS, MAX_EVENT_SIZE=0 KB, diff --git a/src/Microsoft.Data.SqlClient/tests/ManualTests/TracingTests/XEventsTracingTest.cs b/src/Microsoft.Data.SqlClient/tests/ManualTests/TracingTests/XEventsTracingTest.cs index 40fde20faa..3d8e6be8ac 100644 --- a/src/Microsoft.Data.SqlClient/tests/ManualTests/TracingTests/XEventsTracingTest.cs +++ b/src/Microsoft.Data.SqlClient/tests/ManualTests/TracingTests/XEventsTracingTest.cs @@ -21,37 +21,35 @@ public void XEventActivityIDConsistentWithTracing(string query, System.Data.Comm // where it can be recorded in an XEvent session. This is documented at: // https://learn.microsoft.com/en-us/sql/relational-databases/native-client/features/accessing-diagnostic-information-in-the-extended-events-log - using (SqlConnection xEventManagementConnection = new SqlConnection(DataTestUtility.TCPConnectionString)) - using (DataTestUtility.XEventScope xEventSession = new DataTestUtility.XEventScope(xEventManagementConnection, - @"ADD EVENT SQL_STATEMENT_STARTING (ACTION (client_connection_id)), - ADD EVENT RPC_STARTING (ACTION (client_connection_id))", - "ADD TARGET ring_buffer")) - { - Guid connectionId; - HashSet ids; + using SqlConnection activityConnection = new(DataTestUtility.TCPConnectionString); + activityConnection.Open(); - using (DataTestUtility.MDSEventListener TraceListener = new()) - using (SqlConnection connection = new(DataTestUtility.TCPConnectionString)) - { - connection.Open(); - connectionId = connection.ClientConnectionId; + Guid connectionId = activityConnection.ClientConnectionId; + HashSet ids; - using SqlCommand command = new(query, connection) { CommandType = commandType }; - using SqlDataReader reader = command.ExecuteReader(); - while (reader.Read()) - { - // Flush data - } + using SqlConnection xEventManagementConnection = new(DataTestUtility.TCPConnectionString); + using DataTestUtility.XEventScope xEventSession = new(xEventManagementConnection, + $@"ADD EVENT SQL_STATEMENT_STARTING (ACTION (client_connection_id) WHERE (client_connection_id='{connectionId}')), + ADD EVENT RPC_STARTING (ACTION (client_connection_id) WHERE (client_connection_id='{connectionId}'))", + "ADD TARGET ring_buffer"); - ids = TraceListener.ActivityIDs; + using (DataTestUtility.MDSEventListener TraceListener = new()) + { + using SqlCommand command = new(query, activityConnection) { CommandType = commandType }; + using SqlDataReader reader = command.ExecuteReader(); + while (reader.Read()) + { + // Flush data } - XmlDocument eventList = xEventSession.GetEvents(); - // Get the associated activity ID from the XEvent session. We expect to see the same ID in the trace as well. - string activityId = GetCommandActivityId(query, xEvent, connectionId, eventList); - - Assert.Contains(activityId, ids); + ids = TraceListener.ActivityIDs; } + + XmlDocument eventList = xEventSession.GetEvents(); + // Get the associated activity ID from the XEvent session. We expect to see the same ID in the trace as well. + string activityId = GetCommandActivityId(query, xEvent, connectionId, eventList); + + Assert.Contains(activityId, ids); } private static string GetCommandActivityId(string commandText, string eventName, Guid connectionId, XmlDocument xEvents)