Example #1
0
        [NonParallelizable]         // Do not run environment modifying tests in parallel.
        public void InstallAndroidDependenciesTest()
        {
            AssertCommercialBuild();
            // We need to grab the latest API level *before* changing env vars
            var apiLevel = AndroidSdkResolver.GetMaxInstalledPlatform();
            var old      = Environment.GetEnvironmentVariable("ANDROID_SDK_PATH");

            try {
                string sdkPath = Path.Combine(Root, "temp", TestName, "android-sdk");
                Environment.SetEnvironmentVariable("ANDROID_SDK_PATH", sdkPath);
                if (Directory.Exists(sdkPath))
                {
                    Directory.Delete(sdkPath, true);
                }
                Directory.CreateDirectory(sdkPath);
                var proj = new XamarinAndroidApplicationProject {
                    TargetSdkVersion = apiLevel.ToString(),
                };
                using (var b = CreateApkBuilder()) {
                    b.CleanupAfterSuccessfulBuild = false;
                    string defaultTarget = b.Target;
                    b.Target = "InstallAndroidDependencies";
                    Assert.IsTrue(b.Build(proj, parameters: new string [] { "AcceptAndroidSDKLicenses=true" }), "InstallAndroidDependencies should have succeeded.");
                    b.Target = defaultTarget;
                    Assert.IsTrue(b.Build(proj, true), "build should have succeeded.");
                    Assert.IsTrue(b.LastBuildOutput.ContainsText($"Output Property: _AndroidSdkDirectory={sdkPath}"), "_AndroidSdkDirectory was not set to new SDK path.");
                    Assert.IsTrue(b.LastBuildOutput.ContainsText($"JavaPlatformJarPath={sdkPath}"), "JavaPlatformJarPath did not contain new SDK path.");
                }
            } finally {
                Environment.SetEnvironmentVariable("ANDROID_SDK_PATH", old);
            }
        }
Example #2
0
        public void GetDependencyWhenBuildToolsAreMissingTest()
        {
            var apis           = new ApiInfo [] {
            };
            var path           = Path.Combine("temp", TestName);
            var androidSdkPath = CreateFauxAndroidSdkDirectory(Path.Combine(path, "android-sdk"),
                                                               null, apis);
            var referencesPath = CreateFauxReferencesDirectory(Path.Combine(path, "xbuild-frameworks"), apis);
            var proj           = new XamarinAndroidApplicationProject()
            {
                IsRelease = true,
                TargetFrameworkVersion = "v8.0",
                TargetSdkVersion       = "26",
                UseLatestPlatformSdk   = false,
            };
            var parameters = new string [] {
                $"TargetFrameworkRootPath={referencesPath}",
                $"AndroidSdkDirectory={androidSdkPath}",
            };
            string buildToolsVersion = GetExpectedBuildToolsVersion();

            using (var builder = CreateApkBuilder(Path.Combine(path, proj.ProjectName), cleanupAfterSuccessfulBuild: false, cleanupOnDispose: false)) {
                builder.ThrowOnBuildFailure = false;
                builder.Target = "GetAndroidDependencies";
                Assert.True(builder.Build(proj, parameters: parameters),
                            string.Format("First Build should have succeeded"));
                int apiLevel = Builder.UseDotNet ? AndroidSdkResolver.GetMaxInstalledPlatform() : 26;
                StringAssertEx.Contains($"platforms/android-{apiLevel}", builder.LastBuildOutput, $"platforms/android-{apiLevel} should be a dependency.");
                StringAssertEx.Contains($"build-tools/{buildToolsVersion}", builder.LastBuildOutput, $"build-tools/{buildToolsVersion} should be a dependency.");
                StringAssertEx.Contains("platform-tools", builder.LastBuildOutput, "platform-tools should be a dependency.");
            }
        }
