diff --git a/src/Microsoft.SqlTools.ServiceLayer/DisasterRecovery/BackupUtilities.cs b/src/Microsoft.SqlTools.ServiceLayer/DisasterRecovery/BackupOperation.cs
similarity index 88%
rename from src/Microsoft.SqlTools.ServiceLayer/DisasterRecovery/BackupUtilities.cs
rename to src/Microsoft.SqlTools.ServiceLayer/DisasterRecovery/BackupOperation.cs
index 7ce1c47a..c5e8d67a 100644
--- a/src/Microsoft.SqlTools.ServiceLayer/DisasterRecovery/BackupUtilities.cs
+++ b/src/Microsoft.SqlTools.ServiceLayer/DisasterRecovery/BackupOperation.cs
@@ -19,7 +19,7 @@ namespace Microsoft.SqlTools.ServiceLayer.DisasterRecovery
///
/// This class implements backup operations
///
- public class BackupUtilities : IBackupUtilities
+ public class BackupOperation : IBackupOperation
{
private CDataContainer dataContainer;
private ServerConnection serverConnection;
@@ -94,7 +94,7 @@ namespace Microsoft.SqlTools.ServiceLayer.DisasterRecovery
///
/// Ctor
///
- public BackupUtilities()
+ public BackupOperation()
{
}
@@ -110,7 +110,7 @@ namespace Microsoft.SqlTools.ServiceLayer.DisasterRecovery
{
this.dataContainer = dataContainer;
this.serverConnection = new ServerConnection(sqlConnection);
- this.backupRestoreUtil = new CommonUtilities(this.dataContainer, this.serverConnection);
+ this.backupRestoreUtil = new CommonUtilities(this.dataContainer, this.serverConnection);
}
///
@@ -152,11 +152,12 @@ namespace Microsoft.SqlTools.ServiceLayer.DisasterRecovery
public void PerformBackup()
{
this.backup = new Backup();
+ this.backup.Database = this.backupInfo.DatabaseName;
+ this.backup.Action = this.backupActionType;
+ this.backup.Incremental = this.isBackupIncremental;
this.SetBackupProps();
- backup.Database = this.backupInfo.DatabaseName;
- backup.Action = this.backupActionType;
- backup.Incremental = this.isBackupIncremental;
- if (backup.Action == BackupActionType.Files)
+
+ if (this.backup.Action == BackupActionType.Files)
{
IDictionaryEnumerator filegroupEnumerator = this.backupInfo.SelectedFileGroup.GetEnumerator();
filegroupEnumerator.Reset();
@@ -169,14 +170,14 @@ namespace Microsoft.SqlTools.ServiceLayer.DisasterRecovery
if (currentKey.IndexOf(",", StringComparison.Ordinal) < 0)
{
// is a file group
- backup.DatabaseFileGroups.Add(currentValue);
+ this.backup.DatabaseFileGroups.Add(currentValue);
}
else
{
// is a file
int idx = currentValue.IndexOf(".", StringComparison.Ordinal);
currentValue = currentValue.Substring(idx + 1, currentValue.Length - idx - 1);
- backup.DatabaseFiles.Add(currentValue);
+ this.backup.DatabaseFiles.Add(currentValue);
}
}
}
@@ -187,7 +188,7 @@ namespace Microsoft.SqlTools.ServiceLayer.DisasterRecovery
isBackupToUrl = true;
}
- backup.BackupSetName = this.backupInfo.BackupsetName;
+ this.backup.BackupSetName = this.backupInfo.BackupsetName;
if (false == isBackupToUrl)
{
@@ -205,19 +206,19 @@ namespace Microsoft.SqlTools.ServiceLayer.DisasterRecovery
if ((this.backupDeviceType == BackupDeviceType.Disk && backupDeviceType == constDeviceTypeFile)
|| (this.backupDeviceType == BackupDeviceType.Tape && backupDeviceType == constDeviceTypeTape))
{
- backup.Devices.AddDevice(destName, DeviceType.LogicalDevice);
+ this.backup.Devices.AddDevice(destName, DeviceType.LogicalDevice);
}
break;
case (int)DeviceType.File:
if (this.backupDeviceType == BackupDeviceType.Disk)
{
- backup.Devices.AddDevice(destName, DeviceType.File);
+ this.backup.Devices.AddDevice(destName, DeviceType.File);
}
break;
case (int)DeviceType.Tape:
if (this.backupDeviceType == BackupDeviceType.Tape)
{
- backup.Devices.AddDevice(destName, DeviceType.Tape);
+ this.backup.Devices.AddDevice(destName, DeviceType.Tape);
}
break;
}
@@ -225,15 +226,15 @@ namespace Microsoft.SqlTools.ServiceLayer.DisasterRecovery
}
//TODO: This should be changed to get user inputs
- backup.FormatMedia = false;
- backup.Initialize = false;
- backup.SkipTapeHeader = true;
- backup.Checksum = false;
- backup.ContinueAfterError = false;
- backup.LogTruncation = BackupTruncateLogType.Truncate;
+ this.backup.FormatMedia = false;
+ this.backup.Initialize = false;
+ this.backup.SkipTapeHeader = true;
+ this.backup.Checksum = false;
+ this.backup.ContinueAfterError = false;
+ this.backup.LogTruncation = BackupTruncateLogType.Truncate;
// Execute backup
- backup.SqlBackup(this.dataContainer.Server);
+ this.backup.SqlBackup(this.dataContainer.Server);
}
///
@@ -278,20 +279,11 @@ namespace Microsoft.SqlTools.ServiceLayer.DisasterRecovery
///
private bool BackupToUrlSupported()
{
- return BackupRestoreBase.IsBackupUrlDeviceSupported(this.dataContainer.Server.PingSqlServerVersion(this.dataContainer.ServerName)); //@@ originally, DataContainer.Server.ServerVersion
+ return BackupRestoreBase.IsBackupUrlDeviceSupported(this.dataContainer.Server.PingSqlServerVersion(this.dataContainer.ServerName));
}
#endregion
- private string GetDefaultBackupSetName()
- {
- string backupName = this.backupInfo.DatabaseName + "-"
- + this.backupType.ToString() + " "
- + this.backupComponent.ToString() + " "
- + BackupConstants.Backup;
- return backupName;
- }
-
private void SetBackupProps()
{
try
@@ -327,7 +319,6 @@ namespace Microsoft.SqlTools.ServiceLayer.DisasterRecovery
break;
default:
break;
- //throw new Exception("Unexpected error");
}
}
catch
diff --git a/src/Microsoft.SqlTools.ServiceLayer/DisasterRecovery/CommonUtilities.cs b/src/Microsoft.SqlTools.ServiceLayer/DisasterRecovery/CommonUtilities.cs
index 3c97bc2a..aa85258b 100644
--- a/src/Microsoft.SqlTools.ServiceLayer/DisasterRecovery/CommonUtilities.cs
+++ b/src/Microsoft.SqlTools.ServiceLayer/DisasterRecovery/CommonUtilities.cs
@@ -107,8 +107,8 @@ namespace Microsoft.SqlTools.ServiceLayer.DisasterRecovery
///
public CommonUtilities(CDataContainer dataContainer, ServerConnection sqlConnection)
{
- this.dataContainer = dataContainer;
- this.sqlConnection = sqlConnection;
+ this.dataContainer = dataContainer;
+ this.sqlConnection = sqlConnection;
this.excludedDatabases = new ArrayList();
this.excludedDatabases.Add("master");
this.excludedDatabases.Add("tempdb");
@@ -202,7 +202,6 @@ namespace Microsoft.SqlTools.ServiceLayer.DisasterRecovery
}
}
-
public bool ServerHasLogicalDevices()
{
try
@@ -253,7 +252,6 @@ namespace Microsoft.SqlTools.ServiceLayer.DisasterRecovery
return new string(result);
}
-
public RecoveryModel GetRecoveryModel(string databaseName)
{
Enumerator en = null;
@@ -274,7 +272,6 @@ namespace Microsoft.SqlTools.ServiceLayer.DisasterRecovery
}
return recoveryModel;
}
-
public string GetRecoveryModelAsString(RecoveryModel recoveryModel)
{
@@ -296,7 +293,6 @@ namespace Microsoft.SqlTools.ServiceLayer.DisasterRecovery
return recoveryModelString;
}
-
public string GetDefaultBackupFolder()
{
string backupFolder = "";
@@ -570,7 +566,6 @@ namespace Microsoft.SqlTools.ServiceLayer.DisasterRecovery
return result;
}
-
public bool IsDatabaseOnServer(string databaseName)
{
@@ -699,7 +694,6 @@ namespace Microsoft.SqlTools.ServiceLayer.DisasterRecovery
}
}
-
public void GetBackupSetTypeAndComponent(string strType, ref string backupType, ref string backupComponent)
{
string type = strType.ToUpperInvariant();
@@ -815,7 +809,6 @@ namespace Microsoft.SqlTools.ServiceLayer.DisasterRecovery
}
return result;
}
-
public DataSet GetBackupSetFiles(int backupsetId)
{
@@ -853,7 +846,6 @@ namespace Microsoft.SqlTools.ServiceLayer.DisasterRecovery
return backupset;
}
-
public ArrayList GetBackupSetPhysicalSources(int backupsetId)
{
SqlExecutionModes executionMode = this.sqlConnection.SqlExecutionModes;
@@ -902,7 +894,6 @@ namespace Microsoft.SqlTools.ServiceLayer.DisasterRecovery
return sources;
}
-
public RestoreActionType GetRestoreTaskFromBackupSetType(BackupsetType type)
{
RestoreActionType result = RestoreActionType.Database;
@@ -952,7 +943,7 @@ namespace Microsoft.SqlTools.ServiceLayer.DisasterRecovery
}
}
- public List GetLatestBackupLocations(string DatabaseName)
+ public List GetLatestBackupLocations(string databaseName)
{
List latestLocations = new List();
Enumerator en = null;
@@ -961,7 +952,7 @@ namespace Microsoft.SqlTools.ServiceLayer.DisasterRecovery
Request req = new Request();
en = new Enumerator();
- req.Urn = "Server/BackupSet[@DatabaseName='" + Urn.EscapeString(DatabaseName) + "']";
+ req.Urn = "Server/BackupSet[@DatabaseName='" + Urn.EscapeString(databaseName) + "']";
req.OrderByList = new OrderBy[1];
req.OrderByList[0] = new OrderBy();
req.OrderByList[0].Field = "BackupFinishDate";
@@ -1015,7 +1006,7 @@ namespace Microsoft.SqlTools.ServiceLayer.DisasterRecovery
return latestLocations;
}
- public string GetDefaultDatabaseForLogin(string LoginName)
+ public string GetDefaultDatabaseForLogin(string loginName)
{
string defaultDatabase = string.Empty;
Enumerator en = new Enumerator();
@@ -1023,7 +1014,7 @@ namespace Microsoft.SqlTools.ServiceLayer.DisasterRecovery
ds.Locale = System.Globalization.CultureInfo.InvariantCulture;
Request req = new Request();
- req.Urn = "Server/Login[@Name='"+Urn.EscapeString(LoginName)+"']";
+ req.Urn = "Server/Login[@Name='"+Urn.EscapeString(loginName)+"']";
req.Fields = new string[1];
req.Fields[0] = "DefaultDatabase";
ds = en.Process(this.sqlConnection, req);
diff --git a/src/Microsoft.SqlTools.ServiceLayer/DisasterRecovery/DisasterRecoveryService.cs b/src/Microsoft.SqlTools.ServiceLayer/DisasterRecovery/DisasterRecoveryService.cs
index acb60501..15a4fd4d 100644
--- a/src/Microsoft.SqlTools.ServiceLayer/DisasterRecovery/DisasterRecoveryService.cs
+++ b/src/Microsoft.SqlTools.ServiceLayer/DisasterRecovery/DisasterRecoveryService.cs
@@ -23,23 +23,12 @@ namespace Microsoft.SqlTools.ServiceLayer.DisasterRecovery
{
private static readonly Lazy instance = new Lazy(() => new DisasterRecoveryService());
private static ConnectionService connectionService = null;
- private IBackupUtilities backupUtilities;
- private ManualResetEvent backupCompletedEvent = new ManualResetEvent(initialState: false);
///
/// Default, parameterless constructor.
///
internal DisasterRecoveryService()
{
- this.backupUtilities = new BackupUtilities();
- }
-
- ///
- /// For testing purpose only
- ///
- internal DisasterRecoveryService(IBackupUtilities backupUtilities)
- {
- this.backupUtilities = backupUtilities;
}
///
@@ -100,18 +89,14 @@ namespace Microsoft.SqlTools.ServiceLayer.DisasterRecovery
{
DatabaseTaskHelper helper = AdminService.CreateDatabaseTaskHelper(connInfo, databaseExists: true);
SqlConnection sqlConn = GetSqlConnection(connInfo);
- if (sqlConn != null)
+ if ((sqlConn != null) && !connInfo.IsSqlDW && !connInfo.IsAzure)
{
- DisasterRecoveryService.Instance.InitializeBackup(helper.DataContainer, sqlConn);
- if (!connInfo.IsSqlDW)
- {
- BackupConfigInfo backupConfigInfo = DisasterRecoveryService.Instance.GetBackupConfigInfo(sqlConn.Database);
- backupConfigInfo.DatabaseInfo = AdminService.GetDatabaseInfo(connInfo);
- response.BackupConfigInfo = backupConfigInfo;
- }
+ BackupConfigInfo backupConfigInfo = DisasterRecoveryService.Instance.GetBackupConfigInfo(helper.DataContainer, sqlConn, sqlConn.Database);
+ backupConfigInfo.DatabaseInfo = AdminService.GetDatabaseInfo(connInfo);
+ response.BackupConfigInfo = backupConfigInfo;
}
}
-
+
await requestContext.SendResult(response);
}
@@ -131,11 +116,9 @@ namespace Microsoft.SqlTools.ServiceLayer.DisasterRecovery
{
DatabaseTaskHelper helper = AdminService.CreateDatabaseTaskHelper(connInfo, databaseExists: true);
SqlConnection sqlConn = GetSqlConnection(connInfo);
- if (sqlConn != null)
+ if ((sqlConn != null) && !connInfo.IsSqlDW && !connInfo.IsAzure)
{
- // initialize backup
- DisasterRecoveryService.Instance.InitializeBackup(helper.DataContainer, sqlConn);
- DisasterRecoveryService.Instance.SetBackupInput(backupParams.BackupInfo);
+ BackupOperation backupOperation = DisasterRecoveryService.Instance.SetBackupInput(helper.DataContainer, sqlConn, backupParams.BackupInfo);
// create task metadata
TaskMetadata metadata = new TaskMetadata();
@@ -143,9 +126,10 @@ namespace Microsoft.SqlTools.ServiceLayer.DisasterRecovery
metadata.DatabaseName = connInfo.ConnectionDetails.DatabaseName;
metadata.Name = SR.Backup_TaskName;
metadata.IsCancelable = true;
-
+ metadata.Data = backupOperation;
+
// create backup task and perform
- SqlTask sqlTask = SqlTaskManager.Instance.CreateTask(metadata, Instance.BackupTask);
+ SqlTask sqlTask = SqlTaskManager.Instance.CreateTask(metadata, Instance.BackupTaskAsync);
sqlTask.Run();
}
}
@@ -179,48 +163,72 @@ namespace Microsoft.SqlTools.ServiceLayer.DisasterRecovery
return null;
}
- internal void InitializeBackup(CDataContainer dataContainer, SqlConnection sqlConnection)
+ internal BackupConfigInfo GetBackupConfigInfo(CDataContainer dataContainer, SqlConnection sqlConnection, string databaseName)
{
- this.backupUtilities.Initialize(dataContainer, sqlConnection);
+ BackupOperation backupOperation = new BackupOperation();
+ backupOperation.Initialize(dataContainer, sqlConnection);
+ return backupOperation.GetBackupConfigInfo(databaseName);
}
- internal void SetBackupInput(BackupInfo input)
- {
- this.backupUtilities.SetBackupInput(input);
- }
-
- internal void PerformBackup()
+ internal BackupOperation SetBackupInput(CDataContainer dataContainer, SqlConnection sqlConnection, BackupInfo input)
{
- this.backupUtilities.PerformBackup();
+ BackupOperation backupOperation = new BackupOperation();
+ backupOperation.Initialize(dataContainer, sqlConnection);
+ backupOperation.SetBackupInput(input);
+ return backupOperation;
}
- internal BackupConfigInfo GetBackupConfigInfo(string databaseName)
+ ///
+ /// For testing purpose only
+ ///
+ internal void PerformBackup(BackupOperation backupOperation)
{
- return this.backupUtilities.GetBackupConfigInfo(databaseName);
+ backupOperation.PerformBackup();
}
-
+
///
/// Create a backup task for execution and cancellation
///
///
///
- internal async Task BackupTask(SqlTask sqlTask)
+ internal async Task BackupTaskAsync(SqlTask sqlTask)
{
sqlTask.AddMessage(SR.Task_InProgress, SqlTaskStatus.InProgress, true);
- Task performTask = this.PerformTask();
- Task cancelTask = this.CancelTask(sqlTask);
- Task completedTask = await Task.WhenAny(performTask, cancelTask);
- if (completedTask == performTask)
+ IBackupOperation backupOperation = sqlTask.TaskMetadata.Data as IBackupOperation;
+ TaskResult taskResult = null;
+
+ if (backupOperation != null)
{
- this.backupCompletedEvent.Set();
+ AutoResetEvent backupCompletedEvent = new AutoResetEvent(initialState: false);
+ Task performTask = PerformTaskAsync(backupOperation);
+ Task cancelTask = CancelTaskAsync(backupOperation, sqlTask.TokenSource.Token, backupCompletedEvent);
+ Task completedTask = await Task.WhenAny(performTask, cancelTask);
+
+ // Release the cancelTask
+ if (completedTask == performTask)
+ {
+ backupCompletedEvent.Set();
+ }
+
+ sqlTask.AddMessage(completedTask.Result.TaskStatus == SqlTaskStatus.Failed ? completedTask.Result.ErrorMessage : SR.Task_Completed,
+ completedTask.Result.TaskStatus);
+ taskResult = completedTask.Result;
+ }
+ else
+ {
+ taskResult = new TaskResult();
+ taskResult.TaskStatus = SqlTaskStatus.Failed;
}
- sqlTask.AddMessage(completedTask.Result.TaskStatus == SqlTaskStatus.Failed ? completedTask.Result.ErrorMessage : SR.Task_Completed,
- completedTask.Result.TaskStatus);
- return completedTask.Result;
+ return taskResult;
}
- private async Task PerformTask()
+ ///
+ /// Async task to execute backup
+ ///
+ ///
+ ///
+ private async Task PerformTaskAsync(IBackupOperation backupOperation)
{
// Create a task to perform backup
return await Task.Factory.StartNew(() =>
@@ -228,7 +236,7 @@ namespace Microsoft.SqlTools.ServiceLayer.DisasterRecovery
TaskResult result = new TaskResult();
try
{
- this.backupUtilities.PerformBackup();
+ backupOperation.PerformBackup();
result.TaskStatus = SqlTaskStatus.Succeeded;
}
catch (Exception ex)
@@ -244,14 +252,19 @@ namespace Microsoft.SqlTools.ServiceLayer.DisasterRecovery
});
}
- private async Task CancelTask(SqlTask sqlTask)
+ ///
+ /// Async task to cancel backup
+ ///
+ ///
+ ///
+ ///
+ ///
+ private async Task CancelTaskAsync(IBackupOperation backupOperation, CancellationToken token, AutoResetEvent backupCompletedEvent)
{
// Create a task for backup cancellation request
return await Task.Factory.StartNew(() =>
{
TaskResult result = new TaskResult();
-
- CancellationToken token = sqlTask.TokenSource.Token;
WaitHandle[] waitHandles = new WaitHandle[2]
{
backupCompletedEvent,
@@ -259,19 +272,17 @@ namespace Microsoft.SqlTools.ServiceLayer.DisasterRecovery
};
WaitHandle.WaitAny(waitHandles);
- if (token.IsCancellationRequested)
+ try
{
- try
- {
- this.backupUtilities.CancelBackup();
- result.TaskStatus = SqlTaskStatus.Canceled;
- }
- catch (Exception ex)
- {
- result.TaskStatus = SqlTaskStatus.Failed;
- result.ErrorMessage = ex.Message;
- }
+ backupOperation.CancelBackup();
+ result.TaskStatus = SqlTaskStatus.Canceled;
}
+ catch (Exception ex)
+ {
+ result.TaskStatus = SqlTaskStatus.Failed;
+ result.ErrorMessage = ex.Message;
+ }
+
return result;
});
}
diff --git a/src/Microsoft.SqlTools.ServiceLayer/DisasterRecovery/IBackupUtilities.cs b/src/Microsoft.SqlTools.ServiceLayer/DisasterRecovery/IBackupOperation.cs
similarity index 93%
rename from src/Microsoft.SqlTools.ServiceLayer/DisasterRecovery/IBackupUtilities.cs
rename to src/Microsoft.SqlTools.ServiceLayer/DisasterRecovery/IBackupOperation.cs
index fafdac9e..b2f72862 100644
--- a/src/Microsoft.SqlTools.ServiceLayer/DisasterRecovery/IBackupUtilities.cs
+++ b/src/Microsoft.SqlTools.ServiceLayer/DisasterRecovery/IBackupOperation.cs
@@ -2,6 +2,7 @@
// 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.Management.Smo;
using Microsoft.SqlTools.ServiceLayer.Admin;
using Microsoft.SqlTools.ServiceLayer.DisasterRecovery.Contracts;
using System.Data.SqlClient;
@@ -11,7 +12,7 @@ namespace Microsoft.SqlTools.ServiceLayer.DisasterRecovery
///
/// Interface for backup operations
///
- public interface IBackupUtilities
+ public interface IBackupOperation
{
///
/// Initialize
@@ -32,7 +33,7 @@ namespace Microsoft.SqlTools.ServiceLayer.DisasterRecovery
///
///
void SetBackupInput(BackupInfo input);
-
+
///
/// Execute backup
///
diff --git a/src/Microsoft.SqlTools.ServiceLayer/TaskServices/TaskMetadata.cs b/src/Microsoft.SqlTools.ServiceLayer/TaskServices/TaskMetadata.cs
index 2678c12e..3481a6ca 100644
--- a/src/Microsoft.SqlTools.ServiceLayer/TaskServices/TaskMetadata.cs
+++ b/src/Microsoft.SqlTools.ServiceLayer/TaskServices/TaskMetadata.cs
@@ -37,5 +37,10 @@ namespace Microsoft.SqlTools.ServiceLayer.TaskServices
/// Database name this task is created for
///
public string DatabaseName { get; set; }
+
+ ///
+ /// Data required to perform the task
+ ///
+ public object Data { get; set; }
}
}
diff --git a/test/Microsoft.SqlTools.ServiceLayer.IntegrationTests/DisasterRecovery/BackupTests.cs b/test/Microsoft.SqlTools.ServiceLayer.IntegrationTests/DisasterRecovery/BackupTests.cs
index bcc11910..df209371 100644
--- a/test/Microsoft.SqlTools.ServiceLayer.IntegrationTests/DisasterRecovery/BackupTests.cs
+++ b/test/Microsoft.SqlTools.ServiceLayer.IntegrationTests/DisasterRecovery/BackupTests.cs
@@ -57,10 +57,9 @@ namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.DisasterRecovery
// Initialize backup service
DatabaseTaskHelper helper = AdminService.CreateDatabaseTaskHelper(liveConnection.ConnectionInfo, databaseExists: true);
SqlConnection sqlConn = DisasterRecoveryService.GetSqlConnection(liveConnection.ConnectionInfo);
- DisasterRecoveryService.Instance.InitializeBackup(helper.DataContainer, sqlConn);
-
+
// Get default backup path
- BackupConfigInfo backupConfigInfo = DisasterRecoveryService.Instance.GetBackupConfigInfo(sqlConn.Database);
+ BackupConfigInfo backupConfigInfo = DisasterRecoveryService.Instance.GetBackupConfigInfo(helper.DataContainer, sqlConn, sqlConn.Database);
string backupPath = backupConfigInfo.DefaultBackupFolder + "\\" + databaseName + ".bak";
var backupInfo = new BackupInfo();
@@ -81,8 +80,8 @@ namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.DisasterRecovery
};
// Backup the database
- DisasterRecoveryService.Instance.SetBackupInput(backupParams.BackupInfo);
- DisasterRecoveryService.Instance.PerformBackup();
+ BackupOperation backupOperation = DisasterRecoveryService.Instance.SetBackupInput(helper.DataContainer, sqlConn, backupParams.BackupInfo);
+ DisasterRecoveryService.Instance.PerformBackup(backupOperation);
// Remove the backup file
if (File.Exists(backupPath))
diff --git a/test/Microsoft.SqlTools.ServiceLayer.UnitTests/DisasterRecovery/BackupUtilitiesStub.cs b/test/Microsoft.SqlTools.ServiceLayer.UnitTests/DisasterRecovery/BackupOperationStub.cs
similarity index 91%
rename from test/Microsoft.SqlTools.ServiceLayer.UnitTests/DisasterRecovery/BackupUtilitiesStub.cs
rename to test/Microsoft.SqlTools.ServiceLayer.UnitTests/DisasterRecovery/BackupOperationStub.cs
index ea9b3e6f..3936d297 100644
--- a/test/Microsoft.SqlTools.ServiceLayer.UnitTests/DisasterRecovery/BackupUtilitiesStub.cs
+++ b/test/Microsoft.SqlTools.ServiceLayer.UnitTests/DisasterRecovery/BackupOperationStub.cs
@@ -3,6 +3,7 @@
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
//
+using Microsoft.SqlServer.Management.Smo;
using Microsoft.SqlTools.ServiceLayer.Admin;
using Microsoft.SqlTools.ServiceLayer.DisasterRecovery;
using Microsoft.SqlTools.ServiceLayer.DisasterRecovery.Contracts;
@@ -12,9 +13,9 @@ using System.Threading;
namespace Microsoft.SqlTools.ServiceLayer.UnitTests.DisasterRecovery
{
///
- /// Stub class that implements IBackupUtilities
+ /// Stub class that implements IBackupOperation
///
- public class BackupUtilitiesStub : IBackupUtilities
+ public class BackupOperationStub : IBackupOperation
{
///
/// Initialize
diff --git a/test/Microsoft.SqlTools.ServiceLayer.UnitTests/DisasterRecovery/BackupTests.cs b/test/Microsoft.SqlTools.ServiceLayer.UnitTests/DisasterRecovery/BackupTests.cs
index 85b7f77a..75a249b4 100644
--- a/test/Microsoft.SqlTools.ServiceLayer.UnitTests/DisasterRecovery/BackupTests.cs
+++ b/test/Microsoft.SqlTools.ServiceLayer.UnitTests/DisasterRecovery/BackupTests.cs
@@ -21,14 +21,20 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.DisasterRecovery
IsCancelable = true
};
+ ///
+ /// Create and run a backup task
+ ///
+ ///
[Fact]
- public async Task VerifyCreateAndRunningBackupTask()
+ public async Task VerifyRunningBackupTask()
{
using (SqlTaskManager manager = new SqlTaskManager())
{
- var mockUtility = new Mock();
- DisasterRecoveryService service = new DisasterRecoveryService(mockUtility.Object);
- SqlTask sqlTask = manager.CreateTask(this.taskMetaData, service.BackupTask);
+ DisasterRecoveryService service = new DisasterRecoveryService();
+ var mockBackupOperation = new Mock();
+ this.taskMetaData.Data = mockBackupOperation.Object;
+
+ SqlTask sqlTask = manager.CreateTask(this.taskMetaData, service.BackupTaskAsync);
Assert.NotNull(sqlTask);
Task taskToVerify = sqlTask.RunAsync().ContinueWith(Task =>
{
@@ -38,15 +44,52 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.DisasterRecovery
await taskToVerify;
}
}
-
+
+ ///
+ /// Create and run multiple backup tasks
+ ///
+ ///
[Fact]
- public async Task CancelBackupTask()
+ public async Task VerifyRunningMultipleBackupTasks()
+ {
+ using (SqlTaskManager manager = new SqlTaskManager())
+ {
+ DisasterRecoveryService service = new DisasterRecoveryService();
+ var mockUtility = new Mock();
+ this.taskMetaData.Data = mockUtility.Object;
+
+ SqlTask sqlTask = manager.CreateTask(this.taskMetaData, service.BackupTaskAsync);
+ SqlTask sqlTask2 = manager.CreateTask(this.taskMetaData, service.BackupTaskAsync);
+ Assert.NotNull(sqlTask);
+ Assert.NotNull(sqlTask2);
+
+ Task taskToVerify = sqlTask.RunAsync().ContinueWith(Task =>
+ {
+ Assert.Equal(SqlTaskStatus.Succeeded, sqlTask.TaskStatus);
+ });
+
+ Task taskToVerify2 = sqlTask2.RunAsync().ContinueWith(Task =>
+ {
+ Assert.Equal(SqlTaskStatus.Succeeded, sqlTask2.TaskStatus);
+ });
+
+ await Task.WhenAll(taskToVerify, taskToVerify2);
+ }
+ }
+
+ ///
+ /// Cancel a backup task
+ ///
+ ///
+ [Fact]
+ public async Task VerifyCancelBackupTask()
{
using (SqlTaskManager manager = new SqlTaskManager())
{
- IBackupUtilities backupUtility = new BackupUtilitiesStub();
- DisasterRecoveryService service = new DisasterRecoveryService(backupUtility);
- SqlTask sqlTask = manager.CreateTask(this.taskMetaData, service.BackupTask);
+ IBackupOperation backupOperation = new BackupOperationStub();
+ DisasterRecoveryService service = new DisasterRecoveryService();
+ this.taskMetaData.Data = backupOperation;
+ SqlTask sqlTask = manager.CreateTask(this.taskMetaData, service.BackupTaskAsync);
Assert.NotNull(sqlTask);
Task taskToVerify = sqlTask.RunAsync().ContinueWith(Task =>
{
@@ -59,5 +102,77 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.DisasterRecovery
await taskToVerify;
}
}
+
+ ///
+ /// Cancel multiple backup tasks
+ ///
+ ///
+ [Fact]
+ public async Task VerifyCancelMultipleBackupTasks()
+ {
+ using (SqlTaskManager manager = new SqlTaskManager())
+ {
+ IBackupOperation backupOperation = new BackupOperationStub();
+ DisasterRecoveryService service = new DisasterRecoveryService();
+ this.taskMetaData.Data = backupOperation;
+ SqlTask sqlTask = manager.CreateTask(this.taskMetaData, service.BackupTaskAsync);
+ SqlTask sqlTask2 = manager.CreateTask(this.taskMetaData, service.BackupTaskAsync);
+ Assert.NotNull(sqlTask);
+ Assert.NotNull(sqlTask2);
+
+ Task taskToVerify = sqlTask.RunAsync().ContinueWith(Task =>
+ {
+ Assert.Equal(SqlTaskStatus.Canceled, sqlTask.TaskStatus);
+ Assert.Equal(sqlTask.IsCancelRequested, true);
+ manager.Reset();
+ });
+
+ Task taskToVerify2 = sqlTask2.RunAsync().ContinueWith(Task =>
+ {
+ Assert.Equal(SqlTaskStatus.Canceled, sqlTask2.TaskStatus);
+ Assert.Equal(sqlTask2.IsCancelRequested, true);
+ manager.Reset();
+ });
+
+ manager.CancelTask(sqlTask.TaskId);
+ manager.CancelTask(sqlTask2.TaskId);
+
+ await Task.WhenAll(taskToVerify, taskToVerify2);
+ }
+ }
+
+ ///
+ /// Create two backup tasks and cancel one task
+ ///
+ ///
+ [Fact]
+ public async Task VerifyCombinationRunAndCancelBackupTasks()
+ {
+ using (SqlTaskManager manager = new SqlTaskManager())
+ {
+ IBackupOperation backupOperation = new BackupOperationStub();
+ DisasterRecoveryService service = new DisasterRecoveryService();
+ this.taskMetaData.Data = backupOperation;
+ SqlTask sqlTask = manager.CreateTask(this.taskMetaData, service.BackupTaskAsync);
+ SqlTask sqlTask2 = manager.CreateTask(this.taskMetaData, service.BackupTaskAsync);
+ Assert.NotNull(sqlTask);
+ Assert.NotNull(sqlTask2);
+
+ Task taskToVerify = sqlTask.RunAsync().ContinueWith(Task =>
+ {
+ Assert.Equal(SqlTaskStatus.Canceled, sqlTask.TaskStatus);
+ Assert.Equal(sqlTask.IsCancelRequested, true);
+ manager.Reset();
+ });
+
+ Task taskToVerify2 = sqlTask2.RunAsync().ContinueWith(Task =>
+ {
+ Assert.Equal(SqlTaskStatus.Succeeded, sqlTask2.TaskStatus);
+ });
+
+ manager.CancelTask(sqlTask.TaskId);
+ await Task.WhenAll(taskToVerify, taskToVerify2);
+ }
+ }
}
}