public SqlBuildRunData GetSqlBuildRunData_TransactionalNotTrial(SqlSyncBuildData buildData) { SqlBuildRunData runData = new SqlBuildRunData() { BuildData = buildData, BuildDescription = "UnitTestRun", BuildFileName = @"C:\temp\UnitTestBuildFile.sbm", BuildType = "Development", ProjectFileName = @"C:\temp\ProjectFile.xml", Server = this.serverName, StartIndex = 0 }; runData.IsTransactional = true; runData.IsTrial = false; runData.TargetDatabaseOverrides = GetDatabaseOverrides(); return(runData); }
public void ProcessBuildTest_RollbackWithThreeRetries() { Initialization init = GetInitializationObject(); init.TableLockingLoopCount = 10000000; SqlSyncBuildData buildData = init.CreateSqlSyncSqlBuildDataObject(); init.AddScriptForProcessBuild(ref buildData, true, 1); SqlBuildHelper target = init.CreateSqlBuildHelper(buildData); SqlBuildRunData runData = init.GetSqlBuildRunData_TransactionalNotTrial(buildData); BackgroundWorker bgWorker = init.GetBackgroundWorker(); DoWorkEventArgs e = new DoWorkEventArgs(null); string serverName = init.serverName; bool isMultiDbRun = false; ScriptBatchCollection scriptBatchColl = init.GetScriptBatchCollectionForProcessBuild(); int allowableTimeoutRetries = 3; Thread THRInfinite = null; try { THRInfinite = new Thread(new ParameterizedThreadStart(StartInfiniteLockingThread)); THRInfinite.Start(init); string expected = BuildItemStatus.RolledBackAfterRetries; SqlSyncBuildData.BuildRow actual; actual = target.ProcessBuild(runData, bgWorker, e, serverName, isMultiDbRun, scriptBatchColl, allowableTimeoutRetries); Assert.AreEqual(expected, actual.FinalStatus); } finally { if (THRInfinite != null) { THRInfinite.Interrupt(); } } }
public void ProcessBuildTest_CommitWithRetriesNotUsed() { Initialization init = GetInitializationObject(); SqlSyncBuildData buildData = init.CreateSqlSyncSqlBuildDataObject(); init.AddScriptForProcessBuild(ref buildData, true, 20); SqlBuildHelper target = init.CreateSqlBuildHelper(buildData); SqlBuildRunData runData = init.GetSqlBuildRunData_TransactionalNotTrial(buildData); BackgroundWorker bgWorker = init.GetBackgroundWorker(); DoWorkEventArgs e = new DoWorkEventArgs(null); string serverName = init.serverName; bool isMultiDbRun = false; ScriptBatchCollection scriptBatchColl = init.GetScriptBatchCollectionForProcessBuild(); int allowableTimeoutRetries = 3; string expected = BuildItemStatus.Committed; SqlSyncBuildData.BuildRow actual; actual = target.ProcessBuild(runData, bgWorker, e, serverName, isMultiDbRun, scriptBatchColl, allowableTimeoutRetries); Assert.AreEqual(expected, actual.FinalStatus); }
private bool ProcessSyncronizationPackages(IEnumerable <string> sbmPackages, ConnectionData toUpdate, bool runAsTrial, bool continueOnFailure) { log.LogInformation($"Starting synchronization of {toUpdate.DatabaseName} with {sbmPackages.Count()} packages..."); string projFileName = string.Empty; string projectFilePath = string.Empty; string workingDirectory = string.Empty; string result = string.Empty; foreach (var sbmPackageName in sbmPackages) { log.LogInformation($"Synchronization run for {Path.GetFileName(sbmPackageName)}"); //Unzip and read the package SqlSyncBuildData buildData; if (!SqlBuildFileHelper.ExtractSqlBuildZipFile(sbmPackageName, ref workingDirectory, ref projectFilePath, ref projFileName, out result)) { PushInfo(string.Format("Unable to extract build file {0}. See log for details", sbmPackageName)); return(false); } if (!SqlBuildFileHelper.LoadSqlBuildProjectFile(out buildData, projFileName, false)) { PushInfo(string.Format("Unable to load build file {0}. See log for details", sbmPackageName)); return(false); } //set the build data for a new run foreach (SqlSyncBuildData.ScriptRow scriptRow in buildData.Script) { scriptRow.Database = "placeholder"; scriptRow.AllowMultipleRuns = true; } List <DatabaseOverride> lstOverride = new List <DatabaseOverride>(); lstOverride.Add(new DatabaseOverride() { DefaultDbTarget = "placeholder", OverrideDbTarget = toUpdate.DatabaseName, }); //Set the run meta-data SqlSync.SqlBuild.SqlBuildRunData runData = new SqlBuildRunData() { BuildData = buildData, BuildType = BuildType.Other, BuildDescription = new Random().Next(int.MinValue, int.MaxValue).ToString(), //assign random build description StartIndex = -1000, //make sure start a the beginning ProjectFileName = projFileName, IsTrial = runAsTrial, BuildFileName = sbmPackageName, IsTransactional = true, TargetDatabaseOverrides = lstOverride }; //Execute the package SqlBuildHelper helper = new SqlBuildHelper(toUpdate, false, string.Empty, runData.IsTransactional); helper.BuildCommittedEvent += new BuildCommittedEventHandler(helper_BuildCommittedEvent); helper.BuildErrorRollBackEvent += new EventHandler(helper_BuildErrorRollBackEvent); BackgroundWorker bg = new BackgroundWorker() { WorkerReportsProgress = true, WorkerSupportsCancellation = true }; DoWorkEventArgs e = new DoWorkEventArgs(null); PushInfo(string.Format("Applying {0}", Path.GetFileName(sbmPackageName))); helper.ProcessBuild(runData, 0, bg, e); if (lastBuildSuccessful) { string message = string.Format("Successfully applied {0}", Path.GetFileName(sbmPackageName)); PushInfo(message); log.LogInformation(message); } else { string message = string.Format("Failed to apply {0}", Path.GetFileName(sbmPackageName)); PushInfo(message); log.LogInformation(message); if (!continueOnFailure) { PushInfo("Cancelling sync."); return(false); } else { PushInfo("Continue On Failure set. Continuing sync process..."); } } } return(true); }
/// <summary> /// Performs the database scripts execution against the specified server/ database settings /// </summary> /// <param name="serverName">Name of the SQL server to target</param> /// <param name="overrides">List of database override settings to use in execution</param> /// <returns></returns> internal async Task <int> RunDatabaseBuild() { this.returnValue = (int)RunnerReturn.BuildResultInconclusive; ConnectionData connData = null; BackgroundWorker bg = null; DoWorkEventArgs e = null; SqlBuildRunData runData = new SqlBuildRunData(); string targetDatabase = overrides[0].OverrideDbTarget; string loggingDirectory = Path.Combine(ThreadedExecution.WorkingDirectory, server, targetDatabase); try { //Start setting properties on the object that contains the run configuration data. runData.BuildType = "Other"; if (!string.IsNullOrEmpty(cmdArgs.Description)) { runData.BuildDescription = cmdArgs.Description; } else { runData.BuildDescription = "Threaded Multi-Database. Run ID:" + ThreadedExecution.RunID; } runData.IsTrial = this.isTrial; runData.RunScriptOnly = false; runData.TargetDatabaseOverrides = overrides; runData.Server = this.server; runData.IsTransactional = cmdArgs.Transactional; if (this.cmdArgs.LogToDatabaseName.Length > 0) { runData.LogToDatabaseName = this.cmdArgs.LogToDatabaseName; } runData.PlatinumDacPacFileName = cmdArgs.DacPacArgs.PlatinumDacpac; runData.BuildRevision = cmdArgs.BuildRevision; runData.DefaultScriptTimeout = cmdArgs.DefaultScriptTimeout; runData.AllowObjectDelete = cmdArgs.AllowObjectDelete; //Initilize the logging directory for this run if (!Directory.Exists(loggingDirectory)) { Directory.CreateDirectory(loggingDirectory); } if (forceCustomDacpac) { runData.ForceCustomDacpac = true; //This will set the BuildData and BuildFileName and ProjectFileName properties on runData var status = DacPacHelper.UpdateBuildRunDataForDacPacSync(ref runData, server, targetDatabase, this.authType, this.username, this.password, loggingDirectory, cmdArgs.BuildRevision, cmdArgs.DefaultScriptTimeout, cmdArgs.AllowObjectDelete); switch (status) { case DacpacDeltasStatus.Success: //nothing to do break; case DacpacDeltasStatus.InSync: case DacpacDeltasStatus.OnlyPostDeployment: log.LogInformation($"Target database {targetDatabase} is already in sync with {cmdArgs.DacPacArgs.PlatinumDacpac}. Nothing to do!"); this.returnValue = (int)RunnerReturn.DacpacDatabasesInSync; break; default: log.LogError($"Error creating custom dacpac and scripts for {targetDatabase}. No update was performed"); this.returnValue = (int)RunnerReturn.PackageCreationError; return((int)RunnerReturn.PackageCreationError);; } } else { runData.ForceCustomDacpac = false; //Get a full copy of the build data to work with (avoid threading sync issues) SqlSyncBuildData buildData = new SqlSyncBuildData(); string xml = "<?xml version=\"1.0\" standalone=\"yes\"?>\r\n" + ThreadedExecution.BuildData.GetXml(); using (StringReader sr = new StringReader(xml)) { buildData.ReadXml(sr); } //Clear out any existing ComittedScript data.. just log what is relevent to this run. buildData.CommittedScript.Clear(); runData.BuildData = buildData; runData.ProjectFileName = Path.Combine(loggingDirectory, Path.GetFileName(ThreadedExecution.ProjectFileName)); runData.BuildFileName = ThreadedExecution.BuildZipFileName; } //Create a connection object.. all we need is the server here, the DB will be filled in at execution time connData = new ConnectionData(server, ""); if (this.cmdArgs.AuthenticationArgs.UserName.Length > 0 && this.cmdArgs.AuthenticationArgs.Password.Length > 0) { connData.UserId = cmdArgs.AuthenticationArgs.UserName; connData.Password = cmdArgs.AuthenticationArgs.Password; } connData.AuthenticationType = this.cmdArgs.AuthenticationArgs.AuthenticationType; //Set the log file name string logFile = Path.Combine(loggingDirectory, "ExecutionLog.log"); //Create the objects that will handle the event communication back. bg = new BackgroundWorker(); //bg.ProgressChanged += Bg_ProgressChanged; bg.WorkerReportsProgress = true; e = new DoWorkEventArgs(null); } catch (Exception exe) { log.LogError(exe, $"Error Initializing run for {this.TargetTag}"); WriteErrorLog(loggingDirectory, exe.ToString()); this.returnValue = (int)ExecutionReturn.RunInitializationError; return((int)ExecutionReturn.RunInitializationError);; } log.LogDebug("Initializing run for " + this.TargetTag + ". Starting \"ProcessBuild\""); try { //Initilize the run helper object and kick it off. SqlBuildHelper helper = new SqlBuildHelper(connData, true, string.Empty, cmdArgs.Transactional); //don't need an "external" log for this, it's all external! helper.BuildCommittedEvent += new BuildCommittedEventHandler(helper_BuildCommittedEvent); helper.BuildErrorRollBackEvent += new EventHandler(helper_BuildErrorRollBackEvent); helper.BuildSuccessTrialRolledBackEvent += new EventHandler(helper_BuildSuccessTrialRolledBackEvent); await Task.Run(() => { helper.ProcessBuild(runData, bg, e, ThreadedExecution.BatchColl, this.buildRequestedBy, cmdArgs.TimeoutRetryCount); }); } catch (Exception exe) { log.LogError("Error Processing run for " + this.TargetTag, exe); WriteErrorLog(loggingDirectory, exe.ToString()); this.returnValue = (int)ExecutionReturn.ProcessBuildError; return((int)ExecutionReturn.ProcessBuildError);; } return(0); }