public void AppBundleSigned ()
		{
			var aab = Path.Combine (bin, "UnnamedProject.UnnamedProject-Signed.aab");
			FileAssert.Exists (aab);
			var contents = ListArchiveContents (aab);
			Assert.IsTrue (StringAssertEx.ContainsText (contents, "META-INF/MANIFEST.MF"), $"{aab} is not signed!");
		}
예제 #2
0
        public void InstallErrorCode()
        {
            AssertCommercialBuild();
            AssertHasDevices();

            //Setup a situation where we get INSTALL_FAILED_NO_MATCHING_ABIS
            var abi  = "armeabi-v7a";
            var proj = new XamarinAndroidApplicationProject {
                EmbedAssembliesIntoApk = true,
            };

            proj.SetAndroidSupportedAbis(abi);

            using (var builder = CreateApkBuilder(Path.Combine("temp", TestContext.CurrentContext.Test.Name))) {
                builder.ThrowOnBuildFailure = false;
                if (!builder.Install(proj))
                {
                    Assert.IsTrue(StringAssertEx.ContainsText(builder.LastBuildOutput, "ADB0020"), "Should receive ADB0020 error code.");
                }
                else
                {
                    Assert.Ignore($"Install should have failed, but we might have an {abi} emulator attached.");
                }
            }
        }
예제 #3
0
        public void InstallErrorCode()
        {
            if (!CommercialBuildAvailable)
            {
                Assert.Ignore("Not required on Open Source Builds");
            }

            if (!HasDevices)
            {
                Assert.Ignore("Test Skipped no devices or emulators found.");
            }

            //Setup a situation where we get INSTALL_FAILED_NO_MATCHING_ABIS
            var abi  = "armeabi-v7a";
            var proj = new XamarinAndroidApplicationProject {
                AndroidUseSharedRuntime = false,
                EmbedAssembliesIntoApk  = true,
            };

            proj.SetProperty(proj.DebugProperties, KnownProperties.AndroidSupportedAbis, abi);

            using (var builder = CreateApkBuilder(Path.Combine("temp", TestContext.CurrentContext.Test.Name))) {
                builder.ThrowOnBuildFailure = false;
                if (!builder.Install(proj))
                {
                    Assert.IsTrue(StringAssertEx.ContainsText(builder.LastBuildOutput, "ADB0020"), "Should receive ADB0020 error code.");
                }
                else
                {
                    Assert.Ignore($"Install should have failed, but we might have an {abi} emulator attached.");
                }
            }
        }
        public void BuildBasicBindingLibrary(string classParser)
        {
            var proj = new XamarinAndroidBindingProject()
            {
                IsRelease = true,
            };

            proj.Jars.Add(new AndroidItem.EmbeddedJar("Jars\\svg-android.jar")
            {
                WebContent = "https://storage.googleapis.com/google-code-archive-downloads/v2/code.google.com/svg-android/svg-android.jar"
            });
            proj.AndroidClassParser = classParser;
            using (var b = CreateDllBuilder(Path.Combine("temp", TestName))) {
                Assert.IsTrue(b.Build(proj), "Build should have succeeded.");

                //A list of properties we check exist in binding projects
                var properties = new [] {
                    "AndroidSdkBuildToolsVersion",
                    "AndroidSdkPlatformToolsVersion",
                    "AndroidSdkToolsVersion",
                    "AndroidNdkVersion",
                };
                foreach (var property in properties)
                {
                    Assert.IsTrue(StringAssertEx.ContainsText(b.LastBuildOutput, property + " = "), $"$({property}) should be set!");
                }
            }
        }
예제 #5
0
        public void BuildBasicBindingLibrary(string classParser)
        {
            var targets = new List <string> {
                "_ExportJarToXml",
                "GenerateBindings",
                "_ResolveLibraryProjectImports",
                "CoreCompile",
            };

            if (Builder.UseDotNet)
            {
                targets.Add("_CreateAar");
            }
            else
            {
                targets.Add("_CreateBindingResourceArchive");
                //TODO: .NET 5+ cannot support javadoc yet, due to missing mdoc
                targets.Add("_ExtractJavaDocJars");
                targets.Add("BuildDocumentation");
            }

            var proj = new XamarinAndroidBindingProject()
            {
                IsRelease = true,
            };

            proj.Jars.Add(new AndroidItem.AndroidLibrary("Jars\\svg-android.jar")
            {
                WebContent = "https://storage.googleapis.com/google-code-archive-downloads/v2/code.google.com/svg-android/svg-android.jar"
            });
            proj.AndroidClassParser = classParser;
            using (var b = CreateDllBuilder()) {
                Assert.IsTrue(b.Build(proj), "Build should have succeeded.");

                var assemblyPath = Path.Combine(Root, b.ProjectDirectory, proj.OutputPath, $"{proj.ProjectName}.dll");
                using (var assembly = AssemblyDefinition.ReadAssembly(assemblyPath)) {
                    var typeName = "Com.Larvalabs.Svgandroid.SVG";
                    var type     = assembly.MainModule.GetType(typeName);
                    Assert.IsNotNull(type, $"{assemblyPath} should contain {typeName}");
                }

                //A list of properties we check exist in binding projects
                var properties = new [] {
                    "AndroidSdkBuildToolsVersion",
                    "AndroidSdkPlatformToolsVersion",
                    "AndroidSdkToolsVersion",
                    "AndroidNdkVersion",
                };
                foreach (var property in properties)
                {
                    Assert.IsTrue(StringAssertEx.ContainsText(b.LastBuildOutput, property + " = "), $"$({property}) should be set!");
                }

                Assert.IsTrue(b.Build(proj, doNotCleanupOnUpdate: true, saveProject: false), "second build should succeed");
                foreach (var target in targets)
                {
                    Assert.IsTrue(b.Output.IsTargetSkipped(target), $"`{target}` should be skipped on second build!");
                }
            }
        }
