-
Notifications
You must be signed in to change notification settings - Fork 314
Refactor Test TDS Servers. Expand functional testing of connection pooling and transient failures. #3488
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
…ailover-tds-server
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good to me, with a few suggestions.
src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlConnectionBasicTests.cs
Outdated
Show resolved
Hide resolved
src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlConnectionBasicTests.cs
Show resolved
Hide resolved
src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlConnectionReadOnlyRoutingTests.cs
Outdated
Show resolved
Hide resolved
src/Microsoft.Data.SqlClient/tests/tools/TDS/TDS.Servers/AuthenticatingTDSServer.cs
Outdated
Show resolved
Hide resolved
src/Microsoft.Data.SqlClient/tests/tools/TDS/TDS.Servers/GenericTDSServer.cs
Outdated
Show resolved
Hide resolved
src/Microsoft.Data.SqlClient/tests/tools/TDS/TDS.Servers/GenericTDSServer.cs
Outdated
Show resolved
Hide resolved
public TdsServer() : this(new TdsServerArguments()) | ||
{ | ||
} | ||
/// <summary> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Missing a blank line here.
…ut. Clean up transient error server.
…p where they're supposed to, not just side effects.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A few tidying-up suggestions.
src/Microsoft.Data.SqlClient/tests/tools/TDS/TDS.EndPoint/TDSServerEndPointConnection.cs
Outdated
Show resolved
Hide resolved
src/Microsoft.Data.SqlClient/tests/tools/TDS/TDS.Servers/TransientFaultTdsServer.cs
Outdated
Show resolved
Hide resolved
src/Microsoft.Data.SqlClient/tests/tools/TDS/TDS.Servers/TransientTimeoutTdsServer.cs
Outdated
Show resolved
Hide resolved
src/Microsoft.Data.SqlClient/tests/tools/TDS/TDS.Servers/TransientTimeoutTdsServerArguments.cs
Outdated
Show resolved
Hide resolved
…ailover-tds-server
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A couple of suggestions.
src/Microsoft.Data.SqlClient/tests/tools/TDS/TDS.EndPoint/TDSServerEndPointConnection.cs
Outdated
Show resolved
Hide resolved
if (Arguments.IsEnabledPermanentTimeout || | ||
(Arguments.IsEnabledTransientTimeout && RequestCounter < 1)) // Fail first time, then connect | ||
(Arguments.IsEnabledTransientTimeout && RequestCounter < 1)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
RequestCounter < Arguments.RepeatCount
?
…ion string settings and fix tests.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Still some outstanding requests from earlier PRs as well. I will go back through them and see if they have been addressed.
src/Microsoft.Data.SqlClient/tests/tools/TDS/TDS.Servers/GenericTdsServer.cs
Show resolved
Hide resolved
Two small comments remain. Should this convereted from a draft now? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This PR refactors the Test TDS Servers infrastructure by consolidating endpoint initialization and improving the construction flow for mock servers. The changes eliminate duplicated code across TDS.Servers, FunctionalTests, and ManualTests while making constructor parameters more explicit rather than hiding defaults in nested calls.
Key changes include:
- Standardized naming from "TDS" to "Tds" across server classes for consistency
- Replaced properties with field initializers for server arguments to make defaults explicit
- Simplified endpoint initialization by removing auto-generated connection strings
- Added new transient delay and error servers for improved testing scenarios
- Consolidated connection string building using SqlConnectionStringBuilder
Reviewed Changes
Copilot reviewed 42 out of 42 changed files in this pull request and generated 5 comments.
Show a summary per file
File | Description |
---|---|
TransientTdsErrorTdsServerArguments.cs |
Renamed class and replaced properties with field initializers for clearer defaults |
TransientTdsErrorTdsServer.cs |
New server class for testing transient error scenarios with explicit error behavior |
TransientDelayTdsServerArguments.cs |
New arguments class for delay simulation testing |
TransientDelayTdsServer.cs |
New server class for simulating network delays during connections |
TdsServerArguments.cs |
Renamed class and converted properties to field initializers |
TdsServer.cs |
New simplified TDS server implementation |
GenericTdsServer.cs |
Refactored to use generics and added endpoint management |
Connection test files | Updated to use new server construction patterns and explicit connection strings |
public void SetErrorBehavior(bool isEnabledTransientFault, uint errorNumber, int repeatCount = 1, string message = null) | ||
{ | ||
Arguments.IsEnabledTransientError = isEnabledTransientFault; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The parameter name 'isEnabledTransientFault' is inconsistent with the field name 'IsEnabledTransientError'. Consider renaming the parameter to 'isEnabledTransientError' for consistency.
public void SetErrorBehavior(bool isEnabledTransientFault, uint errorNumber, int repeatCount = 1, string message = null) | |
{ | |
Arguments.IsEnabledTransientError = isEnabledTransientFault; | |
public void SetErrorBehavior(bool isEnabledTransientError, uint errorNumber, int repeatCount = 1, string message = null) | |
{ | |
Arguments.IsEnabledTransientError = isEnabledTransientError; |
Copilot uses AI. Check for mistakes.
public void Start([CallerMemberName] string methodName = "") | ||
{ | ||
_endpoint = new TDSServerEndPoint(this) { ServerEndPoint = new IPEndPoint(IPAddress.Any, 0) }; | ||
_endpoint.EndpointName = methodName; | ||
_endpoint.EventLog = Arguments.Log; | ||
_endpoint.Start(); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The Start method creates a new endpoint instance but doesn't check if one already exists. This could lead to resource leaks if Start is called multiple times. Consider adding a check for existing endpoint or making the method idempotent.
Copilot uses AI. Check for mistakes.
@@ -880,5 +910,7 @@ private bool AreEqual(byte[] left, byte[] right) | |||
|
|||
return left.SequenceEqual<byte>(right); | |||
} | |||
|
|||
public virtual void Dispose() => _endpoint?.Dispose(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The Dispose method only disposes the endpoint but doesn't set it to null or prevent further usage. Consider implementing the full IDisposable pattern with a disposed flag to prevent usage after disposal.
Copilot uses AI. Check for mistakes.
{ | ||
/// <summary> | ||
/// Worker thread | ||
/// </summary> | ||
protected Thread ProcessorThread { get; set; } | ||
protected Task ProcessorTask { get; set; } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The ProcessorTask property should be disposed in the Dispose method to prevent potential resource leaks from unfinished tasks.
Copilot uses AI. Check for mistakes.
using RoutingTdsServer router = new RoutingTdsServer( | ||
new RoutingTdsServerArguments() | ||
{ | ||
//RoutingTCPHost = server.EndPoint.Address.ToString() == IPAddress.Any.ToString() ? IPAddress.Loopback.ToString() : server.EndPoint.Address.ToString(), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove commented-out code. If this logic might be needed later, consider documenting the reason or implementing it properly.
//RoutingTCPHost = server.EndPoint.Address.ToString() == IPAddress.Any.ToString() ? IPAddress.Loopback.ToString() : server.EndPoint.Address.ToString(), |
Copilot uses AI. Check for mistakes.
Description
The TDS.Servers project provides mocked server implementations for a variety of use cases. The construction and endpoint initialization flows for these mock servers was complicated and resulted in duplicated code across TDS.Servers, FunctionalTests, and ManualTests. This PR consolidates endpoint initialization and makes test server constructor parameters more explicit (no more defaults buried a few layers deep).
One downside of this approach is that it's now slightly harder to get the connection string for a test server. Before, some servers had a ConnectionString property you could access. The issue with these connection strings is they had a lot of non-standard default behavior coded into them at the time they were constructed. This makes it hard to understand which properties you're actually using when connecting to a test server. With my changes, you now need to manually construct a connection string using SqlConnectionStringBuilder and explicitly set connection parameters. Any parameters you don't set use the stock connection string defaults.
Testing
I added some testing around pool invalidation during failover and routing behavior during transient errors.