示例#1
0
        public void DotNetBuildBinding()
        {
            var proj = new XASdkProject(outputType: "Library");

            proj.Sources.Add(new AndroidItem.TransformFile("Transforms\\Metadata.xml")
            {
                TextContent = () =>
                              @"<metadata>
  <attr path=""/api/package[@name='com.xamarin.android.test.msbuildtest']"" name=""managedName"">MSBuildTest</attr>
</metadata>",
            });
            proj.Sources.Add(new AndroidItem.AndroidLibrary("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)
            //});
            var dotnet = CreateDotNetBuilder(proj);

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

            var assemblyPath = Path.Combine(FullProjectDirectory, proj.OutputPath, "UnnamedProject.dll");

            FileAssert.Exists(assemblyPath);
            using (var assembly = AssemblyDefinition.ReadAssembly(assemblyPath)) {
                var typeName = "MSBuildTest.JavaSourceJarTest";
                var type     = assembly.MainModule.GetType(typeName);
                Assert.IsNotNull(type, $"{assemblyPath} should contain {typeName}");
            }
        }
示例#2
0
        public void XamarinLegacySdk()
        {
            var proj = new XASdkProject(outputType: "Library")
            {
                Sdk     = "Xamarin.Legacy.Sdk/0.1.0-alpha2",
                Sources =
                {
                    new AndroidItem.AndroidLibrary("javaclasses.jar")
                    {
                        BinaryContent = () => ResourceData.JavaSourceJarTestJar,
                    }
                }
            };

            using var b = new Builder();
            var dotnetTargetFramework        = "net6.0-android30.0";
            var legacyTargetFrameworkVersion = b.LatestTargetFrameworkVersion().TrimStart('v');
            var legacyTargetFramework        = $"monoandroid{legacyTargetFrameworkVersion}";

            proj.SetProperty("TargetFramework", value: "");
            proj.SetProperty("TargetFrameworks", value: $"{dotnetTargetFramework};{legacyTargetFramework}");

            var dotnet = CreateDotNetBuilder(proj);

            Assert.IsTrue(dotnet.Pack(), "`dotnet pack` should succeed");

            var nupkgPath = Path.Combine(FullProjectDirectory, proj.OutputPath, $"{proj.ProjectName}.1.0.0.nupkg");

            FileAssert.Exists(nupkgPath);
            using var nupkg = ZipHelper.OpenZip(nupkgPath);
            nupkg.AssertContainsEntry(nupkgPath, $"lib/{dotnetTargetFramework}/{proj.ProjectName}.dll");
            nupkg.AssertContainsEntry(nupkgPath, $"lib/{legacyTargetFramework}/{proj.ProjectName}.dll");
        }
示例#3
0
        public void DotNetBuildBinding()
        {
            var proj = new XASdkProject(outputType: "Library");

            proj.OtherBuildItems.Add(new AndroidItem.AndroidLibrary("javaclasses.jar")
            {
                MetadataValues = "Bind=true",
                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)
            //});
            var dotnet = CreateDotNetBuilder(proj);

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

            var assemblyPath = Path.Combine(FullProjectDirectory, proj.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}");
            }
        }
示例#4
0
        public void DotNetPublish([Values(false, true)] bool isRelease)
        {
            const string runtimeIdentifier = "android.21-arm";
            var          proj = new XASdkProject {
                IsRelease = isRelease
            };

            proj.SetProperty(KnownProperties.RuntimeIdentifier, runtimeIdentifier);
            var dotnet = CreateDotNetBuilder(proj);

            Assert.IsTrue(dotnet.Publish(), "first `dotnet publish` should succeed");

            var publishDirectory = Path.Combine(FullProjectDirectory, proj.OutputPath, runtimeIdentifier, "publish");
            var apk       = Path.Combine(publishDirectory, $"{proj.PackageName}.apk");
            var apkSigned = Path.Combine(publishDirectory, $"{proj.PackageName}-Signed.apk");

            FileAssert.Exists(apk);
            FileAssert.Exists(apkSigned);

            Assert.IsTrue(dotnet.Publish(parameters: new [] { "AndroidPackageFormat=aab" }), $"second `dotnet publish` should succeed");
            var aab       = Path.Combine(publishDirectory, $"{proj.PackageName}.aab");
            var aabSigned = Path.Combine(publishDirectory, $"{proj.PackageName}-Signed.aab");

            FileAssert.DoesNotExist(apk);
            FileAssert.DoesNotExist(apkSigned);
            FileAssert.Exists(aab);
            FileAssert.Exists(aabSigned);
        }
示例#5
0
        public void SignAndroidPackage()
        {
            var proj       = new XASdkProject();
            var builder    = CreateDotNetBuilder(proj);
            var parameters = new [] { "BuildingInsideVisualStudio=true" };

            Assert.IsTrue(builder.Build("SignAndroidPackage", parameters), $"{proj.ProjectName} should succeed");
        }
        public void DotNetBuild([Values(false, true)] bool isRelease)
        {
            var proj = new XASdkProject(SdkVersion)
            {
                IsRelease = isRelease
            };
            var dotnet = CreateDotNetBuilder(proj);

            Assert.IsTrue(dotnet.Build(), "`dotnet build` should succeed");
        }
示例#7
0
        public void BuildXASdkProject([Values(false, true)] bool isRelease)
        {
            var proj = new XASdkProject("0.0.1")
            {
                IsRelease = isRelease
            };

            using (var b = CreateApkBuilder(Path.Combine("temp", TestName))) {
                Assert.IsTrue(b.Build(proj), "Build should have succeeded.");
            }
        }
        public void DotNetPublish([Values(false, true)] bool isRelease)
        {
            var proj = new XASdkProject(SdkVersion)
            {
                IsRelease = isRelease
            };

            proj.SetProperty(KnownProperties.AndroidLinkMode, AndroidLinkMode.None.ToString());
            var dotnet = CreateDotNetBuilder(proj);

            Assert.IsTrue(dotnet.Publish(), "`dotnet publish` should succeed");
        }
        public void BuildWithLiteSdk()
        {
            var proj = new XASdkProject()
            {
                Sdk             = $"Xamarin.Android.Sdk.Lite/{SdkVersion}",
                TargetFramework = "monoandroid10.0"
            };

            using (var b = CreateApkBuilder(Path.Combine("temp", TestName))) {
                Assert.IsTrue(b.Build(proj), "Build should have succeeded.");
            }
        }
示例#10
0
        DotNetCLI CreateDotNetBuilder(XASdkProject project)
        {
            var relativeProjDir = Path.Combine("temp", TestName);
            var fullProjDir     = Path.Combine(Root, relativeProjDir);

            TestOutputDirectories [TestContext.CurrentContext.Test.ID] = fullProjDir;
            var files = project.Save();

            project.Populate(relativeProjDir, files);
            project.CopyNuGetConfig(relativeProjDir);
            return(new DotNetCLI(project, Path.Combine(fullProjDir, project.ProjectFilePath)));
        }
示例#11
0
        DotNetCLI CreateDotNetBuilder(XASdkProject project, string relativeProjectDir = null)
        {
            if (string.IsNullOrEmpty(relativeProjectDir))
            {
                relativeProjectDir = Path.Combine("temp", TestName);
            }
            TestOutputDirectories [TestContext.CurrentContext.Test.ID] =
                FullProjectDirectory = Path.Combine(Root, relativeProjectDir);
            var files = project.Save();

            project.Populate(relativeProjectDir, files);
            project.CopyNuGetConfig(relativeProjectDir);
            return(new DotNetCLI(project, Path.Combine(FullProjectDirectory, project.ProjectFilePath)));
        }
示例#12
0
        public void DotNetPack([Values("net6.0-android", "net6.0-android30")] string targetFramework)
        {
            var proj = new XASdkProject(outputType: "Library")
            {
                TargetFramework = targetFramework,
                IsRelease       = true,
                Sources         =
                {
                    new BuildItem.Source("Foo.cs")
                    {
                        TextContent = () => "public class Foo { }",
                    }
                }
            };

            proj.OtherBuildItems.Add(new AndroidItem.AndroidResource("Resources\\raw\\bar.txt")
            {
                BinaryContent = () => Array.Empty <byte> (),
            });
            proj.OtherBuildItems.Add(new AndroidItem.AndroidLibrary("sub\\directory\\foo.jar")
            {
                BinaryContent = () => ResourceData.JavaSourceJarTestJar,
            });
            proj.OtherBuildItems.Add(new AndroidItem.AndroidLibrary("sub\\directory\\arm64-v8a\\libfoo.so")
            {
                BinaryContent = () => Array.Empty <byte> (),
            });
            proj.OtherBuildItems.Add(new AndroidItem.AndroidNativeLibrary(default(Func <string>))
            {
                Update         = () => "libfoo.so",
                MetadataValues = "Link=x86\\libfoo.so",
                BinaryContent  = () => Array.Empty <byte> (),
            });

            var dotnet = CreateDotNetBuilder(proj);

            Assert.IsTrue(dotnet.Pack(), "`dotnet pack` should succeed");

            var nupkgPath = Path.Combine(FullProjectDirectory, proj.OutputPath, "..", $"{proj.ProjectName}.1.0.0.nupkg");

            FileAssert.Exists(nupkgPath);
            using (var nupkg = ZipHelper.OpenZip(nupkgPath)) {
                nupkg.AssertContainsEntry(nupkgPath, $"lib/net6.0-android30.0/{proj.ProjectName}.dll");
                nupkg.AssertContainsEntry(nupkgPath, $"lib/net6.0-android30.0/{proj.ProjectName}.aar");
            }
        }
示例#13
0
        public void DotNetPack()
        {
            var proj = new XASdkProject(outputType: "Library")
            {
                IsRelease = true,
                Sources   =
                {
                    new BuildItem.Source("Foo.cs")
                    {
                        TextContent = () => "public class Foo { }",
                    }
                }
            };

            proj.OtherBuildItems.Add(new AndroidItem.AndroidResource("Resources\\raw\\bar.txt")
            {
                BinaryContent = () => Array.Empty <byte> (),
            });
            proj.OtherBuildItems.Add(new AndroidItem.AndroidLibrary("sub\\directory\\foo.jar")
            {
                BinaryContent = () => Convert.FromBase64String(InlineData.JavaClassesJarBase64),
            });
            proj.OtherBuildItems.Add(new AndroidItem.AndroidLibrary("sub\\directory\\arm64-v8a\\libfoo.so")
            {
                BinaryContent = () => Array.Empty <byte> (),
            });
            proj.OtherBuildItems.Add(new AndroidItem.AndroidLibrary("libfoo.so")
            {
                MetadataValues = "Link=x86\\libfoo.so",
                BinaryContent  = () => Array.Empty <byte> (),
            });

            var dotnet = CreateDotNetBuilder(proj);

            Assert.IsTrue(dotnet.Pack(), "`dotnet pack` should succeed");

            var nupkgPath = Path.Combine(FullProjectDirectory, proj.OutputPath, "..", $"{proj.ProjectName}.1.0.0.nupkg");

            FileAssert.Exists(nupkgPath);
            using (var nupkg = ZipHelper.OpenZip(nupkgPath)) {
                // TODO: should eventually be $"lib/net5.0-android/{proj.ProjectName}.dll"
                // See: https://github.com/dotnet/sdk/issues/14042
                nupkg.AssertContainsEntry(nupkgPath, $"lib/net5.0/{proj.ProjectName}.dll");
                nupkg.AssertContainsEntry(nupkgPath, $"lib/net5.0-android/{proj.ProjectName}.aar");
            }
        }
示例#14
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.");
            }
        }