예제 #6
0
        public void CheckSignApk([Values(true, false)] bool useApkSigner, [Values(true, false)] bool perAbiApk)
        {
            string ext            = Environment.OSVersion.Platform != PlatformID.Unix ? ".bat" : "";
            var    foundApkSigner = Directory.EnumerateDirectories(Path.Combine(AndroidSdkPath, "build-tools")).Any(dir => Directory.EnumerateFiles(dir, "apksigner" + ext).Any());

            if (useApkSigner && !foundApkSigner)
            {
                Assert.Ignore("Skipping test. Required build-tools verison which contains apksigner is not installed.");
            }
            var proj = new XamarinAndroidApplicationProject()
            {
                IsRelease = true,
            };

            if (useApkSigner)
            {
                proj.SetProperty("AndroidUseApkSigner", "true");
            }
            else
            {
                proj.RemoveProperty("AndroidUseApkSigner");
            }
            proj.SetProperty(proj.ReleaseProperties, KnownProperties.AndroidCreatePackagePerAbi, perAbiApk);
            proj.SetProperty(proj.ReleaseProperties, KnownProperties.AndroidSupportedAbis, "armeabi-v7a;x86");
            using (var b = CreateApkBuilder(Path.Combine("temp", TestContext.CurrentContext.Test.Name))) {
                b.Verbosity = Microsoft.Build.Framework.LoggerVerbosity.Diagnostic;
                Assert.IsTrue(b.Build(proj), "build failed");
                Assert.IsTrue(StringAssertEx.ContainsText(b.LastBuildOutput, " 0 Warning(s)"));
                proj.AndroidResources.First().Timestamp = null;
                Assert.IsTrue(b.Build(proj), "Second build failed");
                Assert.IsTrue(StringAssertEx.ContainsText(b.LastBuildOutput, " 0 Warning(s)"));
            }
        }
예제 #7
0
        public void DotNetBuildXamarinForms()
        {
            var proj   = new XamarinFormsXASdkProject();
            var dotnet = CreateDotNetBuilder(proj);

            Assert.IsTrue(dotnet.Build(), "`dotnet build` should succeed");
            Assert.IsTrue(StringAssertEx.ContainsText(dotnet.LastBuildOutput, " 0 Warning(s)"), "Should have no MSBuild warnings.");
        }
예제 #8
0
        public void CheckSignApk([Values(true, false)] bool useApkSigner, [Values(true, false)] bool perAbiApk)
        {
            string ext            = Environment.OSVersion.Platform != PlatformID.Unix ? ".bat" : "";
            var    foundApkSigner = Directory.EnumerateDirectories(Path.Combine(AndroidSdkPath, "build-tools")).Any(dir => Directory.EnumerateFiles(dir, "apksigner" + ext).Any());

            if (useApkSigner && !foundApkSigner)
            {
                Assert.Ignore("Skipping test. Required build-tools verison which contains apksigner is not installed.");
            }
            var proj = new XamarinAndroidApplicationProject()
            {
                IsRelease = true,
            };

            if (useApkSigner)
            {
                proj.SetProperty("AndroidUseApkSigner", "true");
            }
            else
            {
                proj.RemoveProperty("AndroidUseApkSigner");
            }
            proj.SetProperty(proj.ReleaseProperties, KnownProperties.AndroidCreatePackagePerAbi, perAbiApk);
            proj.SetProperty(proj.ReleaseProperties, KnownProperties.AndroidSupportedAbis, "armeabi-v7a;x86");
            using (var b = CreateApkBuilder(Path.Combine("temp", TestContext.CurrentContext.Test.Name))) {
                var bin = Path.Combine(Root, b.ProjectDirectory, proj.OutputPath);
                Assert.IsTrue(b.Build(proj), "First build failed");
                Assert.IsTrue(StringAssertEx.ContainsText(b.LastBuildOutput, " 0 Warning(s)"),
                              "First build should not contain warnings!  Contains\n" +
                              string.Join("\n", b.LastBuildOutput.Where(line => line.Contains("warning"))));

                //Make sure the APKs are signed
                foreach (var apk in Directory.GetFiles(bin, "*-Signed.apk"))
                {
                    using (var zip = ZipHelper.OpenZip(apk)) {
                        Assert.IsTrue(zip.Any(e => e.FullName == "META-INF/MANIFEST.MF"), $"APK file `{apk}` is not signed! It is missing `META-INF/MANIFEST.MF`.");
                    }
                }

                var item = proj.AndroidResources.First(x => x.Include() == "Resources\\values\\Strings.xml");
                item.TextContent = () => proj.StringsXml.Replace("${PROJECT_NAME}", "Foo");
                item.Timestamp   = null;
                Assert.IsTrue(b.Build(proj), "Second build failed");
                Assert.IsTrue(StringAssertEx.ContainsText(b.LastBuildOutput, " 0 Warning(s)"),
                              "Second build should not contain warnings!  Contains\n" +
                              string.Join("\n", b.LastBuildOutput.Where(line => line.Contains("warning"))));

                //Make sure the APKs are signed
                foreach (var apk in Directory.GetFiles(bin, "*-Signed.apk"))
                {
                    using (var zip = ZipHelper.OpenZip(apk)) {
                        Assert.IsTrue(zip.Any(e => e.FullName == "META-INF/MANIFEST.MF"), $"APK file `{apk}` is not signed! It is missing `META-INF/MANIFEST.MF`.");
                    }
                }
            }
        }
예제 #9
0
        void WarnAboutAppDomains(XamarinAndroidApplicationProject proj, string testName)
        {
            proj.MainActivity = proj.DefaultMainActivity.Replace("base.OnCreate (bundle);", "base.OnCreate (bundle);\nvar appDomain = System.AppDomain.CreateDomain (\"myDomain\");");
            var projDirectory = Path.Combine("temp", testName);

            using (var b = CreateApkBuilder(projDirectory)) {
                Assert.IsTrue(b.Build(proj), "Build should have succeeded.");
                Assert.IsTrue(StringAssertEx.ContainsText(b.LastBuildOutput, "Warning: Use of AppDomain::CreateDomain"), "Should warn about creating AppDomain.");
            }
        }
예제 #10
0
        public void Aapt2Disabled()
        {
            var proj = new XamarinAndroidApplicationProject();

            proj.SetProperty("AndroidUseAapt2", "False");
            using (var b = CreateApkBuilder("temp/Aapt2Disabled")) {
                Assert.IsTrue(b.Build(proj), "Build should have succeeded.");
                Assert.IsTrue(StringAssertEx.ContainsText(b.LastBuildOutput, "Task \"Aapt2Link\" skipped"), "Aapt2Link task should be skipped!");
                Assert.IsTrue(b.Output.IsTargetSkipped("_CreateAapt2VersionCache"), "_CreateAapt2VersionCache target should be skipped!");
            }
        }
