コード例 #1
0
        public void TestIncrementalWithNullLastPostProcessInfo()
        {
            var intermediateFolder = GetRandomFolder();
            var currentBuildInfo   = new BuildInfo
            {
                DirectoryName = IncrementalUtility.CreateRandomDirectory(intermediateFolder)
            };

            // Pass null as last build info
            var postProcessors = GetPostProcessors(typeof(AppendStringPostProcessor));
            var increContext   = new IncrementalPostProcessorsContext(intermediateFolder, currentBuildInfo, null, postProcessors, true);

            // Check context
            Assert.True(increContext.ShouldTraceIncrementalInfo);
            Assert.False(increContext.IsIncremental);

            var increPostProcessorHandler = new PostProcessorsHandlerWithIncremental(PostProcessorsHandler, increContext);
            var manifest     = JsonUtility.Deserialize <Manifest>("PostProcessors/Data/manifest_incremental.json");
            var outputFolder = GetRandomFolder();

            PrepareOutput(outputFolder, "a", "b", "c");
            increPostProcessorHandler.Handle(postProcessors, manifest, outputFolder);

            // Check incremental flag
            Assert.True(manifest.Files.All(f => f.IsIncremental == false));

            // Check output content
            VerifyOutput(outputFolder, AppendStringPostProcessor.AppendString, "a", "b", "c");

            // Check cached PostProcessInfo
            Assert.NotNull(currentBuildInfo.PostProcessInfo);

            var postProcessorInfos = currentBuildInfo.PostProcessInfo.PostProcessorInfos;

            Assert.Equal(1, currentBuildInfo.PostProcessInfo.PostProcessorInfos.Count);
            Assert.Equal($"{typeof(AppendStringPostProcessor).Name}", postProcessorInfos[0].Name);
            Assert.Null(postProcessorInfos[0].IncrementalContextHash);

            var postProcessOutputs = currentBuildInfo.PostProcessInfo.PostProcessOutputs;

            Assert.Equal(9, postProcessOutputs.Count);
            VerifyCachedOutput(Path.Combine(intermediateFolder, currentBuildInfo.DirectoryName), postProcessOutputs, AppendStringPostProcessor.AppendString, AppendStringPostProcessor.AdditionalExtensionString, "a", "b", "c");

            Assert.Equal <ManifestItem>(manifest.Files, currentBuildInfo.PostProcessInfo.ManifestItems);

            // Check incremental info
            Assert.Equal(1, manifest.IncrementalInfo.Count);
            Assert.Equal(false, manifest.IncrementalInfo[0].Status.CanIncremental);
            Assert.Equal(IncrementalPhase.PostProcessing, manifest.IncrementalInfo[0].Status.IncrementalPhase);
            Assert.Equal("Cannot support incremental post processing, the reason is: last post processor info is null.", manifest.IncrementalInfo[0].Status.Details);
        }
コード例 #2
0
        public void TestIncrementalWithNotSupportIncrementalPostProcessor()
        {
            var intermediateFolder = GetRandomFolder();
            var currentBuildInfo   = new BuildInfo
            {
                DirectoryName = IncrementalUtility.CreateRandomDirectory(intermediateFolder)
            };
            var lastBuildInfo = new BuildInfo
            {
                DirectoryName   = IncrementalUtility.CreateRandomDirectory(intermediateFolder),
                PostProcessInfo = new PostProcessInfo()
            };

            lastBuildInfo.PostProcessInfo.PostProcessorInfos.Add(new PostProcessorInfo
            {
                Name = typeof(NonIncrementalPostProcessor).Name
            });

            // Add not post processor which not support incremental
            var postProcessors = GetPostProcessors(typeof(NonIncrementalPostProcessor));
            var increContext   = new IncrementalPostProcessorsContext(intermediateFolder, currentBuildInfo, lastBuildInfo, postProcessors, true);

            // Check context
            Assert.False(increContext.ShouldTraceIncrementalInfo);
            Assert.False(increContext.IsIncremental);

            var increPostProcessorHandler = new PostProcessorsHandlerWithIncremental(PostProcessorsHandler, increContext);
            var manifest     = JsonUtility.Deserialize <Manifest>("PostProcessors/Data/manifest_incremental.json");
            var outputFolder = GetRandomFolder();

            PrepareOutput(outputFolder, "a", "b", "c");
            increPostProcessorHandler.Handle(postProcessors, manifest, outputFolder);

            // Check incremental flag
            Assert.True(manifest.Files.All(f => f.IsIncremental == false));

            // Check output content should append nothing
            VerifyOutput(outputFolder, string.Empty, "a", "b", "c");

            // Check cached PostProcessInfo is null
            Assert.Null(currentBuildInfo.PostProcessInfo);

            // Check incremental info
            Assert.Equal(1, manifest.IncrementalInfo.Count);
            Assert.Equal(false, manifest.IncrementalInfo[0].Status.CanIncremental);
            Assert.Equal(IncrementalPhase.PostProcessing, manifest.IncrementalInfo[0].Status.IncrementalPhase);
            Assert.Equal("Cannot support incremental post processing, the reason is: should not trace intermediate info.", manifest.IncrementalInfo[0].Status.Details);
        }
