dotnet-installer/test/dotnet-compile.UnitTests/GivenACompilationDriver.cs
Andrew Stanton-Nurse ef0ca39da1 Memory usage improvements in build (#2626)
* Use a WorkspaceContext in dotnet-build to cache project data across
multiple compilations in a single build action
* Dramatically reduce string and object duplication by introducing a
"Symbol Table" that shares instances of NuGetVersion, NuGetFramework,
VersionRange and string across multiple lock-file parses

Test Results:
* Testing was done by compiling Microsoft.AspNetCore.Mvc (and it's
dependencies) and taking memory snapshots after each compilation in
dotMemory
* We used to allocate ~3MB and deallocate ~2.5MB on EACH compilation in
a single build action. This has been reduced to ~120KB
allocated/deallocated
* After introducing WorkspaceContext, total memory usage spiked from 6MB
across the whole build action to about 13MB, introducing the symbol
table dropped it back to about 5-6MB.
2016-04-22 15:01:56 -07:00

85 lines
3.4 KiB
C#

// Copyright (c) .NET Foundation and contributors. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
using System;
using System.Collections.Generic;
using System.IO;
using FluentAssertions;
using Microsoft.DotNet.ProjectModel;
using Microsoft.DotNet.Tools.Compiler;
using Moq;
using NuGet.Frameworks;
using Xunit;
namespace Microsoft.DotNet.Tools.Compiler.Tests
{
public class GivenACompilationDriverController
{
private string _projectJson;
private Mock<ICompiler> _managedCompilerMock;
private Mock<ICompiler> _nativeCompilerMock;
private List<ProjectContext> _contexts;
private BuildCommandApp _args;
private readonly WorkspaceContext _workspace;
public GivenACompilationDriverController()
{
_projectJson =
Path.Combine(AppContext.BaseDirectory, "TestAssets", "TestProjects", "TestAppWithLibrary", "TestApp", "project.json");
_managedCompilerMock = new Mock<ICompiler>();
_managedCompilerMock.Setup(c => c
.Compile(It.IsAny<ProjectContext>(), It.IsAny<BuildCommandApp>()))
.Returns(true);
_nativeCompilerMock = new Mock<ICompiler>();
_nativeCompilerMock.Setup(c => c
.Compile(It.IsAny<ProjectContext>(), It.IsAny<BuildCommandApp>()))
.Returns(true);
_workspace = WorkspaceContext.Create(ProjectReaderSettings.ReadFromEnvironment(), designTime: false);
_contexts = new List<ProjectContext>
{
_workspace.GetProjectContext(_projectJson, NuGetFramework.Parse("netcoreapp1.0"))
};
_args = new BuildCommandApp("dotnet compile", ".NET Compiler", "Compiler for the .NET Platform", WorkspaceContext.Create(designTime: false));
}
[Fact]
public void It_compiles_all_project_contexts()
{
var compiledProjectContexts = new List<ProjectContext>();
_managedCompilerMock.Setup(c => c
.Compile(It.IsAny<ProjectContext>(), It.IsAny<BuildCommandApp>()))
.Callback<ProjectContext, BuildCommandApp>((p, c) => compiledProjectContexts.Add(p))
.Returns(true);
var compilerController = new CompilationDriver(_managedCompilerMock.Object, _nativeCompilerMock.Object);
compilerController.Compile(_contexts, _args);
compiledProjectContexts.Should().BeEquivalentTo(_contexts);
}
[Fact]
public void It_does_not_compile_native_when_the_native_parameter_is_not_passed()
{
var compilerController = new CompilationDriver(_managedCompilerMock.Object, _nativeCompilerMock.Object);
compilerController.Compile(_contexts, _args);
_nativeCompilerMock.Verify(c => c.Compile(It.IsAny<ProjectContext>(), It.IsAny<BuildCommandApp>()), Times.Never);
}
[Fact]
public void It_does_compile_native_when_the_native_parameter_is_passed()
{
var compilerController = new CompilationDriver(_managedCompilerMock.Object, _nativeCompilerMock.Object);
_args.IsNativeValue = true;
compilerController.Compile(_contexts, _args);
_nativeCompilerMock.Verify(c => c.Compile(It.IsAny<ProjectContext>(), It.IsAny<BuildCommandApp>()), Times.Once);
}
}
}