예제 #11
0
        void WarnAboutAppDomains(XamarinAndroidApplicationProject proj, string testName)
        {
            proj.MainActivity = proj.DefaultMainActivity.Replace("base.OnCreate (bundle);", "base.OnCreate (bundle);\nvar appDomain = System.AppDomain.CreateDomain (\"myDomain\");");
            var projDirectory = Path.Combine("temp", testName);

            using (var b = CreateApkBuilder(projDirectory)) {
                Assert.IsTrue(b.Build(proj), "Build should have succeeded.");
                Assert.IsTrue(StringAssertEx.ContainsText(b.LastBuildOutput, "2 Warning(s)"), "MSBuild should count 2 warnings.");
                Assert.IsTrue(StringAssertEx.ContainsText(b.LastBuildOutput, "warning CS0618: 'AppDomain.CreateDomain(string)' is obsolete: 'AppDomain.CreateDomain will no longer be supported in .NET 5 and later."), "Should warn CS0618 about creating AppDomain.");
                Assert.IsTrue(StringAssertEx.ContainsText(b.LastBuildOutput, "warning XA2000: Use of AppDomain.CreateDomain()"), "Should warn XA2000 about creating AppDomain.");
            }
        }
        public void Edge(int limit, bool xamarinForms)
        {
            var testName = $"{nameof (Edge)}{xamarinForms}"
                           .PadRight(Files.MaxPath - BaseLength - limit, 'N');
            var proj = CreateProject(xamarinForms);

            using (var b = CreateApkBuilder(Path.Combine("temp", testName))) {
                Assert.IsTrue(b.Build(proj), "Build should have succeeded.");
                Assert.IsTrue(b.Clean(proj), "Clean should have succeeded.");
                Assert.IsTrue(StringAssertEx.ContainsText(b.LastBuildOutput, $"Trying long path: {Files.LongPathPrefix}"), "A long path should be encountered.");
            }
        }
예제 #13
0
        public void Aapt2Disabled()
        {
            AssertAaptSupported(useAapt2: false);
            var proj = new XamarinAndroidApplicationProject();

            proj.AndroidUseAapt2 = false;
            using (var b = CreateApkBuilder()) {
                Assert.IsTrue(b.Build(proj), "Build should have succeeded.");
                Assert.IsFalse(StringAssertEx.ContainsText(b.LastBuildOutput, "Aapt2Link"), "Aapt2Link task should not run!");
                Assert.IsFalse(StringAssertEx.ContainsText(b.LastBuildOutput, "Aapt2Compile"), "Aapt2Compile task should not run!");
                Assert.IsFalse(StringAssertEx.ContainsText(b.LastBuildOutput, "_CreateAapt2VersionCache"), "_CreateAapt2VersionCache target should not run!");
            }
        }
예제 #14
0
        public void LongPath()
        {
            if (!IsWindows)
            {
                Assert.Ignore("MAX_PATH only applies on Windows");
            }
            var file = NewFile(fileName: "foo".PadRight(250, 'N'));
            var task = CreateTask();

            Assert.IsTrue(task.Execute(), "task.Execute() should have succeeded.");
            Assert.AreEqual(1, task.RemovedDirectories.Length, "Changes should have been made.");
            DirectoryAssert.DoesNotExist(tempDirectory);
            Assert.IsTrue(StringAssertEx.ContainsText(messages.Select(m => m.Message), $"Trying long path: {Files.LongPathPrefix}"), "A long path should be encountered.");
        }
        public void OverTheEdge(int limit, bool xamarinForms)
        {
            var testName = $"{nameof (Edge)}{xamarinForms}"
                           .PadRight(Files.MaxPath - BaseLength - limit, 'N');
            var proj = CreateProject(xamarinForms);

            using (var b = CreateApkBuilder(Path.Combine("temp", testName))) {
                b.ThrowOnBuildFailure = false;
                Assert.IsFalse(b.Build(proj), "Build should have failed.");
                Assert.IsTrue(StringAssertEx.ContainsText(b.LastBuildOutput, "XA5301"), "Should get MAX_PATH warning");
                b.ThrowOnBuildFailure = true;
                Assert.IsTrue(b.Clean(proj), "Clean should have succeeded.");
            }
        }
예제 #16
0
        public void LongPath()
        {
            if (LongPathsSupported)
            {
                Assert.Ignore("This environment supports long paths");
            }
            var file = NewFile(fileName: "foo".PadRight(MaxFileName, 'N'));
            var task = CreateTask();

            Assert.IsTrue(task.Execute(), "task.Execute() should have succeeded.");
            Assert.AreEqual(1, task.RemovedDirectories.Length, "Changes should have been made.");
            DirectoryAssert.DoesNotExist(tempDirectory);
            Assert.IsTrue(StringAssertEx.ContainsText(messages.Select(m => m.Message), $"Trying long path: {Files.LongPathPrefix}"), "A long path should be encountered.");
        }
예제 #17
0
        public void BuildBasicBindingLibrary(string classParser)
        {
            var targets = new List <string> {
                "_ExportJarToXml",
                "GenerateBindings",
                "_CreateBindingResourceArchive",
                "_ResolveLibraryProjectImports",
                "CoreCompile",
            };

            if (!Builder.UseDotNet)
            {
                //TODO: .NET 5+ cannot support javadoc yet, due to missing mdoc
                targets.Add("_ExtractJavaDocJars");
                targets.Add("BuildDocumentation");
            }

            var proj = new XamarinAndroidBindingProject()
            {
                IsRelease = true,
            };

            proj.Jars.Add(new AndroidItem.EmbeddedJar("Jars\\svg-android.jar")
            {
                WebContent = "https://storage.googleapis.com/google-code-archive-downloads/v2/code.google.com/svg-android/svg-android.jar"
            });
            proj.AndroidClassParser = classParser;
            using (var b = CreateDllBuilder(Path.Combine("temp", TestName))) {
                Assert.IsTrue(b.Build(proj), "Build should have succeeded.");

                //A list of properties we check exist in binding projects
                var properties = new [] {
                    "AndroidSdkBuildToolsVersion",
                    "AndroidSdkPlatformToolsVersion",
                    "AndroidSdkToolsVersion",
                    "AndroidNdkVersion",
                };
                foreach (var property in properties)
                {
                    Assert.IsTrue(StringAssertEx.ContainsText(b.LastBuildOutput, property + " = "), $"$({property}) should be set!");
                }

                Assert.IsTrue(b.Build(proj, doNotCleanupOnUpdate: true, saveProject: false), "second build should succeed");
                foreach (var target in targets)
                {
                    Assert.IsTrue(b.Output.IsTargetSkipped(target), $"`{target}` should be skipped on second build!");
                }
            }
        }
