public async Task DeleteFromServer(SyncConfiguration conf) { conf.Add(fixture.Tables); configurationProvider = () => conf; var updateRowScript = $@" Declare @id uniqueidentifier; Select top 1 @id = ServiceTicketID from ServiceTickets; Delete From [ServiceTickets] Where ServiceTicketId = @id"; using (var sqlConnection = new SqlConnection(fixture.ServerConnectionString)) { using (var sqlCmd = new SqlCommand(updateRowScript, sqlConnection)) { sqlConnection.Open(); sqlCmd.ExecuteNonQuery(); sqlConnection.Close(); } } // Assert var session = await agent.SynchronizeAsync(); Assert.Equal(1, session.TotalChangesDownloaded); Assert.Equal(0, session.TotalChangesUploaded); }
public async Task InsertFromServer(SyncConfiguration conf) { conf.Add(fixture.Tables); configurationProvider = () => conf; var insertRowScript = $@"INSERT [ServiceTickets] ([ServiceTicketID], [Title], [Description], [StatusValue], [EscalationLevel], [Opened], [Closed], [CustomerID]) VALUES (newid(), 'Insert One Row', 'Description Insert One Row', 1, 0, getdate(), NULL, 1)"; // Act using (var sqlConnection = new SqlConnection(fixture.ServerConnectionString)) { using (var sqlCmd = new SqlCommand(insertRowScript, sqlConnection)) { sqlConnection.Open(); sqlCmd.ExecuteNonQuery(); sqlConnection.Close(); } } // Assert var session = await agent.SynchronizeAsync(); Assert.Equal(1, session.TotalChangesDownloaded); Assert.Equal(0, session.TotalChangesUploaded); }
public async Task SyncNoRows(SyncConfiguration conf) { using (var server = new KestrellTestServer()) { var serverHandler = new RequestDelegate(async context => { conf.Add(fixture.Tables); serverProvider.SetConfiguration(conf); proxyServerProvider.SerializationFormat = conf.SerializationFormat; await proxyServerProvider.HandleRequestAsync(context); }); var clientHandler = new ResponseDelegate(async(serviceUri) => { proxyClientProvider.ServiceUri = new Uri(serviceUri); proxyClientProvider.SerializationFormat = conf.SerializationFormat; var session = await agent.SynchronizeAsync(); Assert.Equal(0, session.TotalChangesDownloaded); Assert.Equal(0, session.TotalChangesUploaded); }); await server.Run(serverHandler, clientHandler); } }
public async Task UpdateFromClient(SyncConfiguration conf) { conf.Add(fixture.Tables); configurationProvider = () => conf; // provision client infrastructure - otherwise this test will fail when run separately, because the sqlite db table won't yet exist await agent.SynchronizeAsync(); Guid newId = Guid.NewGuid(); var insertRowScript = $@"INSERT INTO [ServiceTickets] ([ServiceTicketID], [Title], [Description], [StatusValue], [EscalationLevel], [Opened], [Closed], [CustomerID]) VALUES (@id, 'Insert One Row in Sqlite client', 'Description Insert One Row', 1, 0, datetime('now'), NULL, 1)"; // Act 1 using (var sqlConnection = new SqliteConnection(fixture.ClientSqliteConnectionString)) { using (var sqlCmd = new SqliteCommand(insertRowScript, sqlConnection)) { sqlCmd.Parameters.AddWithValue("@id", newId); sqlConnection.Open(); sqlCmd.ExecuteNonQuery(); sqlConnection.Close(); } } // Assert 1 var session1 = await agent.SynchronizeAsync(); Assert.Equal(0, session1.TotalChangesDownloaded); Assert.Equal(1, session1.TotalChangesUploaded); var updateRowScript = $@" Update [ServiceTickets] Set [Title] = 'Updated from Sqlite Client side !' Where ServiceTicketId = @id"; // Act 2 using (var sqlConnection = new SqliteConnection(fixture.ClientSqliteConnectionString)) { using (var sqlCmd = new SqliteCommand(updateRowScript, sqlConnection)) { sqlCmd.Parameters.AddWithValue("@id", newId); sqlConnection.Open(); sqlCmd.ExecuteNonQuery(); sqlConnection.Close(); } } // Assert 2 var session2 = await agent.SynchronizeAsync(); Assert.Equal(0, session2.TotalChangesDownloaded); Assert.Equal(1, session2.TotalChangesUploaded); }
public async Task SyncNoRows(SyncConfiguration conf) { conf.Add(fixture.Tables); configurationProvider = () => conf; // Act var session = await agent.SynchronizeAsync(); // Assert Assert.Equal(0, session.TotalChangesDownloaded); Assert.Equal(0, session.TotalChangesUploaded); }
public async Task InsertFromClient(SyncConfiguration conf) { Guid newId = Guid.NewGuid(); var insertRowScript = $@"INSERT INTO [ServiceTickets] ([ServiceTicketID], [Title], [Description], [StatusValue], [EscalationLevel], [Opened], [Closed], [CustomerID]) VALUES (@id, 'Insert One Row in Sqlite client', 'Description Insert One Row', 1, 0, datetime('now'), NULL, 1)"; int nbRowsInserted = 0; using (var sqlConnection = new SqliteConnection(fixture.ClientSqliteConnectionString)) { using (var sqlCmd = new SqliteCommand(insertRowScript, sqlConnection)) { sqlCmd.Parameters.AddWithValue("@id", newId); sqlConnection.Open(); nbRowsInserted = sqlCmd.ExecuteNonQuery(); sqlConnection.Close(); } } if (nbRowsInserted < 0) { throw new Exception("Row not inserted"); } using (var server = new KestrellTestServer()) { var serverHandler = new RequestDelegate(async context => { conf.Add(fixture.Tables); serverProvider.SetConfiguration(conf); proxyServerProvider.SerializationFormat = conf.SerializationFormat; await proxyServerProvider.HandleRequestAsync(context); }); var clientHandler = new ResponseDelegate(async(serviceUri) => { proxyClientProvider.ServiceUri = new Uri(serviceUri); proxyClientProvider.SerializationFormat = conf.SerializationFormat; var session = await agent.SynchronizeAsync(); Assert.Equal(0, session.TotalChangesDownloaded); Assert.Equal(1, session.TotalChangesUploaded); }); await server.Run(serverHandler, clientHandler); } }
public async Task DeleteFromClient(SyncConfiguration conf) { int count; var selectcount = $@"Select count(*) From [ServiceTickets]"; var updateRowScript = $@"Delete From [ServiceTickets]"; using (var sqlConnection = new SqlConnection(fixture.Client1ConnectionString)) { sqlConnection.Open(); using (var sqlCmd = new SqlCommand(selectcount, sqlConnection)) count = (int)sqlCmd.ExecuteScalar(); using (var sqlCmd = new SqlCommand(updateRowScript, sqlConnection)) sqlCmd.ExecuteNonQuery(); sqlConnection.Close(); } using (var server = new KestrellTestServer()) { var serverHandler = new RequestDelegate(async context => { conf.Add(fixture.Tables); serverProvider.SetConfiguration(conf); proxyServerProvider.SerializationFormat = conf.SerializationFormat; await proxyServerProvider.HandleRequestAsync(context); }); var clientHandler = new ResponseDelegate(async(serviceUri) => { proxyClientProvider.ServiceUri = new Uri(serviceUri); proxyClientProvider.SerializationFormat = conf.SerializationFormat; var session = await agent.SynchronizeAsync(); Assert.Equal(0, session.TotalChangesDownloaded); Assert.Equal(count, session.TotalChangesUploaded); }); await server.Run(serverHandler, clientHandler); } // check all rows deleted on server side using (var sqlConnection = new SqlConnection(fixture.ServerConnectionString)) { sqlConnection.Open(); using (var sqlCmd = new SqlCommand(selectcount, sqlConnection)) count = (int)sqlCmd.ExecuteScalar(); } Assert.Equal(0, count); }
public async Task UpdateFromServer(SyncConfiguration conf) { string title = $"Update from server at {DateTime.Now.Ticks.ToString()}"; var updateRowScript = $@" Declare @id uniqueidentifier; Select top 1 @id = ServiceTicketID from ServiceTickets; Update [ServiceTickets] Set [Title] = '{title}' Where ServiceTicketId = @id"; using (var sqlConnection = new SqlConnection(fixture.ServerConnectionString)) { using (var sqlCmd = new SqlCommand(updateRowScript, sqlConnection)) { sqlConnection.Open(); sqlCmd.ExecuteNonQuery(); sqlConnection.Close(); } } using (var server = new KestrellTestServer()) { var serverHandler = new RequestDelegate(async context => { conf.Add(fixture.Tables); serverProvider.SetConfiguration(conf); proxyServerProvider.SerializationFormat = conf.SerializationFormat; await proxyServerProvider.HandleRequestAsync(context); }); var clientHandler = new ResponseDelegate(async(serviceUri) => { proxyClientProvider.ServiceUri = new Uri(serviceUri); proxyClientProvider.SerializationFormat = conf.SerializationFormat; var session = await agent.SynchronizeAsync(); Assert.Equal(1, session.TotalChangesDownloaded); Assert.Equal(0, session.TotalChangesUploaded); }); await server.Run(serverHandler, clientHandler); } }
public async Task InsertFromServer(SyncConfiguration conf) { var insertRowScript = $@"INSERT [ServiceTickets] ([ServiceTicketID], [Title], [Description], [StatusValue], [EscalationLevel], [Opened], [Closed], [CustomerID]) VALUES (newid(), N'Insert One Row', N'Description Insert One Row', 1, 0, getdate(), NULL, 1)"; using (var sqlConnection = new SqlConnection(fixture.ServerConnectionString)) { using (var sqlCmd = new SqlCommand(insertRowScript, sqlConnection)) { sqlConnection.Open(); sqlCmd.ExecuteNonQuery(); sqlConnection.Close(); } } using (var server = new KestrellTestServer()) { var serverHandler = new RequestDelegate(async context => { conf.Add(fixture.Tables); serverProvider.SetConfiguration(conf); proxyServerProvider.SerializationFormat = conf.SerializationFormat; await proxyServerProvider.HandleRequestAsync(context); }); var clientHandler = new ResponseDelegate(async(serviceUri) => { proxyClientProvider.ServiceUri = new Uri(serviceUri); proxyClientProvider.SerializationFormat = conf.SerializationFormat; var session = await agent.SynchronizeAsync(); Assert.Equal(1, session.TotalChangesDownloaded); Assert.Equal(0, session.TotalChangesUploaded); }); await server.Run(serverHandler, clientHandler); } }
public async Task DeleteFromClient(SyncConfiguration conf) { conf.Add(fixture.Tables); configurationProvider = () => conf; // provision client infrastructure - otherwise this test will fail when run separately, because the sqlite db table won't yet exist await agent.SynchronizeAsync(); long count; var selectcount = $@"Select count(*) From [ServiceTickets]"; var updateRowScript = $@"Delete From [ServiceTickets]"; using (var sqlConnection = new SqliteConnection(fixture.ClientSqliteConnectionString)) { sqlConnection.Open(); using (var sqlCmd = new SqliteCommand(selectcount, sqlConnection)) count = (long)sqlCmd.ExecuteScalar(); using (var sqlCmd = new SqliteCommand(updateRowScript, sqlConnection)) sqlCmd.ExecuteNonQuery(); sqlConnection.Close(); } // Assert var session = await agent.SynchronizeAsync(); Assert.Equal(0, session.TotalChangesDownloaded); Assert.Equal(count, session.TotalChangesUploaded); // check all rows deleted on server side using (var sqlConnection = new SqlConnection(fixture.ServerConnectionString)) { sqlConnection.Open(); using (var sqlCmd = new SqlCommand(selectcount, sqlConnection)) count = (int)sqlCmd.ExecuteScalar(); } Assert.Equal(0, count); }
public async Task ConflictUpdateUpdateClientWins(SyncConfiguration conf) { var id = Guid.NewGuid().ToString(); using (var sqlConnection = new SqlConnection(fixture.Client1ConnectionString)) { var script = $@"INSERT [ServiceTickets] ([ServiceTicketID], [Title], [Description], [StatusValue], [EscalationLevel], [Opened], [Closed], [CustomerID]) VALUES (N'{id}', N'Line for conflict', N'Description client', 1, 0, getdate(), NULL, 1)"; using (var sqlCmd = new SqlCommand(script, sqlConnection)) { sqlConnection.Open(); sqlCmd.ExecuteNonQuery(); sqlConnection.Close(); } } using (var server = new KestrellTestServer()) { var serverHandler = new RequestDelegate(async context => { conf.Add(fixture.Tables); serverProvider.SetConfiguration(conf); proxyServerProvider.SerializationFormat = conf.SerializationFormat; await proxyServerProvider.HandleRequestAsync(context); }); var clientHandler = new ResponseDelegate(async(serviceUri) => { proxyClientProvider.ServiceUri = new Uri(serviceUri); proxyClientProvider.SerializationFormat = conf.SerializationFormat; var session = await agent.SynchronizeAsync(); // check statistics Assert.Equal(0, session.TotalChangesDownloaded); Assert.Equal(1, session.TotalChangesUploaded); Assert.Equal(0, session.TotalSyncConflicts); }); await server.Run(serverHandler, clientHandler); } using (var sqlConnection = new SqlConnection(fixture.Client1ConnectionString)) { var script = $@"Update [ServiceTickets] Set Title = 'Updated from Client' Where ServiceTicketId = '{id}'"; using (var sqlCmd = new SqlCommand(script, sqlConnection)) { sqlConnection.Open(); sqlCmd.ExecuteNonQuery(); sqlConnection.Close(); } } using (var sqlConnection = new SqlConnection(fixture.ServerConnectionString)) { var script = $@"Update [ServiceTickets] Set Title = 'Updated from Server' Where ServiceTicketId = '{id}'"; using (var sqlCmd = new SqlCommand(script, sqlConnection)) { sqlConnection.Open(); sqlCmd.ExecuteNonQuery(); sqlConnection.Close(); } } using (var server = new KestrellTestServer()) { var serverHandler = new RequestDelegate(async context => { conf.Add(fixture.Tables); serverProvider.SetConfiguration(conf); proxyServerProvider.SerializationFormat = conf.SerializationFormat; // Since we move to server side, it's server to handle errors serverProvider.ApplyChangedFailed += (s, args) => { args.Action = ApplyAction.RetryWithForceWrite; }; await proxyServerProvider.HandleRequestAsync(context); }); var clientHandler = new ResponseDelegate(async(serviceUri) => { proxyClientProvider.ServiceUri = new Uri(serviceUri); proxyClientProvider.SerializationFormat = conf.SerializationFormat; SyncContext session = null; await Assert.RaisesAsync <ApplyChangeFailedEventArgs>( h => serverProvider.ApplyChangedFailed += h, h => serverProvider.ApplyChangedFailed -= h, async() => { session = await agent.SynchronizeAsync(); }); // check statistics Assert.Equal(0, session.TotalChangesDownloaded); Assert.Equal(1, session.TotalChangesUploaded); Assert.Equal(1, session.TotalSyncConflicts); }); await server.Run(serverHandler, clientHandler); } string expectedRes = string.Empty; using (var sqlConnection = new SqlConnection(fixture.ServerConnectionString)) { var script = $@"Select Title from [ServiceTickets] Where ServiceTicketID='{id}'"; using (var sqlCmd = new SqlCommand(script, sqlConnection)) { sqlConnection.Open(); expectedRes = sqlCmd.ExecuteScalar() as string; sqlConnection.Close(); } } // check good title on client Assert.Equal("Updated from Client", expectedRes); }
public async Task ConflictInsertInsertConfigurationClientWins(SyncConfiguration conf) { Guid id = Guid.NewGuid(); using (var sqlConnection = new SqlConnection(fixture.Client1ConnectionString)) { var script = $@"INSERT [ServiceTickets] ([ServiceTicketID], [Title], [Description], [StatusValue], [EscalationLevel], [Opened], [Closed], [CustomerID]) VALUES (N'{id.ToString()}', N'Conflict Line Client', N'Description client', 1, 0, getdate(), NULL, 1)"; using (var sqlCmd = new SqlCommand(script, sqlConnection)) { sqlConnection.Open(); sqlCmd.ExecuteNonQuery(); sqlConnection.Close(); } } using (var sqlConnection = new SqlConnection(fixture.ServerConnectionString)) { var script = $@"INSERT [ServiceTickets] ([ServiceTicketID], [Title], [Description], [StatusValue], [EscalationLevel], [Opened], [Closed], [CustomerID]) VALUES (N'{id.ToString()}', N'Conflict Line Server', N'Description client', 1, 0, getdate(), NULL, 1)"; using (var sqlCmd = new SqlCommand(script, sqlConnection)) { sqlConnection.Open(); sqlCmd.ExecuteNonQuery(); sqlConnection.Close(); } } using (var server = new KestrellTestServer()) { var serverHandler = new RequestDelegate(async context => { conf.Add(fixture.Tables); conf.ConflictResolutionPolicy = ConflictResolutionPolicy.ClientWins; serverProvider.SetConfiguration(conf); proxyServerProvider.SerializationFormat = conf.SerializationFormat; await proxyServerProvider.HandleRequestAsync(context); }); var clientHandler = new ResponseDelegate(async(serviceUri) => { proxyClientProvider.ServiceUri = new Uri(serviceUri); proxyClientProvider.SerializationFormat = conf.SerializationFormat; var session = await agent.SynchronizeAsync(); // check statistics Assert.Equal(0, session.TotalChangesDownloaded); Assert.Equal(1, session.TotalChangesUploaded); Assert.Equal(1, session.TotalSyncConflicts); }); await server.Run(serverHandler, clientHandler); } string expectedRes = string.Empty; using (var sqlConnection = new SqlConnection(fixture.ServerConnectionString)) { var script = $@"Select Title from [ServiceTickets] Where ServiceTicketID='{id.ToString()}'"; using (var sqlCmd = new SqlCommand(script, sqlConnection)) { sqlConnection.Open(); expectedRes = sqlCmd.ExecuteScalar() as string; sqlConnection.Close(); } } // check good title on client Assert.Equal("Conflict Line Client", expectedRes); }
internal SyncContext Sync(string value) { if (String.IsNullOrEmpty(value)) { throw new Exception("Loading a project requires a name. Ex : dotnet sync --load project01"); } Project project = DataStore.Current.LoadProject(value); if (project == null) { throw new Exception($"Project {value} does not exists."); } if (project.ServerProvider == null || string.IsNullOrEmpty(project.ServerProvider.ConnectionString)) { throw new Exception($"Server provider for project {project.Name} is not correctly defined. See help: dotnet sync provider --help"); } if (project.ClientProvider == null || string.IsNullOrEmpty(project.ClientProvider.ConnectionString)) { throw new Exception($"Client provider for project {project.Name} is not correctly defined. See help: dotnet sync provider --help"); } if (project.ServerProvider.ProviderType != ProviderType.Web && (project.Tables == null || project.Tables.Count <= 0)) { throw new Exception($"No table configured for project {project.Name}. See help: dotnet sync table --help"); } IProvider serverProvider, clientprovider; switch (project.ServerProvider.ProviderType) { case ProviderType.Sqlite: throw new Exception("Can't use Sqlite as a server provider"); case ProviderType.Web: serverProvider = new WebProxyClientProvider(new Uri(project.ServerProvider.ConnectionString)); break; case ProviderType.SqlServer: default: serverProvider = new SqlSyncProvider(project.ServerProvider.ConnectionString); break; } switch (project.ClientProvider.ProviderType) { case ProviderType.Sqlite: clientprovider = new SqliteSyncProvider(project.ClientProvider.ConnectionString); break; case ProviderType.Web: throw new Exception("Web proxy is used as a proxy server. You have to use an ASP.NET web backend. CLI uses a proxy as server provider"); case ProviderType.SqlServer: default: clientprovider = new SqlSyncProvider(project.ClientProvider.ConnectionString); break; } SyncAgent agent = null; if (project.ServerProvider.ProviderType != ProviderType.Web) { SyncConfiguration syncConfiguration = new SyncConfiguration(); foreach (var t in project.Tables.OrderBy(tbl => tbl.Order)) { // Potentially user can pass something like [SalesLT].[Product] // or SalesLT.Product or Product. ObjectNameParser will handle it ObjectNameParser parser = new ObjectNameParser(t.Name); var tableName = parser.ObjectName; var schema = string.IsNullOrEmpty(t.Schema) ? parser.SchemaName : t.Schema; var dmTable = new DmTable(tableName); if (!String.IsNullOrEmpty(schema)) { dmTable.Schema = schema; } dmTable.SyncDirection = t.Direction; syncConfiguration.Add(dmTable); } syncConfiguration.BatchDirectory = string.IsNullOrEmpty(project.Configuration.BatchDirectory) ? null : project.Configuration.BatchDirectory; syncConfiguration.SerializationFormat = project.Configuration.SerializationFormat; syncConfiguration.UseBulkOperations = project.Configuration.UseBulkOperations; syncConfiguration.DownloadBatchSizeInKB = (int)Math.Min(Int32.MaxValue, project.Configuration.DownloadBatchSizeInKB); syncConfiguration.ConflictResolutionPolicy = project.Configuration.ConflictResolutionPolicy; agent = new SyncAgent(clientprovider, serverProvider, syncConfiguration); } else { agent = new SyncAgent(clientprovider, serverProvider); } agent.SyncProgress += SyncProgress; // synchronous call var syncContext = agent.SynchronizeAsync().GetAwaiter().GetResult(); agent.SyncProgress -= SyncProgress; var tsEnded = TimeSpan.FromTicks(syncContext.CompleteTime.Ticks); var tsStarted = TimeSpan.FromTicks(syncContext.StartTime.Ticks); var durationTs = tsEnded.Subtract(tsStarted); var durationstr = $"{durationTs.Hours}:{durationTs.Minutes}:{durationTs.Seconds}.{durationTs.Milliseconds}"; Console.ForegroundColor = ConsoleColor.Green; var s = $"Synchronization done. " + Environment.NewLine + $"\tTotal changes downloaded: {syncContext.TotalChangesDownloaded} " + Environment.NewLine + $"\tTotal changes uploaded: {syncContext.TotalChangesUploaded}" + Environment.NewLine + $"\tTotal duration :{durationstr} "; Console.WriteLine(s); Console.ResetColor(); return(syncContext); }
public async Task UpdateFromClient(SyncConfiguration conf) { Guid newId = Guid.NewGuid(); var insertRowScript = $@"INSERT INTO [ServiceTickets] ([ServiceTicketID], [Title], [Description], [StatusValue], [EscalationLevel], [Opened], [Closed], [CustomerID]) VALUES ('{newId.ToString()}', 'Insert One Row in SQLite client', 'Description Insert One Row', 1, 0, datetime('now'), NULL, 1)"; using (var sqlConnection = new SQLiteConnection(fixture.ClientSQLiteConnectionString)) { using (var sqlCmd = new SQLiteCommand(insertRowScript, sqlConnection)) { sqlConnection.Open(); sqlCmd.ExecuteNonQuery(); sqlConnection.Close(); } } using (var server = new KestrellTestServer()) { var serverHandler = new RequestDelegate(async context => { conf.Add(fixture.Tables); serverProvider.SetConfiguration(conf); proxyServerProvider.SerializationFormat = conf.SerializationFormat; await proxyServerProvider.HandleRequestAsync(context); }); var clientHandler = new ResponseDelegate(async(serviceUri) => { proxyClientProvider.ServiceUri = new Uri(serviceUri); proxyClientProvider.SerializationFormat = conf.SerializationFormat; var session = await agent.SynchronizeAsync(); Assert.Equal(0, session.TotalChangesDownloaded); Assert.Equal(1, session.TotalChangesUploaded); }); await server.Run(serverHandler, clientHandler); } var updateRowScript = $@" Update [ServiceTickets] Set [Title] = 'Updated from SQLite Client side !' Where ServiceTicketId = '{newId.ToString()}'"; using (var sqlConnection = new SQLiteConnection(fixture.ClientSQLiteConnectionString)) { using (var sqlCmd = new SQLiteCommand(updateRowScript, sqlConnection)) { sqlConnection.Open(); sqlCmd.ExecuteNonQuery(); sqlConnection.Close(); } } using (var server = new KestrellTestServer()) { var serverHandler = new RequestDelegate(async context => { conf.Add(fixture.Tables); serverProvider.SetConfiguration(conf); proxyServerProvider.SerializationFormat = conf.SerializationFormat; await proxyServerProvider.HandleRequestAsync(context); }); var clientHandler = new ResponseDelegate(async(serviceUri) => { proxyClientProvider.ServiceUri = new Uri(serviceUri); proxyClientProvider.SerializationFormat = conf.SerializationFormat; var session = await agent.SynchronizeAsync(); Assert.Equal(0, session.TotalChangesDownloaded); Assert.Equal(1, session.TotalChangesUploaded); }); await server.Run(serverHandler, clientHandler); } }
public async Task ConflictUpdateUpdateServerWins(SyncConfiguration conf) { Guid updateConflictId = Guid.NewGuid(); using (var sqlConnection = new SqliteConnection(fixture.ClientSqliteConnectionString)) { var script = $@"INSERT INTO [ServiceTickets] ([ServiceTicketID], [Title], [Description], [StatusValue], [EscalationLevel], [Opened], [Closed], [CustomerID]) VALUES (@id, 'Line Client', 'Description client', 1, 0, datetime('now'), NULL, 1)"; using (var sqlCmd = new SqliteCommand(script, sqlConnection)) { sqlCmd.Parameters.AddWithValue("@id", updateConflictId); sqlConnection.Open(); sqlCmd.ExecuteNonQuery(); sqlConnection.Close(); } } using (var server = new KestrellTestServer()) { var serverHandler = new RequestDelegate(async context => { conf.Add(fixture.Tables); serverProvider.SetConfiguration(conf); proxyServerProvider.SerializationFormat = conf.SerializationFormat; await proxyServerProvider.HandleRequestAsync(context); }); var clientHandler = new ResponseDelegate(async(serviceUri) => { proxyClientProvider.ServiceUri = new Uri(serviceUri); proxyClientProvider.SerializationFormat = conf.SerializationFormat; var session = await agent.SynchronizeAsync(); // check statistics Assert.Equal(0, session.TotalChangesDownloaded); Assert.Equal(1, session.TotalChangesUploaded); Assert.Equal(0, session.TotalSyncConflicts); }); await server.Run(serverHandler, clientHandler); } using (var sqlConnection = new SqliteConnection(fixture.ClientSqliteConnectionString)) { var script = $@"Update [ServiceTickets] Set Title = 'Updated from Client' Where ServiceTicketId = @id"; using (var sqlCmd = new SqliteCommand(script, sqlConnection)) { sqlCmd.Parameters.AddWithValue("@id", updateConflictId); sqlConnection.Open(); sqlCmd.ExecuteNonQuery(); sqlConnection.Close(); } } using (var sqlConnection = new SqlConnection(fixture.ServerConnectionString)) { var script = $@"Update [ServiceTickets] Set Title = 'Updated from Server' Where ServiceTicketId = '{updateConflictId.ToString()}'"; using (var sqlCmd = new SqlCommand(script, sqlConnection)) { sqlConnection.Open(); sqlCmd.ExecuteNonQuery(); sqlConnection.Close(); } } using (var server = new KestrellTestServer()) { var serverHandler = new RequestDelegate(async context => { conf.Add(fixture.Tables); serverProvider.SetConfiguration(conf); proxyServerProvider.SerializationFormat = conf.SerializationFormat; await proxyServerProvider.HandleRequestAsync(context); }); var clientHandler = new ResponseDelegate(async(serviceUri) => { proxyClientProvider.ServiceUri = new Uri(serviceUri); proxyClientProvider.SerializationFormat = conf.SerializationFormat; var session = await agent.SynchronizeAsync(); // check statistics Assert.Equal(1, session.TotalChangesDownloaded); Assert.Equal(1, session.TotalChangesUploaded); Assert.Equal(1, session.TotalSyncConflicts); }); await server.Run(serverHandler, clientHandler); } string expectedRes = string.Empty; using (var sqlConnection = new SqliteConnection(fixture.ClientSqliteConnectionString)) { var script = $@"Select Title from [ServiceTickets] Where ServiceTicketID=@id"; using (var sqlCmd = new SqliteCommand(script, sqlConnection)) { sqlCmd.Parameters.AddWithValue("@id", updateConflictId); sqlConnection.Open(); expectedRes = sqlCmd.ExecuteScalar() as string; sqlConnection.Close(); } } // check good title on client Assert.Equal("Updated from Server", expectedRes); }
public async Task ConflictUpdateUpdateClientWins(SyncConfiguration conf) { conf.Add(fixture.Tables); configurationProvider = () => conf; // provision client infrastructure - otherwise this test will fail when run separately, because the sqlite db table won't yet exist await agent.SynchronizeAsync(); var id = Guid.NewGuid().ToString(); using (var sqlConnection = new SqliteConnection(fixture.ClientSqliteConnectionString)) { var script = $@"INSERT INTO [ServiceTickets] ([ServiceTicketID], [Title], [Description], [StatusValue], [EscalationLevel], [Opened], [Closed], [CustomerID]) VALUES (@id, 'Line for conflict', 'Description client', 1, 0, datetime('now'), NULL, 1)"; using (var sqlCmd = new SqliteCommand(script, sqlConnection)) { sqlCmd.Parameters.AddWithValue("@id", id); sqlConnection.Open(); sqlCmd.ExecuteNonQuery(); sqlConnection.Close(); } } var session = await agent.SynchronizeAsync(); // check statistics Assert.Equal(0, session.TotalChangesDownloaded); Assert.Equal(1, session.TotalChangesUploaded); Assert.Equal(0, session.TotalSyncConflicts); using (var sqlConnection = new SqliteConnection(fixture.ClientSqliteConnectionString)) { var script = $@"Update [ServiceTickets] Set Title = 'Updated from Client' Where ServiceTicketId = @id"; using (var sqlCmd = new SqliteCommand(script, sqlConnection)) { sqlCmd.Parameters.AddWithValue("@id", id); sqlConnection.Open(); sqlCmd.ExecuteNonQuery(); sqlConnection.Close(); } } using (var sqlConnection = new SqlConnection(fixture.ServerConnectionString)) { var script = $@"Update [ServiceTickets] Set Title = 'Updated from Server' Where ServiceTicketId = '{id}'"; using (var sqlCmd = new SqlCommand(script, sqlConnection)) { sqlConnection.Open(); sqlCmd.ExecuteNonQuery(); sqlConnection.Close(); } } // Since we move to server side, it's server to handle errors serverProvider.ApplyChangedFailed += (s, args) => { args.Action = ConflictAction.ClientWins; }; SyncContext session2 = null; await Assert.RaisesAsync <ApplyChangeFailedEventArgs>( h => serverProvider.ApplyChangedFailed += h, h => serverProvider.ApplyChangedFailed -= h, async() => { session2 = await agent.SynchronizeAsync(); }); // check statistics Assert.Equal(0, session2.TotalChangesDownloaded); Assert.Equal(1, session2.TotalChangesUploaded); Assert.Equal(1, session2.TotalSyncConflicts); string expectedRes = string.Empty; using (var sqlConnection = new SqlConnection(fixture.ServerConnectionString)) { var script = $@"Select Title from [ServiceTickets] Where ServiceTicketID='{id}'"; using (var sqlCmd = new SqlCommand(script, sqlConnection)) { sqlConnection.Open(); expectedRes = sqlCmd.ExecuteScalar() as string; sqlConnection.Close(); } } // check good title on client Assert.Equal("Updated from Client", expectedRes); }
public async Task ConflictInsertInsertConfigurationClientWins(SyncConfiguration conf) { conf.ConflictResolutionPolicy = ConflictResolutionPolicy.ClientWins; conf.Add(fixture.Tables); configurationProvider = () => conf; // provision client infrastructure - otherwise this test will fail when run separately, because the sqlite db table won't yet exist await agent.SynchronizeAsync(); Guid id = Guid.NewGuid(); using (var sqlConnection = new SqliteConnection(fixture.ClientSqliteConnectionString)) { var script = $@"INSERT INTO [ServiceTickets] ([ServiceTicketID], [Title], [Description], [StatusValue], [EscalationLevel], [Opened], [Closed], [CustomerID]) VALUES (@id, 'Conflict Line Client', 'Description client', 1, 0, datetime('now'), NULL, 1)"; using (var sqlCmd = new SqliteCommand(script, sqlConnection)) { sqlCmd.Parameters.AddWithValue("@id", id); sqlConnection.Open(); sqlCmd.ExecuteNonQuery(); sqlConnection.Close(); } } using (var sqlConnection = new SqlConnection(fixture.ServerConnectionString)) { var script = $@"INSERT [ServiceTickets] ([ServiceTicketID], [Title], [Description], [StatusValue], [EscalationLevel], [Opened], [Closed], [CustomerID]) VALUES ('{id.ToString()}', 'Conflict Line Server', 'Description client', 1, 0, getdate(), NULL, 1)"; using (var sqlCmd = new SqlCommand(script, sqlConnection)) { sqlConnection.Open(); sqlCmd.ExecuteNonQuery(); sqlConnection.Close(); } } // Act var session = await agent.SynchronizeAsync(); // check statistics Assert.Equal(0, session.TotalChangesDownloaded); Assert.Equal(1, session.TotalChangesUploaded); Assert.Equal(1, session.TotalSyncConflicts); string expectedRes = string.Empty; using (var sqlConnection = new SqlConnection(fixture.ServerConnectionString)) { var script = $@"Select Title from [ServiceTickets] Where ServiceTicketID='{id.ToString()}'"; using (var sqlCmd = new SqlCommand(script, sqlConnection)) { sqlConnection.Open(); expectedRes = sqlCmd.ExecuteScalar() as string; sqlConnection.Close(); } } // check good title on client Assert.Equal("Conflict Line Client", expectedRes); }