xamarin-macios/tests/mtouch/MonoNativeTests.cs

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

//
// MonoNativeTests.cs
//
// Author:
// Martin Baulig <mabaul@microsoft.com>
//
// Copyright (c) 2018 Xamarin Inc. (http://www.xamarin.com)
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
using System;
using System.IO;
using System.Linq;
using NUnit.Framework;
// using MTouchLinker = Xamarin.Tests.LinkerOption;
// using ExecutionHelper = Xamarin.Tests.ExecutionHelper;
// using MTouchRegistrar = Xamarin.Tests.RegistrarOption;
namespace Xamarin {
using Tests;
using Utils;
[TestFixture]
public class MonoNativeTests {
[Test]
public void TestDebugSymlink ()
{
using (var mtouch = new MTouchTool ()) {
mtouch.CreateTemporaryApp ();
mtouch.Debug = true;
mtouch.Linker = LinkerOption.DontLink;
mtouch.AssertExecute (MTouchAction.BuildSim, "build");
AssertSymlinked (mtouch.AppPath);
}
}
[Test]
public void TestDebugLinkOut ()
{
using (var mtouch = new MTouchTool ()) {
mtouch.CreateTemporaryApp ();
mtouch.Debug = true;
mtouch.Linker = LinkerOption.LinkAll;
mtouch.AssertExecute (MTouchAction.BuildSim, "build");
AssertStaticLinked (mtouch);
Assert.That (mtouch.NativeSymbolsInExecutable, Does.Not.Contain ("_mono_native_initialize"));
Assert.That (mtouch.NativeSymbolsInExecutable, Does.Not.Contain ("_NetSecurityNative_ImportUserName"));
}
}
[Test]
public void TestDeviceLinkOut ()
{
using (var mtouch = new MTouchTool ()) {
mtouch.CreateTemporaryApp ();
mtouch.Linker = LinkerOption.LinkSdk;
mtouch.AssertExecute (MTouchAction.BuildDev, "build");
AssertStaticLinked (mtouch);
Assert.That (mtouch.NativeSymbolsInExecutable, Does.Not.Contain ("_mono_native_initialize"));
Assert.That (mtouch.NativeSymbolsInExecutable, Does.Not.Contain ("_NetSecurityNative_ImportUserName"));
}
}
[Test]
public void TestDebugLinkAll ()
{
using (var mtouch = new MTouchTool ()) {
mtouch.CreateTemporaryApp (code: MonoNativeInitialize);
mtouch.Debug = true;
mtouch.Linker = LinkerOption.LinkAll;
mtouch.AssertExecute (MTouchAction.BuildSim, "build");
AssertStaticLinked (mtouch);
Assert.That (mtouch.NativeSymbolsInExecutable, Does.Contain ("_mono_native_initialize"));
Assert.That (mtouch.NativeSymbolsInExecutable, Does.Not.Contain ("_NetSecurityNative_ImportUserName"));
}
}
[Test]
public void TestDeviceLinkAll ()
{
using (var mtouch = new MTouchTool ()) {
mtouch.CreateTemporaryApp (code: MonoNativeInitialize);
mtouch.Linker = LinkerOption.LinkAll;
mtouch.AssertExecute (MTouchAction.BuildDev, "build");
AssertStaticLinked (mtouch);
Assert.That (mtouch.NativeSymbolsInExecutable, Does.Contain ("_mono_native_initialize"));
Assert.That (mtouch.NativeSymbolsInExecutable, Does.Not.Contain ("_NetSecurityNative_ImportUserName"));
}
}
[Test]
[TestCase (Profile.iOS, "9.3", "libmono-native-compat.dylib")]
[TestCase (Profile.iOS, "10.0", "libmono-native-unified.dylib")]
[TestCase (Profile.tvOS, "9.0", "libmono-native-compat.dylib")]
[TestCase (Profile.tvOS, "10.0", "libmono-native-unified.dylib")]
[TestCase (Profile.watchOS, "2.0", "libmono-native-compat.dylib")]
[TestCase (Profile.watchOS, "5.0", "libmono-native-unified.dylib")]
public void TestDeviceDylib (Profile profile, string version, string mono_native_dylib)
{
using (var mtouch = new MTouchTool ()) {
mtouch.Profile = profile;
if (profile == Profile.watchOS) {
mtouch.CreateTemporaryWatchKitExtension (code: MonoNativeWatchInitialize, extraCode: MonoNativeInitialize);
} else {
mtouch.CreateTemporaryApp (code: MonoNativeInitialize);
}
mtouch.Linker = LinkerOption.LinkAll;
mtouch.AssemblyBuildTargets.Add ("@all=dynamiclibrary");
mtouch.TargetVer = version;
mtouch.AssertExecute (MTouchAction.BuildDev, "build");
var files = Directory.EnumerateFiles (mtouch.AppPath, "libmono-native*", SearchOption.AllDirectories).Select (Path.GetFileName);
Assert.That (files.Count, Is.EqualTo (1), "One single libmono-native* library");
Assert.That (files.First (), Is.EqualTo (mono_native_dylib));
var mono_native_path = Path.Combine (mtouch.AppPath, mono_native_dylib);
var symbols = MTouch.GetNativeSymbols (mono_native_path);
Implement a different escaping/quoting algorithm for arguments to System.Diagnostics.Process. (#7177) * Implement a different escaping/quoting algorithm for arguments to System.Diagnostics.Process. mono changed how quotes should be escaped when passed to System.Diagnostic.Process, so we need to change accordingly. The main difference is that single quotes don't have to be escaped anymore. This solves problems like this: System.ComponentModel.Win32Exception : ApplicationName='nuget', CommandLine='restore '/Users/vsts/agent/2.158.0/work/1/s/tests/sampletester/bin/Debug/repositories/ios-samples/WorkingWithTables/Part 3 - Customizing a Table\'s appearance/3 - CellCustomTable/CellCustomTable.sln' -Verbosity detailed -SolutionDir '/Users/vsts/agent/2.158.0/work/1/s/tests/sampletester/bin/Debug/repositories/ios-samples/WorkingWithTables/Part 3 - Customizing a Table\'s appearance/3 - CellCustomTable'', CurrentDirectory='/Users/vsts/agent/2.158.0/work/1/s/tests/sampletester/bin/Debug/repositories', Native error= Cannot find the specified file at System.Diagnostics.Process.StartWithCreateProcess (System.Diagnostics.ProcessStartInfo startInfo) [0x0029f] in /Users/builder/jenkins/workspace/build-package-osx-mono/2019-08/external/bockbuild/builds/mono-x64/mcs/class/System/System.Diagnostics/Process.cs:778 ref: https://github.com/mono/mono/pull/15047 * Rework process arguments to pass arrays/lists around instead of quoted strings. And then only convert to a string at the very end when we create the Process instance. In the future there will be a ProcessStartInfo.ArgumentList property we can use to give the original array/list of arguments directly to the BCL so that we can avoid quoting at all. These changes gets us almost all the way there already (except that the ArgumentList property isn't available quite yet). We also have to bump to target framework version v4.7.2 from v4.5 in several places because of 'Array.Empty<T> ()' which is now used in more places. * Parse linker flags from LinkWith attributes. * [sampletester] Bump to v4.7.2 for Array.Empty<T> (). * Fix typo. * Rename GetVerbosity -> AddVerbosity. * Remove unnecessary string interpolation. * Remove unused variable. * [mtouch] Simplify code a bit. * Use implicitly typed arrays.
2019-10-14 17:18:46 +03:00
var otool_dylib = ExecutionHelper.Execute ("otool", new [] { "-L", mono_native_path }, hide_output: true);
Assert.That (symbols, Does.Contain ("_mono_native_initialize"));
Assert.That (otool_dylib, Does.Contain ($"@rpath/{mono_native_dylib}"));
Assert.That (otool_dylib.Replace (mono_native_path, ""), Does.Not.Contain ("/Users/"));
if (profile == Profile.iOS) {
Assert.That (symbols, Does.Contain ("_NetSecurityNative_ImportUserName"));
Assert.That (otool_dylib, Does.Contain ("/System/Library/Frameworks/GSS.framework/GSS"));
} else {
Assert.That (symbols, Does.Not.Contain ("_NetSecurityNative_ImportUserName"));
Assert.That (otool_dylib, Does.Not.Contain ("/System/Library/Frameworks/GSS.framework/GSS"));
}
Implement a different escaping/quoting algorithm for arguments to System.Diagnostics.Process. (#7177) * Implement a different escaping/quoting algorithm for arguments to System.Diagnostics.Process. mono changed how quotes should be escaped when passed to System.Diagnostic.Process, so we need to change accordingly. The main difference is that single quotes don't have to be escaped anymore. This solves problems like this: System.ComponentModel.Win32Exception : ApplicationName='nuget', CommandLine='restore '/Users/vsts/agent/2.158.0/work/1/s/tests/sampletester/bin/Debug/repositories/ios-samples/WorkingWithTables/Part 3 - Customizing a Table\'s appearance/3 - CellCustomTable/CellCustomTable.sln' -Verbosity detailed -SolutionDir '/Users/vsts/agent/2.158.0/work/1/s/tests/sampletester/bin/Debug/repositories/ios-samples/WorkingWithTables/Part 3 - Customizing a Table\'s appearance/3 - CellCustomTable'', CurrentDirectory='/Users/vsts/agent/2.158.0/work/1/s/tests/sampletester/bin/Debug/repositories', Native error= Cannot find the specified file at System.Diagnostics.Process.StartWithCreateProcess (System.Diagnostics.ProcessStartInfo startInfo) [0x0029f] in /Users/builder/jenkins/workspace/build-package-osx-mono/2019-08/external/bockbuild/builds/mono-x64/mcs/class/System/System.Diagnostics/Process.cs:778 ref: https://github.com/mono/mono/pull/15047 * Rework process arguments to pass arrays/lists around instead of quoted strings. And then only convert to a string at the very end when we create the Process instance. In the future there will be a ProcessStartInfo.ArgumentList property we can use to give the original array/list of arguments directly to the BCL so that we can avoid quoting at all. These changes gets us almost all the way there already (except that the ArgumentList property isn't available quite yet). We also have to bump to target framework version v4.7.2 from v4.5 in several places because of 'Array.Empty<T> ()' which is now used in more places. * Parse linker flags from LinkWith attributes. * [sampletester] Bump to v4.7.2 for Array.Empty<T> (). * Fix typo. * Rename GetVerbosity -> AddVerbosity. * Remove unnecessary string interpolation. * Remove unused variable. * [mtouch] Simplify code a bit. * Use implicitly typed arrays.
2019-10-14 17:18:46 +03:00
var otool_exe = ExecutionHelper.Execute ("otool", new [] { "-L", mtouch.NativeExecutablePath }, hide_output: true);
Assert.That (otool_exe, Does.Not.Contain ("GSS"));
Assert.That (otool_exe, Does.Contain ($"@rpath/{mono_native_dylib}"));
}
}
[Test]
public void TestDeviceFrameworkLinkOut ()
{
using (var mtouch = new MTouchTool ()) {
mtouch.CreateTemporaryApp ();
mtouch.Linker = LinkerOption.LinkAll;
mtouch.AssemblyBuildTargets.Add ("@all=framework");
mtouch.TargetVer = "10.0";
mtouch.AssertExecute (MTouchAction.BuildDev, "build");
var files = Directory.EnumerateFiles (mtouch.AppPath, "libmono-native*", SearchOption.AllDirectories).Select (Path.GetFileName);
Assert.That (files.Count, Is.EqualTo (0), "No libmono-native* library");
}
}
[Test]
public void TestGss ()
{
using (var mtouch = new MTouchTool ()) {
mtouch.CreateTemporaryApp (code: MonoNativeGss);
mtouch.Linker = LinkerOption.LinkAll;
mtouch.AssertExecute (MTouchAction.BuildSim, "build");
AssertStaticLinked (mtouch);
var symbols = mtouch.NativeSymbolsInExecutable;
Assert.That (symbols, Does.Contain ("_mono_native_initialize"));
Assert.That (symbols, Does.Contain ("_NetSecurityNative_ImportUserName"));
Implement a different escaping/quoting algorithm for arguments to System.Diagnostics.Process. (#7177) * Implement a different escaping/quoting algorithm for arguments to System.Diagnostics.Process. mono changed how quotes should be escaped when passed to System.Diagnostic.Process, so we need to change accordingly. The main difference is that single quotes don't have to be escaped anymore. This solves problems like this: System.ComponentModel.Win32Exception : ApplicationName='nuget', CommandLine='restore '/Users/vsts/agent/2.158.0/work/1/s/tests/sampletester/bin/Debug/repositories/ios-samples/WorkingWithTables/Part 3 - Customizing a Table\'s appearance/3 - CellCustomTable/CellCustomTable.sln' -Verbosity detailed -SolutionDir '/Users/vsts/agent/2.158.0/work/1/s/tests/sampletester/bin/Debug/repositories/ios-samples/WorkingWithTables/Part 3 - Customizing a Table\'s appearance/3 - CellCustomTable'', CurrentDirectory='/Users/vsts/agent/2.158.0/work/1/s/tests/sampletester/bin/Debug/repositories', Native error= Cannot find the specified file at System.Diagnostics.Process.StartWithCreateProcess (System.Diagnostics.ProcessStartInfo startInfo) [0x0029f] in /Users/builder/jenkins/workspace/build-package-osx-mono/2019-08/external/bockbuild/builds/mono-x64/mcs/class/System/System.Diagnostics/Process.cs:778 ref: https://github.com/mono/mono/pull/15047 * Rework process arguments to pass arrays/lists around instead of quoted strings. And then only convert to a string at the very end when we create the Process instance. In the future there will be a ProcessStartInfo.ArgumentList property we can use to give the original array/list of arguments directly to the BCL so that we can avoid quoting at all. These changes gets us almost all the way there already (except that the ArgumentList property isn't available quite yet). We also have to bump to target framework version v4.7.2 from v4.5 in several places because of 'Array.Empty<T> ()' which is now used in more places. * Parse linker flags from LinkWith attributes. * [sampletester] Bump to v4.7.2 for Array.Empty<T> (). * Fix typo. * Rename GetVerbosity -> AddVerbosity. * Remove unnecessary string interpolation. * Remove unused variable. * [mtouch] Simplify code a bit. * Use implicitly typed arrays.
2019-10-14 17:18:46 +03:00
var otool_exe = ExecutionHelper.Execute ("otool", new [] { "-L", mtouch.NativeExecutablePath }, hide_output: true);
Assert.That (otool_exe, Does.Contain ("/System/Library/Frameworks/GSS.framework/GSS"));
}
}
[Test]
public void TestGssTv ()
{
using (var mtouch = new MTouchTool ()) {
mtouch.Profile = Profile.tvOS;
mtouch.CreateTemporaryApp (code: MonoNativeGss);
mtouch.Linker = LinkerOption.LinkAll;
mtouch.AssertExecuteFailure (MTouchAction.BuildSim, "build");
mtouch.AssertError (5214, "Native linking failed, undefined symbol: _NetSecurityNative_ImportUserName. This symbol was referenced by the managed member X.NetSecurityNative_ImportUserName. Please verify that all the necessary frameworks have been referenced and native libraries linked.");
}
}
void AssertSymlinked (string path)
{
var files = Directory.EnumerateFiles (path, "libmono-native*", SearchOption.AllDirectories).Select (Path.GetFileName);
Assert.That (files.Count, Is.EqualTo (1), "One single libmono-native* library");
Assert.That (files.First (), Is.EqualTo ("libmono-native.dylib"), "Found libmono-native.dylib");
}
void AssertStaticLinked (MTouchTool app)
{
var files = Directory.EnumerateFiles (app.AppPath, "libmono-native*", SearchOption.AllDirectories).Select (Path.GetFileName);
Assert.That (files.Count, Is.EqualTo (0), "No libmono-native* libraries");
}
string MonoNativeWatchInitialize => @"
using WatchKit;
public partial class NotificationController : WKUserNotificationInterfaceController
{
protected NotificationController (System.IntPtr handle) : base (handle) { X.Main(); }
}
";
string MonoNativeInitialize => @"
class X {
[System.Runtime.InteropServices.DllImport (""System.Native"")]
extern static void mono_native_initialize ();
public static void Main ()
{
System.Console.WriteLine (typeof (ObjCRuntime.Runtime).ToString ());
mono_native_initialize ();
}
}
";
string MonoNativeGss => @"
using System;
class X {
[System.Runtime.InteropServices.DllImport (""System.Native"")]
extern static void mono_native_initialize ();
[System.Runtime.InteropServices.DllImport (""System.Net.Security.Native"")]
extern static void NetSecurityNative_ImportUserName (IntPtr a, IntPtr b, int c, IntPtr d);
static void Main ()
{
// Reference Xamarin.iOS
var runtime = typeof (ObjCRuntime.Runtime).ToString ();
// Always false, but the linker does not know that, so the following code won't be linked out.
if (runtime.Equals (""XXX"")) {
mono_native_initialize ();
NetSecurityNative_ImportUserName (IntPtr.Zero, IntPtr.Zero, 0, IntPtr.Zero);
}
}
}
";
}
}