示例#15
0
        public void DotNetLibraryAarChanges()
        {
            var proj = new XASdkProject(outputType: "Library");

            proj.Sources.Add(new AndroidItem.AndroidResource("Resources\\raw\\foo.txt")
            {
                TextContent = () => "foo",
            });
            proj.Sources.Add(new AndroidItem.AndroidResource("Resources\\raw\\bar.txt")
            {
                TextContent = () => "bar",
            });

            var dotnet = CreateDotNetBuilder(proj);

            Assert.IsTrue(dotnet.Build(), "first build should succeed");
            var aarPath = Path.Combine(FullProjectDirectory, proj.OutputPath, $"{proj.ProjectName}.aar");

            FileAssert.Exists(aarPath);
            using (var aar = ZipHelper.OpenZip(aarPath)) {
                aar.AssertEntryContents(aarPath, "res/raw/foo.txt", contents: "foo");
                aar.AssertEntryContents(aarPath, "res/raw/bar.txt", contents: "bar");
            }

            // Change res/raw/bar.txt contents
            WaitFor(1000);
            var bar_txt = Path.Combine(FullProjectDirectory, "Resources", "raw", "bar.txt");

            File.WriteAllText(bar_txt, contents: "baz");
            Assert.IsTrue(dotnet.Build(), "second build should succeed");
            FileAssert.Exists(aarPath);
            using (var aar = ZipHelper.OpenZip(aarPath)) {
                aar.AssertEntryContents(aarPath, "res/raw/foo.txt", contents: "foo");
                aar.AssertEntryContents(aarPath, "res/raw/bar.txt", contents: "baz");
            }

            // Delete res/raw/bar.txt
            File.Delete(bar_txt);
            Assert.IsTrue(dotnet.Build(), "third build should succeed");
            FileAssert.Exists(aarPath);
            using (var aar = ZipHelper.OpenZip(aarPath)) {
                aar.AssertEntryContents(aarPath, "res/raw/foo.txt", contents: "foo");
                aar.AssertDoesNotContainEntry(aarPath, "res/raw/bar.txt");
            }
        }
