diff --git a/CODEOWNERS b/CODEOWNERS index f4266d712b..7973c3c05d 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -193,7 +193,6 @@ /tests/xtro-sharpie @spouliot /tests/mmptest @rolfbjarne /tests/common/mac @rolfbjarne -/tests/msbuild-mac @rolfbjarne /tests/bcl-tests @mandel-macaque /tools/common @rolfbjarne @spouliot diff --git a/tests/bgen/bgen-tests.csproj b/tests/bgen/bgen-tests.csproj index 917cd4665d..fff82edbf6 100644 --- a/tests/bgen/bgen-tests.csproj +++ b/tests/bgen/bgen-tests.csproj @@ -12,6 +12,7 @@ + @@ -48,5 +49,11 @@ StringUtils.cs + + Tool.cs + + + BinLog.cs + diff --git a/tests/common/BinLog.cs b/tests/common/BinLog.cs index aeb08551ca..179b4ec909 100644 --- a/tests/common/BinLog.cs +++ b/tests/common/BinLog.cs @@ -1,12 +1,34 @@ using System.Collections.Generic; +using System.Linq; using System.Text; +using Microsoft.Build.Framework; using Microsoft.Build.Logging.StructuredLogger; #nullable enable namespace Xamarin.Tests { + public class BuildLogEvent { + public BuildLogEventType Type; + + public int ColumnNumber; + public int EndColumnNumber; + public int LineNumber; + public int EndLineNumber; + public string? Code; + public string? SubCategory; + public string? File; + public string? ProjectFile; + public string? Message; + } + + public enum BuildLogEventType { + Message, + Warning, + Error, + } + public class BinLog { // Returns a diagnostic build log as an enumeration of lines @@ -24,11 +46,76 @@ namespace Xamarin.Tests if (args.Message == null) continue; + if (args is ProjectStartedEventArgs psea) { + if (psea.Properties != null) { + yield return "Initial Properties"; + foreach (var prop in psea.Properties.Cast ().OrderBy (v => v.Key)) + yield return $"{prop.Key} = {prop.Value}"; + } + } + foreach (var line in args.Message.Split (eols, System.StringSplitOptions.RemoveEmptyEntries)) yield return line; } } + public static IEnumerable GetBuildMessages (string path) + { + var reader = new BinLogReader (); + var eols = new char [] { '\n', '\r' }; + foreach (var record in reader.ReadRecords (path)) { + if (record == null) + continue; + var args = record.Args; + if (args == null) + continue; + + if (args is BuildErrorEventArgs buildError) { + var ea = buildError; + yield return new BuildLogEvent { + Type = BuildLogEventType.Error, + File = ea.File, + LineNumber = ea.LineNumber, + EndLineNumber = ea.EndLineNumber, + ColumnNumber = ea.ColumnNumber, + EndColumnNumber = ea.EndColumnNumber, + Message = ea.Message, + ProjectFile = ea.ProjectFile, + Code = ea.Code, + SubCategory = ea.Subcategory, + }; + } else if (args is BuildWarningEventArgs buildWarning) { + var ea = buildWarning; + yield return new BuildLogEvent { + Type = BuildLogEventType.Warning, + File = ea.File, + LineNumber = ea.LineNumber, + EndLineNumber = ea.EndLineNumber, + ColumnNumber = ea.ColumnNumber, + EndColumnNumber = ea.EndColumnNumber, + Message = ea.Message, + ProjectFile = ea.ProjectFile, + Code = ea.Code, + SubCategory = ea.Subcategory, + }; + } else if (args is BuildMessageEventArgs buildMessage) { + var ea = buildMessage; + yield return new BuildLogEvent { + Type = BuildLogEventType.Message, + File = ea.File, + LineNumber = ea.LineNumber, + EndLineNumber = ea.EndLineNumber, + ColumnNumber = ea.ColumnNumber, + EndColumnNumber = ea.EndColumnNumber, + Message = ea.Message, + ProjectFile = ea.ProjectFile, + Code = ea.Code, + SubCategory = ea.Subcategory, + }; + } + } + } + // Returns a diagnostic build log as a string public static string PrintToString (string path) { diff --git a/tests/common/ExecutionHelper.cs b/tests/common/ExecutionHelper.cs index dd1deb267d..a38f285422 100644 --- a/tests/common/ExecutionHelper.cs +++ b/tests/common/ExecutionHelper.cs @@ -10,406 +10,6 @@ using Xamarin.Utils; namespace Xamarin.Tests { - class ToolMessage - { - public bool IsError; - public bool IsWarning { get { return !IsError; } } - public string Prefix; - public int Number; - public string PrefixedNumber { get { return Prefix + Number.ToString (); } } - public string Message; - public string FileName; - public int LineNumber; - - public override string ToString () - { - if (string.IsNullOrEmpty (FileName)) { - return String.Format ("{0} {3}{1:0000}: {2}", IsError ? "error" : "warning", Number, Message, Prefix); - } else { - return String.Format ("{3}({4}): {0} {5}{1:0000}: {2}", IsError ? "error" : "warning", Number, Message, FileName, LineNumber, Prefix); - } - } - } - - abstract class Tool - { - StringBuilder output = new StringBuilder (); - - List output_lines; - - List messages = new List (); - - public Dictionary EnvironmentVariables { get; set; } - public TimeSpan Timeout { get; set; } = TimeSpan.FromSeconds (60); -#pragma warning disable 0649 // Field 'X' is never assigned to, and will always have its default value Y - public string WorkingDirectory; -#pragma warning restore 0649 - - public IEnumerable Messages { get { return messages; } } - public List OutputLines { - get { - if (output_lines == null) { - output_lines = new List (); - output_lines.AddRange (output.ToString ().Split ('\n')); - } - return output_lines; - } - } - - public StringBuilder Output { - get { - return output; - } - } - - public int Execute (IList arguments) - { - return Execute (ToolPath, arguments, false); - } - - public int Execute (IList arguments, bool always_show_output) - { - return Execute (ToolPath, arguments, always_show_output); - } - - public int Execute (string toolPath, IList arguments) - { - return Execute (toolPath, arguments, false); - } - - public int Execute (string toolPath, IList arguments, bool always_show_output) - { - output.Clear (); - output_lines = null; - - var args = new List (); - args.Add ("-t"); - args.Add ("--"); - args.Add (toolPath); - args.AddRange (arguments); - var rv = ExecutionHelper.Execute (Configuration.XIBuildPath, args, EnvironmentVariables, output, output, workingDirectory: WorkingDirectory); - - if ((rv != 0 || always_show_output) && output.Length > 0) - Console.WriteLine ("\t" + output.ToString ().Replace ("\n", "\n\t")); - - ParseMessages (); - - return rv; - } - - static bool IndexOfAny (string line, out int start, out int end, params string [] values) - { - foreach (var value in values) { - start = line.IndexOf (value, StringComparison.Ordinal); - if (start >= 0) { - end = start + value.Length; - return true; - } - } - start = -1; - end = -1; - return false; - } - - static string RemovePathAtEnd (string line) - { - if (line.TrimEnd ().EndsWith ("]", StringComparison.Ordinal)) { - var start = line.LastIndexOf ("[", StringComparison.Ordinal); - if (start >= 0) { - // we want to get the space before `[` too. - if (start > 0 && line [start - 1] == ' ') - start --; - - line = line.Substring (0, start); - return line; - } - } - - return line; - } - - public static List ParseMessages (string [] lines, string messageToolName) - { - var messages = new List (); - ParseMessages (messages, lines, messageToolName); - return messages; - } - - public static void ParseMessages (List messages, string [] lines, string messageToolName) - { - foreach (var l in lines) { - var line = l; - var msg = new ToolMessage (); - var origin = string.Empty; - - if (IndexOfAny (line, out var idxError, out var endError, ": error ", ": error ")) { - msg.IsError = true; - origin = line.Substring (0, idxError); - line = line.Substring (endError); - line = RemovePathAtEnd (line); - } else if (IndexOfAny (line, out var idxWarning, out var endWarning, ": warning ", ": warning ")) { - origin = line.Substring (0, idxWarning); - line = line.Substring (endWarning); - line = RemovePathAtEnd (line); - } else if (line.StartsWith ("error ", StringComparison.Ordinal)) { - msg.IsError = true; - line = line.Substring (6); - } else if (line.StartsWith ("warning ", StringComparison.Ordinal)) { - msg.IsError = false; - line = line.Substring (8); - } else { - // something else - continue; - } - if (line.Length < 7) - continue; // something else - - msg.Prefix = line.Substring (0, 2); - if (!int.TryParse (line.Substring (2, 4), out msg.Number)) - continue; // something else - - line = line.Substring (8); - var toolName = messageToolName; - if (toolName != null && line.StartsWith (toolName + ": ", StringComparison.Ordinal)) - line = line.Substring (toolName.Length + 2); - - msg.Message = line; - - if (!string.IsNullOrEmpty (origin)) { - var idx = origin.IndexOf ('('); - if (idx > 0) { - var closing = origin.IndexOf (')'); - var number = 0; - if (!int.TryParse (origin.Substring (idx + 1, closing - idx - 1), out number)) - continue; - msg.LineNumber = number; - msg.FileName = origin.Substring (0, idx); - } else { - msg.FileName = origin; - } - } - - messages.Add (msg); - } - } - - public void ParseMessages () - { - messages.Clear (); - ParseMessages (messages, output.ToString ().Split ('\n'), MessageToolName); - } - - public bool HasErrorPattern (string prefix, int number, string messagePattern) - { - foreach (var msg in messages) { - if (msg.IsError && msg.Prefix == prefix && msg.Number == number && Regex.IsMatch (msg.Message, messagePattern)) - return true; - } - return false; - } - - public int ErrorCount { - get { - return messages.Count ((v) => v.IsError); - } - } - - public int WarningCount { - get { - return GetWarningCount (messages); - } - } - - public static int GetWarningCount (IEnumerable messages) - { - return messages.Count ((v) => v.IsWarning); - } - - public bool HasError (string prefix, int number, string message) - { - foreach (var msg in messages) { - if (msg.IsError && msg.Prefix == prefix && msg.Number == number && msg.Message == message) - return true; - } - return false; - } - - public void AssertWarningCount (int count, string message = "warnings") - { - AssertWarningCount (messages, count, message); - } - - public static void AssertWarningCount (IEnumerable messages, int count, string message = "warnings") - { - if (count != GetWarningCount (messages)) - Assert.Fail ($"{message}\nExpected: {count}\nBut was: { GetWarningCount (messages)}\nWarnings:\n\t{string.Join ("\n\t", messages.Where ((v) => v.IsWarning).Select ((v) => v.ToString ()))}"); - } - - public void AssertErrorCount (int count, string message = "errors") - { - Assert.AreEqual (count, ErrorCount, message); - } - - public void AssertErrorPattern (int number, string messagePattern, string filename = null, int? linenumber = null, bool custom_pattern_syntax = false) - { - AssertErrorPattern (MessagePrefix, number, messagePattern, filename, linenumber, custom_pattern_syntax); - } - - public void AssertErrorPattern (string prefix, int number, string messagePattern, string filename = null, int? linenumber = null, bool custom_pattern_syntax = false) - { - if (!messages.Any ((msg) => msg.Prefix == prefix && msg.Number == number)) - Assert.Fail (string.Format ("The error '{0}{1:0000}' was not found in the output.", prefix, number)); - - // Custom pattern syntax: escape parenthesis and brackets so that they're treated like normal characters. - var processedPattern = custom_pattern_syntax ? messagePattern.Replace ("(", "[(]").Replace (")", "[)]").Replace ("[]", "[[][]]") + "$" : messagePattern; - var matches = messages.Where ((msg) => Regex.IsMatch (msg.Message, processedPattern)); - if (!matches.Any ()) { - var details = messages.Where ((msg) => msg.Prefix == prefix && msg.Number == number && !Regex.IsMatch (msg.Message, processedPattern)).Select ((msg) => string.Format ("\tThe message '{0}' did not match the pattern '{1}'.", msg.Message, messagePattern)); - Assert.Fail (string.Format ("The error '{0}{1:0000}: {2}' was not found in the output:\n{3}", prefix, number, messagePattern, string.Join ("\n", details.ToArray ()))); - } - - AssertFilename (prefix, number, messagePattern, matches, filename, linenumber); - } - - public void AssertError (int number, string message, string filename = null, int? linenumber = null) - { - AssertError (MessagePrefix, number, message, filename, linenumber); - } - - public void AssertError (string prefix, int number, string message, string filename = null, int? linenumber = null) - { - if (!messages.Any ((msg) => msg.Prefix == prefix && msg.Number == number)) - Assert.Fail (string.Format ("The error '{0}{1:0000}' was not found in the output.", prefix, number)); - - var matches = messages.Where ((msg) => msg.Message == message); - if (!matches.Any ()) { - var details = messages. - Where ((msg) => msg.Prefix == prefix && msg.Number == number && msg.Message != message). - Select ((msg) => string.Format ("\tMessage #{2} did not match:\n\t\tactual: '{0}'\n\t\texpected: '{1}'", msg.Message, message, messages.IndexOf (msg) + 1)); - Assert.Fail (string.Format ("The error '{0}{1:0000}: {2}' was not found in the output:\n{3}", prefix, number, message, string.Join ("\n", details.ToArray ()))); - } - - AssertFilename (prefix, number, message, matches, filename, linenumber); - } - - void AssertFilename (string prefix, int number, string message, IEnumerable matches, string filename, int? linenumber) - { - AssertFilename (messages, prefix, number, message, matches, filename, linenumber); - } - - static void AssertFilename (IList messages, string prefix, int number, string message, IEnumerable matches, string filename, int? linenumber) - { - if (filename != null) { - var hasDirectory = filename.IndexOf (Path.DirectorySeparatorChar) > -1; - if (!matches.Any ((v) => { - if (hasDirectory) { - // Check the entire path - return filename == v.FileName; - } else { - // Don't compare the directory unless one was specified. - return filename == Path.GetFileName (v.FileName); - } - })) { - var details = matches.Select ((msg) => string.Format ("\tMessage #{2} did not contain expected filename:\n\t\tactual: '{0}'\n\t\texpected: '{1}'", hasDirectory ? msg.FileName : Path.GetFileName (msg.FileName), filename, messages.IndexOf (msg) + 1)); - Assert.Fail (string.Format ($"The filename '{filename}' was not found in the output for the error {prefix}{number:X4}: {message}:\n{string.Join ("\n", details.ToArray ())}")); - } - } - - if (linenumber != null) { - if (!matches.Any ((v) => linenumber.Value == v.LineNumber)) { - var details = matches.Select ((msg) => string.Format ("\tMessage #{2} did not contain expected line number:\n\t\tactual: '{0}'\n\t\texpected: '{1}'", msg.LineNumber, linenumber, messages.IndexOf (msg) + 1)); - Assert.Fail (string.Format ($"The linenumber '{linenumber.Value}' was not found in the output for the error {prefix}{number:X4}: {message}:\n{string.Join ("\n", details.ToArray ())}")); - } - } - } - - public void AssertWarningPattern (int number, string messagePattern) - { - AssertWarningPattern (MessagePrefix, number, messagePattern); - } - - public void AssertWarningPattern (string prefix, int number, string messagePattern) - { - AssertWarningPattern (messages, prefix, number, messagePattern); - } - - public static void AssertWarningPattern (IEnumerable messages, string prefix, int number, string messagePattern) - { - if (!messages.Any ((msg) => msg.Prefix == prefix && msg.Number == number)) - Assert.Fail (string.Format ("The warning '{0}{1:0000}' was not found in the output.", prefix, number)); - - if (messages.Any ((msg) => Regex.IsMatch (msg.Message, messagePattern))) - return; - - var details = messages.Where ((msg) => msg.Prefix == prefix && msg.Number == number && !Regex.IsMatch (msg.Message, messagePattern)).Select ((msg) => string.Format ("\tThe message '{0}' did not match the pattern '{1}'.", msg.Message, messagePattern)); - Assert.Fail (string.Format ("The warning '{0}{1:0000}: {2}' was not found in the output:\n{3}", prefix, number, messagePattern, string.Join ("\n", details.ToArray ()))); - } - - public void AssertWarning (int number, string message, string filename = null, int? linenumber = null) - { - AssertWarning (MessagePrefix, number, message, filename, linenumber); - } - - public void AssertWarning (string prefix, int number, string message, string filename = null, int? linenumber = null) - { - AssertWarning (messages, prefix, number, message, filename, linenumber); - } - - public static void AssertWarning (IList messages, string prefix, int number, string message, string filename = null, int? linenumber = null) - { - if (!messages.Any ((msg) => msg.Prefix == prefix && msg.Number == number)) - Assert.Fail (string.Format ("The warning '{0}{1:0000}' was not found in the output.", prefix, number)); - - var matches = messages.Where ((msg) => msg.Message == message); - if (!matches.Any ()) { - var details = messages.Where ((msg) => msg.Prefix == prefix && msg.Number == number && msg.Message != message).Select ((msg) => string.Format ("\tMessage #{2} did not match:\n\t\tactual: '{0}'\n\t\texpected: '{1}'", msg.Message, message, messages.IndexOf (msg) + 1)); - Assert.Fail (string.Format ("The warning '{0}{1:0000}: {2}' was not found in the output:\n{3}", prefix, number, message, string.Join ("\n", details.ToArray ()))); - } - - AssertFilename (messages, prefix, number, message, matches, filename, linenumber); - } - - public void AssertNoWarnings () - { - var warnings = messages.Where ((v) => v.IsWarning); - if (!warnings.Any ()) - return; - - Assert.Fail ("No warnings expected, but got:\n{0}\t", string.Join ("\n\t", warnings.Select ((v) => v.Message).ToArray ())); - } - - public bool HasOutput (string line) - { - return OutputLines.Contains (line); - } - - public bool HasOutputPattern (string linePattern) - { - foreach (var line in OutputLines) { - if (Regex.IsMatch (line, linePattern, RegexOptions.CultureInvariant)) - return true; - } - - return false; - } - - public void AssertOutputPattern (string linePattern) - { - if (!HasOutputPattern (linePattern)) - Assert.Fail (string.Format ("The output does not contain the line '{0}'", linePattern)); - } - - public void ForAllOutputLines (Action action) - { - foreach (var line in OutputLines) - action (line); - } - - protected abstract string ToolPath { get; } - protected abstract string MessagePrefix { get; } - protected virtual string MessageToolName { get { return null; } } - } - class XBuild { public static string ToolPath { diff --git a/tests/common/Tool.cs b/tests/common/Tool.cs new file mode 100644 index 0000000000..73128576ea --- /dev/null +++ b/tests/common/Tool.cs @@ -0,0 +1,464 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; +using System.Text.RegularExpressions; + +using NUnit.Framework; +using Xamarin.Utils; + +namespace Xamarin.Tests +{ + class ToolMessage + { + public bool IsError; + public bool IsWarning { get { return !IsError; } } + public string Prefix; + public int Number; + public string PrefixedNumber { get { return Prefix + Number.ToString (); } } + public string Message; + public string FileName; + public int LineNumber; + + public override string ToString () + { + if (string.IsNullOrEmpty (FileName)) { + return String.Format ("{0} {3}{1:0000}: {2}", IsError ? "error" : "warning", Number, Message, Prefix); + } else { + return String.Format ("{3}({4}): {0} {5}{1:0000}: {2}", IsError ? "error" : "warning", Number, Message, FileName, LineNumber, Prefix); + } + } + } + + abstract class Tool + { + StringBuilder output = new StringBuilder (); + + List output_lines; + + List messages = new List (); + + public Dictionary EnvironmentVariables { get; set; } + public TimeSpan Timeout { get; set; } = TimeSpan.FromSeconds (60); +#pragma warning disable 0649 // Field 'X' is never assigned to, and will always have its default value Y + public string WorkingDirectory; +#pragma warning restore 0649 + + public IEnumerable Messages { get { return messages; } } + public List OutputLines { + get { + if (output_lines == null) { + output_lines = new List (); + output_lines.AddRange (output.ToString ().Split ('\n')); + } + return output_lines; + } + } + + public StringBuilder Output { + get { + return output; + } + } + + public int Execute (IList arguments) + { + return Execute (ToolPath, arguments, false); + } + + public int Execute (IList arguments, bool always_show_output) + { + return Execute (ToolPath, arguments, always_show_output); + } + + public int Execute (string toolPath, IList arguments) + { + return Execute (toolPath, arguments, false); + } + + public int Execute (string toolPath, IList arguments, bool always_show_output) + { + output.Clear (); + output_lines = null; + + var args = new List (); + args.Add ("-t"); + args.Add ("--"); + args.Add (toolPath); + args.AddRange (arguments); + var rv = ExecutionHelper.Execute (Configuration.XIBuildPath, args, EnvironmentVariables, output, output, workingDirectory: WorkingDirectory); + + if ((rv != 0 || always_show_output) && output.Length > 0) + Console.WriteLine ("\t" + output.ToString ().Replace ("\n", "\n\t")); + + ParseMessages (); + + return rv; + } + + static bool IndexOfAny (string line, out int start, out int end, params string [] values) + { + foreach (var value in values) { + start = line.IndexOf (value, StringComparison.Ordinal); + if (start >= 0) { + end = start + value.Length; + return true; + } + } + start = -1; + end = -1; + return false; + } + + static string RemovePathAtEnd (string line) + { + if (line.TrimEnd ().EndsWith ("]", StringComparison.Ordinal)) { + var start = line.LastIndexOf ("[", StringComparison.Ordinal); + if (start >= 0) { + // we want to get the space before `[` too. + if (start > 0 && line [start - 1] == ' ') + start --; + + line = line.Substring (0, start); + return line; + } + } + + return line; + } + + public static List ParseMessages (string [] lines, string messageToolName) + { + var messages = new List (); + ParseMessages (messages, lines, messageToolName); + return messages; + } + + public static void ParseMessages (List messages, string [] lines, string messageToolName) + { + foreach (var l in lines) { + var line = l; + var msg = new ToolMessage (); + var origin = string.Empty; + + if (IndexOfAny (line, out var idxError, out var endError, ": error ", ": error ")) { + msg.IsError = true; + origin = line.Substring (0, idxError); + line = line.Substring (endError); + line = RemovePathAtEnd (line); + } else if (IndexOfAny (line, out var idxWarning, out var endWarning, ": warning ", ": warning ")) { + origin = line.Substring (0, idxWarning); + line = line.Substring (endWarning); + line = RemovePathAtEnd (line); + } else if (line.StartsWith ("error ", StringComparison.Ordinal)) { + msg.IsError = true; + line = line.Substring (6); + } else if (line.StartsWith ("warning ", StringComparison.Ordinal)) { + msg.IsError = false; + line = line.Substring (8); + } else { + // something else + continue; + } + if (line.Length < 7) + continue; // something else + + msg.Prefix = line.Substring (0, 2); + if (!int.TryParse (line.Substring (2, 4), out msg.Number)) + continue; // something else + + line = line.Substring (8); + var toolName = messageToolName; + if (toolName != null && line.StartsWith (toolName + ": ", StringComparison.Ordinal)) + line = line.Substring (toolName.Length + 2); + + msg.Message = line; + + if (!string.IsNullOrEmpty (origin)) { + var idx = origin.IndexOf ('('); + if (idx > 0) { + var closing = origin.IndexOf (')'); + var number = 0; + if (!int.TryParse (origin.Substring (idx + 1, closing - idx - 1), out number)) + continue; + msg.LineNumber = number; + msg.FileName = origin.Substring (0, idx); + } else { + msg.FileName = origin; + } + } + + messages.Add (msg); + } + } + + public void ParseMessages () + { + messages.Clear (); + ParseMessages (messages, output.ToString ().Split ('\n'), MessageToolName); + } + + static bool TrySplitCode (string code, out string prefix, out int number) + { + prefix = null; + number = -1; + + if (code == null) + return false; + + for (var i = 0; i < code.Length; i++) { + var c = code [i]; + if (c >= '0' && c <= '9') { + prefix = code.Substring (0, i); + return int.TryParse (code.Substring (i), out number); + } + } + + return false; + } + + public void ParseBinLog (string binlog) + { + messages.Clear (); + foreach (var buildLogEvent in BinLog.GetBuildMessages (binlog)) { + // We're only interested in warnings and errors + if (buildLogEvent.Type != BuildLogEventType.Error && buildLogEvent.Type != BuildLogEventType.Warning) + continue; + + var msg = new ToolMessage (); + + if (TrySplitCode (buildLogEvent.Code, out var prefix, out var number)) { + msg.Prefix = prefix; + msg.Number = number; + } + + msg.IsError = buildLogEvent.Type == BuildLogEventType.Error; + msg.Message = buildLogEvent.Message; + msg.LineNumber = buildLogEvent.LineNumber; + msg.FileName = buildLogEvent.File; + + messages.Add (msg); + } + } + + public bool HasErrorPattern (string prefix, int number, string messagePattern) + { + foreach (var msg in messages) { + if (msg.IsError && msg.Prefix == prefix && msg.Number == number && Regex.IsMatch (msg.Message, messagePattern)) + return true; + } + return false; + } + + public int ErrorCount { + get { + return messages.Count ((v) => v.IsError); + } + } + + public int WarningCount { + get { + return GetWarningCount (messages); + } + } + + public static int GetWarningCount (IEnumerable messages) + { + return messages.Count ((v) => v.IsWarning); + } + + public bool HasError (string prefix, int number, string message) + { + foreach (var msg in messages) { + if (msg.IsError && msg.Prefix == prefix && msg.Number == number && msg.Message == message) + return true; + } + return false; + } + + public void AssertWarningCount (int count, string message = "warnings") + { + AssertWarningCount (messages, count, message); + } + + public static void AssertWarningCount (IEnumerable messages, int count, string message = "warnings") + { + if (count != GetWarningCount (messages)) + Assert.Fail ($"{message}\nExpected: {count}\nBut was: { GetWarningCount (messages)}\nWarnings:\n\t{string.Join ("\n\t", messages.Where ((v) => v.IsWarning).Select ((v) => v.ToString ()))}"); + } + + public void AssertErrorCount (int count, string message = "errors") + { + Assert.AreEqual (count, ErrorCount, message); + } + + public void AssertErrorPattern (int number, string messagePattern, string filename = null, int? linenumber = null, bool custom_pattern_syntax = false) + { + AssertErrorPattern (MessagePrefix, number, messagePattern, filename, linenumber, custom_pattern_syntax); + } + + public void AssertErrorPattern (string prefix, int number, string messagePattern, string filename = null, int? linenumber = null, bool custom_pattern_syntax = false) + { + if (!messages.Any ((msg) => msg.Prefix == prefix && msg.Number == number)) + Assert.Fail (string.Format ("The error '{0}{1:0000}' was not found in the output.", prefix, number)); + + // Custom pattern syntax: escape parenthesis and brackets so that they're treated like normal characters. + var processedPattern = custom_pattern_syntax ? messagePattern.Replace ("(", "[(]").Replace (")", "[)]").Replace ("[]", "[[][]]") + "$" : messagePattern; + var matches = messages.Where ((msg) => Regex.IsMatch (msg.Message, processedPattern)); + if (!matches.Any ()) { + var details = messages.Where ((msg) => msg.Prefix == prefix && msg.Number == number && !Regex.IsMatch (msg.Message, processedPattern)).Select ((msg) => string.Format ("\tThe message '{0}' did not match the pattern '{1}'.", msg.Message, messagePattern)); + Assert.Fail (string.Format ("The error '{0}{1:0000}: {2}' was not found in the output:\n{3}", prefix, number, messagePattern, string.Join ("\n", details.ToArray ()))); + } + + AssertFilename (prefix, number, messagePattern, matches, filename, linenumber); + } + + public void AssertError (int number, string message, string filename = null, int? linenumber = null) + { + AssertError (MessagePrefix, number, message, filename, linenumber); + } + + public void AssertError (string prefix, int number, string message, string filename = null, int? linenumber = null) + { + if (!messages.Any ((msg) => msg.Prefix == prefix && msg.Number == number)) + Assert.Fail (string.Format ("The error '{0}{1:0000}' was not found in the output.", prefix, number)); + + var matches = messages.Where ((msg) => msg.Message == message); + if (!matches.Any ()) { + var details = messages. + Where ((msg) => msg.Prefix == prefix && msg.Number == number && msg.Message != message). + Select ((msg) => string.Format ("\tMessage #{2} did not match:\n\t\tactual: '{0}'\n\t\texpected: '{1}'", msg.Message, message, messages.IndexOf (msg) + 1)); + Assert.Fail (string.Format ("The error '{0}{1:0000}: {2}' was not found in the output:\n{3}", prefix, number, message, string.Join ("\n", details.ToArray ()))); + } + + AssertFilename (prefix, number, message, matches, filename, linenumber); + } + + void AssertFilename (string prefix, int number, string message, IEnumerable matches, string filename, int? linenumber) + { + AssertFilename (messages, prefix, number, message, matches, filename, linenumber); + } + + static void AssertFilename (IList messages, string prefix, int number, string message, IEnumerable matches, string filename, int? linenumber) + { + if (filename != null) { + var hasDirectory = filename.IndexOf (Path.DirectorySeparatorChar) > -1; + if (!matches.Any ((v) => { + if (hasDirectory) { + // Check the entire path + return filename == v.FileName; + } else { + // Don't compare the directory unless one was specified. + return filename == Path.GetFileName (v.FileName); + } + })) { + var details = matches.Select ((msg) => string.Format ("\tMessage #{2} did not contain expected filename:\n\t\tactual: '{0}'\n\t\texpected: '{1}'", hasDirectory ? msg.FileName : Path.GetFileName (msg.FileName), filename, messages.IndexOf (msg) + 1)); + Assert.Fail (string.Format ($"The filename '{filename}' was not found in the output for the error {prefix}{number:X4}: {message}:\n{string.Join ("\n", details.ToArray ())}")); + } + } + + if (linenumber != null) { + if (!matches.Any ((v) => linenumber.Value == v.LineNumber)) { + var details = matches.Select ((msg) => string.Format ("\tMessage #{2} did not contain expected line number:\n\t\tactual: '{0}'\n\t\texpected: '{1}'", msg.LineNumber, linenumber, messages.IndexOf (msg) + 1)); + Assert.Fail (string.Format ($"The linenumber '{linenumber.Value}' was not found in the output for the error {prefix}{number:X4}: {message}:\n{string.Join ("\n", details.ToArray ())}")); + } + } + } + + public void AssertWarningPattern (int number, string messagePattern) + { + AssertWarningPattern (MessagePrefix, number, messagePattern); + } + + public void AssertWarningPattern (string prefix, int number, string messagePattern) + { + AssertWarningPattern (messages, prefix, number, messagePattern); + } + + public static void AssertWarningPattern (IEnumerable messages, string prefix, int number, string messagePattern) + { + if (!messages.Any ((msg) => msg.Prefix == prefix && msg.Number == number)) + Assert.Fail (string.Format ("The warning '{0}{1:0000}' was not found in the output.", prefix, number)); + + if (messages.Any ((msg) => Regex.IsMatch (msg.Message, messagePattern))) + return; + + var details = messages.Where ((msg) => msg.Prefix == prefix && msg.Number == number && !Regex.IsMatch (msg.Message, messagePattern)).Select ((msg) => string.Format ("\tThe message '{0}' did not match the pattern '{1}'.", msg.Message, messagePattern)); + Assert.Fail (string.Format ("The warning '{0}{1:0000}: {2}' was not found in the output:\n{3}", prefix, number, messagePattern, string.Join ("\n", details.ToArray ()))); + } + + public void AssertWarning (int number, string message, string filename = null, int? linenumber = null) + { + AssertWarning (MessagePrefix, number, message, filename, linenumber); + } + + public void AssertWarning (string prefix, int number, string message, string filename = null, int? linenumber = null) + { + AssertWarning (messages, prefix, number, message, filename, linenumber); + } + + public static void AssertWarning (IList messages, string prefix, int number, string message, string filename = null, int? linenumber = null) + { + if (!messages.Any ((msg) => msg.Prefix == prefix && msg.Number == number)) + Assert.Fail (string.Format ("The warning '{0}{1:0000}' was not found in the output.", prefix, number)); + + var matches = messages.Where ((msg) => msg.Message == message); + if (!matches.Any ()) { + var details = messages.Where ((msg) => msg.Prefix == prefix && msg.Number == number && msg.Message != message).Select ((msg) => string.Format ("\tMessage #{2} did not match:\n\t\tactual: '{0}'\n\t\texpected: '{1}'", msg.Message, message, messages.IndexOf (msg) + 1)); + Assert.Fail (string.Format ("The warning '{0}{1:0000}: {2}' was not found in the output:\n{3}", prefix, number, message, string.Join ("\n", details.ToArray ()))); + } + + AssertFilename (messages, prefix, number, message, matches, filename, linenumber); + } + + public void AssertNoWarnings () + { + var warnings = messages.Where ((v) => v.IsWarning); + if (!warnings.Any ()) + return; + + Assert.Fail ("No warnings expected, but got:\n{0}\t", string.Join ("\n\t", warnings.Select ((v) => v.Message).ToArray ())); + } + + public void AssertNoMessage (int number) + { + var msgs = messages.Where ((v) => v.Number == number); + if (!msgs.Any ()) + return; + + Assert.Fail ("No messages with number {0} expected, but got:\n{1}\t", number, string.Join ("\n\t", msgs.Select ((v) => v.Message).ToArray ())); + } + + public bool HasOutput (string line) + { + return OutputLines.Contains (line); + } + + public bool HasOutputPattern (string linePattern) + { + foreach (var line in OutputLines) { + if (Regex.IsMatch (line, linePattern, RegexOptions.CultureInvariant)) + return true; + } + + return false; + } + + public void AssertOutputPattern (string linePattern) + { + if (!HasOutputPattern (linePattern)) + Assert.Fail (string.Format ("The output does not contain the line '{0}'", linePattern)); + } + + public void ForAllOutputLines (Action action) + { + foreach (var line in OutputLines) + action (line); + } + + protected abstract string ToolPath { get; } + protected abstract string MessagePrefix { get; } + protected virtual string MessageToolName { get { return null; } } + } +} diff --git a/tests/common/mac/ProjectTestHelpers.cs b/tests/common/mac/ProjectTestHelpers.cs index 509bae8bbd..6c404e0e4f 100644 --- a/tests/common/mac/ProjectTestHelpers.cs +++ b/tests/common/mac/ProjectTestHelpers.cs @@ -12,35 +12,85 @@ using Xamarin.Tests; namespace Xamarin.MMP.Tests { + internal class MessageTool : Tool { + public MessageTool () + { + } + + public MessageTool (string text) + { + Output.Append (text); + } + + protected override string ToolPath => throw new NotImplementedException (); + + protected override string MessagePrefix => "MM"; + } + public class OutputText { - public string BuildOutput { get; private set; } + public BuildResult BuildResult { get; private set; } public string RunOutput { get; private set; } - public OutputText (string buildOutput, string runOutput) + public OutputText (BuildResult buildOutput, string runOutput) { - BuildOutput = buildOutput; + BuildResult = buildOutput; RunOutput = runOutput; } + internal MessageTool Messages { + get { + return BuildResult.Messages; + } + } + } + + public class BuildResult { + public readonly string BinLogPath; + + string build_output; + public string BuildOutput { + get { + if (build_output == null) + build_output = string.Join ("\n", BuildOutputLines); + return build_output; + } + } + + string [] build_output_lines; + public IList BuildOutputLines { + get { + if (build_output_lines == null) + build_output_lines = BinLog.PrintToLines (BinLogPath).ToArray (); + return build_output_lines; + } + } + + public BuildResult (string binLogPath) + { + BinLogPath = binLogPath; + } + + public bool HasMessage (int code) + { + return Messages.Messages.Any (v => v.Number == code); + } + + public bool HasMessage (int code, string message) + { + return Messages.Messages.Any (v => v.Number == code && v.Message == message); + } + MessageTool messages; internal MessageTool Messages { get { if (messages == null) { messages = new MessageTool (); - messages.Output.Append (BuildOutput); - messages.ParseMessages (); + messages.ParseBinLog (BinLogPath); } return messages; } } - - internal class MessageTool : Tool - { - protected override string ToolPath => throw new NotImplementedException (); - - protected override string MessagePrefix => "MM"; - } } static class FrameworkBuilder @@ -214,41 +264,38 @@ namespace Xamarin.MMP.Tests StringBuilder output = new StringBuilder (); environment ??= new Dictionary (); environment ["MONO_PATH"] = null; - int compileResult = Xamarin.Bundler.Driver.RunCommand (exe, args, environment, output, suppressPrintOnErrors: shouldFail); - if (!shouldFail && compileResult != 0 && Xamarin.Bundler.Driver.Verbosity < 1) { - Console.WriteLine ($"Execution failed; exit code: {compileResult}"); + environment ["DYLD_FALLBACK_LIBRARY_PATH"] = null; + int compileResult = ExecutionHelper.Execute (exe, args, environmentVariables: environment, stdout: output, stderr: output); + if (!shouldFail && compileResult != 0) { + Console.WriteLine ($"Execution of the following command failed (exit code: {compileResult}):"); + Console.WriteLine ($"cd {Environment.CurrentDirectory}"); + foreach (var kvp in Environment.GetEnvironmentVariables ().Cast ().OrderBy (v => v.Key)) + Console.WriteLine ($"export {kvp.Key}={StringUtils.Quote (kvp.Value.ToString ())}"); + Console.WriteLine ($"{exe} {StringUtils.FormatArguments (args)}"); + Console.WriteLine (output); } Func getInfo = () => getAdditionalFailInfo != null ? getAdditionalFailInfo () : ""; bool passed = shouldFail ? compileResult != 0 : compileResult == 0; - if (!passed) { - string outputLine = PrintRedirectIfLong ($"{exe} {StringUtils.FormatArguments (args)} Output: {output} {getInfo ()}"); - Assert.Fail ($@"{stepName} {(shouldFail ? "passed" : "failed")} unexpectedly: {outputLine}"); - } + if (!passed) + Assert.Fail ($@"{stepName} {(shouldFail ? "passed" : "failed")} unexpectedly. Exit code: {compileResult}."); return output.ToString (); } - public static string PrintRedirectIfLong (string outputLine) - { - if (outputLine.Length > 5000) { - Console.WriteLine (outputLine); - outputLine = "(Additional info redirected to console)"; - } - return outputLine; - } - // In most cases we generate projects in tmp and this is not needed. But nuget and test projects can make that hard public static void CleanUnifiedProject (string csprojTarget) { RunAndAssert (Configuration.XIBuildPath, new [] { "--", csprojTarget, "/t:clean" }, "Clean", environment: Configuration.GetBuildEnvironment (ApplePlatform.MacOSX)); } - public static string BuildProject (string csprojTarget, bool shouldFail = false, bool release = false, Dictionary environment = null, IList extraArgs = null) + public static BuildResult BuildProject (string csprojTarget, bool shouldFail = false, bool release = false, Dictionary environment = null, IList extraArgs = null) { Configuration.SetBuildVariables (ApplePlatform.MacOSX, ref environment); // This is to force build to use our mmp and not system mmp var buildArgs = new List (); - buildArgs.Add ("/verbosity:diagnostic"); + var binlog = Path.Combine (Path.GetDirectoryName (csprojTarget), $"log-{DateTime.Now:yyyyMMdd_HHmmss}.binlog"); + buildArgs.Add ($"/bl:{binlog}"); + Console.WriteLine ($"Binlog: {binlog}"); // Restore any package references buildArgs.Add ("/r"); @@ -271,7 +318,9 @@ namespace Xamarin.MMP.Tests }; buildArgs.Insert (0, "--"); - return RunAndAssert (Configuration.XIBuildPath, buildArgs, "Compile", shouldFail, getBuildProjectErrorInfo, environment); + RunAndAssert (Configuration.XIBuildPath, buildArgs, "Compile", shouldFail, getBuildProjectErrorInfo, environment); + + return new BuildResult (binlog); } static string ProjectTextReplacement (UnifiedTestConfig config, string text) @@ -410,7 +459,7 @@ namespace Xamarin.MMP.Tests return GenerateEXEProject (config); } - public static string GenerateAndBuildUnifiedExecutable (UnifiedTestConfig config, bool shouldFail = false, Dictionary environment = null) + public static BuildResult GenerateAndBuildUnifiedExecutable (UnifiedTestConfig config, bool shouldFail = false, Dictionary environment = null) { string csprojTarget = GenerateUnifiedExecutableProject (config); return BuildProject (csprojTarget, shouldFail: shouldFail, release: config.Release, environment: environment); @@ -425,7 +474,7 @@ namespace Xamarin.MMP.Tests { AddGUIDTestCode (config); - string buildOutput = GenerateAndBuildUnifiedExecutable (config, shouldFail, environment); + var buildOutput = GenerateAndBuildUnifiedExecutable (config, shouldFail, environment); if (shouldFail) return new OutputText (buildOutput, ""); @@ -451,7 +500,7 @@ namespace Xamarin.MMP.Tests config.ProjectName = $"{projectName}.csproj"; string csprojTarget = GenerateSystemMonoEXEProject (config); - string buildOutput = BuildProject (csprojTarget, shouldFail: shouldFail, release: config.Release); + var buildOutput = BuildProject (csprojTarget, shouldFail: shouldFail, release: config.Release); if (shouldFail) return new OutputText (buildOutput, ""); @@ -492,7 +541,7 @@ namespace Xamarin.MMP.Tests public static void CopyDirectory (string src, string target) { - Xamarin.Bundler.Driver.RunCommand ("/bin/cp", new [] { "-r", src, target }); + Assert.AreEqual (0, ExecutionHelper.Execute ("/bin/cp", new [] { "-r", src, target })); } public static string CopyFileWithSubstitutions (string src, string target, Func replacementAction) diff --git a/tests/generator/generator-tests.csproj b/tests/generator/generator-tests.csproj index 434325aebe..612d4832e8 100644 --- a/tests/generator/generator-tests.csproj +++ b/tests/generator/generator-tests.csproj @@ -33,6 +33,7 @@ + @@ -55,6 +56,12 @@ Profile.cs + + Tool.cs + + + BinLog.cs + diff --git a/tests/mmptest/mmptest.csproj b/tests/mmptest/mmptest.csproj index ef51257079..d90e303ae6 100644 --- a/tests/mmptest/mmptest.csproj +++ b/tests/mmptest/mmptest.csproj @@ -11,7 +11,7 @@ Xamarin.MMP.Tests mmptest v4.7.2 - latest + preview true @@ -39,6 +39,9 @@ ..\..\_mac-build\Library\Frameworks\Xamarin.Mac.framework\Versions\git\lib\mmp\mmp.exe + + 2.1.176 + @@ -114,6 +117,12 @@ Errors.Designer.cs + + BinLog.cs + + + src\Tool.cs + diff --git a/tests/mmptest/src/AOTTests.cs b/tests/mmptest/src/AOTTests.cs index 4b1ddefaa8..7eade6605f 100644 --- a/tests/mmptest/src/AOTTests.cs +++ b/tests/mmptest/src/AOTTests.cs @@ -14,11 +14,11 @@ namespace Xamarin.MMP.Tests [TestFixture] public class AOTTests { - void ValidateAOTStatus (string tmpDir, Func shouldAOT, string buildResults) + void ValidateAOTStatus (string tmpDir, Func shouldAOT) { foreach (var file in GetOutputDirInfo (tmpDir).EnumerateFiles ()) { bool shouldBeAOT = shouldAOT (file); - Assert.AreEqual (shouldBeAOT, File.Exists (file.FullName + ".dylib"), "{0} should {1}be AOT.\n{2}", file.FullName, shouldBeAOT ? "" : "not ", buildResults); + Assert.AreEqual (shouldBeAOT, File.Exists (file.FullName + ".dylib"), "{0} should {1}be AOT.", file.FullName, shouldBeAOT ? "" : "not "); } } @@ -59,9 +59,8 @@ namespace Xamarin.MMP.Tests TI.UnifiedTestConfig test = new TI.UnifiedTestConfig (tmpDir) { CSProjConfig = GetTestConfig (TestType.Base, useProjectTags) }; - string buildResults = TI.TestUnifiedExecutable (test).BuildOutput; - - ValidateAOTStatus (tmpDir, f => ShouldBaseFilesBeAOT (f), buildResults); + TI.TestUnifiedExecutable (test); + ValidateAOTStatus (tmpDir, f => ShouldBaseFilesBeAOT (f)); }); } @@ -73,15 +72,14 @@ namespace Xamarin.MMP.Tests TI.UnifiedTestConfig test = new TI.UnifiedTestConfig (tmpDir) { CSProjConfig = GetTestConfig (TestType.Hybrid, useProjectTags) }; - string buildResults = TI.TestUnifiedExecutable (test).BuildOutput; + TI.TestUnifiedExecutable (test); foreach (var file in GetOutputDirInfo (tmpDir).EnumerateFiles ()) { if (IsFileManagedCode (file)) TI.RunAndAssert ("/Library/Frameworks/Mono.framework/Commands/mono-cil-strip", new [] { file.ToString () }, "Manually strip IL"); - } - ValidateAOTStatus (tmpDir, IsFileManagedCode, buildResults); + ValidateAOTStatus (tmpDir, IsFileManagedCode); TI.RunEXEAndVerifyGUID (tmpDir, test.guid, GetOutputAppPath (tmpDir)); }); @@ -95,11 +93,11 @@ namespace Xamarin.MMP.Tests TI.UnifiedTestConfig test = new TI.UnifiedTestConfig (tmpDir) { CSProjConfig = GetTestConfig (TestType.Hybrid, useProjectTags) }; - string buildResults = TI.TestUnifiedExecutable (test).BuildOutput; + TI.TestUnifiedExecutable (test); TI.RunAndAssert ("/Library/Frameworks/Mono.framework/Commands/mono-cil-strip", new [] { Path.Combine (GetOutputBundlePath (tmpDir), "UnifiedExample.exe") }, "Manually strip IL"); - ValidateAOTStatus (tmpDir, IsFileManagedCode, buildResults); + ValidateAOTStatus (tmpDir, IsFileManagedCode); TI.RunEXEAndVerifyGUID (tmpDir, test.guid, GetOutputAppPath (tmpDir)); }); diff --git a/tests/mmptest/src/BindingProjectNoEmbeddingTests.cs b/tests/mmptest/src/BindingProjectNoEmbeddingTests.cs index afee3d750e..02de13858d 100644 --- a/tests/mmptest/src/BindingProjectNoEmbeddingTests.cs +++ b/tests/mmptest/src/BindingProjectNoEmbeddingTests.cs @@ -36,7 +36,7 @@ namespace Xamarin.MMP.Tests var projects = BindingProjectTests.GenerateTestProject (type, tmpDir); BindingProjectTests.SetNoEmbedding (projects.Item1); - string appBuildLog = BindingProjectTests.SetupAndBuildLinkedTestProjects (projects.Item1, projects.Item2, tmpDir, useProjectReference, setupDefaultNativeReference: true).Item2; + BindingProjectTests.SetupAndBuildLinkedTestProjects (projects.Item1, projects.Item2, tmpDir, useProjectReference, setupDefaultNativeReference: true); AssertNoResourceWithName (tmpDir, projects.Item1.ProjectName, "SimpleClassDylib.dylib"); AssertFileInBundle (tmpDir, type, "MonoBundle/SimpleClassDylib.dylib"); @@ -54,7 +54,7 @@ namespace Xamarin.MMP.Tests BindingProjectTests.SetNoEmbedding (projects.Item1); projects.Item1.ItemGroup = NativeReferenceTests.CreateSingleNativeRef (frameworkPath, "Framework"); - string appBuildLog = BindingProjectTests.SetupAndBuildLinkedTestProjects (projects.Item1, projects.Item2, tmpDir, useProjectReference, false).Item2; + BindingProjectTests.SetupAndBuildLinkedTestProjects (projects.Item1, projects.Item2, tmpDir, useProjectReference, false); AssertNoResourceWithName (tmpDir, projects.Item1.ProjectName, "Foo"); AssertFileInBundle (tmpDir, type, "Frameworks/Foo.framework/Foo", assertIsSymLink: true); @@ -70,8 +70,8 @@ namespace Xamarin.MMP.Tests projects.Item1.LinkWithName = "SimpleClassDylib.dylib"; - string libBuildLog = BindingProjectTests.SetupAndBuildBindingProject (projects.Item1, false, shouldFail: true); - Assert.True (libBuildLog.Contains ("Can't create a binding resource package unless there are native references in the binding project."), $"Did not fail as expected: {TI.PrintRedirectIfLong (libBuildLog)}"); + var buildResult = BindingProjectTests.SetupAndBuildBindingProject (projects.Item1, false, shouldFail: true); + buildResult.Messages.AssertError (7068, "Can't create a binding resource package unless there are native references in the binding project.\n "); }); } @@ -148,7 +148,7 @@ namespace Xamarin.MMP.Tests var projects = BindingProjectTests.GenerateTestProject (BindingProjectType.Modern, tmpDir); BindingProjectTests.SetNoEmbedding (projects.Item1); - string libBuildLog = BindingProjectTests.SetupAndBuildBindingProject (projects.Item1, true); + BindingProjectTests.SetupAndBuildBindingProject (projects.Item1, true); TI.CleanUnifiedProject (Path.Combine (tmpDir, projects.Item1.ProjectName)); Assert.False (Directory.Exists (Path.Combine (tmpDir, "bin/Debug/MobileBinding.resources")), "Resource bundle was not cleaned up"); diff --git a/tests/mmptest/src/BindingProjectTests.cs b/tests/mmptest/src/BindingProjectTests.cs index 88f3d1647f..b4cf49e30a 100644 --- a/tests/mmptest/src/BindingProjectTests.cs +++ b/tests/mmptest/src/BindingProjectTests.cs @@ -22,9 +22,9 @@ namespace Xamarin.MMP.Tests { internal static string RemoveCSProj (string s) => s.Remove (s.IndexOf (".csproj", StringComparison.InvariantCulture)); - internal static Tuple SetupAndBuildLinkedTestProjects (TI.UnifiedTestConfig binding, TI.UnifiedTestConfig project, string tmpDir, bool useProjectReference, bool setupDefaultNativeReference) + internal static (BuildResult BindingBuildResult, OutputText AppTestResult) SetupAndBuildLinkedTestProjects (TI.UnifiedTestConfig binding, TI.UnifiedTestConfig project, string tmpDir, bool useProjectReference, bool setupDefaultNativeReference) { - string bindingBuildLog = SetupAndBuildBindingProject (binding, setupDefaultNativeReference); + var bindingBuildLog = SetupAndBuildBindingProject (binding, setupDefaultNativeReference); string bindingName = RemoveCSProj (binding.ProjectName); @@ -35,12 +35,13 @@ namespace Xamarin.MMP.Tests project.TestCode = "System.Console.WriteLine (typeof (ExampleBinding.UnifiedWithDepNativeRefLibTestClass));"; - string appBuildLog = TI.TestUnifiedExecutable (project).BuildOutput; + var appBuildLog = TI.TestUnifiedExecutable (project); - return new Tuple (bindingBuildLog, appBuildLog); + (BuildResult BindingBuildResult, OutputText AppTestResult) rv = (bindingBuildLog, appBuildLog); + return rv; } - internal static string SetupAndBuildBindingProject (TI.UnifiedTestConfig binding, bool setupDefaultNativeReference, bool shouldFail = false) + internal static BuildResult SetupAndBuildBindingProject (TI.UnifiedTestConfig binding, bool setupDefaultNativeReference, bool shouldFail = false) { if (setupDefaultNativeReference) binding.ItemGroup += NativeReferenceTests.CreateSingleNativeRef (Path.GetFullPath (NativeReferenceTests.SimpleDylibPath), "Dynamic"); @@ -130,9 +131,9 @@ namespace Xamarin.MMP.Tests var logs = SetupAndBuildLinkedTestProjects (projects.Item1, projects.Item2, tmpDir, useProjectReference: false, setupDefaultNativeReference: noEmbedding); - Assert.True (logs.Item1.Contains ("csc"), "Bindings project must use csc:\n" + logs.Item1); + Assert.True (logs.BindingBuildResult.BuildOutput.Contains ("csc"), "Bindings project must use csc:\n" + logs.Item1); - var bgenInvocation = logs.Item1.SplitLines ().First (x => x.Contains ("bin/bgen")); + var bgenInvocation = logs.BindingBuildResult.BuildOutputLines.First (x => x.Contains ("bin/bgen")); var bgenParts = bgenInvocation.Split (new char[] { ' ' }); var mscorlib = bgenParts.First (x => x.Contains ("mscorlib.dll")); var system = bgenParts.First (x => x.Contains ("System.dll")); @@ -153,9 +154,9 @@ namespace Xamarin.MMP.Tests throw new NotImplementedException (); } - Assert.False (logs.Item1.Contains ("CS1685"), "Binding should not contains CS1685 multiple definition warning:\n" + logs.Item1); + Assert.False (logs.BindingBuildResult.BuildOutput.Contains ("CS1685"), "Binding should not contains CS1685 multiple definition warning."); - Assert.False (logs.Item1.Contains ("MSB9004"), "Binding should not contains MSB9004 warning:\n" + logs.Item1); + Assert.False (logs.BindingBuildResult.BuildOutput.Contains ("MSB9004"), "Binding should not contains MSB9004 warning"); string bindingName = RemoveCSProj (projects.Item1.ProjectName); string appName = RemoveCSProj (projects.Item2.ProjectName); diff --git a/tests/mmptest/src/CodeStrippingTests.cs b/tests/mmptest/src/CodeStrippingTests.cs index e87155c24d..4f50c9a51a 100644 --- a/tests/mmptest/src/CodeStrippingTests.cs +++ b/tests/mmptest/src/CodeStrippingTests.cs @@ -13,8 +13,15 @@ namespace Xamarin.MMP.Tests static Func LipoStripConditional = s => s.Contains ("lipo") && s.Contains ("-thin"); static Func LipoStripSkipPosixAndMonoNativeConditional = s => LipoStripConditional (s) && !s.Contains ("libMonoPosixHelper.dylib") && !s.Contains ("libmono-native.dylib"); - static Func DidAnyLipoStrip = output => output.SplitLines ().Any (LipoStripConditional); - static Func DidAnyLipoStripSkipPosixAndMonoNative = output => output.SplitLines ().Any (LipoStripSkipPosixAndMonoNativeConditional); + static bool DidAnyLipoStripSkipPosixAndMonoNative (BuildResult buildResult) + { + return buildResult.BuildOutputLines.Any (LipoStripSkipPosixAndMonoNativeConditional); + } + + static bool DidAnyLipoStrip (BuildResult buildResult) + { + return buildResult.BuildOutputLines.Any (LipoStripConditional); + } static TI.UnifiedTestConfig CreateStripTestConfig (bool? strip, string tmpDir, string additionalMMPArgs = "") { @@ -43,16 +50,16 @@ namespace Xamarin.MMP.Tests void StripTestCore (TI.UnifiedTestConfig test, bool debugStrips, bool releaseStrips, string libPath, bool shouldWarn) { - string buildOutput = TI.TestUnifiedExecutable (test).BuildOutput; - Assert.AreEqual (debugStrips, DidAnyLipoStrip (buildOutput), "Debug lipo usage did not match expectations"); + var testResult = TI.TestUnifiedExecutable (test); + Assert.AreEqual (debugStrips, DidAnyLipoStrip (testResult.BuildResult), "Debug lipo usage did not match expectations"); AssertStrip (Path.Combine (test.TmpDir, "bin/Debug/UnifiedExample.app/", libPath), shouldStrip: debugStrips); - Assert.AreEqual (shouldWarn && debugStrips, buildOutput.Contains ("MM2108"), "Debug warning did not match expectations"); + Assert.AreEqual (shouldWarn && debugStrips, testResult.BuildResult.HasMessage (2108), "Debug warning did not match expectations"); test.Release = true; - buildOutput = TI.TestUnifiedExecutable (test).BuildOutput; - Assert.AreEqual (releaseStrips, DidAnyLipoStrip (buildOutput), "Release lipo usage did not match expectations"); + testResult = TI.TestUnifiedExecutable (test); + Assert.AreEqual (releaseStrips, DidAnyLipoStrip (testResult.BuildResult), "Release lipo usage did not match expectations"); AssertStrip (Path.Combine (test.TmpDir, "bin/Release/UnifiedExample.app/", libPath), shouldStrip: releaseStrips); - Assert.AreEqual (shouldWarn && releaseStrips, buildOutput.Contains ("MM2108"), "Release warning did not match expectations"); + Assert.AreEqual (shouldWarn && releaseStrips, testResult.BuildResult.HasMessage (2108), "Release warning did not match expectations"); } [TestCase (null, false, true)] @@ -93,36 +100,41 @@ namespace Xamarin.MMP.Tests [TestCase (false, false)] public void ExplictStripOption_ThirdPartyLibrary_AndWarnsIfSo (bool? strip, bool shouldStrip) { - MMPTests.RunMMPTest (tmpDir => - { + MMPTests.RunMMPTest (tmpDir => { string originalLocation = Path.Combine (Configuration.SourceRoot, "tests", "test-libraries", "libtest-fat.macos.dylib"); - string newLibraryLocation = Path.Combine (tmpDir, "libTest.dylib"); + string newLibraryLocation = Path.Combine (tmpDir, "libTest.dylib"); File.Copy (originalLocation, newLibraryLocation); TI.UnifiedTestConfig test = CreateStripTestConfig (strip, tmpDir, $" --native-reference=\"{newLibraryLocation}\""); test.Release = true; - var testOutput = TI.TestUnifiedExecutable (test); - string buildOutput = testOutput.BuildOutput; - Assert.AreEqual (shouldStrip, DidAnyLipoStrip (buildOutput), "lipo usage did not match expectations"); + var testResult = TI.TestUnifiedExecutable (test); + var bundleDylib = Path.Combine (test.BundlePath, "Contents", "MonoBundle", "libTest.dylib"); + Assert.That (bundleDylib, Does.Exist, "libTest.dylib presence in app bundle"); + + var architectures = MachO.GetArchitectures (bundleDylib); if (shouldStrip) { - testOutput.Messages.AssertWarning (2108, "libTest.dylib was stripped of architectures except x86_64 to comply with App Store restrictions. This could break existing codesigning signatures. Consider stripping the library with lipo or disabling with --optimize=-trim-architectures"); + Assert.AreEqual (1, architectures.Count, "libTest.dylib should only contain 1 architecture"); + Assert.AreEqual (Abi.x86_64, architectures [0], "libTest.dylib should be x86_64"); + testResult.Messages.AssertWarning (2108, "libTest.dylib was stripped of architectures except x86_64 to comply with App Store restrictions. This could break existing codesigning signatures. Consider stripping the library with lipo or disabling with --optimize=-trim-architectures"); } else { - testOutput.Messages.AssertWarningCount (0); + Assert.AreEqual (2, architectures.Count, "libTest.dylib should contain 2+ architectures"); + Assert.That (architectures, Is.EquivalentTo (new Abi [] { Abi.i386, Abi.x86_64 }), "libTest.dylib should be x86_64 + i386"); + testResult.Messages.AssertWarningCount (1); // dylib ([...]/xamarin-macios/tests/mmptest/bin/Debug/tmp-test-dir/Xamarin.MMP.Tests.MMPTests.RunMMPTest47/bin/Release/UnifiedExample.app/Contents/MonoBundle/libTest.dylib) was built for newer macOS version (10.11) than being linked (10.9) } }); } - void AssertNoLipoOrWarning (string buildOutput, string context) + void AssertNoLipoOrWarning (BuildResult buildOutput, string context) { Assert.False (DidAnyLipoStrip (buildOutput), "lipo incorrectly run in context: " + context); - Assert.False (buildOutput.Contains ("MM2108"), "MM2108 incorrectly given in in context: " + context); + Assert.False (buildOutput.HasMessage (2108), "MM2108 incorrectly given in in context: " + context); } - void AssertLipoOnlyMonoPosixAndMonoNative (string buildOutput, string context) + void AssertLipoOnlyMonoPosixAndMonoNative (BuildResult buildOutput, string context) { Assert.False (DidAnyLipoStripSkipPosixAndMonoNative (buildOutput), "lipo incorrectly run in context outside of libMonoPosixHelper/libmono-native: " + context); - Assert.False (buildOutput.Contains ("MM2108"), "MM2108 incorrectly given in in context: " + context); + Assert.False (buildOutput.HasMessage (2108), "MM2108 incorrectly given in in context: " + context); } [TestCase (false)] @@ -136,14 +148,15 @@ namespace Xamarin.MMP.Tests TI.UnifiedTestConfig test = CreateStripTestConfig (null, tmpDir, $" --native-reference=\"{frameworkPath}\""); // Should always skip lipo/warning in Debug - string buildOutput = TI.TestUnifiedExecutable(test).BuildOutput; - AssertNoLipoOrWarning (buildOutput, "Debug"); + var testResult = TI.TestUnifiedExecutable (test); + AssertNoLipoOrWarning (testResult.BuildResult, "Debug"); // Should always lipo/warn in Release test.Release = true; - buildOutput = TI.TestUnifiedExecutable (test).BuildOutput; - Assert.True (DidAnyLipoStrip (buildOutput), $"lipo did not run in release"); - Assert.True (buildOutput.Contains ("MM2108"), $"MM2108 not given in release"); + testResult = TI.TestUnifiedExecutable (test); + Assert.True (DidAnyLipoStrip (testResult.BuildResult), $"lipo did not run in release"); + testResult.BuildResult.Messages.AssertError (2108, $"{frameworkPath} was stripped of architectures except x86_64 to comply with App Store restrictions. This could break existing codesigning signatures. Consider stripping the library with lipo or disabling with --optimize=-trim-architectures"); + // Assert.True (testResult.Contains ("MM2108"), $"MM2108 not given in release"); }); } @@ -157,12 +170,12 @@ namespace Xamarin.MMP.Tests TI.UnifiedTestConfig test = CreateStripTestConfig (null, tmpDir, $" --native-reference=\"{frameworkPath}\""); - string buildOutput = TI.TestUnifiedExecutable (test).BuildOutput; - AssertNoLipoOrWarning (buildOutput, "Debug"); + var testResult = TI.TestUnifiedExecutable (test); + AssertNoLipoOrWarning (testResult.BuildResult, "Debug"); test.Release = true; - buildOutput = TI.TestUnifiedExecutable (test).BuildOutput; - AssertLipoOnlyMonoPosixAndMonoNative (buildOutput, "Release"); // libMonoPosixHelper.dylib and libmono-native.dylib will lipo in Release + testResult = TI.TestUnifiedExecutable (test); + AssertLipoOnlyMonoPosixAndMonoNative (testResult.BuildResult, "Release"); // libMonoPosixHelper.dylib and libmono-native.dylib will lipo in Release }); } } diff --git a/tests/mmptest/src/LinkerTests.cs b/tests/mmptest/src/LinkerTests.cs index c49cad7359..cd9945ece0 100644 --- a/tests/mmptest/src/LinkerTests.cs +++ b/tests/mmptest/src/LinkerTests.cs @@ -78,21 +78,18 @@ namespace Xamarin.MMP.Tests CSProjConfig = $"--dynamic-symbol-mode={mode}\n", }; var output = TI.TestUnifiedExecutable (config); - string build_output; + var build_output = output.BuildResult.BuildOutput; switch (mode) { case "linker": case "default": - build_output = output.BuildOutput; Assert.That (build_output, Does.Contain ("-u "), "reference.m"); Assert.That (build_output, Does.Not.Contain ("reference.m"), "reference.m"); break; case "code": - build_output = output.BuildOutput; Assert.That (build_output, Does.Not.Contain ("-u "), "reference.m"); Assert.That (build_output, Does.Contain ("reference.m"), "reference.m"); break; case "ignore": - build_output = output.BuildOutput; Assert.That (build_output, Does.Not.Contain ("-u "), "reference.m"); Assert.That (build_output, Does.Not.Contain ("reference.m"), "reference.m"); break; @@ -117,8 +114,8 @@ namespace Xamarin.MMP.Tests TestCode = "System.Console.WriteLine (typeof (MixedClassLibrary.Class1));", }; - var buildOutput = TI.TestUnifiedExecutable (test, shouldFail: builds_successfully).BuildOutput; - Assert.True (buildOutput.Contains ("2014") == builds_successfully, $"Building with {linker} did not give 2014 status {builds_successfully} as expected.\n\n{buildOutput}"); + var buildOutput = TI.TestUnifiedExecutable (test, shouldFail: builds_successfully).BuildResult; + Assert.True (buildOutput.HasMessage (2014) == builds_successfully, $"Building with {linker} did not give 2014 status {builds_successfully} as expected."); }); } @@ -127,8 +124,8 @@ namespace Xamarin.MMP.Tests { MMPTests.RunMMPTest (tmpDir => { TI.UnifiedTestConfig test = new TI.UnifiedTestConfig (tmpDir) { CSProjConfig = "-v -v --linkplatform" }; - string buildOutput = TI.TestUnifiedExecutable (test).BuildOutput; - Assert.IsTrue (buildOutput.Contains ("Selected Linking: 'Platform'"), $"Build Output did not contain expected selected linking line: {buildOutput}"); + var testResult = TI.TestUnifiedExecutable (test); + Assert.IsTrue (testResult.BuildResult.BuildOutput.Contains ("Selected Linking: 'Platform'"), $"Build Output did not contain expected selected linking line: {testResult}"); }); } @@ -137,8 +134,8 @@ namespace Xamarin.MMP.Tests { MMPTests.RunMMPTest (tmpDir => { TI.UnifiedTestConfig test = new TI.UnifiedTestConfig (tmpDir) { CSProjConfig = "--registrar:partial --linkplatform" }; - string buildOutput = TI.TestUnifiedExecutable (test, shouldFail: true).BuildOutput; - Assert.True (buildOutput.Contains ("2110"), $"Building did not give the expected 2110 error.\n\n{buildOutput}"); + var testResult = TI.TestUnifiedExecutable (test, shouldFail: true); + testResult.BuildResult.Messages.AssertError (2110, "Xamarin.Mac 'Partial Static' registrar does not support linking. Disable linking or use another registrar mode."); }); } } diff --git a/tests/mmptest/src/MMPTest.cs b/tests/mmptest/src/MMPTest.cs index 9af9015648..59de9db1ad 100644 --- a/tests/mmptest/src/MMPTest.cs +++ b/tests/mmptest/src/MMPTest.cs @@ -24,8 +24,7 @@ namespace Xamarin.MMP.Tests public static string [] GetUnifiedProjectClangInvocation (string tmpDir, string projectConfig = "") { TI.UnifiedTestConfig test = new TI.UnifiedTestConfig (tmpDir) { CSProjConfig = projectConfig }; - string buildOutput = TI.TestUnifiedExecutable (test).BuildOutput; - string [] splitBuildOutput = TI.TestUnifiedExecutable (test).BuildOutput.Split (new string[] { Environment.NewLine }, StringSplitOptions.None); + var splitBuildOutput = TI.TestUnifiedExecutable (test).BuildResult.BuildOutputLines; string clangInvocation = splitBuildOutput.Single (x => x.Contains ("usr/bin/clang") && x.Contains ("mmacosx-version-min")); return clangInvocation.Split (new string[] { " " }, StringSplitOptions.None); } @@ -87,8 +86,8 @@ namespace Xamarin.MMP.Tests { RunMMPTest (tmpDir => { TI.UnifiedTestConfig test = new TI.UnifiedTestConfig (tmpDir) { CSProjConfig = "--new-refcount=false" }; - string buildOutput = TI.TestUnifiedExecutable (test).BuildOutput; - Assert.IsTrue (buildOutput.Contains ("Disabling the new refcount logic is deprecated"), "Mobile_NewRefCount_Warns did not warn as expected:\n\n", buildOutput); + var testResult = TI.TestUnifiedExecutable (test); + testResult.Messages.AssertWarning (80, "Disabling the new refcount logic is deprecated."); }); } @@ -136,7 +135,7 @@ namespace Xamarin.MMP.Tests test.XM45 = full; var rv = TI.TestUnifiedExecutable (test); - Console.WriteLine (rv.BuildOutput); + Console.WriteLine (rv.BuildResult); if (full && release) { rv.Messages.AssertWarning (5220, "Skipping framework 'QTKit'. It is prohibited (rejected) by the Mac App Store"); // We get the MM5220 twice in the output, once from mmp and once from msbuild repeating what mmp said, so we can't assert that there's exactly 1 warning. @@ -262,9 +261,8 @@ namespace Xamarin.MMP.Tests TI.UnifiedTestConfig test = new TI.UnifiedTestConfig (tmpDir) { CSProjConfig = string.Format ("--machine-config={0}", invalidConfigPath) }; - string buildOutput = TI.TestUnifiedExecutable (test, shouldFail : true).BuildOutput; - Assert.IsTrue (buildOutput.Contains ("can not be found"), "Unified_InvalidMachineConfigInBundle_ThrowsError did not error as expected (1):\n\n", buildOutput); - Assert.IsTrue (buildOutput.Contains ("97"), "Unified_InvalidMachineConfigInBundle_ThrowsError did not error as expected (2):\n\n", buildOutput); + var testResult = TI.TestUnifiedExecutable (test, shouldFail : true); + testResult.Messages.AssertError (97, $"machine.config file '{invalidConfigPath}' can not be found."); }); } @@ -339,8 +337,9 @@ namespace Xamarin.MMP.Tests TI.GenerateUnifiedExecutableProject (test); // And try again. - // If we fail, we'll likley fail with "did not generate an exe" before returning but let's check anyway - string secondBuildOutput = TI.BuildProject (Path.Combine (tmpDir, TI.GetUnifiedExecutableProjectName (test))); + // If we fail, we'll likely fail with "did not generate an exe" before returning but let's check anyway + var secondBuildResult = TI.BuildProject (Path.Combine (tmpDir, TI.GetUnifiedExecutableProjectName (test))); + var secondBuildOutput = secondBuildResult.BuildOutput; Assert.IsTrue (!secondBuildOutput.Contains ("Skipping target \"_CompileToNative"), "Did not skip"); Assert.IsTrue (secondBuildOutput.Contains ("Building target \"_CompileToNative\" completely"), "Did need to build"); } @@ -397,8 +396,8 @@ namespace Xamarin.MMP.Tests RunMMPTest (tmpDir => { TI.UnifiedTestConfig test = new TI.UnifiedTestConfig (tmpDir) { XM45 = xm45 }; test.Release = true; - string buildResults = TI.TestUnifiedExecutable (test).BuildOutput; - Assert.IsFalse (buildResults.Contains ("Xamarin.Mac.registrar"), "Release build should not use partial static registrar"); + var testResults = TI.TestUnifiedExecutable (test); + Assert.IsFalse (testResults.BuildResult.BuildOutput.Contains ("Xamarin.Mac.registrar"), "Release build should not use partial static registrar"); }); } @@ -410,8 +409,8 @@ namespace Xamarin.MMP.Tests TI.UnifiedTestConfig test = new TI.UnifiedTestConfig (tmpDir) { XM45 = xm45 }; test.Release = false; test.CSProjConfig = "true"; - var buildResults = TI.TestUnifiedExecutable (test).BuildOutput; - Assert.IsTrue (buildResults.Contains ("Xamarin.Mac.registrar"), "Debug build should use partial static registrar"); + var testResults = TI.TestUnifiedExecutable (test); + Assert.IsTrue (testResults.BuildResult.BuildOutput.Contains ("Xamarin.Mac.registrar"), "Debug build should use partial static registrar"); }); } @@ -423,8 +422,8 @@ namespace Xamarin.MMP.Tests TI.UnifiedTestConfig test = new TI.UnifiedTestConfig (tmpDir) { XM45 = xm45 }; test.Release = false; test.CSProjConfig = "true--registrar=dynamicx86_64"; - var buildResults = TI.TestUnifiedExecutable (test).BuildOutput; - Assert.IsFalse (buildResults.Contains ("Xamarin.Mac.registrar"), "registrar=dynamic build should not use partial static registrar"); + var testResult = TI.TestUnifiedExecutable (test); + Assert.IsFalse (testResult.BuildResult.BuildOutput.Contains ("Xamarin.Mac.registrar"), "registrar=dynamic build should not use partial static registrar"); }); } @@ -436,8 +435,8 @@ namespace Xamarin.MMP.Tests TI.UnifiedTestConfig test = new TI.UnifiedTestConfig (tmpDir) { XM45 = xm45 }; test.Release = false; test.CSProjConfig = "true--registrar=partialx86_64"; - var buildResults = TI.TestUnifiedExecutable (test).BuildOutput; - Assert.IsTrue (buildResults.Contains ("Xamarin.Mac.registrar"), "registrar=partial build should use partial static registrar"); + var testResults = TI.TestUnifiedExecutable (test); + Assert.IsTrue (testResults.BuildResult.BuildOutput.Contains ("Xamarin.Mac.registrar"), "registrar=partial build should use partial static registrar"); }); } //https://testrail.xamarin.com/index.php?/cases/view/234141&group_by=cases:section_id&group_order=asc&group_id=51097 @@ -447,7 +446,7 @@ namespace Xamarin.MMP.Tests RunMMPTest (tmpDir => { TI.UnifiedTestConfig test = new TI.UnifiedTestConfig (tmpDir) { XM45 = true }; var output = TI.TestUnifiedExecutable (test); - Assert.That (output.BuildOutput, Contains.Substring ("Selected target framework: Xamarin.Mac,Version=v4.5,Profile=Full; API: Unified")); + Assert.That (output.BuildResult.BuildOutput, Contains.Substring ("Selected target framework: Xamarin.Mac,Version=v4.5,Profile=Full; API: Unified")); }); } @@ -659,7 +658,7 @@ namespace Xamarin.MMP.Tests string project = TI.GenerateUnifiedExecutableProject (test); TI.NugetRestore (project); var rv = new OutputText (TI.BuildProject (project), string.Empty); - Console.WriteLine (rv.BuildOutput); + Console.WriteLine (rv.BuildResult); if (xm45) { var referenced_version = tfv == null ? "2.0.0.0" : "4.0.0.0"; rv.Messages.AssertWarningPattern (176, $"The assembly 'System.Web, Version={referenced_version}, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' was resolved from the system's GAC: /Library/Frameworks/Mono.framework/Versions/.*/lib/mono/gac/System.Web/4.0.0.0__b03f5f7f11d50a3a/System.Web.dll. This could potentially be a problem in the future; to avoid such problems, please make sure to not use assemblies only available in the system's GAC."); @@ -697,15 +696,18 @@ namespace Xamarin.MMP.Tests string project = TI.GenerateUnifiedExecutableProject (test); - string buildOutput = TI.BuildProject (project); + var buildResult = TI.BuildProject (project); + var buildOutput = buildResult.BuildOutput; Assert.True (buildOutput.Contains (actool), $"Initial build should run actool"); - buildOutput = TI.BuildProject (project); + buildResult = TI.BuildProject (project); + buildOutput = buildResult.BuildOutput; Assert.False (buildOutput.Contains (actool), $"Second build should not run actool"); TI.RunAndAssert ("touch", new [] { Path.Combine (tmpDir, "Assets.xcassets/AppIcon.appiconset/AppIcon-256@2x.png") }, "touch icon"); - buildOutput = TI.BuildProject (project); + buildResult = TI.BuildProject (project); + buildOutput = buildResult.BuildOutput; Assert.True (buildOutput.Contains (actool), $"Build after touching icon must run actool"); }); } @@ -722,7 +724,7 @@ namespace Xamarin.MMP.Tests CSProjConfig = "true" }; - Func findCodesign = o => o.BuildOutput.SplitLines ().Last (x => x.Contains ("Tool /usr/bin/codesign execution started with arguments")); + Func findCodesign = o => o.BuildResult.BuildOutputLines.Last (x => x.Contains ("Tool /usr/bin/codesign execution started with arguments")); var baseOutput = TI.TestUnifiedExecutable (test); string baseCodesign = findCodesign (baseOutput); @@ -764,7 +766,7 @@ namespace Xamarin.MMP.Tests CSProjConfig = "true" }; TI.TestUnifiedExecutable (test); - var output = TI.BuildProject (Path.Combine (tmpDir, full ? "XM45Example.csproj" : "UnifiedExample.csproj"), release: true, extraArgs: new [] { "/p:ArchiveOnBuild=true" }); + TI.BuildProject (Path.Combine (tmpDir, full ? "XM45Example.csproj" : "UnifiedExample.csproj"), release: true, extraArgs: new [] { "/p:ArchiveOnBuild=true" }); }); // TODO: Add something to validate the archive is loadable by Xcode @@ -778,7 +780,7 @@ namespace Xamarin.MMP.Tests CSProjConfig = "-link_flags=-fobjc-arc" }; TI.TestUnifiedExecutable (test); - var output = TI.BuildProject (Path.Combine (tmpDir, "UnifiedExample.csproj")); + TI.BuildProject (Path.Combine (tmpDir, "UnifiedExample.csproj")); }); } diff --git a/tests/mmptest/src/NativeReferencesTests.cs b/tests/mmptest/src/NativeReferencesTests.cs index d89bbeb210..d5a7741f18 100644 --- a/tests/mmptest/src/NativeReferencesTests.cs +++ b/tests/mmptest/src/NativeReferencesTests.cs @@ -55,14 +55,14 @@ namespace Xamarin.MMP.Tests return filePath; } - void NativeReferenceTestCore (string tmpDir, TI.UnifiedTestConfig test, string testName, string libraryName, bool buildShouldBeSuccessful, bool libraryShouldNotBeCopied = false, Func processBuildOutput = null) + void NativeReferenceTestCore (string tmpDir, TI.UnifiedTestConfig test, string testName, string libraryName, bool buildShouldBeSuccessful, bool libraryShouldNotBeCopied = false, Func processBuildOutput = null) { // Mobile test.XM45 = false; - string buildResults = TI.TestUnifiedExecutable (test, false).BuildOutput; - Assert.IsTrue (!buildShouldBeSuccessful || !buildResults.Contains ("MM2006"), string.Format ("{0} - Mobile had MM2006 state {1} not match expected\n{2}", testName, buildShouldBeSuccessful, buildResults)); + var testResult = TI.TestUnifiedExecutable (test, false); + Assert.IsTrue (!buildShouldBeSuccessful || !testResult.BuildResult.HasMessage (2006), string.Format ("{0} - Mobile had MM2006 state {1} not match expected\n{2}", testName, buildShouldBeSuccessful, testResult)); if (processBuildOutput != null) - Assert.IsTrue (processBuildOutput (buildResults), string.Format ("{0} - Mobile - We did not see our expected item in the build output: {1}", testName, libraryName)); + Assert.IsTrue (processBuildOutput (testResult.BuildResult), string.Format ("{0} - Mobile - We did not see our expected item in the build output: {1}", testName, libraryName)); string mobileBundlePath = Path.Combine (tmpDir, "bin/Debug/UnifiedExample.app/Contents/MonoBundle/"); if (libraryName != null) @@ -70,10 +70,10 @@ namespace Xamarin.MMP.Tests // XM45 test.XM45 = true; - buildResults = TI.TestUnifiedExecutable (test, false).BuildOutput; - Assert.IsTrue (!buildShouldBeSuccessful || !buildResults.Contains ("MM2006"), string.Format ("{0} - XM45 had MM2006 state {1} not match expected\n{2}", testName, buildShouldBeSuccessful, buildResults)); + testResult = TI.TestUnifiedExecutable (test, false); + Assert.IsTrue (!buildShouldBeSuccessful || !testResult.BuildResult.HasMessage (2006), string.Format ("{0} - XM45 had MM2006 state {1} not match expected\n{2}", testName, buildShouldBeSuccessful, testResult)); if (processBuildOutput != null) - Assert.IsTrue (processBuildOutput (buildResults), string.Format ("{0} - Mobile - We did not see our expected item in the build output: {1}", testName, libraryName)); + Assert.IsTrue (processBuildOutput (testResult.BuildResult), string.Format ("{0} - Mobile - We did not see our expected item in the build output: {1}", testName, libraryName)); string xm45BundlePath = Path.Combine (tmpDir, "bin/Debug/XM45Example.app/Contents/MonoBundle/"); if (libraryName != null) @@ -112,7 +112,7 @@ namespace Xamarin.MMP.Tests MMPTests.RunMMPTest (tmpDir => { TI.UnifiedTestConfig test = new TI.UnifiedTestConfig (tmpDir) { ItemGroup = CreateSingleNativeRef (SimpleStaticPath, "Static") }; NativeReferenceTestCore (tmpDir, test, "Unified_WithNativeReferences_InMainProjectWorks - Static", null, true, false, s => { - var clangLines = s.Split ('\n').Where (x => x.Contains ("usr/bin/clang")); + var clangLines = s.BuildOutputLines.Where (x => x.Contains ("usr/bin/clang")); var staticLib = clangLines.Where (x => x.Contains ("SimpleClassStatic.a")); Assert.That (staticLib, Is.Not.Empty, "SimpleClassStatic.a:\n\t{0}", string.Join ("\n\t", clangLines)); return true; @@ -208,7 +208,7 @@ namespace Xamarin.MMP.Tests ItemGroup = CreateSingleNativeRef ("/Library/Frameworks/Mono.framework/Libraries/libintl.dylib", "Dynamic") }; var log = TI.TestUnifiedExecutable (test); - Console.WriteLine (log.BuildOutput); + Console.WriteLine (log.BuildResult); Assert.True (File.Exists (Path.Combine (tmpDir, "bin/Debug/XM45Example.app/Contents/MonoBundle/libintl.dylib"))); }); } diff --git a/tests/mmptest/src/PackageReferenceTests.cs b/tests/mmptest/src/PackageReferenceTests.cs index 20e9de4ab2..e0681eef3a 100644 --- a/tests/mmptest/src/PackageReferenceTests.cs +++ b/tests/mmptest/src/PackageReferenceTests.cs @@ -66,8 +66,8 @@ namespace Xamarin.MMP.Tests TI.CopyFileWithSubstitutions (main, main, s => s.Replace ("%TESTCODE%", TestCode)); TI.NugetRestore (project); - string output = TI.BuildProject (Path.Combine (tmpDir, "Today/TodayExtensionTest.csproj")); - Assert.IsTrue (!output.Contains ("MM2013")); + var buildResult = TI.BuildProject (Path.Combine (tmpDir, "Today/TodayExtensionTest.csproj")); + buildResult.Messages.AssertNoMessage (2013); }); } } diff --git a/tests/mmptest/src/TargetFrameworkMutateTests.cs b/tests/mmptest/src/TargetFrameworkMutateTests.cs index 74912a241e..79de09ec31 100644 --- a/tests/mmptest/src/TargetFrameworkMutateTests.cs +++ b/tests/mmptest/src/TargetFrameworkMutateTests.cs @@ -10,9 +10,9 @@ namespace Xamarin.MMP.Tests { const string MigrateCSProjTag = "true"; - public bool MatchesTFI (string expected, string buildOutput) + public bool MatchesTFI (string expected, BuildResult buildOutput) { - string tfiLine = buildOutput.SplitLines ().FirstOrDefault (x => x.StartsWith ("TargetFrameworkIdentifier =", StringComparison.Ordinal)); + var tfiLine = buildOutput.BuildOutputLines.FirstOrDefault (x => x.StartsWith ("TargetFrameworkIdentifier =", StringComparison.Ordinal)); if (tfiLine == null) return false; return tfiLine.Contains (expected); @@ -26,9 +26,9 @@ namespace Xamarin.MMP.Tests TI.UnifiedTestConfig test = new TI.UnifiedTestConfig (tmpDir) { XM45 = xm45 }; - var buildOutput = TI.TestUnifiedExecutable (test).BuildOutput; + var buildOutput = TI.TestUnifiedExecutable (test).BuildResult; string standardTFI = xm45 ? ".NETFramework" : "Xamarin.Mac"; - Assert.True (MatchesTFI (standardTFI, buildOutput), $"Build did not have expected TFI: {TI.PrintRedirectIfLong (buildOutput)}"); + Assert.True (MatchesTFI (standardTFI, buildOutput), $"Build did not have expected TFI."); }); } @@ -37,8 +37,8 @@ namespace Xamarin.MMP.Tests { MMPTests.RunMMPTest (tmpDir => { TI.UnifiedTestConfig test = new TI.UnifiedTestConfig (tmpDir) { CSProjConfig = MigrateCSProjTag }; - var buildOutput = TI.TestUnifiedExecutable (test).BuildOutput; - Assert.True (MatchesTFI ("Xamarin.Mac", buildOutput), $"Build did not have expected TFI: {TI.PrintRedirectIfLong (buildOutput)}"); + var buildOutput = TI.TestUnifiedExecutable (test).BuildResult; + Assert.True (MatchesTFI ("Xamarin.Mac", buildOutput), $"Build did not have expected TFI."); }); } @@ -50,8 +50,8 @@ namespace Xamarin.MMP.Tests XM45 = true, CSProjConfig = MigrateCSProjTag }; - var buildOutput = TI.TestUnifiedExecutable (test).BuildOutput; - Assert.True (MatchesTFI ("Xamarin.Mac.NET", buildOutput), $"Build did not have expected TFI: {TI.PrintRedirectIfLong (buildOutput)}"); + var buildOutput = TI.TestUnifiedExecutable (test).BuildResult; + Assert.True (MatchesTFI ("Xamarin.Mac.NET", buildOutput), $"Build did not have expected TFI."); }); } } diff --git a/tests/msbuild-mac/CustomBuildActions.targets b/tests/msbuild-mac/CustomBuildActions.targets deleted file mode 100644 index d75ccf330c..0000000000 --- a/tests/msbuild-mac/CustomBuildActions.targets +++ /dev/null @@ -1,11 +0,0 @@ - - - - - $(BuildDependsOn);CreateNativeLibs - - - - - - diff --git a/tests/msbuild-mac/msbuild-mac.csproj b/tests/msbuild-mac/msbuild-mac.csproj deleted file mode 100644 index a3e1558235..0000000000 --- a/tests/msbuild-mac/msbuild-mac.csproj +++ /dev/null @@ -1,85 +0,0 @@ - - - - - Debug - x86 - 8.0.30703 - 2.0 - {F8500DCE-2119-4DF9-8360-0F46DDB6930C} - Library - msbuildMac - msbuild-mac - v4.7.2 - latest - - - true - full - false - bin\Debug - DEBUG;MONOMAC - prompt - 4 - - - true - bin\Release - MONOMAC;MMP_TEST - prompt - 4 - - - - - - - - - - - - - - - ProjectTestHelpers.cs - - - Configuration.cs - - - ErrorHelper.cs - - - RuntimeException.cs - - - - - StringUtils.cs - - - ExecutionHelper.cs - - - Profile.cs - - - Driver.execution.cs - - - Execution.cs - - - Cache.cs - - - TargetFramework.cs - - - ApplePlatform.cs - - - - - diff --git a/tests/msbuild-mac/src/MSBuild-Smoke.cs b/tests/msbuild/Xamarin.MacDev.Tests/MSBuild-Smoke.cs similarity index 69% rename from tests/msbuild-mac/src/MSBuild-Smoke.cs rename to tests/msbuild/Xamarin.MacDev.Tests/MSBuild-Smoke.cs index 5b0b5ca6f0..ffdde04db0 100644 --- a/tests/msbuild-mac/src/MSBuild-Smoke.cs +++ b/tests/msbuild/Xamarin.MacDev.Tests/MSBuild-Smoke.cs @@ -40,8 +40,8 @@ namespace Xamarin.MMP.Tests void TestBCLCore (string tmpDir, string projectName) { - File.Copy (Path.Combine (TI.AssemblyDirectory, TI.TestDirectory + "common/mac/System.Collections.Immutable.dll"), Path.Combine (tmpDir, "System.Collections.Immutable.dll")); - string reference = "System.Collections.Immutable.dll"; + var dll = Path.GetFullPath (Path.Combine (TI.TestDirectory + "common", "mac", "System.Collections.Immutable.dll")); + string reference = $"{dll}"; string testCode = "var v = System.Collections.Immutable.ImmutableArray.CreateRange (new int [] { 42 });"; string projectPath = TI.GenerateEXEProject (new TI.UnifiedTestConfig (tmpDir) { ProjectName = projectName, References = reference, TestCode = testCode }); TI.BuildProject (projectPath); @@ -121,68 +121,63 @@ namespace Xamarin.MMP.Tests public void BuildUnifiedProject_WithJustNativeRefNoLinkWith_Builds() { RunMSBuildTest (tmpDir => { - string dylibPath = Path.Combine (tmpDir, "dll/"); - Directory.CreateDirectory (dylibPath); - File.Copy (Path.Combine (TI.AssemblyDirectory, TI.TestDirectory + "mac-binding-project/bin/SimpleClassDylib.dylib"), Path.Combine (dylibPath, "SimpleClassDylib.dylib")); - string itemGroup = " FalseDynamic "; + var dylib = Path.GetFullPath (Path.Combine (TI.TestDirectory, "test-libraries", ".libs", "macos", "libtest.dylib")); + string itemGroup = $" FalseDynamic "; string projectPath = TI.GenerateEXEProject (new TI.UnifiedTestConfig (tmpDir) { ProjectName = "UnifiedExample.csproj", ItemGroup = itemGroup }); - string buildResults = TI.BuildProject (projectPath); - Assert.IsFalse (buildResults.Contains ("MM2006"), "BuildUnifiedProject_WittJustNativeRefNoLinkWith_Builds found 2006 warning: " + buildResults); - Assert.IsTrue (File.Exists (Path.Combine (tmpDir, "bin/Debug/UnifiedExample.app/Contents/MonoBundle/SimpleClassDylib.dylib"))); + var testResults = TI.BuildProject (projectPath); + testResults.Messages.AssertNoMessage (2006); + Assert.That (Path.Combine (tmpDir, $"bin", "Debug", "UnifiedExample.app", "Contents", "MonoBundle", Path.GetFileName (dylib)), Does.Exist, "dylib in app"); - StringBuilder output = new StringBuilder (); - Xamarin.Bundler.Driver.RunCommand ("/usr/bin/otool", new [] { "-L", Path.Combine (tmpDir, "bin/Debug/UnifiedExample.app/Contents/MacOS/UnifiedExample") }, output); - Assert.IsTrue (output.ToString ().Contains ("SimpleClassDylib.dylib")); + Assert.AreEqual (0, ExecutionHelper.Execute ("/usr/bin/otool", new [] { "-L", Path.Combine (tmpDir, "bin/Debug/UnifiedExample.app/Contents/MacOS/UnifiedExample") }, out var output)); + Assert.IsTrue (output.ToString ().Contains (Path.GetFileName (dylib))); }); } [Test] - public void Build_BindingLibrary_SmokeTest () + [TestCase ("XM45Binding.csproj")] + [TestCase ("MobileBinding.csproj")] + [TestCase ("BindingProjectWithNoTag.csproj")] + public void Build_BindingLibrary_SmokeTest (string projectName) { RunMSBuildTest (tmpDir => { - foreach (string projectName in new []{"XM45Binding.csproj", "MobileBinding.csproj", "BindingProjectWithNoTag.csproj"}) { - TI.UnifiedTestConfig test = new TI.UnifiedTestConfig (tmpDir) { ProjectName = projectName }; - string projectPath = TI.GenerateBindingLibraryProject (test); - TI.BuildProject (projectPath); - } + TI.UnifiedTestConfig test = new TI.UnifiedTestConfig (tmpDir) { ProjectName = projectName }; + string projectPath = TI.GenerateBindingLibraryProject (test); + TI.BuildProject (projectPath); }); } [Test] - public void BuildingSameBindingProject_TwoTimes_ShallNotInvokeMMPTwoTimes () + [TestCase ("XM45Binding.csproj")] + [TestCase ("MobileBinding.csproj")] + [TestCase ("BindingProjectWithNoTag.csproj")] + public void BuildingSameBindingProject_TwoTimes_ShallNotInvokeMMPTwoTimes (string project) { const string nativeRefItemGroup = "DynamicFalse"; - RunMSBuildTest (tmpDir => - { - foreach (string project in new[] { "XM45Binding.csproj", "MobileBinding.csproj", "BindingProjectWithNoTag.csproj" }) - { - var config = new TI.UnifiedTestConfig (tmpDir) { ProjectName = project, ItemGroup = nativeRefItemGroup }; - string projectPath = TI.GenerateBindingLibraryProject (config); - string buildOutput = TI.BuildProject (projectPath); - Assert.IsTrue (buildOutput.Contains (@"Building target ""CoreCompile""")); + RunMSBuildTest (tmpDir => { + var config = new TI.UnifiedTestConfig (tmpDir) { ProjectName = project, ItemGroup = nativeRefItemGroup }; + string projectPath = TI.GenerateBindingLibraryProject (config); + string buildOutput = TI.BuildProject (projectPath).BuildOutput; + Assert.IsTrue (buildOutput.Contains (@"Building target ""CoreCompile""")); - string secondBuildOutput = TI.BuildProject (projectPath); - Assert.IsFalse (secondBuildOutput.Contains (@"Building target ""CoreCompile""")); - } + string secondBuildOutput = TI.BuildProject (projectPath).BuildOutput; + Assert.IsFalse (secondBuildOutput.Contains (@"Building target ""CoreCompile""")); }); } [Test] - public void BuildingSameProject_TwoTimes_ShallNotInvokeMMPTwoTimes () + [TestCase ("UnifiedExample.csproj")] + [TestCase ("XM45Example.csproj")] + public void BuildingSameProject_TwoTimes_ShallNotInvokeMMPTwoTimes (string project) { - RunMSBuildTest (tmpDir => - { - foreach (var project in new string[] { "UnifiedExample.csproj", "XM45Example.csproj" }) - { - var config = new TI.UnifiedTestConfig (tmpDir) { ProjectName = project }; - string projectPath = TI.GenerateEXEProject (config); - string buildOutput = TI.BuildProject (projectPath); - Assert.IsTrue (buildOutput.Contains (@"Building target ""_CompileToNative""")); + RunMSBuildTest (tmpDir => { + var config = new TI.UnifiedTestConfig (tmpDir) { ProjectName = project }; + string projectPath = TI.GenerateEXEProject (config); + string buildOutput = TI.BuildProject (projectPath).BuildOutput; + Assert.IsTrue (buildOutput.Contains (@"Building target ""_CompileToNative""")); - string secondBuildOutput = TI.BuildProject (projectPath); - Assert.IsFalse (secondBuildOutput.Contains (@"Building target ""_CompileToNative""")); - } + string secondBuildOutput = TI.BuildProject (projectPath).BuildOutput; + Assert.IsFalse (secondBuildOutput.Contains (@"Building target ""_CompileToNative""")); }); } diff --git a/tests/msbuild-mac/src/RoslynSmokeTests.cs b/tests/msbuild/Xamarin.MacDev.Tests/RoslynSmokeTests.cs similarity index 100% rename from tests/msbuild-mac/src/RoslynSmokeTests.cs rename to tests/msbuild/Xamarin.MacDev.Tests/RoslynSmokeTests.cs diff --git a/tests/msbuild-mac/src/RuntimeTests.cs b/tests/msbuild/Xamarin.MacDev.Tests/RuntimeTests.cs similarity index 100% rename from tests/msbuild-mac/src/RuntimeTests.cs rename to tests/msbuild/Xamarin.MacDev.Tests/RuntimeTests.cs diff --git a/tests/msbuild/Xamarin.MacDev.Tests/TestHelpers/BuildEngine.cs b/tests/msbuild/Xamarin.MacDev.Tests/TestHelpers/BuildEngine.cs index d887370e2b..ab24a2cc72 100644 --- a/tests/msbuild/Xamarin.MacDev.Tests/TestHelpers/BuildEngine.cs +++ b/tests/msbuild/Xamarin.MacDev.Tests/TestHelpers/BuildEngine.cs @@ -122,20 +122,6 @@ namespace Xamarin.Tests { return props.LastOrDefault ()?.Value ?? string.Empty; } - public static void PrintBinLog (string path, StringBuilder sb) - { - var reader = new BinLogReader (); - foreach (var record in reader.ReadRecords (path)) { - if (record == null) - continue; - var args = record.Args; - if (args == null) - continue; - - sb.AppendLine (args.Message); - } - } - public void ParseBinLog (string log) { ErrorEvents.Clear (); diff --git a/tests/msbuild/Xamarin.MacDev.Tests/Xamarin.MacDev.Tests.csproj b/tests/msbuild/Xamarin.MacDev.Tests/Xamarin.MacDev.Tests.csproj index dcb182cc71..917b0150d0 100644 --- a/tests/msbuild/Xamarin.MacDev.Tests/Xamarin.MacDev.Tests.csproj +++ b/tests/msbuild/Xamarin.MacDev.Tests/Xamarin.MacDev.Tests.csproj @@ -47,6 +47,15 @@ external\Profile.cs + + external\ProjectTestHelpers.cs + + + external\BinLog.cs + + + external\Tool.cs + diff --git a/tests/mtouch/mtouch.csproj b/tests/mtouch/mtouch.csproj index f7079ab2e7..7c301a4d14 100644 --- a/tests/mtouch/mtouch.csproj +++ b/tests/mtouch/mtouch.csproj @@ -28,6 +28,7 @@ + @@ -115,6 +116,12 @@ tools\common\FileCopier.cs + + Tool.cs + + + BinLog.cs + diff --git a/tests/tests-mac.sln b/tests/tests-mac.sln index 5e595a2c52..d37abf4c49 100644 --- a/tests/tests-mac.sln +++ b/tests/tests-mac.sln @@ -3,8 +3,6 @@ Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 2012 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "mmptest", "mmptest\mmptest.csproj", "{6E5405EC-1F68-4CD8-AD4B-E4CCFBE47977}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "msbuild-mac", "msbuild-mac\msbuild-mac.csproj", "{F8500DCE-2119-4DF9-8360-0F46DDB6930C}" -EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "xammac_tests", "xammac_tests\xammac_tests.csproj", "{22BF080C-AFAD-445B-8BB5-42B9E7FDBC68}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "dont link-mac", "linker\mac\dont link\dont link-mac.csproj", "{78831857-A261-8EE0-A5F6-33D2628DE5D0}" @@ -43,14 +41,6 @@ Global {6E5405EC-1F68-4CD8-AD4B-E4CCFBE47977}.Debug|x86.Build.0 = Debug|x86 {6E5405EC-1F68-4CD8-AD4B-E4CCFBE47977}.Release|x86.ActiveCfg = Release|x86 {6E5405EC-1F68-4CD8-AD4B-E4CCFBE47977}.Release|x86.Build.0 = Release|x86 - {F8500DCE-2119-4DF9-8360-0F46DDB6930C}.Debug|Any CPU.ActiveCfg = Debug|x86 - {F8500DCE-2119-4DF9-8360-0F46DDB6930C}.Debug|Any CPU.Build.0 = Debug|x86 - {F8500DCE-2119-4DF9-8360-0F46DDB6930C}.Release|Any CPU.ActiveCfg = Release|x86 - {F8500DCE-2119-4DF9-8360-0F46DDB6930C}.Release|Any CPU.Build.0 = Release|x86 - {F8500DCE-2119-4DF9-8360-0F46DDB6930C}.Debug|x86.ActiveCfg = Debug|x86 - {F8500DCE-2119-4DF9-8360-0F46DDB6930C}.Debug|x86.Build.0 = Debug|x86 - {F8500DCE-2119-4DF9-8360-0F46DDB6930C}.Release|x86.ActiveCfg = Release|x86 - {F8500DCE-2119-4DF9-8360-0F46DDB6930C}.Release|x86.Build.0 = Release|x86 {22BF080C-AFAD-445B-8BB5-42B9E7FDBC68}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {22BF080C-AFAD-445B-8BB5-42B9E7FDBC68}.Debug|Any CPU.Build.0 = Debug|Any CPU {22BF080C-AFAD-445B-8BB5-42B9E7FDBC68}.Release|Any CPU.ActiveCfg = Release|Any CPU diff --git a/tests/xammac_tests/xammac_tests.csproj b/tests/xammac_tests/xammac_tests.csproj index 57d0ed3bad..83308dbf94 100644 --- a/tests/xammac_tests/xammac_tests.csproj +++ b/tests/xammac_tests/xammac_tests.csproj @@ -97,9 +97,6 @@ EmbeddedResources\ResourcesTest.cs - - ProjectTestHelpers.cs - StringUtils.cs diff --git a/tests/xharness/Harness.cs b/tests/xharness/Harness.cs index 4f4fbf9c34..538ac3ae8f 100644 --- a/tests/xharness/Harness.cs +++ b/tests/xharness/Harness.cs @@ -276,7 +276,6 @@ namespace Xharness { var hard_coded_test_suites = new [] { new { Directory = "mmptest", ProjectFile = "mmptest", Name = "mmptest", IsNUnit = true, Configurations = (string[]) null, Platform = "x86", Flavors = MacFlavors.Console, }, - new { Directory = "msbuild-mac", ProjectFile = "msbuild-mac", Name = "MSBuild tests", IsNUnit = true, Configurations = (string[]) null, Platform = "x86", Flavors = MacFlavors.Console, }, new { Directory = "xammac_tests", ProjectFile = "xammac_tests", Name = "xammac tests", IsNUnit = false, Configurations = new string [] { "Debug", "Release" }, Platform = "AnyCPU", Flavors = MacFlavors.Modern, }, new { Directory = "linker/mac/link all", ProjectFile = "link all-mac", Name = "link all", IsNUnit = false, Configurations = new string [] { "Debug", "Release" }, Platform = "x86", Flavors = MacFlavors.Modern, }, new { Directory = "linker/mac/link sdk", ProjectFile = "link sdk-mac", Name = "link sdk", IsNUnit = false, Configurations = new string [] { "Debug", "Release" }, Platform = "x86", Flavors = MacFlavors.Modern, }, diff --git a/tests/xharness/Jenkins/Jenkins.cs b/tests/xharness/Jenkins/Jenkins.cs index 788c837457..51ded45033 100644 --- a/tests/xharness/Jenkins/Jenkins.cs +++ b/tests/xharness/Jenkins/Jenkins.cs @@ -45,7 +45,7 @@ namespace Xharness.Jenkins { public bool IncludetvOS = true; public bool IncludewatchOS = true; public bool IncludeMmpTest; - public bool IncludeiOSMSBuild = true; + public bool IncludeMSBuild = true; public bool IncludeMtouch; public bool IncludeBtouch; public bool IncludeMacBindingProject; diff --git a/tests/xharness/Jenkins/NUnitTestTasksEnumerable.cs b/tests/xharness/Jenkins/NUnitTestTasksEnumerable.cs index 32e67dc3ea..5961f4d6ed 100644 --- a/tests/xharness/Jenkins/NUnitTestTasksEnumerable.cs +++ b/tests/xharness/Jenkins/NUnitTestTasksEnumerable.cs @@ -34,9 +34,9 @@ namespace Xharness.Jenkins { ProjectConfiguration = "Debug", Platform = TestPlatform.iOS, TestName = "MSBuild tests", - Mode = "iOS (tasks)", + Mode = "Tasks", Timeout = TimeSpan.FromMinutes (60), - Ignored = !jenkins.IncludeiOSMSBuild, + Ignored = !jenkins.IncludeMSBuild, SupportsParallelExecution = false, }; yield return nunitExecutioniOSMSBuild; @@ -56,9 +56,9 @@ namespace Xharness.Jenkins { ProjectConfiguration = "Debug", Platform = TestPlatform.iOS, TestName = "MSBuild tests", - Mode = "iOS (integration)", + Mode = "Integration", Timeout = TimeSpan.FromMinutes (90), - Ignored = !jenkins.IncludeiOSMSBuild, + Ignored = !jenkins.IncludeMSBuild, SupportsParallelExecution = false, }; yield return nunitExecutioniOSMSBuildIntegration; diff --git a/tests/xharness/Jenkins/TestSelector.cs b/tests/xharness/Jenkins/TestSelector.cs index cc4b8a10b0..76198cf675 100644 --- a/tests/xharness/Jenkins/TestSelector.cs +++ b/tests/xharness/Jenkins/TestSelector.cs @@ -179,7 +179,7 @@ namespace Xharness.Jenkins { SetEnabled (files, xtroPrefixes, "xtro", ref jenkins.IncludeXtro); SetEnabled (files, cecilPrefixes, "cecil", ref jenkins.IncludeCecil); SetEnabled (files, dotnetFilenames, "dotnet", ref jenkins.IncludeDotNet); - SetEnabled (files, msbuildFilenames, "ios-msbuild", ref jenkins.IncludeiOSMSBuild); + SetEnabled (files, msbuildFilenames, "msbuild", ref jenkins.IncludeMSBuild); } void SelectTestsByLabel (int pullRequest) @@ -248,7 +248,7 @@ namespace Xharness.Jenkins { SetEnabled (labels, "tvos", ref jenkins.IncludetvOS); SetEnabled (labels, "watchos", ref jenkins.IncludewatchOS); SetEnabled (labels, "mac", ref jenkins.IncludeMac); - SetEnabled (labels, "ios-msbuild", ref jenkins.IncludeiOSMSBuild); + SetEnabled (labels, "msbuild", ref jenkins.IncludeMSBuild); SetEnabled (labels, "ios-simulator", ref jenkins.IncludeSimulator); SetEnabled (labels, "non-monotouch", ref jenkins.IncludeNonMonotouch); SetEnabled (labels, "monotouch", ref jenkins.IncludeMonotouch);