Example #3
0
        public void CheckPerformanceOfManagedParser()
        {
            var path = Path.Combine("temp", TestName);

            CreateResourceDirectory(path);
            IBuildEngine      engine        = new MockBuildEngine(TestContext.Out);
            TaskLoggingHelper loggingHelper = new TaskLoggingHelper(engine, nameof(ManagedResourceParser));
            string            resPath       = Path.Combine(Root, path, "res");
            int       platform = AndroidSdkResolver.GetMaxInstalledPlatform();
            var       flagFile = Path.Combine(Root, path, "AndroidResgen.flag");
            var       lp       = new string [] { Path.Combine(Root, path, "lp", "res") };
            Stopwatch sw       = new Stopwatch();
            long      totalMS  = 0;
            int       i;

            for (i = 0; i < 100; i++)
            {
                var parser = new ManagedResourceParser()
                {
                    Log = loggingHelper,
                    JavaPlatformDirectory = Path.Combine(AndroidSdkDirectory, "platforms", $"android-{platform}"),
                    ResourceFlagFile      = flagFile,
                };
                sw.Start();
                var codeDom = parser.Parse(resPath, lp, isApp: true, resourceMap: new Dictionary <string, string> ());
                sw.Stop();
                TestContext.Out.WriteLine($"Pass {i} took {sw.ElapsedMilliseconds} ms");
                totalMS += sw.ElapsedMilliseconds;
                sw.Reset();
                Assert.AreEqual(20, codeDom.Members.Count, "Expected 20 Classes to be generated");
            }
            TestContext.Out.WriteLine($"Average {totalMS / i} ms");
            Assert.LessOrEqual(totalMS / i, 160, "Parser should have taken on average less than 160 ms.");
        }
Example #4
0
        public void Aapt2AndroidResgenExtraArgsAreSplit()
        {
            var path = Path.Combine(Root, "temp", TestName);

            Directory.CreateDirectory(path);
            var resPath      = Path.Combine(path, "res");
            var archivePath  = Path.Combine(path, "flata");
            var flatFilePath = Path.Combine(path, "flat");

            Directory.CreateDirectory(resPath);
            Directory.CreateDirectory(archivePath);
            Directory.CreateDirectory(Path.Combine(resPath, "values"));
            Directory.CreateDirectory(Path.Combine(resPath, "layout"));
            File.WriteAllText(Path.Combine(resPath, "values", "strings.xml"), @"<?xml version='1.0' ?><resources><string name='foo'>foo</string></resources>");
            File.WriteAllText(Path.Combine(resPath, "layout", "main.xml"), @"<?xml version='1.0' ?><LinearLayout xmlns:android='http://schemas.android.com/apk/res/android' />");
            File.WriteAllText(Path.Combine(path, "AndroidManifest.xml"), @"<?xml version='1.0' ?><manifest xmlns:android='http://schemas.android.com/apk/res/android' package='Foo.Foo' />");
            File.WriteAllText(Path.Combine(path, "foo.map"), @"a\nb");
            var          errors   = new List <BuildErrorEventArgs> ();
            var          warnings = new List <BuildWarningEventArgs> ();
            var          messages = new List <BuildMessageEventArgs> ();
            IBuildEngine engine   = new MockBuildEngine(TestContext.Out, errors, warnings, messages);
            var          archives = new List <ITaskItem>();

            CallAapt2Compile(engine, resPath, archivePath, flatFilePath);
            var    outputFile = Path.Combine(path, "resources.apk");
            int    platform   = AndroidSdkResolver.GetMaxInstalledPlatform();
            string emitids    = Path.Combine(path, "emitids.txt");
            string Rtxt       = Path.Combine(path, "R.txt");
            var    task       = new Aapt2Link {
                BuildEngine                 = engine,
                ToolPath                    = GetPathToAapt2(),
                ResourceDirectories         = new ITaskItem [] { new TaskItem(resPath) },
                ManifestFiles               = new ITaskItem [] { new TaskItem(Path.Combine(path, "AndroidManifest.xml")) },
                CompiledResourceFlatArchive = new TaskItem(Path.Combine(archivePath, "compiled.flata")),
                OutputFile                  = outputFile,
                AssemblyIdentityMapFile     = Path.Combine(path, "foo.map"),
                JavaPlatformJarPath         = Path.Combine(AndroidSdkPath, "platforms", $"android-{platform}", "android.jar"),
                ExtraArgs                   = $@"--no-version-vectors -v --emit-ids ""{emitids}"" --output-text-symbols '{Rtxt}'"
            };

            Assert.True(task.Execute(), $"task should have succeeded. {string.Join (" ", errors.Select (e => e.Message))}");
            Assert.AreEqual(0, errors.Count, $"No errors should have been raised. {string.Join (" ", errors.Select (e => e.Message))}");
            Assert.True(File.Exists(emitids), $"{emitids} should have been created.");
            Assert.True(File.Exists(Rtxt), $"{Rtxt} should have been created.");
            Directory.Delete(Path.Combine(Root, path), recursive: true);
        }