예제 #18
0
        [Category("DotNetIgnore")]          // n/a on .NET 5+
        public void WarnAboutAppDomains([Values(true, false)] bool isRelease)
        {
            var proj = new XamarinAndroidApplicationProject()
            {
                IsRelease = isRelease
            };

            proj.MainActivity = proj.DefaultMainActivity.Replace("base.OnCreate (bundle);", "base.OnCreate (bundle);\nvar appDomain = System.AppDomain.CreateDomain (\"myDomain\");");
            using (var b = CreateApkBuilder()) {
                Assert.IsTrue(b.Build(proj), "Build should have succeeded.");
                Assert.IsTrue(StringAssertEx.ContainsText(b.LastBuildOutput, "2 Warning(s)"), "MSBuild should count 2 warnings.");
                Assert.IsTrue(StringAssertEx.ContainsText(b.LastBuildOutput, "warning CS0618: 'AppDomain.CreateDomain(string)' is obsolete: 'AppDomain.CreateDomain will no longer be supported in .NET 5 and later."), "Should warn CS0618 about creating AppDomain.");
                Assert.IsTrue(StringAssertEx.ContainsText(b.LastBuildOutput, "warning XA2000: Use of AppDomain.CreateDomain()"), "Should warn XA2000 about creating AppDomain.");
            }
        }
예제 #19
0
        public void DotNetBuild(string runtimeIdentifier, bool isRelease)
        {
            var abi  = MonoAndroidHelper.RuntimeIdentifierToAbi(runtimeIdentifier);
            var proj = new XASdkProject {
                IsRelease = isRelease
            };

            proj.OtherBuildItems.Add(new AndroidItem.InputJar("javaclasses.jar")
            {
                BinaryContent = () => Convert.FromBase64String(InlineData.JavaClassesJarBase64)
            });
            // TODO: bring back when Xamarin.Android.Bindings.Documentation.targets is working
            //proj.OtherBuildItems.Add (new BuildItem ("JavaSourceJar", "javasources.jar") {
            //	BinaryContent = () => Convert.FromBase64String (InlineData.JavaSourcesJarBase64)
            //});
            proj.SetProperty(KnownProperties.RuntimeIdentifier, runtimeIdentifier);

            var dotnet = CreateDotNetBuilder(proj);

            Assert.IsTrue(dotnet.Build(), "`dotnet build` should succeed");

            // TODO: run for release once illink warnings are gone
            // context: https://github.com/xamarin/xamarin-android/issues/4708
            if (!isRelease)
            {
                Assert.IsTrue(StringAssertEx.ContainsText(dotnet.LastBuildOutput, " 0 Warning(s)"), "Should have no MSBuild warnings.");
            }

            var outputPath   = Path.Combine(Root, dotnet.ProjectDirectory, proj.OutputPath, runtimeIdentifier);
            var assemblyPath = Path.Combine(outputPath, "UnnamedProject.dll");

            FileAssert.Exists(assemblyPath);
            using (var assembly = AssemblyDefinition.ReadAssembly(assemblyPath)) {
                var typeName = "Com.Xamarin.Android.Test.Msbuildtest.JavaSourceJarTest";
                var type     = assembly.MainModule.GetType(typeName);
                Assert.IsNotNull(type, $"{assemblyPath} should contain {typeName}");
            }

            var apk = Path.Combine(outputPath, "UnnamedProject.UnnamedProject.apk");

            FileAssert.Exists(apk);
            using (var zip = ZipHelper.OpenZip(apk)) {
                Assert.IsTrue(zip.ContainsEntry($"lib/{abi}/libmonodroid.so"), "libmonodroid.so should exist.");
                Assert.IsTrue(zip.ContainsEntry($"lib/{abi}/libmonosgen-2.0.so"), "libmonosgen-2.0.so should exist.");
            }
        }
예제 #20
0
        public void DotNetBuild(string runtimeIdentifiers, bool isRelease)
        {
            var proj = new XASdkProject {
                IsRelease = isRelease
            };

            proj.OtherBuildItems.Add(new AndroidItem.InputJar("javaclasses.jar")
            {
                BinaryContent = () => Convert.FromBase64String(InlineData.JavaClassesJarBase64)
            });
            // TODO: bring back when Xamarin.Android.Bindings.Documentation.targets is working
            //proj.OtherBuildItems.Add (new BuildItem ("JavaSourceJar", "javasources.jar") {
            //	BinaryContent = () => Convert.FromBase64String (InlineData.JavaSourcesJarBase64)
            //});
            if (!runtimeIdentifiers.Contains(";"))
            {
                proj.SetProperty(KnownProperties.RuntimeIdentifier, runtimeIdentifiers);
            }
            else
            {
                proj.SetProperty(KnownProperties.RuntimeIdentifiers, runtimeIdentifiers);
            }

            var dotnet = CreateDotNetBuilder(proj);

            Assert.IsTrue(dotnet.Build(), "`dotnet build` should succeed");

            // TODO: run for release once illink warnings are gone
            // context: https://github.com/xamarin/xamarin-android/issues/4708
            if (!isRelease)
            {
                Assert.IsTrue(StringAssertEx.ContainsText(dotnet.LastBuildOutput, " 0 Warning(s)"), "Should have no MSBuild warnings.");
            }

            var outputPath = Path.Combine(FullProjectDirectory, proj.OutputPath);

            if (!runtimeIdentifiers.Contains(";"))
            {
                outputPath = Path.Combine(outputPath, runtimeIdentifiers);
            }

            // TODO: With workloads we don't control the import of Microsoft.NET.Sdk/Sdk.targets.
            //  We can no longer change the default values of `$(GenerateDependencyFile)` and `$(ProduceReferenceAssembly)` as a result.
            //  We should update Microsoft.NET.Sdk to default both of these properties to false when the `$(TargetPlatformIdentifier)` is "mobile" (Android, iOS, etc).
            //  Alternatively, the workload concept could be updated to support some sort of `Before.Microsoft.NET.targets` hook.

            /* var files = Directory.EnumerateFileSystemEntries (outputPath)
             *      .Select (Path.GetFileName)
             *      .OrderBy (f => f);
             * CollectionAssert.AreEqual (new [] {
             *      $"{proj.ProjectName}.dll",
             *      $"{proj.ProjectName}.pdb",
             *      $"{proj.PackageName}.apk",
             *      $"{proj.PackageName}-Signed.apk",
             * }, files);
             */

            var assemblyPath = Path.Combine(outputPath, $"{proj.ProjectName}.dll");

            FileAssert.Exists(assemblyPath);
            using (var assembly = AssemblyDefinition.ReadAssembly(assemblyPath)) {
                var typeName = "Com.Xamarin.Android.Test.Msbuildtest.JavaSourceJarTest";
                var type     = assembly.MainModule.GetType(typeName);
                Assert.IsNotNull(type, $"{assemblyPath} should contain {typeName}");
            }

            bool expectEmbeddedAssembies = !(CommercialBuildAvailable && !isRelease);
            var  apkPath = Path.Combine(outputPath, "UnnamedProject.UnnamedProject.apk");

            FileAssert.Exists(apkPath);
            using (var apk = ZipHelper.OpenZip(apkPath)) {
                var rids = runtimeIdentifiers.Split(';');
                foreach (var abi in rids.Select(MonoAndroidHelper.RuntimeIdentifierToAbi))
                {
                    apk.AssertContainsEntry(apkPath, $"lib/{abi}/libmonodroid.so");
                    apk.AssertContainsEntry(apkPath, $"lib/{abi}/libmonosgen-2.0.so");
                    if (rids.Length > 1)
                    {
                        apk.AssertContainsEntry(apkPath, $"assemblies/{abi}/System.Private.CoreLib.dll", expectEmbeddedAssembies);
                    }
                    else
                    {
                        apk.AssertContainsEntry(apkPath, "assemblies/System.Private.CoreLib.dll", expectEmbeddedAssembies);
                    }
                }
            }
        }