示例#16
0
        public void DotNetInstallAndRun([Values(false, true)] bool isRelease, [Values(false, true)] bool xamarinForms)
        {
            if (!HasDevices)
            {
                Assert.Ignore("Skipping Test. No devices available.");
            }

            XASdkProject proj;

            if (xamarinForms)
            {
                proj = new XamarinFormsXASdkProject(SdkVersion)
                {
                    IsRelease = isRelease
                };
            }
            else
            {
                proj = new XASdkProject(SdkVersion)
                {
                    IsRelease = isRelease
                };
            }
            proj.SetProperty(KnownProperties.AndroidSupportedAbis, DeviceAbi);
            proj.SetRuntimeIdentifier(DeviceAbi);

            var relativeProjDir = Path.Combine("temp", TestName);
            var fullProjDir     = Path.Combine(Root, relativeProjDir);

            TestOutputDirectories [TestContext.CurrentContext.Test.ID] = fullProjDir;
            var files = proj.Save();

            proj.Populate(relativeProjDir, files);
            proj.CopyNuGetConfig(relativeProjDir);
            var dotnet = new DotNetCLI(proj, Path.Combine(fullProjDir, proj.ProjectFilePath));

            Assert.IsTrue(dotnet.Run(), "`dotnet run` should succeed");
            bool didLaunch = WaitForActivityToStart(proj.PackageName, "MainActivity",
                                                    Path.Combine(fullProjDir, "logcat.log"), 30);

            RunAdbCommand($"uninstall {proj.PackageName}");
            Assert.IsTrue(didLaunch, "Activity should have started.");
        }