コード例 #3
0
        public void TestIncrementalWithContextChange()
        {
            var intermediateFolder = GetRandomFolder();
            var currentBuildInfo   = new BuildInfo
            {
                DirectoryName = IncrementalUtility.CreateRandomDirectory(intermediateFolder)
            };
            var lastBuildInfo = new BuildInfo
            {
                DirectoryName   = IncrementalUtility.CreateRandomDirectory(intermediateFolder),
                PostProcessInfo = new PostProcessInfo()
            };

            lastBuildInfo.PostProcessInfo.PostProcessorInfos.Add(new PostProcessorInfo
            {
                Name = typeof(AppendIntegerPostProcessor).Name
            });

            // Add post processor which has changed context hash
            var postProcessors = GetPostProcessors(typeof(AppendIntegerPostProcessor));
            var increContext   = new IncrementalPostProcessorsContext(intermediateFolder, currentBuildInfo, lastBuildInfo, postProcessors, true);

            // Check context
            Assert.True(increContext.ShouldTraceIncrementalInfo);
            Assert.False(increContext.IsIncremental);

            var increPostProcessorHandler = new PostProcessorsHandlerWithIncremental(PostProcessorsHandler, increContext);
            var manifest     = JsonUtility.Deserialize <Manifest>("PostProcessors/Data/manifest_incremental.json");
            var outputFolder = GetRandomFolder();

            PrepareOutput(outputFolder, "a", "b", "c");
            increPostProcessorHandler.Handle(postProcessors, manifest, outputFolder);

            // Check incremental flag
            Assert.True(manifest.Files.All(f => f.IsIncremental == false));

            // Check output content
            VerifyOutput(outputFolder, AppendIntegerPostProcessor.AppendInteger, "a", "b", "c");

            // Check cached PostProcessInfo
            Assert.NotNull(currentBuildInfo.PostProcessInfo);

            var postProcessorInfos = currentBuildInfo.PostProcessInfo.PostProcessorInfos;

            Assert.Equal(1, currentBuildInfo.PostProcessInfo.PostProcessorInfos.Count);
            Assert.Equal($"{typeof(AppendIntegerPostProcessor).Name}", postProcessorInfos[0].Name);
            Assert.NotNull(postProcessorInfos[0].IncrementalContextHash);

            var postProcessOutputs = currentBuildInfo.PostProcessInfo.PostProcessOutputs;

            Assert.Equal(6, postProcessOutputs.Count);
            VerifyCachedOutput(Path.Combine(intermediateFolder, currentBuildInfo.DirectoryName), postProcessOutputs, AppendIntegerPostProcessor.AppendInteger, null, "a", "b", "c");

            Assert.Equal <ManifestItem>(manifest.Files, currentBuildInfo.PostProcessInfo.ManifestItems);

            // Check incremental info
            Assert.Equal(1, manifest.IncrementalInfo.Count);
            Assert.Equal(false, manifest.IncrementalInfo[0].Status.CanIncremental);
            Assert.Equal(IncrementalPhase.PostProcessing, manifest.IncrementalInfo[0].Status.IncrementalPhase);
            Assert.Equal(@"Cannot support incremental post processing, the reason is: post processor info changed from last {""Name"":""AppendIntegerPostProcessor""} to current {""Name"":""AppendIntegerPostProcessor"",""IncrementalContextHash"":""1024""}.",
                         manifest.IncrementalInfo[0].Status.Details);
        }
