From e3617eb4780a4c46f78f4c29b1c33056620b06c2 Mon Sep 17 00:00:00 2001 From: Maxim Lipnin Date: Wed, 6 Jan 2021 22:01:22 +0300 Subject: [PATCH] [mono] Add functional tests for the supported platforms (#46286) Part of https://github.com/dotnet/runtime/issues/43865 The functional tests: - live under src/tests/FunctionalTests directory. - are built as a part of the library tests build. - are isolated from the build/test setup used for the tests in src/tests - run on CI --- src/libraries/sendtohelixhelp.proj | 28 +++++--- src/libraries/tests.proj | 28 +++++--- .../netcore/sample/Android/AndroidSampleApp.csproj | 12 ++-- src/mono/netcore/sample/wasm/browser/Makefile | 2 +- ...asmSample.csproj => Wasm.Browser.Sample.csproj} | 7 +- src/mono/netcore/sample/wasm/browser/index.html | 2 +- src/mono/netcore/sample/wasm/console/Makefile | 4 +- ...asmSample.csproj => Wasm.Console.Sample.csproj} | 4 +- src/mono/wasm/build/WasmApp.targets | 20 +++--- src/tests/Common/dirs.proj | 1 + .../FunctionalTests/Android/Emulator/AOT/README.md | 1 + .../Android.Emulator.Interpreter.Test.csproj | 81 ++++++++++++++++++++++ .../Android/Emulator/Interpreter/Program.cs | 13 ++++ src/tests/FunctionalTests/Android/common.props | 13 ++++ src/tests/FunctionalTests/Directory.Build.props | 9 +++ src/tests/FunctionalTests/Directory.Build.targets | 3 + src/tests/FunctionalTests/README.md | 7 ++ .../FunctionalTests/iOS/Simulator/AOT/Program.cs | 54 +++++++++++++++ .../FunctionalTests/iOS/Simulator/AOT/README.md | 4 ++ .../Simulator/AOT/iOS.Simulator.Aot.Test.csproj | 66 ++++++++++++++++++ src/tests/FunctionalTests/iOS/Simulator/AOT/main.m | 80 +++++++++++++++++++++ .../iOS/Simulator/Interpreter/Program.cs | 54 +++++++++++++++ .../iOS/Simulator/Interpreter/README.md | 3 + .../iOS.Simulator.Interpreter.Test.csproj | 45 ++++++++++++ .../iOS/Simulator/Interpreter/main.m | 80 +++++++++++++++++++++ src/tests/FunctionalTests/iOS/common.props | 14 ++++ src/tests/FunctionalTests/iOS/common.targets | 29 ++++++++ .../FunctionalTests/wasm/AOT/browser/Program.cs | 22 ++++++ .../wasm/AOT/browser/Wasm.Aot.Browser.Test.csproj | 35 ++++++++++ .../FunctionalTests/wasm/AOT/browser/index.html | 57 +++++++++++++++ .../FunctionalTests/wasm/AOT/browser/runtime.js | 26 +++++++ .../FunctionalTests/wasm/AOT/console/Program.cs | 18 +++++ .../wasm/AOT/console/Wasm.Aot.Console.Test.csproj | 29 ++++++++ .../wasm/Interpreter/browser/Program.cs | 22 ++++++ .../browser/Wasm.Interpreter.Browser.Test.csproj | 34 +++++++++ .../wasm/Interpreter/browser/index.html | 57 +++++++++++++++ .../wasm/Interpreter/browser/runtime.js | 26 +++++++ .../wasm/Interpreter/console/Program.cs | 18 +++++ .../console/Wasm.Interpreter.Console.Test.csproj | 28 ++++++++ src/tests/FunctionalTests/wasm/common.props | 27 ++++++++ src/tests/FunctionalTests/wasm/common.targets | 27 ++++++++ 41 files changed, 1046 insertions(+), 44 deletions(-) rename src/mono/netcore/sample/wasm/browser/{WasmSample.csproj => Wasm.Browser.Sample.csproj} (91%) rename src/mono/netcore/sample/wasm/console/{WasmSample.csproj => Wasm.Console.Sample.csproj} (95%) create mode 100644 src/tests/FunctionalTests/Android/Emulator/AOT/README.md create mode 100644 src/tests/FunctionalTests/Android/Emulator/Interpreter/Android.Emulator.Interpreter.Test.csproj create mode 100644 src/tests/FunctionalTests/Android/Emulator/Interpreter/Program.cs create mode 100644 src/tests/FunctionalTests/Android/common.props create mode 100644 src/tests/FunctionalTests/Directory.Build.props create mode 100644 src/tests/FunctionalTests/Directory.Build.targets create mode 100644 src/tests/FunctionalTests/README.md create mode 100644 src/tests/FunctionalTests/iOS/Simulator/AOT/Program.cs create mode 100644 src/tests/FunctionalTests/iOS/Simulator/AOT/README.md create mode 100644 src/tests/FunctionalTests/iOS/Simulator/AOT/iOS.Simulator.Aot.Test.csproj create mode 100644 src/tests/FunctionalTests/iOS/Simulator/AOT/main.m create mode 100644 src/tests/FunctionalTests/iOS/Simulator/Interpreter/Program.cs create mode 100644 src/tests/FunctionalTests/iOS/Simulator/Interpreter/README.md create mode 100644 src/tests/FunctionalTests/iOS/Simulator/Interpreter/iOS.Simulator.Interpreter.Test.csproj create mode 100644 src/tests/FunctionalTests/iOS/Simulator/Interpreter/main.m create mode 100644 src/tests/FunctionalTests/iOS/common.props create mode 100644 src/tests/FunctionalTests/iOS/common.targets create mode 100644 src/tests/FunctionalTests/wasm/AOT/browser/Program.cs create mode 100644 src/tests/FunctionalTests/wasm/AOT/browser/Wasm.Aot.Browser.Test.csproj create mode 100644 src/tests/FunctionalTests/wasm/AOT/browser/index.html create mode 100644 src/tests/FunctionalTests/wasm/AOT/browser/runtime.js create mode 100644 src/tests/FunctionalTests/wasm/AOT/console/Program.cs create mode 100644 src/tests/FunctionalTests/wasm/AOT/console/Wasm.Aot.Console.Test.csproj create mode 100644 src/tests/FunctionalTests/wasm/Interpreter/browser/Program.cs create mode 100644 src/tests/FunctionalTests/wasm/Interpreter/browser/Wasm.Interpreter.Browser.Test.csproj create mode 100644 src/tests/FunctionalTests/wasm/Interpreter/browser/index.html create mode 100644 src/tests/FunctionalTests/wasm/Interpreter/browser/runtime.js create mode 100644 src/tests/FunctionalTests/wasm/Interpreter/console/Program.cs create mode 100644 src/tests/FunctionalTests/wasm/Interpreter/console/Wasm.Interpreter.Console.Test.csproj create mode 100644 src/tests/FunctionalTests/wasm/common.props create mode 100644 src/tests/FunctionalTests/wasm/common.targets diff --git a/src/libraries/sendtohelixhelp.proj b/src/libraries/sendtohelixhelp.proj index 6f29d17..3f29c4b 100644 --- a/src/libraries/sendtohelixhelp.proj +++ b/src/libraries/sendtohelixhelp.proj @@ -169,6 +169,16 @@ + + + armeabi-v7a + arm64-v8a + x86_64 + x86 + net.dot.MonoRunner + $(_workItemTimeout) + + <_apks Include="$(TestArchiveTestsRoot)**/*.apk" /> - armeabi-v7a - arm64-v8a - x86_64 - x86 net.dot.%(Filename) - net.dot.MonoRunner - - $(_workItemTimeout) + + <_runonlyApks Include="$(TestArchiveRoot)runonly/**/*.apk" /> + + net.dot.%(Filename) - 42 + 42 @@ -256,7 +262,7 @@ %(Identity) - dotnet exec $XHARNESS_CLI_PATH wasm $XHARNESS_COMMAND --app=. --engine=V8 --engine-arg=--stack-trace-limit=1000 --js-file=runtime.js --output-directory=$HELIX_WORKITEM_UPLOAD_ROOT/xharness-output -- --run WasmSample.dll + dotnet exec $XHARNESS_CLI_PATH wasm $XHARNESS_COMMAND --app=. --engine=V8 --engine-arg=--stack-trace-limit=1000 --js-file=runtime.js --output-directory=$HELIX_WORKITEM_UPLOAD_ROOT/xharness-output -- --run %(FileName).dll @@ -266,7 +272,7 @@ %(Identity) - dotnet exec $XHARNESS_CLI_PATH wasm $XHARNESS_COMMAND --app=. --browser=Chrome --html-file=index.html --output-directory=$HELIX_WORKITEM_UPLOAD_ROOT/xharness-output -- WasmSample.dll --testing + dotnet exec $XHARNESS_CLI_PATH wasm $XHARNESS_COMMAND --app=. --browser=Chrome --html-file=index.html --output-directory=$HELIX_WORKITEM_UPLOAD_ROOT/xharness-output -- %(FileName).dll --testing diff --git a/src/libraries/tests.proj b/src/libraries/tests.proj index 782db42..9783f7c 100644 --- a/src/libraries/tests.proj +++ b/src/libraries/tests.proj @@ -169,15 +169,27 @@ Exclude="@(ProjectExclusions)" BuildInParallel="false" Condition="'$(TestTrimming)' == 'true'" /> - + + + - + BuildInParallel="false" /> + + + + + + + + + + + $(TargetOS).AnyCPU.$(Configuration) - $(ArtifactsDir)helix/ - $(TestArchiveRoot)tests/ - $(TestArchiveTestsRoot)$(OSPlatformConfig)/ + $(ArtifactsDir)helix/ + $(HelixArchiveRoot)runonly/ + $(HelixArchiveRunOnlyRoot)$(OSPlatformConfig)/ - <_appFiles Include="$(ApkBundlePath)" /> + <_apkFiles Include="$(ApkBundlePath)" /> - + diff --git a/src/mono/netcore/sample/wasm/browser/Makefile b/src/mono/netcore/sample/wasm/browser/Makefile index f5d5713..8a243d4 100644 --- a/src/mono/netcore/sample/wasm/browser/Makefile +++ b/src/mono/netcore/sample/wasm/browser/Makefile @@ -16,7 +16,7 @@ CONFIG?=Release all: build build: - EMSDK_PATH=$(realpath $(TOP)/src/mono/wasm/emsdk) $(DOTNET) publish $(DOTNET_Q_ARGS) $(DOTNET_RUN_AOT_COMPILATION_ARGS) /p:Configuration=$(CONFIG) /p:TargetArchitecture=wasm /p:TargetOS=Browser $(MSBUILD_ARGS) WasmSample.csproj + EMSDK_PATH=$(realpath $(TOP)/src/mono/wasm/emsdk) $(DOTNET) publish $(DOTNET_Q_ARGS) $(DOTNET_RUN_AOT_COMPILATION_ARGS) /p:Configuration=$(CONFIG) /p:TargetArchitecture=wasm /p:TargetOS=Browser $(MSBUILD_ARGS) Wasm.Browser.Sample.csproj clean: rm -rf bin diff --git a/src/mono/netcore/sample/wasm/browser/WasmSample.csproj b/src/mono/netcore/sample/wasm/browser/Wasm.Browser.Sample.csproj similarity index 91% rename from src/mono/netcore/sample/wasm/browser/WasmSample.csproj rename to src/mono/netcore/sample/wasm/browser/Wasm.Browser.Sample.csproj index 4f92851..961e8f2 100644 --- a/src/mono/netcore/sample/wasm/browser/WasmSample.csproj +++ b/src/mono/netcore/sample/wasm/browser/Wasm.Browser.Sample.csproj @@ -39,10 +39,9 @@ $(AppDir) - $(MSBuildProjectDirectory)\$(PublishDir)\ - $(MSBuildProjectDirectory)\bin\WasmSample.dll + $(MSBuildProjectDirectory)\$(PublishDir)\ runtime.js - $(WasmAotDir)WasmSample.dll + $(WasmBuildDir)$(AssemblyName).dll @@ -71,7 +70,7 @@ $(ArtifactsDir)helix/ $(HelixArchiveRoot)runonly/ $(HelixArchiveRunOnlyRoot)$(OSPlatformConfig)/browser/ - $(OutputPath)/WasmBrowserSample.zip + $(OutputPath)$(AssemblyName).zip diff --git a/src/mono/netcore/sample/wasm/browser/index.html b/src/mono/netcore/sample/wasm/browser/index.html index ad5cca3..3fc644b 100644 --- a/src/mono/netcore/sample/wasm/browser/index.html +++ b/src/mono/netcore/sample/wasm/browser/index.html @@ -36,7 +36,7 @@ var App = { init: function () { - var ret = BINDING.call_static_method("[WasmSample] Sample.Test:TestMeaning", []); + var ret = BINDING.call_static_method("[Wasm.Browser.Sample] Sample.Test:TestMeaning", []); document.getElementById("out").innerHTML = ret; if (is_testing) diff --git a/src/mono/netcore/sample/wasm/console/Makefile b/src/mono/netcore/sample/wasm/console/Makefile index 7bf3273..f07b469 100644 --- a/src/mono/netcore/sample/wasm/console/Makefile +++ b/src/mono/netcore/sample/wasm/console/Makefile @@ -17,10 +17,10 @@ CONFIG?=Release all: build build: - EMSDK_PATH=$(realpath $(TOP)/src/mono/wasm/emsdk) $(DOTNET) publish $(DOTNET_Q_ARGS) $(DOTNET_RUN_AOT_COMPILATION_ARGS) $(DOTNET_EXTRA_ARGS) /p:TargetArchitecture=wasm /p:TargetOS=Browser /p:Configuration=$(CONFIG) $(MSBUILD_ARGS) WasmSample.csproj + EMSDK_PATH=$(realpath $(TOP)/src/mono/wasm/emsdk) $(DOTNET) publish $(DOTNET_Q_ARGS) $(DOTNET_RUN_AOT_COMPILATION_ARGS) $(DOTNET_EXTRA_ARGS) /p:TargetArchitecture=wasm /p:TargetOS=Browser /p:Configuration=$(CONFIG) $(MSBUILD_ARGS) Wasm.Console.Sample.csproj clean: rm -rf bin run: - cd bin/$(CONFIG)/AppBundle && ~/.jsvu/v8 --expose_wasm runtime.js -- $(DOTNET_MONO_LOG_LEVEL) --run WasmSample.dll + cd bin/$(CONFIG)/AppBundle && ~/.jsvu/v8 --expose_wasm runtime.js -- $(DOTNET_MONO_LOG_LEVEL) --run Wasm.Console.Sample.dll diff --git a/src/mono/netcore/sample/wasm/console/WasmSample.csproj b/src/mono/netcore/sample/wasm/console/Wasm.Console.Sample.csproj similarity index 95% rename from src/mono/netcore/sample/wasm/console/WasmSample.csproj rename to src/mono/netcore/sample/wasm/console/Wasm.Console.Sample.csproj index 4cae8bb..6597c2a 100644 --- a/src/mono/netcore/sample/wasm/console/WasmSample.csproj +++ b/src/mono/netcore/sample/wasm/console/Wasm.Console.Sample.csproj @@ -41,7 +41,7 @@ $(AppBundleDir) $(MSBuildProjectDirectory)\$(PublishDir)\ $(MonoProjectRoot)\wasm\runtime-test.js - $(WasmBuildDir)WasmSample.dll + $(WasmBuildDir)$(AssemblyName).dll true @@ -64,7 +64,7 @@ $(ArtifactsDir)helix/ $(HelixArchiveRoot)runonly/ $(HelixArchiveRunOnlyRoot)$(OSPlatformConfig)/console/ - $(OutputPath)/WasmConsoleSample.zip + $(OutputPath)$(AssemblyName).zip diff --git a/src/mono/wasm/build/WasmApp.targets b/src/mono/wasm/build/WasmApp.targets index a3f2815..e8ee914 100644 --- a/src/mono/wasm/build/WasmApp.targets +++ b/src/mono/wasm/build/WasmApp.targets @@ -48,7 +48,7 @@ UseAotDataFile="false" AotModulesTablePath="$(WasmBuildDir)driver-gen.c" UseLLVM="true" - DisableParallelAot="true" + DisableParallelAot="true" LLVMPath="$(EMSDK_PATH)\upstream\bin"> @@ -104,7 +104,8 @@ <_managedAppAssemblies Include="$(WasmAppDir)managed\*.dll"/> - + + @@ -120,13 +121,15 @@ $(EmccFlags) -s DISABLE_EXCEPTION_CATCHING=0 $(EmccFlags) -DENABLE_AOT=1 -DDRIVER_GEN=1 + <_EmsdkEnvSourceCommand>source $(EMSDK_PATH)/emsdk_env.sh + <_EmccCommand>$(_EmsdkEnvSourceCommand) && emcc - + @@ -166,16 +169,15 @@ <_WasmIncludeDir>$(MicrosoftNetCoreAppRuntimePackRidDir)native/include <_WasmSrcDir>$(MicrosoftNetCoreAppRuntimePackRidDir)native/src - <_WasmEmcc>source $(EMSDK_PATH)/emsdk_env.sh && emcc $(EmccFlags) -DCORE_BINDINGS -DGEN_PINVOKE=1 -I$(WasmBuildDir) -I$(_WasmIncludeDir)/mono-2.0 -I$(_WasmIncludeDir)/wasm $(EmccFlags) -s TOTAL_MEMORY=536870912 - - - - - + + + + + diff --git a/src/tests/Common/dirs.proj b/src/tests/Common/dirs.proj index 27b5afa..e12d882 100644 --- a/src/tests/Common/dirs.proj +++ b/src/tests/Common/dirs.proj @@ -9,6 +9,7 @@ + diff --git a/src/tests/FunctionalTests/Android/Emulator/AOT/README.md b/src/tests/FunctionalTests/Android/Emulator/AOT/README.md new file mode 100644 index 0000000..55f5010 --- /dev/null +++ b/src/tests/FunctionalTests/Android/Emulator/AOT/README.md @@ -0,0 +1 @@ +TO-DO: add the test case for AOT mode when https://github.com/dotnet/runtime/pull/43535 has been completed. \ No newline at end of file diff --git a/src/tests/FunctionalTests/Android/Emulator/Interpreter/Android.Emulator.Interpreter.Test.csproj b/src/tests/FunctionalTests/Android/Emulator/Interpreter/Android.Emulator.Interpreter.Test.csproj new file mode 100644 index 0000000..496926a --- /dev/null +++ b/src/tests/FunctionalTests/Android/Emulator/Interpreter/Android.Emulator.Interpreter.Test.csproj @@ -0,0 +1,81 @@ + + + + + + + + + $(ArtifactsBinDir)microsoft.netcore.app.runtime.$(RuntimeIdentifier)\$(Configuration) + + + + + + + + + + False + True + $(ANDROID_SDK_ROOT)\platform-tools\adb + $(PublishDir)apk\ + + + + + + arm64-v8a + armeabi-v7a + x86_64 + x86 + + + + + + + + + + + + + + + + + + + + + + $(TargetOS).AnyCPU.$(Configuration) + $(ArtifactsDir)helix/ + $(HelixArchiveRoot)runonly/ + $(HelixArchiveRunOnlyRoot)$(OSPlatformConfig)/ + + + <_apkFiles Include="$(ApkBundlePath)" /> + + + + + + + diff --git a/src/tests/FunctionalTests/Android/Emulator/Interpreter/Program.cs b/src/tests/FunctionalTests/Android/Emulator/Interpreter/Program.cs new file mode 100644 index 0000000..7dcc0f3 --- /dev/null +++ b/src/tests/FunctionalTests/Android/Emulator/Interpreter/Program.cs @@ -0,0 +1,13 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; + +public static class Program +{ + public static int Main(string[] args) + { + Console.WriteLine("Hello, Android!"); // logcat + return 42; + } +} diff --git a/src/tests/FunctionalTests/Android/common.props b/src/tests/FunctionalTests/Android/common.props new file mode 100644 index 0000000..714af35 --- /dev/null +++ b/src/tests/FunctionalTests/Android/common.props @@ -0,0 +1,13 @@ + + + Exe + $(AssemblyBinDirOutputPath) + false + $(NetCoreAppToolCurrent) + false + android-$(TargetArchitecture) + true + Link + $(ArtifactsBinDir)microsoft.netcore.app.runtime.$(RuntimeIdentifier)\$(Configuration)\runtimes\android-$(TargetArchitecture)\ + + \ No newline at end of file diff --git a/src/tests/FunctionalTests/Directory.Build.props b/src/tests/FunctionalTests/Directory.Build.props new file mode 100644 index 0000000..31c34b9 --- /dev/null +++ b/src/tests/FunctionalTests/Directory.Build.props @@ -0,0 +1,9 @@ + + + false + false + true + + + + diff --git a/src/tests/FunctionalTests/Directory.Build.targets b/src/tests/FunctionalTests/Directory.Build.targets new file mode 100644 index 0000000..1ceb64b --- /dev/null +++ b/src/tests/FunctionalTests/Directory.Build.targets @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/src/tests/FunctionalTests/README.md b/src/tests/FunctionalTests/README.md new file mode 100644 index 0000000..08bc44e --- /dev/null +++ b/src/tests/FunctionalTests/README.md @@ -0,0 +1,7 @@ +# Functional tests + +This directory contains the functional tests for the supported platforms. + +Currently the functional tests build is incorporated into the library tests build. + +The functional tests run in CI. \ No newline at end of file diff --git a/src/tests/FunctionalTests/iOS/Simulator/AOT/Program.cs b/src/tests/FunctionalTests/iOS/Simulator/AOT/Program.cs new file mode 100644 index 0000000..e6f8b89 --- /dev/null +++ b/src/tests/FunctionalTests/iOS/Simulator/AOT/Program.cs @@ -0,0 +1,54 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Threading; +using System.Threading.Tasks; +using System.Runtime.InteropServices; + +// it's not part of the BCL but runtime needs it for native-to-managed callbacks in AOT +// To be replaced with NativeCallableAttribute +public class MonoPInvokeCallbackAttribute : Attribute +{ + public MonoPInvokeCallbackAttribute(Type delegateType) { } +} + +public static class Program +{ + // Defined in main.m + [DllImport("__Internal")] + private extern static void ios_set_text(string value); + + [DllImport("__Internal")] + private extern static void ios_register_button_click(Action action); + + private static Action buttonClickHandler = null; + + private static int counter = 0; + + // Called by native code, see main.m + [MonoPInvokeCallback(typeof(Action))] + private static void OnButtonClick() + { + ios_set_text("OnButtonClick! #" + counter++); + } + + public static async Task Main(string[] args) + { + // Register a managed callback (will be called by UIButton, see main.m) + // Also, keep the handler alive so GC won't collect it. + ios_register_button_click(buttonClickHandler = OnButtonClick); + + const string msg = "Hello World!\n.NET 5.0"; + for (int i = 0; i < msg.Length; i++) + { + // a kind of an animation + ios_set_text(msg.Substring(0, i + 1)); + await Task.Delay(100); + } + + Console.WriteLine("Done!"); + await Task.Delay(5000); + return 42; + } +} diff --git a/src/tests/FunctionalTests/iOS/Simulator/AOT/README.md b/src/tests/FunctionalTests/iOS/Simulator/AOT/README.md new file mode 100644 index 0000000..5bda04e --- /dev/null +++ b/src/tests/FunctionalTests/iOS/Simulator/AOT/README.md @@ -0,0 +1,4 @@ +# iOS functional test running on simulator in AOT mode + +Simulator: iPhone 11 + diff --git a/src/tests/FunctionalTests/iOS/Simulator/AOT/iOS.Simulator.Aot.Test.csproj b/src/tests/FunctionalTests/iOS/Simulator/AOT/iOS.Simulator.Aot.Test.csproj new file mode 100644 index 0000000..9cc1038 --- /dev/null +++ b/src/tests/FunctionalTests/iOS/Simulator/AOT/iOS.Simulator.Aot.Test.csproj @@ -0,0 +1,66 @@ + + + + + + + + + + + + $(PublishDir)\app + iPhone 11 + True + + + + + + + @(MonoAOTCompilerDefaultAotArguments, ';') + @(MonoAOTCompilerDefaultProcessArguments, ';') + + + + + + + + + + + + + + + + + + + + diff --git a/src/tests/FunctionalTests/iOS/Simulator/AOT/main.m b/src/tests/FunctionalTests/iOS/Simulator/AOT/main.m new file mode 100644 index 0000000..0ab407e --- /dev/null +++ b/src/tests/FunctionalTests/iOS/Simulator/AOT/main.m @@ -0,0 +1,80 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +#import +#import "runtime.h" + +@interface ViewController : UIViewController +@end + +@interface AppDelegate : UIResponder +@property (strong, nonatomic) UIWindow *window; +@property (strong, nonatomic) ViewController *controller; +@end + +@implementation AppDelegate +- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { + self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; + self.controller = [[ViewController alloc] initWithNibName:nil bundle:nil]; + self.window.rootViewController = self.controller; + [self.window makeKeyAndVisible]; + return YES; +} +@end + +UILabel *label; +void (*clickHandlerPtr)(void); + +@implementation ViewController + +- (void)viewDidLoad { + [super viewDidLoad]; + + label = [[UILabel alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; + label.textColor = [UIColor greenColor]; + label.font = [UIFont boldSystemFontOfSize: 30]; + label.numberOfLines = 2; + label.textAlignment = NSTextAlignmentCenter; + [self.view addSubview:label]; + + UIButton *button = [UIButton buttonWithType:UIButtonTypeInfoDark]; + [button addTarget:self action:@selector(buttonClicked:) forControlEvents:UIControlEventTouchUpInside]; + [button setFrame:CGRectMake(50, 300, 200, 50)]; + [button setTitle:@"Click me" forState:UIControlStateNormal]; + [button setExclusiveTouch:YES]; + [self.view addSubview:button]; + + dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ + mono_ios_runtime_init (); + }); +} +-(void) buttonClicked:(UIButton*)sender +{ + if (clickHandlerPtr) + clickHandlerPtr(); +} + +@end + +// called from C# sample +void +ios_register_button_click (void* ptr) +{ + clickHandlerPtr = ptr; +} + +// called from C# sample +void +ios_set_text (const char* value) +{ + NSString* nsstr = [NSString stringWithUTF8String:strdup(value)]; + dispatch_async(dispatch_get_main_queue(), ^{ + label.text = nsstr; + }); +} + +int main(int argc, char * argv[]) { + @autoreleasepool { + return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); + } +} diff --git a/src/tests/FunctionalTests/iOS/Simulator/Interpreter/Program.cs b/src/tests/FunctionalTests/iOS/Simulator/Interpreter/Program.cs new file mode 100644 index 0000000..e6f8b89 --- /dev/null +++ b/src/tests/FunctionalTests/iOS/Simulator/Interpreter/Program.cs @@ -0,0 +1,54 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Threading; +using System.Threading.Tasks; +using System.Runtime.InteropServices; + +// it's not part of the BCL but runtime needs it for native-to-managed callbacks in AOT +// To be replaced with NativeCallableAttribute +public class MonoPInvokeCallbackAttribute : Attribute +{ + public MonoPInvokeCallbackAttribute(Type delegateType) { } +} + +public static class Program +{ + // Defined in main.m + [DllImport("__Internal")] + private extern static void ios_set_text(string value); + + [DllImport("__Internal")] + private extern static void ios_register_button_click(Action action); + + private static Action buttonClickHandler = null; + + private static int counter = 0; + + // Called by native code, see main.m + [MonoPInvokeCallback(typeof(Action))] + private static void OnButtonClick() + { + ios_set_text("OnButtonClick! #" + counter++); + } + + public static async Task Main(string[] args) + { + // Register a managed callback (will be called by UIButton, see main.m) + // Also, keep the handler alive so GC won't collect it. + ios_register_button_click(buttonClickHandler = OnButtonClick); + + const string msg = "Hello World!\n.NET 5.0"; + for (int i = 0; i < msg.Length; i++) + { + // a kind of an animation + ios_set_text(msg.Substring(0, i + 1)); + await Task.Delay(100); + } + + Console.WriteLine("Done!"); + await Task.Delay(5000); + return 42; + } +} diff --git a/src/tests/FunctionalTests/iOS/Simulator/Interpreter/README.md b/src/tests/FunctionalTests/iOS/Simulator/Interpreter/README.md new file mode 100644 index 0000000..b34e705 --- /dev/null +++ b/src/tests/FunctionalTests/iOS/Simulator/Interpreter/README.md @@ -0,0 +1,3 @@ +# iOS functional test running on simulator in Interpreter mode + +Simulator: iPhone 11 diff --git a/src/tests/FunctionalTests/iOS/Simulator/Interpreter/iOS.Simulator.Interpreter.Test.csproj b/src/tests/FunctionalTests/iOS/Simulator/Interpreter/iOS.Simulator.Interpreter.Test.csproj new file mode 100644 index 0000000..9c01811 --- /dev/null +++ b/src/tests/FunctionalTests/iOS/Simulator/Interpreter/iOS.Simulator.Interpreter.Test.csproj @@ -0,0 +1,45 @@ + + + + + + + + + $(PublishDir)\app + iPhone 11 + True + + + + + + + + + + + + + + + + + + + diff --git a/src/tests/FunctionalTests/iOS/Simulator/Interpreter/main.m b/src/tests/FunctionalTests/iOS/Simulator/Interpreter/main.m new file mode 100644 index 0000000..0ab407e --- /dev/null +++ b/src/tests/FunctionalTests/iOS/Simulator/Interpreter/main.m @@ -0,0 +1,80 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +#import +#import "runtime.h" + +@interface ViewController : UIViewController +@end + +@interface AppDelegate : UIResponder +@property (strong, nonatomic) UIWindow *window; +@property (strong, nonatomic) ViewController *controller; +@end + +@implementation AppDelegate +- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { + self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; + self.controller = [[ViewController alloc] initWithNibName:nil bundle:nil]; + self.window.rootViewController = self.controller; + [self.window makeKeyAndVisible]; + return YES; +} +@end + +UILabel *label; +void (*clickHandlerPtr)(void); + +@implementation ViewController + +- (void)viewDidLoad { + [super viewDidLoad]; + + label = [[UILabel alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; + label.textColor = [UIColor greenColor]; + label.font = [UIFont boldSystemFontOfSize: 30]; + label.numberOfLines = 2; + label.textAlignment = NSTextAlignmentCenter; + [self.view addSubview:label]; + + UIButton *button = [UIButton buttonWithType:UIButtonTypeInfoDark]; + [button addTarget:self action:@selector(buttonClicked:) forControlEvents:UIControlEventTouchUpInside]; + [button setFrame:CGRectMake(50, 300, 200, 50)]; + [button setTitle:@"Click me" forState:UIControlStateNormal]; + [button setExclusiveTouch:YES]; + [self.view addSubview:button]; + + dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ + mono_ios_runtime_init (); + }); +} +-(void) buttonClicked:(UIButton*)sender +{ + if (clickHandlerPtr) + clickHandlerPtr(); +} + +@end + +// called from C# sample +void +ios_register_button_click (void* ptr) +{ + clickHandlerPtr = ptr; +} + +// called from C# sample +void +ios_set_text (const char* value) +{ + NSString* nsstr = [NSString stringWithUTF8String:strdup(value)]; + dispatch_async(dispatch_get_main_queue(), ^{ + label.text = nsstr; + }); +} + +int main(int argc, char * argv[]) { + @autoreleasepool { + return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); + } +} diff --git a/src/tests/FunctionalTests/iOS/common.props b/src/tests/FunctionalTests/iOS/common.props new file mode 100644 index 0000000..c353556 --- /dev/null +++ b/src/tests/FunctionalTests/iOS/common.props @@ -0,0 +1,14 @@ + + + Exe + $(AssemblyBinDirOutputPath) + Portable + $(NetCoreAppToolCurrent) + iOS + $(ArtifactsBinDir)microsoft.netcore.app.runtime.ios-$(TargetArchitecture)\$(Configuration)\runtimes\ios-$(TargetArchitecture)\ + false + ios-$(TargetArchitecture) + true + Link + + \ No newline at end of file diff --git a/src/tests/FunctionalTests/iOS/common.targets b/src/tests/FunctionalTests/iOS/common.targets new file mode 100644 index 0000000..60ed0c20 --- /dev/null +++ b/src/tests/FunctionalTests/iOS/common.targets @@ -0,0 +1,29 @@ + + + + + + + $(ArtifactsBinDir)microsoft.netcore.app.runtime.ios-$(TargetArchitecture)\$(Configuration) + + + + + + + + $(TargetOS).AnyCPU.$(Configuration) + $(ArtifactsDir)helix/ + $(HelixArchiveRoot)runonly/ + $(HelixArchiveRunOnlyRoot)$(OSPlatformConfig)/ + + + <_appFiles Include="$(AppBundlePath)/../**/*" /> + + + + + + + \ No newline at end of file diff --git a/src/tests/FunctionalTests/wasm/AOT/browser/Program.cs b/src/tests/FunctionalTests/wasm/AOT/browser/Program.cs new file mode 100644 index 0000000..743f481 --- /dev/null +++ b/src/tests/FunctionalTests/wasm/AOT/browser/Program.cs @@ -0,0 +1,22 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Runtime.CompilerServices; + +namespace Sample +{ + public class Test + { + public static void Main(string[] args) + { + Console.WriteLine ("Hello, World!"); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + public static int TestMeaning() + { + return 42; + } + } +} diff --git a/src/tests/FunctionalTests/wasm/AOT/browser/Wasm.Aot.Browser.Test.csproj b/src/tests/FunctionalTests/wasm/AOT/browser/Wasm.Aot.Browser.Test.csproj new file mode 100644 index 0000000..ebd72fe --- /dev/null +++ b/src/tests/FunctionalTests/wasm/AOT/browser/Wasm.Aot.Browser.Test.csproj @@ -0,0 +1,35 @@ + + + true + \aot\browser\ + + + + + + + $(AppDir) + $(PublishDir) + runtime.js + $(WasmBuildDir)$(AssemblyName).dll + + + + + + + + + + + + + + Always + + + + + + + diff --git a/src/tests/FunctionalTests/wasm/AOT/browser/index.html b/src/tests/FunctionalTests/wasm/AOT/browser/index.html new file mode 100644 index 0000000..9b527ec --- /dev/null +++ b/src/tests/FunctionalTests/wasm/AOT/browser/index.html @@ -0,0 +1,57 @@ + + + + + + TESTS + + + + + + Result from Sample.Test.TestMeaning: + + + + + + + + \ No newline at end of file diff --git a/src/tests/FunctionalTests/wasm/AOT/browser/runtime.js b/src/tests/FunctionalTests/wasm/AOT/browser/runtime.js new file mode 100644 index 0000000..a39b0b9 --- /dev/null +++ b/src/tests/FunctionalTests/wasm/AOT/browser/runtime.js @@ -0,0 +1,26 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +var Module = { + onRuntimeInitialized: function () { + config.loaded_cb = function () { + try { + App.init (); + } catch (error) { + test_exit(1); + throw (error); + } + }; + config.fetch_file_cb = function (asset) { + return fetch (asset, { credentials: 'same-origin' }); + } + + try + { + MONO.mono_load_runtime_and_bcl_args (config); + } catch (error) { + test_exit(1); + throw(error); + } + }, +}; diff --git a/src/tests/FunctionalTests/wasm/AOT/console/Program.cs b/src/tests/FunctionalTests/wasm/AOT/console/Program.cs new file mode 100644 index 0000000..6af1fa6 --- /dev/null +++ b/src/tests/FunctionalTests/wasm/AOT/console/Program.cs @@ -0,0 +1,18 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Threading.Tasks; + +public class Test +{ + public static async Task Main(string[] args) + { + await Task.Delay(1); + Console.WriteLine("Hello World!"); + for (int i = 0; i < args.Length; i++) { + Console.WriteLine($"args[{i}] = {args[i]}"); + } + return args.Length; + } +} \ No newline at end of file diff --git a/src/tests/FunctionalTests/wasm/AOT/console/Wasm.Aot.Console.Test.csproj b/src/tests/FunctionalTests/wasm/AOT/console/Wasm.Aot.Console.Test.csproj new file mode 100644 index 0000000..d9ececb --- /dev/null +++ b/src/tests/FunctionalTests/wasm/AOT/console/Wasm.Aot.Console.Test.csproj @@ -0,0 +1,29 @@ + + + true + \aot\console\ + + + + + + + $(AppDir) + $(PublishDir) + $(MonoProjectRoot)\wasm\runtime-test.js + $(WasmBuildDir)$(AssemblyName).dll + true + + + + + + + + + + + + + + diff --git a/src/tests/FunctionalTests/wasm/Interpreter/browser/Program.cs b/src/tests/FunctionalTests/wasm/Interpreter/browser/Program.cs new file mode 100644 index 0000000..743f481 --- /dev/null +++ b/src/tests/FunctionalTests/wasm/Interpreter/browser/Program.cs @@ -0,0 +1,22 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Runtime.CompilerServices; + +namespace Sample +{ + public class Test + { + public static void Main(string[] args) + { + Console.WriteLine ("Hello, World!"); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + public static int TestMeaning() + { + return 42; + } + } +} diff --git a/src/tests/FunctionalTests/wasm/Interpreter/browser/Wasm.Interpreter.Browser.Test.csproj b/src/tests/FunctionalTests/wasm/Interpreter/browser/Wasm.Interpreter.Browser.Test.csproj new file mode 100644 index 0000000..b4cb152 --- /dev/null +++ b/src/tests/FunctionalTests/wasm/Interpreter/browser/Wasm.Interpreter.Browser.Test.csproj @@ -0,0 +1,34 @@ + + + false + \interpreter\browser\ + + + + + + + $(AppDir) + runtime.js + $(PublishDir)$(AssemblyName).dll + + + + + + + + + + + + + + Always + + + + + + + diff --git a/src/tests/FunctionalTests/wasm/Interpreter/browser/index.html b/src/tests/FunctionalTests/wasm/Interpreter/browser/index.html new file mode 100644 index 0000000..d264b4c --- /dev/null +++ b/src/tests/FunctionalTests/wasm/Interpreter/browser/index.html @@ -0,0 +1,57 @@ + + + + + + TESTS + + + + + + Result from Sample.Test.TestMeaning: + + + + + + + + \ No newline at end of file diff --git a/src/tests/FunctionalTests/wasm/Interpreter/browser/runtime.js b/src/tests/FunctionalTests/wasm/Interpreter/browser/runtime.js new file mode 100644 index 0000000..a39b0b9 --- /dev/null +++ b/src/tests/FunctionalTests/wasm/Interpreter/browser/runtime.js @@ -0,0 +1,26 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +var Module = { + onRuntimeInitialized: function () { + config.loaded_cb = function () { + try { + App.init (); + } catch (error) { + test_exit(1); + throw (error); + } + }; + config.fetch_file_cb = function (asset) { + return fetch (asset, { credentials: 'same-origin' }); + } + + try + { + MONO.mono_load_runtime_and_bcl_args (config); + } catch (error) { + test_exit(1); + throw(error); + } + }, +}; diff --git a/src/tests/FunctionalTests/wasm/Interpreter/console/Program.cs b/src/tests/FunctionalTests/wasm/Interpreter/console/Program.cs new file mode 100644 index 0000000..6af1fa6 --- /dev/null +++ b/src/tests/FunctionalTests/wasm/Interpreter/console/Program.cs @@ -0,0 +1,18 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Threading.Tasks; + +public class Test +{ + public static async Task Main(string[] args) + { + await Task.Delay(1); + Console.WriteLine("Hello World!"); + for (int i = 0; i < args.Length; i++) { + Console.WriteLine($"args[{i}] = {args[i]}"); + } + return args.Length; + } +} \ No newline at end of file diff --git a/src/tests/FunctionalTests/wasm/Interpreter/console/Wasm.Interpreter.Console.Test.csproj b/src/tests/FunctionalTests/wasm/Interpreter/console/Wasm.Interpreter.Console.Test.csproj new file mode 100644 index 0000000..c41cd2b --- /dev/null +++ b/src/tests/FunctionalTests/wasm/Interpreter/console/Wasm.Interpreter.Console.Test.csproj @@ -0,0 +1,28 @@ + + + false + \interpreter\console\ + + + + + + + $(AppDir) + $(MonoProjectRoot)\wasm\runtime-test.js + $(PublishDir)$(AssemblyName).dll + true + + + + + + + + + + + + + + diff --git a/src/tests/FunctionalTests/wasm/common.props b/src/tests/FunctionalTests/wasm/common.props new file mode 100644 index 0000000..b63d0f0 --- /dev/null +++ b/src/tests/FunctionalTests/wasm/common.props @@ -0,0 +1,27 @@ + + + Exe + $(RepoRoot)artifacts\bin\$(AssemblyName) + false + $(NetCoreAppToolCurrent) + browser-wasm + wasm + Browser + $(ArtifactsBinDir)microsoft.netcore.app.runtime.browser-wasm\$(Configuration)\runtimes\browser-wasm\ + $(MSBuildThisFileDirectory)obj\$(Configuration)\wasm + $(OutputPath)\$(Configuration)\AppBundle\ + true + link + false + false + + + + + false + true + false + false + false + + \ No newline at end of file diff --git a/src/tests/FunctionalTests/wasm/common.targets b/src/tests/FunctionalTests/wasm/common.targets new file mode 100644 index 0000000..206093f --- /dev/null +++ b/src/tests/FunctionalTests/wasm/common.targets @@ -0,0 +1,27 @@ + + + + + + + $(ArtifactsBinDir)microsoft.netcore.app.runtime.browser-wasm\$(Configuration) + + + + + + + + + + $(TargetOS).AnyCPU.$(Configuration) + $(ArtifactsDir)helix/ + $(HelixArchiveRoot)runonly/ + $(HelixArchiveRunOnlyRoot)$(OSPlatformConfig)$(WasmModeSpecificPath)/ + $(OutputPath)$(AssemblyName).zip + + + + + + \ No newline at end of file -- 2.7.4