示例#17
0
        public void DotNetPackageXASdkProject([Values(false, true)] bool isRelease)
        {
            var proj = new XASdkProject("0.0.1")
            {
                IsRelease = isRelease
            };
            var relativeProjDir = Path.Combine("temp", TestName);
            var fullProjDir     = Path.Combine(Root, relativeProjDir);

            TestOutputDirectories [TestContext.CurrentContext.Test.ID] = fullProjDir;
            var files = proj.Save();

            proj.Populate(relativeProjDir, files);
            proj.CopyNuGetConfig(relativeProjDir);

            var dotnet = new DotNetCLI();

            Assert.IsTrue(dotnet.Build(Path.Combine(fullProjDir, proj.ProjectFilePath), proj.Configuration, "SignAndroidPackage"));
        }
        public void DotNetInstallAndRun(bool isRelease, bool xamarinForms, bool?publishTrimmed)
        {
            AssertHasDevices();

            XASdkProject proj;

            if (xamarinForms)
            {
                proj = new XamarinFormsXASdkProject {
                    IsRelease = isRelease
                };
            }
            else
            {
                proj = new XASdkProject {
                    IsRelease = isRelease
                };
            }
            if (publishTrimmed != null)
            {
                proj.SetProperty(KnownProperties.PublishTrimmed, publishTrimmed.ToString());
            }
            proj.SetRuntimeIdentifier(DeviceAbi);

            var relativeProjDir = Path.Combine("temp", TestName);
            var fullProjDir     = Path.Combine(Root, relativeProjDir);

            TestOutputDirectories [TestContext.CurrentContext.Test.ID] = fullProjDir;
            var files = proj.Save();

            proj.Populate(relativeProjDir, files);
            proj.CopyNuGetConfig(relativeProjDir);
            var dotnet = new DotNetCLI(proj, Path.Combine(fullProjDir, proj.ProjectFilePath));

            Assert.IsTrue(dotnet.Run(), "`dotnet run` should succeed");
            WaitForPermissionActivity(Path.Combine(Root, dotnet.ProjectDirectory, "permission-logcat.log"));
            bool didLaunch = WaitForActivityToStart(proj.PackageName, "MainActivity",
                                                    Path.Combine(fullProjDir, "logcat.log"), 30);

            RunAdbCommand($"uninstall {proj.PackageName}");
            Assert.IsTrue(didLaunch, "Activity should have started.");
        }
示例#19
0
        string PrepareProject(string testName)
        {
            string tempRoot             = Path.Combine(TestOutputDir, testName, XABuildPaths.Configuration);
            string temporaryProjectPath = Path.Combine(tempRoot, "project");

            var ignore = new HashSet <string> {
                Path.Combine(TestProjectRootDirectory, "bin"),
                Path.Combine(TestProjectRootDirectory, "obj"),
                Path.Combine(CommonSampleLibraryRootDirectory, "bin"),
                Path.Combine(CommonSampleLibraryRootDirectory, "obj"),
            };

            CopyRecursively(TestProjectRootDirectory, temporaryProjectPath, ignore);
            CopyRecursively(CommonSampleLibraryRootDirectory, Path.Combine(tempRoot, CommonSampleLibraryName), ignore);
            if (Builder.UseDotNet)
            {
                XASdkProject.SaveNuGetConfig(tempRoot);
            }
            return(temporaryProjectPath);
        }
