Exemplo n.º 1
0
    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);
Exemplo n.º 2
0
        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);
        }
Exemplo n.º 3
0
        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());
        }
Exemplo n.º 4
0
        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);
        }
Exemplo n.º 5
0
        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);
        }
Exemplo n.º 6
0
        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);
        }
Exemplo n.º 7
0
        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);
        }
Exemplo n.º 8
0
    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);
        }
    }
Exemplo n.º 9
0
    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);
        }