1 // Licensed to the .NET Foundation under one or more agreements.
2 // The .NET Foundation licenses this file to you under the MIT license.
3 // See the LICENSE file in the project root for more information.
4 
5 using System.Diagnostics;
6 using Xunit;
7 
8 namespace System.Data.SqlClient.Tests
9 {
10     [OuterLoop("Takes minutes on some networks")]
11     public static class TcpDefaultForAzureTest
12     {
13         private const string NP = "Named Pipes Provider";
14         private const string TCP = "TCP Provider";
15         private const string InvalidHostname = "invalidHostname";
16         private const string ErrorMessage = "A network-related or instance-specific error occurred while establishing a connection to SQL Server.";
17 
18         private static string[] AzureExtensions;
19         private static SqlConnectionStringBuilder builder;
20 
TcpDefaultForAzureTest()21         static TcpDefaultForAzureTest()
22         {
23             AzureExtensions = new string[]
24                 {
25                     ".database.windows.net",
26                     ".database.cloudapi.de",
27                     ".database.usgovcloudapi.net",
28                     ".database.chinacloudapi.cn"
29                 };
30 
31             builder = new SqlConnectionStringBuilder();
32             builder.ConnectTimeout = 1;
33         }
34 
35         [Fact]
36         [SkipOnTargetFramework(TargetFrameworkMonikers.Uap)] // Cannot retrieve UseManagedSNI flag via reflection on UAP
NonAzureNoProtocolConnectionTest()37         public static void NonAzureNoProtocolConnectionTest()
38         {
39             builder.DataSource = InvalidHostname;
40             CheckConnectionFailure(builder.ConnectionString, ManualTesting.Tests.DataTestUtility.IsUsingManagedSNI() ? TCP : NP);
41         }
42 
43         [Fact]
NonAzureTcpConnectionTest()44         public static void NonAzureTcpConnectionTest()
45         {
46             builder.DataSource = "tcp:" + InvalidHostname;
47             CheckConnectionFailure(builder.ConnectionString, TCP);
48         }
49 
50         [Fact]
51         [PlatformSpecific(TestPlatforms.Windows)]  // NP NonAzure connection fails correctly on Windows
NonAzureNpConnectionTest()52         public static void NonAzureNpConnectionTest()
53         {
54             builder.DataSource = "np:\\\\" + InvalidHostname + "\\pipe\\sql\\query";
55             CheckConnectionFailure(builder.ConnectionString, NP);
56         }
57 
58         [Fact]
59         [SkipOnTargetFramework(TargetFrameworkMonikers.NetFramework)]
AzureNoProtocolConnectionTest()60         public static void AzureNoProtocolConnectionTest()
61         {
62             foreach (string extension in AzureExtensions)
63             {
64                 builder.DataSource = InvalidHostname + extension;
65                 CheckConnectionFailure(builder.ConnectionString, TCP);
66             }
67         }
68 
69         [Fact]
AzureTcpConnectionTest()70         public static void AzureTcpConnectionTest()
71         {
72             foreach (string extension in AzureExtensions)
73             {
74                 builder.DataSource = "tcp:" + InvalidHostname + extension;
75                 CheckConnectionFailure(builder.ConnectionString, TCP);
76             }
77         }
78 
79         [Fact]
80         [PlatformSpecific(TestPlatforms.Windows)]  // NP Azure connection fails correctly on Windows
AzureNpConnectionTest()81         public static void AzureNpConnectionTest()
82         {
83             foreach (string extension in AzureExtensions)
84             {
85                 builder.DataSource = "np:\\\\" + InvalidHostname + extension + "\\pipe\\sql\\query";
86                 CheckConnectionFailure(builder.ConnectionString, NP);
87             }
88         }
89 
CheckConnectionFailure(string connString, string protocol)90         private static void CheckConnectionFailure(string connString, string protocol)
91         {
92             Debug.Assert(!string.IsNullOrWhiteSpace(connString));
93 
94             string errorMessage = Connect(connString);
95 
96             Assert.True(errorMessage != null, "Did not receive any error message");
97             Assert.True(errorMessage.Contains(ErrorMessage), string.Format("Expected error message {0}, but received: {1}", ErrorMessage, errorMessage));
98 
99             if (protocol != null)
100             {
101                 Assert.True(
102                     errorMessage.Contains(string.Format("provider: {0}, error", protocol)),
103                     string.Format("Expected protocol {0} in the error message, but received: {1}", protocol, errorMessage));
104             }
105         }
106 
Connect(string connString)107         private static string Connect(string connString)
108         {
109             Debug.Assert(!string.IsNullOrWhiteSpace(connString));
110 
111             string errorMessage = null;
112             using (SqlConnection connection = new SqlConnection(connString))
113             {
114                 try
115                 {
116                     connection.Open();
117                     connection.Close();
118                 }
119                 catch (Exception e)
120                 {
121                     errorMessage = e.Message;
122                 }
123             }
124 
125             return errorMessage;
126         }
127     }
128 }
129