Example #1
0
        public void Delete()
        {
            // Arrange
            PermutationSetup permutation = new PermutationSetup();

            permutation.Add(blockpool_1TB);
            permutation.Add(blockpool_Pseudo);

            permutation.Add(case_ms);
            //permutation.Add(decor_fs);
            permutation.Add(case_decor_ms);
            permutation.Add(case_vfs_ms);
            permutation.Add(case_vfs_2ms);
            //permutation.Add(vfs_fsms);
            permutation.Add(init);

            // Act & Assert
            foreach (Scenario scenario in permutation.Scenarios)
            {
                using (Run run = scenario.Run().Initialize())
                {
                    IFileSystem fs = run.Parameters["Class"] as IFileSystem;
                    fs.Observe("**", observer = new Observer());
                    observer.events.Clear();

                    try { fs.Delete(""); Assert.Fail(); } catch (IOException) { }
                    try { fs.Delete("."); Assert.Fail(); } catch (IOException) { }
                    try { fs.Delete(".."); Assert.Fail(); } catch (IOException) { }

                    // Delete file
                    fs.Delete("/tmp/../tmp/helloworld.txt");
                    Assert.IsFalse(fs.Exists("/tmp/helloworld.txt"));
                    Assert.IsTrue(DateTimeOffset.UtcNow - fs.GetEntry("/tmp").LastModified < TimeSpan.FromSeconds(2));
                    Assert.IsTrue(observer.Last is IDeleteEvent);
                    Assert.IsTrue(DateTimeOffset.UtcNow - observer.Last.EventTime < TimeSpan.FromSeconds(2));
                    Assert.AreEqual(fs, observer.Last.Observer.FileSystem);
                    Assert.AreEqual("/tmp/helloworld.txt", observer.Last.Path);

                    // Delete dir
                    Assert.IsTrue(fs.Exists("/tmp"));
                    try { fs.Delete("/tmp", false); Assert.Fail(); } catch (IOException) { }

                    // Delete dir tree
                    Assert.IsTrue(fs.Browse("/").Any(e => e.Path == "/tmp/"));
                    Assert.IsTrue(fs.Exists("/tmp"));
                    Assert.IsTrue(fs.Exists("/tmp/"));
                    fs.Delete("/tmp", true);
                    Assert.IsFalse(fs.Browse("/").Any(e => e.Path == "/tmp/"));
                    Assert.IsFalse(fs.Exists("/tmp"));
                    Assert.IsFalse(fs.Exists("/tmp/"));
                    Assert.IsFalse(fs.Exists("/tmp/helloworld_100.txt"));
                    Assert.IsTrue(observer.events.Count >= 4);
                    Assert.IsTrue(observer.Last is IDeleteEvent);
                    Assert.IsTrue(DateTimeOffset.UtcNow - observer.Last.EventTime < TimeSpan.FromSeconds(2));
                    Assert.AreEqual(fs, observer.Last.Observer.FileSystem);
                    fs.Observe("**", observer = new Observer());
                    observer.events.Clear();
                }
            }
        }
Example #2
0
        public void Browse()
        {
            // Arrange
            PermutationSetup permutation = new PermutationSetup();

            permutation.Add(blockpool_1TB);
            permutation.Add(blockpool_Pseudo);

            permutation.Add(case_ms);
            //permutation.Add(decor_fs);
            permutation.Add(case_decor_ms);
            permutation.Add(case_vfs_ms);
            permutation.Add(case_vfs_2ms);
            //permutation.Add(vfs_fsms);
            permutation.Add(init);

            // Act & Assert
            foreach (Scenario scenario in permutation.Scenarios)
            {
                using (Run run = scenario.Run().Initialize())
                {
                    IFileSystem ram = run.Parameters["Class"] as IFileSystem;
                    Assert.IsTrue(ram.Browse("/tmp/").Count >= 3);
                    Assert.IsTrue(ram.Browse("c:").Any(e => e.Path == "c:/dir/"));
                    Assert.IsTrue(ram.Browse("c:/dir").Any(e => e.Path == "c:/dir/dir/"));
                    Assert.IsTrue(ram.Browse("./c:/dir").Any(e => e.Path == "c:/dir/dir/"));
                    Assert.IsTrue(ram.Browse("./c:/../c:/dir").Any(e => e.Path == "c:/dir/dir/"));
                    Assert.IsTrue(ram.Browse("/tmp").Any(e => e.Path == "/tmp/helloworld.txt"));
                    Assert.IsTrue(ram.Browse(".//tmp").Any(e => e.Path == "/tmp/helloworld.txt"));
                    Assert.IsTrue(ram.Browse(".//tmp/.").Any(e => e.Path == "/tmp/helloworld.txt"));
                    Assert.IsTrue(ram.Browse(".//tmp/../tmp").Any(e => e.Path == "/tmp/helloworld.txt"));
                }
            }
        }