示例#20
0
        public void MauiTargetFramework([Values("net6.0-android", "net6.0-android30", "net6.0-android30.0")] string targetFramework)
        {
            var library = new XASdkProject(outputType: "Library")
            {
                TargetFramework = targetFramework,
            };

            library.ExtraNuGetConfigSources.Add("https://pkgs.dev.azure.com/azure-public/vside/_packaging/xamarin-impl/nuget/v3/index.json");
            library.Sources.Clear();
            library.Sources.Add(new BuildItem.Source("Foo.cs")
            {
                TextContent = () =>
                              @"using Microsoft.Maui;
using Microsoft.Maui.Handlers;

public abstract class Foo<TVirtualView, TNativeView> : AbstractViewHandler<TVirtualView, TNativeView>
	where TVirtualView : class, IView
#if ANDROID
	where TNativeView : Android.Views.View
#else
	where TNativeView : class
#endif
{
		protected Foo (PropertyMapper mapper) : base(mapper)
		{
#if ANDROID
			var t = this.Context;
#endif
		}
}",
            });

            library.PackageReferences.Add(new Package {
                Id = "Microsoft.Maui.Core", Version = "6.0.100-preview.3.269"
            });

            var dotnet = CreateDotNetBuilder(library);

            Assert.IsTrue(dotnet.Build(), $"{library.ProjectName} should succeed");
            dotnet.AssertHasNoWarnings();
        }
示例#21
0
        public void DotNetBuildBinding()
        {
            var proj = new XASdkProject(outputType: "Library");

            // Both transform files should be applied
            proj.Sources.Add(new AndroidItem.TransformFile("Transforms.xml")
            {
                TextContent = () =>
                              @"<metadata>
  <attr path=""/api/package[@name='com.xamarin.android.test.msbuildtest']"" name=""managedName"">FooBar</attr>
</metadata>",
            });
            proj.Sources.Add(new AndroidItem.TransformFile("Transforms\\Metadata.xml")
            {
                TextContent = () =>
                              @"<metadata>
  <attr path=""/api/package[@managedName='FooBar']"" name=""managedName"">MSBuildTest</attr>
</metadata>",
            });
            proj.Sources.Add(new AndroidItem.AndroidLibrary("javaclasses.jar")
            {
                BinaryContent = () => ResourceData.JavaSourceJarTestJar,
            });
            proj.OtherBuildItems.Add(new BuildItem("JavaSourceJar", "javaclasses-sources.jar")
            {
                BinaryContent = () => ResourceData.JavaSourceJarTestSourcesJar,
            });
            var dotnet = CreateDotNetBuilder(proj);

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

            var assemblyPath = Path.Combine(FullProjectDirectory, proj.OutputPath, "UnnamedProject.dll");

            FileAssert.Exists(assemblyPath);
            using (var assembly = AssemblyDefinition.ReadAssembly(assemblyPath)) {
                var typeName = "MSBuildTest.JavaSourceJarTest";
                var type     = assembly.MainModule.GetType(typeName);
                Assert.IsNotNull(type, $"{assemblyPath} should contain {typeName}");
            }
        }
示例#22
0
        public void DotNetIncremental()
        {
            // Setup dependencies App A -> Lib B
            var path = Path.Combine("temp", TestName);

            var libB = new XASdkProject(outputType: "Library")
            {
                ProjectName = "LibraryB"
            };

            libB.Sources.Clear();
            libB.Sources.Add(new BuildItem.Source("Foo.cs")
            {
                TextContent = () => "public class Foo { }",
            });

            // Will save the project, does not need to build it
            CreateDotNetBuilder(libB, Path.Combine(path, libB.ProjectName));

            var appA = new XASdkProject {
                ProjectName = "AppA",
                Sources     =
                {
                    new BuildItem.Source("Bar.cs")
                    {
                        TextContent = () => "public class Bar : Foo { }",
                    }
                }
            };

            appA.AddReference(libB);
            var appBuilder = CreateDotNetBuilder(appA, Path.Combine(path, appA.ProjectName));

            Assert.IsTrue(appBuilder.Build(), $"{appA.ProjectName} should succeed");
            appBuilder.AssertTargetIsNotSkipped("CoreCompile");

            // Build again, no changes
            Assert.IsTrue(appBuilder.Build(), $"{appA.ProjectName} should succeed");
            appBuilder.AssertTargetIsSkipped("CoreCompile");
        }
示例#23
0
        public void DotNetBuildLibrary([Values(false, true)] bool isRelease)
        {
            var proj = new XASdkProject(outputType: "Library")
            {
                IsRelease = isRelease
            };
            var dotnet = CreateDotNetBuilder(proj);

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

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

            FileAssert.Exists(assemblyPath);
            using (var assembly = AssemblyDefinition.ReadAssembly(assemblyPath)) {
                var resourceName = "__AndroidLibraryProjects__.zip";
                var resource     = assembly.MainModule.Resources.OfType <EmbeddedResource> ().FirstOrDefault(r => r.Name == resourceName);
                Assert.IsNotNull(resource, $"{assemblyPath} should contain a {resourceName} EmbeddedResource");
                using (var zip = ZipArchive.Open(resource.GetResourceStream())) {
                    var entry = "library_project_imports/res/values/strings.xml";
                    Assert.IsTrue(zip.ContainsEntry(entry), $"{resourceName} should contain {entry}");
                }
            }
        }