Example #5
0
        public void CompareAaptAndManagedParserOutputWithCustomIds()
        {
            var path = Path.Combine("temp", TestName);

            CreateResourceDirectory(path);
            File.WriteAllText(Path.Combine(Root, path, "res", "layout", "custom.xml"), CustomId);
            File.WriteAllText(Path.Combine(Root, path, "foo.map"), @"a\nb");
            Directory.CreateDirectory(Path.Combine(Root, path, "java"));
            string       resPath  = Path.Combine(Root, path, "res");
            int          platform = AndroidSdkResolver.GetMaxInstalledPlatform();
            IBuildEngine engine   = new MockBuildEngine(TestContext.Out);
            var          aapt     = new Aapt()
            {
                BuildEngine                      = engine,
                ToolPath                         = GetPathToAapt(),
                ResourceDirectory                = resPath,
                ManifestFiles                    = new ITaskItem [] { new TaskItem(Path.Combine(Root, path, "AndroidManifest.xml")) },
                ResourceOutputFile               = Path.Combine(Root, path, "foo.apk"),
                AssemblyIdentityMapFile          = Path.Combine(Root, path, "foo.map"),
                JavaPlatformJarPath              = Path.Combine(AndroidSdkDirectory, "platforms", $"android-{platform}", "android.jar"),
                JavaDesignerOutputDirectory      = Path.Combine(Root, path, "java"),
                ResourceSymbolsTextFileDirectory = Path.Combine(Root, path),
                AdditionalResourceDirectories    = new ITaskItem [] { new TaskItem(Path.Combine(Root, path, "lp", "res")) },
                AndroidUseLatestPlatformSdk      = true,
                ApiLevel                         = $"{platform}",
            };

            Assert.IsTrue(aapt.Execute(), "Aapt should have succeeded.");
            string rTxt = Path.Combine(Root, path, "R.txt");

            FileAssert.Exists(rTxt, $"{rTxt} should have been created.");

            var task = new GenerateResourceDesigner {
                BuildEngine = engine
            };

            task.UseManagedResourceGenerator = true;
            task.DesignTimeBuild             = false;
            task.Namespace           = "MonoAndroidApplication4.MonoAndroidApplication4";
            task.NetResgenOutputFile = Path.Combine(Root, path, "Resource.designer.aapt.cs");
            task.ProjectDir          = Path.Combine(Root, path);
            task.ResourceDirectory   = Path.Combine(Root, path, "res") + Path.DirectorySeparatorChar;
            task.Resources           = new TaskItem [] {
                new TaskItem(Path.Combine(Root, path, "res", "values", "strings.xml"), new Dictionary <string, string> ()
                {
                    { "LogicalName", "values\\strings.xml" },
                }),
            };
            task.AdditionalResourceDirectories = new TaskItem [] {
                new TaskItem(Path.Combine(Root, path, "lp", "res")),
            };
            task.ResourceFlagFile    = Path.Combine(Root, path, "AndroidResgen.flag");
            task.IsApplication       = true;
            task.JavaPlatformJarPath = aapt.JavaPlatformJarPath;
            Assert.IsTrue(task.Execute(), "Task should have executed successfully.");

            string aaptDesigner     = Path.Combine(Root, path, "Resource.designer.aapt.cs");
            var    aaptDesignerText = File.ReadAllText(aaptDesigner);

            StringAssert.Contains("MyCustomID", aaptDesignerText, "");
            StringAssert.Contains("HelloWorldTextView", aaptDesignerText, "");
            StringAssert.Contains("ACustomID", aaptDesignerText, "");
            StringAssert.Contains("foo1", aaptDesignerText, "");

            task.UseManagedResourceGenerator = true;
            task.DesignTimeBuild             = true;
            task.NetResgenOutputFile         = Path.Combine(Root, path, "Resource.designer.managedrtxt.cs");
            Assert.IsTrue(task.Execute(), "Task should have executed successfully.");

            string managedDesignerRtxt = Path.Combine(Root, path, "Resource.designer.managedrtxt.cs");

            CompareFilesIgnoreRuntimeInfoString(managedDesignerRtxt, aaptDesigner);

            File.WriteAllText(task.ResourceFlagFile, string.Empty);
            File.Delete(Path.Combine(Root, path, "R.txt.bak"));
            File.Move(rTxt, Path.Combine(Root, path, "R.txt.bak"));

            task.UseManagedResourceGenerator = true;
            task.DesignTimeBuild             = true;
            task.NetResgenOutputFile         = Path.Combine(Root, path, "Resource.designer.managed.cs");
            Assert.IsTrue(task.Execute(), "Task should have executed successfully.");
            string managedDesigner = Path.Combine(Root, path, "Resource.designer.managed.cs");

            var managedDesignerText = File.ReadAllText(managedDesigner);

            StringAssert.Contains("MyCustomID", managedDesignerText, "");
            StringAssert.Contains("HelloWorldTextView", managedDesignerText, "");
            StringAssert.Contains("ACustomID", managedDesignerText, "");
            StringAssert.Contains("foo1", managedDesignerText, "");

            Directory.Delete(Path.Combine(Root, path), recursive: true);
        }