예제 #21
0
        public void DotNetBuild(string runtimeIdentifiers, bool isRelease)
        {
            var proj = new XASdkProject {
                IsRelease = isRelease
            };

            proj.OtherBuildItems.Add(new AndroidItem.InputJar("javaclasses.jar")
            {
                BinaryContent = () => Convert.FromBase64String(InlineData.JavaClassesJarBase64)
            });
            // TODO: bring back when Xamarin.Android.Bindings.Documentation.targets is working
            //proj.OtherBuildItems.Add (new BuildItem ("JavaSourceJar", "javasources.jar") {
            //	BinaryContent = () => Convert.FromBase64String (InlineData.JavaSourcesJarBase64)
            //});
            if (!runtimeIdentifiers.Contains(";"))
            {
                proj.SetProperty(KnownProperties.RuntimeIdentifier, runtimeIdentifiers);
            }
            else
            {
                proj.SetProperty(KnownProperties.RuntimeIdentifiers, runtimeIdentifiers);
            }

            var dotnet = CreateDotNetBuilder(proj);

            Assert.IsTrue(dotnet.Build(), "`dotnet build` should succeed");

            // TODO: run for release once illink warnings are gone
            // context: https://github.com/xamarin/xamarin-android/issues/4708
            if (!isRelease)
            {
                Assert.IsTrue(StringAssertEx.ContainsText(dotnet.LastBuildOutput, " 0 Warning(s)"), "Should have no MSBuild warnings.");
            }

            var outputPath = Path.Combine(FullProjectDirectory, proj.OutputPath);

            if (!runtimeIdentifiers.Contains(";"))
            {
                outputPath = Path.Combine(outputPath, runtimeIdentifiers);
            }

            var files = Directory.EnumerateFileSystemEntries(outputPath)
                        .Select(Path.GetFileName)
                        .OrderBy(f => f)
                        .ToArray();

            CollectionAssert.AreEqual(new [] {
                $"{proj.ProjectName}.dll",
                $"{proj.ProjectName}.pdb",
                $"{proj.PackageName}.apk",
                $"{proj.PackageName}-Signed.apk",
            }, files);

            var assemblyPath = Path.Combine(outputPath, $"{proj.ProjectName}.dll");

            FileAssert.Exists(assemblyPath);
            using (var assembly = AssemblyDefinition.ReadAssembly(assemblyPath)) {
                var typeName = "Com.Xamarin.Android.Test.Msbuildtest.JavaSourceJarTest";
                var type     = assembly.MainModule.GetType(typeName);
                Assert.IsNotNull(type, $"{assemblyPath} should contain {typeName}");
            }

            bool expectEmbeddedAssembies = !(CommercialBuildAvailable && !isRelease);
            var  apkPath = Path.Combine(outputPath, "UnnamedProject.UnnamedProject.apk");

            FileAssert.Exists(apkPath);
            using (var apk = ZipHelper.OpenZip(apkPath)) {
                apk.AssertContainsEntry(apkPath, $"assemblies/{proj.ProjectName}.dll", shouldContainEntry: expectEmbeddedAssembies);
                apk.AssertContainsEntry(apkPath, $"assemblies/{proj.ProjectName}.pdb", shouldContainEntry: !CommercialBuildAvailable && !isRelease);
                apk.AssertContainsEntry(apkPath, $"assemblies/System.Linq.dll", shouldContainEntry: expectEmbeddedAssembies);
                var rids = runtimeIdentifiers.Split(';');
                foreach (var abi in rids.Select(MonoAndroidHelper.RuntimeIdentifierToAbi))
                {
                    apk.AssertContainsEntry(apkPath, $"lib/{abi}/libmonodroid.so");
                    apk.AssertContainsEntry(apkPath, $"lib/{abi}/libmonosgen-2.0.so");
                    if (rids.Length > 1)
                    {
                        apk.AssertContainsEntry(apkPath, $"assemblies/{abi}/System.Private.CoreLib.dll", shouldContainEntry: expectEmbeddedAssembies);
                        apk.AssertContainsEntry(apkPath, $"assemblies/{abi}/System.Collections.Concurrent.dll", shouldContainEntry: expectEmbeddedAssembies);
                    }
                    else
                    {
                        apk.AssertContainsEntry(apkPath, "assemblies/System.Private.CoreLib.dll", shouldContainEntry: expectEmbeddedAssembies);
                        apk.AssertContainsEntry(apkPath, "assemblies/System.Collections.Concurrent.dll", shouldContainEntry: expectEmbeddedAssembies);
                    }
                }
            }
        }
        public void BuildApplicationWithMonoEnvironment([Values("", "Normal", "Offline")] string sequencePointsMode)
        {
            const string supportedAbis = "armeabi-v7a;x86";

            var lib = new XamarinAndroidLibraryProject {
                ProjectName     = "Library1",
                IsRelease       = true,
                OtherBuildItems = { new AndroidItem.AndroidEnvironment("Mono.env")
                                    {
                                        TextContent = () => "MONO_DEBUG=soft-breakpoints"
                                    }, },
            };
            var app = new XamarinFormsAndroidApplicationProject()
            {
                IsRelease = true,
                AndroidLinkModeRelease = AndroidLinkMode.Full,
                References             =
                {
                    new BuildItem("ProjectReference", "..\\Library1\\Library1.csproj"),
                },
            };
            //LinkSkip one assembly that contains __AndroidLibraryProjects__.zip
            string linkSkip = "FormsViewGroup";

            app.SetProperty("AndroidLinkSkip", linkSkip);
            app.SetProperty("_AndroidSequencePointsMode", sequencePointsMode);
            app.SetAndroidSupportedAbis(supportedAbis);
            using (var libb = CreateDllBuilder(Path.Combine("temp", TestName, lib.ProjectName)))
                using (var appb = CreateApkBuilder(Path.Combine("temp", TestName, app.ProjectName))) {
                    Assert.IsTrue(libb.Build(lib), "Library build should have succeeded.");
                    Assert.IsTrue(appb.Build(app), "App should have succeeded.");
                    Assert.IsTrue(StringAssertEx.ContainsText(appb.LastBuildOutput, $"Save assembly: {linkSkip}"), $"{linkSkip} should be saved, and not linked!");

                    string        intermediateOutputDir = Path.Combine(Root, appb.ProjectDirectory, app.IntermediateOutputPath);
                    List <string> envFiles = EnvironmentHelper.GatherEnvironmentFiles(intermediateOutputDir, supportedAbis, true);
                    Dictionary <string, string> envvars = EnvironmentHelper.ReadEnvironmentVariables(envFiles);
                    Assert.IsTrue(envvars.Count > 0, $"No environment variables defined");

                    string monoDebugVar;
                    Assert.IsTrue(envvars.TryGetValue("MONO_DEBUG", out monoDebugVar), "Environment should contain MONO_DEBUG");
                    Assert.IsFalse(String.IsNullOrEmpty(monoDebugVar), "Environment must contain MONO_DEBUG with a value");
                    Assert.IsTrue(monoDebugVar.IndexOf("soft-breakpoints") >= 0, "Environment must contain MONO_DEBUG with 'soft-breakpoints' in its value");

                    if (!String.IsNullOrEmpty(sequencePointsMode))
                    {
                        Assert.IsTrue(monoDebugVar.IndexOf("gen-compact-seq-points") >= 0, "The values from Mono.env should have been merged into environment");
                    }

                    EnvironmentHelper.AssertValidEnvironmentSharedLibrary(intermediateOutputDir, AndroidSdkPath, AndroidNdkPath, supportedAbis);

                    var assemblyDir = Path.Combine(Root, appb.ProjectDirectory, app.IntermediateOutputPath, "android", "assets");
                    var rp          = new ReaderParameters {
                        ReadSymbols = false
                    };
                    foreach (var assemblyFile in Directory.EnumerateFiles(assemblyDir, "*.dll"))
                    {
                        using (var assembly = AssemblyDefinition.ReadAssembly(assemblyFile)) {
                            foreach (var module in assembly.Modules)
                            {
                                var resources = module.Resources.Select(r => r.Name).ToArray();
                                Assert.IsFalse(StringAssertEx.ContainsText(resources, "__AndroidEnvironment__"), "AndroidEnvironment EmbeddedResource should be stripped!");
                                Assert.IsFalse(StringAssertEx.ContainsText(resources, "__AndroidLibraryProjects__.zip"), "__AndroidLibraryProjects__.zip should be stripped!");
                                Assert.IsFalse(StringAssertEx.ContainsText(resources, "__AndroidNativeLibraries__.zip"), "__AndroidNativeLibraries__.zip should be stripped!");
                            }
                        }
                    }
                }
        }