示例#24
0
        public void DefaultItems()
        {
            void CreateEmptyFile(params string [] paths)
            {
                var path = Path.Combine(FullProjectDirectory, Path.Combine(paths));

                Directory.CreateDirectory(Path.GetDirectoryName(path));
                File.WriteAllText(path, contents: "");
            }

            var proj   = new XASdkProject();
            var dotnet = CreateDotNetBuilder(proj);

            // Build error -> no nested sub-directories in Resources
            CreateEmptyFile("Resources", "drawable", "foo", "bar.png");
            CreateEmptyFile("Resources", "raw", "foo", "bar.png");

            // Build error -> no files/directories that start with .
            CreateEmptyFile("Resources", "raw", ".DS_Store");
            CreateEmptyFile("Assets", ".DS_Store");
            CreateEmptyFile("Assets", ".svn", "foo.txt");

            // Files that should work
            CreateEmptyFile("Resources", "raw", "foo.txt");
            CreateEmptyFile("Assets", "foo", "bar.txt");

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

            var apkPath = Path.Combine(FullProjectDirectory, proj.OutputPath, $"{proj.PackageName}.apk");

            FileAssert.Exists(apkPath);
            using (var apk = ZipHelper.OpenZip(apkPath)) {
                apk.AssertContainsEntry(apkPath, "res/raw/foo.txt");
                apk.AssertContainsEntry(apkPath, "assets/foo/bar.txt");
            }
        }
示例#25
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);
                    }
                }
            }
        }
