//
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
//
using System;
using System.Globalization;
using Microsoft.SqlTools.ServiceLayer.Connection;
using Microsoft.SqlTools.ServiceLayer.Connection.Contracts;
using Xunit;
using System.Data.SqlClient;
using System.Threading.Tasks;
namespace Microsoft.SqlTools.ServiceLayer.Test.Common
{
///
/// Creates a new test database
///
public class SqlTestDb : IDisposable
{
public const string MasterDatabaseName = "master";
public string DatabaseName { get; set; }
public TestServerType ServerType { get; set; }
public bool DoNotCleanupDb { get; set; }
public string ConnectionString
{
get
{
ConnectParams connectParams = TestConnectionProfileService.Instance.GetConnectionParameters(this.ServerType, this.DatabaseName);
SqlConnectionStringBuilder builder = new SqlConnectionStringBuilder
{
DataSource = connectParams.Connection.ServerName,
InitialCatalog = connectParams.Connection.DatabaseName,
};
if (connectParams.Connection.AuthenticationType == "Integrated")
{
builder.IntegratedSecurity = true;
}
else
{
builder.UserID = connectParams.Connection.UserName;
builder.Password = connectParams.Connection.Password;
}
return builder.ToString();
}
}
///
/// Create the test db if not already exists
///
public static SqlTestDb CreateNew(
TestServerType serverType,
bool doNotCleanupDb = false,
string databaseName = null,
string query = null,
string dbNamePrefix = null)
{
return CreateNewAsync(serverType, doNotCleanupDb, databaseName, query, dbNamePrefix).Result;
}
///
/// Create the test db if not already exists
///
public static async Task CreateNewAsync(
TestServerType serverType,
bool doNotCleanupDb = false,
string databaseName = null,
string query = null,
string dbNamePrefix = null)
{
SqlTestDb testDb = new SqlTestDb();
databaseName = databaseName ?? GetUniqueDBName(dbNamePrefix);
string createDatabaseQuery = Scripts.CreateDatabaseQuery.Replace("#DatabaseName#", databaseName);
await TestServiceProvider.Instance.RunQueryAsync(serverType, MasterDatabaseName, createDatabaseQuery);
Console.WriteLine(string.Format(CultureInfo.InvariantCulture, "Test database '{0}' is created", databaseName));
if (!string.IsNullOrEmpty(query))
{
query = string.Format(CultureInfo.InvariantCulture, query, databaseName);
await TestServiceProvider.Instance.RunQueryAsync(serverType, databaseName, query);
Console.WriteLine(string.Format(CultureInfo.InvariantCulture, "Test database '{0}' SQL types are created", databaseName));
}
testDb.DatabaseName = databaseName;
testDb.ServerType = serverType;
testDb.DoNotCleanupDb = doNotCleanupDb;
return testDb;
}
///
/// Create the test db if not already exists
///
public static SqlTestDb CreateNew(TestServerType serverType, string query = null)
{
return CreateNew(serverType, false, null, query);
}
///
/// Create the test db if not already exists
///
public static SqlTestDb CreateNew(TestServerType serverType)
{
return CreateNew(serverType, false, null, null);
}
///
/// Returns a mangled name that unique based on Prefix + Machine + Process
///
///
///
public static string GetUniqueDBName(string namePrefix)
{
string safeMachineName = Environment.MachineName.Replace('-', '_');
return string.Format("{0}_{1}_{2}",
namePrefix, safeMachineName, Guid.NewGuid().ToString().Replace("-", ""));
}
public void Cleanup()
{
CleanupAsync().Wait();
}
public async Task CleanupAsync()
{
try
{
if (!DoNotCleanupDb)
{
string dropDatabaseQuery = string.Format(CultureInfo.InvariantCulture,
(ServerType == TestServerType.Azure ? Scripts.DropDatabaseIfExistAzure : Scripts.DropDatabaseIfExist), DatabaseName);
Console.WriteLine(string.Format(CultureInfo.InvariantCulture, "Cleaning up database {0}", DatabaseName));
await TestServiceProvider.Instance.RunQueryAsync(ServerType, MasterDatabaseName, dropDatabaseQuery);
}
}
catch (Exception ex)
{
Console.WriteLine(string.Format(CultureInfo.InvariantCulture, "Failed to cleanup database: {0} error:{1}", DatabaseName, ex.Message));
}
}
///
/// Returns connection info after making a connection to the database
///
///
///
///
///
public ConnectionInfo InitLiveConnectionInfo(TestServerType serverType, string databaseName, string scriptFilePath)
{
ConnectParams connectParams = TestConnectionProfileService.Instance.GetConnectionParameters(serverType, databaseName);
string ownerUri = scriptFilePath;
var connectionService = ConnectionService.Instance;
var connectionResult = connectionService.Connect(new ConnectParams()
{
OwnerUri = ownerUri,
Connection = connectParams.Connection
});
connectionResult.Wait();
ConnectionInfo connInfo = null;
connectionService.TryFindConnection(ownerUri, out connInfo);
Assert.NotNull(connInfo);
return connInfo;
}
///
/// Runs the passed query against the test db.
///
/// The query to execute.
/// If true, throw an exception if the query encounters an error executing a batch statement.
public void RunQuery(string query, bool throwOnError = false)
{
TestServiceProvider.Instance.RunQuery(this.ServerType, this.DatabaseName, query, throwOnError);
}
public void Dispose()
{
Cleanup();
}
}
}