public static string GetSkipReason(ServerFeatures serverFeatures, ConfigSettings configSettings) { if (!AppConfig.SupportedFeatures.HasFlag(serverFeatures)) { return($"Requires ServerFeatures.{serverFeatures}"); } if (configSettings == ConfigSettings.None) { return(null); } var csb = AppConfig.CreateConnectionStringBuilder(); if (configSettings.HasFlag(ConfigSettings.RequiresSsl) && (csb.SslMode == MySqlSslMode.None #if !BASELINE || csb.SslMode == MySqlSslMode.Preferred #endif )) { return("Requires SslMode=Required or higher in connection string"); } if (configSettings.HasFlag(ConfigSettings.TrustedHost) && (csb.SslMode == MySqlSslMode.None || #if !BASELINE csb.SslMode == MySqlSslMode.Preferred || #endif csb.SslMode == MySqlSslMode.Required)) { return("Requires SslMode=VerifyCA or higher in connection string"); } if (configSettings.HasFlag(ConfigSettings.UntrustedHost) && (csb.SslMode == MySqlSslMode.VerifyCA || csb.SslMode == MySqlSslMode.VerifyFull)) { return("Requires SslMode=Required or lower in connection string"); } if (configSettings.HasFlag(ConfigSettings.KnownClientCertificate)) { if (!((csb.CertificateFile?.EndsWith("ssl-client.pfx", StringComparison.OrdinalIgnoreCase) ?? false) || (csb.SslKey?.EndsWith("ssl-client-key.pem", StringComparison.OrdinalIgnoreCase) ?? false))) { return("Requires CertificateFile=client.pfx in connection string"); } } if (configSettings.HasFlag(ConfigSettings.PasswordlessUser) && string.IsNullOrWhiteSpace(AppConfig.PasswordlessUser)) { return("Requires PasswordlessUser in config.json"); } if (configSettings.HasFlag(ConfigSettings.GSSAPIUser) && string.IsNullOrWhiteSpace(AppConfig.GSSAPIUser)) { return("Requires GSSAPIUser in config.json"); } if (configSettings.HasFlag(ConfigSettings.HasKerberos) && !AppConfig.HasKerberos) { return("Requires HasKerberos in config.json"); } if (configSettings.HasFlag(ConfigSettings.CsvFile) && string.IsNullOrWhiteSpace(AppConfig.MySqlBulkLoaderCsvFile)) { return("Requires MySqlBulkLoaderCsvFile in config.json"); } if (configSettings.HasFlag(ConfigSettings.LocalCsvFile) && string.IsNullOrWhiteSpace(AppConfig.MySqlBulkLoaderLocalCsvFile)) { return("Requires MySqlBulkLoaderLocalCsvFile in config.json"); } if (configSettings.HasFlag(ConfigSettings.TsvFile) && string.IsNullOrWhiteSpace(AppConfig.MySqlBulkLoaderTsvFile)) { return("Requires MySqlBulkLoaderTsvFile in config.json"); } if (configSettings.HasFlag(ConfigSettings.LocalTsvFile) && string.IsNullOrWhiteSpace(AppConfig.MySqlBulkLoaderLocalTsvFile)) { return("Requires MySqlBulkLoaderLocalTsvFile in config.json"); } if (configSettings.HasFlag(ConfigSettings.TcpConnection) && ((csb.Server.StartsWith("/", StringComparison.Ordinal) || csb.Server.StartsWith("./", StringComparison.Ordinal)) || csb.ConnectionProtocol != MySqlConnectionProtocol.Sockets)) { return("Requires a TCP connection"); } if (configSettings.HasFlag(ConfigSettings.SecondaryDatabase) && string.IsNullOrEmpty(AppConfig.SecondaryDatabase)) { return("Requires SecondaryDatabase in config.json"); } return(null); }
public async Task ClearConnectionPool() { var csb = AppConfig.CreateConnectionStringBuilder(); csb.Pooling = true; csb.MinimumPoolSize = 0; csb.MaximumPoolSize = 3; var connections = new List <MySqlConnection>(); for (int i = 0; i < csb.MaximumPoolSize; i++) { var connection = new MySqlConnection(csb.ConnectionString); connections.Add(connection); } Func <HashSet <long> > getConnectionIds = () => { var cids = GetConnectionIds(connections); Assert.Equal(connections.Count, cids.Count); return(cids); }; Func <Task> openConnections = async() => { foreach (var connection in connections) { await connection.OpenAsync(); } }; Action closeConnections = () => { foreach (var connection in connections) { connection.Close(); } }; // connections should all be disposed when returned to pool await openConnections(); var connectionIds = getConnectionIds(); await ClearPoolAsync(connections[0]); closeConnections(); await openConnections(); var connectionIds2 = getConnectionIds(); Assert.Empty(connectionIds.Intersect(connectionIds2)); closeConnections(); // connections should all be disposed in ClearPoolAsync await ClearPoolAsync(connections[0]); await openConnections(); var connectionIds3 = getConnectionIds(); Assert.Empty(connectionIds2.Intersect(connectionIds3)); closeConnections(); // some connections may be disposed in ClearPoolAsync, others in OpenAsync var clearTask = ClearPoolAsync(connections[0]); await openConnections(); var connectionIds4 = GetConnectionIds(connections); Assert.Empty(connectionIds3.Intersect(connectionIds4)); await clearTask; closeConnections(); foreach (var connection in connections) { connection.Dispose(); } }