public async Task ReturnsAndCachesCompiledResultIfCacheMisses() { // Arrange var compiled = new Mock <Type>(); TestableDefaultCompilationManager cm = CreateManager(); TestFile file = TestData.CreateDummyFile(); var compiler = new Mock <ICompiler>(); cm.Compilers.Add(compiler.Object); cm.MockContentIdentifier .Setup(i => i.GenerateContentId(file)).Returns("Foo"); compiler.Setup(c => c.CanCompile(file)).Returns(true); compiler.Setup(c => c.Compile(file)).Returns(Task.FromResult(CompilationResult.Successful(It.IsAny <string>(), compiled.Object, new[] { new CompilationMessage(MessageLevel.Info, "Foo") }))); // Act CompilationResult result = await cm.Compile(file, NullTrace.Instance); // Assert Assert.True(result.Success); Assert.False(result.SatisfiedFromCache); Assert.Equal("Foo", result.Messages.Single().Message); Assert.Same(compiled.Object, result.GetCompiledType()); Type cached; Assert.True(cm.Cache["Foo"].TryGetTarget(out cached)); Assert.Same(compiled.Object, cached); }
public async Task ReturnsCacheIfHitAndReferenceValid() { // Arrange var cached = new Mock <Type>(); TestableDefaultCompilationManager cm = CreateManager(); TestFile file = TestData.CreateDummyFile(); cm.Cache["Foo"] = new WeakReference <Type>(cached.Object); cm.MockContentIdentifier .Setup(i => i.GenerateContentId(file)).Returns("Foo"); // Act CompilationResult result = await cm.Compile(file, NullTrace.Instance); // Assert Assert.True(result.Success); Assert.True(result.SatisfiedFromCache); Assert.Equal(0, result.Messages.Count); Assert.Same(cached.Object, result.GetCompiledType()); }
public void ReturnsAndCachesCompiledResultIfCachedValueHasBeenCollected() { // Arrange var compiled = new Mock <Type>(); TestableDefaultCompilationManager cm = CreateManager(); TestFile file = TestData.CreateDummyFile(); var compiler = new Mock <ICompiler>(); cm.Compilers.Add(compiler.Object); cm.MockContentIdentifier .Setup(i => i.GenerateContentId(file)).Returns("Foo"); compiler.Setup(c => c.CanCompile(file)).Returns(true); compiler.Setup(c => c.Compile(file)).Returns(Task.FromResult(CompilationResult.Successful(It.IsAny <string>(), compiled.Object, new[] { new CompilationMessage(MessageLevel.Info, "Foo") }))); // Add a cache entry, but collect it. cm.Cache["Foo"] = new WeakReference <Type>(new FakeType()); GC.Collect(); // Act // Using ".Result" because making this Async causes a reference to the cached type to be held. CompilationResult result = cm.Compile(file, NullTrace.Instance).Result; // Assert Assert.True(result.Success); Assert.False(result.SatisfiedFromCache); Assert.Equal("Foo", result.Messages.Single().Message); Assert.Same(compiled.Object, result.GetCompiledType()); Type cached; Assert.True(cm.Cache["Foo"].TryGetTarget(out cached)); Assert.Same(compiled.Object, cached); }
public async Task Invoke(IDictionary <string, object> environment) { var sw = new Stopwatch(); var req = new RazorRequest(environment); ITrace trace = Tracer.ForRequest(req); using (trace.StartTrace()) { trace.WriteLine("Received {0} {1}", req.Method, req.Path); if (!IsUnder(VirtualRoot, req.Path)) { // Not for us! await NextApp(environment); return; } // Step 1. Route the request to a file RouteResult routed = await Router.Route(req, trace); if (!routed.Success) { // Also not for us! await NextApp(environment); return; } trace.WriteLine("Router: '{0}' ==> '{1}'::'{2}'", req.Path, routed.File.Name, routed.PathInfo); // Step 2. Use the compilation manager to get the file's compiled type sw.Start(); CompilationResult compiled = await CompilationManager.Compile(routed.File, trace); sw.Stop(); if (!compiled.Success) { trace.WriteLine("Compiler: '{0}' FAILED", routed.File.Name); throw new CompilationFailedException(compiled.Messages, compiled.GeneratedCode); } if (compiled.SatisfiedFromCache) { trace.WriteLine("Retrieved compiled code from cache in {0}ms", sw.ElapsedMilliseconds); } else { trace.WriteLine("Compiled '{0}' in {1}ms", routed.File.Name, sw.ElapsedMilliseconds); } sw.Reset(); // Step 3. Construct an instance using the PageActivator Type type = compiled.GetCompiledType(); ActivationResult activated = Activator.ActivatePage(type, trace); if (!activated.Success) { trace.WriteLine("Activator: '{0}' FAILED", type.FullName); throw new ActivationFailedException(type); } trace.WriteLine("Activator: '{0}' SUCCESS", type.FullName); // Step 4. Execute the activated instance! await Executor.Execute(activated.Page, environment, trace); } }