Example #6
0
        public void CompareAapt2AndManagedParserOutput()
        {
            var path = Path.Combine("temp", TestName);

            CreateResourceDirectory(path);
            File.WriteAllText(Path.Combine(Root, path, "foo.map"), @"a\nb");
            Directory.CreateDirectory(Path.Combine(Root, path, "java"));
            List <BuildErrorEventArgs> errors = new List <BuildErrorEventArgs> ();
            IBuildEngine engine       = new MockBuildEngine(TestContext.Out, errors: errors);
            var          aapt2Compile = new Aapt2Compile {
                BuildEngine         = engine,
                ToolPath            = GetPathToAapt2(),
                ResourceDirectories = new ITaskItem [] {
                    new TaskItem(Path.Combine(Root, path, "lp", "res"), new Dictionary <string, string> {
                        { "Hash", "lp" }
                    }),
                    new TaskItem(Path.Combine(Root, path, "res"), new Dictionary <string, string> {
                        { "Hash", "compiled" }
                    }),
                },
                FlatArchivesDirectory = Path.Combine(Root, path),
                FlatFilesDirectory    = Path.Combine(Root, path),
            };

            Assert.IsTrue(aapt2Compile.Execute(), $"Aapt2 Compile should have succeeded. {string.Join (" ", errors.Select (x => x.Message))}");
            int    platform  = AndroidSdkResolver.GetMaxInstalledPlatform();
            string resPath   = Path.Combine(Root, path, "res");
            string rTxt      = Path.Combine(Root, path, "R.txt");
            var    aapt2Link = new Aapt2Link {
                BuildEngine                 = engine,
                ToolPath                    = GetPathToAapt2(),
                ResourceDirectories         = new ITaskItem [] { new TaskItem(resPath) },
                ManifestFiles               = new ITaskItem [] { new TaskItem(Path.Combine(Root, path, "AndroidManifest.xml")) },
                AdditionalResourceArchives  = new ITaskItem [] { new TaskItem(Path.Combine(Root, path, "lp.flata")) },
                CompiledResourceFlatArchive = new TaskItem(Path.Combine(Root, path, "compiled.flata")),
                OutputFile                  = Path.Combine(Root, path, "foo.apk"),
                AssemblyIdentityMapFile     = Path.Combine(Root, path, "foo.map"),
                JavaPlatformJarPath         = Path.Combine(AndroidSdkDirectory, "platforms", $"android-{platform}", "android.jar"),
                JavaDesignerOutputDirectory = Path.Combine(Root, path, "java"),
                ResourceSymbolsTextFile     = rTxt,
            };

            Assert.IsTrue(aapt2Link.Execute(), "Aapt2 Link should have succeeded.");

            FileAssert.Exists(rTxt, $"{rTxt} should have been created.");

            var task = new GenerateResourceDesigner {
                BuildEngine = engine
            };

            task.UseManagedResourceGenerator = true;
            task.DesignTimeBuild             = false;
            task.Namespace           = "MonoAndroidApplication4.MonoAndroidApplication4";
            task.NetResgenOutputFile = Path.Combine(Root, path, "Resource.designer.aapt2.cs");
            task.ProjectDir          = Path.Combine(Root, path);
            task.ResourceDirectory   = Path.Combine(Root, path, "res") + Path.DirectorySeparatorChar;
            task.Resources           = new TaskItem [] {
                new TaskItem(Path.Combine(Root, path, "res", "values", "strings.xml"), new Dictionary <string, string> ()
                {
                    { "LogicalName", "values\\strings.xml" },
                }),
            };
            task.AdditionalResourceDirectories = new TaskItem [] {
                new TaskItem(Path.Combine(Root, path, "lp", "res")),
            };
            task.ResourceFlagFile    = Path.Combine(Root, path, "AndroidResgen.flag");
            task.IsApplication       = true;
            task.JavaPlatformJarPath = aapt2Link.JavaPlatformJarPath;
            Assert.IsTrue(task.Execute(), "Task should have executed successfully.");

            File.WriteAllText(task.ResourceFlagFile, string.Empty);
            File.Delete(Path.Combine(Root, path, "R.txt.bak"));
            File.Move(rTxt, Path.Combine(Root, path, "R.txt.bak"));

            task.UseManagedResourceGenerator = true;
            task.DesignTimeBuild             = true;
            task.NetResgenOutputFile         = Path.Combine(Root, path, "Resource.designer.managed.cs");
            Assert.IsTrue(task.Execute(), "Task should have executed successfully.");
            string aapt2Designer   = Path.Combine(Root, path, "Resource.designer.aapt2.cs");
            string managedDesigner = Path.Combine(Root, path, "Resource.designer.managed.cs");

            CompareFilesIgnoreRuntimeInfoString(managedDesigner, aapt2Designer);
            Directory.Delete(Path.Combine(Root, path), recursive: true);
        }
