-
Notifications
You must be signed in to change notification settings - Fork 330
Expand file tree
/
Copy pathConnectionReadOnlyRoutingTests.cs
More file actions
158 lines (143 loc) · 6.28 KB
/
Copy pathConnectionReadOnlyRoutingTests.cs
File metadata and controls
158 lines (143 loc) · 6.28 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
using System.Collections.Generic;
using System.Net;
using System.Threading.Tasks;
using Microsoft.SqlServer.TDS.Servers;
using Xunit;
namespace Microsoft.Data.SqlClient.UnitTests.SimulatedServerTests
{
// TODO: Do we need this collection? It serializes all tests within it, which we probably don't
// need since each test uses its own TDS Server with ephemeral listen port.
[Collection("SimulatedServerTests")]
public class ConnectionReadOnlyRoutingTests
{
[Fact]
public void NonRoutedConnection()
{
using TdsServer server = new();
server.Start();
SqlConnectionStringBuilder builder = new() {
DataSource = $"localhost,{server.EndPoint.Port}",
ApplicationIntent = ApplicationIntent.ReadOnly,
Encrypt = SqlConnectionEncryptOption.Optional
};
using SqlConnection connection = new(builder.ConnectionString);
connection.Open();
}
[Fact]
public async Task NonRoutedAsyncConnection()
{
using TdsServer server = new();
server.Start();
SqlConnectionStringBuilder builder = new() {
DataSource = $"localhost,{server.EndPoint.Port}",
ApplicationIntent = ApplicationIntent.ReadOnly,
Encrypt = SqlConnectionEncryptOption.Optional
};
using SqlConnection connection = new(builder.ConnectionString);
await connection.OpenAsync();
}
[Fact]
public void RoutedConnection() => RecursivelyRoutedConnection(1);
[Fact]
public async Task RoutedAsyncConnection() => await RecursivelyRoutedAsyncConnection(1);
[Theory]
[InlineData(11)] // 11 layers of routing should succeed, 12 should fail
public void RecursivelyRoutedConnection(int layers)
{
using TdsServer innerServer = new();
innerServer.Start();
IPEndPoint lastEndpoint = innerServer.EndPoint;
Stack<RoutingTdsServer> routingLayers = new(layers + 1);
string lastConnectionString = (new SqlConnectionStringBuilder() { DataSource = $"localhost,{lastEndpoint.Port}" }).ConnectionString;
try
{
for (int i = 0; i < layers; i++)
{
RoutingTdsServer router = new(
new RoutingTdsServerArguments()
{
RoutingTCPHost = "localhost",
RoutingTCPPort = (ushort)lastEndpoint.Port,
});
router.Start();
routingLayers.Push(router);
lastEndpoint = router.EndPoint;
lastConnectionString = (new SqlConnectionStringBuilder() {
DataSource = $"localhost,{lastEndpoint.Port}",
ApplicationIntent = ApplicationIntent.ReadOnly,
Encrypt = false
}).ConnectionString;
}
SqlConnectionStringBuilder builder = new(lastConnectionString) { ApplicationIntent = ApplicationIntent.ReadOnly };
using SqlConnection connection = new(builder.ConnectionString);
connection.Open();
}
finally
{
while (routingLayers.Count > 0)
{
routingLayers.Pop().Dispose();
}
}
}
[Theory]
[InlineData(11)] // 11 layers of routing should succeed, 12 should fail
public async Task RecursivelyRoutedAsyncConnection(int layers)
{
using TdsServer innerServer = new();
innerServer.Start();
IPEndPoint lastEndpoint = innerServer.EndPoint;
Stack<RoutingTdsServer> routingLayers = new(layers + 1);
string lastConnectionString = (new SqlConnectionStringBuilder() { DataSource = $"localhost,{lastEndpoint.Port}" }).ConnectionString;
try
{
for (int i = 0; i < layers; i++)
{
RoutingTdsServer router = new(
new RoutingTdsServerArguments()
{
RoutingTCPHost = "localhost",
RoutingTCPPort = (ushort)lastEndpoint.Port,
});
router.Start();
routingLayers.Push(router);
lastEndpoint = router.EndPoint;
lastConnectionString = (new SqlConnectionStringBuilder() {
DataSource = $"localhost,{lastEndpoint.Port}",
ApplicationIntent = ApplicationIntent.ReadOnly,
Encrypt = false
}).ConnectionString;
}
SqlConnectionStringBuilder builder = new(lastConnectionString) {
ApplicationIntent = ApplicationIntent.ReadOnly,
Encrypt = false
};
using SqlConnection connection = new(builder.ConnectionString);
await connection.OpenAsync();
}
finally
{
while (routingLayers.Count > 0)
{
routingLayers.Pop().Dispose();
}
}
}
[Fact]
public void ConnectionRoutingLimit()
{
SqlException sqlEx = Assert.Throws<SqlException>(() => RecursivelyRoutedConnection(12)); // This will fail on the 11th redirect
Assert.Contains("Too many redirections have occurred.", sqlEx.Message, StringComparison.InvariantCultureIgnoreCase);
}
[Fact]
public async Task AsyncConnectionRoutingLimit()
{
SqlException sqlEx = await Assert.ThrowsAsync<SqlException>(() => RecursivelyRoutedAsyncConnection(12)); // This will fail on the 11th redirect
Assert.Contains("Too many redirections have occurred.", sqlEx.Message, StringComparison.InvariantCultureIgnoreCase);
}
}
}