コード例 #4
0
        public void TestIncrementalWithFileInDirectory()
        {
            var intermediateFolder = GetRandomFolder();
            var currentBuildInfo   = new BuildInfo
            {
                DirectoryName = IncrementalUtility.CreateRandomDirectory(intermediateFolder)
            };
            var lastBuildInfo = new BuildInfo
            {
                DirectoryName   = IncrementalUtility.CreateRandomDirectory(intermediateFolder),
                PostProcessInfo = new PostProcessInfo()
            };

            lastBuildInfo.PostProcessInfo.PostProcessorInfos.Add(new PostProcessorInfo
            {
                Name = typeof(AppendStringPostProcessor).Name
            });

            // Exclude c, which is not incremental
            var preparedManifest = JsonUtility.Deserialize <Manifest>("PostProcessors/Data/manifest_incremental_with_directory.json");

            PrepareCachedOutput(intermediateFolder, lastBuildInfo, AppendStringPostProcessor.AppendString, preparedManifest.Files, AppendStringPostProcessor.AdditionalExtensionString, "a/b");

            var postProcessors = GetPostProcessors(typeof(AppendStringPostProcessor));
            var increContext   = new IncrementalPostProcessorsContext(intermediateFolder, currentBuildInfo, lastBuildInfo, postProcessors, true);

            // Check context
            Assert.True(increContext.ShouldTraceIncrementalInfo);
            Assert.True(increContext.IsIncremental);

            var increPostProcessorHandler = new PostProcessorsHandlerWithIncremental(PostProcessorsHandler, increContext);
            var manifest     = JsonUtility.Deserialize <Manifest>("PostProcessors/Data/manifest_incremental_with_directory.json");
            var outputFolder = GetRandomFolder();

            PrepareOutput(outputFolder, "a/b", "c");
            CreateFile("breadcrumb.json", "breadcrumb", outputFolder);
            increPostProcessorHandler.Handle(postProcessors, manifest, outputFolder);

            // Check incremental flag
            Assert.Equal(3, manifest.Files.Count);
            Assert.True(manifest.Files.Single(i => i.SourceRelativePath == "a/b.md").IsIncremental);
            Assert.False(manifest.Files.Single(i => i.SourceRelativePath == "c.md").IsIncremental);
            Assert.False(manifest.Files.Single(i => i.SourceRelativePath == "breadcrumb.json").IsIncremental);

            // Check output content
            VerifyOutput(outputFolder, AppendStringPostProcessor.AppendString, "a/b", "c");
            Assert.Equal("breadcrumb", EnvironmentContext.FileAbstractLayer.ReadAllText(Path.Combine(outputFolder, "breadcrumb.json")));

            // Check cached PostProcessInfo
            Assert.NotNull(currentBuildInfo.PostProcessInfo);

            var postProcessorInfos = currentBuildInfo.PostProcessInfo.PostProcessorInfos;

            Assert.Equal(1, currentBuildInfo.PostProcessInfo.PostProcessorInfos.Count);
            Assert.Equal($"{typeof(AppendStringPostProcessor).Name}", postProcessorInfos[0].Name);
            Assert.Null(postProcessorInfos[0].IncrementalContextHash);

            Assert.Equal <ManifestItem>(manifest.Files, currentBuildInfo.PostProcessInfo.ManifestItems);

            var postProcessOutputs = currentBuildInfo.PostProcessInfo.PostProcessOutputs;

            Assert.Equal(6, postProcessOutputs.Count);
            VerifyCachedOutput(Path.Combine(intermediateFolder, currentBuildInfo.DirectoryName), postProcessOutputs, AppendStringPostProcessor.AppendString, AppendStringPostProcessor.AdditionalExtensionString, "a/b", "c");
        }
