2492 строки
95 KiB
C#
2492 строки
95 KiB
C#
using System;
|
|
using System.Linq;
|
|
using System.Collections.Generic;
|
|
using System.IO;
|
|
using System.Diagnostics;
|
|
using System.Text;
|
|
using System.Text.RegularExpressions;
|
|
using System.Xml;
|
|
|
|
using MTouchTests;
|
|
using Xamarin.Tests;
|
|
|
|
using NUnit.Framework;
|
|
|
|
namespace Xamarin.Tests {
|
|
static class TestTarget {
|
|
public static string ToolPath {
|
|
get {
|
|
return Path.Combine (Configuration.SdkBinDir, "mtouch");
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
namespace MTouchTests
|
|
{
|
|
[TestFixture]
|
|
public class MTouch
|
|
{
|
|
[Test]
|
|
[TestCase ("single", "-sdkroot {2} -v -v -v -v --dev {0} -sdk {3} --targetver 6.0 {1} -r:{4} --cache={5}/cache")]
|
|
[TestCase ("dual", "-sdkroot {2} -v -v -v -v --dev {0} -sdk {3} --targetver 6.0 {1} -r:{4} --cache={5}/cache --abi=armv7,arm64")]
|
|
[TestCase ("llvm", "-sdkroot {2} -v -v -v -v --dev {0} -sdk {3} --targetver 6.0 {1} -r:{4} --cache={5}/cache --abi=armv7+llvm")]
|
|
[TestCase ("debug", "-sdkroot {2} -v -v -v -v --dev {0} -sdk {3} --targetver 6.0 {1} -r:{4} --cache={5}/cache --debug")]
|
|
public void RebuildTest (string name, string format)
|
|
{
|
|
var testDir = GetTempDirectory ();
|
|
var app = Path.Combine (testDir, "testApp.app");
|
|
DateTime dt = DateTime.MinValue;
|
|
|
|
Action<string, IEnumerable<string>> checkNotModified = (filename, skip) => {
|
|
var failed = new List<string> ();
|
|
var files = Directory.EnumerateFiles (app, "*", SearchOption.AllDirectories);
|
|
foreach (var file in files) {
|
|
if (skip != null && skip.Contains (Path.GetFileName (file)))
|
|
continue;
|
|
var info = new FileInfo (file);
|
|
if (info.LastWriteTime > dt) {
|
|
failed.Add (string.Format ("{0} is modified, timestamp: {1}", file, info.LastWriteTime));
|
|
} else {
|
|
Console.WriteLine ("{0} not modified", file);
|
|
}
|
|
}
|
|
Assert.IsTrue (failed.Count == 0, filename + "\n" + string.Join ("\n", failed.ToArray ()));
|
|
};
|
|
|
|
Directory.CreateDirectory (app);
|
|
try {
|
|
var exe = CompileUnifiedTestAppExecutable (testDir);
|
|
var args = string.Format (format, app, exe, Configuration.xcode_root, Configuration.sdk_version, Configuration.XamarinIOSDll, testDir);
|
|
ExecutionHelper.Execute (TestTarget.ToolPath, args);
|
|
dt = DateTime.Now;
|
|
System.Threading.Thread.Sleep (1000); // make sure all new timestamps are at least a second older.
|
|
ExecutionHelper.Execute (TestTarget.ToolPath, args);
|
|
|
|
checkNotModified (name, null);
|
|
|
|
// Test that a rebuild (where something changed, in this case the .exe)
|
|
// actually work. We compile with custom code to make sure it's different
|
|
// from the previous exe we built.
|
|
var subDir = Path.Combine (testDir, "other");
|
|
Directory.CreateDirectory (subDir);
|
|
var exe2 = CompileUnifiedTestAppExecutable (subDir,
|
|
/* the code here only changes the class name (default: 'TestApp' changed to 'TestApp2') to minimize the related
|
|
* changes (there should be no changes in Xamarin.iOS.dll nor mscorlib.dll, even after linking) */
|
|
code: "public class TestApp2 { static void Main () { System.Console.WriteLine (typeof (ObjCRuntime.Runtime).ToString ()); } }");
|
|
File.Copy (exe2, exe, true);
|
|
ExecutionHelper.Execute (TestTarget.ToolPath, args);
|
|
|
|
var skip = new string [] { "testApp", "testApp.exe", "testApp.armv7.aotdata", "testApp.arm64.aotdata" };
|
|
checkNotModified (name + "-rebuilt", skip);
|
|
} finally {
|
|
Directory.Delete (testDir, true);
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
public void RebuildTest_Intl ()
|
|
{
|
|
using (var tool = new MTouchTool ()) {
|
|
tool.Profile = Profile.Unified;
|
|
tool.I18N = I18N.West;
|
|
tool.Verbosity = 5;
|
|
tool.Cache = Path.Combine (tool.CreateTemporaryDirectory (), "mtouch-test-cache");
|
|
tool.CreateTemporaryApp ();
|
|
|
|
Assert.AreEqual (0, tool.Execute (MTouchAction.BuildSim));
|
|
|
|
var pre_files = Directory.EnumerateFiles (tool.AppPath, "*", SearchOption.AllDirectories).ToArray ();
|
|
|
|
Directory.Delete (tool.AppPath, true);
|
|
Directory.CreateDirectory (tool.AppPath);
|
|
|
|
Assert.AreEqual (0, tool.Execute (MTouchAction.BuildSim));
|
|
|
|
var post_files = Directory.EnumerateFiles (tool.AppPath, "*", SearchOption.AllDirectories).ToArray ();
|
|
|
|
Assert.That (post_files, Is.EquivalentTo (pre_files), "files");
|
|
}
|
|
}
|
|
|
|
public enum Target { Sim, Dev }
|
|
public enum Config { Debug, Release }
|
|
public enum PackageMdb { Default, WithMdb, WoutMdb }
|
|
public enum MSym { Default, WithMSym, WoutMSym }
|
|
public enum Profile { Classic, Unified, TVOS, WatchOS }
|
|
|
|
[Test]
|
|
// Simulator
|
|
[TestCase (Target.Sim, Config.Release, PackageMdb.Default, MSym.Default, false, false, "")]
|
|
[TestCase (Target.Sim, Config.Debug, PackageMdb.Default, MSym.Default, true, false, "")]
|
|
[TestCase (Target.Sim, Config.Debug, PackageMdb.WoutMdb, MSym.Default, false, false, "")]
|
|
[TestCase (Target.Sim, Config.Release, PackageMdb.WithMdb, MSym.Default, true, false, "")]
|
|
[TestCase (Target.Sim, Config.Debug, PackageMdb.WoutMdb, MSym.Default, false, false, "--nofastsim --nolink")]
|
|
// Device
|
|
[TestCase (Target.Dev, Config.Release, PackageMdb.WithMdb, MSym.Default, true, false, "")]
|
|
[TestCase (Target.Dev, Config.Release, PackageMdb.WithMdb, MSym.WoutMSym, true, false, "")]
|
|
[TestCase (Target.Dev, Config.Release, PackageMdb.Default, MSym.Default, false, false, "--abi:armv7,arm64")]
|
|
[TestCase (Target.Dev, Config.Debug, PackageMdb.WoutMdb, MSym.Default, false, false, "")]
|
|
[TestCase (Target.Dev, Config.Debug, PackageMdb.WoutMdb, MSym.WithMSym, false, true, "")]
|
|
[TestCase (Target.Dev, Config.Release, PackageMdb.WithMdb, MSym.Default, true, false, "--abi:armv7+llvm")]
|
|
public void SymbolicationData (Target target, Config configuration, PackageMdb package_mdb, MSym msym, bool has_mdb, bool has_msym, string extra_mtouch_args)
|
|
{
|
|
var testDir = GetTempDirectory ();
|
|
var appDir = Path.Combine (testDir, "testApp.app");
|
|
Directory.CreateDirectory (appDir);
|
|
|
|
try {
|
|
var is_sim = target == Target.Sim;
|
|
var exe = CompileUnifiedTestAppExecutable (testDir);
|
|
var msymDir = appDir + ".msym";
|
|
var args = extra_mtouch_args;
|
|
|
|
args += is_sim ? " --sim {0} " : " --dev {0} ";
|
|
|
|
if (configuration == Config.Debug)
|
|
args += "--debug ";
|
|
|
|
if (package_mdb == PackageMdb.WithMdb)
|
|
args += "--package-mdb:true ";
|
|
else if (package_mdb == PackageMdb.WoutMdb)
|
|
args += "--package-mdb:false ";
|
|
|
|
if (msym == MSym.WithMSym)
|
|
args += "--msym:true ";
|
|
else if (msym == MSym.WoutMSym)
|
|
args += "--msym:false ";
|
|
|
|
args += " --sdkroot {2} -v -v -v -sdk {3} {1} -r:{4}";
|
|
|
|
ExecutionHelper.Execute (TestTarget.ToolPath, string.Format (args, appDir, exe, Configuration.xcode_root, Configuration.sdk_version, Configuration.XamarinIOSDll));
|
|
|
|
if (is_sim) {
|
|
Assert.AreEqual (has_mdb, File.Exists (Path.Combine (appDir, "mscorlib.dll.mdb")), "#mdb");
|
|
} else {
|
|
Assert.AreEqual (has_mdb, File.Exists (Path.Combine (appDir, ".monotouch-32", "mscorlib.dll.mdb")), "#mdb");
|
|
}
|
|
if (is_sim) {
|
|
Assert.AreEqual (has_msym, File.Exists (Path.Combine (msymDir, "mscorlib.dll.msym")), "#msym");
|
|
} else {
|
|
Assert.AreEqual (has_msym, File.Exists (Path.Combine (msymDir, "32", "mscorlib.dll.msym")), "#msym");
|
|
}
|
|
} finally {
|
|
Directory.Delete (testDir, true);
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
public void ExecutableName ()
|
|
{
|
|
var testDir = GetTempDirectory ();
|
|
var app = Path.Combine (testDir, "testApp.app");
|
|
Directory.CreateDirectory (app);
|
|
|
|
try {
|
|
var exe = CompileTestAppExecutable (testDir);
|
|
|
|
ExecutionHelper.Execute (TestTarget.ToolPath, string.Format ("-sdkroot " + Configuration.xcode_root + " --executable=CustomExecutable -v -v -v --nosign --nofastsim --nolink --sim {0} -sdk " + Configuration.sdk_version + " {1} -debug --fastdev", app, exe));
|
|
Assert.That (File.Exists (Path.Combine (app, "CustomExecutable")), "1");
|
|
Assert.That (!File.Exists (Path.Combine (app, "testApp")), "2");
|
|
} finally {
|
|
Directory.Delete (testDir, true);
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
public void MT0015 ()
|
|
{
|
|
Asserts.Throws<TestExecutionException> (() =>
|
|
ExecutionHelper.Execute (TestTarget.ToolPath, "--abi invalid-arm"),
|
|
"error MT0015: Invalid ABI: invalid-arm. Supported ABIs are: i386, x86_64, armv7, armv7+llvm, armv7+llvm+thumb2, armv7s, armv7s+llvm, armv7s+llvm+thumb2, armv7k, armv7k+llvm, arm64 and arm64+llvm.\n");
|
|
}
|
|
|
|
[Test]
|
|
public void MT0016 ()
|
|
{
|
|
var testDir = GetTempDirectory ();
|
|
var app = Path.Combine (testDir, "testApp.app");
|
|
Directory.CreateDirectory (app);
|
|
|
|
var deprecated_list = new string [] {
|
|
"-d={0}", "--dir={0}", "--cp", "--crossprefix", "--libdir", "-n", "--keeptemp",
|
|
"--main", "--nomanifest", "--mapinject", "--nosign", "--displayname", "--bundleid",
|
|
"--mainnib", "--icon", "-c", "--certificate", "--enable-background-fetch",
|
|
"--llvm", "--thumb", "--armv7", "--noregistrar", "--unsupported--enable-generics-in-registrar"
|
|
};
|
|
|
|
|
|
try {
|
|
var exe = CompileTestAppExecutable (testDir, profile: MTouch.Profile.Unified);
|
|
var args = string.Format (string.Join (" ", deprecated_list), app);
|
|
|
|
Asserts.ThrowsPattern<TestExecutionException> (() =>
|
|
ExecutionHelper.Execute (TestTarget.ToolPath, string.Format ("--sdkroot {5} --dev {0} {1} -r:{2} {3} --sdk {4}", app, exe, Configuration.XamarinIOSDll, args, Configuration.sdk_version, Configuration.xcode_root), hide_output: false),
|
|
"Xamarin.iOS .* using framework:.*\n" +
|
|
"error MT0016: The option '--dir' has been deprecated.\n" +
|
|
"error MT0016: The option '--dir' has been deprecated.\n" +
|
|
"error MT0016: The option '--crossprefix' has been deprecated.\n" +
|
|
"error MT0016: The option '--libdir' has been deprecated.\n" +
|
|
"error MT0016: The option '-n' has been deprecated.\n" +
|
|
"error MT0016: The option '--keeptemp' has been deprecated.\n" +
|
|
"error MT0016: The option '--main' has been deprecated.\n" +
|
|
"error MT0016: The option '--mapinject' has been deprecated.\n" +
|
|
"error MT0016: The option '--nosign' has been deprecated.\n" +
|
|
"error MT0016: The option '--displayname' has been deprecated.\n" +
|
|
"error MT0016: The option '--mainnib' has been deprecated.\n" +
|
|
"error MT0016: The option '--certificate' has been deprecated.\n" +
|
|
"error MT0016: The option '--llvm' has been deprecated.\n" +
|
|
"error MT0016: The option '--thumb' has been deprecated.\n" +
|
|
"error MT0016: The option '--armv7' has been deprecated.\n" +
|
|
"error MT0016: The option '--noregistrar' has been deprecated.\n" +
|
|
"error MT0016: The option '--unsupported--enable-generics-in-registrar' has been deprecated.\n");
|
|
|
|
|
|
exe = CompileTestAppExecutable (testDir);
|
|
Asserts.ThrowsPattern<TestExecutionException> (() =>
|
|
ExecutionHelper.Execute (TestTarget.ToolPath, string.Format ("--sdkroot {5} --dev {0} {1} -r:{2} {3} --sdk {4}", app, exe, Configuration.MonoTouchDll, args, Configuration.sdk_version, Configuration.xcode_root), hide_output: false),
|
|
"Xamarin.iOS .* using framework:.*\n" +
|
|
"warning MT0016: The option '--dir' has been deprecated.\n" +
|
|
"warning MT0016: The option '--dir' has been deprecated.\n" +
|
|
"warning MT0016: The option '--crossprefix' has been deprecated.\n" +
|
|
"warning MT0016: The option '--libdir' has been deprecated.\n" +
|
|
"warning MT0016: The option '-n' has been deprecated.\n" +
|
|
"warning MT0016: The option '--keeptemp' has been deprecated.\n" +
|
|
"warning MT0016: The option '--main' has been deprecated.\n" +
|
|
"warning MT0016: The option '--mapinject' has been deprecated.\n" +
|
|
"warning MT0016: The option '--displayname' has been deprecated.\n" +
|
|
"warning MT0016: The option '--mainnib' has been deprecated.\n" +
|
|
"warning MT0016: The option '--certificate' has been deprecated.\n" +
|
|
"warning MT0016: The option '--llvm' has been deprecated.\n" +
|
|
"warning MT0016: The option '--thumb' has been deprecated.\n" +
|
|
"warning MT0016: The option '--armv7' has been deprecated.\n" +
|
|
"warning MT0016: The option '--noregistrar' has been deprecated.\n" +
|
|
"warning MT0016: The option '--unsupported--enable-generics-in-registrar' has been deprecated.\n" +
|
|
"error MT0022: The options '--unsupported--enable-generics-in-registrar' and '--registrar' are not compatible.\n"
|
|
);
|
|
|
|
|
|
} finally {
|
|
Directory.Delete (testDir, true);
|
|
}
|
|
|
|
}
|
|
|
|
[Test]
|
|
[TestCase (Profile.Classic, Profile.Unified)]
|
|
[TestCase (Profile.Classic, Profile.TVOS)]
|
|
[TestCase (Profile.Classic, Profile.WatchOS)]
|
|
[TestCase (Profile.Unified, Profile.Classic)]
|
|
[TestCase (Profile.Unified, Profile.TVOS)]
|
|
[TestCase (Profile.Unified, Profile.WatchOS)]
|
|
[TestCase (Profile.TVOS, Profile.Classic)]
|
|
[TestCase (Profile.TVOS, Profile.Unified)]
|
|
[TestCase (Profile.TVOS, Profile.WatchOS)]
|
|
[TestCase (Profile.WatchOS, Profile.Classic)]
|
|
[TestCase (Profile.WatchOS, Profile.Unified)]
|
|
[TestCase (Profile.WatchOS, Profile.TVOS)]
|
|
public void MT0041 (Profile profile, Profile other)
|
|
{
|
|
using (var mtouch = new MTouchTool ()) {
|
|
mtouch.Profile = profile;
|
|
mtouch.CreateTemporaryApp ();
|
|
mtouch.References = new string [] {
|
|
GetBaseLibrary (profile),
|
|
GetBaseLibrary (other),
|
|
};
|
|
Assert.AreEqual (1, mtouch.Execute (MTouchAction.BuildSim));
|
|
mtouch.AssertError (41, string.Format ("Cannot reference '{0}' in a {1} app.", Path.GetFileName (GetBaseLibrary (other)), GetPlatformName (profile)));
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
public void MT0042 ()
|
|
{
|
|
using (var mtouch = new MTouchTool ()) {
|
|
mtouch.CreateTemporaryApp ();
|
|
Assert.AreEqual (0, mtouch.Execute (MTouchAction.BuildSim));
|
|
mtouch.AssertError (42, "No reference to either monotouch.dll or Xamarin.iOS.dll was found. A reference to monotouch.dll will be added.");
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
public void MT0073 ()
|
|
{
|
|
var testDir = GetTempDirectory ();
|
|
var app = Path.Combine (testDir, "testApp.app");
|
|
Directory.CreateDirectory (app);
|
|
|
|
try {
|
|
var exe = CompileTestAppExecutable (testDir, profile: MTouch.Profile.Unified);
|
|
|
|
Asserts.ThrowsPattern<TestExecutionException> (() =>
|
|
ExecutionHelper.Execute (TestTarget.ToolPath, string.Format ("-sdkroot " + Configuration.xcode_root + " --dev {0} -sdk " + Configuration.sdk_version + " --targetver 3.1 --abi=armv7s,arm64 {1} -debug -r:" + Configuration.XamarinIOSDll, app, exe)),
|
|
"Xamarin.iOS .* using framework:.*\nerror MT0073: Xamarin.iOS .* does not support a deployment target of 3.1 for iOS .the minimum is 5.1.1.. Please select a newer deployment target in your project's Info.plist.\n");
|
|
|
|
Asserts.ThrowsPattern<TestExecutionException> (() =>
|
|
ExecutionHelper.Execute (TestTarget.ToolPath, string.Format ("-sdkroot " + Configuration.xcode_root + " --dev {0} -sdk " + Configuration.sdk_version + " --targetver 3.1 --abi=armv7s {1} -debug -r:" + Configuration.XamarinIOSDll, app, exe)),
|
|
"Xamarin.iOS .* using framework:.*\nerror MT0073: Xamarin.iOS .* does not support a deployment target of 3.1 for iOS .the minimum is 5.1.1.. Please select a newer deployment target in your project's Info.plist.\n");
|
|
|
|
Asserts.ThrowsPattern<TestExecutionException> (() =>
|
|
ExecutionHelper.Execute (TestTarget.ToolPath, string.Format ("-sdkroot " + Configuration.xcode_root + " --dev {0} -sdk " + Configuration.sdk_version + " --targetver 5.1 --abi=arm64 {1} -debug -r:" + Configuration.XamarinIOSDll, app, exe)),
|
|
"Xamarin.iOS .* using framework:.*\nerror MT0073: Xamarin.iOS .* does not support a deployment target of 5.1 for iOS .the minimum is 5.1.1.. Please select a newer deployment target in your project's Info.plist.\n");
|
|
|
|
// No exception here.
|
|
ExecutionHelper.Execute (TestTarget.ToolPath, string.Format ("-sdkroot " + Configuration.xcode_root + " --dev {0} -sdk " + Configuration.sdk_version + " --targetver 5.1.1 --abi=arm64 {1} -debug -r:" + Configuration.XamarinIOSDll, app, exe));
|
|
|
|
} finally {
|
|
Directory.Delete (testDir, true);
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
public void MT0074 ()
|
|
{
|
|
var testDir = GetTempDirectory ();
|
|
var app = Path.Combine (testDir, "testApp.app");
|
|
Directory.CreateDirectory (app);
|
|
|
|
try {
|
|
var exe = CompileTestAppExecutable (testDir, profile: MTouch.Profile.Unified);
|
|
|
|
Asserts.ThrowsPattern<TestExecutionException> (() =>
|
|
ExecutionHelper.Execute (TestTarget.ToolPath, string.Format ("-sdkroot " + Configuration.xcode_root + " --dev {0} -sdk " + Configuration.sdk_version + " --targetver 400.0.0 --abi=armv7s,arm64 {1} -debug -r:" + Configuration.XamarinIOSDll, app, exe)),
|
|
string.Format ("Xamarin.iOS .* using framework:.*\nerror MT0074: Xamarin.iOS .* does not support a deployment target of 400.0.0 for iOS .the maximum is " + Configuration.sdk_version + ".. Please select an older deployment target in your project's Info.plist or upgrade to a newer version of Xamarin.iOS.\n", Configuration.sdk_version));
|
|
} finally {
|
|
Directory.Delete (testDir, true);
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
public void MT0048 ()
|
|
{
|
|
var testDir = GetTempDirectory ();
|
|
var app = Path.Combine (testDir, "testApp.app");
|
|
Directory.CreateDirectory (app);
|
|
|
|
try {
|
|
var exe = CompileTestAppExecutable (testDir, profile: MTouch.Profile.Unified);
|
|
|
|
Asserts.ThrowsPattern<TestExecutionException> (() => ExecutionHelper.Execute (TestTarget.ToolPath, string.Format ("-sdkroot " + Configuration.xcode_root + " --dev {0} -sdk " + Configuration.sdk_version + " --targetver 5.1.1 --abi=armv7s {1} -debug -r:{2} --crashreporting-api-key APIKEY", app, exe, Configuration.XamarinIOSDll), hide_output: false),
|
|
"error MT0016: The option '--crashreporting-api-key' has been deprecated.");
|
|
} finally {
|
|
Directory.Delete (testDir, true);
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
[TestCase (Profile.Classic, Profile.Unified)]
|
|
[TestCase (Profile.Classic, Profile.TVOS)]
|
|
[TestCase (Profile.Classic, Profile.WatchOS)]
|
|
[TestCase (Profile.Unified, Profile.Classic)]
|
|
[TestCase (Profile.Unified, Profile.TVOS)]
|
|
[TestCase (Profile.Unified, Profile.WatchOS)]
|
|
[TestCase (Profile.TVOS, Profile.Classic)]
|
|
[TestCase (Profile.TVOS, Profile.Unified)]
|
|
[TestCase (Profile.TVOS, Profile.WatchOS)]
|
|
[TestCase (Profile.WatchOS, Profile.Classic)]
|
|
[TestCase (Profile.WatchOS, Profile.Unified)]
|
|
[TestCase (Profile.WatchOS, Profile.TVOS)]
|
|
public void MT0034 (Profile exe_profile, Profile dll_profile)
|
|
{
|
|
using (var mtouch = new MTouchTool ()) {
|
|
var app = mtouch.CreateTemporaryAppDirectory ();
|
|
var testDir = Path.GetDirectoryName (app);
|
|
|
|
string exe = Path.Combine (testDir, "testApp.exe");
|
|
string dll = Path.Combine (testDir, "testLib.dll");
|
|
|
|
var dllCode = @"public class TestLib {
|
|
public TestLib ()
|
|
{
|
|
System.Console.WriteLine (typeof (%PROFILE_NAMESPACE%Foundation.NSObject).ToString ());
|
|
}
|
|
}";
|
|
|
|
var exeCode = @"public class TestApp {
|
|
static void Main ()
|
|
{
|
|
System.Console.WriteLine (typeof (%PROFILE_NAMESPACE%Foundation.NSObject).ToString ());
|
|
System.Console.WriteLine (new TestLib ());
|
|
}
|
|
}";
|
|
|
|
CompileCSharpCode (dll_profile, dllCode, dll);
|
|
CompileCSharpCode (exe_profile, exeCode, exe, "-r:" + dll);
|
|
|
|
mtouch.Profile = exe_profile;
|
|
mtouch.Executable = exe;
|
|
mtouch.References = new string [] { GetBaseLibrary (exe_profile) };
|
|
Assert.AreEqual (1, mtouch.Execute (MTouchAction.BuildSim), "build");
|
|
var dllBase = Path.GetFileName (GetBaseLibrary (dll_profile));
|
|
mtouch.AssertError (34, string.Format ("Cannot reference '{0}' in a {1} project - it is implicitly referenced by 'testLib, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null'.", dllBase, GetPlatformName (exe_profile)));
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
public void MT0037 ()
|
|
{
|
|
var testDir = GetTempDirectory ();
|
|
var app = Path.Combine (testDir, "testApp.app");
|
|
Directory.CreateDirectory (app);
|
|
|
|
try {
|
|
var exe = CompileTestAppExecutable (testDir);
|
|
|
|
Asserts.ThrowsPattern<TestExecutionException> (() =>
|
|
ExecutionHelper.Execute (TestTarget.ToolPath, string.Format ("-sdkroot " + Configuration.xcode_root + " --nosign --dev {0} -sdk " + Configuration.sdk_version + " --targetver 3.1 --abi=arm64 {1} -debug -r:{2}", app, exe, Configuration.MonoTouchDll)),
|
|
"Xamarin.iOS .* using framework:.*\nerror MT0037: monotouch.dll is not 64-bit compatible. Either reference Xamarin.iOS.dll, or do not build for a 64-bit architecture [(]ARM64 or x86_64[)].\n");
|
|
|
|
Asserts.ThrowsPattern<TestExecutionException> (() =>
|
|
ExecutionHelper.Execute (TestTarget.ToolPath, string.Format ("-sdkroot " + Configuration.xcode_root + " --nosign --dev {0} -sdk " + Configuration.sdk_version + " --targetver 3.1 --abi=x86_64 {1} -debug -r:{2}", app, exe, Configuration.MonoTouchDll)),
|
|
"Xamarin.iOS .* using framework:.*\nerror MT0037: monotouch.dll is not 64-bit compatible. Either reference Xamarin.iOS.dll, or do not build for a 64-bit architecture [(]ARM64 or x86_64[)].\n");
|
|
} finally {
|
|
Directory.Delete (testDir, true);
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
public void MT0038 ()
|
|
{
|
|
var testDir = GetTempDirectory ();
|
|
var app = Path.Combine (testDir, "testApp.app");
|
|
Directory.CreateDirectory (app);
|
|
|
|
try {
|
|
var exe = CompileTestAppExecutable (testDir, profile: MTouch.Profile.Unified);
|
|
|
|
Asserts.ThrowsPattern<TestExecutionException> (() =>
|
|
ExecutionHelper.Execute (TestTarget.ToolPath, string.Format ("-sdkroot " + Configuration.xcode_root + " --dev {0} -sdk " + Configuration.sdk_version + " --registrar:oldstatic --targetver 5.1.1 --abi=arm64 {1} -debug -r:{2} ", app, exe, Configuration.XamarinIOSDll)),
|
|
"Xamarin.iOS .* using framework:.*\nerror MT0038: The legacy registrars [(]--registrar:legacy|legacystatic|legacydynamic[)] are not supported with the Unified API.\n");
|
|
|
|
Asserts.ThrowsPattern<TestExecutionException> (() =>
|
|
ExecutionHelper.Execute (TestTarget.ToolPath, string.Format ("-sdkroot " + Configuration.xcode_root + " --sim {0} -sdk " + Configuration.sdk_version + " --registrar:olddynamic --targetver 5.1.1 --abi=x86_64 {1} -debug -r:{2}", app, exe, Configuration.XamarinIOSDll)),
|
|
"Xamarin.iOS .* using framework:.*\nerror MT0038: The legacy registrars [(]--registrar:legacy|legacystatic|legacydynamic[)] are not supported with the Unified API.\n");
|
|
|
|
Asserts.ThrowsPattern<TestExecutionException> (() =>
|
|
ExecutionHelper.Execute (TestTarget.ToolPath, string.Format ("-sdkroot " + Configuration.xcode_root + " --sim {0} -sdk " + Configuration.sdk_version + " --registrar:legacy --targetver 5.1.1 --abi=x86_64 {1} -debug -r:{2}", app, exe, Configuration.XamarinIOSDll)),
|
|
"Xamarin.iOS .* using framework:.*\nerror MT0038: The legacy registrars [(]--registrar:legacy|legacystatic|legacydynamic[)] are not supported with the Unified API.\n");
|
|
|
|
Asserts.ThrowsPattern<TestExecutionException> (() =>
|
|
ExecutionHelper.Execute (TestTarget.ToolPath, string.Format ("-sdkroot " + Configuration.xcode_root + " --sim {0} -sdk " + Configuration.sdk_version + " --registrar:legacystatic --targetver 5.1.1 --abi=x86_64 {1} -debug -r:{2}", app, exe, Configuration.XamarinIOSDll)),
|
|
"Xamarin.iOS .* using framework:.*\nerror MT0038: The legacy registrars [(]--registrar:legacy|legacystatic|legacydynamic[)] are not supported with the Unified API.\n");
|
|
|
|
Asserts.ThrowsPattern<TestExecutionException> (() =>
|
|
ExecutionHelper.Execute (TestTarget.ToolPath, string.Format ("-sdkroot " + Configuration.xcode_root + " --sim {0} -sdk " + Configuration.sdk_version + " --registrar:legacydynamic --targetver 5.1.1 --abi=x86_64 {1} -debug -r:{2}", app, exe, Configuration.XamarinIOSDll)),
|
|
"Xamarin.iOS .* using framework:.*\nerror MT0038: The legacy registrars [(]--registrar:legacy|legacystatic|legacydynamic[)] are not supported with the Unified API.\n");
|
|
} finally {
|
|
Directory.Delete (testDir, true);
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
public void MT0051 ()
|
|
{
|
|
if (Directory.Exists ("/Applications/Xcode44.app/Contents/Developer")) {
|
|
Asserts.ThrowsPattern<TestExecutionException> (() => {
|
|
ExecutionHelper.Execute (TestTarget.ToolPath, "-sdkroot /Applications/Xcode44.app/Contents/Developer -sim /tmp/foo");
|
|
}, "error MT0051: Xamarin.iOS .* requires Xcode 6.0 or later. The current Xcode version [(]found in /Applications/Xcode44.app/Contents/Developer[)] is 4.*");
|
|
}
|
|
|
|
if (Directory.Exists (Configuration.xcode5_root)) {
|
|
Asserts.ThrowsPattern<TestExecutionException> (() => {
|
|
ExecutionHelper.Execute (TestTarget.ToolPath, "-sdkroot /Applications/Xcode511.app/Contents/Developer -sim /tmp/foo");
|
|
}, "error MT0051: Xamarin.iOS .* requires Xcode 6.0 or later. The current Xcode version [(]found in " + Configuration.xcode5_root + "[)] is 5.1.1");
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
public void MT0055 ()
|
|
{
|
|
Asserts.ThrowsPattern<TestExecutionException> (() => {
|
|
ExecutionHelper.Execute (TestTarget.ToolPath, "--sdkroot /dir/that/does/not/exist");
|
|
}, "error MT0055: The Xcode path '/dir/that/does/not/exist' does not exist.");
|
|
}
|
|
|
|
[Test]
|
|
public void MT0060 ()
|
|
{
|
|
var msg = string.Empty;
|
|
if (!Directory.Exists ("/Applications/Xcode.app")) {
|
|
msg = "warning MT0060: Could not find the currently selected Xcode on the system. 'xcode-select --print-path' returned '/dir/that/does/not/exist', but that directory does not exist.\n" +
|
|
"error MT0056: Cannot find Xcode in the default location ./Applications/Xcode.app.. Please install Xcode, or pass a custom path using --sdkroot <path>.\n";
|
|
} else {
|
|
msg = "warning MT0060: Could not find the currently selected Xcode on the system. 'xcode-select --print-path' returned '/dir/that/does/not/exist', but that directory does not exist.\n" +
|
|
"warning MT0062: No Xcode.app specified .using --sdkroot or 'xcode-select --print-path'., using the default Xcode instead: /Applications/Xcode.app\n" +
|
|
"Xamarin.iOS .* using framework: .*\n" +
|
|
"error MT0052: No command specified.";
|
|
}
|
|
|
|
Asserts.ThrowsPattern<TestExecutionException> (() => {
|
|
var envvars = new Dictionary<string, string>
|
|
{
|
|
{ "DEVELOPER_DIR", "/dir/that/does/not/exist" }
|
|
};
|
|
ExecutionHelper.Execute (TestTarget.ToolPath, "", environmentVariables: envvars);
|
|
}, msg);
|
|
}
|
|
|
|
[Test]
|
|
public void MT0061 ()
|
|
{
|
|
// The MT0070 warning depends on system configuration, so it's optional in the regexp
|
|
Asserts.ThrowsPattern<TestExecutionException> (() => {
|
|
ExecutionHelper.Execute (TestTarget.ToolPath, "");
|
|
}, "warning MT0061: No Xcode.app specified .using --sdkroot., using the system Xcode as reported by 'xcode-select --print-path': .*\n" +
|
|
"(warning MT0078: The recommended Xcode version for Xamarin.iOS [0-9.]* is Xcode [0-9.]* or later. The current Xcode version .found in .* is .*)?\\s?" +
|
|
"Xamarin.iOS .* using framework: .*\n" +
|
|
"error MT0052: No command specified.");
|
|
}
|
|
|
|
public void MT0062 ()
|
|
{
|
|
var testDir = GetTempDirectory ();
|
|
var app = Path.Combine (testDir, "testApp.app");
|
|
Directory.CreateDirectory (app);
|
|
|
|
try {
|
|
var exe = CompileUnifiedTestAppExecutable (testDir);
|
|
|
|
Asserts.ThrowsPattern<TestExecutionException> (() =>
|
|
ExecutionHelper.Execute (TestTarget.ToolPath, string.Format ("-sdkroot {3} --sim {0} -sdk {4} --targetver 7.1 --framework /foo/bar/zap.framework -r:{2} {1}", app, exe, Configuration.XamarinIOSDll, Configuration.xcode_root, Configuration.sdk_version), hide_output: false),
|
|
"Xamarin.iOS .* using framework:.*\nerror MT0062: Xamarin.iOS only supports embedded frameworks when deployment target is at least 8.0 .current deployment target: '7.1'; embedded frameworks: '/foo/bar/zap.framework'.\n");
|
|
|
|
Asserts.ThrowsPattern<TestExecutionException> (() =>
|
|
ExecutionHelper.Execute (TestTarget.ToolPath, string.Format ("-sdkroot {3} --sim {0} -sdk {4} --targetver 7.1 --mono:framework -r:{2} {1}", app, exe, Configuration.XamarinIOSDll, Configuration.xcode_root, Configuration.sdk_version), hide_output: false),
|
|
"Xamarin.iOS .* using framework:.*\nerror MT0062: Xamarin.iOS only supports embedded frameworks when deployment target is at least 8.0 .current deployment target: '7.1'; embedded frameworks: '.*/Mono.framework'.\n");
|
|
} finally {
|
|
Directory.Delete (testDir, true);
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
public void MT0064 ()
|
|
{
|
|
var testDir = GetTempDirectory ();
|
|
var app = Path.Combine (testDir, "testApp.app");
|
|
Directory.CreateDirectory (app);
|
|
|
|
try {
|
|
var exe = CompileTestAppExecutable (testDir);
|
|
|
|
Asserts.ThrowsPattern<TestExecutionException> (() =>
|
|
ExecutionHelper.Execute (TestTarget.ToolPath, string.Format ("-sdkroot {3} --nosign --sim {0} -sdk {4} --targetver {4} --framework /foo/bar/zap.framework -r:{2} {1}", app, exe, Configuration.MonoTouchDll, Configuration.xcode_root, Configuration.sdk_version), hide_output: false),
|
|
"Xamarin.iOS .* using framework:.*\nerror MT0064: Xamarin.iOS only supports embedded frameworks with Unified projects.\n");
|
|
} finally {
|
|
Directory.Delete (testDir, true);
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
public void MT0075 ()
|
|
{
|
|
var testDir = GetTempDirectory ();
|
|
var app = Path.Combine (testDir, "testApp.app");
|
|
Directory.CreateDirectory (app);
|
|
|
|
try {
|
|
var exe = CompileTestAppExecutable (testDir);
|
|
|
|
Asserts.ThrowsPattern<TestExecutionException> (() =>
|
|
ExecutionHelper.Execute (TestTarget.ToolPath, string.Format ("-sdkroot {3} --nosign --dev {0} -sdk {4} -r:{2} {1} --abi armv7k", app, exe, Configuration.MonoTouchDll, Configuration.xcode_root, Configuration.sdk_version), hide_output: false),
|
|
"Xamarin.iOS .* using framework:.*\n" +
|
|
"error MT0075: Invalid architecture 'ARMv7k' for iOS projects. Valid architectures are: ARMv7, ARMv7.Thumb, ARMv7.LLVM, ARMv7.LLVM.Thumb, ARMv7s, ARMv7s.Thumb, ARMv7s.LLVM, ARMv7s.LLVM.Thumb");
|
|
} finally {
|
|
Directory.Delete (testDir, true);
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
public void MT0076 ()
|
|
{
|
|
if (!Configuration.include_watchos || !Configuration.include_tvos)
|
|
Assert.Ignore ("This test requires WatchOS and TVOS to be enabled.");
|
|
|
|
var testDir = GetTempDirectory ();
|
|
var app = Path.Combine (testDir, "testApp.app");
|
|
Directory.CreateDirectory (app);
|
|
|
|
try {
|
|
var exe = CompileTestAppExecutable (testDir, profile: MTouch.Profile.WatchOS);
|
|
|
|
Asserts.ThrowsPattern<TestExecutionException> (() =>
|
|
ExecutionHelper.Execute (TestTarget.ToolPath, string.Format ("-sdkroot {3} --nosign --dev {0} -sdk {4} -r:{2} {1} --target-framework Xamarin.WatchOS,v1.0", app, exe, Configuration.XamarinWatchOSDll, Configuration.xcode_root, Configuration.watchos_sdk_version), hide_output: false),
|
|
"error MT0076: No architecture specified .using the --abi argument.. An architecture is required for Xamarin.WatchOS projects.");
|
|
|
|
exe = CompileTestAppExecutable (testDir, profile: MTouch.Profile.TVOS);
|
|
|
|
Asserts.ThrowsPattern<TestExecutionException> (() =>
|
|
ExecutionHelper.Execute (TestTarget.ToolPath, string.Format ("-sdkroot {3} --nosign --dev {0} -sdk {4} -r:{2} {1} --target-framework Xamarin.TVOS,v1.0", app, exe, Configuration.XamarinTVOSDll, Configuration.xcode_root, Configuration.tvos_sdk_version), hide_output: false),
|
|
"error MT0076: No architecture specified .using the --abi argument.. An architecture is required for Xamarin.TVOS projects.");
|
|
} finally {
|
|
Directory.Delete (testDir, true);
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
public void MT0077 ()
|
|
{
|
|
if (!Configuration.include_watchos)
|
|
Assert.Ignore ("This test requires WatchOS and TVOS to be enabled.");
|
|
|
|
var testDir = GetTempDirectory ();
|
|
var app = Path.Combine (testDir, "testApp.app");
|
|
Directory.CreateDirectory (app);
|
|
|
|
try {
|
|
var exe = CompileTestAppExecutable (testDir, profile: MTouch.Profile.WatchOS);
|
|
|
|
Asserts.ThrowsPattern<TestExecutionException> (() =>
|
|
ExecutionHelper.Execute (TestTarget.ToolPath, string.Format ("-sdkroot {3} --nosign --dev {0} -sdk {4} -r:{2} {1} --target-framework Xamarin.WatchOS,v1.0 --abi armv7k", app, exe, Configuration.XamarinWatchOSDll, Configuration.xcode_root, Configuration.watchos_sdk_version), hide_output: false),
|
|
"error MT0077: WatchOS projects must be extensions.");
|
|
} finally {
|
|
Directory.Delete (testDir, true);
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
[TestCase (Profile.TVOS)]
|
|
//[TestCase (Profile.WatchOS)] MT0077 interferring.
|
|
[TestCase (Profile.Unified)]
|
|
[TestCase (Profile.Classic)]
|
|
public void MT0085 (Profile profile)
|
|
{
|
|
using (var mtouch = new MTouchTool ()) {
|
|
mtouch.Profile = profile;
|
|
mtouch.CreateTemporaryApp ();
|
|
mtouch.TargetFramework = GetTargetFramework (profile);
|
|
Assert.AreEqual (0, mtouch.Execute (MTouchAction.BuildSim));
|
|
mtouch.AssertError (85, string.Format ("No reference to '{0}' was found. It will be added automatically.", Path.GetFileName (GetBaseLibrary (profile))));
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
[TestCase (Profile.TVOS)]
|
|
[TestCase (Profile.WatchOS)]
|
|
public void MT0086 (Profile profile)
|
|
{
|
|
using (var mtouch = new MTouchTool ()) {
|
|
mtouch.CreateTemporaryApp ();
|
|
mtouch.References = new string [] { GetBaseLibrary (profile) };
|
|
Assert.AreEqual (1, mtouch.Execute (MTouchAction.BuildSim));
|
|
mtouch.AssertError (86, "A target framework (--target-framework) must be specified when building for TVOS or WatchOS.");
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
[TestCase (Profile.TVOS, "tvOS")]
|
|
[TestCase (Profile.Unified, "iOS")]
|
|
[TestCase (Profile.Classic, "iOS")]
|
|
public void MT0091 (Profile profile, string name)
|
|
{
|
|
// Any old Xcode would do.
|
|
if (!Directory.Exists (Configuration.xcode72_root))
|
|
Assert.Ignore ("This test needs Xcode 7.0");
|
|
|
|
using (var mtouch = new MTouchTool ()) {
|
|
mtouch.Profile = profile;
|
|
mtouch.CreateTemporaryApp ();
|
|
mtouch.SdkRoot = Configuration.xcode72_root;
|
|
mtouch.Linker = MTouchLinker.DontLink;
|
|
mtouch.Sdk = "9.0";
|
|
Assert.AreEqual (1, mtouch.Execute (MTouchAction.BuildSim));
|
|
mtouch.AssertError (91, String.Format ("This version of Xamarin.iOS requires the {0} {1} SDK (shipped with Xcode {2}) when the managed linker is disabled. Either upgrade Xcode, or enable the managed linker.", name, GetSdkVersion (profile), Configuration.XcodeVersion));
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
public void ExtensionBuild ()
|
|
{
|
|
var testDir = GetTempDirectory ();
|
|
var app = Path.Combine (testDir, "testApp.app");
|
|
Directory.CreateDirectory (app);
|
|
|
|
try {
|
|
var exe = CompileTestAppExecutable (testDir);
|
|
File.WriteAllText (Path.Combine (app, "Info.plist"), @"<?xml version=""1.0"" encoding=""UTF-8""?>
|
|
<!DOCTYPE plist PUBLIC ""-//Apple//DTD PLIST 1.0//EN"" ""http://www.apple.com/DTDs/PropertyList-1.0.dtd"">
|
|
<plist version=""1.0"">
|
|
<dict>
|
|
<key>CFBundleDisplayName</key>
|
|
<string>Extensiontest</string>
|
|
<key>CFBundleIdentifier</key>
|
|
<string>com.xamarin.extensiontest</string>
|
|
<key>MinimumOSVersion</key>
|
|
<string>5.1.1</string>
|
|
<key>UIDeviceFamily</key>
|
|
<array>
|
|
<integer>1</integer>
|
|
<integer>2</integer>
|
|
</array>
|
|
<key>UISupportedInterfaceOrientations</key>
|
|
<array>
|
|
<string>UIInterfaceOrientationPortrait</string>
|
|
<string>UIInterfaceOrientationPortraitUpsideDown</string>
|
|
<string>UIInterfaceOrientationLandscapeLeft</string>
|
|
<string>UIInterfaceOrientationLandscapeRight</string>
|
|
</array>
|
|
</dict>
|
|
</plist>
|
|
");
|
|
ExecutionHelper.Execute (TestTarget.ToolPath, string.Format ("-sdkroot " + Configuration.xcode_root + " --nosign --sim {0} -sdk {3} --targetver {3} --extension -r:{2} {1}", app, exe, Configuration.MonoTouchDll, Configuration.sdk_version), hide_output: false);
|
|
ExecutionHelper.Execute (TestTarget.ToolPath, string.Format ("-sdkroot " + Configuration.xcode_root + " --nosign --dev {0} -sdk {3} --targetver {3} --extension -r:{2} {1}", app, exe, Configuration.MonoTouchDll, Configuration.sdk_version), hide_output: false);
|
|
} finally {
|
|
Directory.Delete (testDir, true);
|
|
}
|
|
}
|
|
|
|
static string BindingsLibrary {
|
|
get {
|
|
return Path.Combine (Configuration.SourceRoot, "tests/bindings-test/bin/Debug/bindings-test.dll");
|
|
}
|
|
}
|
|
|
|
static string GetBindingsLibrary (Profile profile)
|
|
{
|
|
string fn;
|
|
|
|
if (profile == Profile.Classic) {
|
|
fn = Path.Combine (Configuration.SourceRoot, "tests", "bindings-test", "bin", GetConfiguration (profile), "bindings-test.dll");
|
|
} else {
|
|
fn = Path.Combine (Configuration.SourceRoot, "tests", "bindings-test", "bin", "Any CPU", GetConfiguration (profile), "bindings-test.dll");
|
|
}
|
|
|
|
if (!File.Exists (fn)) {
|
|
var csproj = Path.Combine (Configuration.SourceRoot, "tests", "bindings-test", "bindings-test" + GetProjectSuffix (profile) + ".csproj");
|
|
XBuild.Build (csproj, platform: "AnyCPU");
|
|
}
|
|
|
|
return fn;
|
|
}
|
|
|
|
public static string GetBaseLibrary (Profile profile)
|
|
{
|
|
switch (profile) {
|
|
case Profile.Classic:
|
|
return Configuration.MonoTouchDll;
|
|
case Profile.Unified:
|
|
return Configuration.XamarinIOSDll;
|
|
case Profile.TVOS:
|
|
return Configuration.XamarinTVOSDll;
|
|
case Profile.WatchOS:
|
|
return Configuration.XamarinWatchOSDll;
|
|
default:
|
|
throw new NotImplementedException ();
|
|
}
|
|
}
|
|
|
|
public static string GetCompiler (Profile profile, StringBuilder args)
|
|
{
|
|
args.Append (" -lib:").Append (Path.GetDirectoryName (GetBaseLibrary (profile))).Append (' ');
|
|
return "/Library/Frameworks/Mono.framework/Commands/mcs";
|
|
}
|
|
|
|
static string GetConfiguration (Profile profile)
|
|
{
|
|
switch (profile) {
|
|
case Profile.Classic:
|
|
return "Debug";
|
|
case Profile.Unified:
|
|
return "Debug-unified";
|
|
case Profile.TVOS:
|
|
return "Debug-tvos";
|
|
case Profile.WatchOS:
|
|
return "Debug-watchos";
|
|
default:
|
|
throw new NotImplementedException ();
|
|
}
|
|
}
|
|
|
|
public static string GetTargetFramework (Profile profile)
|
|
{
|
|
switch (profile) {
|
|
case Profile.Classic:
|
|
return "MonoTouch,v1.0";
|
|
case Profile.Unified:
|
|
return "Xamarin.iOS,v1.0";
|
|
case Profile.TVOS:
|
|
return "Xamarin.TVOS,v1.0";
|
|
case Profile.WatchOS:
|
|
return "Xamarin.WatchOS,v1.0";
|
|
default:
|
|
throw new NotImplementedException ();
|
|
}
|
|
}
|
|
|
|
public static string GetDeviceArchitecture (Profile profile)
|
|
{
|
|
switch (profile) {
|
|
case Profile.Classic:
|
|
case Profile.Unified:
|
|
return "armv7";
|
|
case Profile.TVOS:
|
|
return "arm64";
|
|
case Profile.WatchOS:
|
|
return "armv7k";
|
|
default:
|
|
throw new NotImplementedException ();
|
|
}
|
|
}
|
|
|
|
public static string GetSimulatorArchitecture (Profile profile)
|
|
{
|
|
switch (profile) {
|
|
case Profile.Classic:
|
|
case Profile.Unified:
|
|
case Profile.WatchOS:
|
|
return "i386";
|
|
case Profile.TVOS:
|
|
return "x86_64";
|
|
default:
|
|
throw new NotImplementedException ();
|
|
}
|
|
}
|
|
|
|
public static string GetArchitecture (Profile profile, Target target)
|
|
{
|
|
return target == Target.Dev ? GetDeviceArchitecture (profile) : GetSimulatorArchitecture (profile);
|
|
}
|
|
|
|
static string GetPlatformName (Profile profile)
|
|
{
|
|
switch (profile) {
|
|
case Profile.Classic:
|
|
return "MonoTouch";
|
|
case Profile.Unified:
|
|
return "Xamarin.iOS";
|
|
case Profile.TVOS:
|
|
return "Xamarin.TVOS";
|
|
case Profile.WatchOS:
|
|
return "Xamarin.WatchOS";
|
|
default:
|
|
throw new NotImplementedException ();
|
|
}
|
|
}
|
|
|
|
static string GetProjectSuffix (Profile profile)
|
|
{
|
|
switch (profile) {
|
|
case Profile.Classic:
|
|
return string.Empty;
|
|
case Profile.Unified:
|
|
return "-unified";
|
|
case Profile.TVOS:
|
|
return "-tvos";
|
|
case Profile.WatchOS:
|
|
return "-watchos";
|
|
default:
|
|
throw new NotImplementedException ();
|
|
}
|
|
}
|
|
|
|
public static string GetSdkVersion (Profile profile)
|
|
{
|
|
switch (profile) {
|
|
case Profile.Classic:
|
|
case Profile.Unified:
|
|
return Configuration.sdk_version;
|
|
case Profile.TVOS:
|
|
return Configuration.tvos_sdk_version;
|
|
case Profile.WatchOS:
|
|
return Configuration.watchos_sdk_version;
|
|
default:
|
|
throw new NotImplementedException ();
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
public void LinkAll_Frameworks ()
|
|
{
|
|
// Make sure that mtouch does not link with unused frameworks.
|
|
|
|
var testDir = GetTempDirectory ();
|
|
var app = Path.Combine (testDir, "testApp.app");
|
|
Directory.CreateDirectory (app);
|
|
|
|
try {
|
|
var exe = CompileTestAppExecutable (testDir);
|
|
var bin = Path.Combine (app, Path.GetFileNameWithoutExtension (exe));
|
|
|
|
ExecutionHelper.Execute (TestTarget.ToolPath, string.Format ("-sdkroot " + Configuration.xcode_root + " -v -v -v --nosign --sim {0} -sdk " + Configuration.sdk_version + " {1} -debug", app, exe));
|
|
|
|
var load_commands = ExecutionHelper.Execute ("otool", "-l \"" + bin + "\"");
|
|
Asserts.DoesNotContain ("SafariServices", load_commands, "SafariServices");
|
|
Asserts.DoesNotContain ("GameController", load_commands, "GameController");
|
|
Asserts.DoesNotContain ("QuickLook", load_commands, "QuickLook");
|
|
Asserts.DoesNotContain ("NewsstandKit", load_commands, "NewsstandKit");
|
|
} finally {
|
|
Directory.Delete (testDir, true);
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
[TestCase (Profile.Classic)]
|
|
[TestCase (Profile.Unified)]
|
|
[TestCase (Profile.TVOS)]
|
|
//[TestCase (Profile.WatchOS)] // needs testing improvement
|
|
public void FastDev_LinkWithTest (Profile profile)
|
|
{
|
|
var testDir = GetTempDirectory ();
|
|
var app = Path.Combine (testDir, "testApp.app");
|
|
Directory.CreateDirectory (app);
|
|
|
|
try {
|
|
// --fastdev with static registrar and linkwith library - this will fail to build if the linkwith dylib isn't linked with the corresponding native library.
|
|
var mtouch = new MTouchTool ()
|
|
{
|
|
Profile = profile,
|
|
Debug = true,
|
|
FastDev = true,
|
|
References = new string [] { GetBindingsLibrary (profile) },
|
|
Executable = CompileTestAppExecutableLinkWith (testDir, profile),
|
|
AppPath = app,
|
|
NoFastSim = true,
|
|
Registrar = MTouchRegistrar.Static,
|
|
};
|
|
Assert.AreEqual (0, mtouch.Execute (MTouchAction.BuildDev), "build");
|
|
} finally {
|
|
Directory.Delete (testDir, true);
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
[TestCase (Profile.Classic)]
|
|
[TestCase (Profile.Unified)]
|
|
[TestCase (Profile.TVOS)]
|
|
//[TestCase (Profile.WatchOS)] // needs testing improvement
|
|
public void FastDev_NoFastSim_NoLink (Profile profile)
|
|
{
|
|
var testDir = GetTempDirectory ();
|
|
var app = Path.Combine (testDir, "testApp.app");
|
|
Directory.CreateDirectory (app);
|
|
|
|
try {
|
|
// --sim --nofastsim --nolink --fastdev
|
|
var mtouch = new MTouchTool ()
|
|
{
|
|
Profile = profile,
|
|
Debug = true,
|
|
FastDev = true,
|
|
References = new string [] { GetBindingsLibrary (profile) },
|
|
Executable = CompileTestAppExecutableLinkWith (testDir, profile),
|
|
AppPath = app,
|
|
NoFastSim = true,
|
|
Linker = MTouchLinker.DontLink,
|
|
};
|
|
Assert.AreEqual (0, mtouch.Execute (MTouchAction.BuildSim), "build");
|
|
} finally {
|
|
Directory.Delete (testDir, true);
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
[TestCase (Profile.Classic)]
|
|
[TestCase (Profile.Unified)]
|
|
[TestCase (Profile.TVOS)]
|
|
//[TestCase (Profile.WatchOS)] // needs testing improvement
|
|
public void FastDev_NoFastSim_LinkAll (Profile profile)
|
|
{
|
|
var testDir = GetTempDirectory ();
|
|
var app = Path.Combine (testDir, "testApp.app");
|
|
Directory.CreateDirectory (app);
|
|
|
|
try {
|
|
// --sim --nofastsim --fastdev
|
|
var mtouch = new MTouchTool ()
|
|
{
|
|
Profile = profile,
|
|
Debug = true,
|
|
FastDev = true,
|
|
References = new string [] { GetBindingsLibrary (profile) },
|
|
Executable = CompileTestAppExecutableLinkWith (testDir, profile),
|
|
AppPath = app,
|
|
NoFastSim = true,
|
|
};
|
|
Assert.AreEqual (0, mtouch.Execute (MTouchAction.BuildSim), "build");
|
|
} finally {
|
|
Directory.Delete (testDir, true);
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
[TestCase (Profile.Classic)]
|
|
[TestCase (Profile.Unified)]
|
|
[TestCase (Profile.TVOS)]
|
|
//[TestCase (Profile.WatchOS)] // needs testing improvement
|
|
public void FastDev_NoFastSim_LinkSDK (Profile profile)
|
|
{
|
|
var testDir = GetTempDirectory ();
|
|
var app = Path.Combine (testDir, "testApp.app");
|
|
Directory.CreateDirectory (app);
|
|
|
|
try {
|
|
// --sim --nofastsim --linksdkonly --fastdev
|
|
var mtouch = new MTouchTool ()
|
|
{
|
|
Profile = profile,
|
|
Debug = true,
|
|
FastDev = true,
|
|
References = new string [] { GetBindingsLibrary (profile) },
|
|
Linker = MTouchLinker.LinkSdk,
|
|
Executable = CompileTestAppExecutableLinkWith (testDir, profile),
|
|
AppPath = app,
|
|
NoFastSim = true,
|
|
};
|
|
Assert.AreEqual (0, mtouch.Execute (MTouchAction.BuildSim), "build");
|
|
} finally {
|
|
Directory.Delete (testDir, true);
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
[TestCase (Profile.Classic)]
|
|
[TestCase (Profile.Unified)]
|
|
[TestCase (Profile.TVOS)]
|
|
//[TestCase (Profile.WatchOS)] // needs testing improvement
|
|
public void FastDev_Sim (Profile profile)
|
|
{
|
|
var testDir = GetTempDirectory ();
|
|
var app = Path.Combine (testDir, "testApp.app");
|
|
Directory.CreateDirectory (app);
|
|
|
|
try {
|
|
// --sim --fastdev
|
|
var mtouch = new MTouchTool ()
|
|
{
|
|
Profile = profile,
|
|
Debug = true,
|
|
FastDev = true,
|
|
References = new string [] { GetBindingsLibrary (profile) },
|
|
Executable = CompileTestAppExecutableLinkWith (testDir, profile),
|
|
AppPath = app,
|
|
};
|
|
Assert.AreEqual (0, mtouch.Execute (MTouchAction.BuildSim), "build");
|
|
} finally {
|
|
Directory.Delete (testDir, true);
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
[TestCase (Profile.Classic)]
|
|
[TestCase (Profile.Unified)]
|
|
[TestCase (Profile.TVOS)]
|
|
//[TestCase (Profile.WatchOS)] // needs testing improvement
|
|
public void FastDev_LinkAll (Profile profile)
|
|
{
|
|
using (var mtouch = new MTouchTool ()
|
|
{
|
|
Profile = profile,
|
|
Debug = true,
|
|
FastDev = true,
|
|
References = new string [] { GetBindingsLibrary (profile) },
|
|
}) {
|
|
mtouch.CreateTemporaryApp_LinkWith ();
|
|
Assert.AreEqual (0, mtouch.Execute (MTouchAction.BuildDev), "build");
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
[TestCase (Profile.Classic)]
|
|
[TestCase (Profile.Unified)]
|
|
[TestCase (Profile.TVOS)]
|
|
//[TestCase (Profile.WatchOS)] // needs testing improvement
|
|
public void FastDev_NoLink (Profile profile)
|
|
{
|
|
|
|
// --fastdev w/no link
|
|
using (var mtouch = new MTouchTool ()
|
|
{
|
|
Profile = profile,
|
|
Debug = true,
|
|
FastDev = true,
|
|
References = new string [] { GetBindingsLibrary (profile) },
|
|
Linker = MTouchLinker.DontLink,
|
|
}) {
|
|
mtouch.CreateTemporaryApp_LinkWith ();
|
|
Assert.AreEqual (0, mtouch.Execute (MTouchAction.BuildDev), "build 1");
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
[TestCase (Profile.Classic)]
|
|
[TestCase (Profile.Unified)]
|
|
[TestCase (Profile.TVOS)]
|
|
//[TestCase (Profile.WatchOS)] // needs testing improvement
|
|
public void FastDev_LinkAll_Then_NoLink (Profile profile)
|
|
{
|
|
using (var mtouch = new MTouchTool
|
|
{
|
|
Profile = profile,
|
|
Debug = true,
|
|
FastDev = true,
|
|
References = new string [] { GetBindingsLibrary (profile) },
|
|
}) {
|
|
mtouch.CreateTemporaryApp_LinkWith ();
|
|
|
|
// --fastdev w/all link
|
|
Assert.AreEqual (0, mtouch.Execute (MTouchAction.BuildDev), "build 1");
|
|
|
|
// --fastdev w/no link
|
|
mtouch.Linker = MTouchLinker.DontLink;
|
|
Assert.AreEqual (0, mtouch.Execute (MTouchAction.BuildDev), "build 2");
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
[TestCase (Profile.Classic)]
|
|
[TestCase (Profile.Unified)]
|
|
[TestCase (Profile.TVOS)]
|
|
//[TestCase (Profile.WatchOS)] // needs testing improvement
|
|
public void FastDev_LinkSDK (Profile profile)
|
|
{
|
|
using (var mtouch = new MTouchTool
|
|
{
|
|
Profile = profile,
|
|
Debug = true,
|
|
FastDev = true,
|
|
References = new string [] { GetBindingsLibrary (profile) },
|
|
Linker = MTouchLinker.LinkSdk,
|
|
}) {
|
|
mtouch.CreateTemporaryApp_LinkWith ();
|
|
|
|
// --fastdev w/sdk link
|
|
Assert.AreEqual (0, mtouch.Execute (MTouchAction.BuildDev), "build");
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
public void FastDev_Dual ()
|
|
{
|
|
using (var mtouch = new MTouchTool ()
|
|
{
|
|
Profile = Profile.Unified,
|
|
FastDev = true,
|
|
Abi = "armv7,arm64",
|
|
}) {
|
|
mtouch.CreateTemporaryApp ();
|
|
|
|
Assert.AreEqual (0, mtouch.Execute (MTouchAction.BuildDev));
|
|
var bin = mtouch.NativeExecutablePath;
|
|
VerifyArchitectures (bin, "arm7s/64", "armv7", "arm64");
|
|
foreach (var dylib in Directory.GetFileSystemEntries (mtouch.AppPath, "*.dylib")) {
|
|
if (Path.GetFileName (dylib).StartsWith ("libmono"))
|
|
continue;
|
|
if (Path.GetFileName (dylib).StartsWith ("libxamarin"))
|
|
continue;
|
|
VerifyArchitectures (dylib, dylib + ": arm7s/64", "armv7", "arm64");
|
|
}
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
[TestCase (Target.Dev, "armv7")]
|
|
[TestCase (Target.Dev, "armv7s")]
|
|
[TestCase (Target.Dev, "armv7,armv7s")]
|
|
[TestCase (Target.Sim, "i386")]
|
|
public void Architectures_Classic (Target target, string abi)
|
|
{
|
|
using (var mtouch = new MTouchTool ()) {
|
|
mtouch.CreateTemporaryApp ();
|
|
|
|
mtouch.Abi = abi;
|
|
|
|
var bin = Path.Combine (mtouch.AppPath, Path.GetFileNameWithoutExtension (mtouch.Executable));
|
|
|
|
Assert.AreEqual (0, mtouch.Execute (target == Target.Dev ? MTouchAction.BuildDev : MTouchAction.BuildSim));
|
|
VerifyArchitectures (bin, abi, abi.Split (','));
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
public void Architectures_Classic_Invalid ()
|
|
{
|
|
using (var mtouch = new MTouchTool ()) {
|
|
mtouch.CreateTemporaryApp ();
|
|
|
|
mtouch.Abi = "armv6";
|
|
Assert.AreEqual (1, mtouch.Execute (MTouchTests.MTouchAction.BuildDev));
|
|
mtouch.AssertError ("MT", 15, "Invalid ABI: armv6. Supported ABIs are: i386, x86_64, armv7, armv7+llvm, armv7+llvm+thumb2, armv7s, armv7s+llvm, armv7s+llvm+thumb2, armv7k, armv7k+llvm, arm64 and arm64+llvm.");
|
|
|
|
mtouch.Abi = "armv7";
|
|
Assert.AreEqual (1, mtouch.Execute (MTouchAction.BuildSim));
|
|
mtouch.AssertError ("MT", 75, "Invalid architecture 'ARMv7' for iOS projects. Valid architectures are: i386");
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
[TestCase (Target.Dev, "armv7")]
|
|
[TestCase (Target.Dev, "armv7s")]
|
|
[TestCase (Target.Dev, "armv7,armv7s")]
|
|
[TestCase (Target.Dev, "arm64")]
|
|
[TestCase (Target.Dev, "arm64+llvm")]
|
|
[TestCase (Target.Dev, "armv7,arm64")]
|
|
[TestCase (Target.Dev, "armv7s,arm64")]
|
|
[TestCase (Target.Dev, "armv7,armv7s,arm64")]
|
|
[TestCase (Target.Sim, "i386")]
|
|
[TestCase (Target.Sim, "x86_64")]
|
|
public void Architectures_Unified (Target target, string abi)
|
|
{
|
|
using (var mtouch = new MTouchTool ()) {
|
|
mtouch.Profile = Profile.Unified;
|
|
mtouch.CreateTemporaryApp ();
|
|
|
|
mtouch.Abi = abi;
|
|
|
|
var bin = Path.Combine (mtouch.AppPath, Path.GetFileNameWithoutExtension (mtouch.Executable));
|
|
|
|
Assert.AreEqual (0, mtouch.Execute (target == Target.Dev ? MTouchAction.BuildDev : MTouchAction.BuildSim));
|
|
|
|
VerifyArchitectures (bin, abi, abi.Replace ("+llvm", string.Empty).Split (','));
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
public void Architectures_Unified_FatSimulator ()
|
|
{
|
|
using (var mtouch = new MTouchTool ()) {
|
|
mtouch.Profile = Profile.Unified;
|
|
mtouch.CreateTemporaryApp ();
|
|
|
|
mtouch.Abi = "i386,x86_64";
|
|
|
|
var bin = Path.Combine (mtouch.AppPath, Path.GetFileNameWithoutExtension (mtouch.Executable));
|
|
var bin32 = Path.Combine (mtouch.AppPath, ".monotouch-32", Path.GetFileNameWithoutExtension (mtouch.Executable));
|
|
var bin64 = Path.Combine (mtouch.AppPath, ".monotouch-64", Path.GetFileNameWithoutExtension (mtouch.Executable));
|
|
|
|
Assert.AreEqual (0, mtouch.Execute (MTouchAction.BuildSim));
|
|
|
|
Assert.IsFalse (File.Exists (bin), "none");
|
|
VerifyArchitectures (bin64, "64/x86_64", "x86_64");
|
|
VerifyArchitectures (bin32, "32/i386", "i386");
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
public void Architectures_Unified_Invalid ()
|
|
{
|
|
using (var mtouch = new MTouchTool ()) {
|
|
mtouch.Profile = Profile.Unified;
|
|
mtouch.CreateTemporaryApp ();
|
|
|
|
mtouch.Abi = "armv6";
|
|
Assert.AreEqual (1, mtouch.Execute (MTouchAction.BuildDev));
|
|
mtouch.AssertError ("MT", 15, "Invalid ABI: armv6. Supported ABIs are: i386, x86_64, armv7, armv7+llvm, armv7+llvm+thumb2, armv7s, armv7s+llvm, armv7s+llvm+thumb2, armv7k, armv7k+llvm, arm64 and arm64+llvm.");
|
|
|
|
mtouch.Abi = "armv7";
|
|
Assert.AreEqual (1, mtouch.Execute (MTouchAction.BuildSim));
|
|
mtouch.AssertError ("MT", 75, "Invalid architecture 'ARMv7' for iOS projects. Valid architectures are: i386, x86_64");
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
[TestCase (Target.Dev, null)]
|
|
[TestCase (Target.Dev, "arm64+llvm")]
|
|
[TestCase (Target.Sim, null)]
|
|
public void Architectures_TVOS (Target target, string abi)
|
|
{
|
|
using (var mtouch = new MTouchTool ()) {
|
|
mtouch.Profile = MTouch.Profile.TVOS;
|
|
mtouch.Abi = abi;
|
|
mtouch.CreateTemporaryApp ();
|
|
|
|
var bin = Path.Combine (mtouch.AppPath, Path.GetFileNameWithoutExtension (mtouch.Executable));
|
|
|
|
Assert.AreEqual (0, mtouch.Execute (target == Target.Dev ? MTouchAction.BuildDev : MTouchAction.BuildSim), "build");
|
|
VerifyArchitectures (bin, "arch", target == Target.Dev ? "arm64" : "x86_64");
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
public void Architectures_TVOS_Invalid ()
|
|
{
|
|
using (var mtouch = new MTouchTool ()) {
|
|
mtouch.Profile = Profile.TVOS;
|
|
mtouch.CreateTemporaryApp ();
|
|
|
|
mtouch.Abi = "armv7";
|
|
Assert.AreEqual (1, mtouch.Execute (MTouchAction.BuildDev), "device - armv7");
|
|
mtouch.AssertError ("MT", 75, "Invalid architecture 'ARMv7' for TVOS projects. Valid architectures are: ARM64, ARM64+LLVM");
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
public void GarbageCollectors ()
|
|
{
|
|
var testDir = GetTempDirectory ();
|
|
var app = Path.Combine (testDir, "testApp.app");
|
|
Directory.CreateDirectory (app);
|
|
|
|
try {
|
|
var exe = CompileTestAppExecutable (testDir);
|
|
var bin = Path.Combine (app, Path.GetFileNameWithoutExtension (exe));
|
|
var common_args = string.Format ("-sdkroot " + Configuration.xcode_root + " --nosign --sim {0} -sdk " + Configuration.sdk_version + " --abi=i386 {1} -debug ", app, exe);
|
|
var compat_args = common_args + " -r:" + Configuration.MonoTouchDll;
|
|
|
|
ExecutionHelper.Execute (TestTarget.ToolPath, compat_args);
|
|
VerifyGC (bin, false, "compat/default");
|
|
|
|
ExecutionHelper.Execute (TestTarget.ToolPath, compat_args + " --sgen");
|
|
VerifyGC (bin, false, "compat/sgen");
|
|
|
|
ExecutionHelper.Execute (TestTarget.ToolPath, compat_args + " --boehm");
|
|
VerifyGC (bin, false, "compat/boehm");
|
|
} finally {
|
|
Directory.Delete (testDir, true);
|
|
}
|
|
|
|
Directory.CreateDirectory (app);
|
|
try {
|
|
var code = "public class TestApp { static void Main () { System.Console.WriteLine (typeof (UIKit.UIWindow).ToString ()); } }";
|
|
var exe = CompileTestAppExecutable (testDir, code: code, profile: MTouch.Profile.Unified);
|
|
var bin = Path.Combine (app, Path.GetFileNameWithoutExtension (exe));
|
|
var common_args = string.Format ("-sdkroot " + Configuration.xcode_root + " --sim {0} -sdk " + Configuration.sdk_version + " --targetver 5.1.1 --abi=i386 {1} -debug -gcc_flags -Wl,-w ", app, exe);
|
|
var newstyle_args = common_args + "-r:" + Configuration.XamarinIOSDll;
|
|
ExecutionHelper.Execute (TestTarget.ToolPath, newstyle_args);
|
|
VerifyGC (bin, false, "dual/default");
|
|
|
|
ExecutionHelper.Execute (TestTarget.ToolPath, newstyle_args + " --sgen");
|
|
VerifyGC (bin, false, "dual/sgen");
|
|
|
|
var output = ExecutionHelper.Execute (TestTarget.ToolPath, newstyle_args + " --boehm");
|
|
VerifyGC (bin, false, "dual/boehm");
|
|
VerifyOutput ("Test", output,
|
|
"Xamarin.iOS .* using framework:.*",
|
|
"warning MT0043: The Boehm garbage collector is not supported. The SGen garbage collector has been selected instead.",
|
|
".*testApp.app built successfully.");
|
|
} finally {
|
|
Directory.Delete (testDir, true);
|
|
}
|
|
}
|
|
|
|
void ExecuteWithStats (string binary, string arguments)
|
|
{
|
|
ExecutionHelper.Execute (TestTarget.ToolPath, arguments);
|
|
var fi = new FileInfo (binary);
|
|
Console.WriteLine ("Binary Size: {0} bytes = {1} kb", fi.Length, fi.Length / 1024);
|
|
}
|
|
|
|
string ReplaceExtraArgs (string contents, string replace)
|
|
{
|
|
return ReplaceCsprojData (contents, "MtouchExtraArgs", replace);
|
|
}
|
|
|
|
string ReplaceCompilerDefines (string contents, string replace)
|
|
{
|
|
return ReplaceCsprojData (contents, "DefineConstants", replace);
|
|
}
|
|
|
|
string ReplaceCsprojData (string contents, string key, string replace)
|
|
{
|
|
int idx = 0;
|
|
while (true) {
|
|
var start = contents.IndexOf ("<" + key + ">", idx);
|
|
if (start == -1)
|
|
return contents;
|
|
var end = contents.IndexOf("</" + key + ">", start);
|
|
if (end == -1)
|
|
return contents;
|
|
contents = contents.Substring (0, start + ("<" + key + ">").Length) + replace + contents.Substring (end);
|
|
idx = end;
|
|
}
|
|
}
|
|
|
|
static string MDToolPath {
|
|
get {
|
|
return "/Applications/Xamarin Studio.app/Contents/MacOS/mdtool";
|
|
}
|
|
}
|
|
|
|
void BuildMonotouchTests (string registrar, string defines)
|
|
{
|
|
string dir = Environment.CurrentDirectory;
|
|
while (dir != null && !Directory.Exists (Path.Combine (dir, "monotouch-test"))) {
|
|
dir = Path.GetDirectoryName (dir);
|
|
}
|
|
if (dir == null)
|
|
Assert.Ignore ("Could not find the monotouch-test directory.");
|
|
|
|
var proj = Path.Combine (Path.Combine (dir, "monotouch-test"), "monotouch-test.csproj");
|
|
var tmpproj = Path.Combine (Path.Combine (dir, "monotouch-test"), ".tmp-monotouch-test.csproj");
|
|
var contents = File.ReadAllText (proj);
|
|
var sln = Path.Combine (dir, "tests.sln");
|
|
var tmpsln = Path.Combine (dir, ".tmp-tests.sln");
|
|
var slncontents = File.ReadAllText (sln);
|
|
|
|
try {
|
|
var tmpcontents = ReplaceExtraArgs (contents, "-v -v -v --registrar:" + registrar);
|
|
tmpcontents = ReplaceCompilerDefines (contents, defines);
|
|
File.WriteAllText (tmpproj, tmpcontents);
|
|
var tmpslncontents = slncontents.Replace ("\\monotouch-test.csproj", "\\.tmp-monotouch-test.csproj");
|
|
File.WriteAllText (tmpsln, tmpslncontents);
|
|
using (var p = new Process ()) {
|
|
p.StartInfo.FileName = MDToolPath;
|
|
p.StartInfo.Arguments = "-v build -t:Build \"-c:Debug|iPhoneSimulator\" -p:.tmp-monotouch-test ../.tmp-tests.sln";
|
|
p.StartInfo.WorkingDirectory = Path.GetDirectoryName (tmpproj);
|
|
p.StartInfo.UseShellExecute = false;
|
|
p.StartInfo.RedirectStandardError = true;
|
|
p.StartInfo.RedirectStandardOutput = true;
|
|
p.ErrorDataReceived += (object sender, DataReceivedEventArgs e) => { Console.Error.WriteLine (e.Data); };
|
|
p.OutputDataReceived += (object sender, DataReceivedEventArgs e) => { Console.WriteLine (e.Data); };
|
|
Console.WriteLine ("{0} {1}", p.StartInfo.FileName, p.StartInfo.Arguments);
|
|
p.Start ();
|
|
p.BeginErrorReadLine ();
|
|
p.BeginOutputReadLine ();
|
|
p.WaitForExit ();
|
|
if (p.ExitCode != 0)
|
|
Assert.Fail ("Failed to compile monotouch-test with --registrar:{0} for Debug|iPhoneSimulator", registrar);
|
|
}
|
|
} finally {
|
|
// delete temporary project file
|
|
try {
|
|
File.Delete (tmpproj);
|
|
} catch {
|
|
}
|
|
try {
|
|
File.Delete (tmpsln);
|
|
} catch {
|
|
}
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
public void BuildMonoTouchTests_StaticRegistrar ()
|
|
{
|
|
BuildMonotouchTests ("static --compiler:clang", "DEBUG;STATICREGISTRAR");
|
|
}
|
|
|
|
[Test]
|
|
public void BuildMonoTouchTests_OldStaticRegistrar ()
|
|
{
|
|
BuildMonotouchTests ("oldstatic", "DEBUG;OLDSTATICREGISTRAR");
|
|
}
|
|
|
|
[Test]
|
|
public void Registrar ()
|
|
{
|
|
var testDir = GetTempDirectory ();
|
|
var app = Path.Combine (testDir, "testApp.app");
|
|
Directory.CreateDirectory (app);
|
|
|
|
try {
|
|
var exe = CompileTestAppExecutable (testDir);
|
|
var bin = Path.Combine (app, Path.GetFileNameWithoutExtension (exe));
|
|
var common_args = string.Format ("-sdkroot " + Configuration.xcode_root + " --nosign --dev {0} -sdk {2} {1} -debug", app, exe, Configuration.sdk_version);
|
|
|
|
// fully linked + llvm (+thumb) + default registrar (currently llvm fails to build with clang, so we should transparently switch to gcc in this case)
|
|
ExecuteWithStats (bin, common_args + " --registrar:static --abi:armv7+llvm");
|
|
ExecuteWithStats (bin, common_args + " --registrar:static --abi:armv7+llvm+thumb2");
|
|
|
|
// non-linked device build
|
|
ExecuteWithStats (bin, common_args + " --compiler:clang --nolink --registrar:static");
|
|
ExecuteWithStats (bin, common_args + " --compiler:clang --nolink --registrar:oldstatic");
|
|
ExecuteWithStats (bin, common_args + " --compiler:clang --nolink --registrar:dynamic");
|
|
ExecuteWithStats (bin, common_args + " --compiler:clang --nolink --registrar:olddynamic");
|
|
|
|
// sdk device build
|
|
ExecuteWithStats (bin, common_args + " --compiler:clang --linksdkonly --registrar:static");
|
|
ExecuteWithStats (bin, common_args + " --compiler:clang --linksdkonly --registrar:oldstatic");
|
|
ExecuteWithStats (bin, common_args + " --compiler:clang --linksdkonly --registrar:dynamic");
|
|
ExecuteWithStats (bin, common_args + " --compiler:clang --linksdkonly --registrar:olddynamic");
|
|
|
|
// fully linked device build
|
|
ExecuteWithStats (bin, common_args + " --compiler:clang --registrar:static");
|
|
ExecuteWithStats (bin, common_args + " --compiler:clang --registrar:oldstatic");
|
|
ExecuteWithStats (bin, common_args + " --compiler:clang --registrar:dynamic");
|
|
ExecuteWithStats (bin, common_args + " --compiler:clang --registrar:olddynamic");
|
|
|
|
// non-linked device build
|
|
common_args = string.Format ("-sdkroot " + Configuration.xcode_root + " --nosign --sim {0} -sdk {2} {1} -debug", app, exe, Configuration.sdk_version);
|
|
ExecuteWithStats (bin, common_args + " --compiler:clang --nolink --registrar:static");
|
|
ExecuteWithStats (bin, common_args + " --compiler:clang --nolink --registrar:oldstatic");
|
|
ExecuteWithStats (bin, common_args + " --compiler:clang --nolink --registrar:dynamic");
|
|
ExecuteWithStats (bin, common_args + " --compiler:clang --nolink --registrar:olddynamic");
|
|
} finally {
|
|
Directory.Delete (testDir, true);
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
[TestCase ("")]
|
|
[TestCase ("-nolink")]
|
|
[TestCase ("-linksdkonly")]
|
|
public void ExportedSymbols (string linker_flag)
|
|
{
|
|
//
|
|
// Here we test that symbols P/Invokes and [Field] attributes references are not
|
|
// stripped by the native linker. mtouch has to pass '-u _SYMBOL' to the native linker
|
|
// for this to work.
|
|
//
|
|
|
|
var testDir = GetTempDirectory ();
|
|
var app = Path.Combine (testDir, "testApp.app");
|
|
var cache = Path.Combine (testDir, "cache");
|
|
Directory.CreateDirectory (app);
|
|
|
|
try {
|
|
var nativeCode = @"
|
|
void DummyMethod () {}
|
|
int dummy_field = 0;
|
|
";
|
|
// var nativeLib = CompileNativeLibrary (testDir, nativeCode);
|
|
var extraCode = @"
|
|
public class BindingApp {
|
|
[MonoTouch.Foundation.Field (""dummy_field"", ""__Internal"")]
|
|
public static string DummyField { get { return null; } }
|
|
|
|
[System.Runtime.InteropServices.DllImport (""__Internal"")]
|
|
public static extern void DummyMethod ();
|
|
}
|
|
";
|
|
var bindingLib = CreateBindingLibrary (testDir, nativeCode, null, null, extraCode);
|
|
var exe = CompileTestAppExecutable (testDir, @"
|
|
public class TestApp {
|
|
static void Main () {
|
|
System.Console.WriteLine (typeof (MonoTouch.UIKit.UIWindow).ToString ());
|
|
System.Console.WriteLine (BindingApp.DummyField);
|
|
BindingApp.DummyMethod ();
|
|
}
|
|
}
|
|
",
|
|
"-r:" + bindingLib);
|
|
var bin = Path.Combine (app, Path.GetFileNameWithoutExtension (exe));
|
|
var args = string.Format ("-sdkroot {4} --nosign -sdk {2} {1} -debug --cache {0} -v -v -v -v -r:{3} -dev {5} " + linker_flag,
|
|
cache, exe, Configuration.sdk_version, bindingLib, Configuration.xcode_root, app);
|
|
|
|
// each variation is tested twice so that we don't break when everything is found in the cache the second time around.
|
|
|
|
ExecutionHelper.Execute (TestTarget.ToolPath, args);
|
|
var symbols = ExecutionHelper.Execute ("nm", bin, hide_output: true).Split ('\n');
|
|
Assert.That (symbols, Has.Some.EndsWith (" S _dummy_field"), "Field not found in initial build");
|
|
Assert.That (symbols, Has.Some.EndsWith (" T _DummyMethod"), "P/invoke not found in initial build");
|
|
|
|
ExecutionHelper.Execute ("touch", bindingLib); // This will make it so that the second identical variation won't skip the final link step.
|
|
ExecutionHelper.Execute (TestTarget.ToolPath, args);
|
|
symbols = ExecutionHelper.Execute ("nm", bin, hide_output: true).Split ('\n');
|
|
Assert.That (symbols, Has.Some.EndsWith (" S _dummy_field"), "Field not found in second build");
|
|
Assert.That (symbols, Has.Some.EndsWith (" T _DummyMethod"), "P/invoke not found in second build");
|
|
} finally {
|
|
Directory.Delete (testDir, true);
|
|
}
|
|
}
|
|
|
|
|
|
[Test]
|
|
public void ExportedSymbols_VerifyLinkedAwayField ()
|
|
{
|
|
//
|
|
// Here we test that unused P/Invokes and [Field] members are properly linked away
|
|
// (and we do not request the native linker to preserve those symbols).
|
|
//
|
|
|
|
var testDir = GetTempDirectory ();
|
|
var app = Path.Combine (testDir, "testApp.app");
|
|
var cache = Path.Combine (testDir, "cache");
|
|
|
|
Directory.CreateDirectory (app);
|
|
|
|
try {
|
|
var nativeCode = @"
|
|
void DummyMethod () {}
|
|
int dummy_field = 0;
|
|
";
|
|
// var nativeLib = CompileNativeLibrary (testDir, nativeCode);
|
|
var extraCode = @"
|
|
public class BindingApp {
|
|
[MonoTouch.Foundation.Field (""dummy_field"", ""__Internal"")]
|
|
public static string DummyField { get { return null; } }
|
|
|
|
[System.Runtime.InteropServices.DllImport (""__Internal"")]
|
|
public static extern void DummyMethod ();
|
|
}
|
|
";
|
|
var bindingLib = CreateBindingLibrary (testDir, nativeCode, null, null, extraCode);
|
|
var exe = CompileTestAppExecutable (testDir, @"
|
|
public class TestApp {
|
|
static void Main () {
|
|
System.Console.WriteLine (typeof (MonoTouch.UIKit.UIWindow).ToString ());
|
|
}
|
|
}
|
|
",
|
|
"-r:" + bindingLib);
|
|
var bin = Path.Combine (app, Path.GetFileNameWithoutExtension (exe));
|
|
var common_args = string.Format ("-sdkroot " + Configuration.xcode_root + " --nosign -sdk {2} {1} -debug --cache {0} -v -v -v -v --registrar:static -r:{3}",
|
|
cache, exe, Configuration.sdk_version, bindingLib);
|
|
|
|
var variations = new string [] {
|
|
// each variation is tested twice so that we don't break when everything is found in the cache the second time around.
|
|
" -dev {0}",
|
|
" -dev {0}",
|
|
};
|
|
|
|
for (int v = 0; v < variations.Length; v++) {
|
|
var variation = variations [v];
|
|
|
|
ExecutionHelper.Execute ("touch", bindingLib); // This will make it so that the second identical variation won't skip the final link step.
|
|
|
|
ExecutionHelper.Execute (TestTarget.ToolPath, string.Format (common_args + variation, app));
|
|
var lines = ExecutionHelper.Execute ("nm", bin, hide_output: true).Split ('\n');
|
|
var found_field = false;
|
|
var found_pinvoke = false;
|
|
foreach (var line in lines) {
|
|
found_field |= line.EndsWith (" S _dummy_field");
|
|
found_pinvoke |= line.EndsWith (" T _DummyMethod");
|
|
if (found_field && found_pinvoke)
|
|
break;
|
|
}
|
|
|
|
Assert.IsFalse (found_field, string.Format ("Field found for variation #{0}: {1}", v, variation));
|
|
Assert.IsFalse (found_field, string.Format ("P/Invoke found for variation #{0}: {1}", v, variation));
|
|
}
|
|
} finally {
|
|
Directory.Delete (testDir, true);
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
public void LinkerWarnings ()
|
|
{
|
|
string output;
|
|
var testDir = GetTempDirectory ();
|
|
|
|
try {
|
|
var app = Path.Combine (testDir, "testApp.app");
|
|
Directory.CreateDirectory (app);
|
|
|
|
var exe = CompileTestAppExecutable (testDir);
|
|
|
|
output = ExecutionHelper.Execute (TestTarget.ToolPath, string.Format ("-sdkroot {2} --nosign --dev {0} -sdk {3} --force --abi=armv7,armv7s {1} -debug", app, exe, Configuration.xcode_root, Configuration.sdk_version));
|
|
Asserts.DoesNotContain ("ld: warning:", output, "#a");
|
|
|
|
output = ExecutionHelper.Execute (TestTarget.ToolPath, string.Format ("-sdkroot {2} --nosign --dev {0} -sdk {3} --force --abi=armv7 {1} -debug --gcc_flags={4}", app, exe, Configuration.xcode_root, Configuration.sdk_version, Quote (Path.Combine (Configuration.SourceRoot, "tests/test-libraries/.libs/ios/libtest.armv7s.a"))));
|
|
Asserts.Contains ("libtest.armv7s.a, file was built for archive which is not the architecture being linked (armv7)", output, "#b");
|
|
} finally {
|
|
Directory.Delete (testDir, true);
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
public void NativeLinker_AllLoad ()
|
|
{
|
|
// https://bugzilla.xamarin.com/show_bug.cgi?id=17199
|
|
|
|
var testDir = GetTempDirectory ();
|
|
var app = Path.Combine (testDir, "testApp.app");
|
|
Directory.CreateDirectory (app);
|
|
|
|
try {
|
|
var exe = CompileTestAppExecutable (testDir);
|
|
|
|
ExecutionHelper.Execute (TestTarget.ToolPath, string.Format ("-sdkroot " + Configuration.xcode_root + " --nosign --dev {0} -sdk " + Configuration.sdk_version + " --targetver 7.0 --abi=armv7s {1} -debug --gcc_flags -all_load", app, exe));
|
|
|
|
} finally {
|
|
Directory.Delete (testDir, true);
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
public void CachedManagedLinker ()
|
|
{
|
|
// https://bugzilla.xamarin.com/show_bug.cgi?id=17506
|
|
|
|
var testDir = GetTempDirectory ();
|
|
|
|
foreach (var linker in new string [] { "", "--linksdkonly", "--nolink" }) {
|
|
try {
|
|
var app = Path.Combine (testDir, "testApp.app");
|
|
Directory.CreateDirectory (app);
|
|
|
|
var exe = CompileTestAppExecutable (testDir);
|
|
var cache = Path.Combine (testDir, "mtouch-cache");
|
|
|
|
var args = string.Format ("{3} -sdkroot " + Configuration.xcode_root + " --nosign --dev {0} -sdk " + Configuration.sdk_version + " --targetver 7.0 --abi=armv7 {1} --cache={2}", app, exe, cache, linker);
|
|
ExecutionHelper.Execute (TestTarget.ToolPath, args);
|
|
File.Delete (Path.Combine (app, "testApp")); // This will force the final native link to succeed, while everything before has been cached.
|
|
ExecutionHelper.Execute (TestTarget.ToolPath, args);
|
|
} finally {
|
|
Directory.Delete (testDir, true);
|
|
}
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
public void MT1015 ()
|
|
{
|
|
// BXC 18659
|
|
|
|
var testDir = GetTempDirectory ();
|
|
var app = Path.Combine (testDir, "testApp.app");
|
|
|
|
try {
|
|
Directory.CreateDirectory (Path.Combine (app, "testApp"));
|
|
|
|
var exe = CompileTestAppExecutable (testDir);
|
|
var cache = Path.Combine (testDir, "mtouch-cache");
|
|
|
|
var args = string.Format ("-sdkroot " + Configuration.xcode_root + " --debug --nosign --nolink --sim {0} -sdk " + Configuration.sdk_version + " --abi=i386 {1} --cache={2} --r:{3}", app, exe, cache, Configuration.MonoTouchDll);
|
|
Asserts.ThrowsPattern<TestExecutionException> (() => ExecutionHelper.Execute (TestTarget.ToolPath, args, hide_output: false),
|
|
"Xamarin.iOS .* using framework:.*\nerror MT1015: Failed to create the executable '.*/testApp.app/testApp': .*/testApp.app/testApp is a directory\n");
|
|
} finally {
|
|
Directory.Delete (testDir, true);
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
public void MT1016 ()
|
|
{
|
|
// #20607
|
|
|
|
var testDir = GetTempDirectory ();
|
|
|
|
try {
|
|
var app = Path.Combine (testDir, "testApp.app");
|
|
Directory.CreateDirectory (Path.Combine (app, "NOTICE"));
|
|
|
|
var exe = CompileTestAppExecutable (testDir);
|
|
var cache = Path.Combine (testDir, "mtouch-cache");
|
|
|
|
var args = string.Format ("-sdkroot " + Configuration.xcode_root + " --nosign --nolink --dev {0} -sdk {4} -targetver {4} --abi=armv7 {1} --cache={2} --r:{3} ", app, exe, cache, Configuration.MonoTouchDll, Configuration.sdk_version);
|
|
Asserts.ThrowsPattern<TestExecutionException> (() => ExecutionHelper.Execute (TestTarget.ToolPath, args, hide_output: false),
|
|
"Xamarin.iOS .* using framework:.*\nerror MT1016: Failed to create the NOTICE file because a directory already exists with the same name.\n");
|
|
} finally {
|
|
Directory.Delete (testDir, true);
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
public void MT1017 ()
|
|
{
|
|
// #20607
|
|
|
|
var testDir = GetTempDirectory ();
|
|
|
|
try {
|
|
var app = Path.Combine (testDir, "testApp.app");
|
|
Directory.CreateDirectory (app);
|
|
File.WriteAllText (Path.Combine (app, "NOTICE"), "contents");
|
|
var fi = new FileInfo (Path.Combine (app, "NOTICE"));
|
|
fi.IsReadOnly = true;
|
|
|
|
var exe = CompileTestAppExecutable (testDir);
|
|
var cache = Path.Combine (testDir, "mtouch-cache");
|
|
|
|
var args = string.Format ("-sdkroot " + Configuration.xcode_root + " --nosign --nolink --dev {0} -sdk {4} -targetver {4} --abi=armv7 {1} --cache={2} --r:{3}", app, exe, cache, Configuration.MonoTouchDll, Configuration.sdk_version);
|
|
Asserts.ThrowsPattern<TestExecutionException> (() => ExecutionHelper.Execute (TestTarget.ToolPath, args, hide_output: false),
|
|
"Xamarin.iOS .* using framework:.*\nerror MT1017: Failed to create the NOTICE file: Access to the path \".*/testApp.app/NOTICE\" is denied.\n");
|
|
} finally {
|
|
Directory.Delete (testDir, true);
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
public void MT1202 ()
|
|
{
|
|
using (var mtouch = new MTouchTool ()) {
|
|
mtouch.AppPath = "/tmp";
|
|
mtouch.Device = ":vX;";
|
|
Assert.AreEqual (1, mtouch.Execute (MTouchAction.LaunchSim), "launch");
|
|
mtouch.HasError ("MT", 1202, "Invalid simulator configuration: :vX;");
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
public void MT1203 ()
|
|
{
|
|
using (var mtouch = new MTouchTool ()) {
|
|
mtouch.AppPath = "/tmp";
|
|
mtouch.Device = ":v2;a";
|
|
Assert.AreEqual (1, mtouch.Execute (MTouchAction.LaunchSim), "launch");
|
|
mtouch.HasError ("MT", 1203, "Invalid simulator specification: a");
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
public void MT1204 ()
|
|
{
|
|
using (var mtouch = new MTouchTool ()) {
|
|
mtouch.AppPath = "/tmp";
|
|
mtouch.Device = ":v2;";
|
|
Assert.AreEqual (1, mtouch.Execute (MTouchAction.LaunchSim), "launch");
|
|
mtouch.HasError ("MT", 1204, "Invalid simulator specification '': runtime not specified.");
|
|
}
|
|
|
|
using (var mtouch = new MTouchTool ()) {
|
|
mtouch.AppPath = "/tmp";
|
|
mtouch.Device = ":v2;devicetype=1";
|
|
Assert.AreEqual (1, mtouch.Execute (MTouchAction.LaunchSim), "launch");
|
|
mtouch.HasError ("MT", 1204, "Invalid simulator specification 'devicetype=1': runtime not specified.");
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
public void MT1205 ()
|
|
{
|
|
using (var mtouch = new MTouchTool ()) {
|
|
mtouch.AppPath = "/tmp";
|
|
mtouch.Device = ":v2;runtime=1";
|
|
Assert.AreEqual (1, mtouch.Execute (MTouchAction.LaunchSim), "launch");
|
|
mtouch.HasError ("MT", 1205, "Invalid simulator specification 'runtime=1': device type not specified.");
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
public void MT1206 ()
|
|
{
|
|
using (var mtouch = new MTouchTool ()) {
|
|
mtouch.AppPath = "/tmp";
|
|
mtouch.Device = ":v2;runtime=1,devicetype=2";
|
|
Assert.AreEqual (1, mtouch.Execute (MTouchAction.LaunchSim), "launch");
|
|
mtouch.HasError ("MT", 1206, "Could not find the simulator runtime '1'.");
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
public void MT1207 ()
|
|
{
|
|
using (var mtouch = new MTouchTool ()) {
|
|
mtouch.AppPath = "/tmp";
|
|
mtouch.Device = ":v2;runtime=com.apple.CoreSimulator.SimRuntime.iOS-" + Configuration.sdk_version.Replace ('.', '-') + ",devicetype=2";
|
|
Assert.AreEqual (1, mtouch.Execute (MTouchAction.LaunchSim), "launch");
|
|
mtouch.HasError ("MT", 1207, "Could not find the simulator device type '2'.");
|
|
}
|
|
}
|
|
|
|
// I don't know which --runtime values would cause MT1208, I always end up with MT1215 instead
|
|
|
|
// I don't know which --device values would cause MT1209
|
|
|
|
[Test]
|
|
public void MT1210 ()
|
|
{
|
|
using (var mtouch = new MTouchTool ()) {
|
|
mtouch.AppPath = "/tmp";
|
|
mtouch.Device = ":v2;a=1";
|
|
Assert.AreEqual (1, mtouch.Execute (MTouchAction.LaunchSim), "launch");
|
|
mtouch.HasError ("MT", 1210, "Invalid simulator specification: 'a=1', unknown key 'a'");
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
public void MT1211 ()
|
|
{
|
|
Assert.Ignore ("There are no device types in the iOS 9 simulator that the 8.1 simulator (earliest simulator Xcode 7 can run) doesn't support, so there's no way to produce the MT1211 error");
|
|
Asserts.Throws<TestExecutionException> (() => ExecutionHelper.Execute (TestTarget.ToolPath,"--sdkroot " + Configuration.xcode_root + " --launchsim /path/to/somewhere --device=:v2;runtime=com.apple.CoreSimulator.SimRuntime.iOS-7-1,devicetype=com.apple.CoreSimulator.SimDeviceType.Apple-Watch-38mm"),
|
|
"error MT1211: The simulator version '7.1' does not support the simulator type 'Resizable iPhone'\n");
|
|
}
|
|
|
|
// MT1213: unused
|
|
// MT1214: unused
|
|
// MT1215: unused
|
|
|
|
[Test]
|
|
public void MT1216 ()
|
|
{
|
|
using (var mtouch = new MTouchTool ()) {
|
|
mtouch.AppPath = "/tmp";
|
|
mtouch.Device = ":v2;udid=unknown";
|
|
Assert.AreEqual (1, mtouch.Execute (MTouchAction.LaunchSim), "launch");
|
|
mtouch.HasError ("MT", 1216, "Could not find the simulator UDID 'unknown'.");
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
public void MT5211_UnifiedApp ()
|
|
{
|
|
var testDir = GetTempDirectory ();
|
|
|
|
try {
|
|
var app = Path.Combine (testDir, "testApp.app");
|
|
Directory.CreateDirectory (app);
|
|
|
|
var code = @"
|
|
using System;
|
|
using System.Runtime.InteropServices;
|
|
using UIKit;
|
|
using Foundation;
|
|
|
|
class Test {
|
|
[Register (""Inexistent"", true)]
|
|
public class Inexistent : NSObject {}
|
|
|
|
public class Subexistent : Inexistent { }
|
|
|
|
static void Main ()
|
|
{
|
|
Console.WriteLine (typeof (Subexistent));
|
|
}
|
|
}
|
|
";
|
|
var exe = CompileTestAppExecutable (testDir, code, profile: MTouch.Profile.Unified);
|
|
var cache = Path.Combine (testDir, "mtouch-cache");
|
|
|
|
var mtouch = new MTouchTool ();
|
|
|
|
Assert.AreEqual (1, mtouch.Execute ("-sdkroot {5} --dev {0} -sdk {4} -targetver {4} --abi=armv7,arm64 {1} --cache={2} --r:{3}", app, exe, cache, Configuration.XamarinIOSDll, Configuration.sdk_version, Configuration.xcode_root), "build failure expected");
|
|
|
|
mtouch.AssertOutputPattern ("Undefined symbols for architecture arm64:");
|
|
mtouch.AssertOutputPattern (".*_OBJC_METACLASS_._Inexistent., referenced from:.*");
|
|
mtouch.AssertOutputPattern (".*_OBJC_METACLASS_._Test_Subexistent in registrar.arm64.o.*");
|
|
mtouch.AssertOutputPattern (".*_OBJC_CLASS_._Inexistent., referenced from:.*");
|
|
mtouch.AssertOutputPattern (".*_OBJC_CLASS_._Test_Subexistent in registrar.arm64.o.*");
|
|
mtouch.AssertOutputPattern (".*objc-class-ref in registrar.arm64.o.*");
|
|
mtouch.AssertOutputPattern (".*ld: symbol.s. not found for architecture arm64.*");
|
|
mtouch.AssertOutputPattern (".*clang: error: linker command failed with exit code 1 .use -v to see invocation.*");
|
|
|
|
mtouch.AssertErrorPattern ("MT", 5210, "Native linking failed, undefined symbol: _OBJC_METACLASS_._Inexistent. Please verify that all the necessary frameworks have been referenced and native libraries are properly linked in.");
|
|
mtouch.AssertErrorPattern ("MT", 5211, "Native linking failed, undefined Objective-C class: Inexistent. The symbol ._OBJC_CLASS_._Inexistent. could not be found in any of the libraries or frameworks linked with your application.");
|
|
mtouch.AssertErrorPattern ("MT", 5202, "Native linking failed. Please review the build log.");
|
|
} finally {
|
|
Directory.Delete (testDir, true);
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
public void MT5214 ()
|
|
{
|
|
var testDir = GetTempDirectory ();
|
|
var app = Path.Combine (testDir, "testApp.app");
|
|
Directory.CreateDirectory (app);
|
|
|
|
try {
|
|
var code = @"
|
|
using System;
|
|
using System.Runtime.InteropServices;
|
|
|
|
namespace UIKit {
|
|
}
|
|
|
|
namespace MonoTouch.UIKit {
|
|
class Test {
|
|
[DllImport (""__Internal"")]
|
|
public static extern void InexistentFunc ();
|
|
|
|
static void Main ()
|
|
{
|
|
Console.WriteLine (typeof (UIWindow));
|
|
}
|
|
|
|
}
|
|
}
|
|
";
|
|
var exe = CompileTestAppExecutable (testDir, code);
|
|
var cache = Path.Combine (testDir, "mtouch-cache");
|
|
|
|
var args = string.Format ("-sdkroot " + Configuration.xcode_root + " --nosign --nolink --sim {0} -sdk {4} -targetver {4} --abi=i386 {1} --cache={2} --r:{3} -nofastsim", app, exe, cache, Configuration.MonoTouchDll, Configuration.sdk_version);
|
|
Asserts.ThrowsPattern<TestExecutionException> (() => ExecutionHelper.Execute (TestTarget.ToolPath, args, hide_output: false),
|
|
"Xamarin.iOS .* using framework:.*\n" +
|
|
"Process exited with code 1.*\n" +
|
|
"/Applications/.*clang.*\n" +
|
|
"Undefined symbols.*\n" +
|
|
".*_InexistentFunc.*\n" +
|
|
".*command line option.*\n" +
|
|
".*ld: symbol.*not found.*\n" +
|
|
".*clang: error.*\n" +
|
|
"\n" +
|
|
"error MT5214: Native linking failed, undefined symbol: _InexistentFunc. This symbol was referenced by the managed member MonoTouch.UIKit.Test.InexistentFunc. Please verify that all the necessary frameworks have been referenced and native libraries linked.\n" +
|
|
"error MT5202: Native linking failed. Please review the build log.\n");
|
|
} finally {
|
|
Directory.Delete (testDir, true);
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
public void TestCaseMismatchedAssemblyName ()
|
|
{
|
|
// desk #90367 (and others in the past as well)
|
|
|
|
var testDir = GetTempDirectory ();
|
|
var app = Path.Combine (testDir, "testApp.app");
|
|
Directory.CreateDirectory (testDir);
|
|
|
|
try {
|
|
string dllcs = Path.Combine (testDir, "testLibrary.cs");
|
|
string exe = Path.Combine (testDir, "testApp.exe");
|
|
string dll = Path.Combine (testDir, "testLibrary.dll");
|
|
string DLL = Path.Combine (testDir, "TESTLIBRARY.dll");
|
|
string args;
|
|
string output;
|
|
|
|
File.WriteAllText (dllcs, "public class TestLib { public TestLib () { System.Console.WriteLine (typeof (UIKit.UIWindow).ToString ()); } }");
|
|
|
|
args = string.Format ("\"{0}\" /debug:full /noconfig /t:library /nologo /out:\"{1}\" /r:" + Configuration.XamarinIOSDll, dllcs, dll);
|
|
File.WriteAllText (DLL + ".config", "");
|
|
if (ExecutionHelper.Execute (Configuration.SmcsPath, args, out output) != 0)
|
|
throw new Exception (output);
|
|
|
|
var execs = @"public class TestApp {
|
|
static void Main ()
|
|
{
|
|
System.Console.WriteLine (typeof (UIKit.UIWindow).ToString ());
|
|
System.Console.WriteLine (new TestLib ());
|
|
}
|
|
}";
|
|
|
|
var exeF = Path.Combine (testDir, "testExe.cs");
|
|
|
|
File.WriteAllText (exeF, execs);
|
|
|
|
var cmds = string.Format ("\"{0}\" /noconfig /t:exe /nologo /out:\"{1}\" \"/r:{2}\" -r:{3}", exeF, exe, dll, Configuration.XamarinIOSDll);
|
|
if (ExecutionHelper.Execute (Configuration.SmcsPath, cmds, out output) != 0)
|
|
throw new Exception (output);
|
|
|
|
File.Move (dll, DLL);
|
|
|
|
Action<string> check = (v) =>
|
|
{
|
|
var msg = new StringBuilder ();
|
|
int counter = 0;
|
|
foreach (var file in Directory.EnumerateFiles (app, "*", SearchOption.AllDirectories)) {
|
|
if (file.Contains ("TESTLIBRARY")) {
|
|
msg.AppendFormat ("File {0} has incorrect case.\n", file);
|
|
}
|
|
counter++;
|
|
}
|
|
Console.WriteLine ("Checked {0} files", counter);
|
|
if (msg.Length > 0)
|
|
Assert.Fail (v + "\n" + msg.ToString ());
|
|
};
|
|
|
|
string [][] tests = new string[][] {
|
|
new string [] { "linkall", "-sdkroot {0} --dev {1} -sdk {2} --targetver {2} --abi=armv7s {3} -debug -r:{4} -r:{5}" },
|
|
new string [] { "dontlink", "-sdkroot {0} --dev {1} -sdk {2} --targetver {2} --abi=armv7s {3} -debug -r:{4} -r:{5} --nolink" },
|
|
new string [] { "dual", "-sdkroot {0} --dev {1} -sdk {2} --targetver {2} --abi=armv7,arm64 {3} -debug -r:{4} -r:{5}" }
|
|
};
|
|
|
|
foreach (var kvp in tests) {
|
|
var name = kvp [0];
|
|
var format = kvp [1];
|
|
var mtouch_fmt = string.Format (format, Configuration.xcode_root, app, Configuration.sdk_version, exe, Configuration.XamarinIOSDll, DLL);
|
|
Directory.CreateDirectory (app);
|
|
ExecutionHelper.Execute (TestTarget.ToolPath, mtouch_fmt, hide_output: false);
|
|
check (name);
|
|
Directory.Delete (app, true);
|
|
}
|
|
|
|
} finally {
|
|
Directory.Delete (testDir, true);
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
public void TestDuplicatedFatApp ()
|
|
{
|
|
var testDir = GetTempDirectory ();
|
|
var app = Path.Combine (testDir, "testApp.app");
|
|
Directory.CreateDirectory (app);
|
|
|
|
try {
|
|
var exe = CompileUnifiedTestAppExecutable (testDir);
|
|
var cache = Path.Combine (testDir, "mtouch-cache");
|
|
|
|
var args = string.Format ("-sdkroot {5} --dev {0} -sdk {4} -targetver {4} --abi=armv7,arm64 {1} --cache={2} --r:{3} ", app, exe, cache, Configuration.XamarinIOSDll, Configuration.sdk_version, Configuration.xcode_root);
|
|
ExecutionHelper.Execute (TestTarget.ToolPath, args, hide_output: false);
|
|
var ufe = Mono.Unix.UnixFileInfo.GetFileSystemEntry (Path.Combine (app, ".monotouch-32", "testApp.exe"));
|
|
Assert.IsTrue (ufe.IsSymbolicLink, "testApp.exe IsSymbolicLink");
|
|
} finally {
|
|
Directory.Delete (testDir, true);
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
public void TestAllLoad ()
|
|
{
|
|
var testDir = GetTempDirectory ();
|
|
var app = Path.Combine (testDir, "testApp.app");
|
|
Directory.CreateDirectory (app);
|
|
|
|
try {
|
|
var exe = CompileUnifiedTestAppExecutable (testDir);
|
|
var cache = Path.Combine (testDir, "mtouch-cache");
|
|
|
|
var args = string.Format ("-sdkroot {5} --dev {0} -sdk {4} -targetver {4} --abi=armv7,arm64 {1} --cache={2} --r:{3} -gcc_flags -all_load", app, exe, cache, Configuration.XamarinIOSDll, Configuration.sdk_version, Configuration.xcode_root);
|
|
ExecutionHelper.Execute (TestTarget.ToolPath, args, hide_output: false);
|
|
} finally {
|
|
Directory.Delete (testDir, true);
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
public void ListDev ()
|
|
{
|
|
ExecutionHelper.Execute (TestTarget.ToolPath, string.Format ("--listdev --sdkroot {0}", Configuration.xcode_root));
|
|
}
|
|
|
|
[Test]
|
|
public void LaunchOnDevice ()
|
|
{
|
|
var mtouch = new MTouchTool ();
|
|
var devices = mtouch.FindAvailableDevices (new string [] { "iPad", "iPhone" }).ToArray ();
|
|
if (devices.Length == 0)
|
|
Assert.Ignore ("Could not find any connected devices.");
|
|
|
|
var projectDir = Path.Combine (Configuration.SourceRoot, "tests", "link all");
|
|
var project = Path.Combine (projectDir, "link all.csproj");
|
|
XBuild.Build (project, platform: "iPhone");
|
|
var appPath = Path.Combine (projectDir, "bin", "iPhone", "Debug", "link all.app");
|
|
foreach (var device in devices) {
|
|
if (mtouch.InstallOnDevice (device, appPath) != 0) {
|
|
Console.WriteLine ("Could not install on the device '{0}'.", device);
|
|
continue;
|
|
}
|
|
if (mtouch.LaunchOnDevice (device, appPath, false, false) != 0) {
|
|
if (mtouch.HasErrorPattern ("MT", 1031, "Could not launch the app '.*' on the device '.*' because the device is locked. Please unlock the device and try again."))
|
|
continue;
|
|
Assert.Fail ("Failed to launch on device.");
|
|
} else {
|
|
return;
|
|
}
|
|
}
|
|
|
|
Assert.Ignore ("Could not find any non-locked devices.");
|
|
}
|
|
|
|
[Test]
|
|
public void LaunchOnWatchDevice ()
|
|
{
|
|
var mtouch = new MTouchTool ();
|
|
mtouch.Verbosity = 2;
|
|
var devices = mtouch.FindAvailableDevices (new string [] { "Watch" }).ToArray ();
|
|
if (devices.Length == 0)
|
|
Assert.Ignore ("Could not find any connected watches.");
|
|
|
|
var projectDir = Path.Combine (Configuration.SourceRoot, "msbuild", "tests", "MyWatch2Container");
|
|
var project = Path.Combine (projectDir, "MyWatch2Container.csproj");
|
|
var containerPath = Path.Combine (projectDir, "bin", "iPhone", "Debug", "MyWatch2Container.app");
|
|
var appPath = Path.Combine (containerPath, "Watch", "MyWatchApp2.app");
|
|
|
|
XBuild.Build (project, platform: "iPhone");
|
|
if (!Directory.Exists (appPath))
|
|
Assert.Fail ("Failed to build the watchOS app.");
|
|
|
|
foreach (var device in devices) {
|
|
if (device.Companion == null)
|
|
continue;
|
|
|
|
if (mtouch.InstallOnDevice (device.Companion, containerPath, "ios,watch") != 0) {
|
|
Console.WriteLine ("Could not install on the phone '{0}'. Trying another one.", device.Name);
|
|
continue;
|
|
}
|
|
|
|
if (mtouch.LaunchOnDevice (device, appPath, false, false) != 0) {
|
|
if (mtouch.HasErrorPattern ("MT", 1031, "Could not launch the app '.*' on the device '.*' because the device is locked. Please unlock the device and try again."))
|
|
continue;
|
|
Assert.Fail ("Failed to launch on device.");
|
|
} else {
|
|
return;
|
|
}
|
|
}
|
|
|
|
Assert.Ignore ("Could not find any suitable devices.");
|
|
}
|
|
|
|
[Test]
|
|
[TestCase (Profile.Unified)]
|
|
public void DlsymDisabled (Profile profile)
|
|
{
|
|
using (var tool = new MTouchTool ()) {
|
|
tool.Profile = profile;
|
|
tool.Verbosity = 5;
|
|
tool.Cache = Path.Combine (tool.CreateTemporaryDirectory (), "mtouch-test-cache");
|
|
tool.CreateTemporaryApp ("using UIKit; class C { static void Main (string[] args) { UIApplication.Main (args); } }");
|
|
tool.FastDev = true;
|
|
tool.Dlsym = false;
|
|
|
|
Assert.AreEqual (0, tool.Execute (MTouchAction.BuildDev));
|
|
}
|
|
}
|
|
|
|
#region Helper functions
|
|
static string CompileUnifiedTestAppExecutable (string targetDirectory, string code = null, string extraArg = "")
|
|
{
|
|
return CompileTestAppExecutable (targetDirectory, code, extraArg, profile: MTouch.Profile.Unified);
|
|
}
|
|
|
|
public static string CompileTestAppExecutable (string targetDirectory, string code = null, string extraArg = "", Profile profile = Profile.Classic)
|
|
{
|
|
string cs = Path.Combine (targetDirectory, "testApp.cs");
|
|
string exe = Path.Combine (targetDirectory, "testApp.exe");
|
|
var root_library = GetBaseLibrary (profile);
|
|
|
|
if (code == null) {
|
|
if (profile != Profile.Classic) {
|
|
code = "public class TestApp { static void Main () { System.Console.WriteLine (typeof (ObjCRuntime.Runtime).ToString ()); } }";
|
|
} else {
|
|
code = "public class TestApp { static void Main () { System.Console.WriteLine (typeof (MonoTouch.ObjCRuntime.Runtime).ToString ()); } }";
|
|
}
|
|
}
|
|
|
|
File.WriteAllText (cs, code);
|
|
|
|
string output;
|
|
StringBuilder args = new StringBuilder ();
|
|
string fileName = GetCompiler (profile, args);
|
|
args.AppendFormat (" /noconfig /t:exe /nologo /out:{1} /r:{0} {2} {3}", Quote (root_library), Quote (exe), cs, extraArg);
|
|
if (ExecutionHelper.Execute (fileName, args.ToString (), out output) != 0) {
|
|
Console.WriteLine ("{0} {1}", fileName, args);
|
|
Console.WriteLine (output);
|
|
throw new Exception (output);
|
|
}
|
|
|
|
return exe;
|
|
}
|
|
|
|
static string CreateBindingLibrary (string targetDirectory, string nativeCode, string bindingCode, string linkWith = null, string extraCode = "")
|
|
{
|
|
var o = CompileNativeLibrary (targetDirectory, nativeCode);
|
|
var cs = Path.Combine (targetDirectory, "bindingCode.cs");
|
|
var dll = Path.Combine (targetDirectory, "bindingLibrary.dll");
|
|
|
|
if (linkWith == null) {
|
|
linkWith = @"
|
|
using System;
|
|
using MonoTouch.ObjCRuntime;
|
|
|
|
[assembly: LinkWith (""{0}"", LinkTarget.ArmV7, ForceLoad = true, SmartLink = true)]
|
|
";
|
|
linkWith = string.Format (linkWith, Path.GetFileName (o));
|
|
}
|
|
|
|
File.WriteAllText (cs, bindingCode);
|
|
|
|
extraCode = linkWith + "\n" + extraCode;
|
|
|
|
var x = Path.Combine (targetDirectory, "extraBindingCode.cs");
|
|
File.WriteAllText (x, extraCode);
|
|
|
|
ExecutionHelper.Execute (Configuration.BtouchPath,
|
|
string.Format ("{0} --out:{1} --link-with={2},{3} -x:{4}", cs, dll, o, Path.GetFileName (o), x));
|
|
|
|
return dll;
|
|
}
|
|
|
|
static string CompileNativeLibrary (string targetDirectory, string code)
|
|
{
|
|
var m = Path.Combine (targetDirectory, "testCode.m");
|
|
|
|
File.WriteAllText (m, code);
|
|
|
|
string output;
|
|
string fileName = Path.Combine (Configuration.xcode_root, "Toolchains/XcodeDefault.xctoolchain/usr/bin/clang");
|
|
string args = string.Format ("-gdwarf-2 -arch armv7 -std=c99 -isysroot {0}/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS{2}.sdk -miphoneos-version-min=3.1 " +
|
|
"-c -DDEBUG -o {1}/testCode.o -x objective-c {1}/testCode.m",
|
|
Configuration.xcode_root, targetDirectory, Configuration.sdk_version);
|
|
|
|
if (ExecutionHelper.Execute (fileName, args, out output) != 0) {
|
|
Console.WriteLine ("{0} {1}", fileName, args);
|
|
Console.WriteLine (output);
|
|
throw new Exception (output);
|
|
}
|
|
|
|
return Path.Combine (targetDirectory, "testCode.o");
|
|
}
|
|
|
|
void CompileCSharpCode (Profile profile, string code, string outputPath, params string[] additional_arguments)
|
|
{
|
|
code = code.Replace ("%PROFILE_NAMESPACE%", profile == Profile.Classic ? "MonoTouch." : string.Empty);
|
|
var tmpFile = Path.GetTempFileName ();
|
|
try {
|
|
File.WriteAllText (tmpFile, code);
|
|
|
|
string output;
|
|
var args = new StringBuilder ();
|
|
var compiler = GetCompiler (profile, args);
|
|
|
|
args.Append (" -target:").Append (outputPath.EndsWith (".dll") ? "library" : "exe");
|
|
args.Append (" -r:").Append (Quote (GetBaseLibrary (profile)));
|
|
args.Append (" -out:").Append (Quote (outputPath));
|
|
args.Append (" ").Append (Quote (tmpFile));
|
|
foreach (var aa in additional_arguments)
|
|
args.Append (" ").Append (aa);
|
|
|
|
if (ExecutionHelper.Execute (compiler, args.ToString (), out output) != 0)
|
|
throw new Exception (output);
|
|
} finally {
|
|
File.Delete (tmpFile);
|
|
}
|
|
}
|
|
|
|
static Dictionary<Profile, string> compiled_linkwith_apps = new Dictionary<Profile, string> ();
|
|
public static string CompileTestAppExecutableLinkWith (string targetDirectory, Profile profile = Profile.Classic)
|
|
{
|
|
string compiled_linkwith_app;
|
|
if (compiled_linkwith_apps.TryGetValue (profile, out compiled_linkwith_app) && File.Exists (compiled_linkwith_app))
|
|
return compiled_linkwith_app;
|
|
|
|
string cs = Path.Combine (targetDirectory, "testApp.cs");
|
|
string exe = Path.Combine (targetDirectory, "testApp" + GetProjectSuffix (profile) + ".exe");
|
|
string ns_prefix = profile == Profile.Classic ? "MonoTouch." : string.Empty;
|
|
File.WriteAllText (cs, string.Format (@"
|
|
using System;
|
|
public class TestApp {{
|
|
static void Main ()
|
|
{{
|
|
Console.WriteLine (typeof ({0}UIKit.UIWindow).ToString ());
|
|
Console.WriteLine (Bindings.Test.CFunctions.theUltimateAnswer ());
|
|
Console.WriteLine (typeof (Bindings.Test.UltimateMachine).ToString ());
|
|
}}
|
|
}}", ns_prefix));
|
|
|
|
string output;
|
|
var args = new StringBuilder ();
|
|
args.AppendFormat ("\"{0}\" /noconfig /t:exe /nologo /out:\"{1}\" \"/r:{2}\" /r:\"{3}\"", cs, exe, GetBaseLibrary (profile), GetBindingsLibrary (profile));
|
|
var compiler = GetCompiler (profile, args);
|
|
if (ExecutionHelper.Execute (compiler, args.ToString (), out output) != 0)
|
|
throw new Exception (output);
|
|
|
|
compiled_linkwith_apps [profile] = exe;
|
|
return exe;
|
|
}
|
|
|
|
static void VerifyGC (string file, bool isBoehm, string message)
|
|
{
|
|
var symbols = ExecutionHelper.Execute ("nm", file, hide_output: true);
|
|
var _sgen_gc_lock = symbols.Contains ("_sgen_gc_lock");
|
|
if (isBoehm && _sgen_gc_lock) {
|
|
Assert.Fail ("Expected '{0}' to use Boehm: {1}", file, message);
|
|
} else if (!isBoehm && !_sgen_gc_lock) {
|
|
Assert.Fail ("Expected '{0}' to use SGen: {1}", file, message);
|
|
}
|
|
}
|
|
|
|
static void VerifyArchitectures (string file, string message, params string[] expected)
|
|
{
|
|
var actual = GetArchitectures (file).ToArray ();
|
|
|
|
Array.Sort (expected);
|
|
Array.Sort (actual);
|
|
|
|
var e = string.Join (", ", expected);
|
|
var a = string.Join (", ", actual);
|
|
|
|
Assert.AreEqual (e, a, message);
|
|
}
|
|
|
|
static void VerifyOutput (string msg, string actual, params string[] expected)
|
|
{
|
|
var split = actual.Split (new char[] {'\n', '\r'}, StringSplitOptions.RemoveEmptyEntries);
|
|
var actual_messages = new HashSet<string> (split, new Registrar.PatternEquality ());
|
|
var exp_messages = new HashSet<string> (expected, new Registrar.PatternEquality ());
|
|
|
|
actual_messages.ExceptWith (exp_messages);
|
|
exp_messages.ExceptWith (split);
|
|
|
|
var text = new StringBuilder ();
|
|
foreach (var a in actual_messages)
|
|
text.AppendFormat ("Unexpected error/warning ({0}):\n\t{1}\n", msg, a);
|
|
foreach (var a in exp_messages)
|
|
text.AppendFormat ("Expected error/warning not shown ({0}):\n\t{1}\n", msg, a);
|
|
if (text.Length != 0)
|
|
Assert.Fail (text.ToString ());
|
|
}
|
|
|
|
static List<string> GetArchitectures (string file)
|
|
{
|
|
var result = new List<string> ();
|
|
|
|
using (var fs = File.OpenRead (file)) {
|
|
using (var reader = new BinaryReader (fs)) {
|
|
int magic = reader.ReadInt32 ();
|
|
switch ((uint) magic) {
|
|
case 0xCAFEBABE: // little-endian fat binary
|
|
throw new NotImplementedException ("little endian fat binary");
|
|
case 0xBEBAFECA:
|
|
int architectures = System.Net.IPAddress.NetworkToHostOrder (reader.ReadInt32 ());
|
|
for (int i = 0; i < architectures; i++) {
|
|
result.Add (GetArch (System.Net.IPAddress.NetworkToHostOrder (reader.ReadInt32 ()), System.Net.IPAddress.NetworkToHostOrder (reader.ReadInt32 ())));
|
|
// skip to next entry
|
|
reader.ReadInt32 (); // offset
|
|
reader.ReadInt32 (); // size
|
|
reader.ReadInt32 (); // align
|
|
}
|
|
break;
|
|
case 0xFEEDFACE: // little-endian mach-o header
|
|
case 0xFEEDFACF: // little-endian 64-big mach-o header
|
|
result.Add (GetArch (reader.ReadInt32 (), reader.ReadInt32 ()));
|
|
break;
|
|
case 0xCFFAEDFE:
|
|
case 0xCEFAEDFE:
|
|
result.Add (GetArch (System.Net.IPAddress.NetworkToHostOrder (reader.ReadInt32 ()), System.Net.IPAddress.NetworkToHostOrder (reader.ReadInt32 ())));
|
|
break;
|
|
default:
|
|
throw new Exception (string.Format ("File '{0}' is neither a Universal binary nor a Mach-O binary (magic: 0x{1})", file, magic.ToString ("x")));
|
|
}
|
|
}
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
static string GetArch (int cputype, int cpusubtype)
|
|
{
|
|
const int ABI64 = 0x01000000;
|
|
const int X86 = 7;
|
|
const int ARM = 12;
|
|
|
|
switch (cputype) {
|
|
case ARM : // arm
|
|
switch (cpusubtype) {
|
|
case 6: return "armv6";
|
|
case 9: return "armv7";
|
|
case 11: return "armv7s";
|
|
default:
|
|
return "unknown arm variation: " + cpusubtype.ToString ();
|
|
}
|
|
case ARM | ABI64:
|
|
switch (cpusubtype) {
|
|
case 0:
|
|
return "arm64";
|
|
default:
|
|
return "unknown arm/64 variation: " + cpusubtype.ToString ();
|
|
}
|
|
case X86: // x86
|
|
return "i386";
|
|
case X86 | ABI64: // x64
|
|
return "x86_64";
|
|
}
|
|
|
|
return string.Format ("unknown: {0}/{1}", cputype, cpusubtype);
|
|
}
|
|
|
|
public static string Quote (string f)
|
|
{
|
|
if (f.IndexOf (' ') == -1 && f.IndexOf ('\'') == -1 && f.IndexOf (',') == -1)
|
|
return f;
|
|
|
|
var s = new StringBuilder ();
|
|
|
|
s.Append ('"');
|
|
foreach (var c in f){
|
|
if (c == '"' || c == '\\')
|
|
s.Append ('\\');
|
|
|
|
s.Append (c);
|
|
}
|
|
s.Append ('"');
|
|
|
|
return s.ToString ();
|
|
}
|
|
|
|
public static string GetTempDirectory ()
|
|
{
|
|
var tmp = Path.GetTempFileName ();
|
|
File.Delete (tmp);
|
|
Directory.CreateDirectory (tmp);
|
|
return tmp;
|
|
}
|
|
#endregion
|
|
}
|
|
|
|
class McsException : Exception {
|
|
public McsException (string output)
|
|
: base (output)
|
|
{
|
|
}
|
|
}
|
|
|
|
class ActivationException : Exception {
|
|
public ActivationException (string output)
|
|
: base (output)
|
|
{
|
|
}
|
|
}
|
|
}
|