Exemple #1
0
        public int GetMaxInstalledPlatform()
        {
            string sdkPath = AndroidSdkResolver.GetAndroidSdkPath();
            int    result  = 0;

            foreach (var dir in Directory.EnumerateDirectories(Path.Combine(sdkPath, "platforms")))
            {
                int    version;
                string v = Path.GetFileName(dir).Replace("android-", "");
                if (!int.TryParse(v, out version))
                {
                    continue;
                }
                if (version < result)
                {
                    continue;
                }
                result = version;
            }
            return(result);
        }
        public JarContentBuilder()
        {
            Action <TraceLevel, string> logger = (level, value) => {
                switch (level)
                {
                case TraceLevel.Error:
                    throw new Exception($"AndroidSdkInfo {level}: {value}");

                default:
                    Console.WriteLine($"AndroidSdkInfo {level}: {value}");
                    break;
                }
            };

            var sdkPath    = AndroidSdkResolver.GetAndroidSdkPath();
            var ndkPath    = AndroidSdkResolver.GetAndroidNdkPath();
            var androidSdk = new AndroidSdkInfo(logger, androidSdkPath: sdkPath, androidNdkPath: ndkPath);

            JavacFullPath = Path.Combine(androidSdk.JavaSdkPath, "bin", "javac");
            JarFullPath   = Path.Combine(androidSdk.JavaSdkPath, "bin", "jar");
        }
