未验证 提交 ad3f1c13 编写于 作者: A Ankit Jain 提交者: GitHub

[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<JToken>` parameter. Many tests
pass an async lambda to this, expecting it to get awaited upon.

```csharp
    EvaluateAndCheck (Action<T> 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 81517407.
上级 e7de86fa
......@@ -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 }}
......@@ -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
#
......
......@@ -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
#
......
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
......@@ -36,10 +36,17 @@
<MakeDir Directories="$(SdkWithNoWorkloadForTestingPath)" />
<PropertyGroup>
<_DotNetInstallScriptPath Condition="!$([MSBuild]::IsOSPlatform('windows'))">$(DOTNET_INSTALL_DIR)/dotnet-install.sh</_DotNetInstallScriptPath>
<_DotNetInstallScriptPath Condition=" $([MSBuild]::IsOSPlatform('windows'))">$(RepoRoot).dotnet\dotnet-install.ps1</_DotNetInstallScriptPath>
<_DotNetInstallScriptName Condition="!$([MSBuild]::IsOSPlatform('windows'))">dotnet-install.sh</_DotNetInstallScriptName>
<_DotNetInstallScriptName Condition=" $([MSBuild]::IsOSPlatform('windows'))">dotnet-install.ps1</_DotNetInstallScriptName>
<_DotNetInstallScriptPath>$(ArtifactsObjDir)$(_DotNetInstallScriptName)</_DotNetInstallScriptPath>
</PropertyGroup>
<DownloadFile SourceUrl="https://dot.net/v1/$(_DotNetInstallScriptName)"
DestinationFolder="$(ArtifactsObjDir)"
Retries="3"
Condition="!Exists($(_DotNetInstallScriptPath))"/>
<Exec Condition="!$([MSBuild]::IsOSPlatform('windows'))"
Command="chmod +x $(_DotNetInstallScriptPath); $(_DotNetInstallScriptPath) -i $(SdkWithNoWorkloadForTestingPath) -v $(SdkVersionForWorkloadTesting)" />
......
......@@ -32,6 +32,7 @@
<_workItemTimeout Condition="'$(Scenario)' != '' and '$(_workItemTimeout)' == '' and ('$(TargetArchitecture)' == 'arm64' or '$(TargetArchitecture)' == 'arm')">01:00:00</_workItemTimeout>
<_workItemTimeout Condition="'$(Scenario)' == 'BuildWasmApps' and '$(_workItemTimeout)' == ''">01:30:00</_workItemTimeout>
<_workItemTimeout Condition="'$(TargetOS)' == 'Browser' and '$(NeedsToBuildWasmAppsOnHelix)' == 'true'">01:00:00</_workItemTimeout>
<_workItemTimeout Condition="'$(TargetOS)' == 'Browser' and '$(Scenario)' == 'WasmDebuggerTests'">00:10:00</_workItemTimeout>
<_workItemTimeout Condition="'$(Scenario)' == '' and '$(_workItemTimeout)' == '' and '$(Outerloop)' == 'true'">00:20:00</_workItemTimeout>
<_workItemTimeout Condition="'$(Scenario)' == '' and '$(_workItemTimeout)' == ''">00:15:00</_workItemTimeout>
<_workItemTimeout Condition="'$(Scenario)' != '' and '$(_workItemTimeout)' == ''">00:30:00</_workItemTimeout>
......@@ -40,6 +41,7 @@
<!-- The Helix runtime payload and the tests to run -->
<!-- TestArchiveRuntimeFile will be passed as a property by the calling project -->
<HelixCorrelationPayload Condition="'$(HelixCorrelationPayload)' == ''">$(TestArchiveRuntimeFile)</HelixCorrelationPayload>
<WorkItemArchiveWildCard Condition="'$(Scenario)' == 'WasmDebuggerTests'">$(TestArchiveTestsRoot)**/Wasm.Debugger.Tests.zip</WorkItemArchiveWildCard>
<WorkItemArchiveWildCard Condition="'$(WorkItemArchiveWildCard)' == ''">$(TestArchiveTestsRoot)**/*.zip</WorkItemArchiveWildCard>
<HelixConfiguration>$(Configuration)</HelixConfiguration>
......@@ -54,11 +56,14 @@
<TestRunNamePrefix Condition="'$(TestRunNamePrefixSuffix)' != ''">$(TestRunNamePrefix)$(TestRunNamePrefixSuffix)-</TestRunNamePrefix>
<TestRunNamePrefix Condition="'$(Scenario)' != ''">$(TestRunNamePrefix)$(Scenario)-</TestRunNamePrefix>
<IsWasmDebuggerTests Condition="'$(Scenario)' == 'WasmDebuggerTests'">true</IsWasmDebuggerTests>
<BuildWasmAppsJobsList>$(RepositoryEngineeringDir)\testing\scenarios\BuildWasmAppsJobsList.txt</BuildWasmAppsJobsList>
<WasmDebuggerTestsJobsList>$(RepositoryEngineeringDir)\testing\scenarios\WasmDebuggerTestsJobsList.txt</WasmDebuggerTestsJobsList>
<DefaultHelixWorkItems Condition="'$(Scenario)' != 'BuildWasmApps' and '$(IsWasmDebuggerTests)' != 'true'">true</DefaultHelixWorkItems>
<FailOnTestFailure Condition="'$(WaitForWorkItemCompletion)' != ''">$(WaitForWorkItemCompletion)</FailOnTestFailure>
<NeedsToBuildAppsOnHelix Condition="('$(TargetOS)' == 'iOS' or '$(TargetOS)' == 'iOSSimulator' or '$(TargetOS)' == 'tvOS' or '$(TargetOS)' == 'tvOSSimulator') and '$(NeedsToBuildAppsOnHelix)' == '' and '$(Scenario)' == 'BuildiOSApps'">true</NeedsToBuildAppsOnHelix>
<NeedsiOSSDK Condition="'$(NeedsToBuildAppsOnHelix)' == 'true' and '$(NeedsWorkload)' != 'true'">true</NeedsiOSSDK>
<EMSDK_PATH Condition="$([MSBuild]::IsOSPlatform('WINDOWS')) and '$(EMSDK_PATH)' == ''">$(RepoRoot)src\mono\wasm\emsdk\</EMSDK_PATH>
......@@ -66,6 +71,7 @@
<NeedsWorkload Condition="'$(Scenario)' == 'BuildWasmApps'">true</NeedsWorkload>
<NeedsEMSDK Condition="'$(NeedsToBuildWasmAppsOnHelix)' == 'true' or ('$(Scenario)' == 'BuildWasmApps' and '$(TestUsingWorkloads)' != 'true')">true</NeedsEMSDK>
<NeedsToRunOnBrowser Condition="'$(TargetOS)' == 'Browser' and ('$(Scenario)' == 'WasmTestOnBrowser' or '$(Scenario)' == 'BuildWasmApps')">true</NeedsToRunOnBrowser>
<NeedsToRunOnBrowser Condition="'$(NeedsToRunOnBrowser)' == '' and '$(IsWasmDebuggerTests)' == 'true'">true</NeedsToRunOnBrowser>
<SdkForWorkloadTestingDirName Condition="'$(NeedsWorkload)' == 'true' and '$(TestUsingWorkloads)' == 'true'">dotnet-workload</SdkForWorkloadTestingDirName>
<SdkForWorkloadTestingDirName Condition="'$(NeedsWorkload)' == 'true' and '$(TestUsingWorkloads)' != 'true'">sdk-no-workload</SdkForWorkloadTestingDirName>
......@@ -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.
-->
<InstallDevCerts Condition="'$(Scenario)' != 'BuildWasmApps'">true</InstallDevCerts>
<InstallDevCerts Condition="'$(Scenario)' != 'BuildWasmApps' and '$(Scenario)' != 'WasmDebuggerTests'">true</InstallDevCerts>
<!-- Install SDK so that, we could use `dotnet dev-certs https` -->
<NeedsDotNetSdk Condition="'$(NeedsWorkload)' != 'true'">true</NeedsDotNetSdk>
......@@ -448,6 +454,10 @@
<Output TaskParameter="Lines" ItemName="BuildWasmApps_PerJobList" />
</ReadLinesFromFile>
<ReadLinesFromFile File="$(WasmDebuggerTestsJobsList)" Condition="Exists($(WasmDebuggerTestsJobsList)) and '$(Scenario)' == 'WasmDebuggerTests'">
<Output TaskParameter="Lines" ItemName="WasmDebuggerTests_PerJobList" />
</ReadLinesFromFile>
<ItemGroup Condition="'$(TargetOS)' != 'Android' and '$(TargetOS)' != 'iOS' and '$(TargetOS)' != 'iOSSimulator' and '$(TargetOS)' != 'tvOS' and '$(TargetOS)' != 'tvOSSimulator' and '$(TargetOS)' != 'MacCatalyst'">
<HelixCorrelationPayload Include="$(HelixCorrelationPayload)"
Condition="'$(IncludeHelixCorrelationPayload)' == 'true' and '$(TargetOS)' != 'Browser' and '$(Scenario)' != 'BuildiOSApps'"
......@@ -460,15 +470,19 @@
<_WorkItem Include="$(TestArchiveRoot)runonly/**/WebAssembly.Browser.*.Test.zip" Condition="'$(TargetOS)' == 'Browser' and '$(Scenario)' == 'WasmTestOnBrowser'" />
<_WorkItem Include="$(TestArchiveRoot)browseronly/**/*.zip" Condition="'$(TargetOS)' == 'Browser' and '$(Scenario)' == 'WasmTestOnBrowser'" />
<HelixWorkItem Include="@(_WorkItem -> '$(WorkItemPrefix)%(FileName)')" Condition="'$(Scenario)' != 'BuildWasmApps'">
<HelixWorkItem Include="@(_WorkItem -> '$(WorkItemPrefix)%(FileName)')" Condition="'$(DefaultHelixWorkItems)' == 'true'">
<PayloadArchive>%(Identity)</PayloadArchive>
<Command>$(HelixCommand)</Command>
<Timeout>$(_workItemTimeout)</Timeout>
</HelixWorkItem>
</ItemGroup>
<Error Condition="('$(Scenario)' == 'WasmDebuggerTests' or '$(Scenario)' == 'BuildWasmApps') and @(_WorkItem->Count()) != 1"
Text="Found more than one workitem for Scenario=$(Scenario): @(_WorkItem)" />
<PropertyGroup>
<_BuildWasmAppsPayloadArchive>@(_WorkItem)</_BuildWasmAppsPayloadArchive>
<_WasmDebuggerTestsPayloadArchive>@(_WorkItem)</_WasmDebuggerTestsPayloadArchive>
</PropertyGroup>
<ItemGroup Condition="'$(Scenario)' == 'BuildWasmApps'">
......@@ -481,6 +495,19 @@
</HelixWorkItem>
</ItemGroup>
<ItemGroup Condition="'$(Scenario)' == 'WasmDebuggerTests'">
<HelixWorkItem Include="@(WasmDebuggerTests_PerJobList)">
<PayloadArchive>$(_WasmDebuggerTestsPayloadArchive)</PayloadArchive>
<!-- FIXME: workaround for https://github.com/dotnet/runtime/issues/62660 -->
<PreCommands Condition="'$(OS)' == 'Windows_NT'">set TEST_ARGS=--filter &quot;FullyQualifiedName~%(Identity)^&amp;Category!=windows-failing&quot;</PreCommands>
<PreCommands Condition="'$(OS)' != 'Windows_NT'">export TEST_ARGS=&quot;--filter FullyQualifiedName~%(Identity)&amp;Category!=linux-failing&quot;</PreCommands>
<Command>$(HelixCommand)</Command>
<Timeout>$(_workItemTimeout)</Timeout>
</HelixWorkItem>
</ItemGroup>
<PropertyGroup Condition="'$(TargetOS)' == 'Browser' and '$(BrowserHost)' != 'windows'">
<ExecXHarnessCmd>dotnet exec $XHARNESS_CLI_PATH</ExecXHarnessCmd>
<XHarnessOutput>$HELIX_WORKITEM_UPLOAD_ROOT/xharness-output</XHarnessOutput>
......@@ -493,7 +520,7 @@
<XHarnessBrowserPathArg>--browser-path=%HELIX_CORRELATION_PAYLOAD%\chrome-win\chrome.exe</XHarnessBrowserPathArg>
</PropertyGroup>
<ItemGroup Condition="'$(TargetOS)' == 'Browser' and '$(Scenario)' != 'WasmTestOnBrowser' and '$(Scenario)' != 'BuildWasmApps'">
<ItemGroup Condition="'$(TargetOS)' == 'Browser' and '$(Scenario)' != 'WasmTestOnBrowser' and '$(Scenario)' != 'BuildWasmApps' and '$(Scenario)' != 'WasmDebuggerTests'">
<!-- Create a work item for run-only WASM console app -->
<_RunOnlyWorkItem Include="$(TestArchiveRoot)runonly/**/*.Console.Sample.zip" />
<HelixWorkItem Include="@(_RunOnlyWorkItem -> '%(FileName)')" >
......@@ -526,6 +553,10 @@
ContinueOnError="true"
IgnoreExitCode="true"
IgnoreStandardErrorWarningFormat="true" />
<Message Text="HelixCorrelationPayload: %(HelixCorrelationPayload.Identity)" Condition="'$(HelixDryRun)' == 'true'" Importance="High" />
<Message Text="HelixWorkItem: %(HelixWorkItem.Identity), Command: %(HelixWorkItem.Command), PreCommands: %(HelixWorkItem.PreCommands) with PayloadArchive: %(HelixWorkItem.PayloadArchive)" Condition="'$(HelixDryRun)' == 'true'" Importance="High" />
<Error Text="Stopping the build for dry run" Condition="'$(HelixDryRun)' == 'true'" />
</Target>
<!-- CI has emscripten provisioned in $(EMSDK_PATH) as `/usr/local/emscripten`. Because helix tasks will
......
......@@ -373,12 +373,19 @@
<ProjectReference Include="@(TrimmingTestProjects)" />
<!-- wasm.build.tests are run on _WasmBuildTests job on CI, and with library tests locally. -->
<ProjectReference Include="$(RepoRoot)\src\tests\BuildWasmApps\**\*.Tests.csproj"
<ProjectReference Include="$(RepoRoot)\src\tests\BuildWasmApps\Wasm.Build.Tests\*.Tests.csproj"
Exclude="@(ProjectExclusions)"
Condition="'$(TargetOS)' == 'Browser' and
(('$(ContinuousIntegrationBuild)' == 'true' and '$(TestWasmBuildTests)' == 'true') or
('$(ContinuousIntegrationBuild)' != 'true' and '$(TestAssemblies)' == 'true'))"
BuildInParallel="false" />
<ProjectReference Include="$(RepoRoot)\src\tests\BuildWasmApps\Wasm.Debugger.Tests\*.Tests.csproj"
Exclude="@(ProjectExclusions)"
Condition="'$(TargetOS)' == 'Browser' and
(('$(ContinuousIntegrationBuild)' == 'true' and '$(TestWasmDebuggerTests)' == 'true') or
('$(ContinuousIntegrationBuild)' != 'true' and '$(TestAssemblies)' == 'true'))"
BuildInParallel="false" />
</ItemGroup>
<ItemGroup Condition="'$(ArchiveTests)' == 'true' and '$(TargetOS)' == 'iOS'">
......
......@@ -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); \
......
......@@ -207,9 +207,13 @@
<_ParsedRuntimeConfigFilePath Condition="'$(_WasmRuntimeConfigFilePath)' != ''">$([System.IO.Path]::GetDirectoryName($(_WasmRuntimeConfigFilePath)))\runtimeconfig.bin</_ParsedRuntimeConfigFilePath>
</PropertyGroup>
<Warning Condition="'$(WasmGenerateAppBundle)' == 'true' and $(_MainAssemblyPath) == ''" Text="Could not find %24(AssemblyName)=$(AssemblyName).dll in the assemblies to be bundled." />
<Warning Condition="'$(WasmGenerateAppBundle)' == 'true' and $(_WasmRuntimeConfigFilePath) != '' and !Exists($(_WasmRuntimeConfigFilePath))"
Text="Could not find $(_WasmRuntimeConfigFilePath) for $(_MainAssemblyPath)." />
<Message Condition="'$(WasmGenerateAppBundle)' == 'true' and $(_MainAssemblyPath) == ''"
Text="Could not find %24(AssemblyName)=$(AssemblyName).dll in the assemblies to be bundled."
Importance="Low" />
<Message Condition="'$(WasmGenerateAppBundle)' == 'true' and $(_WasmRuntimeConfigFilePath) != '' and !Exists($(_WasmRuntimeConfigFilePath))"
Text="Could not find $(_WasmRuntimeConfigFilePath) for $(_MainAssemblyPath)."
Importance="Low" />
<ItemGroup>
<_WasmAssembliesInternal Remove="@(_WasmAssembliesInternal)" />
......
......@@ -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)
);
......
......@@ -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<MemoryStream> GetDataAsync(Uri uri, CancellationToken token)
private async Task<MemoryStream> 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;
......
......@@ -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
{
......
......@@ -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;
}
);
}
......
......@@ -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<string>());
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<int>(),
bp_conditional.Value["locations"][0]["columnNumber"].Value<int>(),
"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<int>(),
bp_conditional.Value["locations"][0]["columnNumber"].Value<int>(),
"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<int>(),
bp_conditional.Value["locations"][0]["columnNumber"].Value<int>(),
"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<int>(),
bp_conditional.Value["locations"][0]["columnNumber"].Value<int>(),
"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<int>(),
bp_conditional.Value["locations"][0]["columnNumber"].Value<int>(),
"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<int>(),
bp_conditional.Value["locations"][0]["columnNumber"].Value<int>(),
"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<int>(),
bp_conditional.Value["locations"][0]["columnNumber"].Value<int>(),
"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<int>(),
bp_conditional.Value["locations"][0]["columnNumber"].Value<int>(),
"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()
......
......@@ -8,7 +8,7 @@
namespace DebuggerTests
{
public class DateTimeList : DebuggerTestBase
public class DateTimeTests : DebuggerTestBase
{
[Theory]
......
......@@ -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<JToken> test_fn = null, Func<JObject, Task> wait_for_event_fn = null, bool use_cfo = false)
Func<JToken, Task> test_fn = null, Func<JObject, Task> 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<Result> SetValueOnObject(JToken obj, string property, string
}
internal async Task<JObject> StepAndCheck(StepKind kind, string script_loc, int line, int column, string function_name,
Func<JObject, Task> wait_for_event_fn = null, Action<JToken> locals_fn = null, int times = 1)
Func<JObject, Task> wait_for_event_fn = null, Func<JToken, Task> 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<Result> SetValueOnObject(JToken obj, string property, string
locals_fn: locals_fn);
}
internal async Task<JObject> EvaluateAndCheck(string expression, string script_loc, int line, int column, string function_name,
Func<JObject, Task> wait_for_event_fn = null, Action<JToken> 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<JObject> EvaluateAndCheck(
string expression, string script_loc, int line, int column, string function_name,
Func<JObject, Task> wait_for_event_fn = null, Func<JToken, Task> 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<JObject> SendCommandAndCheck(JObject args, string method, string script_loc, int line, int column, string function_name,
Func<JObject, Task> wait_for_event_fn = null, Action<JToken> locals_fn = null, string waitForEvent = Inspector.PAUSE)
Func<JObject, Task> wait_for_event_fn = null, Func<JToken, Task> 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<Result> SetValueOnObject(JToken obj, string property, string
var locals = await GetProperties(wait_res["callFrames"][0]["callFrameId"].Value<string>());
try
{
locals_fn(locals);
await locals_fn(locals);
}
catch (System.AggregateException ex)
{
......
......@@ -16,7 +16,18 @@
<ItemGroup>
<ProjectReference Include="..\BrowserDebugHost\BrowserDebugHost.csproj" />
<ProjectReference Include="..\BrowserDebugProxy\BrowserDebugProxy.csproj" />
<ProjectReference Include="..\tests\debugger-test\debugger-test.csproj" ReferenceOutputAssembly="false" />
<ProjectReference Include="..\tests\debugger-test\debugger-test.csproj" ReferenceOutputAssembly="false" Private="false" />
</ItemGroup>
<Target Name="CopyTestZipForHelix"
Condition="'$(ArchiveDirForHelix)' != ''"
AfterTargets="Build">
<ItemGroup>
<_FilesToCopy Include="$(OutputPath)\**\*" TargetPath="DebuggerTestSuite" />
<_FilesToCopy Include="$(ArtifactsBinDir)debugger-test\Debug\**\*" TargetPath="debugger-test" />
</ItemGroup>
<Copy SourceFiles="@(_FilesToCopy)" DestinationFiles="$(ArchiveDirForHelix)\%(TargetPath)\%(RecursiveDir)%(FileName)%(Extension)" />
</Target>
</Project>
......@@ -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";
......
......@@ -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<WebSocketException>(async () =>
await SendCommandAndCheck(null, "Browser.close", null, -1, -1, null));
public async Task BrowserClose()
{
ArgumentException ae = await Assert.ThrowsAsync<ArgumentException>(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()
......
......@@ -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<InspectorClient>());
......@@ -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<InspectorClient, CancellationToken, List
break;
case RunLoopStopReason.Cancelled when Token.IsCancellationRequested:
FailAllWaiters(new TaskCanceledException($"Test timed out (elapsed time: {(DateTime.Now - start).TotalSeconds}"));
FailAllWaiters(new TaskCanceledException($"Test timed out (elapsed time: {(DateTime.Now - start).TotalSeconds})"));
break;
default:
......
......@@ -5,7 +5,6 @@
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.WebAssembly.Diagnostics;
using Newtonsoft.Json.Linq;
using Xunit;
......@@ -14,7 +13,7 @@
namespace DebuggerTests
{
public class SourceList : DebuggerTestBase
public class MiscTests : DebuggerTestBase
{
[Fact]
......@@ -66,13 +65,14 @@ public async Task ExceptionThrownInJSOutOfBand()
"dotnet://debugger-test.dll/debugger-test.cs", 10, 8, "IntAdd",
"window.setTimeout(function() { invoke_add(); }, 1);",
use_cfo: use_cfo,
test_fn: (locals) =>
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<Math[], Math.IsMathNull>", description: "Count = 0");
CheckObject(locals, "list_null", "System.Collections.Generic.Dictionary<Math[], Math.IsMathNull>", is_null: true);
......@@ -213,6 +215,7 @@ public async Task ExceptionThrownInJSOutOfBand()
CheckArray(locals, "list_arr_unused", "System.Collections.Generic.Dictionary<Math[], Math.IsMathNull>[]", "System.Collections.Generic.Dictionary<Math[], Math.IsMathNull>[1]");
CheckObject(locals, "list_arr_null_unused", "System.Collections.Generic.Dictionary<Math[], Math.IsMathNull>[]", 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<JArray>()?.Count);
var loc = bp1_res.Value["locations"]?.Value<JArray>()[0];
var sourceToGet = JObject.FromObject(new
{
scriptId = loc["scriptId"]?.Value<string>()
});
Assert.Equal("dotnet://debugger-test.dll/debugger-test.cs", scripts[loc["scriptId"]?.Value<string>()]);
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;
}
);
}
......
......@@ -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<string>();
......@@ -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<string>();
......@@ -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<string>();
......@@ -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<string>();
......@@ -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<string>();
......@@ -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<string>();
......@@ -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<string>();
......@@ -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;
}
);
}
......
......@@ -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<string>());
{
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<string>());
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<int>(),
step_into["callFrames"][0]["location"]["lineNumber"].Value<int>(),
pause_location.Value["locations"][0]["lineNumber"].Value<int>() + 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<int>(),
step_into1["callFrames"][0]["location"]["lineNumber"].Value<int>()
);
......@@ -993,7 +1008,7 @@ public async Task DebuggerAttributeIgnoreStepIntoDebuggerHiddenWithDebuggerBreak
pause_location.Value["locations"][0]["lineNumber"].Value<int>() + 1,
step_into2["callFrames"][0]["location"]["lineNumber"].Value<int>()
);
}
[Fact]
......
......@@ -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
}
......@@ -12,6 +12,9 @@
<EnableAggressiveTrimming>false</EnableAggressiveTrimming>
<PublishTrimmed>false</PublishTrimmed>
<EnableDefaultCompileItems>false</EnableDefaultCompileItems>
<!-- FIXME: issue -->
<DisableSourceLink>true</DisableSourceLink>
</PropertyGroup>
<ItemGroup>
......
......@@ -12,7 +12,7 @@
<NoWarn>219</NoWarn>
<RunAnalyzers>false</RunAnalyzers>
<AppDir>$(ArtifactsBinDir)debugger-test\$(Configuration)\publish</AppDir>
<AppDir>$(ArtifactsBinDir)debugger-test\$(Configuration)\AppBundle</AppDir>
<OutDir>$(ArtifactsBinDir)debugger-test\$(Configuration)\wasm</OutDir>
<MicrosoftNetCoreAppRuntimePackRidDir>$(ArtifactsBinDir)microsoft.netcore.app.runtime.browser-wasm\$(RuntimeConfiguration)\runtimes\browser-wasm\</MicrosoftNetCoreAppRuntimePackRidDir>
......
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<PackageId>LibraryTest</PackageId>
<Version>1.0.0</Version>
<DeterministicSourcePaths>true</DeterministicSourcePaths>
</PropertyGroup>
<PropertyGroup Condition="'$(ContinuousIntegrationBuild)' != 'true'">
<PublishRepositoryUrl>true</PublishRepositoryUrl>
<RepositoryUrl>https://github.com/dotnet/runtime.git</RepositoryUrl>
<RepositoryType>git</RepositoryType>
<EnableSourceLink>true</EnableSourceLink>
<IncludeSymbols>true</IncludeSymbols>
<DebugType>embedded</DebugType>
<IncludeSymbols>true</IncludeSymbols>
<DisableSourceLink>false</DisableSourceLink>
</PropertyGroup>
<PropertyGroup Condition="'$(ContinuousIntegrationBuild)' == 'true'">
<SourceLink>source-link.json</SourceLink>
<AppOutputBase>$(MSBuildProjectDirectory)\</AppOutputBase>
<PathMap>$(AppOutputBase)=/fakepath/$(MSBuildProjectDirectory)</PathMap>
</PropertyGroup>
<PropertyGroup>
<PackageId>LibraryTest</PackageId>
<Version>1.0.0</Version>
<PublishRepositoryUrl>true</PublishRepositoryUrl>
<RepositoryUrl>https://github.com/dotnet/runtime.git</RepositoryUrl>
<RepositoryType>git</RepositoryType>
<EnableSourceLink>true</EnableSourceLink>
<IncludeSymbols>true</IncludeSymbols>
<DebugType>embedded</DebugType>
<IncludeSymbols>true</IncludeSymbols>
<DeterministicSourcePaths>true</DeterministicSourcePaths>
<DisableSourceLink>false</DisableSourceLink>
</PropertyGroup>
</Project>
{
"documents": {
"/fakepath/*": ""
}
}
\ No newline at end of file
......@@ -6,6 +6,7 @@
<RunAnalyzers>false</RunAnalyzers>
<WasmBuildAppDependsOn>PrepareForWasmBuildApp;$(WasmBuildAppDependsOn)</WasmBuildAppDependsOn>
<WasmGenerateAppBundle>true</WasmGenerateAppBundle>
<OutputType>library</OutputType>
</PropertyGroup>
<ItemGroup>
......@@ -24,7 +25,10 @@
<ProjectReference Include="..\debugger-test-with-full-debug-type\debugger-test-with-full-debug-type.csproj" Private="true"/>
</ItemGroup>
<Target Name="PrepareForWasmBuildApp" DependsOnTargets="RebuildWasmAppBuilder;Build">
<Target Name="PrepareForWasmBuildApp" DependsOnTargets="Build">
<Error Condition="!Exists('$(MicrosoftNetCoreAppRuntimePackRidDir)native')"
Text="Cannot find %24(MicrosoftNetCoreAppRuntimePackRidDir)=$(MicrosoftNetCoreAppRuntimePackRidDir)native. Make sure to set the runtime configuration with %24(RuntimeConfiguration). Current value: $(RuntimeConfiguration)" />
<PropertyGroup>
<EnableDefaultWasmAssembliesToBundle>false</EnableDefaultWasmAssembliesToBundle>
<WasmAppDir>$(AppDir)</WasmAppDir>
......
......@@ -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}");
}
}
}
<Project>
<PropertyGroup>
<Scenario>BuildWasmApps</Scenario>
</PropertyGroup>
<Import Project="..\..\libraries\Directory.Build.props" />
</Project>
<Project>
<PropertyGroup>
<!-- needs to be set early -->
<Scenario>BuildWasmApps</Scenario>
</PropertyGroup>
<Import Project="..\Directory.Build.props" />
</Project>
<Project Sdk="Microsoft.Build.NoTargets">
<!-- This is a wrapper project for wasm debugger tests, to enable use of the library test infrastructure -->
<PropertyGroup>
<TargetFrameworks>$(NetCoreAppToolCurrent)</TargetFrameworks>
<IsPublishable>false</IsPublishable>
<EnableCoverageSupport>false</EnableCoverageSupport>
<EnableRunSettingsSupport>false</EnableRunSettingsSupport>
<IsWasmProject>false</IsWasmProject>
<SkipTestUtilitiesReference>true</SkipTestUtilitiesReference>
<BundleXunitRunner>true</BundleXunitRunner>
<TestFramework>xunit</TestFramework>
<CoreBuildDependsOn />
<BundleTestWasmAppDependsOn>BundleDebuggerTestsForHelix</BundleTestWasmAppDependsOn>
</PropertyGroup>
<PropertyGroup>
<RunScriptInputName Condition="'$(OS)' != 'Windows_NT'">RunScriptTemplate.sh</RunScriptInputName>
<RunScriptInputName Condition="'$(OS)' == 'Windows_NT'">RunScriptTemplate.cmd</RunScriptInputName>
<RunScriptInputPath>$(MSBuildThisFileDirectory)data\$(RunScriptInputName)</RunScriptInputPath>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="$(RepoRoot)src/mono/wasm/debugger/DebuggerTestSuite/DebuggerTestSuite.csproj"
ReferenceOutputAssembly="false"
Private="false"
GlobalPropertiesToRemove="TargetFramework;TargetFrameworks;Configuration;TargetOS;TargetArchitecture"
AdditionalProperties="RuntimeConfiguration=$(Configuration);ArchiveTests=$(ArchiveTests);ArchiveDirForHelix=$(TargetDir)" />
</ItemGroup>
<Target Name="UpdateRunScriptCommands" BeforeTargets="GenerateRunScript">
<ItemGroup>
<RunScriptCommands Condition="'$(OS)' != 'Windows_NT'" Include="export DEBUGGER_TEST_PATH=$PWD/debugger-test" />
<RunScriptCommands Condition="'$(OS)' == 'Windows_NT'" Include="set DEBUGGER_TEST_PATH=%25cd%25/debugger-test" />
</ItemGroup>
<ItemGroup>
<RunScriptCommands Condition="'$(ContinuousIntegrationBuild)' == 'true' and '$(OS)' != 'Windows_NT'"
Include="export CHROME_PATH_FOR_DEBUGGER_TESTS=$HELIX_CORRELATION_PAYLOAD/chrome-linux/chrome" />
<RunScriptCommands Condition="'$(ContinuousIntegrationBuild)' == 'true' and '$(OS)' == 'Windows_NT'"
Include="set CHROME_PATH_FOR_DEBUGGER_TESTS=%HELIX_CORRELATION_PAYLOAD%\chrome-win\chrome.exe" />
</ItemGroup>
<PropertyGroup>
<_DotnetCommand Condition="'$(OS)' != 'Windows_NT'">dotnet</_DotnetCommand>
<_DotnetCommand Condition="'$(OS)' == 'Windows_NT'">dotnet.exe</_DotnetCommand>
<RunScriptCommand>$(_DotnetCommand) test DebuggerTestSuite/DebuggerTestSuite.dll</RunScriptCommand>
<RunScriptCommand>$(RunScriptCommand) &quot;-l:trx%3BLogFileName=testResults.trx&quot;</RunScriptCommand>
<RunScriptCommand Condition="'$(OS)' != 'Windows_NT'">$(RunScriptCommand) --results-directory &quot;$TEST_LOG_PATH&quot;</RunScriptCommand>
<RunScriptCommand Condition="'$(OS)' == 'Windows_NT'">$(RunScriptCommand) --results-directory &quot;%TEST_LOG_PATH%&quot;</RunScriptCommand>
<RunScriptCommand Condition="'$(OS)' != 'Windows_NT'">$(RunScriptCommand) %24TEST_ARGS</RunScriptCommand>
<RunScriptCommand Condition="'$(OS)' == 'Windows_NT'">$(RunScriptCommand) %TEST_ARGS%</RunScriptCommand>
<!--<RunScriptCommand Condition="'$(ContinuousIntegrationBuild)' == 'true' or '$(XUnitShowProgress)' == 'true'">$(RunScriptCommand) -v normal</RunScriptCommand>-->
<RunScriptCommand>$(RunScriptCommand) -v diag</RunScriptCommand>
</PropertyGroup>
</Target>
<Target Name="BundleDebuggerTestsForHelix" />
</Project>
@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%
#!/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
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册