Skip to content

Commit 0de3135

Browse files
authored
[MSBuildDeviceIntegration] Give each test a unique package name (#5551)
One of the problems we occasionally see on CI is when two tests run at the same time on the same emulator. This can cause collisions and cause tests to fail because the app was changed while the test was running. Currently ALL of the tests user `UnnamedProject.UnnamedProject` as a package name. This means they overwrite each other. Introduce a new system which will auto generate a package name based on the test name itself. We do this by using the [`[CallerMemberNameAttribute]`][0] attribute to determine the name of the method which called the constructor of `XamarinAndroidApplicationProject`. This is then used to construct a unique (ish) package name in the form `com.xamarin.<TestMethodName>`. This should reduce collisions. As part of the process we also register each `packageName` used with a static cache. We then uninstall those from the device when the `[OneTimeTearDown]` method is called. This means the device will be cleaned as groups of tests are run. [0]: https://docs.microsoft.com/dotnet/api/system.runtime.compilerservices.callermembernameattribute
1 parent 1dbda0f commit 0de3135

26 files changed

+112
-74
lines changed

src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/AndroidUpdateResourcesTest.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1247,7 +1247,7 @@ public void CustomViewAddResourceId ([Values (false, true)] bool useAapt2)
12471247
b.Output.IsTargetSkipped ("_FixupCustomViewsForAapt2"),
12481248
"The target _FixupCustomViewsForAapt2 should have been skipped");
12491249
}
1250-
var r_java = Path.Combine (Root, b.ProjectDirectory, proj.IntermediateOutputPath, "android", "src", "unnamedproject", "unnamedproject", "R.java");
1250+
var r_java = Path.Combine (Root, b.ProjectDirectory, proj.IntermediateOutputPath, "android", "src", proj.PackageNameJavaIntermediatePath, "R.java");
12511251
FileAssert.Exists (r_java);
12521252
var r_java_contents = File.ReadAllLines (r_java);
12531253
Assert.IsTrue (StringAssertEx.ContainsText (r_java_contents, textView1), $"android/support/compat/R.java should contain `{textView1}`!");

