From 213fe4ab37480c8a7ddadc0cc8a26c27ca7b5dfd Mon Sep 17 00:00:00 2001 From: kisantia <31145923+kisantia@users.noreply.github.com> Date: Tue, 9 Apr 2019 15:04:59 -0700 Subject: [PATCH] Add schema compare publish changes operation (#795) * add schema compare publish changes operation --- .../DacFx/DacFxService.cs | 10 +- .../Localization/sr.cs | 66 ++++++++ .../Localization/sr.resx | 24 +++ .../Localization/sr.strings | 11 +- .../Localization/sr.xlf | 30 ++++ .../SchemaCompareGenerateScriptRequest.cs | 17 +- .../SchemaComparePublishChangesRequest.cs | 45 +++++ .../SchemaComparePublishChangesOperation.cs | 73 +++++++++ .../SchemaCompare/SchemaCompareService.cs | 45 ++++- .../SchemaCompareServiceTests.cs | 154 ++++++++++++++++++ 10 files changed, 449 insertions(+), 26 deletions(-) create mode 100644 src/Microsoft.SqlTools.ServiceLayer/SchemaCompare/Contracts/SchemaComparePublishChangesRequest.cs create mode 100644 src/Microsoft.SqlTools.ServiceLayer/SchemaCompare/SchemaComparePublishChangesOperation.cs diff --git a/src/Microsoft.SqlTools.ServiceLayer/DacFx/DacFxService.cs b/src/Microsoft.SqlTools.ServiceLayer/DacFx/DacFxService.cs index 874452d3..bf311aad 100644 --- a/src/Microsoft.SqlTools.ServiceLayer/DacFx/DacFxService.cs +++ b/src/Microsoft.SqlTools.ServiceLayer/DacFx/DacFxService.cs @@ -67,7 +67,7 @@ namespace Microsoft.SqlTools.ServiceLayer.DacFx if (connInfo != null) { ExportOperation operation = new ExportOperation(parameters, connInfo); - await ExecuteOperation(operation, parameters, "Export bacpac", requestContext); + await ExecuteOperation(operation, parameters, SR.ExportBacpacTaskName, requestContext); } } catch (Exception e) @@ -91,7 +91,7 @@ namespace Microsoft.SqlTools.ServiceLayer.DacFx if (connInfo != null) { ImportOperation operation = new ImportOperation(parameters, connInfo); - await ExecuteOperation(operation, parameters, "Import bacpac", requestContext); + await ExecuteOperation(operation, parameters, SR.ImportBacpacTaskName, requestContext); } } catch (Exception e) @@ -115,7 +115,7 @@ namespace Microsoft.SqlTools.ServiceLayer.DacFx if (connInfo != null) { ExtractOperation operation = new ExtractOperation(parameters, connInfo); - await ExecuteOperation(operation, parameters, "Extract dacpac", requestContext); + await ExecuteOperation(operation, parameters, SR.ExtractDacpacTaskName, requestContext); } } catch (Exception e) @@ -139,7 +139,7 @@ namespace Microsoft.SqlTools.ServiceLayer.DacFx if (connInfo != null) { DeployOperation operation = new DeployOperation(parameters, connInfo); - await ExecuteOperation(operation, parameters, "Deploy dacpac", requestContext); + await ExecuteOperation(operation, parameters, SR.DeployDacpacTaskName, requestContext); } } catch (Exception e) @@ -164,7 +164,7 @@ namespace Microsoft.SqlTools.ServiceLayer.DacFx { GenerateDeployScriptOperation operation = new GenerateDeployScriptOperation(parameters, connInfo); SqlTask sqlTask = null; - TaskMetadata metadata = TaskMetadata.Create(parameters, "Generate script", operation, ConnectionServiceInstance); + TaskMetadata metadata = TaskMetadata.Create(parameters, SR.GenerateScriptTaskName, operation, ConnectionServiceInstance); // want to show filepath in task history instead of server and database metadata.ServerName = parameters.ScriptFilePath; diff --git a/src/Microsoft.SqlTools.ServiceLayer/Localization/sr.cs b/src/Microsoft.SqlTools.ServiceLayer/Localization/sr.cs index 1c8b3006..679310f4 100755 --- a/src/Microsoft.SqlTools.ServiceLayer/Localization/sr.cs +++ b/src/Microsoft.SqlTools.ServiceLayer/Localization/sr.cs @@ -2869,6 +2869,46 @@ namespace Microsoft.SqlTools.ServiceLayer } } + public static string ExportBacpacTaskName + { + get + { + return Keys.GetString(Keys.ExportBacpacTaskName); + } + } + + public static string ImportBacpacTaskName + { + get + { + return Keys.GetString(Keys.ImportBacpacTaskName); + } + } + + public static string ExtractDacpacTaskName + { + get + { + return Keys.GetString(Keys.ExtractDacpacTaskName); + } + } + + public static string DeployDacpacTaskName + { + get + { + return Keys.GetString(Keys.DeployDacpacTaskName); + } + } + + public static string GenerateScriptTaskName + { + get + { + return Keys.GetString(Keys.GenerateScriptTaskName); + } + } + public static string ExtractInvalidVersion { get @@ -2877,6 +2917,14 @@ namespace Microsoft.SqlTools.ServiceLayer } } + public static string PublishChangesTaskName + { + get + { + return Keys.GetString(Keys.PublishChangesTaskName); + } + } + public static string ConnectionServiceListDbErrorNotConnected(string uri) { return Keys.GetString(Keys.ConnectionServiceListDbErrorNotConnected, uri); @@ -4190,9 +4238,27 @@ namespace Microsoft.SqlTools.ServiceLayer public const string Error_ExistingDirectoryName = "Error_ExistingDirectoryName"; + public const string ExportBacpacTaskName = "ExportBacpacTaskName"; + + + public const string ImportBacpacTaskName = "ImportBacpacTaskName"; + + + public const string ExtractDacpacTaskName = "ExtractDacpacTaskName"; + + + public const string DeployDacpacTaskName = "DeployDacpacTaskName"; + + + public const string GenerateScriptTaskName = "GenerateScriptTaskName"; + + public const string ExtractInvalidVersion = "ExtractInvalidVersion"; + public const string PublishChangesTaskName = "PublishChangesTaskName"; + + private Keys() { } diff --git a/src/Microsoft.SqlTools.ServiceLayer/Localization/sr.resx b/src/Microsoft.SqlTools.ServiceLayer/Localization/sr.resx index 7a9fe996..433bb93f 100755 --- a/src/Microsoft.SqlTools.ServiceLayer/Localization/sr.resx +++ b/src/Microsoft.SqlTools.ServiceLayer/Localization/sr.resx @@ -1687,8 +1687,32 @@ For directory {0} a file with name {1} already exist + + Export bacpac + + + + Import bacpac + + + + Extract dacpac + + + + Deploy dacpac + + + + Generate script + + Invalid version '{0}' passed. Version must be in the format x.x.x.x where x is a number. + + Apply schema compare changes + + diff --git a/src/Microsoft.SqlTools.ServiceLayer/Localization/sr.strings b/src/Microsoft.SqlTools.ServiceLayer/Localization/sr.strings index 5bf96de0..ade10eee 100644 --- a/src/Microsoft.SqlTools.ServiceLayer/Localization/sr.strings +++ b/src/Microsoft.SqlTools.ServiceLayer/Localization/sr.strings @@ -786,4 +786,13 @@ Error_ExistingDirectoryName = For directory {0} a file with name {1} already exi ############################################################################ # DacFx -ExtractInvalidVersion = Invalid version '{0}' passed. Version must be in the format x.x.x.x where x is a number. \ No newline at end of file +ExportBacpacTaskName = Export bacpac +ImportBacpacTaskName = Import bacpac +ExtractDacpacTaskName = Extract dacpac +DeployDacpacTaskName = Deploy dacpac +GenerateScriptTaskName = Generate script +ExtractInvalidVersion = Invalid version '{0}' passed. Version must be in the format x.x.x.x where x is a number. + +############################################################################ +# Schema Compare +PublishChangesTaskName = Apply schema compare changes \ No newline at end of file diff --git a/src/Microsoft.SqlTools.ServiceLayer/Localization/sr.xlf b/src/Microsoft.SqlTools.ServiceLayer/Localization/sr.xlf index 08ae2fed..8c44ea19 100644 --- a/src/Microsoft.SqlTools.ServiceLayer/Localization/sr.xlf +++ b/src/Microsoft.SqlTools.ServiceLayer/Localization/sr.xlf @@ -1961,6 +1961,36 @@ Invalid version '{0}' passed. Version must be in the format x.x.x.x where x is a number. + + Export bacpac + Export bacpac + + + + Import bacpac + Import bacpac + + + + Extract dacpac + Extract dacpac + + + + Deploy dacpac + Deploy dacpac + + + + Generate script + Generate script + + + + Apply schema compare changes + Apply schema compare changes + + \ No newline at end of file diff --git a/src/Microsoft.SqlTools.ServiceLayer/SchemaCompare/Contracts/SchemaCompareGenerateScriptRequest.cs b/src/Microsoft.SqlTools.ServiceLayer/SchemaCompare/Contracts/SchemaCompareGenerateScriptRequest.cs index f45cec9f..a1613716 100644 --- a/src/Microsoft.SqlTools.ServiceLayer/SchemaCompare/Contracts/SchemaCompareGenerateScriptRequest.cs +++ b/src/Microsoft.SqlTools.ServiceLayer/SchemaCompare/Contracts/SchemaCompareGenerateScriptRequest.cs @@ -13,27 +13,12 @@ namespace Microsoft.SqlTools.ServiceLayer.SchemaCompare.Contracts /// /// Parameters for a schema compare generate script request. /// - public class SchemaCompareGenerateScriptParams + public class SchemaCompareGenerateScriptParams : SchemaComparePublishChangesParams { - /// - /// Operation id of the schema compare operation - /// - public string OperationId { get; set; } - - /// - /// Name of target database - /// - public string TargetDatabaseName { get; set; } - /// /// Gets or sets the filepath where to save the generated script /// public string ScriptFilePath { get; set; } - - /// - /// Execution mode for the operation. Default is execution - /// - public TaskExecutionMode TaskExecutionMode { get; set; } } /// diff --git a/src/Microsoft.SqlTools.ServiceLayer/SchemaCompare/Contracts/SchemaComparePublishChangesRequest.cs b/src/Microsoft.SqlTools.ServiceLayer/SchemaCompare/Contracts/SchemaComparePublishChangesRequest.cs new file mode 100644 index 00000000..28e2d5fc --- /dev/null +++ b/src/Microsoft.SqlTools.ServiceLayer/SchemaCompare/Contracts/SchemaComparePublishChangesRequest.cs @@ -0,0 +1,45 @@ +// +// Copyright (c) Microsoft. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. +// +using Microsoft.SqlTools.Hosting.Protocol.Contracts; +using Microsoft.SqlTools.ServiceLayer.TaskServices; +using Microsoft.SqlTools.ServiceLayer.Utility; + +namespace Microsoft.SqlTools.ServiceLayer.SchemaCompare.Contracts +{ + /// + /// Parameters for a schema compare publish changes request. + /// + public class SchemaComparePublishChangesParams + { + /// + /// Operation id of the schema compare operation + /// + public string OperationId { get; set; } + + /// + /// Name of target server + /// + public string TargetServerName { get; set; } + + /// + /// Name of target database + /// + public string TargetDatabaseName { get; set; } + + /// + /// Execution mode for the operation. Default is execution + /// + public TaskExecutionMode TaskExecutionMode { get; set; } + } + + /// + /// Defines the Schema Compare publish changes request type + /// + class SchemaComparePublishChangesRequest + { + public static readonly RequestType Type = + RequestType.Create("schemaCompare/publish"); + } +} diff --git a/src/Microsoft.SqlTools.ServiceLayer/SchemaCompare/SchemaComparePublishChangesOperation.cs b/src/Microsoft.SqlTools.ServiceLayer/SchemaCompare/SchemaComparePublishChangesOperation.cs new file mode 100644 index 00000000..bc046a1e --- /dev/null +++ b/src/Microsoft.SqlTools.ServiceLayer/SchemaCompare/SchemaComparePublishChangesOperation.cs @@ -0,0 +1,73 @@ +// +// Copyright (c) Microsoft. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. +// +using Microsoft.SqlServer.Dac.Compare; +using Microsoft.SqlTools.ServiceLayer.SchemaCompare.Contracts; +using Microsoft.SqlTools.ServiceLayer.TaskServices; +using Microsoft.SqlTools.Utility; +using System; +using System.Diagnostics; +using System.IO; +using System.Threading; + +namespace Microsoft.SqlTools.ServiceLayer.SchemaCompare +{ + /// + /// Class to represent an in-progress schema compare publish changes operation + /// + class SchemaComparePublishChangesOperation : ITaskOperation + { + private CancellationTokenSource cancellation = new CancellationTokenSource(); + private bool disposed = false; + + /// + /// Gets the unique id associated with this instance. + /// + public string OperationId { get; private set; } + + public SchemaComparePublishChangesParams Parameters { get; } + + protected CancellationToken CancellationToken { get { return this.cancellation.Token; } } + + public string ErrorMessage { get; set; } + + public SqlTask SqlTask { get; set; } + + public SchemaComparisonResult ComparisonResult { get; set; } + + public SchemaComparePublishResult PublishResult { get; set; } + + public SchemaComparePublishChangesOperation(SchemaComparePublishChangesParams parameters, SchemaComparisonResult comparisonResult) + { + Validate.IsNotNull("parameters", parameters); + this.Parameters = parameters; + Validate.IsNotNull("comparisonResult", comparisonResult); + this.ComparisonResult = comparisonResult; + } + + public void Execute(TaskExecutionMode mode) + { + if (this.CancellationToken.IsCancellationRequested) + { + throw new OperationCanceledException(this.CancellationToken); + } + + try + { + this.PublishResult = this.ComparisonResult.PublishChangesToTarget(); + } + catch (Exception e) + { + ErrorMessage = e.Message; + Logger.Write(TraceEventType.Error, string.Format("Schema compare publish changes operation {0} failed with exception {1}", this.OperationId, e.Message)); + throw; + } + } + + // The schema compare public api doesn't currently take a cancellation token so the operation can't be cancelled + public void Cancel() + { + } + } +} diff --git a/src/Microsoft.SqlTools.ServiceLayer/SchemaCompare/SchemaCompareService.cs b/src/Microsoft.SqlTools.ServiceLayer/SchemaCompare/SchemaCompareService.cs index 55220e66..3a3a908b 100644 --- a/src/Microsoft.SqlTools.ServiceLayer/SchemaCompare/SchemaCompareService.cs +++ b/src/Microsoft.SqlTools.ServiceLayer/SchemaCompare/SchemaCompareService.cs @@ -43,6 +43,7 @@ namespace Microsoft.SqlTools.ServiceLayer.SchemaCopmare { serviceHost.SetRequestHandler(SchemaCompareRequest.Type, this.HandleSchemaCompareRequest); serviceHost.SetRequestHandler(SchemaCompareGenerateScriptRequest.Type, this.HandleSchemaCompareGenerateScriptRequest); + serviceHost.SetRequestHandler(SchemaComparePublishChangesRequest.Type, this.HandleSchemaComparePublishChangesRequest); } /// @@ -83,13 +84,13 @@ namespace Microsoft.SqlTools.ServiceLayer.SchemaCopmare Differences = operation.Differences }); } - catch + catch(Exception e) { await requestContext.SendResult(new SchemaCompareResult() { OperationId = operation != null ? operation.OperationId : null, Success = false, - ErrorMessage = operation.ErrorMessage, + ErrorMessage = operation == null ? e.Message : operation.ErrorMessage, }); } }); @@ -117,7 +118,7 @@ namespace Microsoft.SqlTools.ServiceLayer.SchemaCopmare // want to show filepath in task history instead of server and database metadata.ServerName = parameters.ScriptFilePath; metadata.DatabaseName = string.Empty; - metadata.Name = "Generate Script"; + metadata.Name = SR.GenerateScriptTaskName; sqlTask = SqlTaskManagerInstance.CreateAndRun(metadata); @@ -127,14 +128,50 @@ namespace Microsoft.SqlTools.ServiceLayer.SchemaCopmare ErrorMessage = operation.ErrorMessage }); } - catch + catch (Exception e) { await requestContext.SendResult(new ResultStatus() { Success = false, + ErrorMessage = operation == null ? e.Message : operation.ErrorMessage, + }); + } + } + + /// + /// Handles request for schema compare publish changes script + /// + /// + public async Task HandleSchemaComparePublishChangesRequest(SchemaComparePublishChangesParams parameters, RequestContext requestContext) + { + SchemaComparePublishChangesOperation operation = null; + try + { + SchemaComparisonResult compareResult = schemaCompareResults.Value[parameters.OperationId]; + operation = new SchemaComparePublishChangesOperation(parameters, compareResult); + SqlTask sqlTask = null; + TaskMetadata metadata = new TaskMetadata(); + metadata.TaskOperation = operation; + metadata.ServerName = parameters.TargetServerName; + metadata.DatabaseName = parameters.TargetDatabaseName; + metadata.Name = SR.PublishChangesTaskName; + + sqlTask = SqlTaskManagerInstance.CreateAndRun(metadata); + + await requestContext.SendResult(new ResultStatus() + { + Success = true, ErrorMessage = operation.ErrorMessage }); } + catch (Exception e) + { + await requestContext.SendResult(new ResultStatus() + { + Success = false, + ErrorMessage = operation == null ? e.Message : operation.ErrorMessage, + }); + } } private SqlTaskManager SqlTaskManagerInstance diff --git a/test/Microsoft.SqlTools.ServiceLayer.IntegrationTests/SchemaCompare/SchemaCompareServiceTests.cs b/test/Microsoft.SqlTools.ServiceLayer.IntegrationTests/SchemaCompare/SchemaCompareServiceTests.cs index c16b0df4..6643a8fb 100644 --- a/test/Microsoft.SqlTools.ServiceLayer.IntegrationTests/SchemaCompare/SchemaCompareServiceTests.cs +++ b/test/Microsoft.SqlTools.ServiceLayer.IntegrationTests/SchemaCompare/SchemaCompareServiceTests.cs @@ -301,6 +301,141 @@ CREATE TABLE [dbo].[table3] return schemaCompareRequestContext; } + private async Task>> SendAndValidateSchemaComparePublishChangesRequestDacpacToDatabase() + { + var result = GetLiveAutoCompleteTestObjects(); + var schemaCompareRequestContext = new Mock>(); + schemaCompareRequestContext.Setup(x => x.SendResult(It.IsAny())).Returns(Task.FromResult(new object())); + + SqlTestDb sourceDb = await SqlTestDb.CreateNewAsync(TestServerType.OnPrem, false, null, SourceScript, "SchemaCompareSource"); + SqlTestDb targetDb = await SqlTestDb.CreateNewAsync(TestServerType.OnPrem, false, null, null, "SchemaCompareTarget"); + string folderPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "SchemaCompareTest"); + Directory.CreateDirectory(folderPath); + + try + { + string sourceDacpacFilePath = CreateDacpac(sourceDb); + + SchemaCompareEndpointInfo sourceInfo = new SchemaCompareEndpointInfo(); + SchemaCompareEndpointInfo targetInfo = new SchemaCompareEndpointInfo(); + + sourceInfo.EndpointType = SchemaCompareEndpointType.Dacpac; + sourceInfo.PackageFilePath = sourceDacpacFilePath; + targetInfo.EndpointType = SchemaCompareEndpointType.Database; + targetInfo.DatabaseName = targetDb.DatabaseName; + + var schemaCompareParams = new SchemaCompareParams + { + SourceEndpointInfo = sourceInfo, + TargetEndpointInfo = targetInfo + }; + + SchemaCompareOperation schemaCompareOperation = new SchemaCompareOperation(schemaCompareParams, result.ConnectionInfo, result.ConnectionInfo); + schemaCompareOperation.Execute(TaskExecutionMode.Execute); + + Assert.True(schemaCompareOperation.ComparisonResult.IsValid); + Assert.False(schemaCompareOperation.ComparisonResult.IsEqual); + Assert.NotNull(schemaCompareOperation.ComparisonResult.Differences); + var enumerator = schemaCompareOperation.ComparisonResult.Differences.GetEnumerator(); + enumerator.MoveNext(); + Assert.True(enumerator.Current.SourceObject.Name.ToString().Equals("[dbo].[table1]")); + enumerator.MoveNext(); + Assert.True(enumerator.Current.SourceObject.Name.ToString().Equals("[dbo].[table2]")); + + // update target + var publishChangesParams = new SchemaComparePublishChangesParams + { + TargetDatabaseName = targetDb.DatabaseName, + OperationId = schemaCompareOperation.OperationId, + }; + + SchemaComparePublishChangesOperation publishChangesOperation = new SchemaComparePublishChangesOperation(publishChangesParams, schemaCompareOperation.ComparisonResult); + publishChangesOperation.Execute(TaskExecutionMode.Execute); + Assert.True(publishChangesOperation.PublishResult.Success); + Assert.Empty(publishChangesOperation.PublishResult.Errors); + + // Verify that there are no differences after the publish by running the comparison again + schemaCompareOperation.Execute(TaskExecutionMode.Execute); + + Assert.True(schemaCompareOperation.ComparisonResult.IsValid); + Assert.True(schemaCompareOperation.ComparisonResult.IsEqual); + Assert.Empty(schemaCompareOperation.ComparisonResult.Differences); + + // cleanup + VerifyAndCleanup(sourceDacpacFilePath); + } + finally + { + sourceDb.Cleanup(); + targetDb.Cleanup(); + } + return schemaCompareRequestContext; + } + + private async Task>> SendAndValidateSchemaComparePublishChangesRequestDatabaseToDatabase() + { + var result = GetLiveAutoCompleteTestObjects(); + var schemaCompareRequestContext = new Mock>(); + schemaCompareRequestContext.Setup(x => x.SendResult(It.IsAny())).Returns(Task.FromResult(new object())); + + SqlTestDb sourceDb = await SqlTestDb.CreateNewAsync(TestServerType.OnPrem, false, null, SourceScript, "SchemaCompareSource"); + SqlTestDb targetDb = await SqlTestDb.CreateNewAsync(TestServerType.OnPrem, false, null, null, "SchemaCompareTarget"); + + try + { + SchemaCompareEndpointInfo sourceInfo = new SchemaCompareEndpointInfo(); + SchemaCompareEndpointInfo targetInfo = new SchemaCompareEndpointInfo(); + + sourceInfo.EndpointType = SchemaCompareEndpointType.Database; + sourceInfo.DatabaseName = sourceDb.DatabaseName; + targetInfo.EndpointType = SchemaCompareEndpointType.Database; + targetInfo.DatabaseName = targetDb.DatabaseName; + + var schemaCompareParams = new SchemaCompareParams + { + SourceEndpointInfo = sourceInfo, + TargetEndpointInfo = targetInfo + }; + + SchemaCompareOperation schemaCompareOperation = new SchemaCompareOperation(schemaCompareParams, result.ConnectionInfo, result.ConnectionInfo); + schemaCompareOperation.Execute(TaskExecutionMode.Execute); + + Assert.True(schemaCompareOperation.ComparisonResult.IsValid); + Assert.False(schemaCompareOperation.ComparisonResult.IsEqual); + Assert.NotNull(schemaCompareOperation.ComparisonResult.Differences); + var enumerator = schemaCompareOperation.ComparisonResult.Differences.GetEnumerator(); + enumerator.MoveNext(); + Assert.True(enumerator.Current.SourceObject.Name.ToString().Equals("[dbo].[table1]")); + enumerator.MoveNext(); + Assert.True(enumerator.Current.SourceObject.Name.ToString().Equals("[dbo].[table2]")); + + // update target + var publishChangesParams = new SchemaComparePublishChangesParams + { + TargetDatabaseName = targetDb.DatabaseName, + OperationId = schemaCompareOperation.OperationId, + }; + + SchemaComparePublishChangesOperation publishChangesOperation = new SchemaComparePublishChangesOperation(publishChangesParams, schemaCompareOperation.ComparisonResult); + publishChangesOperation.Execute(TaskExecutionMode.Execute); + Assert.True(publishChangesOperation.PublishResult.Success); + Assert.Empty(publishChangesOperation.PublishResult.Errors); + + // Verify that there are no differences after the publish by running the comparison again + schemaCompareOperation.Execute(TaskExecutionMode.Execute); + + Assert.True(schemaCompareOperation.ComparisonResult.IsValid); + Assert.True(schemaCompareOperation.ComparisonResult.IsEqual); + Assert.Empty(schemaCompareOperation.ComparisonResult.Differences); + } + finally + { + sourceDb.Cleanup(); + targetDb.Cleanup(); + } + return schemaCompareRequestContext; + } + /// /// Verify the schema compare request comparing two dacpacs /// @@ -346,6 +481,25 @@ CREATE TABLE [dbo].[table3] Assert.NotNull(await SendAndValidateSchemaCompareGenerateScriptRequestDacpacToDatabase()); } + /// + /// Verify the schema compare publish changes request comparing a dacpac to a database + /// + [Fact] + public async void SchemaComparePublishChangesDacpacToDatabase() + { + Assert.NotNull(await SendAndValidateSchemaComparePublishChangesRequestDacpacToDatabase()); + } + + + /// + /// Verify the schema compare publish changes request comparing a database to a database + /// + [Fact] + public async void SchemaComparePublishChangesDatabaseToDatabase() + { + Assert.NotNull(await SendAndValidateSchemaComparePublishChangesRequestDatabaseToDatabase()); + } + private void VerifyAndCleanup(string filePath) { // Verify it was created