コード例 #5
0
        public void TestIncrementalWithFirstCanIncrementalButSecondShouldnotTraceIncrementalInfo()
        {
            //        | Should trace incremental info | Can incremental |
            // ---------------------------------------------------------
            // First  |               yes             |       yes       |
            // Second |               no              |       no        |

            // Step 1: trace intermediate info and post process incrementally
            var intermediateFolder = GetRandomFolder();
            var currentBuildInfo   = new BuildInfo
            {
                DirectoryName = IncrementalUtility.CreateRandomDirectory(intermediateFolder)
            };
            var lastBuildInfo = new BuildInfo
            {
                DirectoryName   = IncrementalUtility.CreateRandomDirectory(intermediateFolder),
                PostProcessInfo = new PostProcessInfo()
            };

            lastBuildInfo.PostProcessInfo.PostProcessorInfos.Add(new PostProcessorInfo
            {
                Name = typeof(AppendStringPostProcessor).Name
            });

            // Exclude c, which is not incremental
            var preparedManifest = JsonUtility.Deserialize <Manifest>("PostProcessors/Data/manifest_incremental.json");

            PrepareCachedOutput(intermediateFolder, lastBuildInfo, AppendStringPostProcessor.AppendString, preparedManifest.Files, AppendStringPostProcessor.AdditionalExtensionString, "a", "b");

            var postProcessors = GetPostProcessors(typeof(AppendStringPostProcessor));
            var appendString   = $"{AppendStringPostProcessor.AppendString}";
            var increContext   = new IncrementalPostProcessorsContext(intermediateFolder, currentBuildInfo, lastBuildInfo, postProcessors, true);

            // Check context
            Assert.True(increContext.ShouldTraceIncrementalInfo);
            Assert.True(increContext.IsIncremental);

            var increPostProcessorHandler = new PostProcessorsHandlerWithIncremental(PostProcessorsHandler, increContext);
            var manifest     = JsonUtility.Deserialize <Manifest>("PostProcessors/Data/manifest_incremental.json");
            var outputFolder = GetRandomFolder();

            PrepareOutput(outputFolder, "a", "b", "c");
            increPostProcessorHandler.Handle(postProcessors, manifest, outputFolder);

            // Check incremental flag
            Assert.Equal(3, manifest.Files.Count);
            Assert.True(manifest.Files.Single(i => i.SourceRelativePath == "a.md").IsIncremental);
            Assert.True(manifest.Files.Single(i => i.SourceRelativePath == "b.md").IsIncremental);
            Assert.False(manifest.Files.Single(i => i.SourceRelativePath == "c.md").IsIncremental);
            foreach (var file in manifest.Files)
            {
                Assert.True(file.OutputFiles.ContainsKey(AppendStringPostProcessor.AdditionalExtensionString));
            }

            // Check output content
            VerifyOutput(outputFolder, appendString, "a", "b", "c");

            // Check cached PostProcessInfo
            Assert.NotNull(currentBuildInfo.PostProcessInfo);

            var postProcessorInfos = currentBuildInfo.PostProcessInfo.PostProcessorInfos;

            Assert.Equal(1, currentBuildInfo.PostProcessInfo.PostProcessorInfos.Count);
            Assert.Equal($"{typeof(AppendStringPostProcessor).Name}", postProcessorInfos[0].Name);
            Assert.Null(postProcessorInfos[0].IncrementalContextHash);

            Assert.Equal <ManifestItem>(manifest.Files, currentBuildInfo.PostProcessInfo.ManifestItems);

            var postProcessOutputs = currentBuildInfo.PostProcessInfo.PostProcessOutputs;

            Assert.Equal(9, postProcessOutputs.Count);
            VerifyCachedOutput(Path.Combine(intermediateFolder, currentBuildInfo.DirectoryName), postProcessOutputs, appendString, AppendStringPostProcessor.AdditionalExtensionString, "a", "b", "c");

            // Step 2: should not trace inter incremental post process
            currentBuildInfo = new BuildInfo
            {
                DirectoryName = IncrementalUtility.CreateRandomDirectory(intermediateFolder)
            };
            lastBuildInfo = new BuildInfo
            {
                DirectoryName   = Path.GetFileName(increContext.CurrentBaseDir),
                PostProcessInfo = increContext.CurrentInfo
            };

            // Add post processor which not supports incremental
            postProcessors.AddRange(GetPostProcessors(typeof(NonIncrementalPostProcessor)));
            increContext = new IncrementalPostProcessorsContext(intermediateFolder, currentBuildInfo, lastBuildInfo, postProcessors, true);

            // Check context
            Assert.False(increContext.ShouldTraceIncrementalInfo);
            Assert.False(increContext.IsIncremental);

            increPostProcessorHandler = new PostProcessorsHandlerWithIncremental(PostProcessorsHandler, increContext);
            manifest     = JsonUtility.Deserialize <Manifest>("PostProcessors/Data/manifest_incremental.json");
            outputFolder = GetRandomFolder();
            PrepareOutput(outputFolder, "a", "b", "c");
            increPostProcessorHandler.Handle(postProcessors, manifest, outputFolder);

            // Check incremental flag
            Assert.True(manifest.Files.All(f => f.IsIncremental == false));

            // Check output content
            VerifyOutput(outputFolder, appendString, "a", "b", "c");

            // Check cached PostProcessInfo should be null
            Assert.Null(currentBuildInfo.PostProcessInfo);
        }
