// // 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 NUnit.Framework; using Microsoft.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); } /// /// Represents a test Database that was created in a test /// public static SqlTestDb CreateFromExisting( string dbName, TestServerType serverType = TestServerType.OnPrem, bool doNotCleanupDb = false) { SqlTestDb testDb = new SqlTestDb(); if (string.IsNullOrEmpty(dbName)) { throw new ArgumentOutOfRangeException("dbName"); } testDb.DatabaseName = dbName; testDb.ServerType = serverType; return testDb; } /// /// 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) { await DropDatabase(DatabaseName, ServerType); } } catch (Exception ex) { Console.WriteLine(string.Format(CultureInfo.InvariantCulture, "Failed to cleanup database: {0} error:{1}", DatabaseName, ex.Message)); } } public static async Task DropDatabase(string databaseName, TestServerType serverType = TestServerType.OnPrem) { 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); } /// /// 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(); } } }