forked from dotnet/android
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[Xamarin.Android.Build.Tasks] cache java -version output (dotnet#1938)
Context: https://github.com/Microsoft/msbuild/blob/f147a76a60bf9e516800f65f9614c914df0a4f15/src/Framework/IBuildEngine4.cs#L34-L84 Context: https://github.com/xamarin/Xamarin.Forms/blob/42c07d1ae5aa56eb574b7d169499f1a9af7ec080/Xamarin.Forms.ControlGallery.Android/Xamarin.Forms.ControlGallery.Android.csproj The new `<ValidateJavaVersion/>` MSBuild task (93ddf96) gets invoked for *every* project on *every* build, even if nothing changed. Unfortunately, this task also takes around 250ms to run, since it shells out to `java -version` and `javac -version`. We can use MSBuild's `GetRegisteredTaskObject()` and `RegisterTaskObject()` to cache the output of running these command line tools. If we key with the full path to `java` or `javac`, the cache should be properly invalidated if a different `$(JavaSdkDirectory)` value is passed in. I added a new set of `ValidateJavaVersionTests` to directly test this caching functionality, plus a couple smoke tests. In the case of `Xamarin.Forms.ControlGallery.Android`: - `<ValidateJavaVersion/>` runs 7 times - A build (with no changes) went from 12.820s to 11.185s, saving ~1.635s of build time - I also tested the changes in VS Windows, and was able to see logs indicating the value is cached. Improvements to `MockBuildEngine`: - General code formatting / refactoring - Added a `Messages` list that can be asserted against - Refactored the `Task` APIs so that they are fully functional Other changes: - Since `BaseTest` now has a `SetUp` class, we can't have a method named `SetUp` or we get a warning. I used a `Setup` method (with lowercase u) instead, and modified `KeyToolTests` to fix this warning.
- Loading branch information
1 parent
c4fab7c
commit 4a5dd01
Showing
5 changed files
with
188 additions
and
42 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
121 changes: 121 additions & 0 deletions
121
...n.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/Tasks/ValidateJavaVersionTests.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,121 @@ | ||
using Microsoft.Build.Framework; | ||
using NUnit.Framework; | ||
using System.Collections.Generic; | ||
using System.IO; | ||
using System.Linq; | ||
using Xamarin.Android.Tasks; | ||
|
||
namespace Xamarin.Android.Build.Tests | ||
{ | ||
[TestFixture] | ||
public class ValidateJavaVersionTests : BaseTest | ||
{ | ||
string path; | ||
List<BuildErrorEventArgs> errors; | ||
List<BuildMessageEventArgs> messages; | ||
MockBuildEngine engine; | ||
|
||
[SetUp] | ||
public void Setup () | ||
{ | ||
path = Path.Combine ("temp", TestName); | ||
engine = new MockBuildEngine (TestContext.Out, | ||
errors: errors = new List<BuildErrorEventArgs> (), | ||
messages: messages = new List<BuildMessageEventArgs> ()); | ||
|
||
//Setup statics on MonoAndroidHelper | ||
var referencePath = CreateFauxReferencesDirectory (Path.Combine (path, "references"), new [] { | ||
new ApiInfo { Id = "27", Level = 27, Name = "Oreo", FrameworkVersion = "v8.1", Stable = true }, | ||
}); | ||
MonoAndroidHelper.RefreshSupportedVersions (new [] { | ||
Path.Combine (referencePath, "MonoAndroid"), | ||
}); | ||
} | ||
|
||
[TearDown] | ||
public void TearDown () | ||
{ | ||
Directory.Delete (Path.Combine (Root, path), recursive: true); | ||
} | ||
|
||
[Test] | ||
public void TargetFramework8_1_Requires_1_8_0 () | ||
{ | ||
var javaPath = CreateFauxJavaSdkDirectory (Path.Combine (path, "jdk"), "1.7.0", out string javaExe, out string javacExe); | ||
var validateJavaVersion = new ValidateJavaVersion { | ||
BuildEngine = engine, | ||
TargetFrameworkVersion = "v8.1", | ||
JavaSdkPath = javaPath, | ||
JavaToolExe = javaExe, | ||
JavacToolExe = javacExe, | ||
LatestSupportedJavaVersion = "1.8.0", | ||
MinimumSupportedJavaVersion = "1.7.0", | ||
}; | ||
Assert.False (validateJavaVersion.Execute (), "Execute should *not* succeed!"); | ||
Assert.IsTrue (errors.Any (e => e.Message == $"Java SDK 1.8 or above is required when targeting FrameworkVersion {validateJavaVersion.TargetFrameworkVersion}."), "Should get error about TargetFrameworkVersion=v8.1"); | ||
} | ||
|
||
[Test] | ||
public void BuildTools27_Requires_1_8_0 () | ||
{ | ||
var javaPath = CreateFauxJavaSdkDirectory (Path.Combine (path, "jdk"), "1.7.0", out string javaExe, out string javacExe); | ||
var validateJavaVersion = new ValidateJavaVersion { | ||
BuildEngine = engine, | ||
AndroidSdkBuildToolsVersion = "27.0.0", | ||
JavaSdkPath = javaPath, | ||
JavaToolExe = javaExe, | ||
JavacToolExe = javacExe, | ||
LatestSupportedJavaVersion = "1.8.0", | ||
MinimumSupportedJavaVersion = "1.7.0", | ||
}; | ||
Assert.False (validateJavaVersion.Execute (), "Execute should *not* succeed!"); | ||
Assert.IsTrue (errors.Any (e => e.Message == $"Java SDK 1.8 or above is required when using build-tools {validateJavaVersion.AndroidSdkBuildToolsVersion}."), "Should get error about build-tools=27.0.0"); | ||
} | ||
|
||
[Test] | ||
public void CacheWorks () | ||
{ | ||
var javaPath = CreateFauxJavaSdkDirectory (Path.Combine (path, "jdk"), "1.8.0", out string javaExe, out string javacExe); | ||
var validateJavaVersion = new ValidateJavaVersion { | ||
BuildEngine = engine, | ||
JavaSdkPath = javaPath, | ||
JavaToolExe = javaExe, | ||
JavacToolExe = javacExe, | ||
LatestSupportedJavaVersion = "1.8.0", | ||
MinimumSupportedJavaVersion = "1.7.0", | ||
}; | ||
Assert.IsTrue (validateJavaVersion.Execute (), "first Execute should succeed!"); | ||
|
||
messages.Clear (); | ||
|
||
Assert.IsTrue (validateJavaVersion.Execute (), "second Execute should succeed!"); | ||
var javaFullPath = Path.Combine (javaPath, "bin", javaExe); | ||
var javacFullPath = Path.Combine (javaPath, "bin", javacExe); | ||
Assert.IsTrue (messages.Any (m => m.Message == $"Using cached value for `{javaFullPath} -version`: 1.8.0"), "`java -version` should be cached!"); | ||
Assert.IsTrue (messages.Any (m => m.Message == $"Using cached value for `{javacFullPath} -version`: 1.8.0"), "`javac -version` should be cached!"); | ||
} | ||
|
||
[Test] | ||
public void CacheInvalidates () | ||
{ | ||
var javaPath = CreateFauxJavaSdkDirectory (Path.Combine (path, "jdk-1"), "1.8.0", out string javaExe, out string javacExe); | ||
var validateJavaVersion = new ValidateJavaVersion { | ||
BuildEngine = engine, | ||
JavaSdkPath = javaPath, | ||
JavaToolExe = javaExe, | ||
JavacToolExe = javacExe, | ||
LatestSupportedJavaVersion = "1.8.0", | ||
MinimumSupportedJavaVersion = "1.7.0", | ||
}; | ||
Assert.IsTrue (validateJavaVersion.Execute (), "first Execute should succeed!"); | ||
|
||
messages.Clear (); | ||
|
||
javaPath = CreateFauxJavaSdkDirectory (Path.Combine (path, "jdk-2"), "1.8.0", out javaExe, out javacExe); | ||
validateJavaVersion.JavaSdkPath = javaPath; | ||
|
||
Assert.IsTrue (validateJavaVersion.Execute (), "second Execute should succeed!"); | ||
Assert.IsFalse (messages.Any (m => m.Message.StartsWith ("Using cached value for")), "`java -version` should *not* be cached!"); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters