diff --git a/Packages.props b/Packages.props
index 2399365b..09e8d178 100644
--- a/Packages.props
+++ b/Packages.props
@@ -22,7 +22,7 @@
-
+
diff --git a/src/Microsoft.SqlTools.ServiceLayer/SchemaCompare/SchemaCompareOpenScmpOperation.cs b/src/Microsoft.SqlTools.ServiceLayer/SchemaCompare/SchemaCompareOpenScmpOperation.cs
index 268e4fe1..38f4a18e 100644
--- a/src/Microsoft.SqlTools.ServiceLayer/SchemaCompare/SchemaCompareOpenScmpOperation.cs
+++ b/src/Microsoft.SqlTools.ServiceLayer/SchemaCompare/SchemaCompareOpenScmpOperation.cs
@@ -173,9 +173,19 @@ namespace Microsoft.SqlTools.ServiceLayer.SchemaCompare
if (fs != null)
{
DacExtractTarget extractTarget;
- if (Enum.TryParse(fs.FirstOrDefault().Value, out extractTarget))
+ if(fs.FirstOrDefault() != null) // it is possible that this value is not set
{
- endpointInfo.ExtractTarget = extractTarget;
+ if (Enum.TryParse(fs.FirstOrDefault().Value, out extractTarget))
+ {
+ endpointInfo.ExtractTarget = extractTarget;
+ } else
+ {
+ endpointInfo.ExtractTarget = DacExtractTarget.SchemaObjectType; // set default but log an error
+ Logger.Write(TraceEventType.Error, string.Format("Schema compare open scmp operation failed during xml parsing with unknown ExtractTarget"));
+ }
+ } else
+ {
+ endpointInfo.ExtractTarget = DacExtractTarget.SchemaObjectType; // set the default if this value doesn't already exist in the scmp file
}
}
diff --git a/test/Microsoft.SqlTools.ServiceLayer.IntegrationTests/SchemaCompare/SchemaCompare/TestScmpFileTemplate.scmp b/test/Microsoft.SqlTools.ServiceLayer.IntegrationTests/SchemaCompare/SchemaCompare/TestScmpFileTemplate.scmp
new file mode 100644
index 00000000..74e4d07e
--- /dev/null
+++ b/test/Microsoft.SqlTools.ServiceLayer.IntegrationTests/SchemaCompare/SchemaCompare/TestScmpFileTemplate.scmp
@@ -0,0 +1,1025 @@
+
+
+ 10
+
+
+ @@SourceProjectFilePath@@
+ [dummyFolder\table1.sql,dummyFolder\table2.sql]
+ 150
+
+
+
+
+ @@TargetProjectFilePath@@
+ [dummyFolder\table2.sql,dummyFolder\table3.sql]
+ 150
+
+
+
+
+
+ Version
+ 1
+
+
+
+
+ PlanGenerationType
+ SqlDeploymentOptions
+
+
+ AllowExistingModelErrors
+ False
+
+
+ AllowIncompatiblePlatform
+ False
+
+
+ BackupDatabaseBeforeChanges
+ False
+
+
+ IgnoreIndexesStatisticsOnEnclaveEnabledColumns
+ False
+
+
+ BlockOnPossibleDataLoss
+ True
+
+
+ BlockWhenDriftDetected
+ False
+
+
+ CompareUsingTargetCollation
+ False
+
+
+ CommentOutSetVarDeclarations
+ False
+
+
+ CreateNewDatabase
+ False
+
+
+ DeployDatabaseInSingleUserMode
+ False
+
+
+ DisableAndReenableDdlTriggers
+ True
+
+
+ DisableIndexesForDataPhase
+ True
+
+
+ DisableParallelismForEnablingIndexes
+ False
+
+
+ DoNotAlterChangeDataCaptureObjects
+ True
+
+
+ DoNotAlterReplicatedObjects
+ True
+
+
+ DropConstraintsNotInSource
+ True
+
+
+ DropDmlTriggersNotInSource
+ True
+
+
+ DropExtendedPropertiesNotInSource
+ True
+
+
+ DropIndexesNotInSource
+ True
+
+
+ DropPermissionsNotInSource
+ False
+
+
+ DropObjectsNotInSource
+ True
+
+
+ DropRoleMembersNotInSource
+ False
+
+
+ DropStatisticsNotInSource
+ True
+
+
+ GenerateSmartDefaults
+ False
+
+
+ HashObjectNamesInLogs
+ False
+
+
+ IgnoreDdlTriggerOrder
+ False
+
+
+ IgnoreDdlTriggerState
+ False
+
+
+ IgnoreObjectPlacementOnPartitionScheme
+ True
+
+
+ IgnoreAuthorizer
+ False
+
+
+ IgnoreDefaultSchema
+ False
+
+
+ IgnoreRouteLifetime
+ True
+
+
+ IgnoreCryptographicProviderFilePath
+ True
+
+
+ IgnoreComments
+ False
+
+
+ IgnoreWhitespace
+ True
+
+
+ IgnoreKeywordCasing
+ True
+
+
+ IgnoreSemicolonBetweenStatements
+ True
+
+
+ IgnorePartitionSchemes
+ False
+
+
+ IgnoreTablePartitionOptions
+ False
+
+
+ IgnoreWithNocheckOnCheckConstraints
+ False
+
+
+ IgnoreWithNocheckOnForeignKeys
+ False
+
+
+ IgnoreIdentitySeed
+ False
+
+
+ IgnoreIncrement
+ False
+
+
+ IgnoreFillFactor
+ True
+
+
+ IgnoreIndexPadding
+ True
+
+
+ IgnoreColumnCollation
+ False
+
+
+ IgnoreColumnOrder
+ False
+
+
+ IgnoreLockHintsOnIndexes
+ False
+
+
+ IgnoreTableOptions
+ False
+
+
+ IgnoreIndexOptions
+ False
+
+
+ IgnoreDmlTriggerOrder
+ False
+
+
+ IgnoreDmlTriggerState
+ False
+
+
+ IgnoreAnsiNulls
+ True
+
+
+ IgnoreQuotedIdentifiers
+ True
+
+
+ IgnoreUserSettingsObjects
+ False
+
+
+ IgnoreFilegroupPlacement
+ True
+
+
+ IgnoreFullTextCatalogFilePath
+ True
+
+
+ IgnoreFileAndLogFilePath
+ True
+
+
+ IgnoreLoginSids
+ True
+
+
+ IgnoreNotForReplication
+ False
+
+
+ IgnoreFileSize
+ True
+
+
+ IgnoreSensitivityClassifications
+ False
+
+
+ AllowUnsafeRowLevelSecurityDataMovement
+ False
+
+
+ IncludeCompositeObjects
+ False
+
+
+ IncludeTransactionalScripts
+ False
+
+
+ IsAlwaysEncryptedParameterizationEnabled
+ False
+
+
+ NoAlterStatementsToChangeCLRTypes
+ False
+
+
+ PopulateFilesOnFileGroups
+ True
+
+
+ PreserveIdentityLastValues
+ False
+
+
+ RegisterDataTierApplication
+ False
+
+
+ RebuildIndexesOfflineForDataPhase
+ False
+
+
+ RestoreSequenceCurrentValue
+ True
+
+
+ ScriptDatabaseCollation
+ False
+
+
+ ScriptDatabaseCompatibility
+ False
+
+
+ ScriptDatabaseOptions
+ False
+
+
+ ScriptDeployStateChecks
+ False
+
+
+ ScriptFileSize
+ False
+
+
+ ScriptNewConstraintValidation
+ True
+
+
+ ScriptRefreshModule
+ True
+
+
+ TargetDatabaseName
+ TargetProject.sqlproj
+
+
+ TargetConnectionString
+ Integrated Security=True;Pooling=False;Connect Timeout=30
+
+
+ TreatVerificationErrorsAsWarnings
+ False
+
+
+ UnmodifiableObjectWarnings
+ True
+
+
+ VerifyCollationCompatibility
+ True
+
+
+ VerifyDeployment
+ True
+
+
+ RunDeploymentPlanExecutors
+ False
+
+
+ AllowDropBlockingAssemblies
+ False
+
+
+ DoNotEvaluateSqlCmdVariables
+ True
+
+
+ DoNotDropAggregates
+ False
+
+
+ DoNotDropApplicationRoles
+ False
+
+
+ DoNotDropAssemblies
+ False
+
+
+ DoNotDropAsymmetricKeys
+ False
+
+
+ DoNotDropAudits
+ False
+
+
+ DoNotDropBrokerPriorities
+ False
+
+
+ DoNotDropCertificates
+ False
+
+
+ DoNotDropClrUserDefinedTypes
+ False
+
+
+ DoNotDropColumnEncryptionKeys
+ False
+
+
+ DoNotDropColumnMasterKeys
+ False
+
+
+ DoNotDropContracts
+ False
+
+
+ DoNotDropCredentials
+ False
+
+
+ DoNotDropDatabaseScopedCredentials
+ False
+
+
+ DoNotDropCryptographicProviders
+ False
+
+
+ DoNotDropDatabaseAuditSpecifications
+ False
+
+
+ DoNotDropDatabaseRoles
+ False
+
+
+ DoNotDropDatabaseTriggers
+ False
+
+
+ IgnoreDatabaseWorkloadGroups
+ False
+
+
+ DoNotDropDatabaseWorkloadGroups
+ False
+
+
+ IgnoreWorkloadClassifiers
+ False
+
+
+ DoNotDropWorkloadClassifiers
+ False
+
+
+ DoNotDropDefaults
+ False
+
+
+ DoNotDropEndpoints
+ False
+
+
+ DoNotDropErrorMessages
+ False
+
+
+ DoNotDropEventNotifications
+ False
+
+
+ DoNotDropEventSessions
+ False
+
+
+ DoNotDropExtendedProperties
+ False
+
+
+ DoNotDropExternalDataSources
+ False
+
+
+ DoNotDropExternalFileFormats
+ False
+
+
+ DoNotDropExternalLanguages
+ False
+
+
+ DoNotDropExternalLibraries
+ False
+
+
+ DoNotDropExternalStreamingJobs
+ False
+
+
+ DoNotDropExternalTables
+ False
+
+
+ DoNotDropExternalStreams
+ False
+
+
+ DoNotDropFilegroups
+ False
+
+
+ DoNotDropFiles
+ False
+
+
+ DoNotDropFileTables
+ False
+
+
+ DoNotDropFullTextCatalogs
+ False
+
+
+ DoNotDropFullTextStoplists
+ False
+
+
+ DoNotDropTableValuedFunctions
+ False
+
+
+ DoNotDropLinkedServerLogins
+ False
+
+
+ DoNotDropLinkedServers
+ False
+
+
+ DoNotDropLogins
+ False
+
+
+ DoNotDropMessageTypes
+ False
+
+
+ DoNotDropPartitionFunctions
+ False
+
+
+ DoNotDropPartitionSchemes
+ False
+
+
+ DoNotDropPermissions
+ False
+
+
+ DoNotDropQueues
+ False
+
+
+ DoNotDropRemoteServiceBindings
+ False
+
+
+ DoNotDropRoleMembership
+ False
+
+
+ DoNotDropRoutes
+ False
+
+
+ DoNotDropRules
+ False
+
+
+ DoNotDropScalarValuedFunctions
+ False
+
+
+ DoNotDropSearchPropertyLists
+ False
+
+
+ DoNotDropSecurityPolicies
+ False
+
+
+ DoNotDropSequences
+ False
+
+
+ DoNotDropServerAuditSpecifications
+ False
+
+
+ DoNotDropServerRoleMembership
+ False
+
+
+ DoNotDropServerRoles
+ False
+
+
+ DoNotDropServerTriggers
+ False
+
+
+ DoNotDropServices
+ False
+
+
+ DoNotDropSignatures
+ False
+
+
+ DoNotDropStoredProcedures
+ False
+
+
+ DoNotDropSymmetricKeys
+ False
+
+
+ DoNotDropSynonyms
+ False
+
+
+ DoNotDropTables
+ False
+
+
+ DoNotDropUserDefinedDataTypes
+ False
+
+
+ DoNotDropUserDefinedTableTypes
+ False
+
+
+ DoNotDropUsers
+ False
+
+
+ DoNotDropViews
+ False
+
+
+ DoNotDropXmlSchemaCollections
+ False
+
+
+ ExcludeAggregates
+ False
+
+
+ ExcludeApplicationRoles
+ False
+
+
+ ExcludeAssemblies
+ False
+
+
+ ExcludeAsymmetricKeys
+ False
+
+
+ ExcludeAudits
+ True
+
+
+ ExcludeBrokerPriorities
+ False
+
+
+ ExcludeCertificates
+ False
+
+
+ ExcludeClrUserDefinedTypes
+ False
+
+
+ ExcludeColumnEncryptionKeys
+ False
+
+
+ ExcludeColumnMasterKeys
+ False
+
+
+ ExcludeContracts
+ False
+
+
+ ExcludeCredentials
+ True
+
+
+ ExcludeDatabaseScopedCredentials
+ True
+
+
+ ExcludeCryptographicProviders
+ True
+
+
+ ExcludeDatabaseAuditSpecifications
+ True
+
+
+ ExcludeDatabaseRoles
+ False
+
+
+ ExcludeDatabaseTriggers
+ False
+
+
+ ExcludeDefaults
+ False
+
+
+ ExcludeEndpoints
+ True
+
+
+ ExcludeErrorMessages
+ True
+
+
+ ExcludeEventNotifications
+ False
+
+
+ ExcludeExternalDataSources
+ False
+
+
+ ExcludeExternalFileFormats
+ False
+
+
+ ExcludeExternalLanguages
+ False
+
+
+ ExcludeExternalLibraries
+ False
+
+
+ ExcludeExternalStreamingJobs
+ False
+
+
+ ExcludeExternalTables
+ False
+
+
+ ExcludeExternalStreams
+ False
+
+
+ ExcludeEventSessions
+ True
+
+
+ ExcludeFilegroups
+ False
+
+
+ ExcludeFiles
+ True
+
+
+ ExcludeFileTables
+ False
+
+
+ ExcludeFullTextCatalogs
+ False
+
+
+ ExcludeFullTextStoplists
+ False
+
+
+ ExcludeTableValuedFunctions
+ False
+
+
+ ExcludeLinkedServerLogins
+ True
+
+
+ ExcludeLinkedServers
+ True
+
+
+ ExcludeLogins
+ True
+
+
+ ExcludeMessageTypes
+ False
+
+
+ ExcludePartitionFunctions
+ False
+
+
+ ExcludePartitionSchemes
+ False
+
+
+ ExcludeQueues
+ False
+
+
+ ExcludeRemoteServiceBindings
+ False
+
+
+ ExcludeRoutes
+ True
+
+
+ ExcludeRules
+ False
+
+
+ ExcludeScalarValuedFunctions
+ False
+
+
+ ExcludeSearchPropertyLists
+ False
+
+
+ ExcludeSecurityPolicies
+ False
+
+
+ ExcludeSequences
+ False
+
+
+ ExcludeServerAuditSpecifications
+ True
+
+
+ ExcludeServerRoleMembership
+ True
+
+
+ ExcludeServerRoles
+ True
+
+
+ ExcludeServerTriggers
+ True
+
+
+ ExcludeServices
+ False
+
+
+ ExcludeSignatures
+ False
+
+
+ ExcludeStoredProcedures
+ False
+
+
+ ExcludeSymmetricKeys
+ False
+
+
+ ExcludeSynonyms
+ False
+
+
+ ExcludeTables
+ False
+
+
+ ExcludeUserDefinedDataTypes
+ False
+
+
+ ExcludeUserDefinedTableTypes
+ False
+
+
+ ExcludeUsers
+ False
+
+
+ ExcludeViews
+ False
+
+
+ ExcludeXmlSchemaCollections
+ False
+
+
+ AllowExternalLibraryPaths
+ False
+
+
+ AllowExternalLanguagePaths
+ False
+
+
+ Microsoft.Data.Tools.Schema.Sql.SchemaModel.SqlServerDdlTrigger
+ ExcludedType
+
+
+ Microsoft.Data.Tools.Schema.Sql.SchemaModel.SqlRoute
+ ExcludedType
+
+
+ Microsoft.Data.Tools.Schema.Sql.SchemaModel.SqlLinkedServerLogin
+ ExcludedType
+
+
+ Microsoft.Data.Tools.Schema.Sql.SchemaModel.SqlEndpoint
+ ExcludedType
+
+
+ Microsoft.Data.Tools.Schema.Sql.SchemaModel.SqlErrorMessage
+ ExcludedType
+
+
+ Microsoft.Data.Tools.Schema.Sql.SchemaModel.SqlFile
+ ExcludedType
+
+
+ Microsoft.Data.Tools.Schema.Sql.SchemaModel.SqlLogin
+ ExcludedType
+
+
+ Microsoft.Data.Tools.Schema.Sql.SchemaModel.SqlLinkedServer
+ ExcludedType
+
+
+ Microsoft.Data.Tools.Schema.Sql.SchemaModel.SqlCredential
+ ExcludedType
+
+
+ Microsoft.Data.Tools.Schema.Sql.SchemaModel.SqlDatabaseCredential
+ ExcludedType
+
+
+ Microsoft.Data.Tools.Schema.Sql.SchemaModel.SqlDatabaseEncryptionKey
+ ExcludedType
+
+
+ Microsoft.Data.Tools.Schema.Sql.SchemaModel.SqlMasterKey
+ ExcludedType
+
+
+ Microsoft.Data.Tools.Schema.Sql.SchemaModel.SqlDatabaseAuditSpecification
+ ExcludedType
+
+
+ Microsoft.Data.Tools.Schema.Sql.SchemaModel.SqlServerAudit
+ ExcludedType
+
+
+ Microsoft.Data.Tools.Schema.Sql.SchemaModel.SqlServerAuditSpecification
+ ExcludedType
+
+
+ Microsoft.Data.Tools.Schema.Sql.SchemaModel.SqlCryptographicProvider
+ ExcludedType
+
+
+ Microsoft.Data.Tools.Schema.Sql.SchemaModel.SqlUserDefinedServerRole
+ ExcludedType
+
+
+ Microsoft.Data.Tools.Schema.Sql.SchemaModel.SqlEventSession
+ ExcludedType
+
+
+ Microsoft.Data.Tools.Schema.Sql.SchemaModel.SqlDatabaseOptions
+ ExcludedType
+
+
+ Microsoft.Data.Tools.Schema.Sql.SchemaModel.SqlEventNotification
+ ExcludedType
+
+
+ Microsoft.Data.Tools.Schema.Sql.SchemaModel.SqlServerRoleMembership
+ ExcludedType
+
+
+ Microsoft.Data.Tools.Schema.Sql.SchemaModel.SqlDatabaseEventSession
+ ExcludedType
+
+
+ Microsoft.Data.Tools.Schema.Sql.SchemaModel.SqlAssemblyFile
+ ExcludedType
+
+
+
+
+ 2
+ 100
+ Equals_Objects,Not_Supported_Deploy
+
+
\ No newline at end of file
diff --git a/test/Microsoft.SqlTools.ServiceLayer.IntegrationTests/SchemaCompare/SchemaCompareServiceTests.cs b/test/Microsoft.SqlTools.ServiceLayer.IntegrationTests/SchemaCompare/SchemaCompareServiceTests.cs
index 8ef7e3ef..a803e7c5 100644
--- a/test/Microsoft.SqlTools.ServiceLayer.IntegrationTests/SchemaCompare/SchemaCompareServiceTests.cs
+++ b/test/Microsoft.SqlTools.ServiceLayer.IntegrationTests/SchemaCompare/SchemaCompareServiceTests.cs
@@ -81,6 +81,8 @@ WITH VALUES
ADD FILEGROUP [MyFileGroup] CONTAINS MEMORY_OPTIMIZED_DATA;
GO";
+ private string scmpFolder = Path.Combine("..", "..", "..", "SchemaCompare", "SchemaCompare");
+
///
/// Verify the schema compare request comparing two dacpacs
///
@@ -1225,7 +1227,6 @@ WITH VALUES
string filePath = Path.Combine(folderPath, string.Format("SchemaCompareOpenScmpTest{0}.scmp", DateTime.Now.ToFileTime()));
compare.SaveToFile(filePath);
- SchemaCompareTestUtils.VerifyAndCleanup(Directory.GetParent((targetEndpoint as SchemaCompareProjectEndpoint).ProjectFilePath).FullName);
await VerifyContentAndCleanupAsync(filePath, "ObjectType");
}
finally
@@ -1235,6 +1236,56 @@ WITH VALUES
}
}
+ ///
+ /// Verifies https://github.com/microsoft/azuredatastudio/issues/22728 -- Schema compare open scmp file not backward compatible
+ ///
+ [Test]
+ public void VerifyOpenScmpIsBackwardCompatible()
+ {
+ string testFolderPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "SchemaCompareTest", $"{TestContext.CurrentContext?.Test?.Name}_{DateTime.Now.Ticks.ToString()}");
+ Directory.CreateDirectory(testFolderPath);
+ string testScmpFileTemplate = Path.Combine(testFolderPath, "TestScmpFileTemplate.scmp");
+ File.Copy(Path.Combine(scmpFolder, "TestScmpFileTemplate.scmp"), testScmpFileTemplate);
+
+ string testScmpFile = LoadScmpFileTemplate(testTemplateFolderPath: scmpFolder, testWorkingFolderPath: testFolderPath, templateFileName: "TestScmpFileTemplate.scmp", fileName: "TestScmpFile.scmp");
+ var schemaCompareOpenScmpParams = new SchemaCompareOpenScmpParams
+ {
+ FilePath = testScmpFile
+ };
+
+ SchemaCompareOpenScmpOperation schemaCompareOpenScmpOperation = new SchemaCompareOpenScmpOperation(schemaCompareOpenScmpParams);
+ schemaCompareOpenScmpOperation.Execute(TaskExecutionMode.Execute);
+
+ Assert.NotNull(schemaCompareOpenScmpOperation.Result);
+ Assert.True(schemaCompareOpenScmpOperation.Result.Success);
+ Assert.AreEqual(schemaCompareOpenScmpOperation.Result.SourceEndpointInfo.ProjectFilePath, Path.Combine(testFolderPath, "SourceProject.sqlproj"), "Source project was expected to exist but did not");
+ Assert.AreEqual(schemaCompareOpenScmpOperation.Result.SourceEndpointInfo.ExtractTarget, DacExtractTarget.SchemaObjectType, $"Source project was expected to have SchemaObjectType as extract target but {schemaCompareOpenScmpOperation.Result.SourceEndpointInfo.ExtractTarget} was set instead");
+ Assert.AreEqual(schemaCompareOpenScmpOperation.Result.TargetEndpointInfo.ProjectFilePath, Path.Combine(testFolderPath, "TargetProject.sqlproj"), "Target project was expected to exist but did not");
+ Assert.AreEqual(schemaCompareOpenScmpOperation.Result.TargetEndpointInfo.ExtractTarget, DacExtractTarget.SchemaObjectType, $"Target project was expected to have SchemaObjectType as extract target but {schemaCompareOpenScmpOperation.Result.TargetEndpointInfo.ExtractTarget} was set instead");
+
+ SchemaCompareTestUtils.VerifyAndCleanup(testFolderPath);
+ }
+
+ private string LoadScmpFileTemplate(string testTemplateFolderPath, string testWorkingFolderPath, string templateFileName, string fileName)
+ {
+ string templatePath = Path.Combine(testTemplateFolderPath, templateFileName);
+ string text = File.ReadAllText(templatePath);
+
+ string sourceDummyProject = Path.Combine(testWorkingFolderPath, "SourceProject.sqlproj");
+ string targetDummyProject = Path.Combine(testWorkingFolderPath, "TargetProject.sqlproj");
+
+ text = text.Replace($"@@SourceProjectFilePath@@", sourceDummyProject);
+ text = text.Replace($"@@TargetProjectFilePath@@", targetDummyProject);
+
+ File.Create(sourceDummyProject).Close();
+ File.Create(targetDummyProject).Close();
+
+ string scmpPath = Path.Combine(testWorkingFolderPath, fileName);
+ File.WriteAllText(scmpPath, text);
+
+ return scmpPath;
+ }
+
///
/// Verify the schema compare Service Calls ends to end
///