public void CacheLifetime() { const string ForceCaching = "MSBUILDDEBUGFORCECACHING"; FileUtilities.ClearCacheDirectory(); string forceCachingValue = Environment.GetEnvironmentVariable(ForceCaching); try { Environment.SetEnvironmentVariable(ForceCaching, "1"); string outerBuildCacheDirectory; string innerBuildCacheDirectory; // Do a build with one build manager. using (var outerBuildManager = new BuildManager()) { outerBuildCacheDirectory = BuildAndCheckCache(outerBuildManager, new string[] { }); // Do another build with a second build manager while the first still exists. Since both BuildManagers // share a process-wide cache directory, we want to verify that they don't stomp on each other, either // by accidentally sharing results, or by clearing them away. using (var innerBuildManager = new BuildManager()) { innerBuildCacheDirectory = BuildAndCheckCache(innerBuildManager, new string[] { outerBuildCacheDirectory }); // Force the cache for this build manager (and only this build manager) to be cleared. It should leave // behind the results from the other one. innerBuildManager.ResetCaches(); } Assert.IsFalse(Directory.Exists(innerBuildCacheDirectory), "Inner build cache directory still exists after inner build manager was disposed."); Assert.IsTrue(Directory.Exists(outerBuildCacheDirectory), "Outer build cache directory doesn't exist after inner build manager was disposed."); // Force the cache for this build manager to be cleared. outerBuildManager.ResetCaches(); } Assert.IsFalse(Directory.Exists(outerBuildCacheDirectory), "Outer build cache directory still exists after outer build manager was disposed."); } finally { Environment.SetEnvironmentVariable(ForceCaching, forceCachingValue); } }
/// <summary> /// Builds the specified target and returns the build result. /// </summary> /// <param name="project">The project to build</param> /// <param name="logger">The build logger to use. If null then a default logger will be used that dumps the build output to the console.</param> /// <param name="targets">Optional list of targets to execute</param> public static BuildResult BuildTargets(ProjectInstance projectInstance, ILogger logger, params string[] targets) { if (projectInstance == null) { throw new ArgumentNullException("projectInstance"); } if (logger == null) { throw new ArgumentNullException("logger"); } BuildParameters parameters = new BuildParameters(); parameters.Loggers = new ILogger[] { logger ?? new BuildLogger() }; parameters.UseSynchronousLogging = true; parameters.ShutdownInProcNodeOnBuildFinish = true; // required, other we can get an "Attempted to access an unloaded AppDomain" exception when the test finishes. BuildRequestData requestData = new BuildRequestData(projectInstance, targets); BuildResult result = null; BuildManager mgr = new BuildManager(); try { result = mgr.Build(parameters, requestData); result.ProjectStateAfterBuild = projectInstance; BuildUtilities.DumpProjectProperties(projectInstance, "Project properties post-build"); } finally { mgr.ShutdownAllNodes(); mgr.ResetCaches(); mgr.Dispose(); } return result; }
public void ResetCachesDuringBuildIsInvalid () { // Windows does not have useful sleep or alternative, so skip it bool is_windows = true; switch (Environment.OSVersion.Platform) { case PlatformID.Unix: case PlatformID.MacOSX: is_windows = false; break; } string project_xml = string.Format (@"<Project DefaultTargets='Wait1Sec' xmlns='http://schemas.microsoft.com/developer/msbuild/2003'> <Target Name='Wait1Sec'> <Exec Command='{0}' /> </Target> </Project>", is_windows ? "powershell -command \"Start-Sleep -s 1\"" : "/bin/sleep 1"); var xml = XmlReader.Create (new StringReader (project_xml)); var root = ProjectRootElement.Create (xml); var proj = new ProjectInstance (root); var bm = new BuildManager (); bm.BeginBuild (new BuildParameters ()); var sub = bm.PendBuildRequest (new BuildRequestData (proj, new string [] { "Wait1Sec" })); sub.ExecuteAsync (delegate {}, null); try { bm.ResetCaches (); } finally { bm.EndBuild (); // yes, it should work even after invalid ResetCaches call... at least on .NET it does. } }