Example #3
0
        public void CreateDirectory()
        {
            // Arrange
            PermutationSetup permutation = new PermutationSetup();

            permutation.Add(blockpool_1TB);
            permutation.Add(blockpool_Pseudo);

            permutation.Add(case_ms);
            //permutation.Add(decor_fs);
            permutation.Add(case_decor_ms);
            permutation.Add(case_vfs_ms);
            permutation.Add(case_vfs_2ms);
            //permutation.Add(vfs_fsms);
            permutation.Add(init);

            // Act & Assert
            foreach (Scenario scenario in permutation.Scenarios)
            {
                using (Run run = scenario.Run().Initialize())
                {
                    IFileSystem fs = run.Parameters["Class"] as IFileSystem;
                    fs.Observe("**", observer = new Observer());
                    observer.events.Clear();

                    // root
                    Assert.IsNotNull(fs.GetEntry(""));
                    Assert.IsFalse(fs.Browse("").Any(e => e.Path == "dir1/"));
                    fs.CreateDirectory("dir1/../dir2/../dir3/../dir4");
                    Assert.IsTrue(fs.Browse("").Any(e => e.Path == "dir1/"));
                    Assert.IsTrue(fs.Exists("dir1/"));
                    Assert.IsTrue(fs.Exists("dir2/"));
                    Assert.IsTrue(fs.Exists("dir3"));
                    Assert.IsTrue(fs.Exists("dir4"));

                    try
                    {
                        fs.CreateDirectory("../dir");
                        Assert.Fail();
                    }
                    catch (IOException) { }
                    fs.Observe("**", observer = new Observer());
                    observer.events.Clear();
                }
            }
        }
        /// <summary>
        /// Vists tree structure of filesystem.
        ///
        /// Starts at <paramref name="path"/> if provided, otherwise starts at root "".
        /// <paramref name="depth"/> sets maximum visit depths.
        ///
        /// ""
        /// ├──""
        /// │  ├──"mnt"
        /// │  ├──"tmp"
        /// │  │  └──"helloworld.txt"
        /// │  └──"usr"
        /// │     └──"lex"
        /// └──"c:"
        ///    └──"dir"
        ///       └──"dir"
        ///
        ///
        /// Any thrown exceptions are printed into the line that produced the error.
        /// </summary>
        /// <param name="filesystem"></param>
        /// <param name="path"></param>
        /// <param name="depth">maximum visit depth</param>
        /// <param name="option">(optional) operation specific option; capability constraint, a session, security token or credential. Used for authenticating, authorizing or restricting the operation.</param>
        /// <exception cref="Exception">any exception that GetEntry or Browse can throw</exception>
        /// <exception cref="IOException">If Browse returns an entry whose path is not under parent entry's path</exception>
        public static IEnumerable <Line> VisitTree(this IFileSystem filesystem, string path = "", int depth = Int32.MaxValue, IOption option = null)
        {
            List <Line> queue = new List <Line>();
            IEntry      entry = filesystem.GetEntry(path, option);

            if (entry == null)
            {
                yield break;
            }
            queue.Add(new Line(entry, 0, 0UL));
            while (queue.Count > 0)
            {
                // Next entry
                int  lastIx = queue.Count - 1;
                Line line   = queue[lastIx];
                queue.RemoveAt(lastIx);

                // Children
                if (line.Entry.IsDirectory() && line.Level < depth)
                {
                    int startIndex = queue.Count;
                    try
                    {
                        // Browse
                        IDirectoryContent content = filesystem.Browse(line.Entry.Path, option);
                        // Assert children don't refer to the parent of the parent
                        foreach (IEntry child in content)
                        {
                            if (line.Entry.Path.StartsWith(child.Path))
                            {
                                throw new IOException($"{child.Path} cannot be child of {line.Entry.Path}");
                            }
                        }
                        // Bitmask when this level continues
                        ulong levelContinuesBitMask = line.LevelContinuesBitMask | (line.Level < 64 ? 1UL << line.Level : 0UL);
                        // Add children in reverse order
                        foreach (IEntry child in content)
                        {
                            queue.Add(new Line(child, line.Level + 1, levelContinuesBitMask));
                        }
                        // Sort the entries that were added
                        if (content.Count > 1)
                        {
                            sorter.QuickSortInverse(ref queue, startIndex, queue.Count - 1);
                        }
                        // Last entry doesn't continue on its level.
                        if (content.Count >= 1)
                        {
                            queue[startIndex] = queue[startIndex].NewLevelContinuesBitMask(line.LevelContinuesBitMask);
                        }
                    }
                    catch (Exception e)
                    {
                        // Add error to be yielded along
                        line.Error = e;
                    }
                }

                // yield line
                yield return(line);
            }
        }
