public void IsItemValid_NoChecksums_ReturnsTrue() { // Arrange var item = new TestRazorCompiledItem(typeof(string), "mvc.1.0.view", "/Views/Home/Index.cstml", new object[] { }); // Act var result = ChecksumValidator.IsItemValid(ProjectFileSystem, item); // Assert Assert.True(result); }
public void IsItemValid_NoPrimaryChecksum_ReturnsTrue() { // Arrange var item = new TestRazorCompiledItem(typeof(string), "mvc.1.0.view", "/Views/Home/Index.cstml", new object[] { new RazorSourceChecksumAttribute("SHA1", GetChecksum("some import"), "/Views/Home/_ViewImports.cstml"), new RazorSourceChecksumAttribute("SHA1", GetChecksum("some content"), "/Views/Home/About.cstml"), }); // Act var result = ChecksumValidator.IsItemValid(ProjectFileSystem, item); // Assert Assert.True(result); }
public void IsItemValid_PrimaryFileDoesNotExist_ReturnsTrue() { // Arrange var item = new TestRazorCompiledItem(typeof(string), "mvc.1.0.view", "/Views/Home/Index.cstml", new object[] { new RazorSourceChecksumAttribute("SHA1", GetChecksum("some import"), "/Views/Home/_ViewImports.cstml"), new RazorSourceChecksumAttribute("SHA1", GetChecksum("some content"), "/Views/Home/Index.cstml"), }); ProjectFileSystem.Add(new TestRazorProjectItem("/Views/Home/_ViewImports.cstml", "dkdkfkdf")); // This will be ignored // Act var result = ChecksumValidator.IsItemValid(ProjectFileSystem, item); // Assert Assert.True(result); }
public void IsItemValid_ImportFileDoesNotExist_ReturnsFalse() { // Arrange var item = new TestRazorCompiledItem(typeof(string), "mvc.1.0.view", "/Views/Home/Index.cstml", new object[] { new RazorSourceChecksumAttribute("SHA1", GetChecksum("some import"), "/Views/Home/_ViewImports.cstml"), new RazorSourceChecksumAttribute("SHA1", GetChecksum("some content"), "/Views/Home/Index.cstml"), }); FileProvider.AddFile("/Views/Home/Index.cstml", "some content"); // Act var result = ChecksumValidator.IsItemValid(FileSystem, item); // Assert Assert.False(result); }
public void IsItemValid_AllFilesMatch_ReturnsTrue() { // Arrange var item = new TestRazorCompiledItem(typeof(string), "mvc.1.0.view", "/Views/Home/Index.cstml", new object[] { new RazorSourceChecksumAttribute("SHA1", GetChecksum("some other import"), "/Views/_ViewImports.cstml"), new RazorSourceChecksumAttribute("SHA1", GetChecksum("some import"), "/Views/Home/_ViewImports.cstml"), new RazorSourceChecksumAttribute("SHA1", GetChecksum("some content"), "/Views/Home/Index.cstml"), }); FileProvider.AddFile("/Views/Home/Index.cstml", "some content"); FileProvider.AddFile("/Views/Home/_ViewImports.cstml", "some import"); FileProvider.AddFile("/Views/_ViewImports.cstml", "some other import"); // Act var result = ChecksumValidator.IsItemValid(Project, item); // Assert Assert.True(result); }
private Task <CompiledViewDescriptor> OnCacheMiss(string normalizedPath) { ViewCompilerWorkItem item; TaskCompletionSource <CompiledViewDescriptor> taskSource; MemoryCacheEntryOptions cacheEntryOptions; // Safe races cannot be allowed when compiling Razor pages. To ensure only one compilation request succeeds // per file, we'll lock the creation of a cache entry. Creating the cache entry should be very quick. The // actual work for compiling files happens outside the critical section. lock (_cacheLock) { // Double-checked locking to handle a possible race. if (_cache.TryGetValue(normalizedPath, out Task <CompiledViewDescriptor> result)) { return(result); } if (_precompiledViews.TryGetValue(normalizedPath, out var precompiledView)) { _logger.ViewCompilerLocatedCompiledViewForPath(normalizedPath); item = CreatePrecompiledWorkItem(normalizedPath, precompiledView); } else { item = CreateRuntimeCompilationWorkItem(normalizedPath); } // At this point, we've decided what to do - but we should create the cache entry and // release the lock first. cacheEntryOptions = new MemoryCacheEntryOptions(); Debug.Assert(item.ExpirationTokens != null); for (var i = 0; i < item.ExpirationTokens.Count; i++) { cacheEntryOptions.ExpirationTokens.Add(item.ExpirationTokens[i]); } taskSource = new TaskCompletionSource <CompiledViewDescriptor>(creationOptions: TaskCreationOptions.RunContinuationsAsynchronously); if (item.SupportsCompilation) { // We'll compile in just a sec, be patient. } else { // If we can't compile, we should have already created the descriptor Debug.Assert(item.Descriptor != null); taskSource.SetResult(item.Descriptor); } _cache.Set(normalizedPath, taskSource.Task, cacheEntryOptions); } // Now the lock has been released so we can do more expensive processing. if (item.SupportsCompilation) { Debug.Assert(taskSource != null); if (item.Descriptor?.Item != null && ChecksumValidator.IsItemValid(_projectEngine.FileSystem, item.Descriptor.Item)) { // If the item has checksums to validate, we should also have a precompiled view. Debug.Assert(item.Descriptor != null); taskSource.SetResult(item.Descriptor); return(taskSource.Task); } _logger.ViewCompilerInvalidingCompiledFile(item.NormalizedPath); try { var descriptor = CompileAndEmit(normalizedPath); descriptor.ExpirationTokens = cacheEntryOptions.ExpirationTokens; taskSource.SetResult(descriptor); } catch (Exception ex) { taskSource.SetException(ex); } } return(taskSource.Task); }