src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/AotTests.cs

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,7 @@ public void BuildAotApplicationAndÜmläüts (string supportedAbis, bool enableL
118118
IsRelease = true,
119119
BundleAssemblies = false,
120120
AotAssemblies = true,
121+
PackageName = "com.xamarin.buildaotappwithspecialchars",
121122
};
122123
proj.SetProperty (KnownProperties.TargetFrameworkVersion, "v5.1");
123124
proj.SetAndroidSupportedAbis (supportedAbis);
@@ -166,14 +167,14 @@ public void BuildAotApplicationAndÜmläüts (string supportedAbis, bool enableL
166167
"aot", abi, "libaot-UnnamedProject.dll.so");
167168
Assert.IsTrue (File.Exists (assemblies), "{0} libaot-UnnamedProject.dll.so does not exist", abi);
168169
var apk = Path.Combine (Root, b.ProjectDirectory,
169-
proj.IntermediateOutputPath, "android", "bin", "UnnamedProject.UnnamedProject.apk");
170+
proj.IntermediateOutputPath, "android", "bin", $"{proj.PackageName}.apk");
170171
using (var zipFile = ZipHelper.OpenZip (apk)) {
171172
Assert.IsNotNull (ZipHelper.ReadFileFromZip (zipFile,
172173
string.Format ("lib/{0}/libaot-UnnamedProject.dll.so", abi)),
173-
"lib/{0}/libaot-UnnamedProject.dll.so should be in the UnnamedProject.UnnamedProject.apk", abi);
174+
$"lib/{0}/libaot-UnnamedProject.dll.so should be in the {proj.PackageName}.apk", abi);
174175
Assert.IsNotNull (ZipHelper.ReadFileFromZip (zipFile,
175176
"assemblies/UnnamedProject.dll"),
176-
"UnnamedProject.dll should be in the UnnamedProject.UnnamedProject.apk");
177+
$"UnnamedProject.dll should be in the {proj.PackageName}.apk");
177178
}
178179
}
179180
Assert.AreEqual (expectedResult, b.Build (proj), "Second Build should have {0}.", expectedResult ? "succeeded" : "failed");
@@ -196,6 +197,7 @@ public void BuildAotApplicationAndBundleAndÜmläüts (string supportedAbis, boo
196197
IsRelease = true,
197198
BundleAssemblies = true,
198199
AotAssemblies = true,
200+
PackageName = "com.xamarin.buildaotappandbundlewithspecialchars",
199201
};
200202
proj.SetProperty (KnownProperties.TargetFrameworkVersion, "v5.1");
201203
proj.SetAndroidSupportedAbis (supportedAbis);
@@ -217,14 +219,14 @@ public void BuildAotApplicationAndBundleAndÜmläüts (string supportedAbis, boo
217219
"aot", abi, "libaot-UnnamedProject.dll.so");
218220
Assert.IsTrue (File.Exists (assemblies), "{0} libaot-UnnamedProject.dll.so does not exist", abi);
219221
var apk = Path.Combine (Root, b.ProjectDirectory,
220-
proj.IntermediateOutputPath, "android", "bin", "UnnamedProject.UnnamedProject.apk");
222+
proj.IntermediateOutputPath, "android", "bin", $"{proj.PackageName}.apk");
221223
using (var zipFile = ZipHelper.OpenZip (apk)) {
222224
Assert.IsNotNull (ZipHelper.ReadFileFromZip (zipFile,
223225
string.Format ("lib/{0}/libaot-UnnamedProject.dll.so", abi)),
224-
"lib/{0}/libaot-UnnamedProject.dll.so should be in the UnnamedProject.UnnamedProject.apk", abi);
226+
$"lib/{0}/libaot-UnnamedProject.dll.so should be in the {proj.PackageName}.apk", abi);
225227
Assert.IsNull (ZipHelper.ReadFileFromZip (zipFile,
226228
"assemblies/UnnamedProject.dll"),
227-
"UnnamedProject.dll should not be in the UnnamedProject.UnnamedProject.apk");
229+
$"UnnamedProject.dll should not be in the {proj.PackageName}.apk");
228230
}
229231
}
230232
Assert.AreEqual (expectedResult, b.Build (proj), "Second Build should have {0}.", expectedResult ? "succeeded" : "failed");