Example #5
0
        public void Open()
        {
            // Arrange
            PermutationSetup permutation = new PermutationSetup();

            permutation.Add(blockpool_1TB);
            permutation.Add(blockpool_Pseudo);

            permutation.Add(case_ms);
            //permutation.Add(decor_fs);
            permutation.Add(case_decor_ms);
            permutation.Add(case_vfs_ms);
            permutation.Add(case_vfs_2ms);
            //permutation.Add(vfs_fsms);
            permutation.Add(init);

            // Act & Assert
            foreach (Scenario scenario in permutation.Scenarios)
            {
                using (Run run = scenario.Run().Initialize())
                {
                    IFileSystem fs = run.Parameters["Class"] as IFileSystem;
                    fs.Observe("**", observer = new Observer());
                    observer.events.Clear();

                    // Open
                    //    Points to directory
                    try { fs.Open("/tmp", FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite); Assert.Fail(); } catch (IOException) { }
                    //    File doesn't exist
                    try { fs.Open("/tmp/nonexisting.txt", FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite); Assert.Fail(); } catch (IOException) { }
                    //    Access Control tests
                    try
                    {
                        using (Stream s = fs.Open("/tmp/helloworld.txt", FileMode.Open, FileAccess.ReadWrite, FileShare.None))
                            using (Stream s2 = fs.Open("/tmp/helloworld.txt", FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
                            { }
                        Assert.Fail();
                    }
                    catch (IOException) { }
                    try
                    {
                        using (Stream s = fs.Open("/tmp/helloworld.txt", FileMode.Open, FileAccess.Write, FileShare.Write))
                            using (Stream s2 = fs.Open("/tmp/helloworld.txt", FileMode.Open, FileAccess.Read, FileShare.Read))
                            { }// Should not open
                        Assert.Fail();
                    }
                    catch (IOException) { }


                    // OpenOrCreate
                    //    Invalid filename "", ".", ".." -> fail
                    try { fs.Open("/tmp/", FileMode.OpenOrCreate, FileAccess.Write, FileShare.Write); Assert.Fail(); } catch (IOException) { }
                    try { fs.Open("/tmp/.", FileMode.OpenOrCreate, FileAccess.Write, FileShare.Write); Assert.Fail(); } catch (IOException) { }
                    try { fs.Open("/tmp/..", FileMode.OpenOrCreate, FileAccess.Write, FileShare.Write); Assert.Fail(); } catch (IOException) { }
                    //    File already exists (with open stream) -> same file
                    {
                        // Wipe events
                        observer.events.Clear();
                        // Open handle to same file
                        string path = "/tmp/file1.txt";
                        Assert.IsFalse(fs.Browse("/tmp").Any(e => e.Path == path));
                        Stream s1  = fs.Open(path, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.ReadWrite);
                        Stream s2  = fs.Open(path, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.ReadWrite);
                        int    len = HelloWorld.Length;
                        s1.Write(HelloWorld);
                        byte[] data = new byte[len];
                        s2.Read(data);
                        for (int i = 0; i < len; i++)
                        {
                            Assert.AreEqual(HelloWorld[i], data[i]);
                        }
                        //    Assert event
                        Assert.IsTrue(observer.events[0] is ICreateEvent);
                        Assert.IsTrue(observer.events[1] is IChangeEvent);
                        Assert.IsTrue(observer.events[0].Path == path);
                        Assert.IsTrue(observer.events[1].Path == path);
                        //    Assert parent cache is flushed and children updated
                        Assert.IsTrue(fs.Browse("/tmp").Any(e => e.Path == path));
                        //    Assert entry is ok
                        Assert.IsTrue(fs.GetEntry(path).Path == path);
                        // Wipe events
                        observer.events.Clear();
                    }

                    // CreateNew -
                    //    Invalid filename "", ".", ".." -> fail
                    try { fs.Open("/tmp/", FileMode.CreateNew, FileAccess.Write, FileShare.Write); Assert.Fail(); } catch (IOException) { }
                    try { fs.Open("/tmp/.", FileMode.CreateNew, FileAccess.Write, FileShare.Write); Assert.Fail(); } catch (IOException) { }
                    try { fs.Open("/tmp/..", FileMode.CreateNew, FileAccess.Write, FileShare.Write); Assert.Fail(); } catch (IOException) { }
                    {
                        string path = "/tmp/file2.txt";
                        Assert.IsFalse(fs.Browse("/tmp").Any(e => e.Path == path));
                        Stream s1 = fs.Open(path, FileMode.CreateNew, FileAccess.ReadWrite, FileShare.ReadWrite);
                        //    File already exists -> fail
                        try { Stream s2 = fs.Open(path, FileMode.CreateNew, FileAccess.ReadWrite, FileShare.ReadWrite); Assert.Fail(); } catch (IOException) { }
                        //    Assert event
                        Assert.IsTrue(observer.events[0] is ICreateEvent);
                        Assert.IsTrue(observer.events[0].Path == path);
                        //    Assert parent cache is flushed and children updated
                        Assert.IsTrue(fs.Browse("/tmp").Any(e => e.Path == path));
                        //    Assert entry is ok
                        Assert.IsTrue(fs.GetEntry(path).Path == path);
                        // Wipe events
                        observer.events.Clear();
                    }

                    // Create
                    //    Invalid filename "", ".", ".." -> fail
                    try { fs.Open("/tmp/", FileMode.Create, FileAccess.Write, FileShare.Write); Assert.Fail(); } catch (IOException) { }
                    try { fs.Open("/tmp/.", FileMode.Create, FileAccess.Write, FileShare.Write); Assert.Fail(); } catch (IOException) { }
                    try { fs.Open("/tmp/..", FileMode.Create, FileAccess.Write, FileShare.Write); Assert.Fail(); } catch (IOException) { }
                    //    File already exists (with open stream) -> previous file is unlinked
                    {
                        // Open handle to same file
                        string path = "/tmp/file3.txt";
                        Assert.IsFalse(fs.Browse("/tmp").Any(e => e.Path == path));
                        Stream s1 = fs.Open(path, FileMode.Create, FileAccess.ReadWrite, FileShare.ReadWrite);
                        s1.Write(HelloWorld);
                        s1.Dispose();
                        int len = HelloWorld.Length;
                        // Replace other file
                        Stream s2   = fs.Open(path, FileMode.Create, FileAccess.ReadWrite, FileShare.ReadWrite);
                        byte[] data = new byte[(int)s2.Length];
                        s2.Read(data);
                        Assert.AreEqual(0L, s2.Length);
                        //    Assert event
                        Assert.IsTrue(observer.events[0] is ICreateEvent);
                        Assert.IsTrue(observer.events[1] is IChangeEvent);
                        Assert.IsTrue(observer.events[0].Path == path);
                        Assert.IsTrue(observer.events[1].Path == path);
                        //    Assert parent cache is flushed and children updated
                        Assert.IsTrue(fs.Browse("/tmp").Any(e => e.Path == path));
                        //    Assert entry is ok
                        Assert.IsTrue(fs.GetEntry(path).Path == path);
                        // Wipe events
                        observer.events.Clear();
                    }
                    fs.Observe("**", observer = new Observer());
                    observer.events.Clear();
                }
            }
        }
Example #6
0
        public void Move()
        {
            // Arrange
            PermutationSetup permutation = new PermutationSetup();

            permutation.Add(blockpool_1TB);
            permutation.Add(blockpool_Pseudo);

            permutation.Add(case_ms);
            //permutation.Add(decor_fs);
            permutation.Add(case_decor_ms);
            permutation.Add(case_vfs_ms);
            permutation.Add(case_vfs_2ms);
            //permutation.Add(vfs_fsms);
            permutation.Add(init);

            // Act & Assert
            foreach (Scenario scenario in permutation.Scenarios)
            {
                using (Run run = scenario.Run().Initialize())
                {
                    IFileSystem fs = run.Parameters["Class"] as IFileSystem;
                    fs.Observe("**", observer = new Observer());
                    observer.events.Clear();

                    // Rename to same file
                    fs.Move("/tmp/helloworld.txt", "/tmp/../tmp/helloworld.txt");

                    Assert.IsTrue(observer.events.Count == 0);
                    // Move to non-existing dir
                    try { fs.Move("/tmp/helloworld.txt", "/nonexisting/helloworld.txt"); Assert.Fail(); } catch (IOException) { }
                    // Move non-existing file
                    try { fs.Move("/tmp/nonexisting.txt", "/tmp/somefile.txt"); Assert.Fail(); } catch (IOException) { }
                    // Move over to directory
                    try { fs.Move("/tmp/helloworld.txt", "c:"); Assert.Fail(); } catch (IOException) { }

                    // Move a file
                    Assert.IsFalse(fs.Browse("c:").Any(e => e.Path == "c:/helloworld.txt"));
                    Assert.IsTrue(fs.Browse("/tmp").Any(e => e.Path == "/tmp/helloworld.txt"));
                    fs.Move("/tmp/helloworld.txt", "c:/helloworld.txt");
                    Assert.IsTrue(fs.Browse("c:").Any(e => e.Path == "c:/helloworld.txt"));
                    Assert.IsFalse(fs.Browse("/tmp").Any(e => e.Path == "/tmp/helloworld.txt"));
                    Assert.IsTrue(observer.Last is IRenameEvent);
                    Assert.IsTrue(DateTimeOffset.UtcNow - observer.Last.EventTime < TimeSpan.FromSeconds(2));
                    Assert.AreEqual(fs, observer.Last.Observer.FileSystem);

                    // Move whole tree
                    Assert.IsFalse(fs.Browse("c:").Any(e => e.Path == "c:/tmp/"));
                    Assert.IsTrue(fs.Browse("/").Any(e => e.Path == "/tmp/"));
                    fs.Move("/tmp/", "c:/tmp/");
                    Assert.IsTrue(fs.Browse("c:").Any(e => e.Path == "c:/tmp/"));
                    Assert.IsFalse(fs.Browse("/").Any(e => e.Path == "/tmp/"));
                    Assert.IsNull(fs.GetEntry("/tmp/"));
                    Assert.IsTrue(fs.Browse("c:/tmp/").Count >= 3);
                    Assert.IsTrue(observer.Last is IRenameEvent);
                    Assert.IsTrue(DateTimeOffset.UtcNow - observer.Last.EventTime < TimeSpan.FromSeconds(2));
                    Assert.AreEqual(fs, observer.Last.Observer.FileSystem);
                    Assert.IsTrue(observer.Last.Path.StartsWith("/tmp/"));
                    Assert.IsTrue(observer.Last.NewPath().StartsWith("c:/tmp/"));
                    fs.Observe("**", observer = new Observer());
                    observer.events.Clear();
                }
            }
        }