public static SortFilesSettings FillFromUI(SortFilesAction action, string skipDirs, string skipFiles, string dirLeft, string dirRight, bool checkbox1, bool checkbox2, bool mirror, bool previewOnly) { var settings = new SortFilesSettings(); settings.SkipDirectories.AddRange(TextLineByLineToList(skipDirs)); settings.SkipFiles.AddRange(TextLineByLineToList(skipFiles)); settings.LeftDirectory = dirLeft; settings.RightDirectory = dirRight; settings.AllowFiletimesDifferForFAT = checkbox1; settings.AllowFiletimesDifferForDST = checkbox2; settings.Mirror = mirror; settings.PreviewOnly = previewOnly; settings.LogFile = Path.Combine(TestUtil.GetTestWriteDirectory(), "log" + Utils.GetRandomDigits() + ".txt"); // the right directory field isn't shown in UI, we need to set it manually if (action == SortFilesAction.SearchDuplicatesInOneDir) { settings.RightDirectory = settings.LeftDirectory; } else if (action == SortFilesAction.SearchDuplicates) { settings.SearchDuplicatesCanUseFiletimes = checkbox1; } if (!Directory.Exists(settings.LeftDirectory)) { Utils.MessageErr("Directory does not exist " + settings.LeftDirectory, true); return(null); } else if (!Directory.Exists(settings.RightDirectory) && action != SortFilesAction.SearchDuplicatesInOneDir) { Utils.MessageErr("Directory does not exist " + settings.RightDirectory, true); return(null); } if (settings.LeftDirectory.EndsWith(Utils.Sep, StringComparison.Ordinal) || settings.RightDirectory.EndsWith(Utils.Sep, StringComparison.Ordinal)) { Utils.MessageErr("directory should not end with slash.", true); return(null); } if (action != SortFilesAction.SearchDuplicatesInOneDir && !Utils.ArePathsDistinct( settings.LeftDirectory, settings.RightDirectory)) { Utils.MessageErr("directories must be distinct.", true); return(null); } return(settings); }
public static bool AreTimesEqual(DateTime dt1, DateTime dt2, SortFilesSettings settings) { if (settings.AllowFiletimesDifferForDST) { return(AreTimesEqualHelper(dt1, dt2, settings) || AreTimesEqualHelper(dt1, dt2.AddHours(1), settings) || AreTimesEqualHelper(dt1, dt2.AddHours(-1), settings)); } else { return(AreTimesEqualHelper(dt1, dt2, settings)); } }
static bool AreTimesEqualHelper(DateTime dt1, DateTime dt2, SortFilesSettings settings) { if (settings.AllowFiletimesDifferForFAT) { // allow times to differ return(Math.Abs(dt1.Ticks - dt2.Ticks) <= AllowDifferSeconds * TimeSpan.TicksPerSecond); } else { // times must be exact var ret = dt1.Ticks == dt2.Ticks; return(ret); } }
public static string[] GetArgs(SortFilesSettings settings) { var args = new List <string>(); args.Add(settings.LeftDirectory); args.Add(settings.RightDirectory); args.Add("/E"); // subdirectories, including empty directories if (settings.AllowFiletimesDifferForFAT) { args.Add("/FFT"); } if (settings.AllowFiletimesDifferForDST) { args.Add("/DST"); } if (settings.Mirror) { args.Add("/MIR"); } if (settings.PreviewOnly) { args.Add("/L"); } foreach (var s in settings.SkipDirectories) { args.Add("/XD"); args.Add(s); } foreach (var s in settings.SkipFiles) { args.Add("/XF"); args.Add(s); } args.Add("/NS"); // no sizes in output args.Add("/FP"); // full paths in logs args.Add("/NP"); // don't show progress args.Add("/LOG:" + settings.LogFile); return(args.ToArray()); }
public static List <FileComparisonResult> Go(SortFilesSettings settings) { // first, just make an index that simply maps filesizes to filenames. // we don't need to compute any content-hashes yet, because if there // is only one file with that filesize, we know it's not a duplicate. var results = new List <FileComparisonResult>(); var di = new DirectoryInfo(settings.LeftDirectory); var index = SortFilesSearchDuplicates.MapFilesizesToFilenames( settings.LeftDirectory, di.EnumerateFiles("*", SearchOption.AllDirectories)); foreach (var list in index.Values) { if (list.Count > 1) { // if there's more than one file with the same filesize, // compute hashes of contents to look for duplicates. for (int i = 0; i < list.Count; i++) { list[i].ContentHash = Utils.GetSha512( settings.LeftDirectory + list[i].Filename); // have we seen this hash before? this is an n-squared loop, but // basically amortized by the cost of computing hashes. for (int j = 0; j < i; j++) { if (list[j].ContentHash == list[i].ContentHash) { // consistently put the first-appearing file on the 'left' side // so that the user can conveniently safely delete all on 'right'. results.Add(new FileComparisonResult( list[j], list[i], FileComparisonResultType.Same_Contents)); break; } } } } } return(results); }
static void TestMethod_TestFileOpFileSetWritetime() { var dir = TestUtil.GetTestSubDirectory("right_fndmved", true); var now = DateTime.UtcNow; var future = now.AddMinutes(25); var past = now.AddMinutes(-25); // re-use existing logic for fuzzy time comparison, // in case, say, we're running this test on a FAT drive with imprecise times. var settingsForTimeComparison = new SortFilesSettings(); settingsForTimeComparison.AllowFiletimesDifferForDST = false; settingsForTimeComparison.AllowFiletimesDifferForFAT = true; // set write-time to be the future, and undo. var path = dir + Utils.Sep + "testIntoFuture.txt"; File.WriteAllText(path, "testIntoFuture"); File.SetLastWriteTimeUtc(path, now); var op = new FileOpFileSetWritetime(path, now, future); op.Do(); TestUtil.IsTrue(SortFilesSearchDifferences.AreTimesEqual(future, File.GetLastWriteTimeUtc(path), settingsForTimeComparison)); op.Undo(); TestUtil.IsTrue(SortFilesSearchDifferences.AreTimesEqual(now, File.GetLastWriteTimeUtc(path), settingsForTimeComparison)); path = dir + Utils.Sep + "testIntoPast.txt"; File.WriteAllText(path, "testIntoPast"); File.SetLastWriteTimeUtc(path, now); op = new FileOpFileSetWritetime(path, now, past); op.Do(); TestUtil.IsTrue(SortFilesSearchDifferences.AreTimesEqual(past, File.GetLastWriteTimeUtc(path), settingsForTimeComparison)); op.Undo(); TestUtil.IsTrue(SortFilesSearchDifferences.AreTimesEqual(now, File.GetLastWriteTimeUtc(path), settingsForTimeComparison)); }
static void TestMethod_TestSearchMovedFiles() { var settings = new SortFilesSettings(); var left = TestUtil.GetTestSubDirectory("left_fndmved", true); var right = TestUtil.GetTestSubDirectory("right_fndmved", true); settings.LeftDirectory = left; settings.RightDirectory = right; // first, set up test files File.WriteAllText(left + Utils.Sep + "onlyleft.txt", "onlyL"); File.WriteAllText(left + Utils.Sep + "renamed1.txt", "renamed1"); File.WriteAllText(left + Utils.Sep + "renamed2.txt", "renamed2"); File.WriteAllText(left + Utils.Sep + "empty1.txt", ""); File.WriteAllText(left + Utils.Sep + "changed1.txt", "123"); File.WriteAllText(left + Utils.Sep + "same.txt", "s"); File.WriteAllText(right + Utils.Sep + "onlyright.txt", "onlyR"); File.WriteAllText(right + Utils.Sep + "renamed1.a", "renamed1"); File.WriteAllText(right + Utils.Sep + "renamed2.a", "renamed2"); File.WriteAllText(right + Utils.Sep + "empty1.a", ""); File.WriteAllText(right + Utils.Sep + "changed1.txt", "124"); File.WriteAllText(right + Utils.Sep + "same.txt", "s"); // set last-write-times var dtNow = DateTime.Now; foreach (var filename in Directory.EnumerateFiles(left).Concat( Directory.EnumerateFiles(right))) { File.SetLastWriteTimeUtc(filename, dtNow); } File.SetLastWriteTimeUtc(right + Utils.Sep + "changed1.txt", dtNow.AddDays(1)); // run search-for-differences var results = SortFilesSearchDifferences.Go(settings); var expectedDifferences = @"|empty1.a|Right |onlyright.txt|Right |renamed1.a|Right |renamed2.a|Right changed1.txt|changed1.txt|Changed empty1.txt||Left onlyleft.txt||Left renamed1.txt||Left renamed2.txt||Left"; CompareResultsToString(results, expectedDifferences); // run search for moved files var query = from item in results where item.Type == FileComparisonResultType.Left_Only select item; var resultsMoved = SortFilesSearchDuplicates.SearchMovedFiles( settings.LeftDirectory, settings.RightDirectory, query); TestUtil.IsEq(2, resultsMoved.Count); // the 0-length empty.txt isn't included in this list, we don't treat it as a duplicate TestUtil.IsEq(Utils.Sep + "renamed1.txt", resultsMoved[0].Item1.FileInfoLeft.Filename); TestUtil.IsEq(Utils.Sep + "renamed1.a", resultsMoved[0].Item2); TestUtil.IsEq(Utils.Sep + "renamed2.txt", resultsMoved[1].Item1.FileInfoLeft.Filename); TestUtil.IsEq(Utils.Sep + "renamed2.a", resultsMoved[1].Item2); }
static void TestMethod_TestSortFilesListOperations() { // create settings object var settings = new SortFilesSettings(); var left = TestUtil.GetTestSubDirectory("left_sortfileslist"); var right = TestUtil.GetTestSubDirectory("right_sortfileslist"); settings.LeftDirectory = left; settings.RightDirectory = right; // first, set up test files File.WriteAllText(left + Utils.Sep + "onlyleft.txt", "onlyl"); File.WriteAllText(left + Utils.Sep + "changed1.txt", "a"); File.WriteAllText(left + Utils.Sep + "changed2.txt", "123"); File.WriteAllText(left + Utils.Sep + "same.txt", "s"); File.WriteAllText(right + Utils.Sep + "onlyright.txt", "onlyr"); File.WriteAllText(right + Utils.Sep + "changed1.txt", "abc"); File.WriteAllText(right + Utils.Sep + "changed2.txt", "124"); File.WriteAllText(right + Utils.Sep + "same.txt", "s"); Action checkFileContents = () => { TestUtil.IsEq("onlyl", File.ReadAllText(Path.Combine(left, "onlyleft.txt"))); TestUtil.IsEq("a", File.ReadAllText(Path.Combine(left, "changed1.txt"))); TestUtil.IsEq("123", File.ReadAllText(Path.Combine(left, "changed2.txt"))); TestUtil.IsEq("onlyr", File.ReadAllText(Path.Combine(right, "onlyright.txt"))); TestUtil.IsEq("abc", File.ReadAllText(Path.Combine(right, "changed1.txt"))); TestUtil.IsEq("124", File.ReadAllText(Path.Combine(right, "changed2.txt"))); }; // tweak last write times to ensure files on right look different File.SetLastWriteTime(right + Utils.Sep + "changed1.txt", File.GetLastWriteTime(right + Utils.Sep + "changed1.txt").AddDays(1)); File.SetLastWriteTime(right + Utils.Sep + "changed2.txt", File.GetLastWriteTime(right + Utils.Sep + "changed2.txt").AddDays(1)); File.SetLastWriteTime(right + Utils.Sep + "same.txt", File.GetLastWriteTime(left + Utils.Sep + "same.txt")); // create form and run searchdifferences var form = new FormSortFilesList( SortFilesAction.SearchDifferences, settings, "", allActionsSynchronous: true); ListView listView; form.GetTestHooks(out listView, out List <FileComparisonResult> mockSelection, out UndoStack <List <IUndoableFileOp> > undoStack); form.RunSortFilesAction(); // simulate column-header click to sort by path form.listView_ColumnClick(null, new ColumnClickEventArgs(2)); // verify listview contents var items = listView.Items.Cast <FileComparisonResult>().ToArray(); TestUtil.IsEq(4, items.Length); TestUtil.IsEq(Utils.Sep + "changed1.txt", items[0].FileInfoLeft.Filename); TestUtil.IsEq(null, items[0].FileInfoLeft.ContentHash); TestUtil.IsEq(1L, items[0].FileInfoLeft.FileSize); TestUtil.IsEq(Utils.Sep + "changed1.txt", items[0].FileInfoRight.Filename); TestUtil.IsEq(null, items[0].FileInfoRight.ContentHash); TestUtil.IsEq(3L, items[0].FileInfoRight.FileSize); TestUtil.IsEq(Utils.Sep + "changed2.txt", items[1].FileInfoLeft.Filename); TestUtil.IsEq(null, items[1].FileInfoLeft.ContentHash); TestUtil.IsEq(3L, items[1].FileInfoLeft.FileSize); TestUtil.IsEq(Utils.Sep + "changed2.txt", items[1].FileInfoRight.Filename); TestUtil.IsEq(null, items[1].FileInfoRight.ContentHash); TestUtil.IsEq(3L, items[1].FileInfoRight.FileSize); TestUtil.IsEq(Utils.Sep + "onlyleft.txt", items[2].FileInfoLeft.Filename); TestUtil.IsEq(null, items[2].FileInfoLeft.ContentHash); TestUtil.IsEq(5L, items[2].FileInfoLeft.FileSize); TestUtil.IsEq(null, items[2].FileInfoRight); TestUtil.IsEq(Utils.Sep + "onlyright.txt", items[3].FileInfoRight.Filename); TestUtil.IsEq(null, items[3].FileInfoRight.ContentHash); TestUtil.IsEq(5L, items[3].FileInfoRight.FileSize); TestUtil.IsEq(null, items[3].FileInfoLeft); // test CheckSelectedItemsSameType mockSelection.Clear(); TestUtil.IsEq(false, form.CheckSelectedItemsSameType()); mockSelection.Add((FileComparisonResult)listView.Items[0]); TestUtil.IsEq(true, form.CheckSelectedItemsSameType()); mockSelection.Add((FileComparisonResult)listView.Items[1]); TestUtil.IsEq(true, form.CheckSelectedItemsSameType()); mockSelection.Add((FileComparisonResult)listView.Items[2]); TestUtil.IsEq(false, form.CheckSelectedItemsSameType()); mockSelection.Clear(); TestUtil.IsEq(false, form.CheckSelectedItemsSameType()); mockSelection.Add((FileComparisonResult)listView.Items[1]); TestUtil.IsEq(true, form.CheckSelectedItemsSameType()); mockSelection.Add((FileComparisonResult)listView.Items[2]); TestUtil.IsEq(false, form.CheckSelectedItemsSameType()); // delete all on left checkFileContents(); SelectFirstItems(mockSelection, listView, items.Length); form.OnClickDeleteFile(left: true, needConfirm: false); // see if undo was set as expected var lastUndo = undoStack.PeekUndo(); TestUtil.IsEq(3, lastUndo.Count); TestUtil.IsEq(Path.Combine(left, "changed1.txt"), lastUndo[0].Source); TestUtil.IsEq(Path.Combine(left, "changed2.txt"), lastUndo[1].Source); TestUtil.IsEq(Path.Combine(left, "onlyleft.txt"), lastUndo[2].Source); // test file presence TestUtil.IsTrue(!File.Exists(Path.Combine(left, "changed1.txt"))); TestUtil.IsTrue(!File.Exists(Path.Combine(left, "changed2.txt"))); TestUtil.IsTrue(!File.Exists(Path.Combine(left, "onlyleft.txt"))); TestUtil.IsTrue(File.Exists(Path.Combine(right, "changed1.txt"))); TestUtil.IsTrue(File.Exists(Path.Combine(right, "changed2.txt"))); TestUtil.IsTrue(File.Exists(Path.Combine(right, "onlyright.txt"))); // run undo form.OnUndoClick(needConfirm: false); TestUtil.IsEq(null, undoStack.PeekUndo()); checkFileContents(); // delete all on right SelectFirstItems(mockSelection, listView, items.Length); form.OnClickDeleteFile(left: false, needConfirm: false); // see if undo was set as expected lastUndo = undoStack.PeekUndo(); TestUtil.IsEq(3, lastUndo.Count); TestUtil.IsEq(Path.Combine(right, "changed1.txt"), lastUndo[0].Source); TestUtil.IsEq(Path.Combine(right, "changed2.txt"), lastUndo[1].Source); TestUtil.IsEq(Path.Combine(right, "onlyright.txt"), lastUndo[2].Source); // test file presence TestUtil.IsTrue(File.Exists(Path.Combine(left, "changed1.txt"))); TestUtil.IsTrue(File.Exists(Path.Combine(left, "changed2.txt"))); TestUtil.IsTrue(File.Exists(Path.Combine(left, "onlyleft.txt"))); TestUtil.IsTrue(!File.Exists(Path.Combine(right, "changed1.txt"))); TestUtil.IsTrue(!File.Exists(Path.Combine(right, "changed2.txt"))); TestUtil.IsTrue(!File.Exists(Path.Combine(right, "onlyright.txt"))); // run undo form.OnUndoClick(needConfirm: false); TestUtil.IsEq(null, undoStack.PeekUndo()); checkFileContents(); // copy all left to right SelectFirstItems(mockSelection, listView, items.Length); form.OnClickCopyFile(left: true, needConfirm: false); // see if undo was set as expected lastUndo = undoStack.PeekUndo(); TestUtil.IsEq(5, lastUndo.Count); TestUtil.IsTrue(lastUndo[0] is FileOpFileMove); TestUtil.IsEq(Path.Combine(right, "changed1.txt"), lastUndo[0].Source); TestUtil.IsTrue(lastUndo[1] is FileOpFileCopy); TestUtil.IsEq(Path.Combine(left, "changed1.txt"), lastUndo[1].Source); TestUtil.IsEq(Path.Combine(right, "changed1.txt"), lastUndo[1].Dest); TestUtil.IsTrue(lastUndo[2] is FileOpFileMove); TestUtil.IsEq(Path.Combine(right, "changed2.txt"), lastUndo[2].Source); TestUtil.IsTrue(lastUndo[3] is FileOpFileCopy); TestUtil.IsEq(Path.Combine(left, "changed2.txt"), lastUndo[3].Source); TestUtil.IsEq(Path.Combine(right, "changed2.txt"), lastUndo[3].Dest); TestUtil.IsTrue(lastUndo[4] is FileOpFileCopy); TestUtil.IsEq(Path.Combine(left, "onlyleft.txt"), lastUndo[4].Source); TestUtil.IsEq(Path.Combine(right, "onlyleft.txt"), lastUndo[4].Dest); // test file contents TestUtil.IsEq("onlyl", File.ReadAllText(Path.Combine(left, "onlyleft.txt"))); TestUtil.IsEq("a", File.ReadAllText(Path.Combine(left, "changed1.txt"))); TestUtil.IsEq("123", File.ReadAllText(Path.Combine(left, "changed2.txt"))); TestUtil.IsEq("onlyl", File.ReadAllText(Path.Combine(right, "onlyleft.txt"))); TestUtil.IsEq("onlyr", File.ReadAllText(Path.Combine(right, "onlyright.txt"))); TestUtil.IsEq("a", File.ReadAllText(Path.Combine(right, "changed1.txt"))); TestUtil.IsEq("123", File.ReadAllText(Path.Combine(right, "changed2.txt"))); // run undo form.OnUndoClick(needConfirm: false); TestUtil.IsEq(null, undoStack.PeekUndo()); TestUtil.IsTrue(!File.Exists(Path.Combine(right, "onlyleft.txt"))); checkFileContents(); // copy all right to left SelectFirstItems(mockSelection, listView, items.Length); form.OnClickCopyFile(left: false, needConfirm: false); // see if undo was set as expected lastUndo = undoStack.PeekUndo(); TestUtil.IsEq(5, lastUndo.Count); TestUtil.IsTrue(lastUndo[0] is FileOpFileMove); TestUtil.IsEq(Path.Combine(left, "changed1.txt"), lastUndo[0].Source); TestUtil.IsTrue(lastUndo[1] is FileOpFileCopy); TestUtil.IsEq(Path.Combine(right, "changed1.txt"), lastUndo[1].Source); TestUtil.IsEq(Path.Combine(left, "changed1.txt"), lastUndo[1].Dest); TestUtil.IsTrue(lastUndo[2] is FileOpFileMove); TestUtil.IsEq(Path.Combine(left, "changed2.txt"), lastUndo[2].Source); TestUtil.IsTrue(lastUndo[3] is FileOpFileCopy); TestUtil.IsEq(Path.Combine(right, "changed2.txt"), lastUndo[3].Source); TestUtil.IsEq(Path.Combine(left, "changed2.txt"), lastUndo[3].Dest); TestUtil.IsTrue(lastUndo[4] is FileOpFileCopy); TestUtil.IsEq(Path.Combine(right, "onlyright.txt"), lastUndo[4].Source); TestUtil.IsEq(Path.Combine(left, "onlyright.txt"), lastUndo[4].Dest); // test file contents TestUtil.IsEq("onlyl", File.ReadAllText(Path.Combine(left, "onlyleft.txt"))); TestUtil.IsEq("onlyr", File.ReadAllText(Path.Combine(left, "onlyright.txt"))); TestUtil.IsEq("abc", File.ReadAllText(Path.Combine(left, "changed1.txt"))); TestUtil.IsEq("124", File.ReadAllText(Path.Combine(left, "changed2.txt"))); TestUtil.IsEq("onlyr", File.ReadAllText(Path.Combine(right, "onlyright.txt"))); TestUtil.IsEq("abc", File.ReadAllText(Path.Combine(right, "changed1.txt"))); TestUtil.IsEq("124", File.ReadAllText(Path.Combine(right, "changed2.txt"))); // run undo form.OnUndoClick(needConfirm: false); TestUtil.IsEq(null, undoStack.PeekUndo()); TestUtil.IsTrue(!File.Exists(Path.Combine(left, "onlyright.txt"))); checkFileContents(); form.Dispose(); }
static void TestMethod_TestSortFilesOperations() { // run the methods on actual files. first create combinations of modified/not modified. var settings = new SortFilesSettings(); settings.LeftDirectory = TestUtil.GetTestSubDirectory("left_fndmved", true); settings.RightDirectory = TestUtil.GetTestSubDirectory("right_fndmved", true); var filesCreated = CreateFileCombinations.Go( settings.LeftDirectory, settings.RightDirectory); TestUtil.IsEq( CreateFileCombinations.CountPossibleModifiedTimes() * CreateFileCombinations.CountPossibleContents() * CreateFileCombinations.CountPossibleFilenames() * ((1 * 2) + (3 * 2)), // ExtraCopies.None -> 2 files, the rest -> 3 files filesCreated); // search for duplicates in one dir, only ones it will find are 'extra copy on left.' var results = SortFilesSearchDuplicatesInOneDir.Go(settings); TestUtil.IsEq( CreateFileCombinations.CountPossibleModifiedTimes() * CreateFileCombinations.CountPossibleContents() * CreateFileCombinations.CountPossibleFilenames(), results.Count); // verify sort order. for each pair, the left side should sort first alphabetically var expectedDuplicates = @"MTimeAddTextMNameOneOnLeft.a|MTimeAddTextMNameOneOnLeft.a_1|Same_Contents MTimeAddTextSmNameOneOnLeft.a|MTimeAddTextSmNameOneOnLeft.a_1|Same_Contents MTimeAltTextMNameOneOnLeft.a|MTimeAltTextMNameOneOnLeft.a_1|Same_Contents MTimeAltTextSmNameOneOnLeft.a|MTimeAltTextSmNameOneOnLeft.a_1|Same_Contents MTimeSmTextMNameOneOnLeft.a|MTimeSmTextMNameOneOnLeft.a_1|Same_Contents MTimeSmTextSmNameOneOnLeft.a|MTimeSmTextSmNameOneOnLeft.a_1|Same_Contents SmTimeAddTextMNameOneOnLeft.a|SmTimeAddTextMNameOneOnLeft.a_1|Same_Contents SmTimeAddTextSmNameOneOnLeft.a|SmTimeAddTextSmNameOneOnLeft.a_1|Same_Contents SmTimeAltTextMNameOneOnLeft.a|SmTimeAltTextMNameOneOnLeft.a_1|Same_Contents SmTimeAltTextSmNameOneOnLeft.a|SmTimeAltTextSmNameOneOnLeft.a_1|Same_Contents SmTimeSmTextMNameOneOnLeft.a|SmTimeSmTextMNameOneOnLeft.a_1|Same_Contents SmTimeSmTextSmNameOneOnLeft.a|SmTimeSmTextSmNameOneOnLeft.a_1|Same_Contents"; CompareResultsToString(results, expectedDuplicates); // search for duplicates across directories // should find all files on the right marked 'SmText'. results = SortFilesSearchDuplicates.Go(settings); var countExpectedDuplicates = (from filename in Directory.EnumerateFiles(settings.RightDirectory) where filename.Contains("SmText") select filename).Count(); TestUtil.IsEq(countExpectedDuplicates, results.Count); // verify sort order expectedDuplicates = @"MTimeSmTextMNameNone.a|MTimeSmTextMNameNone.z|Same_Contents MTimeSmTextMNameOneOnLeft.a|MTimeSmTextMNameOneOnLeft.z|Same_Contents MTimeSmTextMNameOneOnRight.a|MTimeSmTextMNameOneOnRight.z|Same_Contents MTimeSmTextMNameOneOnRight.a|MTimeSmTextMNameOneOnRight.z_1|Same_Contents MTimeSmTextSmNameNone.a|MTimeSmTextSmNameNone.a|Same_Contents MTimeSmTextSmNameOneOnLeft.a|MTimeSmTextSmNameOneOnLeft.a|Same_Contents MTimeSmTextSmNameOneOnRight.a|MTimeSmTextSmNameOneOnRight.a|Same_Contents MTimeSmTextSmNameOneOnRight.a|MTimeSmTextSmNameOneOnRight.a_1|Same_Contents SmTimeSmTextMNameNone.a|SmTimeSmTextMNameNone.z|Same_Contents SmTimeSmTextMNameOneOnLeft.a|SmTimeSmTextMNameOneOnLeft.z|Same_Contents SmTimeSmTextMNameOneOnRight.a|SmTimeSmTextMNameOneOnRight.z|Same_Contents SmTimeSmTextMNameOneOnRight.a|SmTimeSmTextMNameOneOnRight.z_1|Same_Contents SmTimeSmTextSmNameNone.a|SmTimeSmTextSmNameNone.a|Same_Contents SmTimeSmTextSmNameOneOnLeft.a|SmTimeSmTextSmNameOneOnLeft.a|Same_Contents SmTimeSmTextSmNameOneOnRight.a|SmTimeSmTextSmNameOneOnRight.a|Same_Contents SmTimeSmTextSmNameOneOnRight.a|SmTimeSmTextSmNameOneOnRight.a_1|Same_Contents"; CompareResultsToString(results, expectedDuplicates); // search for duplicates across directories, but uses lmt as a shortcut (less thorough) // it will now think that the SmTimeAltText ones are equal because, // when it sees the lmt are the same, it treats them as the same and doesn't check hash settings.SearchDuplicatesCanUseFiletimes = true; results = SortFilesSearchDuplicates.Go(settings); settings.SearchDuplicatesCanUseFiletimes = false; expectedDuplicates = @"MTimeSmTextMNameNone.a|MTimeSmTextMNameNone.z|Same_Contents MTimeSmTextMNameOneOnLeft.a|MTimeSmTextMNameOneOnLeft.z|Same_Contents MTimeSmTextMNameOneOnRight.a|MTimeSmTextMNameOneOnRight.z|Same_Contents MTimeSmTextMNameOneOnRight.a|MTimeSmTextMNameOneOnRight.z_1|Same_Contents MTimeSmTextSmNameNone.a|MTimeSmTextSmNameNone.a|Same_Contents MTimeSmTextSmNameOneOnLeft.a|MTimeSmTextSmNameOneOnLeft.a|Same_Contents MTimeSmTextSmNameOneOnRight.a|MTimeSmTextSmNameOneOnRight.a|Same_Contents MTimeSmTextSmNameOneOnRight.a|MTimeSmTextSmNameOneOnRight.a_1|Same_Contents SmTimeAltTextSmNameNone.a|SmTimeAltTextSmNameNone.a|Same_Contents SmTimeAltTextSmNameOneOnLeft.a|SmTimeAltTextSmNameOneOnLeft.a|Same_Contents SmTimeAltTextSmNameOneOnRight.a|SmTimeAltTextSmNameOneOnRight.a|Same_Contents SmTimeSmTextMNameNone.a|SmTimeSmTextMNameNone.z|Same_Contents SmTimeSmTextMNameOneOnLeft.a|SmTimeSmTextMNameOneOnLeft.z|Same_Contents SmTimeSmTextMNameOneOnRight.a|SmTimeSmTextMNameOneOnRight.z|Same_Contents SmTimeSmTextMNameOneOnRight.a|SmTimeSmTextMNameOneOnRight.z_1|Same_Contents SmTimeSmTextSmNameNone.a|SmTimeSmTextSmNameNone.a|Same_Contents SmTimeSmTextSmNameOneOnLeft.a|SmTimeSmTextSmNameOneOnLeft.a|Same_Contents SmTimeSmTextSmNameOneOnRight.a|SmTimeSmTextSmNameOneOnRight.a|Same_Contents SmTimeSmTextSmNameOneOnRight.a|SmTimeSmTextSmNameOneOnRight.a_1|Same_Contents"; CompareResultsToString(results, expectedDuplicates); // search for differences in similar directories. results = SortFilesSearchDifferences.Go(settings); var expectedDifferences = @"|MTimeAddTextMNameNone.z|Right |MTimeAddTextMNameOneOnLeft.z|Right |MTimeAddTextMNameOneOnRight.z|Right |MTimeAddTextMNameOneOnRight.z_1|Right |MTimeAddTextSmNameOneOnRight.a_1|Right |MTimeAltTextMNameNone.z|Right |MTimeAltTextMNameOneOnLeft.z|Right |MTimeAltTextMNameOneOnRight.z|Right |MTimeAltTextMNameOneOnRight.z_1|Right |MTimeAltTextSmNameOneOnRight.a_1|Right |MTimeSmTextMNameNone.z|Right |MTimeSmTextMNameOneOnLeft.z|Right |MTimeSmTextMNameOneOnRight.z|Right |MTimeSmTextMNameOneOnRight.z_1|Right |MTimeSmTextSmNameOneOnRight.a_1|Right |SmTimeAddTextMNameNone.z|Right |SmTimeAddTextMNameOneOnLeft.z|Right |SmTimeAddTextMNameOneOnRight.z|Right |SmTimeAddTextMNameOneOnRight.z_1|Right |SmTimeAddTextSmNameOneOnRight.a_1|Right |SmTimeAltTextMNameNone.z|Right |SmTimeAltTextMNameOneOnLeft.z|Right |SmTimeAltTextMNameOneOnRight.z|Right |SmTimeAltTextMNameOneOnRight.z_1|Right |SmTimeAltTextSmNameOneOnRight.a_1|Right |SmTimeSmTextMNameNone.z|Right |SmTimeSmTextMNameOneOnLeft.z|Right |SmTimeSmTextMNameOneOnRight.z|Right |SmTimeSmTextMNameOneOnRight.z_1|Right |SmTimeSmTextSmNameOneOnRight.a_1|Right MTimeAddTextMNameNone.a||Left MTimeAddTextMNameOneOnLeft.a||Left MTimeAddTextMNameOneOnLeft.a_1||Left MTimeAddTextMNameOneOnRight.a||Left MTimeAddTextSmNameNone.a|MTimeAddTextSmNameNone.a|Changed MTimeAddTextSmNameOneOnLeft.a|MTimeAddTextSmNameOneOnLeft.a|Changed MTimeAddTextSmNameOneOnLeft.a_1||Left MTimeAddTextSmNameOneOnRight.a|MTimeAddTextSmNameOneOnRight.a|Changed MTimeAltTextMNameNone.a||Left MTimeAltTextMNameOneOnLeft.a||Left MTimeAltTextMNameOneOnLeft.a_1||Left MTimeAltTextMNameOneOnRight.a||Left MTimeAltTextSmNameNone.a|MTimeAltTextSmNameNone.a|Changed MTimeAltTextSmNameOneOnLeft.a|MTimeAltTextSmNameOneOnLeft.a|Changed MTimeAltTextSmNameOneOnLeft.a_1||Left MTimeAltTextSmNameOneOnRight.a|MTimeAltTextSmNameOneOnRight.a|Changed MTimeSmTextMNameNone.a||Left MTimeSmTextMNameOneOnLeft.a||Left MTimeSmTextMNameOneOnLeft.a_1||Left MTimeSmTextMNameOneOnRight.a||Left MTimeSmTextSmNameNone.a|MTimeSmTextSmNameNone.a|Changed MTimeSmTextSmNameOneOnLeft.a|MTimeSmTextSmNameOneOnLeft.a|Changed MTimeSmTextSmNameOneOnLeft.a_1||Left MTimeSmTextSmNameOneOnRight.a|MTimeSmTextSmNameOneOnRight.a|Changed SmTimeAddTextMNameNone.a||Left SmTimeAddTextMNameOneOnLeft.a||Left SmTimeAddTextMNameOneOnLeft.a_1||Left SmTimeAddTextMNameOneOnRight.a||Left SmTimeAddTextSmNameNone.a|SmTimeAddTextSmNameNone.a|Changed SmTimeAddTextSmNameOneOnLeft.a|SmTimeAddTextSmNameOneOnLeft.a|Changed SmTimeAddTextSmNameOneOnLeft.a_1||Left SmTimeAddTextSmNameOneOnRight.a|SmTimeAddTextSmNameOneOnRight.a|Changed SmTimeAltTextMNameNone.a||Left SmTimeAltTextMNameOneOnLeft.a||Left SmTimeAltTextMNameOneOnLeft.a_1||Left SmTimeAltTextMNameOneOnRight.a||Left SmTimeAltTextSmNameOneOnLeft.a_1||Left SmTimeSmTextMNameNone.a||Left SmTimeSmTextMNameOneOnLeft.a||Left SmTimeSmTextMNameOneOnLeft.a_1||Left SmTimeSmTextMNameOneOnRight.a||Left SmTimeSmTextSmNameOneOnLeft.a_1||Left"; CompareResultsToString(results, expectedDifferences); // account for all 96 files. // (SortFilesSearchDifferences doesn't check hashes, so although it knows // AddText are different because filesize changes, // it won't detect AltText unless filesize or lmt are also different.) var expectedSame = @"SmTimeAltTextSmNameNone.a|SmTimeAltTextSmNameNone.a SmTimeAltTextSmNameOneOnLeft.a|SmTimeAltTextSmNameOneOnLeft.a SmTimeAltTextSmNameOneOnRight.a|SmTimeAltTextSmNameOneOnRight.a SmTimeSmTextSmNameNone.a|SmTimeSmTextSmNameNone.a SmTimeSmTextSmNameOneOnLeft.a|SmTimeSmTextSmNameOneOnLeft.a SmTimeSmTextSmNameOneOnRight.a|SmTimeSmTextSmNameOneOnRight.a"; TestUtil.IsEq(filesCreated, CountFilenames(expectedDifferences) + CountFilenames(expectedSame)); // search for identical files with different write times // will find all with MTimeSmText var found = SortFilesSearchDuplicates.SearchForIdenticalFilesWithDifferentWriteTimes( settings.LeftDirectory, settings.RightDirectory, results); var expectedIdenticalContents = @"MTimeSmTextSmNameNone.a|MTimeSmTextSmNameNone.a|Changed MTimeSmTextSmNameOneOnLeft.a|MTimeSmTextSmNameOneOnLeft.a|Changed MTimeSmTextSmNameOneOnRight.a|MTimeSmTextSmNameOneOnRight.a|Changed"; CompareResultsToString(found, expectedIdenticalContents); }
static void TestMethod_AreTimesEqual() { var time = DateTime.Now; var timePlus3s = time.AddSeconds(3); var timePlus1hr = time.AddHours(1); // strict compare var settings = new SortFilesSettings(); settings.AllowFiletimesDifferForDST = false; settings.AllowFiletimesDifferForFAT = false; TestUtil.IsEq(true, SortFilesSearchDifferences.AreTimesEqual(time, time, settings)); TestUtil.IsEq(false, SortFilesSearchDifferences.AreTimesEqual(time, timePlus3s, settings)); TestUtil.IsEq(false, SortFilesSearchDifferences.AreTimesEqual(timePlus3s, time, settings)); TestUtil.IsEq(false, SortFilesSearchDifferences.AreTimesEqual(time, timePlus1hr, settings)); TestUtil.IsEq(false, SortFilesSearchDifferences.AreTimesEqual(timePlus1hr, time, settings)); // allow DST settings.AllowFiletimesDifferForDST = true; TestUtil.IsEq(true, SortFilesSearchDifferences.AreTimesEqual(time, time, settings)); TestUtil.IsEq(false, SortFilesSearchDifferences.AreTimesEqual(time, timePlus3s, settings)); TestUtil.IsEq(false, SortFilesSearchDifferences.AreTimesEqual(timePlus3s, time, settings)); TestUtil.IsEq(true, SortFilesSearchDifferences.AreTimesEqual(time, timePlus1hr, settings)); TestUtil.IsEq(true, SortFilesSearchDifferences.AreTimesEqual(timePlus1hr, time, settings)); // allow close settings.AllowFiletimesDifferForFAT = true; TestUtil.IsEq(true, SortFilesSearchDifferences.AreTimesEqual(time, time, settings)); TestUtil.IsEq(true, SortFilesSearchDifferences.AreTimesEqual(time, timePlus3s, settings)); TestUtil.IsEq(true, SortFilesSearchDifferences.AreTimesEqual(timePlus3s, time, settings)); TestUtil.IsEq(true, SortFilesSearchDifferences.AreTimesEqual(time, timePlus1hr, settings)); TestUtil.IsEq(true, SortFilesSearchDifferences.AreTimesEqual(timePlus1hr, time, settings)); // disallow DST settings.AllowFiletimesDifferForDST = false; TestUtil.IsEq(true, SortFilesSearchDifferences.AreTimesEqual(time, time, settings)); TestUtil.IsEq(true, SortFilesSearchDifferences.AreTimesEqual(time, timePlus3s, settings)); TestUtil.IsEq(true, SortFilesSearchDifferences.AreTimesEqual(timePlus3s, time, settings)); TestUtil.IsEq(false, SortFilesSearchDifferences.AreTimesEqual(time, timePlus1hr, settings)); TestUtil.IsEq(false, SortFilesSearchDifferences.AreTimesEqual(timePlus1hr, time, settings)); }
public static string GetFullArgs(SortFilesSettings settings) { var args = Utils.CombineProcessArguments(GetArgs(settings)); return("robocopy.exe " + args); }