コード例 #6
0
        public void TestIncrementalBasicScenario()
        {
            var intermediateFolder = GetRandomFolder();
            var currentBuildInfo   = new BuildInfo
            {
                DirectoryName = IncrementalUtility.CreateRandomDirectory(intermediateFolder)
            };
            var lastBuildInfo = new BuildInfo
            {
                DirectoryName   = IncrementalUtility.CreateRandomDirectory(intermediateFolder),
                PostProcessInfo = new PostProcessInfo()
            };

            lastBuildInfo.PostProcessInfo.PostProcessorInfos.Add(new PostProcessorInfo
            {
                Name = typeof(AppendStringPostProcessor).Name
            });

            // Exclude c, which is not incremental
            var preparedManifest = JsonUtility.Deserialize <Manifest>("PostProcessors/Data/manifest_incremental.json");

            PrepareCachedOutput(intermediateFolder, lastBuildInfo, AppendStringPostProcessor.AppendString, preparedManifest.Files, AppendStringPostProcessor.AdditionalExtensionString, "a", "b");

            var postProcessors = GetPostProcessors(typeof(AppendStringPostProcessor));
            var increContext   = new IncrementalPostProcessorsContext(intermediateFolder, currentBuildInfo, lastBuildInfo, postProcessors, true);

            // Check context
            Assert.True(increContext.ShouldTraceIncrementalInfo);
            Assert.True(increContext.IsIncremental);

            var increPostProcessorHandler = new PostProcessorsHandlerWithIncremental(PostProcessorsHandler, increContext);
            var manifest     = JsonUtility.Deserialize <Manifest>("PostProcessors/Data/manifest_incremental.json");
            var outputFolder = GetRandomFolder();

            PrepareOutput(outputFolder, "a", "b", "c");
            increPostProcessorHandler.Handle(postProcessors, manifest, outputFolder);

            // Check incremental flag
            Assert.Equal(3, manifest.Files.Count);
            Assert.True(manifest.Files.Single(i => i.SourceRelativePath == "a.md").IsIncremental);
            Assert.True(manifest.Files.Single(i => i.SourceRelativePath == "b.md").IsIncremental);
            Assert.False(manifest.Files.Single(i => i.SourceRelativePath == "c.md").IsIncremental);
            foreach (var file in manifest.Files)
            {
                Assert.True(file.OutputFiles.ContainsKey(AppendStringPostProcessor.AdditionalExtensionString));
            }

            // Check output content
            VerifyOutput(outputFolder, AppendStringPostProcessor.AppendString, "a", "b", "c");

            // Check cached PostProcessInfo
            Assert.NotNull(currentBuildInfo.PostProcessInfo);

            var postProcessorInfos = currentBuildInfo.PostProcessInfo.PostProcessorInfos;

            Assert.Equal(1, currentBuildInfo.PostProcessInfo.PostProcessorInfos.Count);
            Assert.Equal($"{typeof(AppendStringPostProcessor).Name}", postProcessorInfos[0].Name);
            Assert.Null(postProcessorInfos[0].IncrementalContextHash);

            var postProcessOutputs = currentBuildInfo.PostProcessInfo.PostProcessOutputs;

            Assert.Equal(9, postProcessOutputs.Count);
            VerifyCachedOutput(Path.Combine(intermediateFolder, currentBuildInfo.DirectoryName), postProcessOutputs, AppendStringPostProcessor.AppendString, AppendStringPostProcessor.AdditionalExtensionString, "a", "b", "c");

            // Check incremental info
            Assert.Equal(1, manifest.IncrementalInfo.Count);
            Assert.Equal(true, manifest.IncrementalInfo[0].Status.CanIncremental);
            Assert.Equal(IncrementalPhase.PostProcessing, manifest.IncrementalInfo[0].Status.IncrementalPhase);
            Assert.Equal("Can support incremental post processing.", manifest.IncrementalInfo[0].Status.Details);
        }
