public void ConvertCustomView([Values(true, false)] bool useAapt2) { var path = Path.Combine("temp", TestName); var app = new XamarinAndroidApplicationProject { ProjectName = "MyApp", Sources = { new BuildItem.Source("Foo.cs") { TextContent = () => "public class Foo : Bar { }" }, new BuildItem.Source("CustomTextView.cs") { TextContent = () => @"using Android.Widget; using Android.Content; using Android.Util; namespace MyApp { public class CustomTextView : TextView { public CustomTextView(Context context, IAttributeSet attributes) : base(context, attributes) { } } }" } } }; // Use a custom view app.LayoutMain = app.LayoutMain.Replace("</LinearLayout>", "<MyApp.CustomTextView android:id=\"@+id/myText\" /></LinearLayout>"); //NOTE: so _BuildApkEmbed runs in commercial tests app.SetProperty("EmbedAssembliesIntoApk", "True"); app.SetProperty("AndroidUseSharedRuntime", "False"); app.SetProperty("AndroidUseAapt2", useAapt2.ToString()); int count = 0; var lib = new DotNetStandard { ProjectName = "MyLibrary", Sdk = "Microsoft.NET.Sdk", TargetFramework = "netstandard2.0", Sources = { new BuildItem.Source("Bar.cs") { TextContent = () => "public class Bar { public Bar () { System.Console.WriteLine (" + count++ + "); } }" }, } }; //NOTE: this test is checking when $(ProduceReferenceAssembly) is False lib.SetProperty("ProduceReferenceAssembly", "False"); app.References.Add(new BuildItem.ProjectReference($"..\\{lib.ProjectName}\\{lib.ProjectName}.csproj", lib.ProjectName, lib.ProjectGuid)); using (var libBuilder = CreateDllBuilder(Path.Combine(path, lib.ProjectName), false)) using (var appBuilder = CreateApkBuilder(Path.Combine(path, app.ProjectName))) { Assert.IsTrue(libBuilder.Build(lib), "first library build should have succeeded."); Assert.IsTrue(appBuilder.Build(app), "first app build should have succeeded."); lib.Touch("Bar.cs"); Assert.IsTrue(libBuilder.Build(lib, doNotCleanupOnUpdate: true, saveProject: false), "second library build should have succeeded."); Assert.IsTrue(appBuilder.Build(app, doNotCleanupOnUpdate: true, saveProject: false), "second app build should have succeeded."); var targetsShouldSkip = new [] { "_BuildLibraryImportsCache", "_ResolveLibraryProjectImports", "_ConvertCustomView", }; foreach (var target in targetsShouldSkip) { Assert.IsTrue(appBuilder.Output.IsTargetSkipped(target), $"`{target}` should be skipped!"); } var targetsShouldRun = new [] { //MyLibrary.dll changed and $(ProduceReferenceAssembly)=False "CoreCompile", "_GenerateJavaStubs", "_BuildApkEmbed", "_CopyPackage", "_Sign", }; foreach (var target in targetsShouldRun) { Assert.IsFalse(appBuilder.Output.IsTargetSkipped(target), $"`{target}` should *not* be skipped!"); } } }
public void IncrementalFastDeployment() { AssertCommercialBuild(); AssertHasDevices(); var class1src = new BuildItem.Source("Class1.cs") { TextContent = () => "namespace Library1 { public class Class1 { public static int foo = 0; } }" }; var lib1 = new XamarinAndroidLibraryProject() { ProjectName = "Library1", Sources = { class1src, } }; var class2src = new BuildItem.Source("Class2.cs") { TextContent = () => "namespace Library2 { public class Class2 { public static int foo = 0; } }" }; var lib2 = new DotNetStandard { ProjectName = "Library2", Sdk = "Microsoft.NET.Sdk", TargetFramework = "netstandard2.0", Sources = { class2src, } }; var app = new XamarinFormsAndroidApplicationProject() { EmbedAssembliesIntoApk = false, References = { new BuildItem("ProjectReference", "..\\Library1\\Library1.csproj"), new BuildItem("ProjectReference", "..\\Library2\\Library2.csproj"), }, }; // Set up library projects var rootPath = Path.Combine(Root, "temp", TestName); using (var lb1 = CreateDllBuilder(Path.Combine(rootPath, lib1.ProjectName))) Assert.IsTrue(lb1.Build(lib1), "First library build should have succeeded."); using (var lb2 = CreateDllBuilder(Path.Combine(rootPath, lib2.ProjectName))) Assert.IsTrue(lb2.Build(lib2), "Second library build should have succeeded."); long lib1FirstBuildSize = new FileInfo(Path.Combine(rootPath, lib1.ProjectName, lib1.OutputPath, "Library1.dll")).Length; using (var builder = CreateApkBuilder(Path.Combine(rootPath, app.ProjectName))) { builder.ThrowOnBuildFailure = false; builder.BuildLogFile = "install.log"; Assert.IsTrue(builder.Install(app), "First install should have succeeded."); var logLines = builder.LastBuildOutput; Assert.IsTrue(logLines.Any(l => l.Contains("NotifySync CopyFile") && l.Contains("UnnamedProject.dll")), "UnnamedProject.dll should have been uploaded"); Assert.IsTrue(logLines.Any(l => l.Contains("NotifySync CopyFile") && l.Contains("Library1.dll")), "Library1.dll should have been uploaded"); Assert.IsTrue(logLines.Any(l => l.Contains("NotifySync CopyFile") && l.Contains("Library2.dll")), "Library2.dll should have been uploaded"); var firstInstallTime = builder.LastBuildTime; builder.BuildLogFile = "install2.log"; Assert.IsTrue(builder.Install(app, doNotCleanupOnUpdate: true, saveProject: false), "Second install should have succeeded."); var secondInstallTime = builder.LastBuildTime; var filesToTouch = new [] { Path.Combine(rootPath, lib2.ProjectName, "Class2.cs"), Path.Combine(rootPath, app.ProjectName, "MainPage.xaml"), }; foreach (var file in filesToTouch) { FileAssert.Exists(file); File.SetLastWriteTimeUtc(file, DateTime.UtcNow); } class1src.TextContent = () => "namespace Library1 { public class Class1 { public static int foo = 100; } }"; class1src.Timestamp = DateTime.UtcNow.AddSeconds(1); using (var lb1 = CreateDllBuilder(Path.Combine(rootPath, lib1.ProjectName))) Assert.IsTrue(lb1.Build(lib1), "Second library build should have succeeded."); long lib1SecondBuildSize = new FileInfo(Path.Combine(rootPath, lib1.ProjectName, lib1.OutputPath, "Library1.dll")).Length; Assert.AreEqual(lib1FirstBuildSize, lib1SecondBuildSize, "Library2.dll was not the same size."); builder.BuildLogFile = "install3.log"; Assert.IsTrue(builder.Install(app, doNotCleanupOnUpdate: true, saveProject: false), "Third install should have succeeded."); logLines = builder.LastBuildOutput; Assert.IsTrue(logLines.Any(l => l.Contains("NotifySync CopyFile") && l.Contains("UnnamedProject.dll")), "UnnamedProject.dll should have been uploaded"); Assert.IsTrue(logLines.Any(l => l.Contains("NotifySync CopyFile") && l.Contains("Library1.dll")), "Library1.dll should have been uploaded"); Assert.IsTrue(logLines.Any(l => l.Contains("NotifySync SkipCopyFile") && l.Contains("Library2.dll")), "Library2.dll should not have been uploaded"); var thirdInstallTime = builder.LastBuildTime; builder.BuildLogFile = "install4.log"; Assert.IsTrue(builder.Install(app, doNotCleanupOnUpdate: true, saveProject: false), "Fourth install should have succeeded."); var fourthInstalTime = builder.LastBuildTime; Assert.IsTrue(thirdInstallTime < firstInstallTime, $"Third incremental install: '{thirdInstallTime}' should be faster than clean install: '{firstInstallTime}'."); Assert.IsTrue(secondInstallTime < firstInstallTime && secondInstallTime < thirdInstallTime, $"Second unchanged install: '{secondInstallTime}' should be faster than clean install: '{firstInstallTime}' and incremental install: '{thirdInstallTime}'."); Assert.IsTrue(fourthInstalTime < firstInstallTime && fourthInstalTime < thirdInstallTime, $"Fourth unchanged install: '{fourthInstalTime}' should be faster than clean install: '{firstInstallTime}' and incremental install: '{thirdInstallTime}'."); } }
public void ProduceReferenceAssembly() { var path = Path.Combine("temp", TestName); var app = new XamarinAndroidApplicationProject { ProjectName = "MyApp", Sources = { new BuildItem.Source("Foo.cs") { TextContent = () => "public class Foo : Bar { }" }, } }; //NOTE: so _BuildApkEmbed runs in commercial tests app.SetProperty("EmbedAssembliesIntoApk", true.ToString()); app.SetProperty("AndroidUseSharedRuntime", false.ToString()); int count = 0; var lib = new DotNetStandard { ProjectName = "MyLibrary", Sdk = "Microsoft.NET.Sdk", TargetFramework = "netstandard2.0", Sources = { new BuildItem.Source("Bar.cs") { TextContent = () => "public class Bar { public Bar () { System.Console.WriteLine (" + count++ + "); } }" }, } }; lib.SetProperty("ProduceReferenceAssembly", "True"); app.References.Add(new BuildItem.ProjectReference($"..\\{lib.ProjectName}\\{lib.ProjectName}.csproj", lib.ProjectName, lib.ProjectGuid)); using (var libBuilder = CreateDllBuilder(Path.Combine(path, lib.ProjectName), false)) using (var appBuilder = CreateApkBuilder(Path.Combine(path, app.ProjectName))) { Assert.IsTrue(libBuilder.Build(lib), "first library build should have succeeded."); Assert.IsTrue(appBuilder.Build(app), "first app build should have succeeded."); lib.Touch("Bar.cs"); Assert.IsTrue(libBuilder.Build(lib, doNotCleanupOnUpdate: true, saveProject: false), "second library build should have succeeded."); Assert.IsTrue(appBuilder.Build(app, doNotCleanupOnUpdate: true, saveProject: false), "second app build should have succeeded."); var targetsShouldSkip = new [] { "CoreCompile", "_BuildLibraryImportsCache", "_ResolveLibraryProjectImports", "_GenerateJavaStubs", }; foreach (var target in targetsShouldSkip) { Assert.IsTrue(appBuilder.Output.IsTargetSkipped(target), $"`{target}` should be skipped!"); } var targetsShouldRun = new [] { "_BuildApkEmbed", "_CopyPackage", "_Sign", }; foreach (var target in targetsShouldRun) { Assert.IsFalse(appBuilder.Output.IsTargetSkipped(target), $"`{target}` should *not* be skipped!"); } } }
public void NetStandardReferenceTest() { var netStandardProject = new DotNetStandard() { ProjectName = "XamFormsSample", ProjectGuid = Guid.NewGuid().ToString(), Sdk = "Microsoft.NET.Sdk", TargetFramework = "netstandard1.4", IsRelease = true, PackageTargetFallback = "portable-net45+win8+wpa81+wp8", PackageReferences = { KnownPackages.XamarinForms_2_3_4_231, new Package() { Id = "System.IO.Packaging", Version = "4.4.0", }, new Package() { Id = "Newtonsoft.Json", Version = "10.0.3" }, }, OtherBuildItems = { new BuildItem("None") { Remove = () => "**\\*.xaml", }, new BuildItem("Compile") { Update = () => "**\\*.xaml.cs", DependentUpon = () => "%(Filename)" }, new BuildItem("EmbeddedResource") { Include = () => "**\\*.xaml", SubType = () => "Designer", Generator = () => "MSBuild:UpdateDesignTimeXaml", }, }, Sources = { new BuildItem.Source("App.xaml.cs") { TextContent = () => @"using System; using System.Collections.Generic; using System.Linq; using System.Text; using Newtonsoft.Json; using System.IO.Packaging; using Xamarin.Forms; namespace XamFormsSample { public partial class App : Application { Package package; public App() { try { JsonConvert.DeserializeObject<string>(""test""); package = Package.Open (""""); } catch { } InitializeComponent(); MainPage = new ContentPage (); } protected override void OnStart() { // Handle when your app starts } protected override void OnSleep() { // Handle when your app sleeps } protected override void OnResume() { // Handle when your app resumes } } }", }, new BuildItem.Source("App.xaml") { TextContent = () => @"<?xml version=""1.0"" encoding=""utf-8"" ?> <Application xmlns=""http://xamarin.com/schemas/2014/forms"" xmlns:x=""http://schemas.microsoft.com/winfx/2009/xaml"" x:Class=""XamFormsSample.App""> <Application.Resources> <!-- Application resource dictionary --> </Application.Resources> </Application>", }, }, }; var app = new XamarinAndroidApplicationProject() { ProjectName = "App1", IsRelease = true, UseLatestPlatformSdk = true, References = { new BuildItem.Reference("Mono.Android.Export"), new BuildItem.ProjectReference($"..\\{netStandardProject.ProjectName}\\{netStandardProject.ProjectName}.csproj", netStandardProject.ProjectName, netStandardProject.ProjectGuid), }, PackageReferences = { KnownPackages.SupportDesign_27_0_2_1, KnownPackages.SupportV7CardView_27_0_2_1, KnownPackages.AndroidSupportV4_27_0_2_1, KnownPackages.SupportCoreUtils_27_0_2_1, KnownPackages.SupportMediaCompat_27_0_2_1, KnownPackages.SupportFragment_27_0_2_1, KnownPackages.SupportCoreUI_27_0_2_1, KnownPackages.SupportCompat_27_0_2_1, KnownPackages.SupportV7AppCompat_27_0_2_1, KnownPackages.SupportV7MediaRouter_27_0_2_1, KnownPackages.XamarinForms_2_3_4_231, new Package() { Id = "System.Runtime.Loader", Version = "4.3.0", }, } }; app.MainActivity = @"using System; using Android.App; using Android.Content; using Android.Runtime; using Android.Views; using Android.Widget; using Android.OS; using XamFormsSample; namespace App1 { [Activity (Label = ""App1"", MainLauncher = true, Icon = ""@drawable/icon"")] public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity { protected override void OnCreate (Bundle bundle) { base.OnCreate (bundle); global::Xamarin.Forms.Forms.Init (this, bundle); LoadApplication (new App ()); } } }" ; app.SetProperty(KnownProperties.AndroidSupportedAbis, "x86;armeabi-v7a"); var expectedFiles = new string [] { "Java.Interop.dll", "Mono.Android.dll", "mscorlib.dll", "System.Core.dll", "System.dll", "System.Runtime.Serialization.dll", "System.IO.Packaging.dll", "System.IO.Compression.dll", "Mono.Android.Export.dll", "App1.dll", "FormsViewGroup.dll", "Xamarin.Android.Arch.Core.Common.dll", "Xamarin.Android.Arch.Lifecycle.Common.dll", "Xamarin.Android.Arch.Lifecycle.Runtime.dll", "Xamarin.Android.Support.Compat.dll", "Xamarin.Android.Support.Core.UI.dll", "Xamarin.Android.Support.Core.Utils.dll", "Xamarin.Android.Support.Design.dll", "Xamarin.Android.Support.Fragment.dll", "Xamarin.Android.Support.Media.Compat.dll", "Xamarin.Android.Support.v4.dll", "Xamarin.Android.Support.v7.AppCompat.dll", "Xamarin.Android.Support.Animated.Vector.Drawable.dll", "Xamarin.Android.Support.Vector.Drawable.dll", "Xamarin.Android.Support.Transition.dll", "Xamarin.Android.Support.v7.MediaRouter.dll", "Xamarin.Android.Support.v7.RecyclerView.dll", "Xamarin.Android.Support.Annotations.dll", "Xamarin.Android.Support.v7.CardView.dll", "Xamarin.Android.Support.v7.Palette.dll", "Xamarin.Forms.Core.dll", "Xamarin.Forms.Platform.Android.dll", "Xamarin.Forms.Platform.dll", "Xamarin.Forms.Xaml.dll", "XamFormsSample.dll", "Mono.Security.dll", "System.Xml.dll", "System.Net.Http.dll", "System.ServiceModel.Internals.dll", "Newtonsoft.Json.dll", "Microsoft.CSharp.dll", "System.Numerics.dll", "System.Xml.Linq.dll", }; var path = Path.Combine("temp", TestContext.CurrentContext.Test.Name); using (var builder = CreateDllBuilder(Path.Combine(path, netStandardProject.ProjectName), cleanupOnDispose: false)) { using (var ab = CreateApkBuilder(Path.Combine(path, app.ProjectName), cleanupOnDispose: false)) { builder.RequiresMSBuild = ab.RequiresMSBuild = true; Assert.IsTrue(builder.Build(netStandardProject), "XamFormsSample should have built."); Assert.IsTrue(ab.Build(app), "App should have built."); var apk = Path.Combine(Root, ab.ProjectDirectory, app.IntermediateOutputPath, "android", "bin", "UnnamedProject.UnnamedProject.apk"); using (var zip = ZipHelper.OpenZip(apk)) { var existingFiles = zip.Where(a => a.FullName.StartsWith("assemblies/", StringComparison.InvariantCultureIgnoreCase)); var missingFiles = expectedFiles.Where(x => !zip.ContainsEntry("assemblies/" + Path.GetFileName(x))); Assert.IsFalse(missingFiles.Any(), string.Format("The following Expected files are missing. {0}", string.Join(Environment.NewLine, missingFiles))); var additionalFiles = existingFiles.Where(x => !expectedFiles.Contains(Path.GetFileName(x.FullName))); Assert.IsTrue(!additionalFiles.Any(), string.Format("Unexpected Files found! {0}", string.Join(Environment.NewLine, additionalFiles.Select(x => x.FullName)))); } } } }
public void CheckTheCorrectRuntimeAssemblyIsUsedFromNuget() { string monoandroidFramework = "monoandroid10.0"; string path = Path.Combine(Root, "temp", TestName); var ns = new DotNetStandard() { ProjectName = "Dummy", Sdk = "MSBuild.Sdk.Extras/2.0.54", Sources = { new BuildItem.Source("Class1.cs") { TextContent = () => @"public class Class1 { #if __ANDROID__ public static string Library => ""Android""; #else public static string Library => "".NET Standard""; #endif }", }, }, OtherBuildItems = { new BuildItem.NoActionResource("$(OutputPath)netstandard2.0\\$(AssemblyName).dll") { TextContent = null, BinaryContent = null, Metadata = { { "PackagePath", "ref\\netstandard2.0" }, { "Pack", "True" } }, }, new BuildItem.NoActionResource($"$(OutputPath){monoandroidFramework}\\$(AssemblyName).dll") { TextContent = null, BinaryContent = null, Metadata = { { "PackagePath", $"lib\\{monoandroidFramework}" }, { "Pack", "True" } }, }, }, }; ns.SetProperty("TargetFrameworks", $"netstandard2.0;{monoandroidFramework}"); ns.SetProperty("PackageId", "dummy.package.foo"); ns.SetProperty("PackageVersion", "1.0.0"); ns.SetProperty("GeneratePackageOnBuild", "True"); ns.SetProperty("IncludeBuildOutput", "False"); ns.SetProperty("Summary", "Test"); ns.SetProperty("Description", "Test"); ns.SetProperty("PackageOutputPath", path); var xa = new XamarinAndroidApplicationProject() { ProjectName = "App", PackageReferences = { new Package() { Id = "dummy.package.foo", Version = "1.0.0", }, }, OtherBuildItems = { new BuildItem.NoActionResource("NuGet.config") { }, }, }; xa.SetProperty("RestoreNoCache", "true"); xa.SetProperty("RestorePackagesPath", "$(MSBuildThisFileDirectory)packages"); using (var nsb = CreateDllBuilder(Path.Combine(path, ns.ProjectName), cleanupAfterSuccessfulBuild: false, cleanupOnDispose: false)) using (var xab = CreateApkBuilder(Path.Combine(path, xa.ProjectName), cleanupAfterSuccessfulBuild: false, cleanupOnDispose: false)) { nsb.ThrowOnBuildFailure = xab.ThrowOnBuildFailure = false; Assert.IsTrue(nsb.Build(ns), "Build of NetStandard Library should have succeeded."); Assert.IsFalse(xab.Build(xa, doNotCleanupOnUpdate: true), "Build of App Library should have failed."); File.WriteAllText(Path.Combine(Root, xab.ProjectDirectory, "NuGet.config"), @"<?xml version='1.0' encoding='utf-8'?> <configuration> <packageSources> <add key='nuget.org' value='https://api.nuget.org/v3/index.json' protocolVersion='3' /> <add key='bug-testing' value='..' /> </packageSources> </configuration>"); Assert.IsTrue(xab.Build(xa, doNotCleanupOnUpdate: true), "Build of App Library should have succeeded."); string expected = Path.Combine("dummy.package.foo", "1.0.0", "lib", monoandroidFramework, "Dummy.dll"); Assert.IsTrue(xab.LastBuildOutput.ContainsText(expected), $"Build should be using {expected}"); } }
public void IncrementalFastDeployment() { AssertCommercialBuild(); AssertHasDevices(); var lib1 = new XamarinAndroidLibraryProject() { ProjectName = "Library1", Sources = { new BuildItem.Source("Class1.cs") { TextContent = () => "namespace Library1 { public class Class1 { } }" }, } }; var lib2 = new DotNetStandard { ProjectName = "Library2", Sdk = "Microsoft.NET.Sdk", TargetFramework = "netstandard2.0", Sources = { new BuildItem.Source("Class2.cs") { TextContent = () => "namespace Library2 { public class Class2 { } }" }, } }; var app = new XamarinFormsAndroidApplicationProject() { AndroidUseSharedRuntime = true, EmbedAssembliesIntoApk = false, References = { new BuildItem("ProjectReference", "..\\Library1\\Library1.csproj"), new BuildItem("ProjectReference", "..\\Library2\\Library2.csproj"), }, }; // Set up library projects var rootPath = Path.Combine(Root, "temp", TestName); using (var lb1 = CreateDllBuilder(Path.Combine(rootPath, lib1.ProjectName))) Assert.IsTrue(lb1.Build(lib1), "First library build should have succeeded."); using (var lb2 = CreateDllBuilder(Path.Combine(rootPath, lib2.ProjectName))) Assert.IsTrue(lb2.Build(lib2), "Second library build should have succeeded."); using (var builder = CreateApkBuilder(Path.Combine(rootPath, app.ProjectName))) { builder.ThrowOnBuildFailure = false; Assert.IsTrue(builder.Install(app), "First install should have succeeded."); var firstInstallTime = builder.LastBuildTime; Assert.IsTrue(builder.Install(app, doNotCleanupOnUpdate: true, saveProject: false), "Second install should have succeeded."); var secondInstallTime = builder.LastBuildTime; var filesToTouch = new [] { Path.Combine(rootPath, lib1.ProjectName, "Class1.cs"), Path.Combine(rootPath, lib2.ProjectName, "Class2.cs"), Path.Combine(rootPath, app.ProjectName, "MainPage.xaml"), }; foreach (var file in filesToTouch) { FileAssert.Exists(file); File.SetLastWriteTimeUtc(file, DateTime.UtcNow); } Assert.IsTrue(builder.Install(app, doNotCleanupOnUpdate: true, saveProject: false), "Third install should have succeeded."); var thirdInstallTime = builder.LastBuildTime; Assert.IsTrue(builder.Install(app, doNotCleanupOnUpdate: true, saveProject: false), "Fourth install should have succeeded."); var fourthInstalTime = builder.LastBuildTime; Assert.IsTrue(thirdInstallTime < firstInstallTime, $"Third incremental install: '{thirdInstallTime}' should be faster than clean install: '{firstInstallTime}'."); Assert.IsTrue(secondInstallTime < firstInstallTime && secondInstallTime < thirdInstallTime, $"Second unchanged install: '{secondInstallTime}' should be faster than clean install: '{firstInstallTime}' and incremental install: '{thirdInstallTime}'."); Assert.IsTrue(fourthInstalTime < firstInstallTime && fourthInstalTime < thirdInstallTime, $"Fourth unchanged install: '{fourthInstalTime}' should be faster than clean install: '{firstInstallTime}' and incremental install: '{thirdInstallTime}'."); } }
public void Build_XAML_Change(bool produceReferenceAssembly, bool install) { if (install) { AssertCommercialBuild(); // This test will fail without Fast Deployment AssertHasDevices(); } var path = Path.Combine("temp", TestName); var xaml = @"<?xml version=""1.0"" encoding=""utf-8"" ?> <ContentPage xmlns=""http://xamarin.com/schemas/2014/forms"" xmlns:x=""http://schemas.microsoft.com/winfx/2009/xaml"" x:Class=""MyLibrary.MyPage""> </ContentPage>"; var caller = nameof(Build_XAML_Change); if (install) { caller = caller.Replace("Build", "Install"); } else if (produceReferenceAssembly) { caller += "_RefAssembly"; } var app = new XamarinFormsAndroidApplicationProject { ProjectName = "MyApp", Sources = { new BuildItem.Source("Foo.cs") { TextContent = () => "public class Foo : Bar { }" }, } }; //NOTE: this will skip a 382ms <VerifyVersionsTask/> from the support library app.SetProperty("XamarinAndroidSupportSkipVerifyVersions", "True"); int count = 0; var lib = new DotNetStandard { ProjectName = "MyLibrary", Sdk = "Microsoft.NET.Sdk", TargetFramework = "netstandard2.0", Sources = { new BuildItem.Source("Bar.cs") { TextContent = () => "public class Bar { public Bar () { System.Console.WriteLine (" + count++ + "); } }" }, new BuildItem("EmbeddedResource", "MyPage.xaml") { TextContent = () => xaml, } }, PackageReferences = { KnownPackages.XamarinForms_4_0_0_425677 } }; lib.SetProperty("ProduceReferenceAssembly", produceReferenceAssembly.ToString()); app.References.Add(new BuildItem.ProjectReference($"..\\{lib.ProjectName}\\{lib.ProjectName}.csproj", lib.ProjectName, lib.ProjectGuid)); using (var libBuilder = CreateDllBuilder(Path.Combine(path, lib.ProjectName))) using (var appBuilder = CreateBuilderWithoutLogFile(Path.Combine(path, app.ProjectName))) { libBuilder.Build(lib); appBuilder.Target = "Build"; if (install) { appBuilder.Install(app); } else { appBuilder.Build(app); } libBuilder.AutomaticNuGetRestore = appBuilder.AutomaticNuGetRestore = false; // Profile XAML change xaml += $"{Environment.NewLine}<!--comment-->"; lib.Touch("MyPage.xaml"); libBuilder.Build(lib, doNotCleanupOnUpdate: true); if (install) { Profile(appBuilder, b => b.Install(app, doNotCleanupOnUpdate: true), caller); } else { Profile(appBuilder, b => b.Build(app, doNotCleanupOnUpdate: true), caller); } } }
public void CustomLinkDescriptionPreserve([Values(AndroidLinkMode.SdkOnly, AndroidLinkMode.Full)] AndroidLinkMode linkMode) { AssertHasDevices(); var lib1 = new XamarinAndroidLibraryProject() { ProjectName = "Library1", Sources = { new BuildItem.Source("SomeClass.cs") { TextContent = () => "namespace Library1 { public class SomeClass { } }" }, new BuildItem.Source("NonPreserved.cs") { TextContent = () => "namespace Library1 { public class NonPreserved { } }" }, new BuildItem.Source("LinkerClass.cs") { TextContent = () => @" namespace Library1 { public class LinkerClass { public LinkerClass () { } public bool IsPreserved { get { return true; } } public bool ThisMethodShouldBePreserved () { return true; } public void WasThisMethodPreserved (string arg1) { } [Android.Runtime.Preserve] public void PreserveAttribMethod () { } } }", }, new BuildItem.Source("LinkModeFullClass.cs") { TextContent = () => @" namespace Library1 { public class LinkModeFullClass { public bool ThisMethodShouldNotBePreserved () { return true; } } }", }, } }; var lib2 = new DotNetStandard { ProjectName = "LinkTestLib", Sdk = "Microsoft.NET.Sdk", TargetFramework = "netstandard2.0", PackageReferences = { new Package { Id = "sqlite-net-pcl", Version = "1.7.335", } }, Sources = { new BuildItem.Source("Bug21578.cs") { TextContent = () =>{ using (var sr = new StreamReader(typeof(InstallAndRunTests).Assembly.GetManifestResourceStream("Xamarin.Android.Build.Tests.Resources.LinkDescTest.Bug21578.cs"))) return(sr.ReadToEnd()); }, }, new BuildItem.Source("Bug35195.cs") { TextContent = () =>{ using (var sr = new StreamReader(typeof(InstallAndRunTests).Assembly.GetManifestResourceStream("Xamarin.Android.Build.Tests.Resources.LinkDescTest.Bug35195.cs"))) return(sr.ReadToEnd()); }, }, }, }; if (!Builder.UseDotNet) { // DataContractSerializer is not trimming safe // https://github.com/dotnet/runtime/issues/45559 lib2.Sources.Add(new BuildItem.Source("Bug36250.cs") { TextContent = () => { using (var sr = new StreamReader(typeof(InstallAndRunTests).Assembly.GetManifestResourceStream("Xamarin.Android.Build.Tests.Resources.LinkDescTest.Bug36250.cs"))) return(sr.ReadToEnd()); }, }); } proj = new XamarinFormsAndroidApplicationProject() { IsRelease = true, AndroidLinkModeRelease = linkMode, References = { new BuildItem("ProjectReference", "..\\Library1\\Library1.csproj"), new BuildItem("ProjectReference", "..\\LinkTestLib\\LinkTestLib.csproj"), }, OtherBuildItems = { new BuildItem("LinkDescription", "linker.xml") { TextContent = () => linkMode == AndroidLinkMode.SdkOnly ? "<linker/>" : @" <linker> <assembly fullname=""Library1""> <type fullname=""Library1.LinkerClass""> <method name="".ctor"" /> <method name=""WasThisMethodPreserved"" /> <method name=""get_IsPreserved"" /> </type> </assembly> <assembly fullname=""LinkTestLib""> <type fullname=""LinkTestLib.TodoTask"" /> </assembly> </linker> ", }, }, }; if (Builder.UseDotNet) { // NOTE: workaround for netcoreapp3.1 dependency preferred over monoandroid8.0 proj.PackageReferences.Add(new Package { Id = "SQLitePCLRaw.lib.e_sqlite3.android", Version = "2.0.4", }); } proj.AndroidManifest = proj.AndroidManifest.Replace("</manifest>", "<uses-permission android:name=\"android.permission.INTERNET\" /></manifest>"); proj.SetAndroidSupportedAbis("armeabi-v7a", "arm64-v8a", "x86", "x86_64"); using (var sr = new StreamReader(typeof(InstallAndRunTests).Assembly.GetManifestResourceStream("Xamarin.Android.Build.Tests.Resources.LinkDescTest.MainActivityReplacement.cs"))) proj.MainActivity = sr.ReadToEnd(); // Set up library projects var rootPath = Path.Combine(Root, "temp", TestName); using (var lb1 = CreateDllBuilder(Path.Combine(rootPath, lib1.ProjectName))) Assert.IsTrue(lb1.Build(lib1), "First library build should have succeeded."); using (var lb2 = CreateDllBuilder(Path.Combine(rootPath, lib2.ProjectName))) Assert.IsTrue(lb2.Build(lib2), "Second library build should have succeeded."); builder = CreateApkBuilder(Path.Combine(rootPath, proj.ProjectName)); Assert.IsTrue(builder.Install(proj), "First install should have succeeded."); ClearAdbLogcat(); if (CommercialBuildAvailable) { Assert.True(builder.RunTarget(proj, "_Run"), "Project should have run."); } else { AdbStartActivity($"{proj.PackageName}/{proj.JavaPackageName}.MainActivity"); } var logcatPath = Path.Combine(Root, builder.ProjectDirectory, "logcat.log"); Assert.IsTrue(MonitorAdbLogcat((line) => { return(line.Contains("All regression tests completed.")); }, logcatPath, 90), "Linker test app did not run successfully."); var logcatOutput = File.ReadAllText(logcatPath); StringAssert.Contains("[PASS]", logcatOutput); StringAssert.DoesNotContain("[FAIL]", logcatOutput); if (linkMode == AndroidLinkMode.Full) { StringAssert.Contains("[LINKALLPASS]", logcatOutput); StringAssert.DoesNotContain("[LINKALLFAIL]", logcatOutput); } }
public void MonoSymbolicateNetStandardStackTrace() { AssertHasDevices(); var lib = new DotNetStandard { ProjectName = "Library1", Sdk = "Microsoft.NET.Sdk", TargetFramework = "netstandard2.0", Sources = { new BuildItem.Source("Class1.cs") { TextContent = () => @" using System; namespace Library1 { public class Class1 { string Data { get; set; } public Class1(string data) { Data = data; } public string GetData() { if (Data == null) throw new NullReferenceException(); return Data; } } }", }, } }; proj = new XamarinFormsAndroidApplicationProject() { IsRelease = true, References = { new BuildItem("ProjectReference", "..\\Library1\\Library1.csproj"), }, }; proj.SetAndroidSupportedAbis("armeabi-v7a", "arm64-v8a", "x86", "x86_64"); proj.SetProperty(proj.ReleaseProperties, "MonoSymbolArchive", "True"); proj.MainActivity = proj.DefaultMainActivity.Replace("//${AFTER_ONCREATE}", @" var cl = new Library1.Class1(null); cl.GetData(); "); var rootPath = Path.Combine(Root, "temp", TestName); using (var lb = CreateDllBuilder(Path.Combine(Path.Combine(Root, "temp", TestName), lib.ProjectName))) { Assert.IsTrue(lb.Build(lib), "Library build should have succeeded."); builder = CreateApkBuilder(Path.Combine(rootPath, proj.ProjectName)); Assert.IsTrue(builder.Install(proj), "Install should have succeeded."); var archivePath = Path.Combine(Root, builder.ProjectDirectory, proj.OutputPath, $"{proj.PackageName}.apk.mSYM"); Assert.IsTrue(Directory.Exists(archivePath), $"Symbol archive path {archivePath} should exist."); ClearAdbLogcat(); if (CommercialBuildAvailable) { Assert.True(builder.RunTarget(proj, "_Run"), "Project should have run."); } else { AdbStartActivity($"{proj.PackageName}/{proj.JavaPackageName}.MainActivity"); } var logcatPath = Path.Combine(Root, builder.ProjectDirectory, "crash-logcat.log"); MonitorAdbLogcat((line) => { return(line.Contains($"Force finishing activity {proj.PackageName}")); }, logcatPath, 30); var didParse = int.TryParse(proj.TargetSdkVersion, out int apiLevel); Assert.IsTrue(didParse, $"Unable to parse {proj.TargetSdkVersion} as an int."); SymbolicateAndAssert(archivePath, logcatPath, new string [] { Path.Combine(Root, lb.ProjectDirectory, "Class1.cs:12"), Path.Combine(Root, builder.ProjectDirectory, "MainActivity.cs:33"), Directory.Exists(builder.BuildOutputDirectory) ? Path.Combine("src", "Mono.Android", "obj", XABuildPaths.Configuration, "monoandroid10", $"android-{apiLevel}", "mcw", "Android.App.Activity.cs:") : $"src/Mono.Android/obj/Release/monoandroid10/android-{apiLevel}/mcw/Android.App.Activity.cs:", }); } }
public void NetStandardReferenceTest() { var netStandardProject = new DotNetStandard() { Language = XamarinAndroidProjectLanguage.CSharp, ProjectName = "XamFormsSample", ProjectGuid = Guid.NewGuid().ToString(), Sdk = "Microsoft.NET.Sdk", TargetFramework = "netstandard1.4", IsRelease = true, PackageTargetFallback = "portable-net45+win8+wpa81+wp8", PackageReferences = { KnownPackages.XamarinFormsPCL_2_3_4_231, new Package() { Id = "System.IO.Packaging", Version = "4.4.0", }, new Package() { Id = "Newtonsoft.Json", Version = "10.0.3" }, }, OtherBuildItems = { new BuildItem("None") { Remove = () => "**\\*.xaml", }, new BuildItem("Compile") { Update = () => "**\\*.xaml.cs", DependentUpon = () => "%(Filename)" }, new BuildItem("EmbeddedResource") { Include = () => "**\\*.xaml", SubType = () => "Designer", Generator = () => "MSBuild:UpdateDesignTimeXaml", }, }, Sources = { new BuildItem.Source("App.xaml.cs") { TextContent = () => @"using System; using System.Collections.Generic; using System.Linq; using System.Text; using Newtonsoft.Json; using Xamarin.Forms; namespace XamFormsSample { public partial class App : Application { public App() { JsonConvert.DeserializeObject<string>(""test""); InitializeComponent(); } protected override void OnStart() { // Handle when your app starts } protected override void OnSleep() { // Handle when your app sleeps } protected override void OnResume() { // Handle when your app resumes } } }", }, new BuildItem.Source("App.xaml") { TextContent = () => @"<?xml version=""1.0"" encoding=""utf-8"" ?> <Application xmlns=""http://xamarin.com/schemas/2014/forms"" xmlns:x=""http://schemas.microsoft.com/winfx/2009/xaml"" x:Class=""XamFormsSample.App""> <Application.Resources> <!-- Application resource dictionary --> </Application.Resources> </Application>", }, }, }; var app = new XamarinAndroidApplicationProject() { ProjectName = "App1", IsRelease = true, UseLatestPlatformSdk = true, References = { new BuildItem.Reference("Mono.Android.Export"), new BuildItem.ProjectReference($"..\\{netStandardProject.ProjectName}\\{netStandardProject.ProjectName}.csproj", netStandardProject.ProjectName, netStandardProject.ProjectGuid), }, PackageReferences = { KnownPackages.SupportDesign_25_4_0_1, KnownPackages.SupportV7CardView_24_2_1, KnownPackages.AndroidSupportV4_25_4_0_1, KnownPackages.SupportCoreUtils_25_4_0_1, KnownPackages.SupportMediaCompat_25_4_0_1, KnownPackages.SupportFragment_25_4_0_1, KnownPackages.SupportCoreUI_25_4_0_1, KnownPackages.SupportCompat_25_4_0_1, KnownPackages.SupportV7AppCompat_25_4_0_1, KnownPackages.XamarinForms_2_3_4_231, } }; app.SetProperty(KnownProperties.AndroidSupportedAbis, "x86;armeabi-v7a"); var expectedFiles = new string [] { "Java.Interop.dll", "Mono.Android.dll", "mscorlib.dll", "mscorlib.dll.mdb", "System.Collections.Concurrent.dll", "System.Collections.dll", "System.Core.dll", "System.Diagnostics.Debug.dll", "System.dll", "System.Linq.dll", "System.Reflection.dll", "System.Reflection.Extensions.dll", "System.Runtime.dll", "System.Runtime.Extensions.dll", "System.Runtime.InteropServices.dll", "System.Runtime.Serialization.dll", "System.Threading.dll", "System.IO.Packaging.dll", "System.IO.Compression.dll", "System.IO.Compression.pdb", "Mono.Android.Export.dll", "Mono.Android.Export.pdb", "App1.dll", "App1.pdb", "FormsViewGroup.dll", "FormsViewGroup.dll.mdb", "Xamarin.Android.Support.Compat.dll", "Xamarin.Android.Support.Core.UI.dll", "Xamarin.Android.Support.Core.Utils.dll", "Xamarin.Android.Support.Design.dll", "Xamarin.Android.Support.Fragment.dll", "Xamarin.Android.Support.Media.Compat.dll", "Xamarin.Android.Support.v4.dll", "Xamarin.Android.Support.v7.AppCompat.dll", "Xamarin.Android.Support.Animated.Vector.Drawable.dll", "Xamarin.Android.Support.Vector.Drawable.dll", "Xamarin.Android.Support.Transition.dll", "Xamarin.Android.Support.v7.MediaRouter.dll", "Xamarin.Android.Support.v7.RecyclerView.dll", "Xamarin.Android.Support.Annotations.dll", "Xamarin.Android.Support.v7.CardView.dll", "Xamarin.Forms.Core.dll", "Xamarin.Forms.Core.dll.mdb", "Xamarin.Forms.Platform.Android.dll", "Xamarin.Forms.Platform.Android.dll.mdb", "Xamarin.Forms.Platform.dll", "Xamarin.Forms.Xaml.dll", "Xamarin.Forms.Xaml.dll.mdb", "XamFormsSample.dll", "XamFormsSample.pdb", "Mono.Android.pdb", "System.Core.pdb", "System.pdb", "Mono.Security.dll", "Mono.Security.pdb", "System.Xml.dll", "System.Xml.pdb", "System.ComponentModel.Composition.dll", "System.ComponentModel.Composition.pdb", "System.Net.Http.dll", "System.Net.Http.pdb", "System.Runtime.Serialization.pdb", "System.ServiceModel.Internals.dll", "System.ServiceModel.Internals.pdb", "System.Threading.Tasks.dll", "System.ObjectModel.dll", "System.Globalization.dll", "System.ComponentModel.dll", "System.Xml.ReaderWriter.dll", "System.Linq.Expressions.dll", "System.IO.dll", "System.Dynamic.Runtime.dll", "System.Text.RegularExpressions.dll", "System.Diagnostics.Tools.dll", "Newtonsoft.Json.dll", "Microsoft.CSharp.dll", "System.Numerics.dll", "System.Xml.Linq.dll", }; var path = Path.Combine("temp", TestContext.CurrentContext.Test.Name); using (var builder = CreateDllBuilder(Path.Combine(path, netStandardProject.ProjectName), cleanupOnDispose: false)) { if (!Directory.Exists(builder.MicrosoftNetSdkDirectory)) { Assert.Ignore("Microsoft.NET.Sdk not found."); } builder.RequiresMSBuild = true; builder.Target = "Restore"; Assert.IsTrue(builder.Build(netStandardProject), "XamFormsSample Nuget packages should have been restored."); builder.Target = "Build"; Assert.IsTrue(builder.Build(netStandardProject), "XamFormsSample should have built."); using (var ab = CreateApkBuilder(Path.Combine(path, app.ProjectName), cleanupOnDispose: false)) { ab.RequiresMSBuild = true; ab.Target = "Restore"; Assert.IsTrue(ab.Build(app), "App should have built."); ab.Target = "SignAndroidPackage"; Assert.IsTrue(ab.Build(app), "App should have built."); var apk = Path.Combine(Root, ab.ProjectDirectory, app.IntermediateOutputPath, "android", "bin", "UnnamedProject.UnnamedProject.apk"); using (var zip = ZipHelper.OpenZip(apk)) { var existingFiles = zip.Where(a => a.FullName.StartsWith("assemblies/", StringComparison.InvariantCultureIgnoreCase)); var missingFiles = expectedFiles.Where(x => !zip.ContainsEntry("assmelbies/" + Path.GetFileName(x))); Assert.IsTrue(missingFiles.Any(), string.Format("The following Expected files are missing. {0}", string.Join(Environment.NewLine, missingFiles))); var additionalFiles = existingFiles.Where(x => !expectedFiles.Contains(Path.GetFileName(x.FullName))); Assert.IsTrue(!additionalFiles.Any(), string.Format("Unexpected Files found! {0}", string.Join(Environment.NewLine, additionalFiles.Select(x => x.FullName)))); } if (!HasDevices) { Assert.Ignore("Skipping Installation. No devices available."); } ab.Target = "Install"; Assert.IsTrue(ab.Build(app), "App should have installed."); } } }