src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/BuildAssetsTest.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ public void CheckAssetsAreIncludedInAPK ([Values (true, false)] bool useAapt2)
9494
Encoding = Encoding.ASCII,
9595
},
9696
new AndroidItem.AndroidAsset ("Assets\\subfolder\\") {
97-
97+
9898
},
9999
new AndroidItem.AndroidAsset ("Assets\\subfolder\\asset4.txt") {
100100
TextContent = () => "Asset4",
@@ -113,7 +113,7 @@ public void CheckAssetsAreIncludedInAPK ([Values (true, false)] bool useAapt2)
113113
Assert.IsTrue (libb.Build (libproj), "{0} should have built successfully.", libproj.ProjectName);
114114
using (var b = CreateApkBuilder (Path.Combine (projectPath, proj.ProjectName))) {
115115
Assert.IsTrue (b.Build (proj), "{0} should have built successfully.", proj.ProjectName);
116-
using (var apk = ZipHelper.OpenZip (Path.Combine (Root, b.ProjectDirectory, proj.IntermediateOutputPath, "android", "bin", "UnnamedProject.UnnamedProject.apk"))) {
116+
using (var apk = ZipHelper.OpenZip (Path.Combine (Root, b.ProjectDirectory, proj.IntermediateOutputPath, "android", "bin", $"{proj.PackageName}.apk"))) {
117117
foreach (var a in libproj.OtherBuildItems.Where (x => x is AndroidItem.AndroidAsset)) {
118118
var item = a.Include ().ToLower ().Replace ("\\", "/");
119119
if (item.EndsWith ("/"))

src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/BuildTest.cs

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -994,14 +994,14 @@ public void BuildMkBundleApplicationRelease ()
994994
"bundles", "armeabi-v7a", "libmonodroid_bundle_app.so");
995995
Assert.IsTrue (File.Exists (libapp), "libmonodroid_bundle_app.so does not exist");
996996
var apk = Path.Combine (Root, b.ProjectDirectory,
997-
proj.IntermediateOutputPath, "android", "bin", "UnnamedProject.UnnamedProject.apk");
997+
proj.IntermediateOutputPath, "android", "bin", $"{proj.PackageName}.apk");
998998
using (var zipFile = ZipHelper.OpenZip (apk)) {
999999
Assert.IsNotNull (ZipHelper.ReadFileFromZip (zipFile,
10001000
"lib/armeabi-v7a/libmonodroid_bundle_app.so"),
1001-
"lib/armeabi-v7a/libmonodroid_bundle_app.so should be in the UnnamedProject.UnnamedProject.apk");
1001+
$"lib/armeabi-v7a/libmonodroid_bundle_app.so should be in the {proj.PackageName}.apk");
10021002
Assert.IsNull (ZipHelper.ReadFileFromZip (zipFile,
10031003
Path.Combine ("assemblies", "UnnamedProject.dll")),
1004-
"UnnamedProject.dll should not be in the UnnamedProject.UnnamedProject.apk");
1004+
$"UnnamedProject.dll should not be in the {proj.PackageName}.apk");
10051005
}
10061006
}
10071007
}
@@ -1022,14 +1022,14 @@ public void BuildMkBundleApplicationReleaseAllAbi ()
10221022
"bundles", abi, "libmonodroid_bundle_app.so");
10231023
Assert.IsTrue (File.Exists (libapp), abi + " libmonodroid_bundle_app.so does not exist");
10241024
var apk = Path.Combine (Root, b.ProjectDirectory,
1025-
proj.IntermediateOutputPath, "android", "bin", "UnnamedProject.UnnamedProject.apk");
1025+
proj.IntermediateOutputPath, "android", "bin", $"{proj.PackageName}.apk");
10261026
using (var zipFile = ZipHelper.OpenZip (apk)) {
10271027
Assert.IsNotNull (ZipHelper.ReadFileFromZip (zipFile,
10281028
"lib/" + abi + "/libmonodroid_bundle_app.so"),
1029-
"lib/{0}/libmonodroid_bundle_app.so should be in the UnnamedProject.UnnamedProject.apk", abi);
1029+
$"lib/{0}/libmonodroid_bundle_app.so should be in the {proj.PackageName}.apk", abi);
10301030
Assert.IsNull (ZipHelper.ReadFileFromZip (zipFile,
10311031
Path.Combine ("assemblies", "UnnamedProject.dll")),
1032-
"UnnamedProject.dll should not be in the UnnamedProject.UnnamedProject.apk");
1032+
$"UnnamedProject.dll should not be in the {proj.PackageName}.apk");
10331033
}
10341034
}
10351035
}
@@ -1170,7 +1170,7 @@ public void BuildAfterMultiDexIsNotRequired ([Values ("dx", "d8")] string dexToo
11701170
using (var b = CreateApkBuilder ()) {
11711171
string intermediateDir = Path.Combine (Root, b.ProjectDirectory, proj.IntermediateOutputPath);
11721172
string androidBinDir = Path.Combine (intermediateDir, "android", "bin");
1173-
string apkPath = Path.Combine (androidBinDir, "UnnamedProject.UnnamedProject.apk");
1173+
string apkPath = Path.Combine (androidBinDir, $"{proj.PackageName}.apk");
11741174

11751175
Assert.IsTrue (b.Build (proj), "Build should have succeeded.");
11761176
FileAssert.Exists (Path.Combine (androidBinDir, "classes.dex"));
@@ -1902,7 +1902,7 @@ public void CheckWhichRuntimeIsIncluded (string supportedAbi, bool debugSymbols,
19021902
var runtimeInfo = b.GetSupportedRuntimes ();
19031903
Assert.IsTrue (b.Build (proj), "Build should have succeeded.");
19041904
var apkPath = Path.Combine (Root, b.ProjectDirectory,
1905-
proj.IntermediateOutputPath,"android", "bin", "UnnamedProject.UnnamedProject.apk");
1905+
proj.IntermediateOutputPath,"android", "bin", $"{proj.PackageName}.apk");
19061906
using (var apk = ZipHelper.OpenZip (apkPath)) {
19071907
var runtime = runtimeInfo.FirstOrDefault (x => x.Abi == supportedAbi && x.Runtime == expectedRuntime);
19081908
Assert.IsNotNull (runtime, "Could not find the expected runtime.");
@@ -1946,13 +1946,13 @@ public void CheckSequencePointGeneration (bool isRelease, bool monoSymbolArchive
19461946
Assert.Ignore ("Cross compiler was not available");
19471947
Assert.IsTrue (b.Build (proj), "Build should have succeeded.");
19481948
var apk = Path.Combine (Root, b.ProjectDirectory,
1949-
proj.IntermediateOutputPath, "android", "bin", "UnnamedProject.UnnamedProject.apk");
1949+
proj.IntermediateOutputPath, "android", "bin", $"{proj.PackageName}.apk");
19501950
var msymarchive = Path.Combine (Root, b.ProjectDirectory, proj.OutputPath, proj.PackageName + ".apk.mSYM");
19511951
using (var zipFile = ZipHelper.OpenZip (apk)) {
19521952
var mdbExits = ZipHelper.ReadFileFromZip (zipFile, "assemblies/UnnamedProject.dll.mdb") != null ||
19531953
ZipHelper.ReadFileFromZip (zipFile, "assemblies/UnnamedProject.pdb") != null;
19541954
Assert.AreEqual (embedMdb, mdbExits,
1955-
"assemblies/UnnamedProject.dll.mdb or assemblies/UnnamedProject.pdb should{0}be in the UnnamedProject.UnnamedProject.apk", embedMdb ? " " : " not ");
1955+
$"assemblies/UnnamedProject.dll.mdb or assemblies/UnnamedProject.pdb should{0}be in the {proj.PackageName}.apk", embedMdb ? " " : " not ");
19561956
if (aotAssemblies) {
19571957
foreach (var abi in abis) {
19581958
var assemblies = Path.Combine (Root, b.ProjectDirectory, proj.IntermediateOutputPath,
@@ -1971,10 +1971,10 @@ public void CheckSequencePointGeneration (bool isRelease, bool monoSymbolArchive
19711971
Assert.IsTrue (File.Exists (assemblies), "{0} libaot-UnnamedProject.dll.so does not exist", abi);
19721972
Assert.IsNotNull (ZipHelper.ReadFileFromZip (zipFile,
19731973
string.Format ("lib/{0}/libaot-UnnamedProject.dll.so", abi)),
1974-
"lib/{0}/libaot-UnnamedProject.dll.so should be in the UnnamedProject.UnnamedProject.apk", abi);
1974+
$"lib/{0}/libaot-UnnamedProject.dll.so should be in the {proj.PackageName}.apk", abi);
19751975
Assert.IsNotNull (ZipHelper.ReadFileFromZip (zipFile,
19761976
"assemblies/UnnamedProject.dll"),
1977-
"UnnamedProject.dll should be in the UnnamedProject.UnnamedProject.apk");
1977+
$"UnnamedProject.dll should be in the {proj.PackageName}.apk");
19781978
}
19791979
}
19801980
var runtimeInfo = b.GetSupportedRuntimes ();
@@ -2062,7 +2062,7 @@ public void BuildWithNativeLibraries ([Values (true, false)] bool isRelease)
20622062
using (var builder = CreateApkBuilder (Path.Combine (path, proj.ProjectName))) {
20632063
Assert.IsTrue (builder.Build (proj), "Build should have succeeded.");
20642064
var apk = Path.Combine (Root, builder.ProjectDirectory,
2065-
proj.IntermediateOutputPath, "android", "bin", "UnnamedProject.UnnamedProject.apk");
2065+
proj.IntermediateOutputPath, "android", "bin", $"{proj.PackageName}.apk");
20662066
Assert.IsTrue (StringAssertEx.ContainsText (builder.LastBuildOutput, "warning XA4301: APK already contains the item lib/armeabi-v7a/libRSSupport.so; ignoring."),
20672067
"warning about skipping libRSSupport.so should have been raised");
20682068
using (var zipFile = ZipHelper.OpenZip (apk)) {
@@ -2259,7 +2259,7 @@ public void ApplicationIdPlaceholder ()
22592259
var manifest = XDocument.Load (Path.Combine (Root, builder.ProjectDirectory, "obj", "Debug", "android", "AndroidManifest.xml"));
22602260
var namespaceResolver = new XmlNamespaceManager (new NameTable ());
22612261
namespaceResolver.AddNamespace ("android", "http://schemas.android.com/apk/res/android");
2262-
var element = manifest.XPathSelectElement ("/manifest/application/provider[@android:name='UnnamedProject.UnnamedProject']", namespaceResolver);
2262+
var element = manifest.XPathSelectElement ($"/manifest/application/provider[@android:name='{proj.PackageName}']", namespaceResolver);
22632263
Assert.IsNotNull (element, "placeholder not replaced");
22642264
}
22652265
}
@@ -2279,7 +2279,7 @@ public void ExtraAaptManifest ()
22792279
builder.Target = "Build";
22802280
Assert.IsTrue (builder.Build (proj), "Build should have succeeded.");
22812281
var manifest = File.ReadAllText (Path.Combine (Root, builder.ProjectDirectory, "obj", "Debug", "android", "AndroidManifest.xml"));
2282-
Assert.IsTrue (manifest.Contains ("android:authorities=\"UnnamedProject.UnnamedProject.crashlyticsinitprovider\""), "placeholder not replaced");
2282+
Assert.IsTrue (manifest.Contains ($"android:authorities=\"{proj.PackageName}.crashlyticsinitprovider\""), "placeholder not replaced");
22832283
Assert.IsFalse (manifest.Contains ("dollar_openBracket_applicationId_closeBracket"), "`aapt/AndroidManifest.xml` not ignored");
22842284
}
22852285
}
@@ -2577,7 +2577,7 @@ public void BuildReleaseApplicationWithNugetPackages ()
25772577
StringAssert.Contains ("Xamarin.Android.Support.v4", assets,
25782578
"Nuget Package Xamarin.Android.Support.v4.21.0.3.0 should have been restored.");
25792579
var src = Path.Combine (Root, b.ProjectDirectory, proj.IntermediateOutputPath, "android", "src");
2580-
var main_r_java = Path.Combine (src, "unnamedproject", "unnamedproject", "R.java");
2580+
var main_r_java = Path.Combine (src, proj.PackageNameJavaIntermediatePath, "R.java");
25812581
FileAssert.Exists (main_r_java);
25822582
var lib_r_java = Path.Combine (src, "android", "support", "compat", "R.java");
25832583
FileAssert.Exists (lib_r_java);
@@ -2815,7 +2815,7 @@ public void BuildBasicApplicationCheckPdb ()
28152815
File.Exists (Path.Combine (Root, b.ProjectDirectory, proj.IntermediateOutputPath, "android", "assets", "NetStandard16.pdb")),
28162816
"NetStandard16.pdb must be copied to Intermediate directory");
28172817
var apk = Path.Combine (Root, b.ProjectDirectory,
2818-
proj.IntermediateOutputPath, "android", "bin", "UnnamedProject.UnnamedProject.apk");
2818+
proj.IntermediateOutputPath, "android", "bin", $"{proj.PackageName}.apk");
28192819
using (var zipFile = ZipHelper.OpenZip (apk)) {
28202820
Assert.IsNotNull (ZipHelper.ReadFileFromZip (zipFile,
28212821
"assemblies/NetStandard16.pdb"),
@@ -3962,7 +3962,7 @@ public void KotlinServiceLoader ([Values ("apk", "aab")] string packageFormat)
39623962
using (var b = CreateApkBuilder ()) {
39633963
Assert.IsTrue (b.Build (proj), "build should have succeeded.");
39643964
var archive = Path.Combine (Root, b.ProjectDirectory,
3965-
proj.IntermediateOutputPath, "android", "bin", $"UnnamedProject.UnnamedProject.{packageFormat}");
3965+
proj.IntermediateOutputPath, "android", "bin", $"{proj.PackageName}.{packageFormat}");
39663966
var prefix = packageFormat == "apk" ? "" : "base/root/";
39673967
var expectedFiles = new [] {
39683968
prefix + "META-INF/maven/com.google.code.gson/gson/pom.xml",

src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/EnvironmentContentTests.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -248,7 +248,7 @@ public void BuildWithTlsProvider (string androidTlsProvider, bool isRelease, boo
248248
proj.SetProperty ("AndroidTlsProvider", androidTlsProvider);
249249
Assert.IsTrue (b.Build (proj), "Build should have succeeded.");
250250
var intermediateOutputDir = Path.Combine (Root, b.ProjectDirectory, proj.IntermediateOutputPath);
251-
var apk = Path.Combine (intermediateOutputDir, "android", "bin", "UnnamedProject.UnnamedProject.apk");
251+
var apk = Path.Combine (intermediateOutputDir, "android", "bin", $"{proj.PackageName}.apk");
252252
using (var zipFile = ZipHelper.OpenZip (apk)) {
253253
foreach (var abi in supportedAbis) {
254254
if (expected) {

src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/IncrementalBuildTest.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1269,7 +1269,7 @@ public void AndroidAssetChange ()
12691269
TextContent = () => text
12701270
});
12711271
using (var b = CreateApkBuilder ()) {
1272-
var apk = Path.Combine (Root, b.ProjectDirectory, proj.OutputPath, "UnnamedProject.UnnamedProject.apk");
1272+
var apk = Path.Combine (Root, b.ProjectDirectory, proj.OutputPath, $"{proj.PackageName}.apk");
12731273
Assert.IsTrue (b.Build (proj), "first build should succeed");
12741274
AssertAssetContents (apk);
12751275

@@ -1310,7 +1310,7 @@ public void AndroidAssetMissing ()
13101310
using (var b = CreateApkBuilder ()) {
13111311
Assert.IsTrue (b.Build (proj), "first build should succeed");
13121312

1313-
var apk = Path.Combine (Root, b.ProjectDirectory, proj.OutputPath, "UnnamedProject.UnnamedProject.apk");
1313+
var apk = Path.Combine (Root, b.ProjectDirectory, proj.OutputPath, $"{proj.PackageName}.apk");
13141314
FileAssert.Exists (apk);
13151315
using (var zip = ZipHelper.OpenZip (apk)) {
13161316
Assert.IsTrue (zip.ContainsEntry ("assets/foo/bar.txt"), "bar.txt should exist in apk!");
@@ -1396,7 +1396,7 @@ public void BuildPropsBreaksConvertResourcesCasesOnSecondBuild ([Values (true, f
13961396
using (var b = CreateApkBuilder (Path.Combine ("temp", TestName))) {
13971397
Assert.IsTrue (b.Build (proj), "first build should have succeeded.");
13981398
var assemblyPath = Path.Combine (Root, b.ProjectDirectory, proj.OutputPath, "UnnamedProject.dll");
1399-
var apkPath = Path.Combine (Root, b.ProjectDirectory, proj.OutputPath, "UnnamedProject.UnnamedProject-Signed.apk");
1399+
var apkPath = Path.Combine (Root, b.ProjectDirectory, proj.OutputPath, $"{proj.PackageName}-Signed.apk");
14001400
var firstAssemblyWrite = new FileInfo (assemblyPath).LastWriteTime;
14011401
var firstApkWrite = new FileInfo (apkPath).LastWriteTime;
14021402

0 commit comments

Comments
 (0)