private static async Task CreateSnapshotAsync() { // Create 2 Sql Sync providers var serverProvider = new SqlSyncProvider(DBHelper.GetDatabaseConnectionString(serverDbName)); // specific Setup with only 2 tables, and one filtered var setup = new SyncSetup(allTables); // Using the Progress pattern to handle progession during the synchronization var progress = new SynchronousProgress <ProgressArgs>(s => { Console.ForegroundColor = ConsoleColor.Green; Console.WriteLine($"{s.Context.SyncStage}:\t{s.Message}"); Console.ResetColor(); }); var remoteProgress = new SynchronousProgress <ProgressArgs>(s => { Console.ForegroundColor = ConsoleColor.Yellow; Console.WriteLine($"{s.Context.SyncStage}:\t{s.Message}"); Console.ResetColor(); }); // snapshot directory var directory = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), "Snapshots"); var options = new SyncOptions { SnapshotsDirectory = directory, BatchSize = 2000 }; var remoteOrchestrator = new RemoteOrchestrator(serverProvider, options, setup); await remoteOrchestrator.CreateSnapshotAsync(null, default, remoteProgress);
private static async Task CreateSnapshotAsync() { // [Required]: Get a connection string to your server data source var connectionString = configuration.GetSection("ConnectionStrings")["SqlConnection"]; // [Required] Tables involved in the sync process: var tables = new string[] { "ProductCategory", "ProductModel", "Product", "Address", "Customer", "CustomerAddress", "SalesOrderHeader", "SalesOrderDetail" }; var syncOptions = new SyncOptions { SnapshotsDirectory = Path.Combine(SyncOptions.GetDefaultUserBatchDiretory(), "Snapshots"), BatchSize = 2000, }; var syncSetup = new SyncSetup(tables); // Using the Progress pattern to handle progession during the synchronization var progress = new SynchronousProgress <ProgressArgs>(s => Console.WriteLine($"{s.Source}:\t{s.Message}")); var provider = new SqlSyncProvider(connectionString); var orchestrator = new RemoteOrchestrator(provider, syncOptions, syncSetup); var snap = await orchestrator.CreateSnapshotAsync(progress : progress); }
public async Task <IActionResult> CreateSnapshotAsync() { var connectionString = configuration.GetConnectionString("DefaultConnection"); var serverProvider = new SqlSyncProvider(connectionString); // Create a remote orchestrator var remoteOrchestrator = new RemoteOrchestrator(serverProvider, syncOptions, syncSetup); // Create a snapshot await remoteOrchestrator.CreateSnapshotAsync(); return(Ok()); }
public async Task RemoteOrchestrator_CreateSnapshot_ShouldFail_If_MissingMandatoriesOptions() { var dbName = HelperDatabase.GetRandomName("tcp_lo_"); await HelperDatabase.CreateDatabaseAsync(ProviderType.Sql, dbName, true); var cs = HelperDatabase.GetConnectionString(ProviderType.Sql, dbName); var sqlProvider = new SqlSyncProvider(cs); var ctx = new AdventureWorksContext((dbName, ProviderType.Sql, sqlProvider), true, true); await ctx.Database.EnsureCreatedAsync(); var scopeName = "scopesnap"; // snapshot directory var snapshotDirctoryName = HelperDatabase.GetRandomName(); var snapshotDirectory = Path.Combine(Environment.CurrentDirectory, snapshotDirctoryName); var options = new SyncOptions { SnapshotsDirectory = snapshotDirectory }; var setup = new SyncSetup(Tables); var provider = new SqlSyncProvider(cs); var orchestrator = new RemoteOrchestrator(provider, options, setup, scopeName); var se = await Assert.ThrowsAsync <SyncException>(() => orchestrator.CreateSnapshotAsync()); Assert.Equal(SyncStage.SnapshotCreating, se.SyncStage); Assert.Equal(SyncSide.ServerSide, se.Side); Assert.Equal("SnapshotMissingMandatariesOptionsException", se.TypeName); options = new SyncOptions { BatchSize = 2000 }; orchestrator = new RemoteOrchestrator(provider, options, setup, scopeName); se = await Assert.ThrowsAsync <SyncException>(() => orchestrator.CreateSnapshotAsync()); Assert.Equal(SyncStage.SnapshotCreating, se.SyncStage); Assert.Equal(SyncSide.ServerSide, se.Side); Assert.Equal("SnapshotMissingMandatariesOptionsException", se.TypeName); options = new SyncOptions { }; orchestrator = new RemoteOrchestrator(provider, options, setup, scopeName); se = await Assert.ThrowsAsync <SyncException>(() => orchestrator.CreateSnapshotAsync()); Assert.Equal(SyncStage.SnapshotCreating, se.SyncStage); Assert.Equal(SyncSide.ServerSide, se.Side); Assert.Equal("SnapshotMissingMandatariesOptionsException", se.TypeName); HelperDatabase.DropDatabase(ProviderType.Sql, dbName); }
public async Task RemoteOrchestrator_CreateSnapshot_CheckInterceptors() { var dbName = HelperDatabase.GetRandomName("tcp_lo_srv"); await HelperDatabase.CreateDatabaseAsync(ProviderType.Sql, dbName, true); var cs = HelperDatabase.GetConnectionString(ProviderType.Sql, dbName); var serverProvider = new SqlSyncProvider(cs); var ctx = new AdventureWorksContext((dbName, ProviderType.Sql, serverProvider), true, true); await ctx.Database.EnsureCreatedAsync(); var scopeName = "scopesnap1"; var onSnapshotCreating = false; var onSnapshotCreated = false; // snapshot directory var snapshotDirctoryName = HelperDatabase.GetRandomName(); var snapshotDirectory = Path.Combine(Environment.CurrentDirectory, snapshotDirctoryName); var options = new SyncOptions { SnapshotsDirectory = snapshotDirectory, BatchSize = 200 }; var setup = new SyncSetup(Tables); var remoteOrchestrator = new RemoteOrchestrator(serverProvider, options, setup, scopeName); // Assert on connection and transaction interceptors BaseOrchestratorTests.AssertConnectionAndTransaction(remoteOrchestrator, SyncStage.SnapshotCreating); remoteOrchestrator.OnSnapshotCreating(args => { Assert.IsType <SnapshotCreatingArgs>(args); Assert.Equal(SyncStage.SnapshotCreating, args.Context.SyncStage); Assert.Equal(scopeName, args.Context.ScopeName); Assert.NotNull(args.Connection); Assert.NotNull(args.Transaction); Assert.Equal(ConnectionState.Open, args.Connection.State); Assert.NotNull(args.Schema); Assert.Equal(snapshotDirectory, args.SnapshotDirectory); Assert.NotEqual(0, args.Timestamp); onSnapshotCreating = true; }); remoteOrchestrator.OnSnapshotCreated(args => { Assert.IsType <SnapshotCreatedArgs>(args); Assert.Equal(SyncStage.SnapshotCreating, args.Context.SyncStage); Assert.Equal(scopeName, args.Context.ScopeName); Assert.NotNull(args.Connection); Assert.Null(args.Transaction); Assert.NotNull(args.BatchInfo); var finalDirectoryFullName = Path.Combine(snapshotDirectory, scopeName); Assert.Equal(finalDirectoryFullName, args.BatchInfo.DirectoryRoot); Assert.Equal("ALL", args.BatchInfo.DirectoryName); Assert.Single(args.BatchInfo.BatchPartsInfo); Assert.Equal(17, args.BatchInfo.BatchPartsInfo[0].Tables.Length); Assert.True(args.BatchInfo.BatchPartsInfo[0].IsLastBatch); onSnapshotCreated = true; }); var bi = await remoteOrchestrator.CreateSnapshotAsync(); Assert.Equal(SyncStage.SnapshotCreating, remoteOrchestrator.GetContext().SyncStage); Assert.True(onSnapshotCreating); Assert.True(onSnapshotCreated); var dbNameCli = HelperDatabase.GetRandomName("tcp_lo_cli"); await HelperDatabase.CreateDatabaseAsync(ProviderType.Sql, dbNameCli, true); var csClient = HelperDatabase.GetConnectionString(ProviderType.Sql, dbNameCli); var clientProvider = new SqlSyncProvider(csClient); // Make a first sync to be sure everything is in place var agent = new SyncAgent(clientProvider, serverProvider, options, setup, scopeName); var onSnapshotApplying = false; var onSnapshotApplied = false; agent.LocalOrchestrator.OnSnapshotApplying(saa => { onSnapshotApplying = true; }); agent.LocalOrchestrator.OnSnapshotApplied(saa => { onSnapshotApplied = true; }); // Making a first sync, will initialize everything we need await agent.SynchronizeAsync(); Assert.True(onSnapshotApplying); Assert.True(onSnapshotApplied); HelperDatabase.DropDatabase(ProviderType.Sql, dbName); }
public async Task RemoteOrchestrator_CreateSnapshot_WithParameters_CheckBatchInfo() { var dbName = HelperDatabase.GetRandomName("tcp_lo_"); await HelperDatabase.CreateDatabaseAsync(ProviderType.Sql, dbName, true); var cs = HelperDatabase.GetConnectionString(ProviderType.Sql, dbName); var sqlProvider = new SqlSyncProvider(cs); var ctx = new AdventureWorksContext((dbName, ProviderType.Sql, sqlProvider), true, true); await ctx.Database.EnsureCreatedAsync(); // snapshot directory var snapshotDirctoryName = HelperDatabase.GetRandomName(); var snapshotDirectory = Path.Combine(Environment.CurrentDirectory, snapshotDirctoryName); var options = new SyncOptions { SnapshotsDirectory = snapshotDirectory, BatchSize = 200 }; var setup = new SyncSetup(Tables); var provider = new SqlSyncProvider(cs); setup.Filters.Add("Customer", "CompanyName"); var addressCustomerFilter = new SetupFilter("CustomerAddress"); addressCustomerFilter.AddParameter("CompanyName", "Customer"); addressCustomerFilter.AddJoin(Join.Left, "Customer").On("CustomerAddress", "CustomerId", "Customer", "CustomerId"); addressCustomerFilter.AddWhere("CompanyName", "Customer", "CompanyName"); setup.Filters.Add(addressCustomerFilter); var addressFilter = new SetupFilter("Address"); addressFilter.AddParameter("CompanyName", "Customer"); addressFilter.AddJoin(Join.Left, "CustomerAddress").On("CustomerAddress", "AddressId", "Address", "AddressId"); addressFilter.AddJoin(Join.Left, "Customer").On("CustomerAddress", "CustomerId", "Customer", "CustomerId"); addressFilter.AddWhere("CompanyName", "Customer", "CompanyName"); setup.Filters.Add(addressFilter); var orderHeaderFilter = new SetupFilter("SalesOrderHeader"); orderHeaderFilter.AddParameter("CompanyName", "Customer"); orderHeaderFilter.AddJoin(Join.Left, "CustomerAddress").On("CustomerAddress", "CustomerId", "SalesOrderHeader", "CustomerId"); orderHeaderFilter.AddJoin(Join.Left, "Customer").On("CustomerAddress", "CustomerId", "Customer", "CustomerId"); orderHeaderFilter.AddWhere("CompanyName", "Customer", "CompanyName"); setup.Filters.Add(orderHeaderFilter); var orderDetailsFilter = new SetupFilter("SalesOrderDetail"); orderDetailsFilter.AddParameter("CompanyName", "Customer"); orderDetailsFilter.AddJoin(Join.Left, "SalesOrderHeader").On("SalesOrderDetail", "SalesOrderID", "SalesOrderHeader", "SalesOrderID"); orderDetailsFilter.AddJoin(Join.Left, "CustomerAddress").On("CustomerAddress", "CustomerId", "SalesOrderHeader", "CustomerId"); orderDetailsFilter.AddJoin(Join.Left, "Customer").On("CustomerAddress", "CustomerId", "Customer", "CustomerId"); orderDetailsFilter.AddWhere("CompanyName", "Customer", "CompanyName"); setup.Filters.Add(orderDetailsFilter); var orchestrator = new RemoteOrchestrator(provider, options, setup); SyncParameters parameters = new SyncParameters(); var p1 = new SyncParameter("CompanyName", "A Bike Store"); parameters.Add(p1); var bi = await orchestrator.CreateSnapshotAsync(parameters); var finalDirectoryFullName = Path.Combine(snapshotDirectory, SyncOptions.DefaultScopeName); Assert.NotNull(bi); Assert.Equal(finalDirectoryFullName, bi.DirectoryRoot); Assert.Equal("CompanyName_ABikeStore", bi.DirectoryName); Assert.Single(bi.BatchPartsInfo); Assert.Equal(17, bi.BatchPartsInfo[0].Tables.Length); Assert.True(bi.BatchPartsInfo[0].IsLastBatch); // Check summary.json exists. var summaryFile = Path.Combine(bi.GetDirectoryFullPath(), "summary.json"); var summaryString = new StreamReader(summaryFile).ReadToEnd(); var summaryObject = JObject.Parse(summaryString); Assert.NotNull(summaryObject); string summaryDirname = (string)summaryObject["dirname"]; Assert.NotNull(summaryDirname); Assert.Equal("CompanyName_ABikeStore", summaryDirname); string summaryDir = (string)summaryObject["dir"]; Assert.NotNull(summaryDir); Assert.Equal(finalDirectoryFullName, summaryDir); Assert.Single(summaryObject["parts"]); Assert.NotNull(summaryObject["parts"][0]["file"]); Assert.NotNull(summaryObject["parts"][0]["index"]); Assert.Equal(0, (int)summaryObject["parts"][0]["index"]); Assert.NotNull(summaryObject["parts"][0]["last"]); Assert.True((bool)summaryObject["parts"][0]["last"]); Assert.Equal(17, summaryObject["parts"][0]["tables"].Count()); HelperDatabase.DropDatabase(ProviderType.Sql, dbName); }
public async Task RemoteOrchestrator_CreateSnapshot_CheckBatchInfo() { var dbName = HelperDatabase.GetRandomName("tcp_lo_"); await HelperDatabase.CreateDatabaseAsync(ProviderType.Sql, dbName, true); var cs = HelperDatabase.GetConnectionString(ProviderType.Sql, dbName); var sqlProvider = new SqlSyncProvider(cs); var ctx = new AdventureWorksContext((dbName, ProviderType.Sql, sqlProvider), true, true); await ctx.Database.EnsureCreatedAsync(); var rowsCount = GetServerDatabaseRowsCount((dbName, ProviderType.Sql, sqlProvider)); var scopeName = "scopesnap2"; // snapshot directory var snapshotDirctoryName = HelperDatabase.GetRandomName(); var snapshotDirectory = Path.Combine(Environment.CurrentDirectory, snapshotDirctoryName); var options = new SyncOptions { SnapshotsDirectory = snapshotDirectory, BatchSize = 200 }; var setup = new SyncSetup(Tables); var provider = new SqlSyncProvider(cs); var orchestrator = new RemoteOrchestrator(provider, options, setup, scopeName); var bi = await orchestrator.CreateSnapshotAsync(); var finalDirectoryFullName = Path.Combine(snapshotDirectory, scopeName); Assert.NotNull(bi); Assert.Equal(finalDirectoryFullName, bi.DirectoryRoot); Assert.Equal("ALL", bi.DirectoryName); Assert.Single(bi.BatchPartsInfo); Assert.Equal(17, bi.BatchPartsInfo[0].Tables.Length); Assert.True(bi.BatchPartsInfo[0].IsLastBatch); Assert.Equal(rowsCount, bi.RowsCount); // Check summary.json exists. var summaryFile = Path.Combine(bi.GetDirectoryFullPath(), "summary.json"); var summaryString = new StreamReader(summaryFile).ReadToEnd(); var summaryObject = JObject.Parse(summaryString); Assert.NotNull(summaryObject); string summaryDirname = (string)summaryObject["dirname"]; Assert.NotNull(summaryDirname); Assert.Equal("ALL", summaryDirname); string summaryDir = (string)summaryObject["dir"]; Assert.NotNull(summaryDir); Assert.Equal(finalDirectoryFullName, summaryDir); Assert.Single(summaryObject["parts"]); Assert.NotNull(summaryObject["parts"][0]["file"]); Assert.NotNull(summaryObject["parts"][0]["index"]); Assert.Equal(0, (int)summaryObject["parts"][0]["index"]); Assert.NotNull(summaryObject["parts"][0]["last"]); Assert.True((bool)summaryObject["parts"][0]["last"]); Assert.Equal(17, summaryObject["parts"][0]["tables"].Count()); HelperDatabase.DropDatabase(ProviderType.Sql, dbName); }
public static async Task SyncHttpThroughKestellAsync() { // server provider // Create 2 Sql Sync providers var serverProvider = new SqlSyncProvider(DbHelper.GetDatabaseConnectionString(serverDbName)); var clientProvider = new SqlSyncProvider(DbHelper.GetDatabaseConnectionString(clientDbName)); // ---------------------------------- // Client side // ---------------------------------- var clientOptions = new SyncOptions { BatchSize = 500 }; var proxyClientProvider = new WebClientOrchestrator(); // ---------------------------------- // Web Server side // ---------------------------------- var setup = new SyncSetup(allTables) { ScopeName = "all_tables_scope", StoredProceduresPrefix = "s", StoredProceduresSuffix = "", TrackingTablesPrefix = "t", TrackingTablesSuffix = "", TriggersPrefix = "", TriggersSuffix = "t" }; // snapshot directory var directory = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), "Snapshots"); // ---------------------------------- // Create a snapshot // ---------------------------------- Console.ForegroundColor = ConsoleColor.Yellow; Console.WriteLine($"Creating snapshot"); var remoteOrchestrator = new RemoteOrchestrator(serverProvider); await remoteOrchestrator.CreateSnapshotAsync(new SyncContext(), setup, directory, 500, CancellationToken.None); Console.WriteLine($"Done."); Console.ResetColor(); // ---------------------------------- // Insert a value after snapshot created // ---------------------------------- using (var c = serverProvider.CreateConnection()) { var command = c.CreateCommand(); command.CommandText = "INSERT INTO [dbo].[ProductCategory] ([Name]) VALUES ('Bikes revolution');"; c.Open(); command.ExecuteNonQuery(); c.Close(); } var webServerOptions = new WebServerOptions { SnapshotsDirectory = directory }; // Creating an agent that will handle all the process var agent = new SyncAgent(clientProvider, proxyClientProvider); agent.Options = clientOptions; var configureServices = new Action <IServiceCollection>(services => { services.AddSyncServer <SqlSyncProvider>(serverProvider.ConnectionString, setup, webServerOptions); }); var serverHandler = new RequestDelegate(async context => { var webProxyServer = context.RequestServices.GetService(typeof(WebProxyServerOrchestrator)) as WebProxyServerOrchestrator; await webProxyServer.HandleRequestAsync(context); }); using (var server = new KestrellTestServer(configureServices)) { var clientHandler = new ResponseDelegate(async(serviceUri) => { proxyClientProvider.ServiceUri = serviceUri; do { Console.Clear(); Console.WriteLine("Web sync start"); try { var progress = new SynchronousProgress <ProgressArgs>(pa => Console.WriteLine($"{pa.Context.SyncStage}\t {pa.Message}")); var s = await agent.SynchronizeAsync(progress); Console.WriteLine(s); } catch (SyncException e) { Console.WriteLine(e.ToString()); } catch (Exception e) { Console.WriteLine("UNKNOW EXCEPTION : " + e.Message); } Console.WriteLine("Sync Ended. Press a key to start again, or Escapte to end"); } while (Console.ReadKey().Key != ConsoleKey.Escape); }); await server.Run(serverHandler, clientHandler); } }
private static async Task CreateSnapshotAsync() { // Create 2 Sql Sync providers var serverProvider = new SqlSyncProvider(DbHelper.GetDatabaseConnectionString(serverDbName)); var remoteOrchestrator = new RemoteOrchestrator(serverProvider); // specific Setup with only 2 tables, and one filtered var setup = new SyncSetup(allTables); // snapshot directory var directory = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), "Snapshots"); await remoteOrchestrator.CreateSnapshotAsync(new SyncContext(), setup, directory, 500, CancellationToken.None); // client provider var clientProvider = new SqlSyncProvider(DbHelper.GetDatabaseConnectionString(clientDbName)); // Insert a value after snapshot created using (var c = serverProvider.CreateConnection()) { var command = c.CreateCommand(); command.CommandText = "INSERT INTO [dbo].[ProductCategory] ([Name]) VALUES ('Bikes revolution');"; c.Open(); command.ExecuteNonQuery(); c.Close(); } // Creating an agent that will handle all the process var agent = new SyncAgent(clientProvider, serverProvider, setup); var syncOptions = new SyncOptions { SnapshotsDirectory = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), "Snapshots") }; // Setting the snapshots directory for client agent.Options.SnapshotsDirectory = directory; // Using the Progress pattern to handle progession during the synchronization var progress = new SynchronousProgress <ProgressArgs>(s => { Console.ForegroundColor = ConsoleColor.Green; Console.WriteLine($"{s.Context.SyncStage}:\t{s.Message}"); Console.ResetColor(); }); var remoteProgress = new SynchronousProgress <ProgressArgs>(s => { Console.ForegroundColor = ConsoleColor.Yellow; Console.WriteLine($"{s.Context.SyncStage}:\t{s.Message}"); Console.ResetColor(); }); //// Launch the sync process //if (!agent.Parameters.Contains("City")) // agent.Parameters.Add("City", "Toronto"); //if (!agent.Parameters.Contains("postal")) // agent.Parameters.Add("postal", "NULL"); do { Console.Clear(); Console.WriteLine("Sync Start"); try { var s1 = await agent.SynchronizeAsync(progress); Console.WriteLine(s1); } catch (Exception e) { Console.WriteLine(e.Message); } } while (Console.ReadKey().Key != ConsoleKey.Escape); Console.WriteLine("End"); }
public async Task RemoteOrchestrator_CreateSnapshot_CheckInterceptors() { var dbName = HelperDatabase.GetRandomName("tcp_lo_"); await HelperDatabase.CreateDatabaseAsync(ProviderType.Sql, dbName, true); var cs = HelperDatabase.GetConnectionString(ProviderType.Sql, dbName); var sqlProvider = new SqlSyncProvider(cs); var ctx = new AdventureWorksContext((dbName, ProviderType.Sql, sqlProvider), true, true); await ctx.Database.EnsureCreatedAsync(); var scopeName = "scopesnap1"; var onSnapshotCreating = false; var onSnapshotCreated = false; // snapshot directory var snapshotDirctoryName = HelperDatabase.GetRandomName(); var snapshotDirectory = Path.Combine(Environment.CurrentDirectory, snapshotDirctoryName); var options = new SyncOptions { SnapshotsDirectory = snapshotDirectory, BatchSize = 200 }; var setup = new SyncSetup(Tables); var provider = new SqlSyncProvider(cs); var orchestrator = new RemoteOrchestrator(provider, options, setup, scopeName); // Assert on connection and transaction interceptors BaseOrchestratorTests.AssertConnectionAndTransaction(orchestrator, SyncStage.SnapshotCreating, SyncStage.SnapshotCreated); orchestrator.OnSnapshotCreating(args => { Assert.IsType <SnapshotCreatingArgs>(args); Assert.Equal(SyncStage.SnapshotCreating, args.Context.SyncStage); Assert.Equal(scopeName, args.Context.ScopeName); Assert.NotNull(args.Connection); Assert.NotNull(args.Transaction); Assert.Equal(ConnectionState.Open, args.Connection.State); Assert.NotNull(args.Schema); Assert.Equal(snapshotDirectory, args.SnapshotDirectory); Assert.NotEqual(0, args.Timestamp); onSnapshotCreating = true; }); orchestrator.OnSnapshotCreated(args => { Assert.IsType <SnapshotCreatedArgs>(args); Assert.Equal(SyncStage.SnapshotCreated, args.Context.SyncStage); Assert.Equal(scopeName, args.Context.ScopeName); Assert.NotNull(args.Connection); Assert.Null(args.Transaction); Assert.Equal(ConnectionState.Closed, args.Connection.State); Assert.NotNull(args.Schema); Assert.NotNull(args.BatchInfo); var finalDirectoryFullName = Path.Combine(snapshotDirectory, scopeName); Assert.Equal(finalDirectoryFullName, args.BatchInfo.DirectoryRoot); Assert.Equal("ALL", args.BatchInfo.DirectoryName); Assert.Single(args.BatchInfo.BatchPartsInfo); Assert.Equal(17, args.BatchInfo.BatchPartsInfo[0].Tables.Length); Assert.True(args.BatchInfo.BatchPartsInfo[0].IsLastBatch); onSnapshotCreated = true; }); var bi = await orchestrator.CreateSnapshotAsync(); Assert.Equal(SyncStage.SnapshotCreated, orchestrator.GetContext().SyncStage); Assert.True(onSnapshotCreating); Assert.True(onSnapshotCreated); HelperDatabase.DropDatabase(ProviderType.Sql, dbName); }