diff --git a/eng/pipelines/coreclr/templates/helix-queues-setup.yml b/eng/pipelines/coreclr/templates/helix-queues-setup.yml index e6a413266ae13a..2b3a80ce94349c 100644 --- a/eng/pipelines/coreclr/templates/helix-queues-setup.yml +++ b/eng/pipelines/coreclr/templates/helix-queues-setup.yml @@ -26,18 +26,22 @@ jobs: runtimeFlavorDisplayName: ${{ parameters.runtimeFlavorDisplayName }} helixQueues: + # iOS/tvOS simulator x64/x86 + - ${{ if in(parameters.platform, 'iOSSimulator_x64', 'tvOSSimulator_x64') }}: + - OSX.1015.Amd64.Open + # Android arm64 - ${{ if in(parameters.platform, 'Android_arm64') }}: - Windows.10.Amd64.Android.Open - + # Android x64 - ${{ if in(parameters.platform, 'Android_x64') }}: - Ubuntu.1804.Amd64.Android.Open - + # Browser wasm - ${{ if eq(parameters.platform, 'Browser_wasm') }}: - Ubuntu.1804.Amd64.Open - + # Linux arm - ${{ if eq(parameters.platform, 'Linux_arm') }}: - ${{ if eq(variables['System.TeamProject'], 'public') }}: diff --git a/eng/pipelines/runtime-staging.yml b/eng/pipelines/runtime-staging.yml index 27843c8959dd42..92e672c5b187ca 100644 --- a/eng/pipelines/runtime-staging.yml +++ b/eng/pipelines/runtime-staging.yml @@ -259,6 +259,48 @@ jobs: creator: dotnet-bot testRunNamePrefixSuffix: Mono_$(_BuildConfig) +# +# Build the whole product using Mono and run runtime tests with the JIT. +# +- template: /eng/pipelines/common/platform-matrix.yml + parameters: + jobTemplate: /eng/pipelines/common/global-build-job.yml + helixQueuesTemplate: /eng/pipelines/coreclr/templates/helix-queues-setup.yml + buildConfig: Release + runtimeFlavor: mono + platforms: + - iOSSimulator_x64 + variables: + - ${{ if and(eq(variables['System.TeamProject'], 'public'), eq(variables['Build.Reason'], 'PullRequest')) }}: + - name: _HelixSource + value: pr/dotnet/runtime/$(Build.SourceBranch) + - ${{ if and(eq(variables['System.TeamProject'], 'public'), ne(variables['Build.Reason'], 'PullRequest')) }}: + - name: _HelixSource + value: ci/dotnet/runtime/$(Build.SourceBranch) + - name: timeoutPerTestInMinutes + value: 60 + - name: timeoutPerTestCollectionInMinutes + value: 180 + jobParameters: + testGroup: innerloop + nameSuffix: AllSubsets_Mono_RuntimeTests + buildArgs: -s mono+libs -c $(_BuildConfig) + timeoutInMinutes: 240 + condition: >- + or( + eq(dependencies.evaluate_paths.outputs['SetPathVars_runtimetests.containsChange'], true), + eq(dependencies.evaluate_paths.outputs['SetPathVars_mono.containsChange'], true), + eq(variables['isFullMatrix'], true)) + # Test execution is temporarily disabled because test apps no longer launch + # and the test suite times out after two hours, even if xharness cannot + # successfully launch any tests. Re-enable once these issues have been fixed. + # + # extra steps, run tests + # extraStepsTemplate: /eng/pipelines/common/templates/runtimes/android-runtime-and-send-to-helix.yml + # extraStepsParameters: + # creator: dotnet-bot + # testRunNamePrefixSuffix: Mono_$(_BuildConfig) + # # Build the whole product using Mono for Android and run runtime tests with Android devices # diff --git a/src/tasks/AppleAppBuilder/AppleAppBuilder.cs b/src/tasks/AppleAppBuilder/AppleAppBuilder.cs index 6183fe0442f2ae..9127192f9f6c4f 100644 --- a/src/tasks/AppleAppBuilder/AppleAppBuilder.cs +++ b/src/tasks/AppleAppBuilder/AppleAppBuilder.cs @@ -50,9 +50,11 @@ public string TargetOS public string MonoRuntimeHeaders { get; set; } = ""!; /// - /// This library will be used as an entry-point (e.g. TestRunner.dll) + /// This library will be used as an entry point (e.g. TestRunner.dll). Can + /// be empty. If empty, the entry point of the app must be specified in an + /// environment variable named "MONO_APPLE_APP_ENTRY_POINT_LIB_NAME" when + /// running the resulting app. /// - [Required] public string MainLibraryFileName { get; set; } = ""!; /// @@ -155,9 +157,12 @@ public override bool Execute() { bool isDevice = (TargetOS == TargetNames.iOS || TargetOS == TargetNames.tvOS); - if (!File.Exists(Path.Combine(AppDir, MainLibraryFileName))) + if (!string.IsNullOrEmpty(MainLibraryFileName)) { - throw new ArgumentException($"MainLibraryFileName='{MainLibraryFileName}' was not found in AppDir='{AppDir}'"); + if (!File.Exists(Path.Combine(AppDir, MainLibraryFileName))) + { + throw new ArgumentException($"MainLibraryFileName='{MainLibraryFileName}' was not found in AppDir='{AppDir}'"); + } } if (ProjectName.Contains(' ')) diff --git a/src/tasks/AppleAppBuilder/Templates/runtime.m b/src/tasks/AppleAppBuilder/Templates/runtime.m index de9ca63b868382..3146f05b7f73c2 100644 --- a/src/tasks/AppleAppBuilder/Templates/runtime.m +++ b/src/tasks/AppleAppBuilder/Templates/runtime.m @@ -86,13 +86,33 @@ munmap (handle, size); } -static MonoAssembly* +static const char *assembly_load_prefix = NULL; + +static MonoAssembly * +load_assembly_aux (const char *filename, const char *culture, const char *bundle) +{ + char path [1024]; + int res; + if (culture && strcmp (culture, "")) + res = snprintf (path, sizeof (path) - 1, "%s/%s/%s", bundle, culture, filename); + else + res = snprintf (path, sizeof (path) - 1, "%s/%s", bundle, filename); + assert (res > 0); + + struct stat buffer; + if (stat (path, &buffer) == 0) { + MonoAssembly *assembly = mono_assembly_open (path, NULL); + assert (assembly); + return assembly; + } + return NULL; +} + +static MonoAssembly * load_assembly (const char *name, const char *culture) { const char *bundle = get_bundle_path (); char filename [1024]; - char path [1024]; - int res; os_log_info (OS_LOG_DEFAULT, "assembly_preload_hook: %{public}s %{public}s %{public}s\n", name, culture, bundle); @@ -105,19 +125,14 @@ strlcat (filename, ".dll", sizeof (filename)); } - if (culture && strcmp (culture, "")) - res = snprintf (path, sizeof (path) - 1, "%s/%s/%s", bundle, culture, filename); - else - res = snprintf (path, sizeof (path) - 1, "%s/%s", bundle, filename); - assert (res > 0); - - struct stat buffer; - if (stat (path, &buffer) == 0) { - MonoAssembly *assembly = mono_assembly_open (path, NULL); - assert (assembly); - return assembly; + if (assembly_load_prefix [0] != '\0') { + char prefix_bundle [1024]; + int res = snprintf (prefix_bundle, sizeof (prefix_bundle) - 1, "%s/%s", bundle, assembly_load_prefix); + assert (res > 0); + MonoAssembly *ret = load_assembly_aux (filename, culture, prefix_bundle); + if (ret) return ret; } - return NULL; + return load_assembly_aux (filename, culture, bundle); } static MonoAssembly* @@ -260,7 +275,7 @@ // TODO: set TRUSTED_PLATFORM_ASSEMBLIES, APP_PATHS and NATIVE_DLL_SEARCH_DIRECTORIES const char *appctx_keys [] = { - "RUNTIME_IDENTIFIER", + "RUNTIME_IDENTIFIER", "APP_CONTEXT_BASE_DIRECTORY", #if !defined(INVARIANT_GLOBALIZATION) "ICU_DAT_FILE_PATH" @@ -291,6 +306,19 @@ free (file_path); } + const char* executable = "%EntryPointLibName%"; + if (executable [0] == '\0') { + executable = getenv ("MONO_APPLE_APP_ENTRY_POINT_LIB_NAME"); + } + if (executable == NULL) { + executable = ""; + } + + assembly_load_prefix = getenv ("MONO_APPLE_APP_ASSEMBLY_LOAD_PREFIX"); + if (assembly_load_prefix == NULL) { + assembly_load_prefix = ""; + } + monovm_initialize (sizeof (appctx_keys) / sizeof (appctx_keys [0]), appctx_keys, appctx_values); #if (FORCE_INTERPRETER && !FORCE_AOT) @@ -334,7 +362,6 @@ MONO_EXIT_GC_UNSAFE; #endif - const char* executable = "%EntryPointLibName%"; MonoAssembly *assembly = load_assembly (executable, NULL); assert (assembly); os_log_info (OS_LOG_DEFAULT, "Executable: %{public}s", executable); diff --git a/src/tests/Common/CLRTest.Execute.Bash.targets b/src/tests/Common/CLRTest.Execute.Bash.targets index 7031b45d72e95b..ee375b80694172 100644 --- a/src/tests/Common/CLRTest.Execute.Bash.targets +++ b/src/tests/Common/CLRTest.Execute.Bash.targets @@ -11,7 +11,7 @@ This file contains the logic for providing Execution Script generation. WARNING: When setting properties based on their current state (for example: - - + @@ -124,11 +124,11 @@ fi if [ -z ${CLRTestExpectedExitCode+x} ]%3B then export CLRTestExpectedExitCode=$(CLRTestExitCode)%3B fi echo BEGIN EXECUTION]]> - + - + - + @@ -188,29 +188,29 @@ ReflectionRoots= shopt -s nullglob -if [ ! -z "$DoLink" ]; +if [ ! -z "$DoLink" ]; then - if [ ! -x "$ILLINK" ]; + if [ ! -x "$ILLINK" ]; then echo "Illink executable [$ILLINK] Invalid" exit 1 fi - + # Clean up old Linked binaries, if any rm -rf $LinkBin - + # Remove Native images, since the goal is to run from Linked binaries rm -f *.ni.* # Use hints for reflection roots, if provided in $(ReflectionRootsXml) - if [ -f $(ReflectionRootsXml) ]; + if [ -f $(ReflectionRootsXml) ]; then ReflectionRoots="-x $(ReflectionRootsXml)" fi # Include all .exe files in this directory as entry points (some tests had multiple .exe file modules) - for bin in *.exe *.dll; - do + for bin in *.exe *.dll; + do Assemblies="$Assemblies -a ${bin%.*}" done @@ -224,14 +224,14 @@ then if [ $ERRORLEVEL -ne 0 ] then echo ILLINK FAILED $ERRORLEVEL - if [ -z "$KeepLinkedBinaries" ]; + if [ -z "$KeepLinkedBinaries" ]; then rm -rf $LinkBin fi exit 1 fi - - # Copy CORECLR native binaries to $LinkBin, + + # Copy CORECLR native binaries to $LinkBin, # so that we can run the test based on that directory cp $CORE_ROOT/*.so $LinkBin/ cp $CORE_ROOT/corerun $LinkBin/ @@ -252,9 +252,9 @@ fi # Clean up the LinkBin directories after test execution. # Otherwise, RunTests may run out of disk space. -if [ ! -z "$DoLink" ]; +if [ ! -z "$DoLink" ]; then - if [ -z "$KeepLinkedBinaries" ]; + if [ -z "$KeepLinkedBinaries" ]; then rm -rf $LinkBin fi @@ -364,7 +364,43 @@ fi $__Command $HARNESS_RUNNER android run --instrumentation="net.dot.MonoRunner" --package-name="net.dot.$__Category" --output-directory="$__OutputDir" --arg=entrypoint:libname=$(MsBuildProjectName).dll --expected-exit-code=100 -v CLRTestExitCode=$? -# Exist code of xharness is zero when tests finished successfully +# Exit code of xharness is zero when tests finished successfully +CLRTestExpectedExitCode=0 + ]]> + + + @@ -383,17 +419,17 @@ CLRTestExpectedExitCode=0 @(CLRTestBashEnvironmentVariable -> '%(Identity)', '%0a') - + - + <_RequiredProperties Include="_CLRTestRunFile"> $(_CLRTestRunFile) - + @@ -407,7 +443,7 @@ CLRTestExpectedExitCode=0 usage() { echo "Usage: $0 $(_CLRTestParamList)" - echo + echo echo "Arguments:" @(BashCLRTestExecutionScriptArgument -> ' echo "-%(Identity)=%(ParamName)" echo "%(Description)"', ' @@ -498,14 +534,14 @@ $(BashCLRTestExitCodeCheck) - + diff --git a/src/tests/Common/Coreclr.TestWrapper/MobileAppHandler.cs b/src/tests/Common/Coreclr.TestWrapper/MobileAppHandler.cs index f4d179ce4ce29c..7a58262a95420d 100644 --- a/src/tests/Common/Coreclr.TestWrapper/MobileAppHandler.cs +++ b/src/tests/Common/Coreclr.TestWrapper/MobileAppHandler.cs @@ -81,6 +81,11 @@ private static int HandleMobileApp(string action, string platform, string catego } } + if (platform != "android") + { + cmdStr += " --target ios-simulator-64"; + } + using (Process process = new Process()) { if (OperatingSystem.IsWindows()) @@ -97,6 +102,8 @@ private static int HandleMobileApp(string action, string platform, string catego process.StartInfo.RedirectStandardOutput = true; process.StartInfo.RedirectStandardError = true; + outputWriter.WriteLine("XXXih: cmdStr = {0}", cmdStr); + errorWriter.WriteLine("XXXih: cmdStr = {0}", cmdStr); DateTime startTime = DateTime.Now; process.Start(); @@ -125,7 +132,7 @@ private static int HandleMobileApp(string action, string platform, string catego cmdStr, timeout, startTime.ToString(), endTime.ToString()); errorWriter.WriteLine("\ncmdLine:{0} Timed Out (timeout in milliseconds: {1}, start: {2}, end: {3})", cmdStr, timeout, startTime.ToString(), endTime.ToString()); - + process.Kill(entireProcessTree: true); } } @@ -152,7 +159,7 @@ private static string ConvertCmd2Arg(string cmd) { cmdPrefix = "-c"; } - + return $"{cmdPrefix} \"{cmd}\""; } } diff --git a/src/tests/Common/helixpublishwitharcade.proj b/src/tests/Common/helixpublishwitharcade.proj index b98bd8e8289b17..349530a5b22530 100644 --- a/src/tests/Common/helixpublishwitharcade.proj +++ b/src/tests/Common/helixpublishwitharcade.proj @@ -83,6 +83,7 @@ linux-musl-$(TargetArchitecture) browser-wasm android-$(TargetArchitecture) + iossimulator-$(TargetArchitecture) @@ -107,7 +108,15 @@ win-x64 - + + sdk + $([System.IO.File]::ReadAllText('$(RepoRoot)global.json')) + $([System.Text.RegularExpressions.Regex]::Match($(GlobalJsonContent), '(%3F<="dotnet": ").*(%3F=")')) + + osx-x64 + + + true @@ -156,6 +165,8 @@ <_PayloadFiles Include="@(_TestGroupingRelevant->WithMetadataValue('TestGroup','$(_PayloadGroup)')->DistinctWithCase())" Condition="'$(_TestGroupingExists)' == 'true'" /> <_PayloadFiles Include="$(_FileDirectory)*" Condition="'$(_TestGroupingExists)' == 'true'" /> + <_PayloadFiles Include="$(_FileDirectory)/*.app" Condition="'$(_TestGroupingExists)' == 'true'" /> + <_PayloadFiles Include="$(_FileDirectory)/*.app/**" Condition="'$(_TestGroupingExists)' == 'true'" /> <_PayloadFiles Update="@(_PayloadFiles)"> + Condition="'@(NativeProjectBinaries)' == '' And '$(TargetOS)' != 'Browser' And '$(TargetOS)' != 'Android' And '$(TargetOS)' != 'iOS' And '$(TargetOS)' != 'iOSSimulator'"/> Exe true - true + true diff --git a/src/tests/build.sh b/src/tests/build.sh index 7bd0ca06d85d67..ada962503ad62a 100755 --- a/src/tests/build.sh +++ b/src/tests/build.sh @@ -51,6 +51,13 @@ build_mono_aot() build_MSBuild_projects "Tests_MonoAot" "$__RepoRootDir/src/tests/run.proj" "Mono AOT compile tests" "/t:MonoAotCompileTests" "/p:RuntimeFlavor=$__RuntimeFlavor" "/p:MonoBinDir=$__MonoBinDir" } +build_ios_apps() +{ + __RuntimeFlavor="mono" \ + __Exclude="$__RepoRootDir/src/tests/issues.targets" \ + build_MSBuild_projects "Create_iOS_App" "$__RepoRootDir/src/tests/run.proj" "Create iOS Apps" "/t:BuildAlliOSApp" +} + generate_layout() { echo "${__MsgPrefix}Creating test overlay..." @@ -256,7 +263,7 @@ build_Tests() fi fi - if [[ "$__SkipNative" != 1 && "$__TargetOS" != "Browser" && "$__TargetOS" != "Android" ]]; then + if [[ "$__SkipNative" != 1 && "$__TargetOS" != "Browser" && "$__TargetOS" != "Android" && "$__TargetOS" != "iOS" && "$__TargetOS" != "iOSSimulator" ]]; then build_native "$__TargetOS" "$__BuildArch" "$__TestDir" "$__NativeTestIntermediatesDir" "install" "CoreCLR test component" if [[ "$?" -ne 0 ]]; then @@ -624,6 +631,8 @@ echo "${__MsgPrefix}Test binaries are available at ${__TestBinDir}" if [ "$__TargetOS" == "Android" ]; then build_MSBuild_projects "Create_Android_App" "$__RepoRootDir/src/tests/run.proj" "Create Android Apps" "/t:BuildAllAndroidApp" "/p:RunWithAndroid=true" +elif [ "$__TargetOS" == "iOS" ] || [ "$__TargetOS" == "iOSSimulator" ]; then + build_ios_apps fi if [[ "$__RunTests" -ne 0 ]]; then diff --git a/src/tests/issues.targets b/src/tests/issues.targets index 854204fd744fc9..cd4bbfaae7c83b 100644 --- a/src/tests/issues.targets +++ b/src/tests/issues.targets @@ -2920,4 +2920,164 @@ https://github.com/dotnet/runtime/issues/52781 + + + + missing assembly + + + missing assembly + + + missing assembly + + + missing assembly + + + missing assembly + + + missing assembly + + + missing assembly + + + missing assembly + + + System.PlatformNotSupportedException: Operation is not supported on this platform + + + System.DllNotFoundException: DoesNotExist + + + System.DllNotFoundException: DoesNotExist + + + System.DllNotFoundException: UnmanagedCallersOnlyDll + + + System.DllNotFoundException: ObjectiveC + + + System.DllNotFoundException: SuppressGCTransitionNative + + + + System.IO.FileNotFoundException: Could not load file or assembly 'xunit.assert, Version=2.4.1.0, Culture=neutral, PublicKeyToken=8d05b1bb7a6fdb6c' or one of its dependencies. + + + System.DllNotFoundException: GCPollNative + + + + System.ArgumentNullException: Value cannot be null. (Parameter 'path1') + + + System.Exception: Values for 'retCode' are not equal! Left='1' Right='0' + + + + System.IO.FileNotFoundException: Could not load file or assembly '/.../Library/Developer/CoreSimulator/Devices/941235AB-7563-4D79-AC28-946B7AD2304A/data/Containers/Bundle/Application/40176A30-D8F5-4497-958A-6514E5C684FC/readytorun_multifolder.app/testdir-multifolder/../FolderA/FolderA/FolderA.dll' or one of its dependencies. + + + + Failed to catch an exception! System.DllNotFoundException: ForeignThreadExceptionsNative + + + + USAGE: MultipleWR.exe num objects [track] + + + USAGE: MultipleWR.exe num objects [track] + + + GC_API 0|1|2 + + + GC_API 0|1|2 + + + + System.IO.FileNotFoundException: Could not load file or assembly 'xunit.runner.utility.netcoreapp10, Version=2.4.1.0, Culture=neutral, PublicKeyToken=8d05b1bb7a6fdb6c' or one of its dependencies. + + + + Environment variable is not set: 'CORE_ROOT' + + + + USAGE: ThreadStartBool bool + + + USAGE: ThreadStartBool bool + + + + System.ArgumentOutOfRangeException: Index was out of range. Must be non-negative and less than the size of the collection. (Parameter 'index') + + + + System.DllNotFoundException: ThisCallNative + + + https://github.com/dotnet/runtime/issues/50440 + + + https://github.com/dotnet/runtime/issues/50440 + + + https://github.com/dotnet/runtime/issues/50440 + + + + System.IO.FileNotFoundException: Could not load file or assembly 'xunit.performance.core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=67066efe964d3b03' or one of its dependencies. + + + System.IO.FileNotFoundException: Could not load file or assembly 'xunit.performance.core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=67066efe964d3b03' or one of its dependencies. + + + ((null) error) * Assertion at runtime/src/mono/mono/metadata/assembly.c:2049, condition `is_ok (error)' not met, function:mono_assembly_load_friends, Could not load file or assembly 'xunit.performance.core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=67066efe964d3b03' or one of its dependencies. + + + ((null) error) * Assertion at runtime/src/mono/mono/metadata/assembly.c:2049, condition `is_ok (error)' not met, function:mono_assembly_load_friends, Could not load file or assembly 'xunit.performance.core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=67066efe964d3b03' or one of its dependencies. + + + ((null) error) * Assertion at runtime/src/mono/mono/metadata/assembly.c:2049, condition `is_ok (error)' not met, function:mono_assembly_load_friends, Could not load file or assembly 'xunit.performance.core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=67066efe964d3b03' or one of its dependencies. + + + ((null) error) * Assertion at runtime/src/mono/mono/metadata/assembly.c:2049, condition `is_ok (error)' not met, function:mono_assembly_load_friends, Could not load file or assembly 'xunit.performance.core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=67066efe964d3b03' or one of its dependencies. + + + This test requires CORE_ROOT to be set + + + ((null) error) * Assertion at runtime/src/mono/mono/metadata/assembly.c:2049, condition `is_ok (error)' not met, function:mono_assembly_load_friends, Could not load file or assembly 'xunit.performance.core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=67066efe964d3b03' or one of its dependencies. + + + System.IO.FileNotFoundException: Could not load file or assembly 'xunit.assert, Version=2.4.1.0, Culture=neutral, PublicKeyToken=8d05b1bb7a6fdb6c' or one of its dependencies. + + + ((null) error) * Assertion at runtime/src/mono/mono/metadata/assembly.c:2049, condition `is_ok (error)' not met, function:mono_assembly_load_friends, Could not load file or assembly 'xunit.performance.core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=67066efe964d3b03' or one of its dependencies. + + + ((null) error) * Assertion at runtime/src/mono/mono/metadata/assembly.c:2049, condition `is_ok (error)' not met, function:mono_assembly_load_friends, Could not load file or assembly 'xunit.performance.core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=67066efe964d3b03' or one of its dependencies. + + + System.IO.FileNotFoundException: Could not load file or assembly 'xunit.performance.core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=67066efe964d3b03' or one of its dependencies. + + + System.IO.FileNotFoundException: Could not load file or assembly 'xunit.performance.core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=67066efe964d3b03' or one of its dependencies. + + + + CORE_ROOT must be set + + + + Could not load file or assembly 'System.Drawing.Common, Version=6.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51' or one of its dependencies. + + diff --git a/src/tests/run.proj b/src/tests/run.proj index 4f17417636d840..f21a0bd1284065 100644 --- a/src/tests/run.proj +++ b/src/tests/run.proj @@ -707,6 +707,112 @@ namespace $([System.String]::Copy($(Category)).Replace(".","_").Replace("\",""). + + + + + + $([System.IO.Path]::GetDirectoryName($([System.IO.Path]::GetDirectoryName($(_CMDDIR))))) + $([System.String]::Copy('$(_CMDDIR)').Replace("$(CMDDIR_Grandparent)/","")) + $([System.String]::Copy('$(CategoryWithSlash)').Replace('/','_')) + $([System.String]::Copy('$(CategoryWithSlash)').Replace('/', '.')).XUnitWrapper.dll + $(CMDDIR_GrandParent)/$(CategoryWithSlash)/$(XUnitWrapperFileName) + $(IntermediateOutputPath)\iOSApps\$(Category) + $(XUnitTestBinBase)$(CategoryWithSlash)\$(Category).app + + + + $(Category) + $(ArtifactsBinDir)microsoft.netcore.app.runtime.iossimulator-$(TargetArchitecture)/$(Configuration)/runtimes/iossimulator-$(TargetArchitecture) + $(MicrosoftNetCoreAppRuntimePackDir)/native + + + + + + + + + + + + + + + @(TestDlls->'%(Filename)') + + + + $([MSBuild]::NormalizeDirectory('$(BuildDir)', 'AppBundle')) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + _CMDDIR=%(TestDirectories.Identity) + + + + +