public void BeforeDeploymentTests() { AssertHasDevices(); string debuggable = RunAdbCommand("shell getprop ro.debuggable"); if (debuggable != "1") { Assert.Ignore("TimeZone tests need to use `su root` and this device does not support that feature. Try using an emulator."); } proj = new XamarinFormsAndroidApplicationProject(); proj.SetAndroidSupportedAbis("armeabi-v7a", "x86"); var mainPage = proj.Sources.First(x => x.Include() == "MainPage.xaml.cs"); var source = mainPage.TextContent().Replace("InitializeComponent ();", @"InitializeComponent (); Console.WriteLine ($""TimeZoneInfo={TimeZoneInfo.Local.DisplayName}""); "); mainPage.TextContent = () => source; builder = CreateApkBuilder(Path.Combine("temp", "DeploymentTests")); string apiLevel; proj.TargetFrameworkVersion = builder.LatestTargetFrameworkVersion(out apiLevel); proj.PackageName = "Xamarin.TimeZoneTest"; proj.AndroidManifest = $@"<?xml version=""1.0"" encoding=""utf-8""?> <manifest xmlns:android=""http://schemas.android.com/apk/res/android"" android:versionCode=""1"" android:versionName=""1.0"" package=""Xamarin.TimeZoneTest""> <uses-sdk android:minSdkVersion=""24"" android:targetSdkVersion=""{apiLevel}"" /> <application android:label=""${{PROJECT_NAME}}""> </application > </manifest> "; Assert.IsTrue(builder.Build(proj), "Build should have succeeded."); Assert.IsTrue(builder.Install(proj), "Install should have succeeded."); }
public void ApplicationRunsWithoutDebugger([Values(false, true)] bool isRelease) { AssertHasDevices(); var proj = new XamarinFormsAndroidApplicationProject() { IsRelease = isRelease, }; if (isRelease || !CommercialBuildAvailable) { proj.SetAndroidSupportedAbis("armeabi-v7a", "x86"); } proj.SetDefaultTargetDevice(); using (var b = CreateApkBuilder(Path.Combine("temp", TestName))) { SetTargetFrameworkAndManifest(proj, b); Assert.True(b.Install(proj), "Project should have installed."); ClearAdbLogcat(); if (CommercialBuildAvailable) { Assert.True(b.RunTarget(proj, "_Run"), "Project should have run."); } else { AdbStartActivity($"{proj.PackageName}/{proj.JavaPackageName}.MainActivity"); } Assert.True(WaitForActivityToStart(proj.PackageName, "MainActivity", Path.Combine(Root, b.ProjectDirectory, "logcat.log"), 30), "Activity should have started."); Assert.True(b.Uninstall(proj), "Project should have uninstalled."); } }
public void ApplicationRunsWithoutDebugger([Values(false, true)] bool isRelease, [Values(false, true)] bool extractNativeLibs) { AssertHasDevices(); var proj = new XamarinFormsAndroidApplicationProject() { IsRelease = isRelease, }; if (isRelease || !CommercialBuildAvailable) { proj.SetAndroidSupportedAbis("armeabi-v7a", "x86"); } proj.SetDefaultTargetDevice(); using (var b = CreateApkBuilder(Path.Combine("temp", TestName))) { SetTargetFrameworkAndManifest(proj, b); proj.AndroidManifest = proj.AndroidManifest.Replace("<application ", $"<application android:extractNativeLibs=\"{extractNativeLibs.ToString ().ToLowerInvariant ()}\" "); Assert.True(b.Install(proj), "Project should have installed."); var manifest = Path.Combine(Root, b.ProjectDirectory, proj.IntermediateOutputPath, "android", "AndroidManifest.xml"); AssertExtractNativeLibs(manifest, extractNativeLibs); ClearAdbLogcat(); if (CommercialBuildAvailable) { Assert.True(b.RunTarget(proj, "_Run"), "Project should have run."); } else { AdbStartActivity($"{proj.PackageName}/{proj.JavaPackageName}.MainActivity"); } Assert.True(WaitForActivityToStart(proj.PackageName, "MainActivity", Path.Combine(Root, b.ProjectDirectory, "logcat.log"), 30), "Activity should have started."); Assert.True(b.Uninstall(proj), "Project should have uninstalled."); } }
public void BuildApplicationWithMonoEnvironment([Values("", "Normal", "Offline")] string sequencePointsMode) { const string supportedAbis = "armeabi-v7a;x86"; var lib = new XamarinAndroidLibraryProject { ProjectName = "Library1", IsRelease = true, OtherBuildItems = { new AndroidItem.AndroidEnvironment("Mono.env") { TextContent = () => "MONO_DEBUG=soft-breakpoints" }, }, }; var app = new XamarinFormsAndroidApplicationProject() { IsRelease = true, AndroidLinkModeRelease = AndroidLinkMode.Full, References = { new BuildItem("ProjectReference", "..\\Library1\\Library1.csproj"), }, }; //LinkSkip one assembly that contains __AndroidLibraryProjects__.zip string linkSkip = "FormsViewGroup"; app.SetProperty("AndroidLinkSkip", linkSkip); app.SetProperty("_AndroidSequencePointsMode", sequencePointsMode); app.SetAndroidSupportedAbis(supportedAbis); using (var libb = CreateDllBuilder(Path.Combine("temp", TestName, lib.ProjectName))) using (var appb = CreateApkBuilder(Path.Combine("temp", TestName, app.ProjectName))) { Assert.IsTrue(libb.Build(lib), "Library build should have succeeded."); Assert.IsTrue(appb.Build(app), "App should have succeeded."); Assert.IsTrue(StringAssertEx.ContainsText(appb.LastBuildOutput, $"Save assembly: {linkSkip}"), $"{linkSkip} should be saved, and not linked!"); string intermediateOutputDir = Path.Combine(Root, appb.ProjectDirectory, app.IntermediateOutputPath); List <string> envFiles = EnvironmentHelper.GatherEnvironmentFiles(intermediateOutputDir, supportedAbis, true); Dictionary <string, string> envvars = EnvironmentHelper.ReadEnvironmentVariables(envFiles); Assert.IsTrue(envvars.Count > 0, $"No environment variables defined"); string monoDebugVar; Assert.IsTrue(envvars.TryGetValue("MONO_DEBUG", out monoDebugVar), "Environment should contain MONO_DEBUG"); Assert.IsFalse(String.IsNullOrEmpty(monoDebugVar), "Environment must contain MONO_DEBUG with a value"); Assert.IsTrue(monoDebugVar.IndexOf("soft-breakpoints") >= 0, "Environment must contain MONO_DEBUG with 'soft-breakpoints' in its value"); if (!String.IsNullOrEmpty(sequencePointsMode)) { Assert.IsTrue(monoDebugVar.IndexOf("gen-compact-seq-points") >= 0, "The values from Mono.env should have been merged into environment"); } EnvironmentHelper.AssertValidEnvironmentSharedLibrary(intermediateOutputDir, AndroidSdkPath, AndroidNdkPath, supportedAbis); var assemblyDir = Path.Combine(Root, appb.ProjectDirectory, app.IntermediateOutputPath, "android", "assets"); var rp = new ReaderParameters { ReadSymbols = false }; foreach (var assemblyFile in Directory.EnumerateFiles(assemblyDir, "*.dll")) { using (var assembly = AssemblyDefinition.ReadAssembly(assemblyFile)) { foreach (var module in assembly.Modules) { var resources = module.Resources.Select(r => r.Name).ToArray(); Assert.IsFalse(StringAssertEx.ContainsText(resources, "__AndroidEnvironment__"), "AndroidEnvironment EmbeddedResource should be stripped!"); Assert.IsFalse(StringAssertEx.ContainsText(resources, "__AndroidLibraryProjects__.zip"), "__AndroidLibraryProjects__.zip should be stripped!"); Assert.IsFalse(StringAssertEx.ContainsText(resources, "__AndroidNativeLibraries__.zip"), "__AndroidNativeLibraries__.zip should be stripped!"); } } } } }
public void ApplicationRunsWithDebuggerAndBreaks(bool embedAssemblies, string fastDevType, bool allowDeltaInstall, string username) { AssertCommercialBuild(); AssertHasDevices(); int userId = GetUserId(username); List <string> parameters = new List <string> (); if (userId >= 0) { parameters.Add($"AndroidDeviceUserId={userId}"); } if (SwitchUser(username)) { WaitFor(5); ClickButton("", "android:id/button1", "Yes continue"); } var proj = new XamarinFormsAndroidApplicationProject() { IsRelease = false, EmbedAssembliesIntoApk = embedAssemblies, AndroidFastDeploymentType = fastDevType }; proj.SetAndroidSupportedAbis("armeabi-v7a", "x86"); proj.SetProperty(KnownProperties._AndroidAllowDeltaInstall, allowDeltaInstall.ToString()); proj.SetDefaultTargetDevice(); using (var b = CreateApkBuilder(Path.Combine("temp", TestName))) { SetTargetFrameworkAndManifest(proj, b); Assert.True(b.Install(proj, parameters: parameters.ToArray()), "Project should have installed."); int breakcountHitCount = 0; ManualResetEvent resetEvent = new ManualResetEvent(false); var sw = new Stopwatch(); // setup the debugger var session = new SoftDebuggerSession(); session.Breakpoints = new BreakpointStore { { Path.Combine(Root, b.ProjectDirectory, "MainActivity.cs"), 20 }, { Path.Combine(Root, b.ProjectDirectory, "MainPage.xaml.cs"), 14 }, { Path.Combine(Root, b.ProjectDirectory, "MainPage.xaml.cs"), 19 }, { Path.Combine(Root, b.ProjectDirectory, "App.xaml.cs"), 12 }, }; session.TargetHitBreakpoint += (sender, e) => { TestContext.WriteLine($"BREAK {e.Type}, {e.Backtrace.GetFrame (0)}"); breakcountHitCount++; 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(b.ProjectDirectory, proj.IntermediateOutputPath, "android", "assets"), }; var options = new DebuggerSessionOptions() { EvaluationOptions = EvaluationOptions.DefaultOptions, }; options.EvaluationOptions.UseExternalTypeResolver = true; ClearAdbLogcat(); b.BuildLogFile = "run.log"; parameters.Add($"AndroidSdbTargetPort={port}"); parameters.Add($"AndroidSdbHostPort={port}"); parameters.Add("AndroidAttachDebugger=True"); Assert.True(b.RunTarget(proj, "_Run", doNotCleanupOnUpdate: true, parameters: parameters.ToArray()), "Project should have run."); Assert.IsTrue(WaitForDebuggerToStart(Path.Combine(Root, b.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); int expected = 3; while (session.IsConnected && breakcountHitCount < 3 && timeout >= TimeSpan.Zero) { Thread.Sleep(10); timeout = timeout.Subtract(TimeSpan.FromMilliseconds(10)); } WaitFor(2000); Assert.AreEqual(expected, breakcountHitCount, $"Should have hit {expected} breakpoints. Only hit {breakcountHitCount}"); breakcountHitCount = 0; ClearAdbLogcat(); ClickButton(proj.PackageName, "myXFButton", "CLICK ME"); while (session.IsConnected && breakcountHitCount < 1 && timeout >= TimeSpan.Zero) { Thread.Sleep(10); timeout = timeout.Subtract(TimeSpan.FromMilliseconds(10)); } expected = 1; Assert.AreEqual(expected, breakcountHitCount, $"Should have hit {expected} breakpoints. Only hit {breakcountHitCount}"); b.BuildLogFile = "uninstall.log"; Assert.True(b.Uninstall(proj), "Project should have uninstalled."); session.Exit(); } }