Skip to content

Commit be2c8c3

Browse files
Snap master -> release/3.0 for end of Preview 7 (#1099)
1 parent f3e3771 commit be2c8c3

File tree

1,324 files changed

+186588
-191936
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

1,324 files changed

+186588
-191936
lines changed

Documentation/api-compat.md

+73
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
# API Compatibility
2+
API compatibility is a build-time check that ensures that an `implementation` assembly implements the API surface area of a `contract` assembly.
3+
4+
For `WPF on .NET Core`, this means the following:
5+
* All `WPF on .NET Core` reference assemblies contain **at least** the API surface area contained by `WPF on .NET Framework 4.8` reference assemblies.
6+
* All hand-crafted reference assemblies for `WPF on .NET Core` contain **exactly** the needed API surface area defined by their corresponding runtime assemblies.
7+
8+
This is accomplished by the use of the [Arcade API Compatibility tool](https://github.com/dotnet/arcade/blob/master/src/Microsoft.DotNet.ApiCompat) with some modifications to fit our specific needs.
9+
10+
## [ApiCompat.props](/eng/WpfArcadeSdk/tools/ApiCompat.props)
11+
This props file implements necessary elements to trigger and control the usage of API Compatibility checks.
12+
### Net48CompatNeededProjects
13+
This property contains a list of projects that should have their reference assemblies compared against reference assemblies for `WPF on .NET Framework 4.8`.
14+
### Net48RefAssembliesDir
15+
This property points to the directory where reference assemblies for `WPF on .NET Framework 4.8` will be downloaded during native tool acquisition. In order
16+
to avoid requiring the [.NET Framework 4.8 Developer Pack](https://dotnet.microsoft.com/download/dotnet-framework/net48) to be installed on all machines that build `WPF on .NET Core`, a private tools zip is used that
17+
contains a copy of these assemblies.
18+
### RefApiCompatNeededProjects
19+
This property contains a list of projects that have hand-crafted references assemblies that must be compared against their corresponding runtime assemblies during API Compatibility checks.
20+
21+
## [ApiCompat.targets](/eng/WpfArcadeSdk/tools/ApiCompat.targets)
22+
This targets file implements necessary targets to run API compatibility checks.
23+
### Properties
24+
#### RunNetFrameworkApiCompat
25+
Controls if a project's reference assembly is checked for API compatibility against the reference assemblies for `WPF on .NET Framework 4.8`.
26+
#### RunRefApiCompat
27+
Controls if a project's hand-crafted reference assembly is checked for API compatibility against its corresponding runtime assembly.
28+
#### RunApiCompat
29+
Controls if Arcade's default API compatibility targets will run. WPF turns this off.
30+
#### ApiCompatBaseline
31+
Controls the location of the API compatibility baseline file for a specific project and API compatibility check.
32+
### Items
33+
These MSBuild Items are important to the setup of the API compatibility checks.
34+
#### ResolvedMatchingContract
35+
This points to the assembly that contains the contract API surface to validate against.
36+
#### ResolvedImplementationAssembly
37+
This points to the assembly whose API surface is being validated.
38+
### Targets
39+
The various targets both setup and execute API compatibility checks.
40+
#### ResolveNetFrameworkApiCompatItems
41+
Sets up [ApiCompatBaseline](#ApiCompatBaseline), [ResolvedMatchingContract](#ResolvedMatchingContract), and [ResolvedImplementationAssembly](#ResolvedImplementationAssembly) for projects that require
42+
API compatibility checks against `WPF on .NET Framework 4.8`. This is run before [WpfValidateApiCompatForNetFramework](#WpfValidateApiCompatForNetFramework) to
43+
ensure that the necessary configuration is availabe for the check.
44+
#### ResolveRefApiCompatItems
45+
Sets up [ApiCompatBaseline](#ApiCompatBaseline), [ResolvedMatchingContract](#ResolvedMatchingContract), and [ResolvedImplementationAssembly](#ResolvedImplementationAssembly) for projects that require
46+
API compatibility checks between runtime assemblies and hand-crafted reference assemblies. This is run before [WpfValidateApiCompatForRef](#WpfValidateApiCompatForRef) to
47+
ensure that the necessary configuration is availabe for the check.
48+
#### WpfValidateApiCompatForNetFramework
49+
Calls the API compatibility tool in order to validate a particular project's reference assembly against the corresponding reference assembly for `WPF on .NET Framework 4.8`.
50+
The [ResolvedMatchingContract](#ResolvedMatchingContract) is the `.NET Framework 4.8` assembly and the [ResolvedImplementationAssembly](#ResolvedImplementationAssembly) is the
51+
`.NET Core` assembly. This will generate and MSBuild error for each compatibility issue found. A developer can examine the current [baseline files](#Baseline-Files) to get
52+
an idea of the kinds of errors that can be reported.
53+
54+
If the tool fails completely, an error of the form "ApiCompat failed for..." will be generated. If this occurs, please [file an issue](https://github.com/dotnet/wpf/issues/new/choose) and include a link to your fork and branch that failed.
55+
#### WpfValidateApiCompatForRef
56+
Calls the API compatibility tool in order to validate a particular project's hand-crafted reference assembly against the corresponding runtime assembly.
57+
The [ResolvedMatchingContract](#ResolvedMatchingContract) is the runtime assembly and the [ResolvedImplementationAssembly](#ResolvedImplementationAssembly) is the
58+
hand-crafted reference assembly. This will generate and MSBuild error for each compatibility issue found. A developer can examine the current [baseline files](#Baseline-Files) to get
59+
an idea of the kinds of errors that can be reported.
60+
61+
If the tool fails completely, an error of the form "ApiCompat failed for..." will be generated. If this occurs, please [file an issue](https://github.com/dotnet/wpf/issues/new/choose) and include a link to your fork and branch that failed.
62+
## [Baseline Files](/src/Microsoft.DotNet.Wpf/ApiCompat/Baselines)
63+
This directory contains the aggregate baseline files for all initial API compatibility checks. The filenames are of the general form
64+
"{Project}-{APICompatType}.baseline.txt", where `APICompatType` is either `Net48` or `ref`.
65+
66+
Errors listed in a baseline file are ignored by the API compatibility tool on subsequent runs.
67+
68+
These baselined errors are, generally, one of the following:
69+
* Intential API changes that diverge from `WPF on .NET Framework 4.8`
70+
* Errors resulting from changes to underlying assemblies in `.NET Core` that do not adversely affect product functionality
71+
* Errors due to build-specific architecture at the time of baselining (e.g. the split nature of WPF's product build).
72+
73+
A developer can re-baseline the entirety of the product by setting the property `BaselineAllAPICompatError` to `true` during a build.

Documentation/developer-guide.md

+59-30
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,39 @@ We use the following workflow for building and testing features and fixes.
2323

2424
You first need to [Fork](https://github.com/dotnet/corefx/wiki/Checking-out-the-code-repository#fork-the-repository) and [Clone](https://github.com/dotnet/corefx/wiki/Checking-out-the-code-repository#clone-the-repository) this WPF repository. This is a one-time task.
2525

26+
27+
### Running DRTs locally ###
28+
In order to run the set of DRTs on your local machine, pass the `-test` parameter to the `build.cmd` script. At the end of the run, you should see something like this:
29+
30+
```
31+
A total of 1 test Infos were processed, with the following results.
32+
Passed: 1
33+
Failed (need to analyze): 0
34+
Failed (with BugIDs): 0
35+
Ignore: 0
36+
37+
```
38+
If there were any failures, you can cd into $(RepoRoot)\artifacts\test\$(Configuration)\$(Platform)\Test and run the tests manually with the `/debugtests` flag using the `RunDrts.cmd` script. Note that you do not run the `RunDrtsDebug` script, as this will debug the test infrastructure, `QualityVault`. When you pass the `/debugtests` flag, a cmd window will open where you can open the test executable in Visual Studio and debug it. When the cmd pops up, you will see instructions for debugging using a few different commands, however these commands will enable you to debug the `Simple Test Invocation` executable, `sti.exe`, which simply launches the test executable you are most likely interested in debugging. Using `DrtXaml.exe` as an example, this is how you can debug the test executable. Any MSBuild style properties should be replaced with actual values:
39+
40+
1. `$(RepoRoot)\artifacts\test\$(Configuration)\$(Platform)\Test\RunDrts.cmd /name=DrtXaml /debugtests`
41+
2. Enter following command into the cmd window that pops up:
42+
`"%ProgramFiles%\Microsoft Visual Studio\2019\Preview\Common7\IDE\devenv.exe" DrtXaml.exe`
43+
3. Once Visual Studio is open, go to `Debug-> DrtXaml Properties` and do the following:
44+
- Manually change the `Debugger Type` from `Auto` to `Mixed (CoreCLR)`.
45+
- Change the `Environment` from `Default` to a custom one that properly defines the `DOTNET_ROOT` variable so that the host is able to locate the install of `Microsoft.NETCore.App`.
46+
- x86 (Default): Name: `DOTNET_ROOT(x86)` Value: `$(RepoRoot).dotnet\x86`
47+
- x64 (/p:Platform=x64): Name: `DOTNET_ROOT` Value: `$(RepoRoot).dotnet`
48+
4. From there you can F5 and the test will execute.
49+
50+
*Note: To run a specific test, you can pass the name of the test like this: `/name=DrtXaml`. The names of these tests are contained in DrtList.xml.*
51+
52+
**NOTE: This requires being run from an admin window at the moment. Removing this restriction is tracked by https://github.com/dotnet/wpf/issues/816. **
53+
2654
### Testing Locally built WPF assemblies (excluding PresentationBuildTasks)
2755
This section of guide is intended to discuss the different approaches for ad-hoc testing of WPF assemblies,
28-
and not automated testing. There are a few different ways this can be done, and for the most part,
29-
it can be a matter of personal preference on which workflow you choose.
56+
and not automated testing. For automated testing, see the [Running DRTs locally](#Running-DRTs-locally) section above. There are a few different ways this can be done, and for the most part, it depends on what you are trying to accomplish. This section tries to lay out which scenarios require which workflow.
57+
58+
*NOTE: You should build locally with the `-pack` param to ensure the binaries are put in the correct location for manual testing.*
3059

3160
#### Copying binaries to publish location of a self-contained application
3261
The simplest approach is to publish your sample app using `dotnet publish -r <rid> --self-contained`.
@@ -39,23 +68,25 @@ Then to copy the WPF assemblies to this published location, simply run the copy-
3968
located in the `eng` folder of the repo and point it to the location of your test application:
4069
> eng\copy-wpf.ps1 -destination "c:\mysampleproj"
4170
42-
#### Copying binaries to local dotnet installation
71+
#### Copying binaries to test host installation of dotnet
4372

44-
If you want/need to test an existing application that targets the shared installation,
45-
it is safest to setup a test host, rather than trying to copy assemblies over the shared installation.
46-
The arcade infrastructure creates a local dotnet installation in the `.dotnet` folder contained at the root
47-
of the repository when you do a full build using the `build.cmd` or `build.sh` script.
48-
You can run the copy-wpf.ps1 script again, except you can leave out the destination and be sure to pass in the
49-
the `-testhost` parameter:
50-
> eng\copy-wpf.ps1 -testhost
51-
```cmd eng\copy-wpf.ps1 -testhost ```
73+
If you want/need to test an existing application that targets the shared installation, it is safest to setup a test host, rather than trying to copy assemblies over the shared installation. A test host is a complete install of dotnet (host and runtimes) used for testing applications and can be setup by using the [dotnet install script](https://docs.microsoft.com/en-us/dotnet/core/tools/dotnet-install-script). This method is also effective for internal contributors who are working on porting our current test corpus from .NET Framework to .NET Core and wants to run the tests against locally built assemblies. Note that there is nothing fundamentally different between a testhost installation of dotnet and the one installed in `$env:ProgramFiles`. However the dotnet host dll won't be able to find the testhost install if the appropriate environment variables aren't set. Note that these environment variables are set for you by copy-wpf.ps1
5274

53-
You need to set environment variables so that your testhost installation is used when launching the application.
54-
Once these are set, you should be able to launch the executable from the command line and then your assemblies
55-
will be used.
75+
You can run the copy-wpf.ps1 script again and be sure to pass in the `-testhost` parameter:
76+
> eng\copy-wpf.ps1 -testhost -destination "c:\testhost\x86"
5677
57-
- DOTNET_ROOT=<path_to_wpf_repo>\\.dotnet
58-
- DOTNET_MULTILEVEL_LOOKUP=0
78+
If your testhost directory has multiple versions of the `Microsoft.WindowsDesktop.App` shared runtime in it, you can use the `-version` parameter to specify which one you want:
79+
80+
> eng\copy-wpf.ps1 -testhost -destination "c:\testhost\x86" -version "3.0.0-preview6-27728-04"
81+
82+
If there are multiple versions, you will see a warning and the last installed runtime will be selected. You can backup the folder by creating a copy of it, and the script will ensure that this folder isn't touched as long as the word "Copy" is in the path. This was chosen because the default for Windows Explorer is to append "- Copy" to the folder. This allows you to easily backup folders containing the runtime assemblies knowing you can restore them to their original state if needed.
83+
84+
If you are installing to a special test host location, you will see output from the script that confirms the appropriate environment variables are set:
85+
86+
```
87+
** Setting env:DOTNET_ROOT(x86) to c:\testhost\x86 **
88+
** Setting env:DOTNET_MULTILEVEL_LOOKUP to 0 **
89+
```
5990

6091
**How to find location of the exe to test?**
6192
If you are testing an application and don't know where the executable is located, the easiest thing to do
@@ -69,7 +100,6 @@ When the C# compiler detects a collision with assembly references, the assembly
69100
higher version number is chosen. Assuming our locally built binaries are newer than what is
70101
installed, we can then simply reference those local binaries directly from the project file, like this:
71102

72-
*Note: you should build locally with the `-pack` param to ensure the binaries are put in the correct location.*
73103
```xml
74104
<PropertyGroup>
75105
<!-- Change this value based on where your local repo is located -->
@@ -82,21 +112,17 @@ installed, we can then simply reference those local binaries directly from the p
82112
<RuntimeIdentifier>win-x86</RuntimeIdentifier>
83113
</PropertyGroup>
84114
<ItemGroup>
85-
<Reference Include="$(WpfRepoRoot)\artifacts\packaging\$(WpfConfig)\Microsoft.DotNet.Wpf.GitHub\ref\netcoreapp3.0\*.dll" Private="false" />
86-
<ReferenceCopyLocalPaths Include="$(WpfRepoRoot)\artifacts\packaging\$(WpfConfig)\Microsoft.DotNet.Wpf.GitHub\lib\netcoreapp3.0\*.dll" />
115+
<Reference Include="$(WpfRepoRoot)\artifacts\packaging\$(WpfConfig)\Microsoft.DotNet.Wpf.GitHub\lib\netcoreapp3.0\*.dll" />
87116
<ReferenceCopyLocalPaths Include="$(WpfRepoRoot)\artifacts\packaging\$(WpfConfig)\Microsoft.DotNet.Wpf.GitHub\lib\$(RuntimeIdentifier)\*.dll" />
88117
</ItemGroup>
89118
```
90119

91120
### Testing specific versions of the Microsoft.WindowsDesktop.App runtime
92-
At times, it is necessary to install and test specific versions of the runtime. This can be helpful if you are trying to root cause when an issue started occuring.
93-
94-
For testing different versions of the runtime, you can install a specific version of the runtimes via the dotnet install script: https://docs.microsoft.com/en-us/dotnet/core/tools/dotnet-install-script
95-
**Note**: These install the versions to your %user% directory, so you can use the DOTNET_ROOT environment variables to ensure these get used as described above. Otherwise, you can point them to install in %programfiles% and specify which version of the runtime should be picked up.
121+
At times, it is necessary to install and test specific versions of the runtime. This can be helpful if you are trying to root cause when an issue started occuring, or need to compare functionality between two different versions.
96122

97-
Below is an example powershell script of how you can use the `dotnet-install.ps1` script:
123+
For testing different versions of the runtime, you can install a specific version of the runtimes via the [dotnet install script](https://docs.microsoft.com/en-us/dotnet/core/tools/dotnet-install-script). Below is an example powershell script of how you can use the `dotnet-install.ps1` script that will install both 32-bit and 64-bit versions of the `Microsoft.WindowsDesktop.App` runtime into the specified folder:
98124

99-
```
125+
```ps1
100126
$dotnet_install = "$env:TEMP\dotnet-install.ps1"
101127
$x64InstallDir = "$env:ProgramFiles\dotnet"
102128
$x86InstallDir = "${env:ProgramFiles(x86)}\dotnet"
@@ -126,14 +152,16 @@ In this example, the version of `Microsoft.WindowsDesktop.App` associated with t
126152
**Note**: The ability to install the WindowsDesktop runtime via the dotnet install script is being tracked by: https://github.com/dotnet/cli/issues/11115
127153

128154
#### Specifying which version of the runtime to use
129-
If you can build directly from source, you can add this to your project file to pick up the version of the shared runtime you want to test:
155+
If you can build directly from source, and want to test your application against a certain version of the `Microsoft.WindowsDesktop.App` shared runtime, you can add this to your project file to pick up the version of the shared runtime you want to test:
130156
```xml
131157
<PropertyGroup>
132158
<MicrosoftWindowsDesktopAppVersion>3.0.0-preview5-27619-18</MicrosoftWindowsDesktopAppVersion>
133-
<PropertyGroup>
134-
<FrameworkReference Update="Microsoft.WindowsDesktop.App">
135-
<TargetingPackVersion>$(MicrosoftWindowsDesktopAppVersion)</TargetingPackVersion>
136-
</FrameworkReference>
159+
</PropertyGroup>
160+
<ItemGroup>
161+
<FrameworkReference Update="Microsoft.WindowsDesktop.App">
162+
<TargetingPackVersion>$(MicrosoftWindowsDesktopAppVersion)</TargetingPackVersion>
163+
</FrameworkReference>
164+
</ItemGroup>
137165
```
138166

139167
If you don't have the ability to build from source, you can update the *.runtimeconfig.json file located next to the executable to pick up your version:
@@ -162,3 +190,4 @@ Follow the steps defined [here](https://github.com/dotnet/arcade/blob/master/Doc
162190
* [up-for-grabs WPF issues](https://github.com/dotnet/wpf/issues?q=is%3Aopen+is%3Aissue+label%3Aup-for-grabs)
163191
* [easy WPF issues](https://github.com/dotnet/wpf/issues?utf8=%E2%9C%93&q=is%3Aopen+is%3Aissue+label%3Aeasy)
164192
* [Code generation in dotnet/wpf](codegen.md)
193+
* [Testing in Helix](testing-in-helix.md)

0 commit comments

Comments
 (0)