示例#26
0
        public void DotNetBuildLibrary(bool isRelease, bool duplicateAar)
        {
            var path    = Path.Combine("temp", TestName);
            var env_var = "MY_ENVIRONMENT_VAR";
            var env_val = "MY_VALUE";

            // Setup dependencies App A -> Lib B -> Lib C

            var libC = new XASdkProject(outputType: "Library")
            {
                ProjectName = "LibraryC",
                IsRelease   = isRelease,
                Sources     =
                {
                    new BuildItem.Source("Bar.cs")
                    {
                        TextContent = () => "public class Bar { }",
                    }
                }
            };

            libC.OtherBuildItems.Add(new AndroidItem.AndroidAsset("Assets\\bar\\bar.txt")
            {
                BinaryContent = () => Array.Empty <byte> (),
            });
            var activity = libC.Sources.FirstOrDefault(s => s.Include() == "MainActivity.cs");

            if (activity != null)
            {
                libC.Sources.Remove(activity);
            }
            var libCBuilder = CreateDotNetBuilder(libC, Path.Combine(path, libC.ProjectName));

            Assert.IsTrue(libCBuilder.Build(), $"{libC.ProjectName} should succeed");

            var libB = new XASdkProject(outputType: "Library")
            {
                ProjectName = "LibraryB",
                IsRelease   = isRelease,
                Sources     =
                {
                    new BuildItem.Source("Foo.cs")
                    {
                        TextContent = () => "public class Foo : Bar { }",
                    }
                }
            };

            libB.OtherBuildItems.Add(new AndroidItem.AndroidAsset("Assets\\foo\\foo.txt")
            {
                BinaryContent = () => Array.Empty <byte> (),
            });
            libB.OtherBuildItems.Add(new AndroidItem.AndroidResource("Resources\\layout\\MyLayout.axml")
            {
                TextContent = () => "<?xml version=\"1.0\" encoding=\"utf-8\" ?><LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\" />"
            });
            libB.OtherBuildItems.Add(new AndroidItem.AndroidResource("Resources\\raw\\bar.txt")
            {
                BinaryContent = () => Array.Empty <byte> (),
            });
            libB.OtherBuildItems.Add(new AndroidItem.AndroidEnvironment("env.txt")
            {
                TextContent = () => $"{env_var}={env_val}",
            });
            libB.OtherBuildItems.Add(new AndroidItem.AndroidEnvironment("sub\\directory\\env.txt")
            {
                TextContent = () => $"{env_var}={env_val}",
            });
            libB.OtherBuildItems.Add(new AndroidItem.AndroidLibrary("sub\\directory\\foo.jar")
            {
                BinaryContent = () => Convert.FromBase64String(InlineData.JavaClassesJarBase64),
            });
            libB.OtherBuildItems.Add(new AndroidItem.AndroidLibrary("sub\\directory\\arm64-v8a\\libfoo.so")
            {
                BinaryContent = () => Array.Empty <byte> (),
            });
            libB.OtherBuildItems.Add(new AndroidItem.AndroidLibrary("libfoo.so")
            {
                MetadataValues = "Link=x86\\libfoo.so",
                BinaryContent  = () => Array.Empty <byte> (),
            });
            libB.AddReference(libC);

            activity = libB.Sources.FirstOrDefault(s => s.Include() == "MainActivity.cs");
            if (activity != null)
            {
                libB.Sources.Remove(activity);
            }
            var libBBuilder = CreateDotNetBuilder(libB, Path.Combine(path, libB.ProjectName));

            Assert.IsTrue(libBBuilder.Build(), $"{libB.ProjectName} should succeed");

            // Check .aar file for class library
            var aarPath = Path.Combine(FullProjectDirectory, libB.OutputPath, $"{libB.ProjectName}.aar");

            FileAssert.Exists(aarPath);
            using (var aar = ZipHelper.OpenZip(aarPath)) {
                aar.AssertContainsEntry(aarPath, "assets/foo/foo.txt");
                aar.AssertContainsEntry(aarPath, "res/layout/mylayout.xml");
                aar.AssertContainsEntry(aarPath, "res/raw/bar.txt");
                aar.AssertContainsEntry(aarPath, ".net/__res_name_case_map.txt");
                aar.AssertContainsEntry(aarPath, ".net/env/190E30B3D205731E.env");
                aar.AssertContainsEntry(aarPath, ".net/env/2CBDAB7FEEA94B19.env");
                aar.AssertContainsEntry(aarPath, "libs/A1AFA985571E728E.jar");
                aar.AssertContainsEntry(aarPath, "jni/arm64-v8a/libfoo.so");
                aar.AssertContainsEntry(aarPath, "jni/x86/libfoo.so");
            }

            // Check EmbeddedResource files do not exist
            var assemblyPath = Path.Combine(FullProjectDirectory, libB.OutputPath, $"{libB.ProjectName}.dll");

            FileAssert.Exists(assemblyPath);
            using (var assembly = AssemblyDefinition.ReadAssembly(assemblyPath)) {
                Assert.AreEqual(0, assembly.MainModule.Resources.Count);
            }

            var appA = new XASdkProject {
                ProjectName = "AppA",
                IsRelease   = isRelease,
                Sources     =
                {
                    new BuildItem.Source("Bar.cs")
                    {
                        TextContent = () => "public class Bar : Foo { }",
                    }
                }
            };

            appA.AddReference(libB);
            if (duplicateAar)
            {
                // Test a duplicate @(AndroidLibrary) item with the same path of LibraryB.aar
                appA.OtherBuildItems.Add(new AndroidItem.AndroidLibrary(aarPath));
            }
            var appBuilder = CreateDotNetBuilder(appA, Path.Combine(path, appA.ProjectName));

            Assert.IsTrue(appBuilder.Build(), $"{appA.ProjectName} should succeed");

            // Check .apk for assets, res, and native libraries
            var apkPath = Path.Combine(FullProjectDirectory, appA.OutputPath, $"{appA.PackageName}.apk");

            FileAssert.Exists(apkPath);
            using (var apk = ZipHelper.OpenZip(apkPath)) {
                apk.AssertContainsEntry(apkPath, "assets/foo/foo.txt");
                apk.AssertContainsEntry(apkPath, "assets/bar/bar.txt");
                apk.AssertContainsEntry(aarPath, "res/layout/mylayout.xml");
                apk.AssertContainsEntry(apkPath, "res/raw/bar.txt");
                apk.AssertContainsEntry(apkPath, "lib/arm64-v8a/libfoo.so");
                apk.AssertContainsEntry(apkPath, "lib/x86/libfoo.so");
            }

            // Check classes.dex contains foo.jar
            var intermediate = Path.Combine(FullProjectDirectory, appA.IntermediateOutputPath);
            var dexFile      = Path.Combine(intermediate, "android", "bin", "classes.dex");

            FileAssert.Exists(dexFile);
            string className = "Lcom/xamarin/android/test/msbuildtest/JavaSourceJarTest;";

            Assert.IsTrue(DexUtils.ContainsClass(className, dexFile, AndroidSdkPath), $"`{dexFile}` should include `{className}`!");

            // Check environment variable
            var environmentFiles     = EnvironmentHelper.GatherEnvironmentFiles(intermediate, "x86", required: true);
            var environmentVariables = EnvironmentHelper.ReadEnvironmentVariables(environmentFiles);

            Assert.IsTrue(environmentVariables.TryGetValue(env_var, out string actual), $"Environment should contain {env_var}");
            Assert.AreEqual(env_val, actual, $"{env_var} should be {env_val}");

            // Check Resource.designer.cs
            var resource_designer_cs = Path.Combine(intermediate, "Resource.designer.cs");

            FileAssert.Exists(resource_designer_cs);
            var resource_designer_text = File.ReadAllText(resource_designer_cs);

            StringAssert.Contains("public const int MyLayout", resource_designer_text);
        }
