public void DataValidation() { string fileContent = "Le TP 2/3 consiste à mettre en place un système de partage de fichier inspiré de systèmes comme\r\n" + "Dropbox, GoogleDrive, etc. Le système permettra à différents clients de partager et de\r\n" + "synchroniser des fichiers au sein de groupes définis. Le système est constitué de deux\r\n" + "composantes : un serveur central et un client. Le serveur est accessible à une adresse fixe,\r\n" + "connue de tous les clients. Le serveur a pour rôle de synchroniser, recevoir et transmettre les\r\n" + "fichiers des clients, et gérer les groupes auxquels les clients peuvent se rattacher. Les clients\r\n" + "doivent se synchroniser avec le serveur. Le système à implémenter est donc un système de clientserveur\r\n" + "basé sur le protocole TCP."; string fileAdded = Path.Combine(TESTING_PATH, GROUP1, Path.GetRandomFileName()); GroupSummary oldSummary = new GroupSummary(GROUP1, TESTING_PATH); File.WriteAllText(fileAdded, fileContent); GroupSummary newSummary = new GroupSummary(GROUP1, TESTING_PATH); byte[] extractData = newSummary.GenerateRevisions(oldSummary)[0].Data; //WriteAllText write in UTF8 by default. Assert.AreEqual(Encoding.UTF8.GetBytes(fileContent), extractData); File.Delete(fileAdded); }
public void GenerateRevision() { string fileAdded = Path.Combine(TESTING_PATH, GROUP1, Path.GetRandomFileName()); string fileDeleted = Path.Combine(TESTING_PATH, GROUP1, Path.GetRandomFileName()); string fileModifed = Path.Combine(TESTING_PATH, GROUP1, Path.GetRandomFileName()); string fileModifedPast = Path.Combine(TESTING_PATH, GROUP1, Path.GetRandomFileName()); File.Create(fileDeleted).Close(); File.Create(fileModifed).Close(); File.Create(fileModifedPast).Close(); GroupSummary oldSummary = new GroupSummary(GROUP1, TESTING_PATH); //When we create a file, a stream is created, so we need to close the stream because we are done with it. File.Create(fileAdded).Close(); File.Delete(fileDeleted); File.SetLastWriteTime(fileModifed, DateTime.Now); File.SetLastWriteTime(fileModifedPast, DateTime.Now - new TimeSpan(12, 0, 0, 0)); GroupSummary newSummary = new GroupSummary(GROUP1, TESTING_PATH); List <Revision> result = newSummary.GenerateRevisions(oldSummary); Assert.AreEqual(4, result.Count); //We are suppose to have only one new file. Assert.AreEqual(1, result.Count(revision => revision.Action == Action.Create)); Revision createRevision = result.Find(revision => revision.Action == Action.Create); Assert.AreEqual(Path.GetFileName(fileAdded), createRevision.File.Name); Assert.AreEqual(GROUP1, createRevision.GroupName); //Delete Test Assert.AreEqual(1, result.Count(revision => revision.Action == Action.Delete)); Revision deleteRevision = result.Find(revision => revision.Action == Action.Delete); Assert.AreEqual(Path.GetFileName(fileDeleted), deleteRevision.File.Name); Assert.AreEqual(GROUP1, deleteRevision.GroupName); //Modify test Assert.AreEqual(2, result.Count(revision => revision.Action == Action.Modify)); Revision modifyRevision = result.Find(revision => revision.File.Name == Path.GetFileName(fileModifed)); Assert.AreEqual(Path.GetFileName(fileModifed), modifyRevision.File.Name); Assert.AreEqual(GROUP1, modifyRevision.GroupName); //Modify test past Revision modifyRevisionpast = result.Find(revision => revision.File.Name == Path.GetFileName(fileModifedPast)); Assert.AreEqual(Path.GetFileName(fileModifedPast), modifyRevisionpast.File.Name); Assert.AreEqual(GROUP1, modifyRevisionpast.GroupName); File.Delete(fileAdded); File.Delete(fileModifed); File.Delete(fileModifedPast); }
/// <summary> /// Generate and push revisions list /// </summary> /// <returns>Revision list of the server.</returns> public List <Revision> UpdateServerHistory() { List <Revision> localRevisions = new List <Revision>(); List <GroupSummary> newGroupSummaries = new List <GroupSummary>(); //Creating the revision list foreach (GroupSummary group in lastGroupsSummaries) { GroupSummary updateSummary = new GroupSummary(group.GroupName, rootFolderPath); localRevisions.AddRange(updateSummary.GenerateRevisions(group)); newGroupSummaries.Add(updateSummary); } lastGroupsSummaries = newGroupSummaries; List <Revision> serverRevisions = access.UpdateServerHistory(userName, localRevisions, lastGroupsSummaries); return(serverRevisions); }
public void Execute() { // Blocking call foreach (Job job in syncJobs.GetConsumingEnumerable()) { Console.WriteLine(@"Execute Job {0}", ++executionCount); List <Revision> returnRevisions = new List <Revision>(); // For each client group revision foreach (GroupSummary clientGroupSummary in job.GroupSummaries) { // Check user authorizations if (dataStore.CheckUserInGroup(job.Username, clientGroupSummary.GroupName)) { // Get the server GroupSummary equal to client GroupSummary GroupSummary serverGroupSummary = serverGroupSummaries.Find(s => s.GroupName == clientGroupSummary.GroupName); if (serverGroupSummary != null) { // Build revision list with client List <Revision> revisions = serverGroupSummary.GenerateRevisions(clientGroupSummary); foreach (Revision rev in revisions) { ShareLibrary.Models.FileInfo currentServerFile = serverGroupSummary.Files.Find(f => f.Name == rev.File.Name); ShareLibrary.Models.FileInfo currentClientFile = clientGroupSummary.Files.Find(f => f.Name == rev.File.Name); Revision currentRelatedjobRevision = job.Revisions.Find(r => r.File?.Name == currentClientFile?.Name); switch (rev.Action) { case Action.Create: // Rebind the currentRelatedjobRevision from the server instead of the client currentRelatedjobRevision = job.Revisions.Find(r => r.File?.Name == currentServerFile?.Name); // Case 1 : The file was deleted by the current client // Update server history (delete the current file) if (currentRelatedjobRevision?.File.Name == rev.File.Name && currentRelatedjobRevision?.Action == Action.Delete) { currentRelatedjobRevision.Apply(rootPath); serverGroupSummary.Update(); } // Case 2 : There is a new file on the server and the current client doesn't have it. // Add revision to response with data (Create) else { returnRevisions.Add(rev); } break; case Action.Modify: rev.Data = currentRelatedjobRevision?.Data ?? rev.Data; // Case 1 : Server modification date > client modification date // Add revision to response with data (Modify) if (currentServerFile.LastModificationDate > currentClientFile.LastModificationDate) { returnRevisions.Add(rev); } // Case 2 : Server modification date < client modification date // Update server history (replace the current file) else { rev.Apply(rootPath); serverGroupSummary.Update(); } break; case Action.Delete: // Case 1 : The file was created by the current client. // Update server history (add the current file) if (currentRelatedjobRevision?.Action == Action.Create) { currentRelatedjobRevision.Apply(rootPath); serverGroupSummary.Update(); } // Case 2 : The file is deleted for real (deleted from an other client) // Add revision to response (Delete) else { rev.Data = new byte[0]; returnRevisions.Add(rev); } break; } } } else { // Initial case when the server does not have the client group synced // Add the client files (revisions) to the server files List <Revision> clientRevisions = job.Revisions.FindAll(r => r.GroupName == clientGroupSummary.GroupName); // Create the group directory Directory.CreateDirectory(Path.Combine(rootPath, clientGroupSummary.GroupName)); // Add every client file to the server foreach (Revision clientRev in clientRevisions) { clientRev.Apply(rootPath); } // Create the server group summary because he didn't exist serverGroupSummaries.Add(new GroupSummary(clientGroupSummary.GroupName, rootPath)); } } } // Return the truth job.CallBack(returnRevisions); } }