예제 #23
0
        public void DotNetBuild(string runtimeIdentifiers, bool isRelease)
        {
            var proj = new XASdkProject {
                IsRelease = isRelease,
                ExtraNuGetConfigSources =
                {
                    "https://pkgs.dev.azure.com/azure-public/vside/_packaging/xamarin-impl/nuget/v3/index.json"
                },
                PackageReferences =
                {
                    new Package {
                        Id = "Xamarin.AndroidX.AppCompat", Version = "1.2.0.7-net6preview01"
                    }
                },
                Sources =
                {
                    new BuildItem("EmbeddedResource", "Foo.resx")
                    {
                        TextContent = () => InlineData.ResxWithContents("<data name=\"CancelButton\"><value>Cancel</value></data>")
                    },
                    new BuildItem("EmbeddedResource", "Foo.es.resx")
                    {
                        TextContent = () => InlineData.ResxWithContents("<data name=\"CancelButton\"><value>Cancelar</value></data>")
                    },
                }
            };

            proj.MainActivity = proj.DefaultMainActivity.Replace(": Activity", ": AndroidX.AppCompat.App.AppCompatActivity");
            proj.OtherBuildItems.Add(new AndroidItem.InputJar("javaclasses.jar")
            {
                BinaryContent = () => ResourceData.JavaSourceJarTestJar,
            });
            proj.OtherBuildItems.Add(new BuildItem("JavaSourceJar", "javaclasses-sources.jar")
            {
                BinaryContent = () => ResourceData.JavaSourceJarTestSourcesJar,
            });
            if (!runtimeIdentifiers.Contains(";"))
            {
                proj.SetProperty(KnownProperties.RuntimeIdentifier, runtimeIdentifiers);
            }
            else
            {
                proj.SetProperty(KnownProperties.RuntimeIdentifiers, runtimeIdentifiers);
            }

            var dotnet = CreateDotNetBuilder(proj);

            Assert.IsTrue(dotnet.Build(), "`dotnet build` should succeed");

            Assert.IsTrue(StringAssertEx.ContainsText(dotnet.LastBuildOutput, " 0 Warning(s)"), "Should have no MSBuild warnings.");

            var outputPath             = Path.Combine(FullProjectDirectory, proj.OutputPath);
            var intermediateOutputPath = Path.Combine(FullProjectDirectory, proj.IntermediateOutputPath);

            if (!runtimeIdentifiers.Contains(";"))
            {
                outputPath             = Path.Combine(outputPath, runtimeIdentifiers);
                intermediateOutputPath = Path.Combine(intermediateOutputPath, runtimeIdentifiers);
            }

            var files = Directory.EnumerateFileSystemEntries(outputPath)
                        .Select(Path.GetFileName)
                        .OrderBy(f => f)
                        .ToArray();
            var expectedFiles = new[] {
                $"{proj.PackageName}.apk",
                $"{proj.PackageName}-Signed.apk",
                "es",
                $"{proj.ProjectName}.dll",
                $"{proj.ProjectName}.pdb",
                $"{proj.ProjectName}.xml",
            };

            CollectionAssert.AreEqual(expectedFiles, files, $"Expected: {string.Join (";", expectedFiles)}\n   Found: {string.Join (";", files)}");

            var assemblyPath = Path.Combine(outputPath, $"{proj.ProjectName}.dll");

            FileAssert.Exists(assemblyPath);
            using (var assembly = AssemblyDefinition.ReadAssembly(assemblyPath)) {
                var typeName = "Com.Xamarin.Android.Test.Msbuildtest.JavaSourceJarTest";
                var type     = assembly.MainModule.GetType(typeName);
                Assert.IsNotNull(type, $"{assemblyPath} should contain {typeName}");
            }

            var rids = runtimeIdentifiers.Split(';');

            if (isRelease)
            {
                // Check for stripped native libraries
                foreach (var rid in rids)
                {
                    FileAssert.Exists(Path.Combine(intermediateOutputPath, "native", rid, "libmono-android.release.so"));
                    FileAssert.Exists(Path.Combine(intermediateOutputPath, "native", rid, "libmonosgen-2.0.so"));
                }
            }

            bool expectEmbeddedAssembies = !(CommercialBuildAvailable && !isRelease);
            var  apkPath = Path.Combine(outputPath, $"{proj.PackageName}.apk");

            FileAssert.Exists(apkPath);
            using (var apk = ZipHelper.OpenZip(apkPath)) {
                apk.AssertContainsEntry(apkPath, $"assemblies/{proj.ProjectName}.dll", shouldContainEntry: expectEmbeddedAssembies);
                apk.AssertContainsEntry(apkPath, $"assemblies/{proj.ProjectName}.pdb", shouldContainEntry: !CommercialBuildAvailable && !isRelease);
                apk.AssertContainsEntry(apkPath, $"assemblies/System.Linq.dll", shouldContainEntry: expectEmbeddedAssembies);
                apk.AssertContainsEntry(apkPath, $"assemblies/es/{proj.ProjectName}.resources.dll", shouldContainEntry: expectEmbeddedAssembies);
                foreach (var abi in rids.Select(AndroidRidAbiHelper.RuntimeIdentifierToAbi))
                {
                    apk.AssertContainsEntry(apkPath, $"lib/{abi}/libmonodroid.so");
                    apk.AssertContainsEntry(apkPath, $"lib/{abi}/libmonosgen-2.0.so");
                    if (rids.Length > 1)
                    {
                        apk.AssertContainsEntry(apkPath, $"assemblies/{abi}/System.Private.CoreLib.dll", shouldContainEntry: expectEmbeddedAssembies);
                    }
                    else
                    {
                        apk.AssertContainsEntry(apkPath, "assemblies/System.Private.CoreLib.dll", shouldContainEntry: expectEmbeddedAssembies);
                    }
                }
            }
        }
 public static void AssertHasNoWarnings(this ProjectBuilder builder)
 {
     Assert.IsTrue(StringAssertEx.ContainsText(builder.LastBuildOutput, " 0 Warning(s)"), $"{builder.BuildLogFile} should have no MSBuild warnings.");
 }
 public static void AssertHasNoWarnings(this DotNetCLI dotnet)
 {
     Assert.IsTrue(StringAssertEx.ContainsText(dotnet.LastBuildOutput, " 0 Warning(s)"), $"{dotnet.BuildLogFile} should have no MSBuild warnings.");
 }
        public void CheckSignApk([Values(true, false)] bool useApkSigner, [Values(true, false)] bool perAbiApk)
        {
            string ext            = Environment.OSVersion.Platform != PlatformID.Unix ? ".bat" : "";
            var    foundApkSigner = Directory.EnumerateDirectories(Path.Combine(AndroidSdkPath, "build-tools")).Any(dir => Directory.EnumerateFiles(dir, "apksigner" + ext).Any());

            if (useApkSigner && !foundApkSigner)
            {
                Assert.Ignore("Skipping test. Required build-tools verison which contains apksigner is not installed.");
            }
            string keyfile = Path.Combine(Root, "temp", TestName, "release.keystore");

            if (File.Exists(keyfile))
            {
                File.Delete(keyfile);
            }
            var androidSdk     = new AndroidSdkInfo((level, message) => {
            }, AndroidSdkPath, AndroidNdkPath);
            string keyToolPath = Path.Combine(androidSdk.JavaSdkPath, "bin");
            var    engine      = new MockBuildEngine(Console.Out);
            string pass        = "******";
            var    task        = new AndroidCreateDebugKey {
                BuildEngine  = engine,
                KeyStore     = keyfile,
                StorePass    = pass,
                KeyAlias     = "releasestore",
                KeyPass      = pass,
                KeyAlgorithm = "RSA",
                Validity     = 30,
                StoreType    = "pkcs12",
                Command      = "-genkeypair",
                ToolPath     = keyToolPath,
            };

            Assert.IsTrue(task.Execute(), "Task should have succeeded.");
            var proj = new XamarinAndroidApplicationProject()
            {
                IsRelease = true,
            };

            if (useApkSigner)
            {
                proj.SetProperty("AndroidUseApkSigner", "true");
            }
            else
            {
                proj.RemoveProperty("AndroidUseApkSigner");
            }
            proj.SetProperty(proj.ReleaseProperties, "AndroidKeyStore", "True");
            proj.SetProperty(proj.ReleaseProperties, "AndroidSigningKeyStore", keyfile);
            proj.SetProperty(proj.ReleaseProperties, "AndroidSigningKeyAlias", "releasestore");
            proj.SetProperty(proj.ReleaseProperties, "AndroidSigningKeyPass", pass);
            proj.SetProperty(proj.ReleaseProperties, "AndroidSigningStorePass", pass);
            proj.SetProperty(proj.ReleaseProperties, KnownProperties.AndroidCreatePackagePerAbi, perAbiApk);
            proj.SetAndroidSupportedAbis("armeabi-v7a", "x86");
            using (var b = CreateApkBuilder(Path.Combine("temp", TestContext.CurrentContext.Test.Name))) {
                var bin = Path.Combine(Root, b.ProjectDirectory, proj.OutputPath);
                Assert.IsTrue(b.Build(proj), "First build failed");
                Assert.IsTrue(StringAssertEx.ContainsText(b.LastBuildOutput, " 0 Warning(s)"),
                              "First build should not contain warnings!  Contains\n" +
                              string.Join("\n", b.LastBuildOutput.Where(line => line.Contains("warning"))));

                //Make sure the APKs are signed
                foreach (var apk in Directory.GetFiles(bin, "*-Signed.apk"))
                {
                    using (var zip = ZipHelper.OpenZip(apk)) {
                        Assert.IsTrue(zip.Any(e => e.FullName == "META-INF/MANIFEST.MF"), $"APK file `{apk}` is not signed! It is missing `META-INF/MANIFEST.MF`.");
                    }
                }

                var item = proj.AndroidResources.First(x => x.Include() == "Resources\\values\\Strings.xml");
                item.TextContent = () => proj.StringsXml.Replace("${PROJECT_NAME}", "Foo");
                item.Timestamp   = null;
                Assert.IsTrue(b.Build(proj), "Second build failed");
                Assert.IsTrue(StringAssertEx.ContainsText(b.LastBuildOutput, " 0 Warning(s)"),
                              "Second build should not contain warnings!  Contains\n" +
                              string.Join("\n", b.LastBuildOutput.Where(line => line.Contains("warning"))));

                //Make sure the APKs are signed
                foreach (var apk in Directory.GetFiles(bin, "*-Signed.apk"))
                {
                    using (var zip = ZipHelper.OpenZip(apk)) {
                        Assert.IsTrue(zip.Any(e => e.FullName == "META-INF/MANIFEST.MF"), $"APK file `{apk}` is not signed! It is missing `META-INF/MANIFEST.MF`.");
                    }
                }
            }
        }
