public void ShadowScopeCompleteWithFileConflict() { var logger = Mock.Of <ILogger>(); var path = IOHelper.MapPath("FileSysTests"); var shadowfs = IOHelper.MapPath("App_Data/TEMP/ShadowFs"); Directory.CreateDirectory(path); var scopedFileSystems = false; var phy = new PhysicalFileSystem(path, "ignore"); var container = Mock.Of <IFactory>(); var fileSystems = new FileSystems(container, logger) { IsScoped = () => scopedFileSystems }; var fs = fileSystems.GetFileSystem <FS>(phy); var sw = (ShadowWrapper)fs.InnerFileSystem; using (var ms = new MemoryStream(Encoding.UTF8.GetBytes("foo"))) sw.AddFile("sub/f1.txt", ms); Assert.IsTrue(phy.FileExists("sub/f1.txt")); Guid id; scopedFileSystems = true; // pretend we have a scope var scope = new ShadowFileSystems(fileSystems, id = Guid.NewGuid()); Assert.IsTrue(Directory.Exists(shadowfs + "/" + id)); using (var ms = new MemoryStream(Encoding.UTF8.GetBytes("foo"))) sw.AddFile("sub/f2.txt", ms); Assert.IsFalse(phy.FileExists("sub/f2.txt")); // pretend we're another thread w/out scope scopedFileSystems = false; using (var ms = new MemoryStream(Encoding.UTF8.GetBytes("bar"))) sw.AddFile("sub/f2.txt", ms); scopedFileSystems = true; // pretend we have a scope Assert.IsTrue(phy.FileExists("sub/f2.txt")); // other thread has written out to fs scope.Complete(); scope.Dispose(); scopedFileSystems = false; Assert.IsTrue(phy.FileExists("sub/f2.txt")); TestHelper.TryAssert(() => Assert.IsFalse(Directory.Exists(shadowfs + "/" + id))); string text; using (var s = phy.OpenFile("sub/f2.txt")) using (var r = new StreamReader(s)) text = r.ReadToEnd(); // the shadow filesystem will happily overwrite anything it can Assert.AreEqual("foo", text); }
public void ShadowScopeCompleteWithDirectoryConflict() { var logger = Mock.Of <ILogger>(); var path = IOHelper.MapPath("FileSysTests"); var shadowfs = IOHelper.MapPath("App_Data/TEMP/ShadowFs"); Directory.CreateDirectory(path); var scopedFileSystems = false; var phy = new PhysicalFileSystem(path, "ignore"); var container = Mock.Of <IFactory>(); var fileSystems = new FileSystems(container, logger) { IsScoped = () => scopedFileSystems }; var fs = fileSystems.GetFileSystem <FS>(phy); var sw = (ShadowWrapper)fs.InnerFileSystem; using (var ms = new MemoryStream(Encoding.UTF8.GetBytes("foo"))) sw.AddFile("sub/f1.txt", ms); Assert.IsTrue(phy.FileExists("sub/f1.txt")); Guid id; scopedFileSystems = true; // pretend we have a scope var scope = new ShadowFileSystems(fileSystems, id = Guid.NewGuid()); Assert.IsTrue(Directory.Exists(shadowfs + "/" + id)); using (var ms = new MemoryStream(Encoding.UTF8.GetBytes("foo"))) sw.AddFile("sub/f2.txt", ms); Assert.IsFalse(phy.FileExists("sub/f2.txt")); // pretend we're another thread w/out scope scopedFileSystems = false; using (var ms = new MemoryStream(Encoding.UTF8.GetBytes("bar"))) sw.AddFile("sub/f2.txt/f2.txt", ms); scopedFileSystems = true; // pretend we have a scope Assert.IsTrue(phy.FileExists("sub/f2.txt/f2.txt")); // other thread has written out to fs using (var ms = new MemoryStream(Encoding.UTF8.GetBytes("foo"))) sw.AddFile("sub/f3.txt", ms); Assert.IsFalse(phy.FileExists("sub/f3.txt")); scope.Complete(); try { // no way this can work since we're trying to write a file // but there's now a directory with the same name on the real fs scope.Dispose(); Assert.Fail("Expected AggregateException."); } catch (AggregateException ae) { Assert.AreEqual(1, ae.InnerExceptions.Count); var e = ae.InnerExceptions[0]; Assert.IsNotNull(e.InnerException); Assert.IsInstanceOf <AggregateException>(e); ae = (AggregateException)e; Assert.AreEqual(1, ae.InnerExceptions.Count); e = ae.InnerExceptions[0]; Assert.IsNotNull(e.InnerException); Assert.IsInstanceOf <Exception>(e.InnerException); } // still, the rest of the changes has been applied ok Assert.IsTrue(phy.FileExists("sub/f3.txt")); }
public void ShadowScopeComplete() { var logger = Mock.Of <ILogger>(); var path = IOHelper.MapPath("FileSysTests"); var shadowfs = IOHelper.MapPath("App_Data/TEMP/ShadowFs"); Directory.CreateDirectory(path); Directory.CreateDirectory(shadowfs); var scopedFileSystems = false; var phy = new PhysicalFileSystem(path, "ignore"); var container = Mock.Of <IFactory>(); var fileSystems = new FileSystems(container, logger) { IsScoped = () => scopedFileSystems }; var fs = fileSystems.GetFileSystem <FS>(phy); var sw = (ShadowWrapper)fs.InnerFileSystem; using (var ms = new MemoryStream(Encoding.UTF8.GetBytes("foo"))) sw.AddFile("sub/f1.txt", ms); Assert.IsTrue(phy.FileExists("sub/f1.txt")); Guid id; // explicit shadow without scope does not work sw.Shadow(id = Guid.NewGuid()); Assert.IsTrue(Directory.Exists(shadowfs + "/" + id)); using (var ms = new MemoryStream(Encoding.UTF8.GetBytes("foo"))) sw.AddFile("sub/f2.txt", ms); Assert.IsTrue(phy.FileExists("sub/f2.txt")); sw.UnShadow(true); Assert.IsTrue(phy.FileExists("sub/f2.txt")); Assert.IsFalse(Directory.Exists(shadowfs + "/" + id)); // shadow with scope but no complete does not complete scopedFileSystems = true; // pretend we have a scope var scope = new ShadowFileSystems(fileSystems, id = Guid.NewGuid()); Assert.IsTrue(Directory.Exists(shadowfs + "/" + id)); using (var ms = new MemoryStream(Encoding.UTF8.GetBytes("foo"))) sw.AddFile("sub/f3.txt", ms); Assert.IsFalse(phy.FileExists("sub/f3.txt")); var dirs = Directory.GetDirectories(shadowfs); Assert.AreEqual(1, dirs.Length); Assert.AreEqual((shadowfs + "/" + id).Replace('\\', '/'), dirs[0].Replace('\\', '/')); dirs = Directory.GetDirectories(dirs[0]); var typedDir = dirs.FirstOrDefault(x => x.Replace('\\', '/').EndsWith("/typed")); Assert.IsNotNull(typedDir); dirs = Directory.GetDirectories(typedDir); var scopedDir = dirs.FirstOrDefault(x => x.Replace('\\', '/').EndsWith("/Umbraco.Tests.IO.ShadowFileSystemTests+FS")); // this is where files go Assert.IsNotNull(scopedDir); scope.Dispose(); scopedFileSystems = false; Assert.IsFalse(phy.FileExists("sub/f3.txt")); TestHelper.TryAssert(() => Assert.IsFalse(Directory.Exists(shadowfs + "/" + id))); // shadow with scope and complete does complete scopedFileSystems = true; // pretend we have a scope scope = new ShadowFileSystems(fileSystems, id = Guid.NewGuid()); Assert.IsTrue(Directory.Exists(shadowfs + "/" + id)); using (var ms = new MemoryStream(Encoding.UTF8.GetBytes("foo"))) sw.AddFile("sub/f4.txt", ms); Assert.IsFalse(phy.FileExists("sub/f4.txt")); Assert.AreEqual(1, Directory.GetDirectories(shadowfs).Length); scope.Complete(); scope.Dispose(); scopedFileSystems = false; TestHelper.TryAssert(() => Assert.AreEqual(0, Directory.GetDirectories(shadowfs).Length)); Assert.IsTrue(phy.FileExists("sub/f4.txt")); Assert.IsFalse(Directory.Exists(shadowfs + "/" + id)); // test scope for "another thread" scopedFileSystems = true; // pretend we have a scope scope = new ShadowFileSystems(fileSystems, id = Guid.NewGuid()); Assert.IsTrue(Directory.Exists(shadowfs + "/" + id)); using (var ms = new MemoryStream(Encoding.UTF8.GetBytes("foo"))) sw.AddFile("sub/f5.txt", ms); Assert.IsFalse(phy.FileExists("sub/f5.txt")); // pretend we're another thread w/out scope scopedFileSystems = false; using (var ms = new MemoryStream(Encoding.UTF8.GetBytes("foo"))) sw.AddFile("sub/f6.txt", ms); scopedFileSystems = true; // pretend we have a scope Assert.IsTrue(phy.FileExists("sub/f6.txt")); // other thread has written out to fs scope.Complete(); scope.Dispose(); scopedFileSystems = false; Assert.IsTrue(phy.FileExists("sub/f5.txt")); Assert.IsFalse(Directory.Exists(shadowfs + "/" + id)); }