[tests] Merge the msbuild-mac tests into the Xamarin.MacDev.Tests project. (#10129)
This commit is contained in:
Родитель
4f75b9e8da
Коммит
9e20285ebb
|
@ -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
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
<PackageReference Include="NUnit3TestAdapter" Version="3.15.1" />
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.2.0" />
|
||||
<PackageReference Include="Mono.Cecil" Version="0.11.2" />
|
||||
<PackageReference Include="MSBuild.StructuredLogger" Version="2.1.176" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
@ -48,5 +49,11 @@
|
|||
<Compile Include="..\..\tools\common\StringUtils.cs">
|
||||
<Link>StringUtils.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\common\Tool.cs">
|
||||
<Link>Tool.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\common\BinLog.cs">
|
||||
<Link>BinLog.cs</Link>
|
||||
</Compile>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
|
|
@ -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<System.Collections.DictionaryEntry> ().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<BuildLogEvent> 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)
|
||||
{
|
||||
|
|
|
@ -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<string> output_lines;
|
||||
|
||||
List<ToolMessage> messages = new List<ToolMessage> ();
|
||||
|
||||
public Dictionary<string, string> 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<ToolMessage> Messages { get { return messages; } }
|
||||
public List<string> OutputLines {
|
||||
get {
|
||||
if (output_lines == null) {
|
||||
output_lines = new List<string> ();
|
||||
output_lines.AddRange (output.ToString ().Split ('\n'));
|
||||
}
|
||||
return output_lines;
|
||||
}
|
||||
}
|
||||
|
||||
public StringBuilder Output {
|
||||
get {
|
||||
return output;
|
||||
}
|
||||
}
|
||||
|
||||
public int Execute (IList<string> arguments)
|
||||
{
|
||||
return Execute (ToolPath, arguments, false);
|
||||
}
|
||||
|
||||
public int Execute (IList<string> arguments, bool always_show_output)
|
||||
{
|
||||
return Execute (ToolPath, arguments, always_show_output);
|
||||
}
|
||||
|
||||
public int Execute (string toolPath, IList<string> arguments)
|
||||
{
|
||||
return Execute (toolPath, arguments, false);
|
||||
}
|
||||
|
||||
public int Execute (string toolPath, IList<string> arguments, bool always_show_output)
|
||||
{
|
||||
output.Clear ();
|
||||
output_lines = null;
|
||||
|
||||
var args = new List<string> ();
|
||||
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<ToolMessage> ParseMessages (string [] lines, string messageToolName)
|
||||
{
|
||||
var messages = new List<ToolMessage> ();
|
||||
ParseMessages (messages, lines, messageToolName);
|
||||
return messages;
|
||||
}
|
||||
|
||||
public static void ParseMessages (List<ToolMessage> 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<ToolMessage> 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<ToolMessage> 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<ToolMessage> matches, string filename, int? linenumber)
|
||||
{
|
||||
AssertFilename (messages, prefix, number, message, matches, filename, linenumber);
|
||||
}
|
||||
|
||||
static void AssertFilename (IList<ToolMessage> messages, string prefix, int number, string message, IEnumerable<ToolMessage> 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<ToolMessage> 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<ToolMessage> 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<string> 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 {
|
||||
|
|
|
@ -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<string> output_lines;
|
||||
|
||||
List<ToolMessage> messages = new List<ToolMessage> ();
|
||||
|
||||
public Dictionary<string, string> 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<ToolMessage> Messages { get { return messages; } }
|
||||
public List<string> OutputLines {
|
||||
get {
|
||||
if (output_lines == null) {
|
||||
output_lines = new List<string> ();
|
||||
output_lines.AddRange (output.ToString ().Split ('\n'));
|
||||
}
|
||||
return output_lines;
|
||||
}
|
||||
}
|
||||
|
||||
public StringBuilder Output {
|
||||
get {
|
||||
return output;
|
||||
}
|
||||
}
|
||||
|
||||
public int Execute (IList<string> arguments)
|
||||
{
|
||||
return Execute (ToolPath, arguments, false);
|
||||
}
|
||||
|
||||
public int Execute (IList<string> arguments, bool always_show_output)
|
||||
{
|
||||
return Execute (ToolPath, arguments, always_show_output);
|
||||
}
|
||||
|
||||
public int Execute (string toolPath, IList<string> arguments)
|
||||
{
|
||||
return Execute (toolPath, arguments, false);
|
||||
}
|
||||
|
||||
public int Execute (string toolPath, IList<string> arguments, bool always_show_output)
|
||||
{
|
||||
output.Clear ();
|
||||
output_lines = null;
|
||||
|
||||
var args = new List<string> ();
|
||||
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<ToolMessage> ParseMessages (string [] lines, string messageToolName)
|
||||
{
|
||||
var messages = new List<ToolMessage> ();
|
||||
ParseMessages (messages, lines, messageToolName);
|
||||
return messages;
|
||||
}
|
||||
|
||||
public static void ParseMessages (List<ToolMessage> 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<ToolMessage> 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<ToolMessage> 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<ToolMessage> matches, string filename, int? linenumber)
|
||||
{
|
||||
AssertFilename (messages, prefix, number, message, matches, filename, linenumber);
|
||||
}
|
||||
|
||||
static void AssertFilename (IList<ToolMessage> messages, string prefix, int number, string message, IEnumerable<ToolMessage> 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<ToolMessage> 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<ToolMessage> 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<string> 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; } }
|
||||
}
|
||||
}
|
|
@ -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<string> 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<string, string> ();
|
||||
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<System.Collections.DictionaryEntry> ().OrderBy (v => v.Key))
|
||||
Console.WriteLine ($"export {kvp.Key}={StringUtils.Quote (kvp.Value.ToString ())}");
|
||||
Console.WriteLine ($"{exe} {StringUtils.FormatArguments (args)}");
|
||||
Console.WriteLine (output);
|
||||
}
|
||||
Func<string> 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<string, string> environment = null, IList<string> extraArgs = null)
|
||||
public static BuildResult BuildProject (string csprojTarget, bool shouldFail = false, bool release = false, Dictionary<string, string> environment = null, IList<string> 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<string> ();
|
||||
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<string, string> environment = null)
|
||||
public static BuildResult GenerateAndBuildUnifiedExecutable (UnifiedTestConfig config, bool shouldFail = false, Dictionary<string, string> 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<string, string > replacementAction)
|
||||
|
|
|
@ -33,6 +33,7 @@
|
|||
<PackageReference Include="NUnit" Version="3.12.0" />
|
||||
<PackageReference Include="NUnit.ConsoleRunner" Version="3.11.1" />
|
||||
<PackageReference Include="Mono.Cecil" Version="0.11.1" />
|
||||
<PackageReference Include="MSBuild.StructuredLogger" Version="2.1.176" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="ErrorTests.cs" />
|
||||
|
@ -55,6 +56,12 @@
|
|||
<Compile Include="..\common\Profile.cs">
|
||||
<Link>Profile.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\common\Tool.cs">
|
||||
<Link>Tool.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\common\BinLog.cs">
|
||||
<Link>BinLog.cs</Link>
|
||||
</Compile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="tests\is-direct-binding.cs" />
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
<RootNamespace>Xamarin.MMP.Tests</RootNamespace>
|
||||
<AssemblyName>mmptest</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
|
||||
<LangVersion>latest</LangVersion>
|
||||
<LangVersion>preview</LangVersion>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
|
@ -39,6 +39,9 @@
|
|||
<HintPath>..\..\_mac-build\Library\Frameworks\Xamarin.Mac.framework\Versions\git\lib\mmp\mmp.exe</HintPath>
|
||||
</Reference>
|
||||
<PackageReference Include="Mono.Cecil" Version="0.11.1" />
|
||||
<PackageReference Include="MSBuild.StructuredLogger">
|
||||
<Version>2.1.176</Version>
|
||||
</PackageReference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Folder Include="Resources\" />
|
||||
|
@ -114,6 +117,12 @@
|
|||
<Link>Errors.Designer.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="src\NativeExtensionEmbedding.cs" />
|
||||
<Compile Include="..\common\BinLog.cs">
|
||||
<Link>BinLog.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\common\Tool.cs">
|
||||
<Link>src\Tool.cs</Link>
|
||||
</Compile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="Info.plist" />
|
||||
|
|
|
@ -14,11 +14,11 @@ namespace Xamarin.MMP.Tests
|
|||
[TestFixture]
|
||||
public class AOTTests
|
||||
{
|
||||
void ValidateAOTStatus (string tmpDir, Func<FileInfo, bool> shouldAOT, string buildResults)
|
||||
void ValidateAOTStatus (string tmpDir, Func<FileInfo, bool> 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));
|
||||
});
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -22,9 +22,9 @@ namespace Xamarin.MMP.Tests
|
|||
{
|
||||
internal static string RemoveCSProj (string s) => s.Remove (s.IndexOf (".csproj", StringComparison.InvariantCulture));
|
||||
|
||||
internal static Tuple<string, string> 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<string, string> (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);
|
||||
|
|
|
@ -13,8 +13,15 @@ namespace Xamarin.MMP.Tests
|
|||
static Func<string, bool> LipoStripConditional = s => s.Contains ("lipo") && s.Contains ("-thin");
|
||||
static Func<string, bool> LipoStripSkipPosixAndMonoNativeConditional = s => LipoStripConditional (s) && !s.Contains ("libMonoPosixHelper.dylib") && !s.Contains ("libmono-native.dylib");
|
||||
|
||||
static Func<string, bool> DidAnyLipoStrip = output => output.SplitLines ().Any (LipoStripConditional);
|
||||
static Func<string, bool> 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
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -78,21 +78,18 @@ namespace Xamarin.MMP.Tests
|
|||
CSProjConfig = $"<MonoBundlingExtraArgs>--dynamic-symbol-mode={mode}</MonoBundlingExtraArgs>\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 = "<MonoBundlingExtraArgs>-v -v --linkplatform</MonoBundlingExtraArgs>" };
|
||||
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 = "<MonoBundlingExtraArgs>--registrar:partial --linkplatform</MonoBundlingExtraArgs>" };
|
||||
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.");
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 = "<MonoBundlingExtraArgs>--new-refcount=false</MonoBundlingExtraArgs>" };
|
||||
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 ("<MonoBundlingExtraArgs>--machine-config={0}</MonoBundlingExtraArgs>", 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 = "<DebugSymbols>true</DebugSymbols>";
|
||||
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 = "<DebugSymbols>true</DebugSymbols><MonoBundlingExtraArgs>--registrar=dynamic</MonoBundlingExtraArgs><XamMacArch>x86_64</XamMacArch>";
|
||||
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 = "<DebugSymbols>true</DebugSymbols><MonoBundlingExtraArgs>--registrar=partial</MonoBundlingExtraArgs><XamMacArch>x86_64</XamMacArch>";
|
||||
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 = "<EnableCodeSigning>true</EnableCodeSigning>"
|
||||
};
|
||||
|
||||
Func<OutputText, string> findCodesign = o => o.BuildOutput.SplitLines ().Last (x => x.Contains ("Tool /usr/bin/codesign execution started with arguments"));
|
||||
Func<OutputText, string> 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 = "<EnableCodeSigning>true</EnableCodeSigning>"
|
||||
};
|
||||
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 = "<MonoBundlingExtraArgs>-link_flags=-fobjc-arc</MonoBundlingExtraArgs>"
|
||||
};
|
||||
TI.TestUnifiedExecutable (test);
|
||||
var output = TI.BuildProject (Path.Combine (tmpDir, "UnifiedExample.csproj"));
|
||||
TI.BuildProject (Path.Combine (tmpDir, "UnifiedExample.csproj"));
|
||||
});
|
||||
|
||||
}
|
||||
|
|
|
@ -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<string, bool> processBuildOutput = null)
|
||||
void NativeReferenceTestCore (string tmpDir, TI.UnifiedTestConfig test, string testName, string libraryName, bool buildShouldBeSuccessful, bool libraryShouldNotBeCopied = false, Func<BuildResult, bool> 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")));
|
||||
});
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,9 +10,9 @@ namespace Xamarin.MMP.Tests
|
|||
{
|
||||
const string MigrateCSProjTag = "<MigrateToNewXMIdentifier>true</MigrateToNewXMIdentifier>";
|
||||
|
||||
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.");
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,11 +0,0 @@
|
|||
<!-- All msbuild target logic needs to be inside a project tag -->
|
||||
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
|
||||
<PropertyGroup>
|
||||
<BuildDependsOn>$(BuildDependsOn);CreateNativeLibs</BuildDependsOn>
|
||||
</PropertyGroup>
|
||||
|
||||
<Target Name="CreateNativeLibs" Inputs="$(MSBuildThisFileDirectory)/../common/mac/SimpleClass.m" Outputs="$(MSBuildThisFileDirectory)/../mac-binding-project/bin/SimpleClassDylib.dylib">
|
||||
<Exec Command="make bin/SimpleClassDylib.dylib" WorkingDirectory="$(MSBuildThisFileDirectory)/../mac-binding-project/" />
|
||||
</Target>
|
||||
</Project>
|
|
@ -1,85 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="..\..\packages\NUnit.3.11.0\build\NUnit.props" Condition="Exists('..\..\packages\NUnit.3.11.0\build\NUnit.props')" />
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">x86</Platform>
|
||||
<ProductVersion>8.0.30703</ProductVersion>
|
||||
<SchemaVersion>2.0</SchemaVersion>
|
||||
<ProjectGuid>{F8500DCE-2119-4DF9-8360-0F46DDB6930C}</ProjectGuid>
|
||||
<OutputType>Library</OutputType>
|
||||
<RootNamespace>msbuildMac</RootNamespace>
|
||||
<AssemblyName>msbuild-mac</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
|
||||
<LangVersion>latest</LangVersion>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>bin\Debug</OutputPath>
|
||||
<DefineConstants>DEBUG;MONOMAC</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>bin\Release</OutputPath>
|
||||
<DefineConstants>MONOMAC;MMP_TEST</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="System.Xml" />
|
||||
<PackageReference Include="NUnit" Version="3.12.0" />
|
||||
<PackageReference Include="NUnit.ConsoleRunner" Version="3.11.1" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Folder Include="Resources\" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="src\MSBuild-Smoke.cs" />
|
||||
<Compile Include="..\common\mac\ProjectTestHelpers.cs">
|
||||
<Link>ProjectTestHelpers.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\..\tests\common\Configuration.cs">
|
||||
<Link>Configuration.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\..\src\ObjCRuntime\ErrorHelper.cs">
|
||||
<Link>ErrorHelper.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\..\src\ObjCRuntime\RuntimeException.cs">
|
||||
<Link>RuntimeException.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="src\RoslynSmokeTests.cs" />
|
||||
<Compile Include="src\RuntimeTests.cs" />
|
||||
<Compile Include="..\..\tools\common\StringUtils.cs">
|
||||
<Link>StringUtils.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\common\ExecutionHelper.cs">
|
||||
<Link>ExecutionHelper.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\common\Profile.cs">
|
||||
<Link>Profile.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\..\tools\common\Driver.execution.cs">
|
||||
<Link>Driver.execution.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\..\tools\common\Execution.cs">
|
||||
<Link>Execution.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\mtouch\Cache.cs">
|
||||
<Link>Cache.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\..\tools\common\TargetFramework.cs">
|
||||
<Link>TargetFramework.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\..\tools\common\ApplePlatform.cs">
|
||||
<Link>ApplePlatform.cs</Link>
|
||||
</Compile>
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
|
||||
<Import Project="CustomBuildActions.targets" />
|
||||
</Project>
|
|
@ -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 = "<Reference Include=\"System.Collections.Immutable\"><HintPath>System.Collections.Immutable.dll</HintPath></Reference>";
|
||||
var dll = Path.GetFullPath (Path.Combine (TI.TestDirectory + "common", "mac", "System.Collections.Immutable.dll"));
|
||||
string reference = $"<Reference Include=\"System.Collections.Immutable\"><HintPath>{dll}</HintPath></Reference>";
|
||||
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 = "<ItemGroup><NativeReference Include=\".\\dll\\SimpleClassDylib.dylib\"> <IsCxx>False</IsCxx><Kind>Dynamic</Kind> </NativeReference> </ItemGroup>";
|
||||
var dylib = Path.GetFullPath (Path.Combine (TI.TestDirectory, "test-libraries", ".libs", "macos", "libtest.dylib"));
|
||||
string itemGroup = $"<ItemGroup><NativeReference Include=\"{dylib}\"> <IsCxx>False</IsCxx><Kind>Dynamic</Kind> </NativeReference> </ItemGroup>";
|
||||
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 = "<ItemGroup><NativeReference Include = \"\\usr\\lib\\libz.dylib\"><Kind>Dynamic</Kind><SmartLink>False</SmartLink></NativeReference></ItemGroup>";
|
||||
|
||||
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"""));
|
||||
});
|
||||
}
|
||||
|
|
@ -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 ();
|
||||
|
|
|
@ -47,6 +47,15 @@
|
|||
<Compile Include="..\..\common\Profile.cs">
|
||||
<Link>external\Profile.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\..\common\mac\ProjectTestHelpers.cs">
|
||||
<Link>external\ProjectTestHelpers.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\..\common\BinLog.cs">
|
||||
<Link>external\BinLog.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\..\common\Tool.cs">
|
||||
<Link>external\Tool.cs</Link>
|
||||
</Compile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\..\external\Xamarin.MacDev\Xamarin.MacDev\Xamarin.MacDev.csproj" />
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
<PackageReference Include="NUnit" Version="3.12.0" />
|
||||
<PackageReference Include="NUnit.ConsoleRunner" Version="3.11.1" />
|
||||
<PackageReference Include="Mono.Cecil" Version="0.11.1" />
|
||||
<PackageReference Include="MSBuild.StructuredLogger" Version="2.1.176" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="MTouch.cs" />
|
||||
|
@ -115,6 +116,12 @@
|
|||
<Compile Include="..\..\tools\common\FileCopier.cs">
|
||||
<Link>tools\common\FileCopier.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\common\Tool.cs">
|
||||
<Link>Tool.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\common\BinLog.cs">
|
||||
<Link>BinLog.cs</Link>
|
||||
</Compile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="..\..\tools\mtouch\Errors.resx">
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -97,9 +97,6 @@
|
|||
<Compile Include="..\EmbeddedResources\ResourcesTest.cs">
|
||||
<Link>EmbeddedResources\ResourcesTest.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\common\mac\ProjectTestHelpers.cs">
|
||||
<Link>ProjectTestHelpers.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\..\tools\common\StringUtils.cs">
|
||||
<Link>StringUtils.cs</Link>
|
||||
</Compile>
|
||||
|
|
|
@ -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, },
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
Загрузка…
Ссылка в новой задаче