From ad3f1c135bfb4fbb0c4bd0b4492eb10fc5ca4323 Mon Sep 17 00:00:00 2001 From: Ankit Jain Date: Thu, 16 Dec 2021 18:17:37 +0000 Subject: [PATCH] [wasm] Add support for running debugger tests CI (#62431) * [wasm] Don't emit warning if runtimeconfig.json cannot be found Library projects don't have runtimeconfig.json files by default. So, don't make it a warning. Instead, emit a low importance which might be useful when debugging. But library projects can have runtimeconfig.json, like the runtime test projects. So, don't limit processing that by OutputType. IOW, if it's found then use it. * [wasm] Add timestamp to logs * Download dotnet-install script for installing workloads Instead of trying to use the script from `.dotnet`, download the script. `.dotnet` might not exist, for example, when the `global.json` version matches the system installed one. * [wasm] WasmAppBuilder: catch UnauthorizedAccessException also * [wasm] Fix bug in tests Some helper methods have a `Action` parameter. Many tests pass an async lambda to this, expecting it to get awaited upon. ```csharp EvaluateAndCheck (Action locals_fn) { ... locals_fn(); // no await ... } async Task Test() { EvaluateAndCheck( async (locals) => { ... CheckNumber(locals, ...); await CheckDateTime(locals, ..); ... } ); } ``` In the above example, roslyn generates an async-void lambda, so the compiler never complains about the async lambda being passed. `EvaluateAndCheck` cannot, and does not await this, but if the lambda happens to block, then it will return at that point, and the test(calling method) will end, without ever completing the lambda. And for most tests, the actual checks are done in that lambda. This gets hit when `CheckDateTimeValue` tries to fetch properties of a `DateTime` object. And it started to show up when adding `ConfigureAwait(false)` to some calls. * [wasm] Add Wasm.Debugger.Tests wrapper project This is a proxy/wrapper project for `src/mono/wasm/debugger/DebuggerTestSuite/DebuggerTestSuite.csproj`. - Building the project as part of the regular browser-wasm build presents some issues, because of part the tests need use the aspnet sdk, and that doesn't work with `browser-wasm`. - This wrapper project essentially builds the `DebuggerTestSuite` project, with some properties(`TargetFramework;TargetFrameworks;Configuration;TargetOS;TargetArchitecture`) removed so they don't propogate from the parent build. - And it packages it up for running the tests on helix - I did try to convert `DebuggerTestSuite` into a `Wasm.Debugger.Tests`, and make it use the library tests infrastructure, but ran into an issue - it built the project with no `testhost.dll`, so can't use `dotnet test` - it did get `xunit.console.dll`, but that would fail to run the tests because of missing `System.Runtime` (and I'm guessing, other assemblies) - attempts to publish the project failed - So, for now, this is what we have! * [wasm][tests] Make them friendly to running outside the tree .. like on helix. Add new `DEBUGGER_TEST_PATH`, and `CHROME_PATH_FOR_DEBUGGER_TESTS` which will be set for helix. And change the appbundle directory name from the misleading `publish/` to `AppBundle/`. * [wasm] Tests.cs -> MiscTests.cs * [wasm] Add support for submitting debugger tests to helix Also, added `eng/testing/scenarios/WasmDebuggerTestsJobsList.txt` which is a manually generated list of test classes. This will be changed to be generated at runtime, in an upcoming PR. * [wasm] Add debugger tests job for linux, and windows They follow the same pattern as other wasm jobs: - build when isFullMatrix - build in runtime-manual - Additionally, build when there are changes in: ``` - src/mono/wasm/debugger/* - src/mono/wasm/runtime/* - src/mono/mono/* ``` * [wasm] Add new make targets to submit tests to helix `submit-debugger-tests-helix` `submit-tests-helix` - submits any library test archives * Build Wasm.Debugger.Tests from src/libraries/tests.proj * DebuggerTestSuite: Copy files for the test archive * [wasm] Fix HarnessTests.BrowserClose * [wasm] Fix building `ApplyUpdateReferencedAssembly` project on CI Essentially, disable use of SourceLink which gets enabled by default when using `-p:ContinuousIntegrationBuild=true`. Issue: https://github.com/dotnet/runtime/issues/62618 * cleanup * Wasm.Build.Tests: add missing file * [wasm] sendtohelixhelp.proj: Error out if there is more than one zip .. file when running for Wasm.Build.Tests, or Wasm.Debugger.Tests . * [wasm] Disable DebuggerTests.ArrayTests on helix Issue: https://github.com/dotnet/runtime/issues/62661 Using `[Trait..` instead of `ActiveIssue` because: https://github.com/dotnet/runtime/issues/62660 * disable non-wasma builds * sendtohelixhelp.proj: guard against no payload found * Disable more tests * add back builds * [wasm][debugger] Disable failing debugger test `DebuggerTests.BreakpointTests.BreakpointInAssemblyUsingTypeFromAnotherAssembly_BothDynamicallyLoaded` Issue: https://github.com/dotnet/runtime/issues/62823 * Try to fix windows command line * Move debugger-tests for linux to runtime-staging * Revert "[wasm][debugger] Fix source-link test (#62786)" .. as it is breaking debugger tests build on windows. Issue: https://github.com/dotnet/runtime/issues/62892 This reverts commit 815174072529c5183fc7418bec20dce61f2f6f15. --- .../common/evaluate-default-paths.yml | 5 ++ eng/pipelines/runtime-manual.yml | 63 ++++++++++++++ eng/pipelines/runtime-staging.yml | 61 ++++++++++++++ .../scenarios/WasmDebuggerTestsJobsList.txt | 18 ++++ eng/testing/workloads-testing.targets | 11 ++- src/libraries/sendtohelixhelp.proj | 39 ++++++++- src/libraries/tests.proj | 9 +- src/mono/wasm/Makefile | 27 ++++++ src/mono/wasm/build/WasmApp.targets | 10 ++- .../wasm/debugger/BrowserDebugHost/Startup.cs | 6 +- .../debugger/BrowserDebugProxy/DebugStore.cs | 4 +- .../debugger/DebuggerTestSuite/ArrayTests.cs | 5 +- .../DebuggerTestSuite/AssignmentTests.cs | 6 +- .../DebuggerTestSuite/BreakpointTests.cs | 67 ++++++++++----- .../DebuggerTestSuite/DateTimeTests.cs | 2 +- .../DebuggerTestSuite/DebuggerTestBase.cs | 82 ++++++++++++------- .../DebuggerTestSuite.csproj | 13 ++- .../DebuggerTestSuite/ExceptionTests.cs | 1 + .../DebuggerTestSuite/HarnessTests.cs | 9 +- .../debugger/DebuggerTestSuite/Inspector.cs | 9 +- .../{Tests.cs => MiscTests.cs} | 50 +++-------- .../SetVariableValueTests.cs | 64 +++++++++------ .../DebuggerTestSuite/SteppingTests.cs | 57 ++++++++----- .../DebuggerTestSuite/TestHarnessProxy.cs | 10 ++- .../ApplyUpdateReferencedAssembly.csproj | 3 + .../wasm/debugger/tests/Directory.Build.props | 2 +- .../debugger-test-with-source-link.csproj | 33 +++----- .../source-link.json | 5 -- .../tests/debugger-test/debugger-test.csproj | 6 +- src/tasks/WasmAppBuilder/WasmAppBuilder.cs | 4 +- src/tests/BuildWasmApps/Directory.Build.props | 3 - .../Wasm.Build.Tests/Directory.Build.props | 8 ++ .../Wasm.Debugger.Tests.csproj | 65 +++++++++++++++ .../data/RunScriptTemplate.cmd | 32 ++++++++ .../data/RunScriptTemplate.sh | 21 +++++ 35 files changed, 620 insertions(+), 190 deletions(-) create mode 100644 eng/testing/scenarios/WasmDebuggerTestsJobsList.txt rename src/mono/wasm/debugger/DebuggerTestSuite/{Tests.cs => MiscTests.cs} (95%) delete mode 100644 src/mono/wasm/debugger/tests/debugger-test-with-source-link/source-link.json create mode 100644 src/tests/BuildWasmApps/Wasm.Build.Tests/Directory.Build.props create mode 100644 src/tests/BuildWasmApps/Wasm.Debugger.Tests/Wasm.Debugger.Tests.csproj create mode 100644 src/tests/BuildWasmApps/Wasm.Debugger.Tests/data/RunScriptTemplate.cmd create mode 100644 src/tests/BuildWasmApps/Wasm.Debugger.Tests/data/RunScriptTemplate.sh diff --git a/eng/pipelines/common/evaluate-default-paths.yml b/eng/pipelines/common/evaluate-default-paths.yml index 326cc764703..7b404e2c37b 100644 --- a/eng/pipelines/common/evaluate-default-paths.yml +++ b/eng/pipelines/common/evaluate-default-paths.yml @@ -116,6 +116,11 @@ jobs: - src/mono/nuget/Microsoft.NET.Runtime.MonoAOTCompiler.Task/* - src/mono/nuget/Microsoft.NET.Runtime.MonoTargets.Sdk/* - src/mono/mono/* + - subset: wasmdebuggertests + include: + - src/mono/wasm/debugger/* + - src/mono/wasm/runtime/* + - src/mono/mono/* - ${{ if ne(parameters.extraSubsets, '') }}: - ${{ parameters.extraSubsets }} diff --git a/eng/pipelines/runtime-manual.yml b/eng/pipelines/runtime-manual.yml index 3be3efb85c9..77f7b29cad8 100644 --- a/eng/pipelines/runtime-manual.yml +++ b/eng/pipelines/runtime-manual.yml @@ -497,6 +497,69 @@ jobs: creator: dotnet-bot testRunNamePrefixSuffix: Mono_$(_BuildConfig) +# Wasm debugger tests +- template: /eng/pipelines/common/platform-matrix.yml + parameters: + jobTemplate: /eng/pipelines/common/global-build-job.yml + helixQueuesTemplate: /eng/pipelines/libraries/helix-queues-setup.yml + buildConfig: Release + runtimeFlavor: mono + platforms: + - Browser_wasm + variables: + # map dependencies variables to local variables + - name: wasmdebuggertestsContainsChange + value: $[ dependencies.evaluate_paths.outputs['SetPathVars_wasmdebuggertests.containsChange'] ] + jobParameters: + testGroup: innerloop + nameSuffix: Mono_DebuggerTests + buildArgs: -s mono+libs+libs.tests -c $(_BuildConfig) /p:ArchiveTests=true /p:TestWasmDebuggerTests=true /p:TestAssemblies=false + timeoutInMinutes: 180 + condition: >- + or( + eq(dependencies.evaluate_paths.outputs['SetPathVars_wasmdebuggertests.containsChange'], true), + eq(variables['isManualOrIsNotPR'], true), + eq(variables['isFullMatrix'], true)) + # extra steps, run tests + extraStepsTemplate: /eng/pipelines/libraries/helix.yml + extraStepsParameters: + creator: dotnet-bot + testRunNamePrefixSuffix: Mono_$(_BuildConfig) + scenarios: + - wasmdebuggertests + +# Wasm debugger tests - windows +- template: /eng/pipelines/common/platform-matrix.yml + parameters: + jobTemplate: /eng/pipelines/common/global-build-job.yml + helixQueuesTemplate: /eng/pipelines/libraries/helix-queues-setup.yml + buildConfig: Release + runtimeFlavor: mono + platforms: + - Browser_wasm_win + variables: + # map dependencies variables to local variables + - name: wasmdebuggertestsContainsChange + value: $[ dependencies.evaluate_paths.outputs['SetPathVars_wasmdebuggertests.containsChange'] ] + jobParameters: + testGroup: innerloop + nameSuffix: Windows_wasm_DebuggerTests + buildArgs: -s mono+libs+libs.tests -c $(_BuildConfig) /p:ArchiveTests=true /p:TestWasmDebuggerTests=true /p:TestAssemblies=false /p:BrowserHost=windows + timeoutInMinutes: 180 + condition: >- + or( + eq(dependencies.evaluate_paths.outputs['SetPathVars_wasmdebuggertests.containsChange'], true), + eq(variables['isManualOrIsNotPR'], true), + eq(variables['isFullMatrix'], true)) + # extra steps, run tests + extraStepsTemplate: /eng/pipelines/libraries/helix.yml + extraStepsParameters: + creator: dotnet-bot + testRunNamePrefixSuffix: Mono_$(_BuildConfig) + extraHelixArguments: /p:BrowserHost=windows + scenarios: + - wasmdebuggertests + # # Build the whole product using Mono for Android and run runtime tests with Android emulator # diff --git a/eng/pipelines/runtime-staging.yml b/eng/pipelines/runtime-staging.yml index 7a76fbcd117..79ed215e3a6 100644 --- a/eng/pipelines/runtime-staging.yml +++ b/eng/pipelines/runtime-staging.yml @@ -616,6 +616,67 @@ jobs: eq(variables['isManualOrIsNotPR'], true), eq(variables['isFullMatrix'], true)) +# Wasm debugger tests +- template: /eng/pipelines/common/platform-matrix.yml + parameters: + jobTemplate: /eng/pipelines/common/global-build-job.yml + helixQueuesTemplate: /eng/pipelines/libraries/helix-queues-setup.yml + buildConfig: Release + runtimeFlavor: mono + platforms: + - Browser_wasm + variables: + # map dependencies variables to local variables + - name: wasmdebuggertestsContainsChange + value: $[ dependencies.evaluate_paths.outputs['SetPathVars_wasmdebuggertests.containsChange'] ] + jobParameters: + testGroup: innerloop + nameSuffix: Mono_DebuggerTests + buildArgs: -s mono+libs+libs.tests -c $(_BuildConfig) /p:ArchiveTests=true /p:TestWasmDebuggerTests=true /p:TestAssemblies=false + timeoutInMinutes: 180 + condition: >- + or( + eq(dependencies.evaluate_paths.outputs['SetPathVars_wasmdebuggertests.containsChange'], true), + eq(variables['isFullMatrix'], true)) + # extra steps, run tests + extraStepsTemplate: /eng/pipelines/libraries/helix.yml + extraStepsParameters: + creator: dotnet-bot + testRunNamePrefixSuffix: Mono_$(_BuildConfig) + scenarios: + - wasmdebuggertests + +# Wasm debugger tests - windows +- template: /eng/pipelines/common/platform-matrix.yml + parameters: + jobTemplate: /eng/pipelines/common/global-build-job.yml + helixQueuesTemplate: /eng/pipelines/libraries/helix-queues-setup.yml + buildConfig: Release + runtimeFlavor: mono + platforms: + - Browser_wasm_win + variables: + # map dependencies variables to local variables + - name: wasmdebuggertestsContainsChange + value: $[ dependencies.evaluate_paths.outputs['SetPathVars_wasmdebuggertests.containsChange'] ] + jobParameters: + testGroup: innerloop + nameSuffix: Windows_wasm_DebuggerTests + buildArgs: -s mono+libs+libs.tests -c $(_BuildConfig) /p:ArchiveTests=true /p:TestWasmDebuggerTests=true /p:TestAssemblies=false /p:BrowserHost=windows + timeoutInMinutes: 180 + condition: >- + or( + eq(dependencies.evaluate_paths.outputs['SetPathVars_wasmdebuggertests.containsChange'], true), + eq(variables['isFullMatrix'], true)) + # extra steps, run tests + extraStepsTemplate: /eng/pipelines/libraries/helix.yml + extraStepsParameters: + creator: dotnet-bot + testRunNamePrefixSuffix: Mono_$(_BuildConfig) + extraHelixArguments: /p:BrowserHost=windows + scenarios: + - wasmdebuggertests + # # CoreCLR Build for running Apple Silicon libraries-innerloop # diff --git a/eng/testing/scenarios/WasmDebuggerTestsJobsList.txt b/eng/testing/scenarios/WasmDebuggerTestsJobsList.txt new file mode 100644 index 00000000000..d4ef9dcbfc3 --- /dev/null +++ b/eng/testing/scenarios/WasmDebuggerTestsJobsList.txt @@ -0,0 +1,18 @@ +DebuggerTests.ArrayTests +DebuggerTests.AssignmentTests +DebuggerTests.AsyncTests +DebuggerTests.BadHarnessInitTests +DebuggerTests.BreakpointTests +DebuggerTests.CallFunctionOnTests +DebuggerTests.CustomViewTests +DebuggerTests.DateTimeTests +DebuggerTests.DelegateTests +DebuggerTests.EvaluateOnCallFrameTests +DebuggerTests.ExceptionTests +DebuggerTests.GetPropertiesTests +DebuggerTests.HarnessTests +DebuggerTests.MonoJsTests +DebuggerTests.PointerTests +DebuggerTests.SetVariableValueTests +DebuggerTests.MiscTests +DebuggerTests.SteppingTests diff --git a/eng/testing/workloads-testing.targets b/eng/testing/workloads-testing.targets index 67a781d1058..866e80d596f 100644 --- a/eng/testing/workloads-testing.targets +++ b/eng/testing/workloads-testing.targets @@ -36,10 +36,17 @@ - <_DotNetInstallScriptPath Condition="!$([MSBuild]::IsOSPlatform('windows'))">$(DOTNET_INSTALL_DIR)/dotnet-install.sh - <_DotNetInstallScriptPath Condition=" $([MSBuild]::IsOSPlatform('windows'))">$(RepoRoot).dotnet\dotnet-install.ps1 + <_DotNetInstallScriptName Condition="!$([MSBuild]::IsOSPlatform('windows'))">dotnet-install.sh + <_DotNetInstallScriptName Condition=" $([MSBuild]::IsOSPlatform('windows'))">dotnet-install.ps1 + + <_DotNetInstallScriptPath>$(ArtifactsObjDir)$(_DotNetInstallScriptName) + + diff --git a/src/libraries/sendtohelixhelp.proj b/src/libraries/sendtohelixhelp.proj index 9051d411c55..6fcbb9d4e59 100644 --- a/src/libraries/sendtohelixhelp.proj +++ b/src/libraries/sendtohelixhelp.proj @@ -32,6 +32,7 @@ <_workItemTimeout Condition="'$(Scenario)' != '' and '$(_workItemTimeout)' == '' and ('$(TargetArchitecture)' == 'arm64' or '$(TargetArchitecture)' == 'arm')">01:00:00 <_workItemTimeout Condition="'$(Scenario)' == 'BuildWasmApps' and '$(_workItemTimeout)' == ''">01:30:00 <_workItemTimeout Condition="'$(TargetOS)' == 'Browser' and '$(NeedsToBuildWasmAppsOnHelix)' == 'true'">01:00:00 + <_workItemTimeout Condition="'$(TargetOS)' == 'Browser' and '$(Scenario)' == 'WasmDebuggerTests'">00:10:00 <_workItemTimeout Condition="'$(Scenario)' == '' and '$(_workItemTimeout)' == '' and '$(Outerloop)' == 'true'">00:20:00 <_workItemTimeout Condition="'$(Scenario)' == '' and '$(_workItemTimeout)' == ''">00:15:00 <_workItemTimeout Condition="'$(Scenario)' != '' and '$(_workItemTimeout)' == ''">00:30:00 @@ -40,6 +41,7 @@ $(TestArchiveRuntimeFile) + $(TestArchiveTestsRoot)**/Wasm.Debugger.Tests.zip $(TestArchiveTestsRoot)**/*.zip $(Configuration) @@ -54,11 +56,14 @@ $(TestRunNamePrefix)$(TestRunNamePrefixSuffix)- $(TestRunNamePrefix)$(Scenario)- + true $(RepositoryEngineeringDir)\testing\scenarios\BuildWasmAppsJobsList.txt + $(RepositoryEngineeringDir)\testing\scenarios\WasmDebuggerTestsJobsList.txt + true $(WaitForWorkItemCompletion) true - + true $(RepoRoot)src\mono\wasm\emsdk\ @@ -66,6 +71,7 @@ true true true + true dotnet-workload sdk-no-workload @@ -116,7 +122,7 @@ We also run some network tests to this server and so, we are running it on both HTTP and HTTPS. For the HTTPS endpoint we need development SSL certificate. --> - true + true true @@ -448,6 +454,10 @@ + + + + <_WorkItem Include="$(TestArchiveRoot)browseronly/**/*.zip" Condition="'$(TargetOS)' == 'Browser' and '$(Scenario)' == 'WasmTestOnBrowser'" /> - + %(Identity) $(HelixCommand) $(_workItemTimeout) + + <_BuildWasmAppsPayloadArchive>@(_WorkItem) + <_WasmDebuggerTestsPayloadArchive>@(_WorkItem) @@ -481,6 +495,19 @@ + + + $(_WasmDebuggerTestsPayloadArchive) + + + set TEST_ARGS=--filter "FullyQualifiedName~%(Identity)^&Category!=windows-failing" + export TEST_ARGS="--filter FullyQualifiedName~%(Identity)&Category!=linux-failing" + + $(HelixCommand) + $(_workItemTimeout) + + + dotnet exec $XHARNESS_CLI_PATH $HELIX_WORKITEM_UPLOAD_ROOT/xharness-output @@ -493,7 +520,7 @@ --browser-path=%HELIX_CORRELATION_PAYLOAD%\chrome-win\chrome.exe - + <_RunOnlyWorkItem Include="$(TestArchiveRoot)runonly/**/*.Console.Sample.zip" /> @@ -526,6 +553,10 @@ ContinueOnError="true" IgnoreExitCode="true" IgnoreStandardErrorWarningFormat="true" /> + + + + - + + diff --git a/src/mono/wasm/Makefile b/src/mono/wasm/Makefile index 04828bba724..d3f9b3bf08c 100644 --- a/src/mono/wasm/Makefile +++ b/src/mono/wasm/Makefile @@ -23,6 +23,7 @@ SYSTEM_NATIVE_LIBDIR?=$(TOP)/src/native/libs/System.Native _MSBUILD_WASM_BUILD_ARGS=/p:TargetOS=Browser /p:TargetArchitecture=wasm /p:Configuration=$(CONFIG) XHARNESS_BROWSER?=chrome EMCC_DEFAULT_RSP=$(NATIVE_BIN_DIR)/src/emcc-default.rsp +HELIX_TARGET_QUEUE?=Ubuntu.1804.Amd64.Open all: build-native icu-files source-files header-files @@ -164,6 +165,32 @@ run-build-tests: run-browser-tests-%: PATH="$(GECKODRIVER):$(CHROMEDRIVER):$(PATH)" XHARNESS_COMMAND="test-browser --browser=$(XHARNESS_BROWSER)" $(DOTNET) build $(TOP)/src/libraries/$*/tests/ /t:Test $(_MSBUILD_WASM_BUILD_ARGS) $(MSBUILD_ARGS) +build-debugger-tests-helix: + $(DOTNET) build -restore -bl:$(TOP)/artifacts/log/$(CONFIG)/Wasm.Debugger.Tests.binlog \ + /p:ContinuousIntegrationBuild=true /p:ArchiveTests=true \ + $(TOP)/src/tests/BuildWasmApps/Wasm.Debugger.Tests/Wasm.Debugger.Tests.csproj \ + $(_MSBUILD_WASM_BUILD_ARGS) $(MSBUILD_ARGS) + +submit-debugger-tests-helix: build-debugger-tests-helix + EMSDK_PATH=$(EMSDK_PATH) BUILD_REASON=wasm-test SYSTEM_TEAMPROJECT=public BUILD_REPOSITORY_NAME=dotnet/runtime BUILD_SOURCEBRANCH=main \ + $(TOP)/eng/common/msbuild.sh --ci -restore $(TOP)/src/libraries/sendtohelix.proj \ + /p:TestRunNamePrefixSuffix=WasmDebugger /p:HelixBuild=`date "+%Y%m%d.%H%M"` /p:Creator=`whoami` \ + /bl:$(TOP)/artifacts/log/$(CONFIG)/SendToHelix.binlog -p:HelixTargetQueue=$(HELIX_TARGET_QUEUE) \ + /p:RuntimeFlavor=mono /p:TargetRuntimeIdentifier= /p:MonoForceInterpreter= /p:TestScope=innerloop \ + /p:_Scenarios=wasmdebuggertests \ + $(_MSBUILD_WASM_BUILD_ARGS) \ + $(MSBUILD_ARGS) + +submit-tests-helix: + echo "\n** This will submit all the available test zip files to helix **\n" + EMSDK_PATH=$(EMSDK_PATH) BUILD_REASON=wasm-test SYSTEM_TEAMPROJECT=public BUILD_REPOSITORY_NAME=dotnet/runtime BUILD_SOURCEBRANCH=main \ + $(TOP)/eng/common/msbuild.sh --ci -restore $(TOP)/src/libraries/sendtohelix.proj \ + /p:TestRunNamePrefixSuffix=WasmTests /p:HelixBuild=`date "+%Y%m%d.%H%M"` /p:Creator=`whoami` \ + /bl:$(TOP)/artifacts/log/$(CONFIG)/SendToHelix.binlog -v:n -p:HelixTargetQueue=$(HELIX_TARGET_QUEUE) \ + /p:RuntimeFlavor=mono /p:TargetRuntimeIdentifier= /p:MonoForceInterpreter= /p:TestScope=innerloop \ + $(_MSBUILD_WASM_BUILD_ARGS) \ + $(MSBUILD_ARGS) + run-debugger-tests: if [ ! -z "$(TEST_FILTER)" ]; then \ $(DOTNET) test $(TOP)/src/mono/wasm/debugger/DebuggerTestSuite $(MSBUILD_ARGS) --filter FullyQualifiedName~$(TEST_FILTER) $(TEST_ARGS); \ diff --git a/src/mono/wasm/build/WasmApp.targets b/src/mono/wasm/build/WasmApp.targets index 1185fc11a56..1df620145be 100644 --- a/src/mono/wasm/build/WasmApp.targets +++ b/src/mono/wasm/build/WasmApp.targets @@ -207,9 +207,13 @@ <_ParsedRuntimeConfigFilePath Condition="'$(_WasmRuntimeConfigFilePath)' != ''">$([System.IO.Path]::GetDirectoryName($(_WasmRuntimeConfigFilePath)))\runtimeconfig.bin - - + + + <_WasmAssembliesInternal Remove="@(_WasmAssembliesInternal)" /> diff --git a/src/mono/wasm/debugger/BrowserDebugHost/Startup.cs b/src/mono/wasm/debugger/BrowserDebugHost/Startup.cs index f5dc5ecca47..074a953b694 100644 --- a/src/mono/wasm/debugger/BrowserDebugHost/Startup.cs +++ b/src/mono/wasm/debugger/BrowserDebugHost/Startup.cs @@ -160,7 +160,11 @@ async Task ConnectProxy(HttpContext context) try { using ILoggerFactory loggerFactory = LoggerFactory.Create(builder => - builder.AddSimpleConsole(options => options.SingleLine = true) + builder.AddSimpleConsole(options => + { + options.SingleLine = true; + options.TimestampFormat = "[HH:mm:ss] "; + }) .AddFilter(null, LogLevel.Information) ); diff --git a/src/mono/wasm/debugger/BrowserDebugProxy/DebugStore.cs b/src/mono/wasm/debugger/BrowserDebugProxy/DebugStore.cs index e5579df8f86..6fb9b309d88 100644 --- a/src/mono/wasm/debugger/BrowserDebugProxy/DebugStore.cs +++ b/src/mono/wasm/debugger/BrowserDebugProxy/DebugStore.cs @@ -824,14 +824,14 @@ internal void AddMethod(MethodInfo mi) return (start.StartLocation.Line, start.StartLocation.Column, end.EndLocation.Line, end.EndLocation.Column); } - private static async Task GetDataAsync(Uri uri, CancellationToken token) + private async Task GetDataAsync(Uri uri, CancellationToken token) { var mem = new MemoryStream(); try { if (uri.IsFile && File.Exists(uri.LocalPath)) { - using (FileStream file = File.Open(uri.LocalPath, FileMode.Open)) + using (FileStream file = File.Open(SourceUri.LocalPath, FileMode.Open)) { await file.CopyToAsync(mem, token).ConfigureAwait(false); mem.Position = 0; diff --git a/src/mono/wasm/debugger/DebuggerTestSuite/ArrayTests.cs b/src/mono/wasm/debugger/DebuggerTestSuite/ArrayTests.cs index 05d3d6cccbf..82057f4c75b 100644 --- a/src/mono/wasm/debugger/DebuggerTestSuite/ArrayTests.cs +++ b/src/mono/wasm/debugger/DebuggerTestSuite/ArrayTests.cs @@ -4,13 +4,14 @@ using System; using System.Linq; using System.Threading.Tasks; -using Microsoft.WebAssembly.Diagnostics; using Newtonsoft.Json.Linq; using Xunit; namespace DebuggerTests { - + // https://github.com/dotnet/runtime/issues/62661 + [Trait("Category", "windows-failing")] + [Trait("Category", "linux-failing")] public class ArrayTests : DebuggerTestBase { diff --git a/src/mono/wasm/debugger/DebuggerTestSuite/AssignmentTests.cs b/src/mono/wasm/debugger/DebuggerTestSuite/AssignmentTests.cs index 0601552db6b..7a5111b3647 100644 --- a/src/mono/wasm/debugger/DebuggerTestSuite/AssignmentTests.cs +++ b/src/mono/wasm/debugger/DebuggerTestSuite/AssignmentTests.cs @@ -46,19 +46,21 @@ async Task InspectVariableBeforeAndAfterAssignment(string clazz, JObject checkDe // 1) check un-assigned variables await StepAndCheck(StepKind.Into, "dotnet://debugger-test.dll/debugger-assignment-test.cs", -1, -1, "TestedMethod", - locals_fn: (locals) => + locals_fn: async (locals) => { Assert.Equal(2, locals.Count()); Check(locals, "r", checkDefault); + await Task.CompletedTask; } ); // 2) check assigned variables await StepAndCheck(StepKind.Over, "dotnet://debugger-test.dll/debugger-assignment-test.cs", -1, -1, "TestedMethod", times: 3, - locals_fn: (locals) => + locals_fn: async (locals) => { Assert.Equal(2, locals.Count()); Check(locals, "r", checkValue); + await Task.CompletedTask; } ); } diff --git a/src/mono/wasm/debugger/DebuggerTestSuite/BreakpointTests.cs b/src/mono/wasm/debugger/DebuggerTestSuite/BreakpointTests.cs index f3bf3c8ecb4..b80a8f429b4 100644 --- a/src/mono/wasm/debugger/DebuggerTestSuite/BreakpointTests.cs +++ b/src/mono/wasm/debugger/DebuggerTestSuite/BreakpointTests.cs @@ -257,38 +257,45 @@ public async Task BreakOnDebuggerBreak() "window.setTimeout(function() { invoke_static_method_async('[debugger-test] UserBreak:BreakOnDebuggerBreakCommand'); }, 1);", "dotnet://debugger-test.dll/debugger-test2.cs", 58, 8, "BreakOnDebuggerBreakCommand", - locals_fn: (locals) => + locals_fn: async (locals) => { CheckNumber(locals, "a", 10); + await Task.CompletedTask; } ); await StepAndCheck(StepKind.Over, "dotnet://debugger-test.dll/debugger-test2.cs", 59, 8, "BreakOnDebuggerBreakCommand", - locals_fn: (locals) => + locals_fn: async (locals) => { CheckNumber(locals, "a", 10); + await Task.CompletedTask; } ); await StepAndCheck(StepKind.Over, "dotnet://debugger-test.dll/debugger-test2.cs", 60, 8, "BreakOnDebuggerBreakCommand", - locals_fn: (locals) => + locals_fn: async (locals) => { CheckNumber(locals, "a", 20); + await Task.CompletedTask; } ); await StepAndCheck(StepKind.Over, "dotnet://debugger-test.dll/debugger-test2.cs", 61, 8, "BreakOnDebuggerBreakCommand", - locals_fn: (locals) => + locals_fn: async (locals) => { CheckNumber(locals, "a", 50); + await Task.CompletedTask; } ); await StepAndCheck(StepKind.Over, "dotnet://debugger-test.dll/debugger-test2.cs", 62, 4, "BreakOnDebuggerBreakCommand", - locals_fn: (locals) => + locals_fn: async (locals) => { CheckNumber(locals, "a", 100); + await Task.CompletedTask; } ); } [Fact] + [Trait("Category", "windows-failing")] // https://github.com/dotnet/runtime/issues/62823 + [Trait("Category", "linux-failing")] // https://github.com/dotnet/runtime/issues/62823 public async Task BreakpointInAssemblyUsingTypeFromAnotherAssembly_BothDynamicallyLoaded() { int line = 7; @@ -370,24 +377,27 @@ public async Task DebugHotReloadMethodAddBreakpoint() CheckBool(locals, "c", true); await StepAndCheck(StepKind.Over, "dotnet://ApplyUpdateReferencedAssembly.dll/MethodBody1.cs", 31, 12, "StaticMethod3", - locals_fn: (locals) => + locals_fn: async (locals) => { CheckNumber(locals, "d", 10); + await Task.CompletedTask; } ); await StepAndCheck(StepKind.Over, "dotnet://ApplyUpdateReferencedAssembly.dll/MethodBody1.cs", 32, 12, "StaticMethod3", - locals_fn: (locals) => + locals_fn: async (locals) => { CheckNumber(locals, "d", 10); CheckNumber(locals, "e", 20); + await Task.CompletedTask; } ); await StepAndCheck(StepKind.Over, "dotnet://ApplyUpdateReferencedAssembly.dll/MethodBody1.cs", 33, 8, "StaticMethod3", - locals_fn: (locals) => + locals_fn: async (locals) => { CheckNumber(locals, "d", 10); CheckNumber(locals, "e", 20); CheckNumber(locals, "f", 50); + await Task.CompletedTask; } ); } @@ -408,37 +418,42 @@ public async Task DebugHotReloadMethodEmpty() pause_location = await SendCommandAndCheck(JObject.FromObject(new { }), "Debugger.resume", "dotnet://ApplyUpdateReferencedAssembly.dll/MethodBody1.cs", 38, 12, "StaticMethod4"); locals = await GetProperties(pause_location["callFrames"][0]["callFrameId"].Value()); await StepAndCheck(StepKind.Over, "dotnet://ApplyUpdateReferencedAssembly.dll/MethodBody1.cs", 39, 12, "StaticMethod4", - locals_fn: (locals) => + locals_fn: async (locals) => { CheckNumber(locals, "a", 10); + await Task.CompletedTask; } ); await StepAndCheck(StepKind.Over, "dotnet://ApplyUpdateReferencedAssembly.dll/MethodBody1.cs", 40, 12, "StaticMethod4", - locals_fn: (locals) => + locals_fn: async (locals) => { CheckNumber(locals, "a", 10); CheckNumber(locals, "b", 20); + await Task.CompletedTask; } ); await StepAndCheck(StepKind.Over, "dotnet://ApplyUpdateReferencedAssembly.dll/MethodBody1.cs", 41, 12, "StaticMethod4", - locals_fn: (locals) => + locals_fn: async (locals) => { CheckNumber(locals, "a", 10); CheckNumber(locals, "b", 20); + await Task.CompletedTask; } ); await StepAndCheck(StepKind.Over, "dotnet://ApplyUpdateReferencedAssembly.dll/MethodBody1.cs", 42, 12, "StaticMethod4", - locals_fn: (locals) => + locals_fn: async (locals) => { CheckNumber(locals, "a", 10); CheckNumber(locals, "b", 20); + await Task.CompletedTask; } ); await StepAndCheck(StepKind.Over, "dotnet://ApplyUpdateReferencedAssembly.dll/MethodBody1.cs", 43, 8, "StaticMethod4", - locals_fn: (locals) => + locals_fn: async (locals) => { CheckNumber(locals, "a", 10); CheckNumber(locals, "b", 20); + await Task.CompletedTask; } ); pause_location = await SendCommandAndCheck(JObject.FromObject(new { }), "Debugger.resume", "dotnet://ApplyUpdateReferencedAssembly.dll/MethodBody1.cs", 38, 8, "StaticMethod4"); @@ -456,9 +471,10 @@ public async Task ConditionalBreakpointInALoop() bp_conditional.Value["locations"][0]["lineNumber"].Value(), bp_conditional.Value["locations"][0]["columnNumber"].Value(), "LoopToBreak", - locals_fn: (locals) => + locals_fn: async (locals) => { CheckNumber(locals, "i", 3); + await Task.CompletedTask; } ); @@ -480,9 +496,10 @@ public async Task ConditionalBreakpointInALoopStopMoreThanOnce() bp_conditional.Value["locations"][0]["lineNumber"].Value(), bp_conditional.Value["locations"][0]["columnNumber"].Value(), "LoopToBreak", - locals_fn: (locals) => + locals_fn: async (locals) => { CheckNumber(locals, "i", 0); + await Task.CompletedTask; } ); @@ -491,9 +508,10 @@ public async Task ConditionalBreakpointInALoopStopMoreThanOnce() bp_conditional.Value["locations"][0]["lineNumber"].Value(), bp_conditional.Value["locations"][0]["columnNumber"].Value(), "LoopToBreak", - locals_fn: (locals) => + locals_fn: async (locals) => { CheckNumber(locals, "i", 3); + await Task.CompletedTask; }); await SendCommandAndCheck(null, "Debugger.resume", @@ -501,9 +519,10 @@ public async Task ConditionalBreakpointInALoopStopMoreThanOnce() bp_conditional.Value["locations"][0]["lineNumber"].Value(), bp_conditional.Value["locations"][0]["columnNumber"].Value(), "LoopToBreak", - locals_fn: (locals) => + locals_fn: async (locals) => { CheckNumber(locals, "i", 6); + await Task.CompletedTask; }); await SendCommandAndCheck(null, "Debugger.resume", @@ -511,9 +530,10 @@ public async Task ConditionalBreakpointInALoopStopMoreThanOnce() bp_conditional.Value["locations"][0]["lineNumber"].Value(), bp_conditional.Value["locations"][0]["columnNumber"].Value(), "LoopToBreak", - locals_fn: (locals) => + locals_fn: async (locals) => { CheckNumber(locals, "i", 9); + await Task.CompletedTask; }); await SendCommandAndCheck(null, "Debugger.resume", @@ -547,9 +567,10 @@ public async Task ConditionalBreakpointNotBooleanInALoop() bp_conditional.Value["locations"][0]["lineNumber"].Value(), bp_conditional.Value["locations"][0]["columnNumber"].Value(), "LoopToBreak", - locals_fn: (locals) => + locals_fn: async (locals) => { CheckNumber(locals, "i", 0); + await Task.CompletedTask; } ); @@ -558,9 +579,10 @@ public async Task ConditionalBreakpointNotBooleanInALoop() bp_conditional.Value["locations"][0]["lineNumber"].Value(), bp_conditional.Value["locations"][0]["columnNumber"].Value(), "LoopToBreak", - locals_fn: (locals) => + locals_fn: async (locals) => { CheckNumber(locals, "i", 1); + await Task.CompletedTask; }); await SendCommandAndCheck(null, "Debugger.resume", @@ -568,9 +590,10 @@ public async Task ConditionalBreakpointNotBooleanInALoop() bp_conditional.Value["locations"][0]["lineNumber"].Value(), bp_conditional.Value["locations"][0]["columnNumber"].Value(), "LoopToBreak", - locals_fn: (locals) => + locals_fn: async (locals) => { CheckNumber(locals, "i", 2); + await Task.CompletedTask; }); } @@ -642,7 +665,7 @@ public async Task CreateGoodBreakpointAndHitGoToNonWasmPageComeBackAndHitAgain() } ); } - + [Fact] public async Task DebuggerAttributeNoStopInDebuggerHidden() diff --git a/src/mono/wasm/debugger/DebuggerTestSuite/DateTimeTests.cs b/src/mono/wasm/debugger/DebuggerTestSuite/DateTimeTests.cs index 2d3707fec1d..8115604204a 100644 --- a/src/mono/wasm/debugger/DebuggerTestSuite/DateTimeTests.cs +++ b/src/mono/wasm/debugger/DebuggerTestSuite/DateTimeTests.cs @@ -8,7 +8,7 @@ namespace DebuggerTests { - public class DateTimeList : DebuggerTestBase + public class DateTimeTests : DebuggerTestBase { [Theory] diff --git a/src/mono/wasm/debugger/DebuggerTestSuite/DebuggerTestBase.cs b/src/mono/wasm/debugger/DebuggerTestSuite/DebuggerTestBase.cs index 1329e284eb0..fbc176dc2ca 100644 --- a/src/mono/wasm/debugger/DebuggerTestSuite/DebuggerTestBase.cs +++ b/src/mono/wasm/debugger/DebuggerTestSuite/DebuggerTestBase.cs @@ -40,17 +40,30 @@ protected static string DebuggerTestAppPath static protected string FindTestPath() { - var asm_dir = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); + string test_app_path = Environment.GetEnvironmentVariable("DEBUGGER_TEST_PATH"); + + if (string.IsNullOrEmpty(test_app_path)) + { + var asm_dir = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); #if DEBUG - var config="Debug"; + var config="Debug"; #else - var config="Release"; -#endif - var test_app_path = Path.Combine(asm_dir, "..", "..", "..", "debugger-test", config, "publish"); + var config="Release"; +#endif + test_app_path = Path.Combine(asm_dir, "..", "..", "..", "debugger-test", config); + + if (string.IsNullOrEmpty(test_app_path)) + throw new Exception("Could not figure out debugger-test app path from the 'DEBUGGER_TEST_PATH' " + + $"environment variable, or based on the test suite location ({asm_dir})"); + } + + if (!string.IsNullOrEmpty(test_app_path)) + test_app_path = Path.Combine(test_app_path, "AppBundle"); + if (File.Exists(Path.Combine(test_app_path, "debugger-driver.html"))) return test_app_path; - throw new Exception($"Could not figure out debugger-test app path ({test_app_path}) based on the test suite location ({asm_dir})"); + throw new Exception($"Cannot find 'debugger-driver.html' in {test_app_path}"); } static string[] PROBE_LIST = { @@ -63,21 +76,32 @@ static protected string FindTestPath() }; static string chrome_path; - static string FindChromePath() + static string GetChromePath() { - if (chrome_path != null) - return chrome_path; + if (string.IsNullOrEmpty(chrome_path)) + { + chrome_path = FindChromePath(); + if (!string.IsNullOrEmpty(chrome_path)) + Console.WriteLine ($"** Using chrome from {chrome_path}"); + else + throw new Exception("Could not find an installed Chrome to use"); + } - foreach (var s in PROBE_LIST) + return chrome_path; + + string FindChromePath() { - if (File.Exists(s)) + string chrome_path_env_var = Environment.GetEnvironmentVariable("CHROME_PATH_FOR_DEBUGGER_TESTS"); + if (!string.IsNullOrEmpty(chrome_path_env_var)) { - chrome_path = s; - Console.WriteLine($"Using chrome path: ${s}"); - return s; + if (File.Exists(chrome_path_env_var)) + return chrome_path_env_var; + + Console.WriteLine ($"warning: Could not find CHROME_PATH_FOR_DEBUGGER_TESTS={chrome_path_env_var}"); } + + return PROBE_LIST.FirstOrDefault(p => File.Exists(p)); } - throw new Exception("Could not find an installed Chrome to use"); } public DebuggerTestBase(string driver = "debugger-driver.html") @@ -90,7 +114,7 @@ public DebuggerTestBase(string driver = "debugger-driver.html") cli = insp.Client; scripts = SubscribeToScripts(insp); - startTask = TestHarnessProxy.Start(FindChromePath(), DebuggerTestAppPath, driver); + startTask = TestHarnessProxy.Start(GetChromePath(), DebuggerTestAppPath, driver); } public virtual async Task InitializeAsync() @@ -148,7 +172,7 @@ public virtual async Task InitializeAsync() } internal async Task CheckInspectLocalsAtBreakpointSite(string url_key, int line, int column, string function_name, string eval_expression, - Action test_fn = null, Func wait_for_event_fn = null, bool use_cfo = false) + Func test_fn = null, Func wait_for_event_fn = null, bool use_cfo = false) { UseCallFunctionOnBeforeGetProperties = use_cfo; @@ -171,10 +195,10 @@ public virtual async Task InitializeAsync() else await Task.CompletedTask; }, - locals_fn: (locals) => + locals_fn: async (locals) => { if (test_fn != null) - test_fn(locals); + await test_fn(locals); } ); } @@ -436,7 +460,7 @@ internal async Task SetValueOnObject(JToken obj, string property, string } internal async Task StepAndCheck(StepKind kind, string script_loc, int line, int column, string function_name, - Func wait_for_event_fn = null, Action locals_fn = null, int times = 1) + Func wait_for_event_fn = null, Func locals_fn = null, int times = 1) { string method = (kind == StepKind.Resume ? "Debugger.resume" : $"Debugger.step{kind}"); for (int i = 0; i < times - 1; i++) @@ -451,15 +475,17 @@ internal async Task SetValueOnObject(JToken obj, string property, string locals_fn: locals_fn); } - internal async Task EvaluateAndCheck(string expression, string script_loc, int line, int column, string function_name, - Func wait_for_event_fn = null, Action locals_fn = null) => await SendCommandAndCheck( - JObject.FromObject(new { expression = expression }), - "Runtime.evaluate", script_loc, line, column, function_name, - wait_for_event_fn: wait_for_event_fn, - locals_fn: locals_fn); + internal async Task EvaluateAndCheck( + string expression, string script_loc, int line, int column, string function_name, + Func wait_for_event_fn = null, Func locals_fn = null) + => await SendCommandAndCheck( + JObject.FromObject(new { expression = expression }), + "Runtime.evaluate", script_loc, line, column, function_name, + wait_for_event_fn: wait_for_event_fn, + locals_fn: locals_fn); internal async Task SendCommandAndCheck(JObject args, string method, string script_loc, int line, int column, string function_name, - Func wait_for_event_fn = null, Action locals_fn = null, string waitForEvent = Inspector.PAUSE) + Func wait_for_event_fn = null, Func locals_fn = null, string waitForEvent = Inspector.PAUSE) { var res = await cli.SendCommand(method, args, token); if (!res.IsOk) @@ -486,7 +512,7 @@ internal async Task SetValueOnObject(JToken obj, string property, string var locals = await GetProperties(wait_res["callFrames"][0]["callFrameId"].Value()); try { - locals_fn(locals); + await locals_fn(locals); } catch (System.AggregateException ex) { diff --git a/src/mono/wasm/debugger/DebuggerTestSuite/DebuggerTestSuite.csproj b/src/mono/wasm/debugger/DebuggerTestSuite/DebuggerTestSuite.csproj index a46fd059b01..90e236ceb5b 100644 --- a/src/mono/wasm/debugger/DebuggerTestSuite/DebuggerTestSuite.csproj +++ b/src/mono/wasm/debugger/DebuggerTestSuite/DebuggerTestSuite.csproj @@ -16,7 +16,18 @@ - + + + + + <_FilesToCopy Include="$(OutputPath)\**\*" TargetPath="DebuggerTestSuite" /> + <_FilesToCopy Include="$(ArtifactsBinDir)debugger-test\Debug\**\*" TargetPath="debugger-test" /> + + + + diff --git a/src/mono/wasm/debugger/DebuggerTestSuite/ExceptionTests.cs b/src/mono/wasm/debugger/DebuggerTestSuite/ExceptionTests.cs index 8919f4a6ee1..e1ed977ae52 100644 --- a/src/mono/wasm/debugger/DebuggerTestSuite/ExceptionTests.cs +++ b/src/mono/wasm/debugger/DebuggerTestSuite/ExceptionTests.cs @@ -235,6 +235,7 @@ public async Task ExceptionTestUncaughtWithReload() [Theory] [InlineData("[debugger-test] DebuggerTests.ExceptionTestsClassDefault:TestExceptions", "System.Exception", 76)] [InlineData("[debugger-test] DebuggerTests.ExceptionTestsClass:TestExceptions", "DebuggerTests.CustomException", 28)] + [Trait("Category", "linux-failing")] // https://github.com/dotnet/runtime/issues/62666 public async Task ExceptionTestAllWithReload(string entry_method_name, string class_name, int line_number) { var debugger_test_loc = "dotnet://debugger-test.dll/debugger-exception-test.cs"; diff --git a/src/mono/wasm/debugger/DebuggerTestSuite/HarnessTests.cs b/src/mono/wasm/debugger/DebuggerTestSuite/HarnessTests.cs index ef36ace6624..865eaa8c630 100644 --- a/src/mono/wasm/debugger/DebuggerTestSuite/HarnessTests.cs +++ b/src/mono/wasm/debugger/DebuggerTestSuite/HarnessTests.cs @@ -36,8 +36,13 @@ public async Task ExceptionThrown() await SendCommandAndCheck(null, "Browser.crash", null, -1, -1, null)); [Fact] - public async Task BrowserClose() => await Assert.ThrowsAsync(async () => - await SendCommandAndCheck(null, "Browser.close", null, -1, -1, null)); + public async Task BrowserClose() + { + ArgumentException ae = await Assert.ThrowsAsync(async () => + await SendCommandAndCheck(null, "Browser.close", null, -1, -1, null)); + Assert.Contains("Inspector.detached", ae.Message); + Assert.Contains("target_close", ae.Message); + } [Fact] public async Task InspectorWaitForAfterMessageAlreadyReceived() diff --git a/src/mono/wasm/debugger/DebuggerTestSuite/Inspector.cs b/src/mono/wasm/debugger/DebuggerTestSuite/Inspector.cs index 826d860c21e..616349e3385 100644 --- a/src/mono/wasm/debugger/DebuggerTestSuite/Inspector.cs +++ b/src/mono/wasm/debugger/DebuggerTestSuite/Inspector.cs @@ -42,7 +42,11 @@ public Inspector() Token = _cancellationTokenSource.Token; _loggerFactory = LoggerFactory.Create(builder => - builder.AddSimpleConsole(options => options.SingleLine = true) + builder.AddSimpleConsole(options => + { + options.SingleLine = true; + options.TimestampFormat = "[HH:mm:ss] "; + }) .AddFilter(null, LogLevel.Trace)); Client = new InspectorClient(_loggerFactory.CreateLogger()); @@ -175,6 +179,7 @@ async Task OnMessage(string method, JObject args, CancellationToken token) } else if (fail) { + args["__forMethod"] = method; FailAllWaiters(new ArgumentException(args.ToString())); } } @@ -198,7 +203,7 @@ public async Task OpenSessionAsync(Func + test_fn: async (locals) => { CheckNumber(locals, "a", 10); CheckNumber(locals, "b", 20); CheckNumber(locals, "c", 30); CheckNumber(locals, "d", 0); CheckNumber(locals, "e", 0); + await Task.CompletedTask; } ); @@ -81,10 +81,11 @@ public async Task ExceptionThrownInJSOutOfBand() await CheckInspectLocalsAtBreakpointSite( "dotnet://debugger-test.dll/debugger-test.cs", 154, 8, "PrimitiveTypesTest", "window.setTimeout(function() { invoke_static_method ('[debugger-test] Math:PrimitiveTypesTest'); }, 1);", - test_fn: (locals) => + test_fn: async (locals) => { CheckSymbol(locals, "c0", "8364 '€'"); CheckSymbol(locals, "c1", "65 'A'"); + await Task.CompletedTask; } ); @@ -94,7 +95,7 @@ public async Task ExceptionThrownInJSOutOfBand() "dotnet://debugger-test.dll/debugger-test2.cs", 50, 8, "Types", "window.setTimeout(function() { invoke_static_method (\"[debugger-test] Fancy:Types\")(); }, 1);", use_cfo: false, - test_fn: (locals) => + test_fn: async (locals) => { CheckNumber(locals, "dPI", Math.PI); CheckNumber(locals, "fPI", (float)Math.PI); @@ -116,6 +117,7 @@ public async Task ExceptionThrownInJSOutOfBand() CheckNumber(locals, "sMin", short.MinValue); CheckNumber(locals, "usMin", ushort.MinValue); CheckNumber(locals, "usMax", ushort.MaxValue); + await Task.CompletedTask; } ); @@ -199,7 +201,7 @@ public async Task ExceptionThrownInJSOutOfBand() "dotnet://debugger-test.dll/debugger-test.cs", 74, 8, "GenericTypesTest", "window.setTimeout(function() { invoke_generic_types_test (); }, 1);", use_cfo: use_cfo, - test_fn: (locals) => + test_fn: async (locals) => { CheckObject(locals, "list", "System.Collections.Generic.Dictionary", description: "Count = 0"); CheckObject(locals, "list_null", "System.Collections.Generic.Dictionary", is_null: true); @@ -213,6 +215,7 @@ public async Task ExceptionThrownInJSOutOfBand() CheckArray(locals, "list_arr_unused", "System.Collections.Generic.Dictionary[]", "System.Collections.Generic.Dictionary[1]"); CheckObject(locals, "list_arr_null_unused", "System.Collections.Generic.Dictionary[]", is_null: true); + await Task.CompletedTask; } ); @@ -753,6 +756,7 @@ public async Task DebugLazyLoadedAssemblyWithPdb() } [Fact] + [Trait("Category", "linux-failing")] // https://github.com/dotnet/runtime/issues/62667 public async Task DebugLazyLoadedAssemblyWithEmbeddedPdb() { int line = 9; @@ -806,38 +810,9 @@ public async Task CannotDebugLazyLoadedAssemblyWithoutPdb() Assert.DoesNotContain(source_location, scripts.Values); } - [Fact] - public async Task GetSourceUsingSourceUri() - { - //testing without using sourcelink, expected values at GetSourceAsync - //SourceUri - file:///LOCAL_PATH/runtime/src/mono/wasm/debugger/tests/debugger-test/debugger-test.cs - //SourceLinkUri - empty - var bp1_res = await SetBreakpoint("dotnet://debugger-test.dll/debugger-test.cs", 10, 8); - - Assert.EndsWith("debugger-test.cs", bp1_res.Value["breakpointId"].ToString()); - Assert.Equal(1, bp1_res.Value["locations"]?.Value()?.Count); - - var loc = bp1_res.Value["locations"]?.Value()[0]; - - var sourceToGet = JObject.FromObject(new - { - scriptId = loc["scriptId"]?.Value() - }); - - Assert.Equal("dotnet://debugger-test.dll/debugger-test.cs", scripts[loc["scriptId"]?.Value()]); - var source = await cli.SendCommand("Debugger.getScriptSource", sourceToGet, token); - Assert.True(source.IsOk); - } [Fact] public async Task GetSourceUsingSourceLink() { - //testing using sourcelink, expected values at GetSourceAsync - // On CI - //SourceUri - file:///fakepath/LOCAL_PATH/runtime/src/mono/wasm/debugger/tests/debugger-test-with-source-link/test.cs - //SourceLinkUri - file:///LOCAL_PATH/runtime/src/mono/wasm/debugger/tests/debugger-test-with-source-link/test.cs - // Locally - // SourceUri - file:////src/mono/wasm/debugger/tests/debugger-test-with-source-link/test.cs - // SourceLinkUri - https://raw.githubusercontent.com/FORK/runtime/COMMIT_ID/src/mono/wasm/debugger/tests/debugger-test-with-source-link/test.cs var bp = await SetBreakpointInMethod("debugger-test-with-source-link.dll", "DebuggerTests.ClassToBreak", "TestBreakpoint", 0); var pause_location = await EvaluateAndCheck( "window.setTimeout(function() { invoke_static_method ('[debugger-test-with-source-link] DebuggerTests.ClassToBreak:TestBreakpoint'); }, 1);", @@ -852,7 +827,7 @@ public async Task GetSourceUsingSourceLink() }); var source = await cli.SendCommand("Debugger.getScriptSource", sourceToGet, token); - Assert.True(source.IsOk); + Assert.True(source.IsOk, $"Failed to getScriptSource: {source}"); } [Fact] @@ -882,9 +857,10 @@ public async Task GetSourceUsingSourceLink() "window.setTimeout(function() { invoke_static_method('[debugger-test] MainPage:CallSetValue'); }, 1);", "dotnet://debugger-test.dll/debugger-test.cs", 758, 16, "set_SomeValue", - locals_fn: (locals) => + locals_fn: async (locals) => { CheckNumber(locals, "view", 150); + await Task.CompletedTask; } ); } diff --git a/src/mono/wasm/debugger/DebuggerTestSuite/SetVariableValueTests.cs b/src/mono/wasm/debugger/DebuggerTestSuite/SetVariableValueTests.cs index 9214a4fe6e8..df0970f5ebf 100644 --- a/src/mono/wasm/debugger/DebuggerTestSuite/SetVariableValueTests.cs +++ b/src/mono/wasm/debugger/DebuggerTestSuite/SetVariableValueTests.cs @@ -27,14 +27,15 @@ public class SetVariableValueTests : DebuggerTestBase [InlineData("d", 5, 70, 2147483648)] [InlineData("d2", 6, 70, -50)] [InlineData("d2", 6, 70, 4294967296)] - public async Task SetLocalPrimitiveTypeVariableOutOfRange(string variableName, long originalValue, long newValue, long overflowValue) { + public async Task SetLocalPrimitiveTypeVariableOutOfRange(string variableName, long originalValue, long newValue, long overflowValue) { await SetBreakpointInMethod("debugger-test.dll", "DebuggerTests.SetVariableLocals", "run", 12); var pause_location = await EvaluateAndCheck( "window.setTimeout(function() {{ invoke_static_method_async('[debugger-test] DebuggerTests.SetVariableLocals:run');}}, 1);", "dotnet://debugger-test.dll/debugger-set-variable-value-test.cs", 22, 12, "run", - locals_fn: (locals) => + locals_fn: async (locals) => { CheckNumber(locals, variableName, originalValue); + await Task.CompletedTask; } ); var callFrameId = pause_location["callFrames"][0]["callFrameId"].Value(); @@ -42,9 +43,10 @@ public class SetVariableValueTests : DebuggerTestBase await SetVariableValueOnCallFrame( JObject.FromObject(new {callFrameId, variableName, newValue=JObject.FromObject(new {value=newValue}) })); pause_location = await StepAndCheck(StepKind.Over, "dotnet://debugger-test.dll/debugger-set-variable-value-test.cs", 23, 12, "run", - locals_fn: (locals) => + locals_fn: async (locals) => { CheckNumber(locals, variableName, newValue); + await Task.CompletedTask; } ); @@ -53,9 +55,10 @@ public class SetVariableValueTests : DebuggerTestBase await SetVariableValueOnCallFrame( JObject.FromObject(new {callFrameId, variableName, newValue=JObject.FromObject(new {value=overflowValue}) }), false); pause_location = await StepAndCheck(StepKind.Over, "dotnet://debugger-test.dll/debugger-set-variable-value-test.cs", 24, 8, "run", - locals_fn: (locals) => + locals_fn: async (locals) => { CheckNumber(locals, variableName, newValue); + await Task.CompletedTask; } ); } @@ -63,14 +66,15 @@ public class SetVariableValueTests : DebuggerTestBase [Theory] [InlineData("f", 9, 150.15616, 0.4564)] [InlineData("f", 9, -454.54654, -0.5648)] - public async Task SetLocalFloatVariable(string variableName, float originalValue, float newValue, float newValue2) { + public async Task SetLocalFloatVariable(string variableName, float originalValue, float newValue, float newValue2) { await SetBreakpointInMethod("debugger-test.dll", "DebuggerTests.SetVariableLocals", "run", 12); var pause_location = await EvaluateAndCheck( "window.setTimeout(function() {{ invoke_static_method_async('[debugger-test] DebuggerTests.SetVariableLocals:run');}}, 1);", "dotnet://debugger-test.dll/debugger-set-variable-value-test.cs", 22, 12, "run", - locals_fn: (locals) => + locals_fn: async (locals) => { CheckNumber(locals, variableName, originalValue); + await Task.CompletedTask; } ); var callFrameId = pause_location["callFrames"][0]["callFrameId"].Value(); @@ -78,9 +82,10 @@ public class SetVariableValueTests : DebuggerTestBase await SetVariableValueOnCallFrame( JObject.FromObject(new {callFrameId, variableName, newValue=JObject.FromObject(new {value=newValue}) })); pause_location = await StepAndCheck(StepKind.Over, "dotnet://debugger-test.dll/debugger-set-variable-value-test.cs", 23, 12, "run", - locals_fn: (locals) => + locals_fn: async (locals) => { CheckNumber(locals, variableName, newValue); + await Task.CompletedTask; } ); @@ -89,9 +94,10 @@ public class SetVariableValueTests : DebuggerTestBase await SetVariableValueOnCallFrame( JObject.FromObject(new {callFrameId, variableName, newValue=JObject.FromObject(new {value=newValue2}) })); pause_location = await StepAndCheck(StepKind.Over, "dotnet://debugger-test.dll/debugger-set-variable-value-test.cs", 24, 8, "run", - locals_fn: (locals) => + locals_fn: async (locals) => { CheckNumber(locals, variableName, newValue2); + await Task.CompletedTask; } ); } @@ -99,14 +105,15 @@ public class SetVariableValueTests : DebuggerTestBase [Theory] [InlineData("g", 10, 150.15615844726562, 0.4564000070095062)] [InlineData("g", 10, -454.5465393066406, -0.5648000240325928)] - public async Task SetLocalDoubleVariable(string variableName, double originalValue, double newValue, double newValue2) { + public async Task SetLocalDoubleVariable(string variableName, double originalValue, double newValue, double newValue2) { await SetBreakpointInMethod("debugger-test.dll", "DebuggerTests.SetVariableLocals", "run", 12); var pause_location = await EvaluateAndCheck( "window.setTimeout(function() {{ invoke_static_method_async('[debugger-test] DebuggerTests.SetVariableLocals:run');}}, 1);", "dotnet://debugger-test.dll/debugger-set-variable-value-test.cs", 22, 12, "run", - locals_fn: (locals) => + locals_fn: async (locals) => { CheckNumber(locals, variableName, originalValue); + await Task.CompletedTask; } ); var callFrameId = pause_location["callFrames"][0]["callFrameId"].Value(); @@ -114,9 +121,10 @@ public class SetVariableValueTests : DebuggerTestBase await SetVariableValueOnCallFrame( JObject.FromObject(new {callFrameId, variableName, newValue=JObject.FromObject(new {value=newValue}) })); pause_location = await StepAndCheck(StepKind.Over, "dotnet://debugger-test.dll/debugger-set-variable-value-test.cs", 23, 12, "run", - locals_fn: (locals) => + locals_fn: async (locals) => { CheckNumber(locals, variableName, newValue); + await Task.CompletedTask; } ); @@ -125,9 +133,10 @@ public class SetVariableValueTests : DebuggerTestBase await SetVariableValueOnCallFrame( JObject.FromObject(new {callFrameId, variableName, newValue=JObject.FromObject(new {value=newValue2}) })); pause_location = await StepAndCheck(StepKind.Over, "dotnet://debugger-test.dll/debugger-set-variable-value-test.cs", 24, 8, "run", - locals_fn: (locals) => + locals_fn: async (locals) => { CheckNumber(locals, variableName, newValue2); + await Task.CompletedTask; } ); } @@ -146,14 +155,15 @@ public class SetVariableValueTests : DebuggerTestBase [InlineData("e", "7", "70", "-9223372036854775808")] [InlineData("e", "7", "70", "9254456")] [InlineData("e2", "8", "70", "184467")] - public async Task SetLocalPrimitiveTypeVariableValid(string variableName, string originalValue, string newValue, string newValue2) { + public async Task SetLocalPrimitiveTypeVariableValid(string variableName, string originalValue, string newValue, string newValue2) { await SetBreakpointInMethod("debugger-test.dll", "DebuggerTests.SetVariableLocals", "run", 12); var pause_location = await EvaluateAndCheck( "window.setTimeout(function() {{ invoke_static_method_async('[debugger-test] DebuggerTests.SetVariableLocals:run');}}, 1);", "dotnet://debugger-test.dll/debugger-set-variable-value-test.cs", 22, 12, "run", - locals_fn: (locals) => + locals_fn: async (locals) => { CheckNumberAsString(locals, variableName, originalValue.ToString()); + await Task.CompletedTask; } ); var callFrameId = pause_location["callFrames"][0]["callFrameId"].Value(); @@ -161,9 +171,10 @@ public class SetVariableValueTests : DebuggerTestBase await SetVariableValueOnCallFrame( JObject.FromObject(new {callFrameId, variableName, newValue=JObject.FromObject(new {value=newValue}) })); pause_location = await StepAndCheck(StepKind.Over, "dotnet://debugger-test.dll/debugger-set-variable-value-test.cs", 23, 12, "run", - locals_fn: (locals) => + locals_fn: async (locals) => { CheckNumberAsString(locals, variableName, newValue.ToString()); + await Task.CompletedTask; } ); @@ -172,13 +183,14 @@ public class SetVariableValueTests : DebuggerTestBase await SetVariableValueOnCallFrame( JObject.FromObject(new {callFrameId, variableName, newValue=JObject.FromObject(new {value=newValue2}) })); pause_location = await StepAndCheck(StepKind.Over, "dotnet://debugger-test.dll/debugger-set-variable-value-test.cs", 24, 8, "run", - locals_fn: (locals) => + locals_fn: async (locals) => { CheckNumberAsString(locals, variableName, newValue2.ToString()); + await Task.CompletedTask; } ); } - + [Theory] [InlineData(1, "a", 10, 30)] [InlineData(1, "a", 10, -1)] @@ -190,9 +202,10 @@ public class SetVariableValueTests : DebuggerTestBase var pause_location = await EvaluateAndCheck( "window.setTimeout(function() { invoke_add(); }, 1);", "dotnet://debugger-test.dll/debugger-test.cs", 8+offset, 8, "IntAdd", - locals_fn: (locals) => + locals_fn: async (locals) => { CheckNumber(locals, variableName, originalValue); + await Task.CompletedTask; } ); var callFrameId = pause_location["callFrames"][0]["callFrameId"].Value(); @@ -200,9 +213,10 @@ public class SetVariableValueTests : DebuggerTestBase await SetVariableValueOnCallFrame( JObject.FromObject(new {callFrameId, variableName, newValue=JObject.FromObject(new {value=newValue}) })); await StepAndCheck(StepKind.Over, "dotnet://debugger-test.dll/debugger-test.cs", 9+offset, 8, "IntAdd", - locals_fn: (locals) => + locals_fn: async (locals) => { CheckNumber(locals, variableName, newValue); + await Task.CompletedTask; } ); } @@ -218,9 +232,10 @@ public class SetVariableValueTests : DebuggerTestBase var pause_location = await EvaluateAndCheck( "window.setTimeout(function() { invoke_add(); }, 1);", "dotnet://debugger-test.dll/debugger-test.cs", 8+offset, 8, "IntAdd", - locals_fn: (locals) => + locals_fn: async (locals) => { CheckNumber(locals, variableName, originalValue); + await Task.CompletedTask; } ); var callFrameId = pause_location["callFrames"][0]["callFrameId"].Value(); @@ -228,9 +243,10 @@ public class SetVariableValueTests : DebuggerTestBase await SetVariableValueOnCallFrame( JObject.FromObject(new {callFrameId, variableName, newValue=JObject.FromObject(new {value=invalidValue}) }), false); await StepAndCheck(StepKind.Over, "dotnet://debugger-test.dll/debugger-test.cs", 9+offset, 8, "IntAdd", - locals_fn: (locals) => + locals_fn: async (locals) => { CheckNumber(locals, variableName, originalValue); + await Task.CompletedTask; } ); } @@ -243,9 +259,10 @@ public class SetVariableValueTests : DebuggerTestBase var pause_location = await EvaluateAndCheck( "window.setTimeout(function() { invoke_add(); }, 1);", "dotnet://debugger-test.dll/debugger-test.cs", 8+offset, 8, "IntAdd", - locals_fn: (locals) => + locals_fn: async (locals) => { CheckBool(locals, variableName, originalValue); + await Task.CompletedTask; } ); var callFrameId = pause_location["callFrames"][0]["callFrameId"].Value(); @@ -253,9 +270,10 @@ public class SetVariableValueTests : DebuggerTestBase await SetVariableValueOnCallFrame( JObject.FromObject(new {callFrameId, variableName, newValue=JObject.FromObject(new {value=newValue}) })); await StepAndCheck(StepKind.Over, "dotnet://debugger-test.dll/debugger-test.cs", 9+offset, 4, "IntAdd", - locals_fn: (locals) => + locals_fn: async (locals) => { CheckBool(locals, variableName, newValue); + await Task.CompletedTask; } ); } diff --git a/src/mono/wasm/debugger/DebuggerTestSuite/SteppingTests.cs b/src/mono/wasm/debugger/DebuggerTestSuite/SteppingTests.cs index bec62b77f97..4a54cac6e8c 100644 --- a/src/mono/wasm/debugger/DebuggerTestSuite/SteppingTests.cs +++ b/src/mono/wasm/debugger/DebuggerTestSuite/SteppingTests.cs @@ -50,36 +50,39 @@ public async Task InspectLocalsDuringStepping() await EvaluateAndCheck( "window.setTimeout(function() { invoke_add(); }, 1);", debugger_test_loc, 10, 8, "IntAdd", - locals_fn: (locals) => + locals_fn: async (locals) => { CheckNumber(locals, "a", 10); CheckNumber(locals, "b", 20); CheckNumber(locals, "c", 30); CheckNumber(locals, "d", 0); CheckNumber(locals, "e", 0); + await Task.CompletedTask; } ); await StepAndCheck(StepKind.Over, debugger_test_loc, 11, 8, "IntAdd", - locals_fn: (locals) => + locals_fn: async (locals) => { CheckNumber(locals, "a", 10); CheckNumber(locals, "b", 20); CheckNumber(locals, "c", 30); CheckNumber(locals, "d", 50); CheckNumber(locals, "e", 0); + await Task.CompletedTask; } ); //step and get locals await StepAndCheck(StepKind.Over, debugger_test_loc, 12, 8, "IntAdd", - locals_fn: (locals) => + locals_fn: async (locals) => { CheckNumber(locals, "a", 10); CheckNumber(locals, "b", 20); CheckNumber(locals, "c", 30); CheckNumber(locals, "d", 50); CheckNumber(locals, "e", 60); + await Task.CompletedTask; } ); } @@ -100,10 +103,11 @@ public async Task InspectLocalsInPreviousFramesDuringSteppingIn2(bool use_cfo) var pause_location = await EvaluateAndCheck( "window.setTimeout(function() { invoke_use_complex (); }, 1);", dep_cs_loc, 35, 8, "DoEvenMoreStuff", - locals_fn: (locals) => + locals_fn: async (locals) => { Assert.Single(locals); CheckObject(locals, "this", "Simple.Complex"); + await Task.CompletedTask; } ); @@ -165,13 +169,14 @@ public async Task InspectLocalsInPreviousFramesDuringSteppingIn(bool use_cfo) var wait_res = await EvaluateAndCheck( "window.setTimeout(function() { invoke_outer_method(); }, 1);", debugger_test_loc, 111, 12, "InnerMethod", - locals_fn: (locals) => + locals_fn: async (locals) => { Assert.Equal(4, locals.Count()); CheckNumber(locals, "i", 5); CheckNumber(locals, "j", 24); CheckString(locals, "foo_str", "foo"); CheckObject(locals, "this", "Math.NestedInMath"); + await Task.CompletedTask; } ); @@ -199,7 +204,7 @@ public async Task InspectLocalsInPreviousFramesDuringSteppingIn(bool use_cfo) // step back into OuterMethod await StepAndCheck(StepKind.Over, debugger_test_loc, 91, 8, "OuterMethod", times: 6, - locals_fn: (locals) => + locals_fn: async (locals) => { Assert.Equal(5, locals.Count()); @@ -208,6 +213,7 @@ public async Task InspectLocalsInPreviousFramesDuringSteppingIn(bool use_cfo) // FIXME: Failing test CheckNumber (locals, "new_i", 24); CheckNumber(locals, "k", 19); CheckObject(locals, "nim", "Math.NestedInMath"); + await Task.CompletedTask; } ); @@ -215,29 +221,31 @@ public async Task InspectLocalsInPreviousFramesDuringSteppingIn(bool use_cfo) // step into InnerMethod2 await StepAndCheck(StepKind.Into, "dotnet://debugger-test.dll/debugger-test.cs", 96, 4, "InnerMethod2", - locals_fn: (locals) => + locals_fn: async (locals) => { Assert.Equal(3, locals.Count()); CheckString(locals, "s", "test string"); //out var: CheckNumber (locals, "k", 0); CheckNumber(locals, "i", 24); + await Task.CompletedTask; } ); await StepAndCheck(StepKind.Over, "dotnet://debugger-test.dll/debugger-test.cs", 100, 4, "InnerMethod2", times: 4, - locals_fn: (locals) => + locals_fn: async (locals) => { Assert.Equal(3, locals.Count()); CheckString(locals, "s", "test string"); // FIXME: Failing test CheckNumber (locals, "k", 34); CheckNumber(locals, "i", 24); + await Task.CompletedTask; } ); await StepAndCheck(StepKind.Over, "dotnet://debugger-test.dll/debugger-test.cs", 92, 8, "OuterMethod", times: 1, - locals_fn: (locals) => + locals_fn: async (locals) => { Assert.Equal(5, locals.Count()); @@ -246,6 +254,7 @@ public async Task InspectLocalsInPreviousFramesDuringSteppingIn(bool use_cfo) CheckNumber(locals, "new_i", 22); CheckNumber(locals, "k", 34); CheckObject(locals, "nim", "Math.NestedInMath"); + await Task.CompletedTask; } ); } @@ -257,7 +266,7 @@ public async Task InspectLocalsDuringSteppingIn() await EvaluateAndCheck("window.setTimeout(function() { invoke_outer_method(); }, 1);", "dotnet://debugger-test.dll/debugger-test.cs", 86, 8, "OuterMethod", - locals_fn: (locals) => + locals_fn: async (locals) => { Assert.Equal(5, locals.Count()); @@ -266,11 +275,12 @@ public async Task InspectLocalsDuringSteppingIn() CheckNumber(locals, "k", 0); CheckNumber(locals, "new_i", 0); CheckString(locals, "text", null); + await Task.CompletedTask; } ); await StepAndCheck(StepKind.Over, "dotnet://debugger-test.dll/debugger-test.cs", 87, 8, "OuterMethod", - locals_fn: (locals) => + locals_fn: async (locals) => { Assert.Equal(5, locals.Count()); @@ -279,13 +289,14 @@ public async Task InspectLocalsDuringSteppingIn() CheckNumber(locals, "k", 0); CheckNumber(locals, "new_i", 0); CheckString(locals, "text", "Hello"); + await Task.CompletedTask; } ); // Step into InnerMethod await StepAndCheck(StepKind.Into, "dotnet://debugger-test.dll/debugger-test.cs", 105, 8, "InnerMethod"); await StepAndCheck(StepKind.Over, "dotnet://debugger-test.dll/debugger-test.cs", 110, 12, "InnerMethod", times: 5, - locals_fn: (locals) => + locals_fn: async (locals) => { Assert.Equal(4, locals.Count()); @@ -293,12 +304,13 @@ public async Task InspectLocalsDuringSteppingIn() CheckNumber(locals, "j", 15); CheckString(locals, "foo_str", "foo"); CheckObject(locals, "this", "Math.NestedInMath"); + await Task.CompletedTask; } ); // Step back to OuterMethod await StepAndCheck(StepKind.Over, "dotnet://debugger-test.dll/debugger-test.cs", 90, 8, "OuterMethod", times: 6, - locals_fn: (locals) => + locals_fn: async (locals) => { Assert.Equal(5, locals.Count()); @@ -307,6 +319,7 @@ public async Task InspectLocalsDuringSteppingIn() CheckNumber(locals, "k", 0); CheckNumber(locals, "new_i", 24); CheckString(locals, "text", "Hello"); + await Task.CompletedTask; } ); } @@ -326,13 +339,14 @@ public async Task InspectLocalsInAsyncMethods(bool use_cfo) var wait_res = await EvaluateAndCheck( "window.setTimeout(function() { invoke_async_method_with_await(); }, 1);", debugger_test_loc, 120, 12, "MoveNext", //FIXME: - locals_fn: (locals) => + locals_fn: async (locals) => { Assert.Equal(4, locals.Count()); CheckString(locals, "s", "string from js"); CheckNumber(locals, "i", 42); CheckString(locals, "local0", "value0"); CheckObject(locals, "this", "Math.NestedInMath"); + await Task.CompletedTask; } ); Console.WriteLine(wait_res); @@ -347,7 +361,7 @@ public async Task InspectLocalsInAsyncMethods(bool use_cfo) // TODO: previous frames have async machinery details, so no point checking that right now var pause_loc = await SendCommandAndCheck(null, "Debugger.resume", debugger_test_loc, 135, 12, /*FIXME: "AsyncMethodNoReturn"*/ "MoveNext", - locals_fn: (locals) => + locals_fn: async (locals) => { Assert.Equal(4, locals.Count()); CheckString(locals, "str", "AsyncMethodNoReturn's local"); @@ -356,6 +370,7 @@ public async Task InspectLocalsInAsyncMethods(bool use_cfo) CheckValueType(locals, "ss", "Math.SimpleStruct"); CheckArray(locals, "ss_arr", "Math.SimpleStruct[]", "Math.SimpleStruct[0]"); // TODO: struct fields + await Task.CompletedTask; } ); @@ -417,7 +432,7 @@ public async Task InspectValueTypeMethodArgsWhileStepping(bool use_cfo) } pause_location = await StepAndCheck(StepKind.Over, debugger_test_loc, 40, 8, "MethodWithStructArgs", times: 4, - locals_fn: (l) => { /* non-null to make sure that locals get fetched */ }); + locals_fn: async (l) => { /* non-null to make sure that locals get fetched */ await Task.CompletedTask; }); locals = await GetProperties(pause_location["callFrames"][0]["callFrameId"].Value()); { Assert.Equal(3, locals.Count()); @@ -469,7 +484,7 @@ public async Task InspectValueTypeMethodArgsWhileStepping(bool use_cfo) // ----------- Step back to the caller --------- pause_location = await StepAndCheck(StepKind.Over, debugger_test_loc, 30, 12, "TestStructsAsMethodArgs", - times: 1, locals_fn: (l) => { /* non-null to make sure that locals get fetched */ }); + times: 1, locals_fn: async (l) => { /* non-null to make sure that locals get fetched */ await Task.CompletedTask; }); locals = await GetProperties(pause_location["callFrames"][0]["callFrameId"].Value()); await CheckProps(locals, new { @@ -963,10 +978,10 @@ public async Task DebuggerAttributeIgnoreStepIntoDebuggerHidden() var step_into = await SendCommandAndCheck(null, $"Debugger.stepInto", null, -1, -1, null); Assert.Equal( - step_into["callFrames"][0]["location"]["lineNumber"].Value(), + step_into["callFrames"][0]["location"]["lineNumber"].Value(), pause_location.Value["locations"][0]["lineNumber"].Value() + 1 ); - + } [Fact] @@ -982,7 +997,7 @@ public async Task DebuggerAttributeIgnoreStepIntoDebuggerHiddenWithDebuggerBreak ); var step_into1 = await SendCommandAndCheck(null, $"Debugger.stepInto", null, -1, -1, null); - Assert.Equal( + Assert.Equal( pause_location.Value["locations"][0]["lineNumber"].Value(), step_into1["callFrames"][0]["location"]["lineNumber"].Value() ); @@ -993,7 +1008,7 @@ public async Task DebuggerAttributeIgnoreStepIntoDebuggerHiddenWithDebuggerBreak pause_location.Value["locations"][0]["lineNumber"].Value() + 1, step_into2["callFrames"][0]["location"]["lineNumber"].Value() ); - + } [Fact] diff --git a/src/mono/wasm/debugger/DebuggerTestSuite/TestHarnessProxy.cs b/src/mono/wasm/debugger/DebuggerTestSuite/TestHarnessProxy.cs index 7a5c30d9cc9..728cff78816 100644 --- a/src/mono/wasm/debugger/DebuggerTestSuite/TestHarnessProxy.cs +++ b/src/mono/wasm/debugger/DebuggerTestSuite/TestHarnessProxy.cs @@ -2,11 +2,9 @@ // The .NET Foundation licenses this file to you under the MIT license. using System; -using System.IO; using System.Threading; using System.Threading.Tasks; using Microsoft.AspNetCore; -using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; @@ -38,7 +36,11 @@ public static Task Start(string chromePath, string appPath, string pagePath) }) .ConfigureLogging(logging => { - logging.AddSimpleConsole(options => options.SingleLine = true) + logging.AddSimpleConsole(options => + { + options.SingleLine = true; + options.TimestampFormat = "[HH:mm:ss] "; + }) .AddFilter(null, LogLevel.Information); }) .ConfigureServices((ctx, services) => @@ -62,4 +64,4 @@ public static Task Start(string chromePath, string appPath, string pagePath) return hostTask; } } -} \ No newline at end of file +} diff --git a/src/mono/wasm/debugger/tests/ApplyUpdateReferencedAssembly/ApplyUpdateReferencedAssembly.csproj b/src/mono/wasm/debugger/tests/ApplyUpdateReferencedAssembly/ApplyUpdateReferencedAssembly.csproj index 66e7bd7f555..7ddd1b47740 100644 --- a/src/mono/wasm/debugger/tests/ApplyUpdateReferencedAssembly/ApplyUpdateReferencedAssembly.csproj +++ b/src/mono/wasm/debugger/tests/ApplyUpdateReferencedAssembly/ApplyUpdateReferencedAssembly.csproj @@ -12,6 +12,9 @@ false false false + + + true diff --git a/src/mono/wasm/debugger/tests/Directory.Build.props b/src/mono/wasm/debugger/tests/Directory.Build.props index ff8864839da..c1d2850617c 100644 --- a/src/mono/wasm/debugger/tests/Directory.Build.props +++ b/src/mono/wasm/debugger/tests/Directory.Build.props @@ -12,7 +12,7 @@ 219 false - $(ArtifactsBinDir)debugger-test\$(Configuration)\publish + $(ArtifactsBinDir)debugger-test\$(Configuration)\AppBundle $(ArtifactsBinDir)debugger-test\$(Configuration)\wasm $(ArtifactsBinDir)microsoft.netcore.app.runtime.browser-wasm\$(RuntimeConfiguration)\runtimes\browser-wasm\ diff --git a/src/mono/wasm/debugger/tests/debugger-test-with-source-link/debugger-test-with-source-link.csproj b/src/mono/wasm/debugger/tests/debugger-test-with-source-link/debugger-test-with-source-link.csproj index a2750bd53e1..879a6ee169e 100644 --- a/src/mono/wasm/debugger/tests/debugger-test-with-source-link/debugger-test-with-source-link.csproj +++ b/src/mono/wasm/debugger/tests/debugger-test-with-source-link/debugger-test-with-source-link.csproj @@ -1,22 +1,15 @@ - - LibraryTest - 1.0.0 - true - - - true - https://github.com/dotnet/runtime.git - git - true - true - embedded - true - false - - - source-link.json - $(MSBuildProjectDirectory)\ - $(AppOutputBase)=/fakepath/$(MSBuildProjectDirectory) - + + LibraryTest + 1.0.0 + true + https://github.com/dotnet/runtime.git + git + true + true + embedded + true + true + false + diff --git a/src/mono/wasm/debugger/tests/debugger-test-with-source-link/source-link.json b/src/mono/wasm/debugger/tests/debugger-test-with-source-link/source-link.json deleted file mode 100644 index b2c43725600..00000000000 --- a/src/mono/wasm/debugger/tests/debugger-test-with-source-link/source-link.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "documents": { - "/fakepath/*": "" - } -} \ No newline at end of file diff --git a/src/mono/wasm/debugger/tests/debugger-test/debugger-test.csproj b/src/mono/wasm/debugger/tests/debugger-test/debugger-test.csproj index a55b5a51365..d68825274d0 100644 --- a/src/mono/wasm/debugger/tests/debugger-test/debugger-test.csproj +++ b/src/mono/wasm/debugger/tests/debugger-test/debugger-test.csproj @@ -6,6 +6,7 @@ false PrepareForWasmBuildApp;$(WasmBuildAppDependsOn) true + library @@ -24,7 +25,10 @@ - + + + false $(AppDir) diff --git a/src/tasks/WasmAppBuilder/WasmAppBuilder.cs b/src/tasks/WasmAppBuilder/WasmAppBuilder.cs index 47e56293a52..e90f74a4010 100644 --- a/src/tasks/WasmAppBuilder/WasmAppBuilder.cs +++ b/src/tasks/WasmAppBuilder/WasmAppBuilder.cs @@ -373,9 +373,9 @@ private bool FileCopyChecked(string src, string dst, string label) return true; } - catch (IOException ioex) + catch (Exception ex) when (ex is IOException or UnauthorizedAccessException) { - throw new LogAsErrorException($"{label} Failed to copy {src} to {dst} because {ioex.Message}"); + throw new LogAsErrorException($"{label} Failed to copy {src} to {dst} because {ex.Message}"); } } } diff --git a/src/tests/BuildWasmApps/Directory.Build.props b/src/tests/BuildWasmApps/Directory.Build.props index 68eaef41905..a7a271abad0 100644 --- a/src/tests/BuildWasmApps/Directory.Build.props +++ b/src/tests/BuildWasmApps/Directory.Build.props @@ -1,6 +1,3 @@ - - BuildWasmApps - diff --git a/src/tests/BuildWasmApps/Wasm.Build.Tests/Directory.Build.props b/src/tests/BuildWasmApps/Wasm.Build.Tests/Directory.Build.props new file mode 100644 index 00000000000..a48db59c3af --- /dev/null +++ b/src/tests/BuildWasmApps/Wasm.Build.Tests/Directory.Build.props @@ -0,0 +1,8 @@ + + + + BuildWasmApps + + + + diff --git a/src/tests/BuildWasmApps/Wasm.Debugger.Tests/Wasm.Debugger.Tests.csproj b/src/tests/BuildWasmApps/Wasm.Debugger.Tests/Wasm.Debugger.Tests.csproj new file mode 100644 index 00000000000..b6233edfea2 --- /dev/null +++ b/src/tests/BuildWasmApps/Wasm.Debugger.Tests/Wasm.Debugger.Tests.csproj @@ -0,0 +1,65 @@ + + + + + $(NetCoreAppToolCurrent) + false + false + false + false + true + true + xunit + + + BundleDebuggerTestsForHelix + + + + RunScriptTemplate.sh + RunScriptTemplate.cmd + + $(MSBuildThisFileDirectory)data\$(RunScriptInputName) + + + + + + + + + + + + + + + + + + + <_DotnetCommand Condition="'$(OS)' != 'Windows_NT'">dotnet + <_DotnetCommand Condition="'$(OS)' == 'Windows_NT'">dotnet.exe + + $(_DotnetCommand) test DebuggerTestSuite/DebuggerTestSuite.dll + $(RunScriptCommand) "-l:trx%3BLogFileName=testResults.trx" + + $(RunScriptCommand) --results-directory "$TEST_LOG_PATH" + $(RunScriptCommand) --results-directory "%TEST_LOG_PATH%" + + $(RunScriptCommand) %24TEST_ARGS + $(RunScriptCommand) %TEST_ARGS% + + + $(RunScriptCommand) -v diag + + + + + diff --git a/src/tests/BuildWasmApps/Wasm.Debugger.Tests/data/RunScriptTemplate.cmd b/src/tests/BuildWasmApps/Wasm.Debugger.Tests/data/RunScriptTemplate.cmd new file mode 100644 index 00000000000..a8e21478831 --- /dev/null +++ b/src/tests/BuildWasmApps/Wasm.Debugger.Tests/data/RunScriptTemplate.cmd @@ -0,0 +1,32 @@ +@echo off +setlocal enabledelayedexpansion + +set EXECUTION_DIR=%~dp0 + +cd %EXECUTION_DIR% + +if [%HELIX_WORKITEM_UPLOAD_ROOT%] == [] ( + set XHARNESS_OUT=%EXECUTION_DIR%xharness-output +) else ( + set XHARNESS_OUT=%HELIX_WORKITEM_UPLOAD_ROOT%\xharness-output +) + +set TEST_LOG_PATH=%XHARNESS_OUT%\logs + +:: ========================= BEGIN Test Execution ============================= +echo ----- start %DATE% %TIME% =============== To repro directly: ===================================================== +echo pushd %EXECUTION_DIR% +[[RunCommandsEcho]] +echo popd +echo =========================================================================================================== +pushd %EXECUTION_DIR% +@echo on +[[RunCommands]] +set EXIT_CODE=%ERRORLEVEL% +@echo off +popd +echo ----- end %DATE% %TIME% ----- exit code %EXIT_CODE% ---------------------------------------------------------- + +echo artifacts: %XHARNESS_OUT% + +exit /b %EXIT_CODE% diff --git a/src/tests/BuildWasmApps/Wasm.Debugger.Tests/data/RunScriptTemplate.sh b/src/tests/BuildWasmApps/Wasm.Debugger.Tests/data/RunScriptTemplate.sh new file mode 100644 index 00000000000..2e131fe110f --- /dev/null +++ b/src/tests/BuildWasmApps/Wasm.Debugger.Tests/data/RunScriptTemplate.sh @@ -0,0 +1,21 @@ +#!/usr/bin/env bash + +EXECUTION_DIR=$(dirname $0) + +cd $EXECUTION_DIR + +if [[ -z "$HELIX_WORKITEM_UPLOAD_ROOT" ]]; then + XHARNESS_OUT="$EXECUTION_DIR/xharness-output" +else + XHARNESS_OUT="$HELIX_WORKITEM_UPLOAD_ROOT/xharness-output" +fi + +export TEST_LOG_PATH=${XHARNESS_OUT}/logs + +[[RunCommands]] + +_exitCode=$? + +echo "artifacts: $XHARNESS_OUT" + +exit $_exitCode -- GitLab