Exemple #3
0
        protected bool BuildInternal(string projectOrSolution, string target, string [] parameters = null, Dictionary <string, string> environmentVariables = null, bool restore = true)
        {
            buildLogFullPath = (!string.IsNullOrEmpty(BuildLogFile))
                                ? Path.GetFullPath(Path.Combine(XABuildPaths.TestOutputDirectory, Path.GetDirectoryName(projectOrSolution), BuildLogFile))
                                : null;
            string processLog = !string.IsNullOrEmpty(BuildLogFile)
                                ? Path.Combine(Path.GetDirectoryName(buildLogFullPath), "process.log")
                                : null;

            var logger = buildLogFullPath == null
                                ? string.Empty
                                : string.Format("/noconsolelogger \"/flp1:LogFile={0};Encoding=UTF-8;Verbosity={1}\"",
                                                buildLogFullPath, Verbosity.ToString().ToLower());

            var start        = DateTime.UtcNow;
            var args         = new StringBuilder();
            var psi          = new ProcessStartInfo(BuildTool);
            var responseFile = Path.Combine(XABuildPaths.TestOutputDirectory, Path.GetDirectoryName(projectOrSolution), "project.rsp");

            if (UseDotNet)
            {
                args.Append("build ");
            }
            args.AppendFormat("{0} /t:{1} {2}",
                              QuoteFileName(Path.Combine(XABuildPaths.TestOutputDirectory, projectOrSolution)), target, logger);
            if (AutomaticNuGetRestore && restore && !UseDotNet)
            {
                args.Append(" /restore");
            }
            args.Append($" @\"{responseFile}\"");
            using (var sw = new StreamWriter(responseFile, append: false, encoding: Encoding.UTF8)) {
                sw.WriteLine($" /p:BuildingInsideVisualStudio={BuildingInsideVisualStudio}");
                if (BuildingInsideVisualStudio)
                {
                    sw.WriteLine(" /p:BuildingOutOfProcess=true");
                }
                string sdkPath = AndroidSdkResolver.GetAndroidSdkPath();
                if (Directory.Exists(sdkPath))
                {
                    sw.WriteLine(" /p:AndroidSdkDirectory=\"{0}\" ", sdkPath);
                }
                string ndkPath = AndroidSdkResolver.GetAndroidNdkPath();
                if (Directory.Exists(ndkPath))
                {
                    sw.WriteLine(" /p:AndroidNdkDirectory=\"{0}\" ", ndkPath);
                }
                string jdkPath = AndroidSdkResolver.GetJavaSdkPath();
                if (Directory.Exists(jdkPath))
                {
                    sw.WriteLine(" /p:JavaSdkDirectory=\"{0}\" ", jdkPath);
                }
                if (parameters != null)
                {
                    foreach (var param in parameters)
                    {
                        sw.WriteLine(" /p:{0}", param);
                    }
                }
                var msbuildArgs = Environment.GetEnvironmentVariable("NUNIT_MSBUILD_ARGS");
                if (!string.IsNullOrEmpty(msbuildArgs))
                {
                    sw.WriteLine(msbuildArgs);
                }

                psi.EnvironmentVariables ["MSBUILD"] = "msbuild";
                sw.WriteLine($" /bl:\"{Path.GetFullPath (Path.Combine (XABuildPaths.TestOutputDirectory, Path.GetDirectoryName (projectOrSolution), "msbuild.binlog"))}\"");

                if (environmentVariables != null)
                {
                    foreach (var kvp in environmentVariables)
                    {
                        psi.EnvironmentVariables [kvp.Key] = kvp.Value;
                    }
                }
            }

            //NOTE: commit messages can "accidentally" cause test failures
            // Consider if you added an error message in a commit message, then wrote a test asserting the error no longer occurs.
            // Both Jenkins and VSTS have an environment variable containing the full commit message, which will inexplicably cause your test to fail...
            // For a Jenkins case, see https://github.com/xamarin/xamarin-android/pull/1049#issuecomment-347625456
            // For a VSTS case, see http://build.devdiv.io/1806783
            psi.EnvironmentVariables ["ghprbPullLongDescription"]       =
                psi.EnvironmentVariables ["BUILD_SOURCEVERSIONMESSAGE"] = "";

            psi.Arguments = args.ToString();

            psi.CreateNoWindow         = true;
            psi.UseShellExecute        = false;
            psi.RedirectStandardOutput = true;
            psi.RedirectStandardError  = true;
            psi.StandardErrorEncoding  = Encoding.UTF8;
            psi.StandardOutputEncoding = Encoding.UTF8;

            bool             nativeCrashDetected = false;
            bool             result          = false;
            bool             ranToCompletion = false;
            int              attempts        = 1;
            ManualResetEvent err             = new ManualResetEvent(false);
            ManualResetEvent stdout          = new ManualResetEvent(false);

            for (int attempt = 0; attempt < attempts; attempt++)
            {
                if (processLog != null)
                {
                    File.AppendAllText(processLog, psi.FileName + " " + args.ToString() + Environment.NewLine);
                }
                using (var p = new Process()) {
                    p.ErrorDataReceived += (sender, e) => {
                        if (e.Data != null && !string.IsNullOrEmpty(processLog))
                        {
                            File.AppendAllText(processLog, e.Data + Environment.NewLine);
                            if (e.Data.StartsWith(SigSegvError, StringComparison.OrdinalIgnoreCase))
                            {
                                nativeCrashDetected = true;
                            }
                            if (e.Data.StartsWith(ConsoleLoggerError, StringComparison.OrdinalIgnoreCase))
                            {
                                nativeCrashDetected = true;
                            }
                        }
                        if (e.Data == null)
                        {
                            err.Set();
                        }
                    };
                    p.OutputDataReceived += (sender, e) => {
                        if (e.Data != null && !string.IsNullOrEmpty(processLog))
                        {
                            File.AppendAllText(processLog, e.Data + Environment.NewLine);
                            if (e.Data.StartsWith(SigSegvError, StringComparison.OrdinalIgnoreCase))
                            {
                                nativeCrashDetected = true;
                            }
                            if (e.Data.StartsWith(ConsoleLoggerError, StringComparison.OrdinalIgnoreCase))
                            {
                                nativeCrashDetected = true;
                            }
                        }
                        if (e.Data == null)
                        {
                            stdout.Set();
                        }
                    };
                    p.StartInfo = psi;
                    Console.WriteLine($"{psi.FileName} {psi.Arguments}");
                    p.Start();
                    p.BeginOutputReadLine();
                    p.BeginErrorReadLine();
                    ranToCompletion = p.WaitForExit((int)new TimeSpan(0, 15, 0).TotalMilliseconds);
                    if (psi.RedirectStandardOutput)
                    {
                        stdout.WaitOne();
                    }
                    if (psi.RedirectStandardError)
                    {
                        err.WaitOne();
                    }
                    result = ranToCompletion && p.ExitCode == 0;
                }

                LastBuildTime = DateTime.UtcNow - start;

                if (processLog != null && !ranToCompletion)
                {
                    File.AppendAllText(processLog, "Build Timed Out!");
                }
                if (buildLogFullPath != null && File.Exists(buildLogFullPath))
                {
                    foreach (var line in LastBuildOutput)
                    {
                        if (line.StartsWith("Time Elapsed", StringComparison.OrdinalIgnoreCase))
                        {
                            var match = timeElapsedRegEx.Match(line);
                            if (match.Success)
                            {
                                LastBuildTime = TimeSpan.Parse(match.Groups ["TimeSpan"].Value);
                                Console.WriteLine($"Found Time Elapsed {LastBuildTime}");
                            }
                        }
                    }
                }

                if (nativeCrashDetected)
                {
                    Console.WriteLine($"Native crash detected! Running the build for {projectOrSolution} again.");
                    if (attempt == 0)
                    {
                        File.Move(processLog, processLog + ".bak");
                    }
                    nativeCrashDetected = false;
                    continue;
                }
                else
                {
                    break;
                }
            }


            if (buildLogFullPath != null && processLog != null)
            {
                Directory.CreateDirectory(Path.GetDirectoryName(buildLogFullPath));
                if (File.Exists(processLog))
                {
                    File.AppendAllText(buildLogFullPath, File.ReadAllText(processLog));
                }
            }
            if (!result && ThrowOnBuildFailure)
            {
                string message = "Build failure: " + Path.GetFileName(projectOrSolution) + (BuildLogFile != null && File.Exists(buildLogFullPath) ? "Build log recorded at " + buildLogFullPath : null);
                //NOTE: enormous logs will lock up IDE's UI. Build result files should be appended to the TestResult on failure.
                throw new FailedBuildException(message);
            }

            return(result);
        }