示例#27
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 DotNetDebug()
        {
            AssertCommercialBuild();
            AssertHasDevices();

            XASdkProject proj;

            proj = new XASdkProject {
                //TODO: targetSdkVersion="30" causes a crash on startup in .NET 5
                MinSdkVersion    = null,
                TargetSdkVersion = null,
            };
            proj.SetRuntimeIdentifier(DeviceAbi);

            var relativeProjDir = Path.Combine("temp", TestName);
            var fullProjDir     = Path.Combine(Root, relativeProjDir);

            TestOutputDirectories [TestContext.CurrentContext.Test.ID] = fullProjDir;
            var files = proj.Save();

            proj.Populate(relativeProjDir, files);
            proj.CopyNuGetConfig(relativeProjDir);
            var dotnet = new DotNetCLI(proj, Path.Combine(fullProjDir, proj.ProjectFilePath));

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

            bool             breakpointHit = false;
            ManualResetEvent resetEvent    = new ManualResetEvent(false);
            var sw = new Stopwatch();
            // setup the debugger
            var session = new SoftDebuggerSession();

            session.Breakpoints = new BreakpointStore {
                { Path.Combine(Root, dotnet.ProjectDirectory, "MainActivity.cs"), 19 },
            };
            session.TargetHitBreakpoint += (sender, e) => {
                Console.WriteLine($"BREAK {e.Type}");
                breakpointHit = true;
                session.Continue();
            };
            var rnd  = new Random();
            int port = rnd.Next(10000, 20000);

            TestContext.Out.WriteLine($"{port}");
            var args = new SoftDebuggerConnectArgs("", IPAddress.Loopback, port)
            {
                MaxConnectionAttempts = 10,
            };
            var startInfo = new SoftDebuggerStartInfo(args)
            {
                WorkingDirectory = Path.Combine(dotnet.ProjectDirectory, proj.IntermediateOutputPath, "android", "assets"),
            };
            var options = new DebuggerSessionOptions()
            {
                EvaluationOptions = EvaluationOptions.DefaultOptions,
            };

            options.EvaluationOptions.UseExternalTypeResolver = true;
            ClearAdbLogcat();
            Assert.True(dotnet.Build("Run", new string [] {
                $"AndroidSdbTargetPort={port}",
                $"AndroidSdbHostPort={port}",
                "AndroidAttachDebugger=True",
            }), "Project should have run.");

            Assert.IsTrue(WaitForDebuggerToStart(Path.Combine(Root, dotnet.ProjectDirectory, "logcat.log")), "Activity should have started");
            // we need to give a bit of time for the debug server to start up.
            WaitFor(2000);
            session.LogWriter    += (isStderr, text) => { Console.WriteLine(text); };
            session.OutputWriter += (isStderr, text) => { Console.WriteLine(text); };
            session.DebugWriter  += (level, category, message) => { Console.WriteLine(message); };
            session.Run(startInfo, options);
            WaitFor(TimeSpan.FromSeconds(30), () => session.IsConnected);
            Assert.True(session.IsConnected, "Debugger should have connected but it did not.");
            // we need to wait here for a while to allow the breakpoints to hit
            // but we need to timeout
            TimeSpan timeout = TimeSpan.FromSeconds(60);

            while (session.IsConnected && !breakpointHit && timeout >= TimeSpan.Zero)
            {
                Thread.Sleep(10);
                timeout = timeout.Subtract(TimeSpan.FromMilliseconds(10));
            }
            WaitFor(2000);
            Assert.IsTrue(breakpointHit, "Should have a breakpoint");
        }
示例#29
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"
                    },
                    new Package {
                        Id = "Microsoft.AspNetCore.Components.WebView", Version = "6.0.0-preview.5.21301.17"
                    },
                    new Package {
                        Id = "Microsoft.Extensions.FileProviders.Embedded", Version = "6.0.0-preview.6.21306.3"
                    },
                    new Package {
                        Id = "Microsoft.JSInterop", Version = "6.0.0-preview.6.21306.3"
                    },
                    new Package {
                        Id = "System.Text.Json", Version = "6.0.0-preview.7.21323.3"
                    },
                },
                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");
            dotnet.AssertHasNoWarnings();

            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}.runtimeconfig.json",
                $"{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);
                    }
                }
            }
        }
示例#30
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);
                    }
                }
            }
        }