Example #7
0
        public void Aapt2Link([Values(true, false)] bool compilePerFile)
        {
            var path = Path.Combine(Root, "temp", TestName);

            Directory.CreateDirectory(path);
            var resPath      = Path.Combine(path, "res");
            var archivePath  = Path.Combine(path, "flata");
            var flatFilePath = Path.Combine(path, "flat");

            Directory.CreateDirectory(resPath);
            Directory.CreateDirectory(archivePath);
            Directory.CreateDirectory(flatFilePath);
            Directory.CreateDirectory(Path.Combine(resPath, "values"));
            Directory.CreateDirectory(Path.Combine(resPath, "layout"));
            File.WriteAllText(Path.Combine(resPath, "values", "strings.xml"), @"<?xml version='1.0' ?><resources><string name='foo'>foo</string></resources>");
            File.WriteAllText(Path.Combine(resPath, "layout", "main.xml"), @"<?xml version='1.0' ?><LinearLayout xmlns:android='http://schemas.android.com/apk/res/android' />");
            var libPath = Path.Combine(path, "lp");

            Directory.CreateDirectory(libPath);
            Directory.CreateDirectory(Path.Combine(libPath, "0", "res", "values"));
            Directory.CreateDirectory(Path.Combine(libPath, "1", "res", "values"));
            File.WriteAllText(Path.Combine(libPath, "0", "res", "values", "strings.xml"), @"<?xml version='1.0' ?><resources><string name='foo1'>foo1</string></resources>");
            File.WriteAllText(Path.Combine(libPath, "1", "res", "values", "strings.xml"), @"<?xml version='1.0' ?><resources><string name='foo2'>foo2</string></resources>");
            File.WriteAllText(Path.Combine(path, "AndroidManifest.xml"), @"<?xml version='1.0' ?><manifest xmlns:android='http://schemas.android.com/apk/res/android' package='Foo.Foo' />");
            File.WriteAllText(Path.Combine(path, "foo.map"), @"a\nb");
            var          errors   = new List <BuildErrorEventArgs> ();
            var          warnings = new List <BuildWarningEventArgs> ();
            IBuildEngine engine   = new MockBuildEngine(TestContext.Out, errors, warnings);
            var          archives = new List <ITaskItem>();

            if (compilePerFile)
            {
                foreach (var file in Directory.EnumerateFiles(resPath, "*.*", SearchOption.AllDirectories))
                {
                    CallAapt2Compile(engine, file, archivePath, flatFilePath);
                }
            }
            else
            {
                CallAapt2Compile(engine, resPath, archivePath, flatFilePath);
            }
            CallAapt2Compile(engine, Path.Combine(libPath, "0", "res"), archivePath, flatFilePath, archives);
            CallAapt2Compile(engine, Path.Combine(libPath, "1", "res"), archivePath, flatFilePath, archives);
            List <ITaskItem> items = new List <ITaskItem> ();

            if (compilePerFile)
            {
                // collect all the flat archives
                foreach (var file in Directory.EnumerateFiles(flatFilePath, "*.flat", SearchOption.AllDirectories))
                {
                    items.Add(new TaskItem(file));
                }
            }
            int platform   = AndroidSdkResolver.GetMaxInstalledPlatform();
            var outputFile = Path.Combine(path, "resources.apk");
            var task       = new Aapt2Link {
                BuildEngine                = engine,
                ToolPath                   = GetPathToAapt2(),
                ResourceDirectories        = new ITaskItem [] { new TaskItem(resPath) },
                ManifestFiles              = new ITaskItem [] { new TaskItem(Path.Combine(path, "AndroidManifest.xml")) },
                AdditionalResourceArchives = !compilePerFile?archives.ToArray() : null,
                                                 CompiledResourceFlatArchive = !compilePerFile ? new TaskItem(Path.Combine(archivePath, "compiled.flata")) : null,
                                                 CompiledResourceFlatFiles   = compilePerFile ? items.ToArray() : null,
                                                 OutputFile = outputFile,
                                                 AssemblyIdentityMapFile = Path.Combine(path, "foo.map"),
                                                 JavaPlatformJarPath     = Path.Combine(AndroidSdkPath, "platforms", $"android-{platform}", "android.jar"),
            };

            Assert.True(task.Execute(), $"task should have succeeded. {string.Join (";", errors.Select (x => x.Message))}");
            Assert.AreEqual(0, errors.Count, "There should be no errors.");
            Assert.LessOrEqual(0, warnings.Count, "There should be 0 warnings.");
            Assert.True(File.Exists(outputFile), $"{outputFile} should have been created.");
            using (var apk = ZipHelper.OpenZip(outputFile)) {
                Assert.AreEqual(3, apk.EntryCount, $"{outputFile} should have 3 entries.");
            }
            Directory.Delete(Path.Combine(Root, path), recursive: true);
        }