コード例 #7
0
        public void TestIncrementalWithFirstCannotIncrementalButSecondCanIncremental()
        {
            //        | Should trace incremental info | Can incremental |
            // ---------------------------------------------------------
            // First  |               yes             |       no        |
            // Second |               yes             |       yes       |

            var          intermediateFolder = GetRandomFolder();
            const string phaseName          = PrependIncrementalPhaseName + "FirstCannotIncrementalButSecondCanIncremental";
            var          postProcessors     = GetPostProcessors(typeof(AppendStringPostProcessor), typeof(AppendIntegerPostProcessor));
            var          appendString       = $"{AppendStringPostProcessor.AppendString}{AppendIntegerPostProcessor.AppendInteger}";
            IncrementalPostProcessorsContext increContext = null;

            IncrementalActions
                (phaseName, () =>
            {
                // Step 1: trace intermediate info
                using (new LoggerPhaseScope(phaseName + "First"))
                {
                    var currentBuildInfo = new BuildInfo
                    {
                        DirectoryName = IncrementalUtility.CreateRandomDirectory(intermediateFolder)
                    };
                    increContext = new IncrementalPostProcessorsContext(intermediateFolder, currentBuildInfo, null, postProcessors, true);

                    // Check context
                    Assert.True(increContext.ShouldTraceIncrementalInfo);
                    Assert.False(increContext.IsIncremental);

                    var increPostProcessorHandler = new PostProcessorsHandlerWithIncremental(PostProcessorsHandler, increContext);
                    var manifest     = JsonUtility.Deserialize <Manifest>("PostProcessors/Data/manifest_incremental.json");
                    var outputFolder = GetRandomFolder();
                    PrepareOutput(outputFolder, "a", "b", "c");
                    increPostProcessorHandler.Handle(postProcessors, manifest, outputFolder);

                    // Check incremental flag
                    Assert.True(manifest.Files.All(f => f.IsIncremental == false));

                    // Check output content
                    VerifyOutput(outputFolder, appendString, "a", "b", "c");

                    // Check cached PostProcessInfo
                    Assert.NotNull(currentBuildInfo.PostProcessInfo);

                    var postProcessorInfos = currentBuildInfo.PostProcessInfo.PostProcessorInfos;
                    Assert.Equal(2, currentBuildInfo.PostProcessInfo.PostProcessorInfos.Count);
                    Assert.Equal($"{typeof(AppendStringPostProcessor).Name}", postProcessorInfos[0].Name);
                    Assert.Null(postProcessorInfos[0].IncrementalContextHash);
                    Assert.Equal($"{typeof(AppendIntegerPostProcessor).Name}", postProcessorInfos[1].Name);
                    Assert.Equal(AppendIntegerPostProcessor.HashValue, postProcessorInfos[1].IncrementalContextHash);
                    Assert.NotNull(postProcessorInfos[1].ContextInfoFile);
                    Assert.Equal(new List <string> {
                        "a.html", "b.html", "c.html"
                    },
                                 JsonUtility.Deserialize <List <string> >(Path.Combine(intermediateFolder, currentBuildInfo.DirectoryName, postProcessorInfos[1].ContextInfoFile)));

                    Assert.Equal(3, currentBuildInfo.PostProcessInfo.ManifestItems.Count);
                    Assert.Equal <ManifestItem>(manifest.Files, currentBuildInfo.PostProcessInfo.ManifestItems);

                    var postProcessOutputs = currentBuildInfo.PostProcessInfo.PostProcessOutputs;
                    Assert.Equal(9, postProcessOutputs.Count);
                    VerifyCachedOutput(Path.Combine(intermediateFolder, currentBuildInfo.DirectoryName), postProcessOutputs, appendString, AppendStringPostProcessor.AdditionalExtensionString, "a", "b", "c");

                    // Check log messages
                    var logs = Listener.Items.Where(i => i.Phase.StartsWith(phaseName)).ToList();
                    Assert.Equal(3, logs.Count);
                    Assert.True(logs.All(l => l.Message.Contains("is not in html format.")));
                }
            }, () =>
            {
                // Step 2: incremental post process
                using (new LoggerPhaseScope(phaseName + "Second"))
                {
                    var secondBuildInfo = new BuildInfo
                    {
                        DirectoryName = IncrementalUtility.CreateRandomDirectory(intermediateFolder)
                    };
                    var lastBuildInfo = new BuildInfo
                    {
                        DirectoryName   = Path.GetFileName(increContext.CurrentBaseDir),
                        PostProcessInfo = increContext.CurrentInfo
                    };
                    increContext = new IncrementalPostProcessorsContext(intermediateFolder, secondBuildInfo, lastBuildInfo, postProcessors, true);

                    // Check context
                    Assert.True(increContext.ShouldTraceIncrementalInfo);
                    Assert.True(increContext.IsIncremental);

                    var increPostProcessorHandler = new PostProcessorsHandlerWithIncremental(PostProcessorsHandler, increContext);
                    var manifest     = JsonUtility.Deserialize <Manifest>("PostProcessors/Data/manifest_incremental.json");
                    var outputFolder = GetRandomFolder();
                    PrepareOutput(outputFolder, "a", "b", "c");
                    increPostProcessorHandler.Handle(postProcessors, manifest, outputFolder);

                    // Check incremental flag
                    Assert.Equal(3, manifest.Files.Count);
                    Assert.True(manifest.Files.Single(i => i.SourceRelativePath == "a.md").IsIncremental);
                    Assert.True(manifest.Files.Single(i => i.SourceRelativePath == "b.md").IsIncremental);
                    Assert.False(manifest.Files.Single(i => i.SourceRelativePath == "c.md").IsIncremental);
                    foreach (var file in manifest.Files)
                    {
                        Assert.True(file.OutputFiles.ContainsKey(AppendStringPostProcessor.AdditionalExtensionString));
                    }

                    // Check output content
                    VerifyOutput(outputFolder, appendString, "a", "b", "c");

                    // Check cached PostProcessInfo
                    Assert.NotNull(secondBuildInfo.PostProcessInfo);

                    var postProcessorInfos = secondBuildInfo.PostProcessInfo.PostProcessorInfos;
                    Assert.Equal(2, secondBuildInfo.PostProcessInfo.PostProcessorInfos.Count);
                    Assert.Equal($"{typeof(AppendStringPostProcessor).Name}", postProcessorInfos[0].Name);
                    Assert.Null(postProcessorInfos[0].IncrementalContextHash);
                    Assert.Equal($"{typeof(AppendIntegerPostProcessor).Name}", postProcessorInfos[1].Name);
                    Assert.Equal(AppendIntegerPostProcessor.HashValue, postProcessorInfos[1].IncrementalContextHash);
                    Assert.NotNull(postProcessorInfos[1].ContextInfoFile);
                    Assert.Equal(new List <string> {
                        "a.html", "b.html", "c.html"
                    },
                                 JsonUtility.Deserialize <List <string> >(Path.Combine(intermediateFolder, secondBuildInfo.DirectoryName, postProcessorInfos[1].ContextInfoFile)));

                    Assert.Equal(3, secondBuildInfo.PostProcessInfo.ManifestItems.Count);
                    Assert.Equal <ManifestItem>(manifest.Files, secondBuildInfo.PostProcessInfo.ManifestItems);

                    var postProcessOutputs = secondBuildInfo.PostProcessInfo.PostProcessOutputs;
                    Assert.Equal(9, postProcessOutputs.Count);
                    VerifyCachedOutput(Path.Combine(intermediateFolder, secondBuildInfo.DirectoryName), postProcessOutputs, appendString, AppendStringPostProcessor.AdditionalExtensionString, "a", "b", "c");

                    // Check log messages
                    var logs = Listener.Items.Where(i => i.Phase.StartsWith(phaseName)).ToList();
                    Assert.Equal(3, logs.Count);
                    Assert.True(logs.All(l => l.Message.Contains("is not in html format.")));
                }
            });
        }