public void SyncCommand_PurgedFile()
        {
            Decr1.UpdateTo("file1.txt < aa");
            SyncDecr1andEncr1();

            {
                var syncLog = Decr1AndEncr1SyncLog();
                Assert.IsTrue(syncLog.Length == 1);
                Assert.IsTrue(syncLog[0].DecrFileName == "file1.txt");
                Assert.IsTrue(syncLog[0].EntryType == FileEntryType.File);
            }

            Decr1.UpdateTo("");
            SyncDecr1andEncr1();

            {
                var syncLog = Decr1AndEncr1SyncLog();
                Assert.IsTrue(syncLog.Length == 1);
                Assert.IsTrue(syncLog[0].DecrFileName == "file1.txt");
                Assert.IsTrue(syncLog[0].EntryType == FileEntryType.Removed);
            }

            //removes the encr file should trigger a purge
            Encr1.Clear(new Regex("helix.hx"));

            SyncDecr1andEncr1();

            {
                var syncLog = Decr1AndEncr1SyncLog();
                Assert.IsTrue(syncLog.Length == 0);
            }
        }
        public void SyncCommand_MultipleSyncUnchanged()
        {
            Decr1.UpdateTo("file1.txt < aa");
            var sync1     = SyncDecr1andEncr1();
            var logLength = Decr1AndEncr1SyncLog().Length;

            Assert.AreEqual(1, sync1.Changes.Count);
            var sync2 = SyncDecr1andEncr1();

            Assert.AreEqual(0, sync2.Changes.Count);
            Assert.AreEqual(logLength, Decr1AndEncr1SyncLog().Length);
        }
        protected virtual void Dispose(bool disposing)
        {
            if (!IsDisposed)
            {
                if (disposing)
                {
                    Decr1.Dispose();
                    Decr2.Dispose();
                    Encr1.Dispose();
                    Encr2.Dispose();
                }

                IsDisposed = true;
            }
        }
        public void FindChanges_AddsInOrderParentToChildren()
        {
            Decr1.UpdateTo("file1.txt < aa", "zz/file2.txt");

            using (var pair = DirectoryPair.Open(Decr1.DirectoryPath, Encr1.DirectoryPath, DerivedBytesProvider.FromPassword("password"), true, HelixFileVersion.UnitTest))
            {
                for (int i = 0; i < 100; i++)
                {
                    var changes     = pair.FindChanges();
                    var parentIndex = changes.FindIndex(c => c.DecrFileName == "zz");
                    var childIndex  = changes.FindIndex(c => HelixUtil.PathNative(c.DecrFileName) == HelixUtil.PathNative("zz/file2.txt"));
                    Assert.IsTrue(parentIndex < childIndex, "Parent Directory Add did not come before Child File Add");
                }
            }
        }
        public void SyncCommand_DeleteThenReAdd()
        {
            Decr1.UpdateTo("file1.txt < aa");
            SyncDecr1andEncr1();
            SyncDecr2andEncr1();

            Decr1.UpdateTo("");
            SyncDecr1andEncr1();
            SyncDecr2andEncr1();
            DirectoryAreEqual(Decr2, "", "deleted file propigated");

            Decr1.UpdateTo("file1.txt < abc");
            SyncDecr1andEncr1();
            SyncDecr2andEncr1();

            Decr2.AssertEqual("file1.txt < abc");
        }
        public void FindChanges_ReturtsInRandomOrder()
        {
            Decr1.UpdateTo("file1.txt < aa", "file2.txt", "file3.txt");

            HashSet <int> indexes = new HashSet <int>();

            using (var pair = DirectoryPair.Open(Decr1.DirectoryPath, Encr1.DirectoryPath, DerivedBytesProvider.FromPassword("password"), true, HelixFileVersion.UnitTest))
            {
                for (int i = 0; i < 100; i++)
                {
                    var changes = pair.FindChanges();
                    var index   = changes.FindIndex(c => c.DecrFileName == "file1.txt");
                    indexes.Add(index);
                }

                Assert.IsTrue(indexes.Count == 3, "file1.txt not found in all random spots");
            }
        }
        public void SyncCommand_SyncSummary()
        {
            Decr1.UpdateTo(@"001.txt");
            Decr2.UpdateTo(@"002.txt");


            SyncSummary sum;

            (sum, _) = SyncDecr1andEncr1();

            Assert.AreEqual(1, sum.DecrTotal);
            Assert.AreEqual(0, sum.EncrTotal);


            (sum, _) = SyncDecr2andEncr1();
            Assert.AreEqual(1, sum.DecrTotal);
            Assert.AreEqual(1, sum.EncrTotal);
        }
        public void SyncCommand_DeleteFolderOn1andAddFileOn2()
        {
            Decr1.UpdateTo(@"aa\001.txt < 001");
            Decr2.UpdateTo(@"");
            SyncDecr1andEncr1();
            SyncDecr2andEncr1();

            Decr1.UpdateTo(@""); //removes file and directory
            Decr2.UpdateTo(      //add file to directory
                @"aa\001.txt < 001",
                @"aa\002.txt < 002");
            SyncDecr1andEncr1();

            SyncDecr2andEncr1();
            Decr2.AssertEqual(new string[] { @"aa/", @"aa\002.txt < 002" });

            SyncDecr1andEncr1();
            Decr1.AssertEqual(new string[] { @"aa/", @"aa\002.txt < 002" });
        }
        public void SyncCommand_ChangeCaseOnly()
        {
            for (int i = 0; i < 10; i++)
            {
                Decr1.UpdateTo("A < xyz");
                SyncDecr1andEncr1(p => Assert.IsTrue(p.SyncMode == PreSyncMode.DecryptedSide));
                SyncDecr2andEncr1(p => Assert.IsTrue(p.SyncMode == PreSyncMode.EncryptedSide));
                Decr1.AssertEqual(new string[] { "A < xyz" });
                Decr2.AssertEqual(new string[] { "A < xyz" });

                Decr1.UpdateTo("a");
                SyncDecr1andEncr1(p => Assert.IsTrue(p.SyncMode == PreSyncMode.DecryptedSide));
                SyncDecr2andEncr1(p => Assert.IsTrue(p.SyncMode == PreSyncMode.EncryptedSide));
                Decr1.AssertEqual(new string[] { "a" });
                Decr2.AssertEqual(new string[] { "a" });
            }

            //Assert.IsTrue(false, "Sometimes works sometimes fails depending if th delete comes before the add");
        }
        public void SyncCommand_OneWaySync_NoConflict_FuzzTesting(byte[] d1, byte[] d2)
        {
            Decr1.Clear(true);
            Decr2.Clear(true);

            string[] d1str = (d1 ?? (new byte[] { })).Select(d => choices[d % choices.Length]).ToArray();
            string[] d2str = (d2 ?? (new byte[] { })).Select(d => choices[d % choices.Length]).ToArray();

            Decr1.UpdateTo(d1str);
            SyncDecr1andEncr1(p => Assert.IsTrue(p.SyncMode == PreSyncMode.DecryptedSide));
            SyncDecr2andEncr1(p => Assert.IsTrue(p.SyncMode == PreSyncMode.EncryptedSide));
            Decr1.AssertEqual(d1str);
            Decr2.AssertEqual(d1str);

            Decr1.UpdateTo(d2str);
            SyncDecr1andEncr1(p => Assert.IsTrue(p.SyncMode == PreSyncMode.DecryptedSide));
            SyncDecr2andEncr1(p => Assert.IsTrue(p.SyncMode == PreSyncMode.EncryptedSide));
            Decr1.AssertEqual(d2str);
            Decr2.AssertEqual(d2str);
        }
        public void FindChanges_CaseChangeDeletesBeforeAdds()
        {
            Decr1.UpdateTo("file1.txt");

            using (var pair = DirectoryPair.Open(Decr1.DirectoryPath, Encr1.DirectoryPath, DerivedBytesProvider.FromPassword("password"), true, HelixFileVersion.UnitTest))
            {
                pair.SyncChanges();


                Decr1.UpdateTo("FILE1.txt");


                for (int i = 0; i < 100; i++)
                {
                    var changes     = pair.FindChanges();
                    var deleteIndex = changes.FindIndex(c => c.DecrFileName == "file1.txt");
                    var addIndex    = changes.FindIndex(c => c.DecrFileName == "FILE1.txt");

                    Assert.IsTrue(deleteIndex < addIndex, "Case Rename did not order delete before add");
                }
            }
        }
        public void SyncCommand_SimpleSync()
        {
            Decr1.UpdateTo("file1.txt < aa");
            var sync1 = SyncDecr1andEncr1();

            Assert.AreEqual(1, sync1.Changes.Count);

            var sync2 = SyncDecr2andEncr1();

            Assert.AreEqual(1, sync1.Changes.Count);


            Decr2.AssertEqual(new string[] { "file1.txt < aa" });

            Decr1.UpdateTo("file1.txt < aa",
                           "file2.txt < bb");

            SyncDecr1andEncr1();
            SyncDecr2andEncr1();
            Decr2.AssertEqual(new string[] { "file1.txt < aa",
                                             "file2.txt < bb" });;
        }
        public void SyncCommand_TwoWaySync_NoConflict_FuzzTesting(byte[] d1, byte[] d2)
        {
            string[] d1str = (d1 ?? (new byte[] { })).Select(d => choices[d % choices.Length]).ToArray();
            string[] d2str = (d2 ?? (new byte[] { })).Select(d => choices[d % choices.Length]).ToArray();

            Decr1.Subdirectory("d1").UpdateTo(d1str);
            Decr2.Subdirectory("d2").UpdateTo(d2str);

            Decr1.Subdirectory("d1").AssertEqual(d1str);
            Decr2.Subdirectory("d2").AssertEqual(d2str);

            SyncDecr1andEncr1(p => Assert.IsTrue(p.SyncMode == PreSyncMode.DecryptedSide));
            Decr1.Subdirectory("d1").AssertEqual(d1str);
            SyncDecr1andEncr1(p => Assert.Fail("Unexpected change post sync"));

            SyncDecr2andEncr1();
            Decr2.Subdirectory("d1").AssertEqual(d1str);
            Decr2.Subdirectory("d2").AssertEqual(d2str);
            SyncDecr2andEncr1(p => Assert.Fail("Unexpected change post sync"));

            SyncDecr1andEncr1(p => Assert.IsTrue(p.SyncMode == PreSyncMode.EncryptedSide));
            Decr1.Subdirectory("d1").AssertEqual(d1str);
            Decr1.Subdirectory("d2").AssertEqual(d2str);
        }