xamarin-macios/tests/common/ExecutionHelper.cs

661 строка
25 KiB
C#
Исходник Обычный вид История

2016-05-26 16:06:52 +03:00
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using System.Diagnostics;
using NUnit.Framework;
using Xamarin.Utils;
2016-05-26 16:06:52 +03:00
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);
}
}
2016-05-26 16:06:52 +03:00
}
abstract class Tool
2016-05-26 16:06:52 +03:00
{
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
2016-05-26 16:06:52 +03:00
public IEnumerable<ToolMessage> Messages { get { return messages; } }
[registrar] Add support for specifying that a protocol changed informal status in a certain SDK. Fixes #43780 and #48311. (#2130) * [registrar] Add support for specifying that a protocol changed informal status in a certain SDK. Fixes #43780 Add support for specifying that an informal protocol became a formal protocol (or the reverse) in a certain SDK version, so that the static registrar can generate the correct code based on the SDK being built with. This also fixes a series of compiler warnings when using the static registrar: In file included from Xamarin.Mac.registrar.full.i386.m:1: ./Xamarin.Mac.registrar.full.i386.h:374:11: warning: duplicate protocol definition of 'CALayerDelegate' is ignored @protocol CALayerDelegate ^ /Applications/Xcode83.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.12.sdk/System/Library/Frameworks/QuartzCore.framework/Headers/CALayer.h:798:11: note: previous definition is here @protocol CALayerDelegate <NSObject> ^ In file included from Xamarin.Mac.registrar.full.i386.m:1: ./Xamarin.Mac.registrar.full.i386.h:824:11: warning: duplicate protocol definition of 'WebDownloadDelegate' is ignored @protocol WebDownloadDelegate ^ /Applications/Xcode83.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.12.sdk/System/Library/Frameworks/WebKit.framework/Headers/WebDownload.h:60:11: note: previous definition is here @protocol WebDownloadDelegate <NSURLDownloadDelegate> ^ In file included from Xamarin.Mac.registrar.full.i386.m:1: ./Xamarin.Mac.registrar.full.i386.h:851:11: warning: duplicate protocol definition of 'WebFrameLoadDelegate' is ignored @protocol WebFrameLoadDelegate ^ /Applications/Xcode83.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.12.sdk/System/Library/Frameworks/WebKit.framework/Headers/WebFrameLoadDelegate.h:51:11: note: previous definition is here @protocol WebFrameLoadDelegate <NSObject> ^ In file included from Xamarin.Mac.registrar.full.i386.m:1: ./Xamarin.Mac.registrar.full.i386.h:866:11: warning: duplicate protocol definition of 'WebPolicyDelegate' is ignored @protocol WebPolicyDelegate ^ /Applications/Xcode83.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.12.sdk/System/Library/Frameworks/WebKit.framework/Headers/WebPolicyDelegate.h:138:11: note: previous definition is here @protocol WebPolicyDelegate <NSObject> ^ In file included from Xamarin.Mac.registrar.full.i386.m:1: ./Xamarin.Mac.registrar.full.i386.h:869:11: warning: duplicate protocol definition of 'WebResourceLoadDelegate' is ignored @protocol WebResourceLoadDelegate ^ /Applications/Xcode83.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.12.sdk/System/Library/Frameworks/WebKit.framework/Headers/WebResourceLoadDelegate.h:46:11: note: previous definition is here @protocol WebResourceLoadDelegate <NSObject> ^ In file included from Xamarin.Mac.registrar.full.i386.m:1: ./Xamarin.Mac.registrar.full.i386.h:872:11: warning: duplicate protocol definition of 'WebUIDelegate' is ignored @protocol WebUIDelegate ^ /Applications/Xcode83.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.12.sdk/System/Library/Frameworks/WebKit.framework/Headers/WebUIDelegate.h:153:11: note: previous definition is here @protocol WebUIDelegate <NSObject> ^ https://bugzilla.xamarin.com/show_bug.cgi?id=43780 * [registrar] Use a string to specify when a protocol went from informal to formal. Use a string to specify when a protocol went from informal to formal, and don't support the reverse condition (going from formal to informal), since it's currently not needed and makes the code more complicated and harder to understand. Also add an mtouch test, and update an existing mmp test to be more restrictive. * [registrar] Rename from 'InformalUntil' to 'FormalSince'. It just sounds better.
2017-05-29 17:15:54 +03:00
public List<string> OutputLines {
2016-05-26 16:06:52 +03:00
get {
if (output_lines == null) {
output_lines = new List<string> ();
output_lines.AddRange (output.ToString ().Split ('\n'));
}
return output_lines;
}
}
[mtouch/mmp] Give users more control over optimizations, and share more code between mtouch and mmp. (#3242) * [mtouch/mmp] Give users more control over optimizations, and share more code between mtouch and mmp. 1. Add an --optimize flag to mtouch/mmp that allows users to select which optimizations to apply (or not). This makes it easier to add future optimizations, and allow users to disable any optimization that causes problems without having to disable many other features. 2. Share as much optimization code as possible between mtouch and mmp. This immediately gives a benefit to mmp, which has three new optimizations only mtouch had: NSObject.IsDirectBinding inlining, IntPtr.Size inlining and dead code elimination. This results in ~6kb of disk space saved for a linked Xamarin.Mac app: * link sdk: [Debug][1], [Release][2] * link all: [Debug][3], [Release][4] Testing also verifies that monotouchtest ([Debug][5], [Release][6]) has not changed size at all, which means that no default optimizations have changed inadvertedly. [1]: https://gist.github.com/rolfbjarne/6b731e3b5ca6170355662e6505c3d492#link-sdk-mac--debug [2]: https://gist.github.com/rolfbjarne/6b731e3b5ca6170355662e6505c3d492#link-sdk-mac--release [3]: https://gist.github.com/rolfbjarne/6b731e3b5ca6170355662e6505c3d492#link-all-mac--debug [4]: https://gist.github.com/rolfbjarne/6b731e3b5ca6170355662e6505c3d492#link-all-mac--release [5]: https://gist.github.com/rolfbjarne/6b731e3b5ca6170355662e6505c3d492#monotouchtest-iphonedebug64 [6]: https://gist.github.com/rolfbjarne/6b731e3b5ca6170355662e6505c3d492#monotouchtest-iphonerelease64 * [tools] Don't enable the IsDirectBinding optimization by default for Xamarin.Mac apps, it's not safe. * Fix whitespace issues. * [doc] Document optimizations. * Officially support optimizations by adding them to the Versions.plist. * [linker] Improve IntPtr.Size inliner + dead code eliminatior and add tests. * Properly handle operands for the ldc_i4_s instruction (they're sbyte). * Fix less-than condition to actually do a less-than comparison. * Make sure to look up the bitness in the Target, not the Application, since the Application's value will be incorrect when building fat apps (both Is32Build and Is64Build will be true). * Remove unnecessary checks for the IntPtr.Size inliner: this optimization does not depend on other instructions than the IntPtr.get_Size call, so remove the checks that verify surrounding instructions. This makes the IntPtr.Size inliner kick in in more scenarios (such as the new tests). * Add tests. * [tests] Add mmp tests for optimizations. * [tests] Fix XM optimization tests. * [tests] Fix test build error.
2018-01-23 13:33:48 +03:00
public StringBuilder Output {
get {
return output;
}
}
2016-05-26 16:06:52 +03:00
public int Execute (string arguments, params string [] args)
{
return Execute (ToolPath, arguments, false, args);
}
public int Execute (string arguments, bool always_show_output, params string [] args)
{
return Execute (ToolPath, arguments, always_show_output, args);
}
public int Execute (string toolPath, string arguments, params string [] args)
{
return Execute (toolPath, arguments, false, args);
}
public int Execute (string toolPath, string arguments, bool always_show_output, params string [] args)
2016-05-26 16:06:52 +03:00
{
output.Clear ();
output_lines = null;
var rv = ExecutionHelper.Execute (Configuration.XIBuildPath, $"-t -- {toolPath} " + string.Format (arguments, args), EnvironmentVariables, output, output, workingDirectory: WorkingDirectory);
2016-05-26 16:06:52 +03:00
if ((rv != 0 || always_show_output) && output.Length > 0)
Console.WriteLine ("\t" + output.ToString ().Replace ("\n", "\n\t"));
2016-05-26 16:06:52 +03:00
ParseMessages ();
return rv;
}
static bool IndexOfAny (string line, out int start, out int end, params string [] values)
[mtouch/mmp] Give users more control over optimizations, and share more code between mtouch and mmp. (#3242) * [mtouch/mmp] Give users more control over optimizations, and share more code between mtouch and mmp. 1. Add an --optimize flag to mtouch/mmp that allows users to select which optimizations to apply (or not). This makes it easier to add future optimizations, and allow users to disable any optimization that causes problems without having to disable many other features. 2. Share as much optimization code as possible between mtouch and mmp. This immediately gives a benefit to mmp, which has three new optimizations only mtouch had: NSObject.IsDirectBinding inlining, IntPtr.Size inlining and dead code elimination. This results in ~6kb of disk space saved for a linked Xamarin.Mac app: * link sdk: [Debug][1], [Release][2] * link all: [Debug][3], [Release][4] Testing also verifies that monotouchtest ([Debug][5], [Release][6]) has not changed size at all, which means that no default optimizations have changed inadvertedly. [1]: https://gist.github.com/rolfbjarne/6b731e3b5ca6170355662e6505c3d492#link-sdk-mac--debug [2]: https://gist.github.com/rolfbjarne/6b731e3b5ca6170355662e6505c3d492#link-sdk-mac--release [3]: https://gist.github.com/rolfbjarne/6b731e3b5ca6170355662e6505c3d492#link-all-mac--debug [4]: https://gist.github.com/rolfbjarne/6b731e3b5ca6170355662e6505c3d492#link-all-mac--release [5]: https://gist.github.com/rolfbjarne/6b731e3b5ca6170355662e6505c3d492#monotouchtest-iphonedebug64 [6]: https://gist.github.com/rolfbjarne/6b731e3b5ca6170355662e6505c3d492#monotouchtest-iphonerelease64 * [tools] Don't enable the IsDirectBinding optimization by default for Xamarin.Mac apps, it's not safe. * Fix whitespace issues. * [doc] Document optimizations. * Officially support optimizations by adding them to the Versions.plist. * [linker] Improve IntPtr.Size inliner + dead code eliminatior and add tests. * Properly handle operands for the ldc_i4_s instruction (they're sbyte). * Fix less-than condition to actually do a less-than comparison. * Make sure to look up the bitness in the Target, not the Application, since the Application's value will be incorrect when building fat apps (both Is32Build and Is64Build will be true). * Remove unnecessary checks for the IntPtr.Size inliner: this optimization does not depend on other instructions than the IntPtr.get_Size call, so remove the checks that verify surrounding instructions. This makes the IntPtr.Size inliner kick in in more scenarios (such as the new tests). * Add tests. * [tests] Add mmp tests for optimizations. * [tests] Fix XM optimization tests. * [tests] Fix test build error.
2018-01-23 13:33:48 +03:00
{
foreach (var value in values) {
start = line.IndexOf (value, StringComparison.Ordinal);
[mtouch/mmp] Give users more control over optimizations, and share more code between mtouch and mmp. (#3242) * [mtouch/mmp] Give users more control over optimizations, and share more code between mtouch and mmp. 1. Add an --optimize flag to mtouch/mmp that allows users to select which optimizations to apply (or not). This makes it easier to add future optimizations, and allow users to disable any optimization that causes problems without having to disable many other features. 2. Share as much optimization code as possible between mtouch and mmp. This immediately gives a benefit to mmp, which has three new optimizations only mtouch had: NSObject.IsDirectBinding inlining, IntPtr.Size inlining and dead code elimination. This results in ~6kb of disk space saved for a linked Xamarin.Mac app: * link sdk: [Debug][1], [Release][2] * link all: [Debug][3], [Release][4] Testing also verifies that monotouchtest ([Debug][5], [Release][6]) has not changed size at all, which means that no default optimizations have changed inadvertedly. [1]: https://gist.github.com/rolfbjarne/6b731e3b5ca6170355662e6505c3d492#link-sdk-mac--debug [2]: https://gist.github.com/rolfbjarne/6b731e3b5ca6170355662e6505c3d492#link-sdk-mac--release [3]: https://gist.github.com/rolfbjarne/6b731e3b5ca6170355662e6505c3d492#link-all-mac--debug [4]: https://gist.github.com/rolfbjarne/6b731e3b5ca6170355662e6505c3d492#link-all-mac--release [5]: https://gist.github.com/rolfbjarne/6b731e3b5ca6170355662e6505c3d492#monotouchtest-iphonedebug64 [6]: https://gist.github.com/rolfbjarne/6b731e3b5ca6170355662e6505c3d492#monotouchtest-iphonerelease64 * [tools] Don't enable the IsDirectBinding optimization by default for Xamarin.Mac apps, it's not safe. * Fix whitespace issues. * [doc] Document optimizations. * Officially support optimizations by adding them to the Versions.plist. * [linker] Improve IntPtr.Size inliner + dead code eliminatior and add tests. * Properly handle operands for the ldc_i4_s instruction (they're sbyte). * Fix less-than condition to actually do a less-than comparison. * Make sure to look up the bitness in the Target, not the Application, since the Application's value will be incorrect when building fat apps (both Is32Build and Is64Build will be true). * Remove unnecessary checks for the IntPtr.Size inliner: this optimization does not depend on other instructions than the IntPtr.get_Size call, so remove the checks that verify surrounding instructions. This makes the IntPtr.Size inliner kick in in more scenarios (such as the new tests). * Add tests. * [tests] Add mmp tests for optimizations. * [tests] Fix XM optimization tests. * [tests] Fix test build error.
2018-01-23 13:33:48 +03:00
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)
2016-05-26 16:06:52 +03:00
{
var messages = new List<ToolMessage> ();
ParseMessages (messages, lines, messageToolName);
return messages;
}
2016-05-26 16:06:52 +03:00
public static void ParseMessages (List<ToolMessage> messages, string [] lines, string messageToolName)
{
foreach (var l in lines) {
2016-05-26 16:06:52 +03:00
var line = l;
var msg = new ToolMessage ();
var origin = string.Empty;
// FIXME: remove this warning check once WatchKit is back with us again.
if (l.Contains ("warning MT0099: Not linking with WatchKit because Xcode 11 beta 1 does not ship with the WatchKit framework")) {
// Ignore this line since it's confusing all our tests that asserts the exact number of warnings we get.
continue;
}
[mtouch/mmp] Give users more control over optimizations, and share more code between mtouch and mmp. (#3242) * [mtouch/mmp] Give users more control over optimizations, and share more code between mtouch and mmp. 1. Add an --optimize flag to mtouch/mmp that allows users to select which optimizations to apply (or not). This makes it easier to add future optimizations, and allow users to disable any optimization that causes problems without having to disable many other features. 2. Share as much optimization code as possible between mtouch and mmp. This immediately gives a benefit to mmp, which has three new optimizations only mtouch had: NSObject.IsDirectBinding inlining, IntPtr.Size inlining and dead code elimination. This results in ~6kb of disk space saved for a linked Xamarin.Mac app: * link sdk: [Debug][1], [Release][2] * link all: [Debug][3], [Release][4] Testing also verifies that monotouchtest ([Debug][5], [Release][6]) has not changed size at all, which means that no default optimizations have changed inadvertedly. [1]: https://gist.github.com/rolfbjarne/6b731e3b5ca6170355662e6505c3d492#link-sdk-mac--debug [2]: https://gist.github.com/rolfbjarne/6b731e3b5ca6170355662e6505c3d492#link-sdk-mac--release [3]: https://gist.github.com/rolfbjarne/6b731e3b5ca6170355662e6505c3d492#link-all-mac--debug [4]: https://gist.github.com/rolfbjarne/6b731e3b5ca6170355662e6505c3d492#link-all-mac--release [5]: https://gist.github.com/rolfbjarne/6b731e3b5ca6170355662e6505c3d492#monotouchtest-iphonedebug64 [6]: https://gist.github.com/rolfbjarne/6b731e3b5ca6170355662e6505c3d492#monotouchtest-iphonerelease64 * [tools] Don't enable the IsDirectBinding optimization by default for Xamarin.Mac apps, it's not safe. * Fix whitespace issues. * [doc] Document optimizations. * Officially support optimizations by adding them to the Versions.plist. * [linker] Improve IntPtr.Size inliner + dead code eliminatior and add tests. * Properly handle operands for the ldc_i4_s instruction (they're sbyte). * Fix less-than condition to actually do a less-than comparison. * Make sure to look up the bitness in the Target, not the Application, since the Application's value will be incorrect when building fat apps (both Is32Build and Is64Build will be true). * Remove unnecessary checks for the IntPtr.Size inliner: this optimization does not depend on other instructions than the IntPtr.get_Size call, so remove the checks that verify surrounding instructions. This makes the IntPtr.Size inliner kick in in more scenarios (such as the new tests). * Add tests. * [tests] Add mmp tests for optimizations. * [tests] Fix XM optimization tests. * [tests] Fix test build error.
2018-01-23 13:33:48 +03:00
if (IndexOfAny (line, out var idxError, out var endError, ": error ", ": error ")) {
msg.IsError = true;
[mtouch/mmp] Give users more control over optimizations, and share more code between mtouch and mmp. (#3242) * [mtouch/mmp] Give users more control over optimizations, and share more code between mtouch and mmp. 1. Add an --optimize flag to mtouch/mmp that allows users to select which optimizations to apply (or not). This makes it easier to add future optimizations, and allow users to disable any optimization that causes problems without having to disable many other features. 2. Share as much optimization code as possible between mtouch and mmp. This immediately gives a benefit to mmp, which has three new optimizations only mtouch had: NSObject.IsDirectBinding inlining, IntPtr.Size inlining and dead code elimination. This results in ~6kb of disk space saved for a linked Xamarin.Mac app: * link sdk: [Debug][1], [Release][2] * link all: [Debug][3], [Release][4] Testing also verifies that monotouchtest ([Debug][5], [Release][6]) has not changed size at all, which means that no default optimizations have changed inadvertedly. [1]: https://gist.github.com/rolfbjarne/6b731e3b5ca6170355662e6505c3d492#link-sdk-mac--debug [2]: https://gist.github.com/rolfbjarne/6b731e3b5ca6170355662e6505c3d492#link-sdk-mac--release [3]: https://gist.github.com/rolfbjarne/6b731e3b5ca6170355662e6505c3d492#link-all-mac--debug [4]: https://gist.github.com/rolfbjarne/6b731e3b5ca6170355662e6505c3d492#link-all-mac--release [5]: https://gist.github.com/rolfbjarne/6b731e3b5ca6170355662e6505c3d492#monotouchtest-iphonedebug64 [6]: https://gist.github.com/rolfbjarne/6b731e3b5ca6170355662e6505c3d492#monotouchtest-iphonerelease64 * [tools] Don't enable the IsDirectBinding optimization by default for Xamarin.Mac apps, it's not safe. * Fix whitespace issues. * [doc] Document optimizations. * Officially support optimizations by adding them to the Versions.plist. * [linker] Improve IntPtr.Size inliner + dead code eliminatior and add tests. * Properly handle operands for the ldc_i4_s instruction (they're sbyte). * Fix less-than condition to actually do a less-than comparison. * Make sure to look up the bitness in the Target, not the Application, since the Application's value will be incorrect when building fat apps (both Is32Build and Is64Build will be true). * Remove unnecessary checks for the IntPtr.Size inliner: this optimization does not depend on other instructions than the IntPtr.get_Size call, so remove the checks that verify surrounding instructions. This makes the IntPtr.Size inliner kick in in more scenarios (such as the new tests). * Add tests. * [tests] Add mmp tests for optimizations. * [tests] Fix XM optimization tests. * [tests] Fix test build error.
2018-01-23 13:33:48 +03:00
origin = line.Substring (0, idxError);
line = line.Substring (endError);
line = RemovePathAtEnd (line);
[mtouch/mmp] Give users more control over optimizations, and share more code between mtouch and mmp. (#3242) * [mtouch/mmp] Give users more control over optimizations, and share more code between mtouch and mmp. 1. Add an --optimize flag to mtouch/mmp that allows users to select which optimizations to apply (or not). This makes it easier to add future optimizations, and allow users to disable any optimization that causes problems without having to disable many other features. 2. Share as much optimization code as possible between mtouch and mmp. This immediately gives a benefit to mmp, which has three new optimizations only mtouch had: NSObject.IsDirectBinding inlining, IntPtr.Size inlining and dead code elimination. This results in ~6kb of disk space saved for a linked Xamarin.Mac app: * link sdk: [Debug][1], [Release][2] * link all: [Debug][3], [Release][4] Testing also verifies that monotouchtest ([Debug][5], [Release][6]) has not changed size at all, which means that no default optimizations have changed inadvertedly. [1]: https://gist.github.com/rolfbjarne/6b731e3b5ca6170355662e6505c3d492#link-sdk-mac--debug [2]: https://gist.github.com/rolfbjarne/6b731e3b5ca6170355662e6505c3d492#link-sdk-mac--release [3]: https://gist.github.com/rolfbjarne/6b731e3b5ca6170355662e6505c3d492#link-all-mac--debug [4]: https://gist.github.com/rolfbjarne/6b731e3b5ca6170355662e6505c3d492#link-all-mac--release [5]: https://gist.github.com/rolfbjarne/6b731e3b5ca6170355662e6505c3d492#monotouchtest-iphonedebug64 [6]: https://gist.github.com/rolfbjarne/6b731e3b5ca6170355662e6505c3d492#monotouchtest-iphonerelease64 * [tools] Don't enable the IsDirectBinding optimization by default for Xamarin.Mac apps, it's not safe. * Fix whitespace issues. * [doc] Document optimizations. * Officially support optimizations by adding them to the Versions.plist. * [linker] Improve IntPtr.Size inliner + dead code eliminatior and add tests. * Properly handle operands for the ldc_i4_s instruction (they're sbyte). * Fix less-than condition to actually do a less-than comparison. * Make sure to look up the bitness in the Target, not the Application, since the Application's value will be incorrect when building fat apps (both Is32Build and Is64Build will be true). * Remove unnecessary checks for the IntPtr.Size inliner: this optimization does not depend on other instructions than the IntPtr.get_Size call, so remove the checks that verify surrounding instructions. This makes the IntPtr.Size inliner kick in in more scenarios (such as the new tests). * Add tests. * [tests] Add mmp tests for optimizations. * [tests] Fix XM optimization tests. * [tests] Fix test build error.
2018-01-23 13:33:48 +03:00
} 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)) {
2016-05-26 16:06:52 +03:00
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
2016-05-26 16:06:52 +03:00
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;
2016-05-26 16:06:52 +03:00
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;
}
}
2016-05-26 16:06:52 +03:00
messages.Add (msg);
}
}
public void ParseMessages ()
{
messages.Clear ();
ParseMessages (messages, output.ToString ().Split ('\n'), MessageToolName);
}
2016-05-26 16:06:52 +03:00
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 messages.Count ((v) => v.IsWarning);
}
}
2016-05-26 16:06:52 +03:00
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;
}
[mtouch/mmp] Give users more control over optimizations, and share more code between mtouch and mmp. (#3242) * [mtouch/mmp] Give users more control over optimizations, and share more code between mtouch and mmp. 1. Add an --optimize flag to mtouch/mmp that allows users to select which optimizations to apply (or not). This makes it easier to add future optimizations, and allow users to disable any optimization that causes problems without having to disable many other features. 2. Share as much optimization code as possible between mtouch and mmp. This immediately gives a benefit to mmp, which has three new optimizations only mtouch had: NSObject.IsDirectBinding inlining, IntPtr.Size inlining and dead code elimination. This results in ~6kb of disk space saved for a linked Xamarin.Mac app: * link sdk: [Debug][1], [Release][2] * link all: [Debug][3], [Release][4] Testing also verifies that monotouchtest ([Debug][5], [Release][6]) has not changed size at all, which means that no default optimizations have changed inadvertedly. [1]: https://gist.github.com/rolfbjarne/6b731e3b5ca6170355662e6505c3d492#link-sdk-mac--debug [2]: https://gist.github.com/rolfbjarne/6b731e3b5ca6170355662e6505c3d492#link-sdk-mac--release [3]: https://gist.github.com/rolfbjarne/6b731e3b5ca6170355662e6505c3d492#link-all-mac--debug [4]: https://gist.github.com/rolfbjarne/6b731e3b5ca6170355662e6505c3d492#link-all-mac--release [5]: https://gist.github.com/rolfbjarne/6b731e3b5ca6170355662e6505c3d492#monotouchtest-iphonedebug64 [6]: https://gist.github.com/rolfbjarne/6b731e3b5ca6170355662e6505c3d492#monotouchtest-iphonerelease64 * [tools] Don't enable the IsDirectBinding optimization by default for Xamarin.Mac apps, it's not safe. * Fix whitespace issues. * [doc] Document optimizations. * Officially support optimizations by adding them to the Versions.plist. * [linker] Improve IntPtr.Size inliner + dead code eliminatior and add tests. * Properly handle operands for the ldc_i4_s instruction (they're sbyte). * Fix less-than condition to actually do a less-than comparison. * Make sure to look up the bitness in the Target, not the Application, since the Application's value will be incorrect when building fat apps (both Is32Build and Is64Build will be true). * Remove unnecessary checks for the IntPtr.Size inliner: this optimization does not depend on other instructions than the IntPtr.get_Size call, so remove the checks that verify surrounding instructions. This makes the IntPtr.Size inliner kick in in more scenarios (such as the new tests). * Add tests. * [tests] Add mmp tests for optimizations. * [tests] Fix XM optimization tests. * [tests] Fix test build error.
2018-01-23 13:33:48 +03:00
public void AssertWarningCount (int count, string message = "warnings")
{
if (count != WarningCount)
Assert.Fail ($"{message}\nExpected: {count}\nBut was: {WarningCount}\nWarnings:\n\t{string.Join ("\n\t", this.Messages.Where ((v) => v.IsWarning).Select ((v) => v.ToString ()))}");
[mtouch/mmp] Give users more control over optimizations, and share more code between mtouch and mmp. (#3242) * [mtouch/mmp] Give users more control over optimizations, and share more code between mtouch and mmp. 1. Add an --optimize flag to mtouch/mmp that allows users to select which optimizations to apply (or not). This makes it easier to add future optimizations, and allow users to disable any optimization that causes problems without having to disable many other features. 2. Share as much optimization code as possible between mtouch and mmp. This immediately gives a benefit to mmp, which has three new optimizations only mtouch had: NSObject.IsDirectBinding inlining, IntPtr.Size inlining and dead code elimination. This results in ~6kb of disk space saved for a linked Xamarin.Mac app: * link sdk: [Debug][1], [Release][2] * link all: [Debug][3], [Release][4] Testing also verifies that monotouchtest ([Debug][5], [Release][6]) has not changed size at all, which means that no default optimizations have changed inadvertedly. [1]: https://gist.github.com/rolfbjarne/6b731e3b5ca6170355662e6505c3d492#link-sdk-mac--debug [2]: https://gist.github.com/rolfbjarne/6b731e3b5ca6170355662e6505c3d492#link-sdk-mac--release [3]: https://gist.github.com/rolfbjarne/6b731e3b5ca6170355662e6505c3d492#link-all-mac--debug [4]: https://gist.github.com/rolfbjarne/6b731e3b5ca6170355662e6505c3d492#link-all-mac--release [5]: https://gist.github.com/rolfbjarne/6b731e3b5ca6170355662e6505c3d492#monotouchtest-iphonedebug64 [6]: https://gist.github.com/rolfbjarne/6b731e3b5ca6170355662e6505c3d492#monotouchtest-iphonerelease64 * [tools] Don't enable the IsDirectBinding optimization by default for Xamarin.Mac apps, it's not safe. * Fix whitespace issues. * [doc] Document optimizations. * Officially support optimizations by adding them to the Versions.plist. * [linker] Improve IntPtr.Size inliner + dead code eliminatior and add tests. * Properly handle operands for the ldc_i4_s instruction (they're sbyte). * Fix less-than condition to actually do a less-than comparison. * Make sure to look up the bitness in the Target, not the Application, since the Application's value will be incorrect when building fat apps (both Is32Build and Is64Build will be true). * Remove unnecessary checks for the IntPtr.Size inliner: this optimization does not depend on other instructions than the IntPtr.get_Size call, so remove the checks that verify surrounding instructions. This makes the IntPtr.Size inliner kick in in more scenarios (such as the new tests). * Add tests. * [tests] Add mmp tests for optimizations. * [tests] Fix XM optimization tests. * [tests] Fix test build error.
2018-01-23 13:33:48 +03:00
}
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)
2016-05-26 16:06:52 +03:00
{
AssertErrorPattern (MessagePrefix, number, messagePattern, filename, linenumber, custom_pattern_syntax);
2016-05-26 16:06:52 +03:00
}
public void AssertErrorPattern (string prefix, int number, string messagePattern, string filename = null, int? linenumber = null, bool custom_pattern_syntax = false)
2016-05-26 16:06:52 +03:00
{
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);
2016-05-26 16:06:52 +03:00
}
public void AssertError (int number, string message, string filename = null, int? linenumber = null)
2016-05-26 16:06:52 +03:00
{
AssertError (MessagePrefix, number, message, filename, linenumber);
2016-05-26 16:06:52 +03:00
}
public void AssertError (string prefix, int number, string message, string filename = null, int? linenumber = null)
2016-05-26 16:06:52 +03:00
{
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 ())));
}
2016-05-26 16:06:52 +03:00
AssertFilename (prefix, number, message, matches, filename, linenumber);
}
void AssertFilename (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 ())}"));
}
}
2016-05-26 16:06:52 +03:00
}
public void AssertWarningPattern (int number, string messagePattern)
{
AssertWarningPattern (MessagePrefix, number, messagePattern);
}
public void AssertWarningPattern (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 ())));
}
Optimize calls to BlockLiteral.SetupBlock to inject the block signature. (#3391) * [linker] Optimize calls to BlockLiteral.SetupBlock to inject the block signature. Optimize calls to BlockLiteral.SetupBlock[Unsafe] to calculate the block signature at build time, and inject it into the call site. This makes block invocations 10-15x faster (I've added tests that asserts at least an 8x increase). It's also required in order to be able to remove the dynamic registrar code in the future (since calculating the block signature at runtime requires the dynamic registrar). * [mtouch/mmp] Add support for reporting errors/warnings that point to the code line causing the error/warning. Add support for reporting errors/warnings that point to the code line causing the error/warning by adding ErrorHelper overloads that take the exact instruction to report (previously we defaulted to the first line/instruction in a method). * [tests] Add support for asserting filename/linenumber in warning messages. * Make all methods that manually create BlockLiterals optimizable. * [tests] Create a BaseOptimizeGeneratedCodeTest test that's included in both XI's and XM's link all test. * [tests] Add link all test (for both XI and XM) to test the BlockLiteral.SetupBlock optimization. * [tests] Add mtouch/mmp tests for the BlockLiteral.SetupBlock optimization. * [tests][linker] Make the base test class abstract, so tests in the base class aren't executed twice. * [tests][linker] Don't execute linkall-only tests in linksdk. The optimization tests only apply when the test assembly is linked, and that only happens in linkall, so exclude those tests in linksdk. * [tests][mmptest] Update test according to mmp changes. Fixes these test failures: 1) Failed : Xamarin.MMP.Tests.MMPTests.MM0132("inline-runtime-arch") The warning 'MM0132: Unknown optimization: 'inline-runtime-arch'. Valid optimizations are: remove-uithread-checks, dead-code-elimination, inline-isdirectbinding, inline-intptr-size.' was not found in the output: Message #1 did not match: actual: 'Unknown optimization: 'inline-runtime-arch'. Valid optimizations are: remove-uithread-checks, dead-code-elimination, inline-isdirectbinding, inline-intptr-size, blockliteral-setupblock.' expected: 'Unknown optimization: 'inline-runtime-arch'. Valid optimizations are: remove-uithread-checks, dead-code-elimination, inline-isdirectbinding, inline-intptr-size.' Message #2 did not match: actual: 'Unknown optimization: 'inline-runtime-arch'. Valid optimizations are: remove-uithread-checks, dead-code-elimination, inline-isdirectbinding, inline-intptr-size, blockliteral-setupblock.' expected: 'Unknown optimization: 'inline-runtime-arch'. Valid optimizations are: remove-uithread-checks, dead-code-elimination, inline-isdirectbinding, inline-intptr-size.' 2) Failed : Xamarin.MMP.Tests.MMPTests.MM0132("foo") The warning 'MM0132: Unknown optimization: 'foo'. Valid optimizations are: remove-uithread-checks, dead-code-elimination, inline-isdirectbinding, inline-intptr-size.' was not found in the output: Message #1 did not match: actual: 'Unknown optimization: 'foo'. Valid optimizations are: remove-uithread-checks, dead-code-elimination, inline-isdirectbinding, inline-intptr-size, blockliteral-setupblock.' expected: 'Unknown optimization: 'foo'. Valid optimizations are: remove-uithread-checks, dead-code-elimination, inline-isdirectbinding, inline-intptr-size.' Message #2 did not match: actual: 'Unknown optimization: 'foo'. Valid optimizations are: remove-uithread-checks, dead-code-elimination, inline-isdirectbinding, inline-intptr-size, blockliteral-setupblock.' expected: 'Unknown optimization: 'foo'. Valid optimizations are: remove-uithread-checks, dead-code-elimination, inline-isdirectbinding, inline-intptr-size.' * [tests][linker] Fix typo. Fixes this test failure: 1) SetupBlock_CustomDelegate (Linker.Shared.BaseOptimizeGeneratedCodeTest.SetupBlock_CustomDelegate) Counter Expected: 1 But was: 2 * [registrar] Minor adjustment to error message to match previous (and better) behavior. Fixes this test failure: 1) Failed : Xamarin.Registrar.GenericType_WithInvalidParameterTypes The error 'MT4136: The registrar cannot marshal the parameter type 'System.Collections.Generic.List`1<U>' of the parameter 'arg' in the method 'Open`1.Bar(System.Collections.Generic.List`1<U>)'' was not found in the output: Message #1 did not match: actual: 'The registrar cannot marshal the parameter type 'System.Collections.Generic.List`1<Foundation.NSObject>' of the parameter 'arg' in the method 'Open`1.Bar(System.Collections.Generic.List`1<U>)'' expected: 'The registrar cannot marshal the parameter type 'System.Collections.Generic.List`1<U>' of the parameter 'arg' in the method 'Open`1.Bar(System.Collections.Generic.List`1<U>)'' * [docs] mmp shows MM errors/warnings. * [docs] Improve according to reviews. * [tests] Fix merge failure causing test duplication.
2018-02-06 09:08:15 +03:00
public void AssertWarning (int number, string message, string filename = null, int? linenumber = null)
{
Optimize calls to BlockLiteral.SetupBlock to inject the block signature. (#3391) * [linker] Optimize calls to BlockLiteral.SetupBlock to inject the block signature. Optimize calls to BlockLiteral.SetupBlock[Unsafe] to calculate the block signature at build time, and inject it into the call site. This makes block invocations 10-15x faster (I've added tests that asserts at least an 8x increase). It's also required in order to be able to remove the dynamic registrar code in the future (since calculating the block signature at runtime requires the dynamic registrar). * [mtouch/mmp] Add support for reporting errors/warnings that point to the code line causing the error/warning. Add support for reporting errors/warnings that point to the code line causing the error/warning by adding ErrorHelper overloads that take the exact instruction to report (previously we defaulted to the first line/instruction in a method). * [tests] Add support for asserting filename/linenumber in warning messages. * Make all methods that manually create BlockLiterals optimizable. * [tests] Create a BaseOptimizeGeneratedCodeTest test that's included in both XI's and XM's link all test. * [tests] Add link all test (for both XI and XM) to test the BlockLiteral.SetupBlock optimization. * [tests] Add mtouch/mmp tests for the BlockLiteral.SetupBlock optimization. * [tests][linker] Make the base test class abstract, so tests in the base class aren't executed twice. * [tests][linker] Don't execute linkall-only tests in linksdk. The optimization tests only apply when the test assembly is linked, and that only happens in linkall, so exclude those tests in linksdk. * [tests][mmptest] Update test according to mmp changes. Fixes these test failures: 1) Failed : Xamarin.MMP.Tests.MMPTests.MM0132("inline-runtime-arch") The warning 'MM0132: Unknown optimization: 'inline-runtime-arch'. Valid optimizations are: remove-uithread-checks, dead-code-elimination, inline-isdirectbinding, inline-intptr-size.' was not found in the output: Message #1 did not match: actual: 'Unknown optimization: 'inline-runtime-arch'. Valid optimizations are: remove-uithread-checks, dead-code-elimination, inline-isdirectbinding, inline-intptr-size, blockliteral-setupblock.' expected: 'Unknown optimization: 'inline-runtime-arch'. Valid optimizations are: remove-uithread-checks, dead-code-elimination, inline-isdirectbinding, inline-intptr-size.' Message #2 did not match: actual: 'Unknown optimization: 'inline-runtime-arch'. Valid optimizations are: remove-uithread-checks, dead-code-elimination, inline-isdirectbinding, inline-intptr-size, blockliteral-setupblock.' expected: 'Unknown optimization: 'inline-runtime-arch'. Valid optimizations are: remove-uithread-checks, dead-code-elimination, inline-isdirectbinding, inline-intptr-size.' 2) Failed : Xamarin.MMP.Tests.MMPTests.MM0132("foo") The warning 'MM0132: Unknown optimization: 'foo'. Valid optimizations are: remove-uithread-checks, dead-code-elimination, inline-isdirectbinding, inline-intptr-size.' was not found in the output: Message #1 did not match: actual: 'Unknown optimization: 'foo'. Valid optimizations are: remove-uithread-checks, dead-code-elimination, inline-isdirectbinding, inline-intptr-size, blockliteral-setupblock.' expected: 'Unknown optimization: 'foo'. Valid optimizations are: remove-uithread-checks, dead-code-elimination, inline-isdirectbinding, inline-intptr-size.' Message #2 did not match: actual: 'Unknown optimization: 'foo'. Valid optimizations are: remove-uithread-checks, dead-code-elimination, inline-isdirectbinding, inline-intptr-size, blockliteral-setupblock.' expected: 'Unknown optimization: 'foo'. Valid optimizations are: remove-uithread-checks, dead-code-elimination, inline-isdirectbinding, inline-intptr-size.' * [tests][linker] Fix typo. Fixes this test failure: 1) SetupBlock_CustomDelegate (Linker.Shared.BaseOptimizeGeneratedCodeTest.SetupBlock_CustomDelegate) Counter Expected: 1 But was: 2 * [registrar] Minor adjustment to error message to match previous (and better) behavior. Fixes this test failure: 1) Failed : Xamarin.Registrar.GenericType_WithInvalidParameterTypes The error 'MT4136: The registrar cannot marshal the parameter type 'System.Collections.Generic.List`1<U>' of the parameter 'arg' in the method 'Open`1.Bar(System.Collections.Generic.List`1<U>)'' was not found in the output: Message #1 did not match: actual: 'The registrar cannot marshal the parameter type 'System.Collections.Generic.List`1<Foundation.NSObject>' of the parameter 'arg' in the method 'Open`1.Bar(System.Collections.Generic.List`1<U>)'' expected: 'The registrar cannot marshal the parameter type 'System.Collections.Generic.List`1<U>' of the parameter 'arg' in the method 'Open`1.Bar(System.Collections.Generic.List`1<U>)'' * [docs] mmp shows MM errors/warnings. * [docs] Improve according to reviews. * [tests] Fix merge failure causing test duplication.
2018-02-06 09:08:15 +03:00
AssertWarning (MessagePrefix, number, message, filename, linenumber);
}
Optimize calls to BlockLiteral.SetupBlock to inject the block signature. (#3391) * [linker] Optimize calls to BlockLiteral.SetupBlock to inject the block signature. Optimize calls to BlockLiteral.SetupBlock[Unsafe] to calculate the block signature at build time, and inject it into the call site. This makes block invocations 10-15x faster (I've added tests that asserts at least an 8x increase). It's also required in order to be able to remove the dynamic registrar code in the future (since calculating the block signature at runtime requires the dynamic registrar). * [mtouch/mmp] Add support for reporting errors/warnings that point to the code line causing the error/warning. Add support for reporting errors/warnings that point to the code line causing the error/warning by adding ErrorHelper overloads that take the exact instruction to report (previously we defaulted to the first line/instruction in a method). * [tests] Add support for asserting filename/linenumber in warning messages. * Make all methods that manually create BlockLiterals optimizable. * [tests] Create a BaseOptimizeGeneratedCodeTest test that's included in both XI's and XM's link all test. * [tests] Add link all test (for both XI and XM) to test the BlockLiteral.SetupBlock optimization. * [tests] Add mtouch/mmp tests for the BlockLiteral.SetupBlock optimization. * [tests][linker] Make the base test class abstract, so tests in the base class aren't executed twice. * [tests][linker] Don't execute linkall-only tests in linksdk. The optimization tests only apply when the test assembly is linked, and that only happens in linkall, so exclude those tests in linksdk. * [tests][mmptest] Update test according to mmp changes. Fixes these test failures: 1) Failed : Xamarin.MMP.Tests.MMPTests.MM0132("inline-runtime-arch") The warning 'MM0132: Unknown optimization: 'inline-runtime-arch'. Valid optimizations are: remove-uithread-checks, dead-code-elimination, inline-isdirectbinding, inline-intptr-size.' was not found in the output: Message #1 did not match: actual: 'Unknown optimization: 'inline-runtime-arch'. Valid optimizations are: remove-uithread-checks, dead-code-elimination, inline-isdirectbinding, inline-intptr-size, blockliteral-setupblock.' expected: 'Unknown optimization: 'inline-runtime-arch'. Valid optimizations are: remove-uithread-checks, dead-code-elimination, inline-isdirectbinding, inline-intptr-size.' Message #2 did not match: actual: 'Unknown optimization: 'inline-runtime-arch'. Valid optimizations are: remove-uithread-checks, dead-code-elimination, inline-isdirectbinding, inline-intptr-size, blockliteral-setupblock.' expected: 'Unknown optimization: 'inline-runtime-arch'. Valid optimizations are: remove-uithread-checks, dead-code-elimination, inline-isdirectbinding, inline-intptr-size.' 2) Failed : Xamarin.MMP.Tests.MMPTests.MM0132("foo") The warning 'MM0132: Unknown optimization: 'foo'. Valid optimizations are: remove-uithread-checks, dead-code-elimination, inline-isdirectbinding, inline-intptr-size.' was not found in the output: Message #1 did not match: actual: 'Unknown optimization: 'foo'. Valid optimizations are: remove-uithread-checks, dead-code-elimination, inline-isdirectbinding, inline-intptr-size, blockliteral-setupblock.' expected: 'Unknown optimization: 'foo'. Valid optimizations are: remove-uithread-checks, dead-code-elimination, inline-isdirectbinding, inline-intptr-size.' Message #2 did not match: actual: 'Unknown optimization: 'foo'. Valid optimizations are: remove-uithread-checks, dead-code-elimination, inline-isdirectbinding, inline-intptr-size, blockliteral-setupblock.' expected: 'Unknown optimization: 'foo'. Valid optimizations are: remove-uithread-checks, dead-code-elimination, inline-isdirectbinding, inline-intptr-size.' * [tests][linker] Fix typo. Fixes this test failure: 1) SetupBlock_CustomDelegate (Linker.Shared.BaseOptimizeGeneratedCodeTest.SetupBlock_CustomDelegate) Counter Expected: 1 But was: 2 * [registrar] Minor adjustment to error message to match previous (and better) behavior. Fixes this test failure: 1) Failed : Xamarin.Registrar.GenericType_WithInvalidParameterTypes The error 'MT4136: The registrar cannot marshal the parameter type 'System.Collections.Generic.List`1<U>' of the parameter 'arg' in the method 'Open`1.Bar(System.Collections.Generic.List`1<U>)'' was not found in the output: Message #1 did not match: actual: 'The registrar cannot marshal the parameter type 'System.Collections.Generic.List`1<Foundation.NSObject>' of the parameter 'arg' in the method 'Open`1.Bar(System.Collections.Generic.List`1<U>)'' expected: 'The registrar cannot marshal the parameter type 'System.Collections.Generic.List`1<U>' of the parameter 'arg' in the method 'Open`1.Bar(System.Collections.Generic.List`1<U>)'' * [docs] mmp shows MM errors/warnings. * [docs] Improve according to reviews. * [tests] Fix merge failure causing test duplication.
2018-02-06 09:08:15 +03:00
public void AssertWarning (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));
Optimize calls to BlockLiteral.SetupBlock to inject the block signature. (#3391) * [linker] Optimize calls to BlockLiteral.SetupBlock to inject the block signature. Optimize calls to BlockLiteral.SetupBlock[Unsafe] to calculate the block signature at build time, and inject it into the call site. This makes block invocations 10-15x faster (I've added tests that asserts at least an 8x increase). It's also required in order to be able to remove the dynamic registrar code in the future (since calculating the block signature at runtime requires the dynamic registrar). * [mtouch/mmp] Add support for reporting errors/warnings that point to the code line causing the error/warning. Add support for reporting errors/warnings that point to the code line causing the error/warning by adding ErrorHelper overloads that take the exact instruction to report (previously we defaulted to the first line/instruction in a method). * [tests] Add support for asserting filename/linenumber in warning messages. * Make all methods that manually create BlockLiterals optimizable. * [tests] Create a BaseOptimizeGeneratedCodeTest test that's included in both XI's and XM's link all test. * [tests] Add link all test (for both XI and XM) to test the BlockLiteral.SetupBlock optimization. * [tests] Add mtouch/mmp tests for the BlockLiteral.SetupBlock optimization. * [tests][linker] Make the base test class abstract, so tests in the base class aren't executed twice. * [tests][linker] Don't execute linkall-only tests in linksdk. The optimization tests only apply when the test assembly is linked, and that only happens in linkall, so exclude those tests in linksdk. * [tests][mmptest] Update test according to mmp changes. Fixes these test failures: 1) Failed : Xamarin.MMP.Tests.MMPTests.MM0132("inline-runtime-arch") The warning 'MM0132: Unknown optimization: 'inline-runtime-arch'. Valid optimizations are: remove-uithread-checks, dead-code-elimination, inline-isdirectbinding, inline-intptr-size.' was not found in the output: Message #1 did not match: actual: 'Unknown optimization: 'inline-runtime-arch'. Valid optimizations are: remove-uithread-checks, dead-code-elimination, inline-isdirectbinding, inline-intptr-size, blockliteral-setupblock.' expected: 'Unknown optimization: 'inline-runtime-arch'. Valid optimizations are: remove-uithread-checks, dead-code-elimination, inline-isdirectbinding, inline-intptr-size.' Message #2 did not match: actual: 'Unknown optimization: 'inline-runtime-arch'. Valid optimizations are: remove-uithread-checks, dead-code-elimination, inline-isdirectbinding, inline-intptr-size, blockliteral-setupblock.' expected: 'Unknown optimization: 'inline-runtime-arch'. Valid optimizations are: remove-uithread-checks, dead-code-elimination, inline-isdirectbinding, inline-intptr-size.' 2) Failed : Xamarin.MMP.Tests.MMPTests.MM0132("foo") The warning 'MM0132: Unknown optimization: 'foo'. Valid optimizations are: remove-uithread-checks, dead-code-elimination, inline-isdirectbinding, inline-intptr-size.' was not found in the output: Message #1 did not match: actual: 'Unknown optimization: 'foo'. Valid optimizations are: remove-uithread-checks, dead-code-elimination, inline-isdirectbinding, inline-intptr-size, blockliteral-setupblock.' expected: 'Unknown optimization: 'foo'. Valid optimizations are: remove-uithread-checks, dead-code-elimination, inline-isdirectbinding, inline-intptr-size.' Message #2 did not match: actual: 'Unknown optimization: 'foo'. Valid optimizations are: remove-uithread-checks, dead-code-elimination, inline-isdirectbinding, inline-intptr-size, blockliteral-setupblock.' expected: 'Unknown optimization: 'foo'. Valid optimizations are: remove-uithread-checks, dead-code-elimination, inline-isdirectbinding, inline-intptr-size.' * [tests][linker] Fix typo. Fixes this test failure: 1) SetupBlock_CustomDelegate (Linker.Shared.BaseOptimizeGeneratedCodeTest.SetupBlock_CustomDelegate) Counter Expected: 1 But was: 2 * [registrar] Minor adjustment to error message to match previous (and better) behavior. Fixes this test failure: 1) Failed : Xamarin.Registrar.GenericType_WithInvalidParameterTypes The error 'MT4136: The registrar cannot marshal the parameter type 'System.Collections.Generic.List`1<U>' of the parameter 'arg' in the method 'Open`1.Bar(System.Collections.Generic.List`1<U>)'' was not found in the output: Message #1 did not match: actual: 'The registrar cannot marshal the parameter type 'System.Collections.Generic.List`1<Foundation.NSObject>' of the parameter 'arg' in the method 'Open`1.Bar(System.Collections.Generic.List`1<U>)'' expected: 'The registrar cannot marshal the parameter type 'System.Collections.Generic.List`1<U>' of the parameter 'arg' in the method 'Open`1.Bar(System.Collections.Generic.List`1<U>)'' * [docs] mmp shows MM errors/warnings. * [docs] Improve according to reviews. * [tests] Fix merge failure causing test duplication.
2018-02-06 09:08:15 +03:00
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 ())));
}
Optimize calls to BlockLiteral.SetupBlock to inject the block signature. (#3391) * [linker] Optimize calls to BlockLiteral.SetupBlock to inject the block signature. Optimize calls to BlockLiteral.SetupBlock[Unsafe] to calculate the block signature at build time, and inject it into the call site. This makes block invocations 10-15x faster (I've added tests that asserts at least an 8x increase). It's also required in order to be able to remove the dynamic registrar code in the future (since calculating the block signature at runtime requires the dynamic registrar). * [mtouch/mmp] Add support for reporting errors/warnings that point to the code line causing the error/warning. Add support for reporting errors/warnings that point to the code line causing the error/warning by adding ErrorHelper overloads that take the exact instruction to report (previously we defaulted to the first line/instruction in a method). * [tests] Add support for asserting filename/linenumber in warning messages. * Make all methods that manually create BlockLiterals optimizable. * [tests] Create a BaseOptimizeGeneratedCodeTest test that's included in both XI's and XM's link all test. * [tests] Add link all test (for both XI and XM) to test the BlockLiteral.SetupBlock optimization. * [tests] Add mtouch/mmp tests for the BlockLiteral.SetupBlock optimization. * [tests][linker] Make the base test class abstract, so tests in the base class aren't executed twice. * [tests][linker] Don't execute linkall-only tests in linksdk. The optimization tests only apply when the test assembly is linked, and that only happens in linkall, so exclude those tests in linksdk. * [tests][mmptest] Update test according to mmp changes. Fixes these test failures: 1) Failed : Xamarin.MMP.Tests.MMPTests.MM0132("inline-runtime-arch") The warning 'MM0132: Unknown optimization: 'inline-runtime-arch'. Valid optimizations are: remove-uithread-checks, dead-code-elimination, inline-isdirectbinding, inline-intptr-size.' was not found in the output: Message #1 did not match: actual: 'Unknown optimization: 'inline-runtime-arch'. Valid optimizations are: remove-uithread-checks, dead-code-elimination, inline-isdirectbinding, inline-intptr-size, blockliteral-setupblock.' expected: 'Unknown optimization: 'inline-runtime-arch'. Valid optimizations are: remove-uithread-checks, dead-code-elimination, inline-isdirectbinding, inline-intptr-size.' Message #2 did not match: actual: 'Unknown optimization: 'inline-runtime-arch'. Valid optimizations are: remove-uithread-checks, dead-code-elimination, inline-isdirectbinding, inline-intptr-size, blockliteral-setupblock.' expected: 'Unknown optimization: 'inline-runtime-arch'. Valid optimizations are: remove-uithread-checks, dead-code-elimination, inline-isdirectbinding, inline-intptr-size.' 2) Failed : Xamarin.MMP.Tests.MMPTests.MM0132("foo") The warning 'MM0132: Unknown optimization: 'foo'. Valid optimizations are: remove-uithread-checks, dead-code-elimination, inline-isdirectbinding, inline-intptr-size.' was not found in the output: Message #1 did not match: actual: 'Unknown optimization: 'foo'. Valid optimizations are: remove-uithread-checks, dead-code-elimination, inline-isdirectbinding, inline-intptr-size, blockliteral-setupblock.' expected: 'Unknown optimization: 'foo'. Valid optimizations are: remove-uithread-checks, dead-code-elimination, inline-isdirectbinding, inline-intptr-size.' Message #2 did not match: actual: 'Unknown optimization: 'foo'. Valid optimizations are: remove-uithread-checks, dead-code-elimination, inline-isdirectbinding, inline-intptr-size, blockliteral-setupblock.' expected: 'Unknown optimization: 'foo'. Valid optimizations are: remove-uithread-checks, dead-code-elimination, inline-isdirectbinding, inline-intptr-size.' * [tests][linker] Fix typo. Fixes this test failure: 1) SetupBlock_CustomDelegate (Linker.Shared.BaseOptimizeGeneratedCodeTest.SetupBlock_CustomDelegate) Counter Expected: 1 But was: 2 * [registrar] Minor adjustment to error message to match previous (and better) behavior. Fixes this test failure: 1) Failed : Xamarin.Registrar.GenericType_WithInvalidParameterTypes The error 'MT4136: The registrar cannot marshal the parameter type 'System.Collections.Generic.List`1<U>' of the parameter 'arg' in the method 'Open`1.Bar(System.Collections.Generic.List`1<U>)'' was not found in the output: Message #1 did not match: actual: 'The registrar cannot marshal the parameter type 'System.Collections.Generic.List`1<Foundation.NSObject>' of the parameter 'arg' in the method 'Open`1.Bar(System.Collections.Generic.List`1<U>)'' expected: 'The registrar cannot marshal the parameter type 'System.Collections.Generic.List`1<U>' of the parameter 'arg' in the method 'Open`1.Bar(System.Collections.Generic.List`1<U>)'' * [docs] mmp shows MM errors/warnings. * [docs] Improve according to reviews. * [tests] Fix merge failure causing test duplication.
2018-02-06 09:08:15 +03:00
AssertFilename (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 ()));
}
2016-05-26 16:06:52 +03:00
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; } }
2016-05-26 16:06:52 +03:00
}
class XBuild
{
public static string ToolPath {
get
{
return Configuration.XIBuildPath;
2016-05-26 16:06:52 +03:00
}
}
public static void BuildXM (string project, string configuration = "Debug", string platform = "iPhoneSimulator", string verbosity = null, TimeSpan? timeout = null, string [] arguments = null)
2016-05-26 16:06:52 +03:00
{
Build (project,
new Dictionary<string, string> {
{ "MD_APPLE_SDK_ROOT", Path.GetDirectoryName (Path.GetDirectoryName (Configuration.xcode_root)) },
{ "TargetFrameworkFallbackSearchPaths", Path.Combine (Configuration.TargetDirectoryXM, "Library", "Frameworks", "Mono.framework", "External", "xbuild-frameworks") },
{ "MSBuildExtensionsPathFallbackPathsOverride", Path.Combine (Configuration.TargetDirectoryXM, "Library", "Frameworks", "Mono.framework", "External", "xbuild") },
{ "XamarinMacFrameworkRoot", Path.Combine (Configuration.TargetDirectoryXM, "Library", "Frameworks", "Xamarin.Mac.framework", "Versions", "Current") },
{ "XAMMAC_FRAMEWORK_PATH", Path.Combine (Configuration.TargetDirectoryXM, "Library", "Frameworks", "Xamarin.Mac.framework", "Versions", "Current") },
}, configuration, platform, verbosity, timeout, arguments);
}
public static void BuildXI (string project, string configuration = "Debug", string platform = "iPhoneSimulator", string verbosity = null, TimeSpan? timeout = null, string [] arguments = null)
{
Build (project,
new Dictionary<string, string> {
{ "MD_APPLE_SDK_ROOT", Path.GetDirectoryName (Path.GetDirectoryName (Configuration.xcode_root)) },
{ "TargetFrameworkFallbackSearchPaths", Path.Combine (Configuration.TargetDirectoryXI, "Library", "Frameworks", "Mono.framework", "External", "xbuild-frameworks") },
{ "MSBuildExtensionsPathFallbackPathsOverride", Path.Combine (Configuration.TargetDirectoryXI, "Library", "Frameworks", "Mono.framework", "External", "xbuild") },
{ "MD_MTOUCH_SDK_ROOT", Path.Combine (Configuration.TargetDirectoryXI, "Library", "Frameworks", "Xamarin.iOS.framework", "Versions", "Current") },
}, configuration, platform, verbosity, timeout, arguments);
}
static void Build (string project, Dictionary<string, string> environmentVariables, string configuration = "Debug", string platform = "iPhoneSimulator", string verbosity = null, TimeSpan? timeout = null, string [] arguments = null)
{
ExecutionHelper.Execute (ToolPath,
new string [] {
"--",
$"/p:Configuration={configuration}",
$"/p:Platform={platform}",
$"/verbosity:{(string.IsNullOrEmpty (verbosity) ? "normal" : verbosity)}",
project
}.Union (arguments ?? new string [] { }).ToArray (),
environmentVariables: environmentVariables,
timeout: timeout);
2016-05-26 16:06:52 +03:00
}
}
static class ExecutionHelper {
static int Execute (string fileName, string[] arguments, StringBuilder stdout, StringBuilder stderr, TimeSpan? timeout = null)
{
var psi = new ProcessStartInfo (fileName, string.Join (" ", arguments.Select ((v) => StringUtils.Quote (v))));
return Execute (psi, (line) => {
lock (stdout)
stdout.AppendLine (line);
}, (line) => {
lock (stderr)
stderr.AppendLine (line);
}, timeout);
}
2016-05-26 16:06:52 +03:00
static int Execute (ProcessStartInfo psi, StringBuilder stdout, StringBuilder stderr, TimeSpan? timeout = null)
{
return Execute (psi, (line) => {
lock (stdout)
stdout.AppendLine (line);
}, (line) => {
lock (stderr)
stderr.AppendLine (line);
}, timeout);
}
public static int Execute (string fileName, string [] arguments, Action<string> stdout_callback = null, Action<string> stderr_callback = null, TimeSpan? timeout = null)
{
return Execute (fileName, arguments, null, stdout_callback, stderr_callback, timeout);
}
public static int Execute (string fileName, string [] arguments, string working_directory = null, Action<string> stdout_callback = null, Action<string> stderr_callback = null, TimeSpan? timeout = null)
{
var psi = new ProcessStartInfo (fileName, string.Join (" ", arguments.Select ((v) => StringUtils.Quote (v))));
psi.WorkingDirectory = working_directory;
return Execute (psi, stdout_callback, stderr_callback, timeout);
}
public static int Execute (string fileName, string [] arguments, out StringBuilder output, string working_directory = null, TimeSpan? timeout = null)
{
output = new StringBuilder ();
var psi = new ProcessStartInfo (fileName, string.Join (" ", arguments.Select ((v) => StringUtils.Quote (v))));
psi.WorkingDirectory = working_directory;
var capturedOutput = output;
var callback = new Action<string> ((v) => {
lock (psi)
capturedOutput.AppendLine (v);
});
return Execute (psi, callback, callback, timeout);
}
public static int Execute (string fileName, string [] arguments, out bool timed_out, Dictionary<string, string> environment_variables = null, Action<string> stdout_callback = null, Action<string> stderr_callback = null, TimeSpan? timeout = null)
{
var psi = new ProcessStartInfo (fileName, string.Join (" ", StringUtils.Quote (arguments)));
if (environment_variables != null) {
foreach (var ev in environment_variables)
psi.EnvironmentVariables [ev.Key] = ev.Value;
}
return Execute (psi, out timed_out, stdout_callback, stderr_callback, timeout);
}
public static int Execute (string fileName, string [] arguments, out bool timed_out, string working_directory = null, Dictionary<string, string> environment_variables = null, Action<string> stdout_callback = null, Action<string> stderr_callback = null, TimeSpan? timeout = null)
{
var psi = new ProcessStartInfo (fileName, string.Join (" ", StringUtils.Quote (arguments)));
psi.WorkingDirectory = working_directory;
if (environment_variables != null) {
foreach (var ev in environment_variables)
psi.EnvironmentVariables [ev.Key] = ev.Value;
}
return Execute (psi, out timed_out, stdout_callback, stderr_callback, timeout);
}
public static int Execute (ProcessStartInfo psi, Action<string> stdout_callback = null, Action<string> stderr_callback = null, TimeSpan? timeout = null)
{
return Execute (psi, out var _, stdout_callback, stderr_callback, timeout);
}
public static int Execute (ProcessStartInfo psi, out bool timed_out, Action<string> stdout_callback = null, Action<string> stderr_callback = null, TimeSpan? timeout = null)
2016-05-26 16:06:52 +03:00
{
var watch = new Stopwatch ();
watch.Start ();
if (stdout_callback == null)
stdout_callback = Console.WriteLine;
if (stderr_callback == null)
stderr_callback = Console.Error.WriteLine;
2016-05-26 16:06:52 +03:00
try {
psi.UseShellExecute = false;
psi.RedirectStandardError = true;
psi.RedirectStandardOutput = true;
if (!string.IsNullOrEmpty (psi.WorkingDirectory))
Console.Write ($"cd {StringUtils.Quote (psi.WorkingDirectory)} && ");
2016-05-26 16:06:52 +03:00
Console.WriteLine ("{0} {1}", psi.FileName, psi.Arguments);
using (var p = new Process ()) {
p.StartInfo = psi;
// mtouch/mmp writes UTF8 data outside of the ASCII range, so we need to make sure
// we read it in the same format. This also means we can't use the events to get
// stdout/stderr, because mono's Process class parses those using Encoding.Default.
p.StartInfo.StandardOutputEncoding = Encoding.UTF8;
p.StartInfo.StandardErrorEncoding = Encoding.UTF8;
p.Start ();
var outReader = new Thread (() =>
{
string l;
while ((l = p.StandardOutput.ReadLine ()) != null) {
stdout_callback (l);
2016-05-26 16:06:52 +03:00
}
})
{
IsBackground = true,
};
outReader.Start ();
var errReader = new Thread (() =>
{
string l;
while ((l = p.StandardError.ReadLine ()) != null) {
stderr_callback (l);
2016-05-26 16:06:52 +03:00
}
})
{
IsBackground = true,
};
errReader.Start ();
if (timeout == null)
timeout = TimeSpan.FromMinutes (5);
if (!p.WaitForExit ((int) timeout.Value.TotalMilliseconds)) {
timed_out = true;
2016-05-26 16:06:52 +03:00
Console.WriteLine ("Command didn't finish in {0} minutes:", timeout.Value.TotalMinutes);
Console.WriteLine ("{0} {1}", p.StartInfo.FileName, p.StartInfo.Arguments);
Console.WriteLine ("Will now kill the process");
kill (p.Id, 9);
if (!p.WaitForExit (1000 /* killing should be fairly quick */)) {
Console.WriteLine ("Kill failed to kill in 1 second !?");
return 1;
}
} else {
timed_out = false;
2016-05-26 16:06:52 +03:00
}
outReader.Join (TimeSpan.FromSeconds (1));
errReader.Join (TimeSpan.FromSeconds (1));
return p.ExitCode;
}
} finally {
Console.WriteLine ("{0} Executed in {1}: {2} {3}", DateTime.Now, watch.Elapsed.ToString (), psi.FileName, psi.Arguments);
}
}
public static int Execute (string fileName, string arguments, out string output, TimeSpan? timeout = null)
{
var sb = new StringBuilder ();
var psi = new ProcessStartInfo ();
psi.FileName = fileName;
psi.Arguments = arguments;
var rv = Execute (psi, sb, sb, timeout);
output = sb.ToString ();
return rv;
}
// The arguments are automatically quoted.
public static int Execute (string fileName, string[] arguments, Dictionary<string, string> environmentVariables, StringBuilder stdout, StringBuilder stderr, TimeSpan? timeout = null, string workingDirectory = null)
{
return Execute (fileName, string.Join (" ", Xamarin.Utils.StringUtils.Quote (arguments)), environmentVariables, stdout, stderr, timeout, workingDirectory);
}
public static int Execute (string fileName, string arguments, Dictionary<string, string> environmentVariables, StringBuilder stdout, StringBuilder stderr, TimeSpan? timeout = null, string workingDirectory = null)
2016-05-26 16:06:52 +03:00
{
if (stdout == null)
stdout = new StringBuilder ();
if (stderr == null)
stderr = new StringBuilder ();
var psi = new ProcessStartInfo ();
psi.FileName = fileName;
psi.Arguments = arguments;
if (!string.IsNullOrEmpty (workingDirectory))
psi.WorkingDirectory = workingDirectory;
2016-05-26 16:06:52 +03:00
if (environmentVariables != null) {
var envs = psi.EnvironmentVariables;
foreach (var kvp in environmentVariables) {
envs [kvp.Key] = kvp.Value;
2016-05-26 16:06:52 +03:00
}
}
return Execute (psi, stdout, stderr, timeout);
}
[DllImport ("libc")]
private static extern void kill (int pid, int sig);
public static string Execute (string fileName, string[] arguments, bool throwOnError = true, Dictionary<string, string> environmentVariables = null, bool hide_output = false, TimeSpan? timeout = null)
{
return Execute (fileName, string.Join (" ", StringUtils.Quote (arguments)), throwOnError, environmentVariables, hide_output, timeout);
}
2016-05-26 16:06:52 +03:00
public static string Execute (string fileName, string arguments, bool throwOnError = true, Dictionary<string, string> environmentVariables = null,
bool hide_output = false, TimeSpan? timeout = null
2016-05-26 16:06:52 +03:00
)
{
StringBuilder output = new StringBuilder ();
int exitCode = Execute (fileName, arguments, environmentVariables, output, output, timeout);
var throw_exc = throwOnError && exitCode != 0;
if (!hide_output || throw_exc) {
2016-05-26 16:06:52 +03:00
Console.WriteLine ("{0} {1}", fileName, arguments);
Console.WriteLine (output);
Console.WriteLine ("Exit code: {0}", exitCode);
2016-05-26 16:06:52 +03:00
}
if (throw_exc)
throw new TestExecutionException ($"Execution failed (exit code: {exitCode}) for '{fileName} {arguments}'");
2016-05-26 16:06:52 +03:00
return output.ToString ();
}
}
class TestExecutionException : Exception {
public TestExecutionException (string output)
: base (output)
{
}
}
}