예제 #27
0
        public void DotNetBuild(string runtimeIdentifiers, bool isRelease)
        {
            var proj = new XASdkProject {
                IsRelease = isRelease,
                Sources   =
                {
                    new BuildItem("EmbeddedResource", "Foo.resx")
                    {
                        TextContent = () => InlineData.ResxWithContents("<data name=\"CancelButton\"><value>Cancel</value></data>")
                    },
                    new BuildItem("EmbeddedResource", "Foo.es.resx")
                    {
                        TextContent = () => InlineData.ResxWithContents("<data name=\"CancelButton\"><value>Cancelar</value></data>")
                    },
                }
            };

            proj.OtherBuildItems.Add(new AndroidItem.InputJar("javaclasses.jar")
            {
                BinaryContent = () => ResourceData.JavaSourceJarTestJar,
            });
            proj.OtherBuildItems.Add(new BuildItem("JavaSourceJar", "javaclasses-sources.jar")
            {
                BinaryContent = () => ResourceData.JavaSourceJarTestSourcesJar,
            });
            if (!runtimeIdentifiers.Contains(";"))
            {
                proj.SetProperty(KnownProperties.RuntimeIdentifier, runtimeIdentifiers);
            }
            else
            {
                proj.SetProperty(KnownProperties.RuntimeIdentifiers, runtimeIdentifiers);
            }

            var dotnet = CreateDotNetBuilder(proj);

            Assert.IsTrue(dotnet.Build(), "`dotnet build` should succeed");

            // TODO: run for release once illink warnings are gone
            // context: https://github.com/xamarin/xamarin-android/issues/4708
            if (!isRelease)
            {
                Assert.IsTrue(StringAssertEx.ContainsText(dotnet.LastBuildOutput, " 0 Warning(s)"), "Should have no MSBuild warnings.");
            }

            var outputPath = Path.Combine(FullProjectDirectory, proj.OutputPath);

            if (!runtimeIdentifiers.Contains(";"))
            {
                outputPath = Path.Combine(outputPath, runtimeIdentifiers);
            }

            var files = Directory.EnumerateFileSystemEntries(outputPath)
                        .Select(Path.GetFileName)
                        .OrderBy(f => f)
                        .ToArray();
            var expectedFiles = new[] {
                "es",
                $"{proj.ProjectName}.dll",
                $"{proj.ProjectName}.pdb",
                $"{proj.PackageName}.apk",
                $"{proj.PackageName}-Signed.apk",
                $"{proj.ProjectName}.xml",
            };

            CollectionAssert.AreEqual(expectedFiles, files, $"Expected: {string.Join (";", expectedFiles)}\n   Found: {string.Join (";", files)}");

            var assemblyPath = Path.Combine(outputPath, $"{proj.ProjectName}.dll");

            FileAssert.Exists(assemblyPath);
            using (var assembly = AssemblyDefinition.ReadAssembly(assemblyPath)) {
                var typeName = "Com.Xamarin.Android.Test.Msbuildtest.JavaSourceJarTest";
                var type     = assembly.MainModule.GetType(typeName);
                Assert.IsNotNull(type, $"{assemblyPath} should contain {typeName}");
            }

            bool expectEmbeddedAssembies = !(CommercialBuildAvailable && !isRelease);
            var  apkPath = Path.Combine(outputPath, "UnnamedProject.UnnamedProject.apk");

            FileAssert.Exists(apkPath);
            using (var apk = ZipHelper.OpenZip(apkPath)) {
                apk.AssertContainsEntry(apkPath, $"assemblies/{proj.ProjectName}.dll", shouldContainEntry: expectEmbeddedAssembies);
                apk.AssertContainsEntry(apkPath, $"assemblies/{proj.ProjectName}.pdb", shouldContainEntry: !CommercialBuildAvailable && !isRelease);
                apk.AssertContainsEntry(apkPath, $"assemblies/System.Linq.dll", shouldContainEntry: expectEmbeddedAssembies);
                apk.AssertContainsEntry(apkPath, $"assemblies/es/{proj.ProjectName}.resources.dll", shouldContainEntry: expectEmbeddedAssembies);
                var rids = runtimeIdentifiers.Split(';');
                foreach (var abi in rids.Select(AndroidRidAbiHelper.RuntimeIdentifierToAbi))
                {
                    apk.AssertContainsEntry(apkPath, $"lib/{abi}/libmonodroid.so");
                    apk.AssertContainsEntry(apkPath, $"lib/{abi}/libmonosgen-2.0.so");
                    if (rids.Length > 1)
                    {
                        apk.AssertContainsEntry(apkPath, $"assemblies/{abi}/System.Private.CoreLib.dll", shouldContainEntry: expectEmbeddedAssembies);
                    }
                    else
                    {
                        apk.AssertContainsEntry(apkPath, "assemblies/System.Private.CoreLib.dll", shouldContainEntry: expectEmbeddedAssembies);
                    }
                }
            }
        }