Skip to content

Commit e7020cd

Browse files
authored
Fix Nagler tests to run on Linux (#524)
* Author: William Xie <willxie@microsoft.com> Date: Mon Oct 10 11:23:07 2022 -0700 Squashed commit of the following: commit 2292449 Author: William Xie <willxie@microsoft.com> Date: Fri Oct 7 14:30:06 2022 -0700 Fix up some last bugs commit 364ab15 Author: William Xie <willxie@microsoft.com> Date: Fri Oct 7 10:36:24 2022 -0700 Fix libxml2 handling of comment nodes commit 4bcbe1f Author: William Xie <willxie@microsoft.com> Date: Thu Oct 6 21:42:24 2022 -0700 Add timeout override commit 85b5661 Author: William Xie <willxie@microsoft.com> Date: Thu Oct 6 21:22:28 2022 -0700 Fix logging test commit 8ca135c Author: William Xie <willxie@microsoft.com> Date: Thu Oct 6 21:02:01 2022 -0700 Fix linux nagler tests commit e21c6db Author: William Xie <willxie@microsoft.com> Date: Thu Oct 6 11:33:38 2022 -0700 temporary changes * Update test.md and fix linux managed build * Test PR build * PR comments
1 parent f248aad commit e7020cd

35 files changed

Lines changed: 342 additions & 47 deletions

build/yaml/jobs/linux/tests.yaml

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
# Copyright (c) Microsoft Corporation. All rights reserved.
2+
# Licensed under the MIT License.
3+
4+
# Job Template: Test Linux Binaries
5+
6+
parameters:
7+
MatrixStrategy: {}
8+
9+
jobs:
10+
- job: Test_Linux_Binaries
11+
displayName: Linux Tests
12+
13+
strategy:
14+
matrix:
15+
${{ insert }}: ${{ parameters.MatrixStrategy }}
16+
17+
pool:
18+
${{ if eq(variables['System.TeamProject'], 'devdiv') }}:
19+
name: AzurePipelines-EO
20+
demands: ImageOverride -equals AzurePipelinesUbuntu20.04compliant
21+
${{ else }}:
22+
vmImage: ubuntu-latest
23+
24+
workspace:
25+
clean: outputs
26+
27+
variables:
28+
configuration: Debug
29+
30+
steps:
31+
- template: ../../steps/azuredevops/downloadbuildartifacts.yaml
32+
parameters:
33+
ArtifactName: binaries-windows-$(Configuration)
34+
35+
- template: ../../steps/azuredevops/downloadbuildartifacts.yaml
36+
parameters:
37+
ArtifactName: binaries-linux-ubuntu-$(Configuration)
38+
39+
# Simulate DeploymentItem by copying the Linux binaries
40+
- task: CopyFiles@2
41+
displayName: Setup Linux binaries for tests
42+
inputs:
43+
sourceFolder: $(Build.StagingDirectory)/binaries-linux-ubuntu-$(Configuration)/ClrInstrumentationEngine/
44+
targetFolder: $(Build.StagingDirectory)/binaries-windows-$(Configuration)/AnyCPU/$(TargetFrameworkFolder)/
45+
46+
- task: UseDotNet@2
47+
displayName: 'Use .NET sdk'
48+
inputs:
49+
version: $(NetSdkVersion)
50+
includePreviewVersions: true
51+
installationPath: $(Agent.TempDirectory)/dotnet
52+
53+
# Environment variable used by tests
54+
- bash: |
55+
echo "##vso[task.setvariable variable=DOTNET_EXE]$(Agent.TempDirectory)/dotnet/dotnet"
56+
57+
- task: DotNetCoreCLI@2
58+
displayName: 'Run Tests: InstrEngineTests.dll'
59+
inputs:
60+
command: test
61+
workingDirectory: $(Agent.TempDirectory)/dotnet
62+
arguments: $(Build.StagingDirectory)/binaries-windows-$(Configuration)/AnyCPU/$(TargetFrameworkFolder)/InstrEngineTests.dll
63+
testRunTitle: Linux Nagler Tests
64+
publishTestResults: true
65+
condition: succeededOrFailed()

build/yaml/jobs/tests.yaml

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,5 +36,13 @@ jobs:
3636
Platform: 'AnyCPU'
3737
RunSettingsFile: 'x64.runsettings'
3838

39-
# Linux Binaries (TBD)
40-
#- template: linux/tests.yaml
39+
# Test Linux Binaries
40+
- template: linux/tests.yaml
41+
parameters:
42+
MatrixStrategy:
43+
NET_Next:
44+
TargetFrameworkFolder: net70
45+
NetSdkVersion: 7.x
46+
NET_LTS:
47+
TargetFrameworkFolder: net60
48+
NetSdkVersion: 6.x

build/yaml/steps/azuredevops/downloadbuildartifacts.yaml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
parameters:
77
ArtifactName: ''
88
ItemPattern: '**'
9+
DownloadPath: $(Build.ArtifactStagingDirectory)
910

1011
steps:
1112
# download Artifacts
@@ -14,5 +15,5 @@ steps:
1415
inputs:
1516
downloadType: single
1617
artifactName: ${{ parameters.ArtifactName }}
17-
downloadPath: $(Build.ArtifactStagingDirectory)
18+
downloadPath: ${{ parameters.DownloadPath }}
1819
itemPattern: ${{ parameters.ItemPattern }}

docs/test.md

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,5 +35,22 @@ Verbose|Sets msbuild verbosity to `normal`. By default, verbosity is set to `Err
3535

3636
### Linux
3737

38-
Currently there are no unit tests support for Linux. However, Linux builds will run via PR validations. Please contact
39-
clrieowners@microsoft.com for more details.
38+
#### Prerequisites
39+
40+
The following technologies/tools are required in order to run Linux tests on Windows. These instructions were tested for Ubuntu 18.04 LTS and may require adjustments for other distros/versions.
41+
42+
* WSL (Windows Subsystem for Linux) 2.0 with Ubuntu 18.04 LTS
43+
- WSL is available on Windows 10 Build 19041+ and Windows 11.
44+
- Run this in a command prompt `wsl --install -d Ubuntu-18.04` or download Ubuntu 18.04 from the Microsoft Store. Restart as needed and setup a user/pass for your account.
45+
* Docker Desktop for Linux (Ubuntu)
46+
- Follow the instructions from the official docs https://docs.docker.com/engine/install/ubuntu/
47+
48+
#### Steps
49+
50+
1. On Windows, build InstrumentationEngine for Debug AnyCPU (which builds managed projects and dlls)
51+
- You can also run `dotnet build InstrumentationEngine.sln` in the interactive container session from step 2 instead.
52+
2. Run `src\scripts\DockerLocalBuild.ps1 -Wsl -BuildDockerImage -Interactive -RebuildImage`. This will build a docker container and drop you in an interactive session. By default builds for Ubuntu/Debian; set `-CLib musl` if you want to build for Alpine Linux instead.
53+
3. Run `./src/build.sh` within the interactive session. This builds the native shared object files (.so).
54+
4. Run `dotnet test bin/Debug/AnyCPU/net70/InstrEngineTests.dll`
55+
56+
Please contact clrieowners@microsoft.com for any details or questions.

src/Common.Lib/XmlNode.cpp

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,15 @@ namespace CommonLib
8282
name = pName.m_str;
8383

8484
#else
85-
IfFailRet(SystemString::Convert((const char*)m_pNode->name, name));
85+
// LibXML2 will return an empty string for comment node names so we mark it as '#comment'.
86+
if (m_pNode->type == XML_COMMENT_NODE)
87+
{
88+
name = _T("#comment");
89+
}
90+
else
91+
{
92+
IfFailRet(SystemString::Convert((const char*)m_pNode->name, name));
93+
}
8694
#endif
8795

8896
return S_OK;

src/InstrumentationEngine.Attach/InstrumentationEngine.Attach.csproj

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,11 @@
4242
<PackageReference Include="System.CommandLine" Version="2.0.0-beta1.20104.2" />
4343
</ItemGroup>
4444
<Import Project="$(EnlistmentRoot)\build\Managed.targets" />
45-
<Target Name="XsdGeneration" AfterTargets="PrepareForBuild" Inputs="@(XsdSchemaFile)" Outputs="@(XsdSchemaFile.OutputFile)" Condition="'@(XsdSchemaFile)' != ''">
45+
<Target Name="XsdGeneration"
46+
AfterTargets="PrepareForBuild"
47+
Inputs="@(XsdSchemaFile)"
48+
Outputs="@(XsdSchemaFile.OutputFile)"
49+
Condition="$([MSBuild]::IsOSPlatform('Windows')) AND '@(XsdSchemaFile)' != ''">
4650
<Error Condition="'%(XsdSchemaFile.Namespace)' == ''" Text="Missing Namespace attribute for XsdSchemaFile %(XsdSchemaFile.FullPath)" />
4751
<PropertyGroup>
4852
<XsdToolPath Condition="!Exists('$(XsdToolPath)')">$(MSBuildProgramFiles32)\Microsoft SDKs\Windows\v10.0A\bin\NETFX 4.8 Tools\xsd.exe</XsdToolPath>

src/InstrumentationEngine/ProfilerManagerForInstrumentationMethod.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,15 @@ CProfilerManagerForInstrumentationMethod::CProfilerManagerForInstrumentationMeth
2424
// 1 offset = trim start bracket
2525
// 36 length = keep only Guid portion
2626
m_wszInstrumentationMethodGuid = tstring(wszCurrentMethodGuid).substr(1, 36);
27+
for (int i = 0; i < 36; i++)
28+
{
29+
m_wszInstrumentationMethodGuid[i] = std::toupper(m_wszInstrumentationMethodGuid[i]);
30+
}
31+
2732
m_instrumentationMethodGuid = instrumentationMethodGuid;
2833

2934
// Get InstrumentationMethod-specific LogLevel Environment Variable
35+
// Environment variables are case-insensitive on Windows and case-sensitive on Linux/Mac.
3036
tstring wszInstrumentationMethodLogLevelEnvVar = _T("MicrosoftInstrumentationEngine_LogLevel_") + m_wszInstrumentationMethodGuid;
3137
WCHAR wszEnvVar[MAX_PATH];
3238
if (GetEnvironmentVariable(wszInstrumentationMethodLogLevelEnvVar.c_str(), wszEnvVar, MAX_PATH) > 0)

src/Tests/InstrEngineTests/InstrEngineTests/InstrEngineTests.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
<EmbeddedResource Include="EmbeddedResources\**" />
2121
</ItemGroup>
2222
<ItemGroup>
23+
<None Include="RefStructsTests.cs" />
2324
<None Remove="EmbeddedResources\InvalidCSharp\readme.txt" />
2425
</ItemGroup>
2526
<ItemGroup Condition="!$([MSBuild]::IsTargetFrameworkCompatible('$(TargetFramework)', 'net7.0'))">

src/Tests/InstrEngineTests/InstrEngineTests/MaxStackSizeTests.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,9 @@ namespace InstrEngineTests
2121
[DeploymentItem(PathUtils.NaglerInstrumentationConfigX86BinPath)]
2222
[DeploymentItem(PathUtils.NaglerInstrumentationMethodX64BinPath)]
2323
[DeploymentItem(PathUtils.NaglerInstrumentationMethodX86BinPath)]
24+
[DeploymentItem(PathUtils.LinuxInstrumentationEngineX64BinPath)]
25+
[DeploymentItem(PathUtils.LinuxNaglerInstrumentationConfigX64BinPath)]
26+
[DeploymentItem(PathUtils.LinuxNaglerInstrumentationMethodX64BinPath)]
2427
public class MaxStackSizeTests
2528
{
2629
private static TestContext Context;

src/Tests/InstrEngineTests/InstrEngineTests/PathUtils.cs

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -13,15 +13,19 @@ public static class PathUtils
1313
private const string TestScriptsFolder = "TestScripts";
1414
private const string ResourcesFolder = "ExtractedResources";
1515

16-
// All paths are relative to the AnyCPU binaries directory e.g. bin\Debug\AnyCPU
17-
public const string BaselinesBinPath = @".\" + BaselinesFolder;
18-
public const string TestScriptsBinPath = @".\" + TestScriptsFolder;
19-
public const string InstrumentationEngineX64BinPath = @"..\..\x64\MicrosoftInstrumentationEngine_x64.dll";
20-
public const string InstrumentationEngineX86BinPath = @"..\..\x86\MicrosoftInstrumentationEngine_x86.dll";
21-
public const string NaglerInstrumentationConfigX64BinPath = @"..\..\x64\NaglerInstrumentationMethod_x64.xml";
22-
public const string NaglerInstrumentationConfigX86BinPath = @"..\..\x86\NaglerInstrumentationMethod_x86.xml";
23-
public const string NaglerInstrumentationMethodX64BinPath = @"..\..\x64\NaglerInstrumentationMethod_x64.dll";
24-
public const string NaglerInstrumentationMethodX86BinPath = @"..\..\x86\NaglerInstrumentationMethod_x86.dll";
16+
// All paths are relative to the AnyCPU binaries directory e.g. bin/Debug/AnyCPU/(framework)
17+
// Use forward slashes '/' to maintain compatibility between Windows and Linux
18+
public const string BaselinesBinPath = @"./" + BaselinesFolder;
19+
public const string TestScriptsBinPath = @"./" + TestScriptsFolder;
20+
public const string InstrumentationEngineX64BinPath = @"../../x64/MicrosoftInstrumentationEngine_x64.dll";
21+
public const string InstrumentationEngineX86BinPath = @"../../x86/MicrosoftInstrumentationEngine_x86.dll";
22+
public const string NaglerInstrumentationConfigX64BinPath = @"../../x64/NaglerInstrumentationMethod_x64.xml";
23+
public const string NaglerInstrumentationConfigX86BinPath = @"../../x86/NaglerInstrumentationMethod_x86.xml";
24+
public const string NaglerInstrumentationMethodX64BinPath = @"../../x64/NaglerInstrumentationMethod_x64.dll";
25+
public const string NaglerInstrumentationMethodX86BinPath = @"../../x86/NaglerInstrumentationMethod_x86.dll";
26+
public const string LinuxInstrumentationEngineX64BinPath = @"../../../../out/Linux/bin/x64.Debug/ClrInstrumentationEngine/libInstrumentationEngine.so";
27+
public const string LinuxNaglerInstrumentationConfigX64BinPath = @"../../../../out/Linux/bin/x64.Debug/ClrInstrumentationEngine/NaglerInstrumentationMethod/LinuxNaglerInstrumentationMethod.xml";
28+
public const string LinuxNaglerInstrumentationMethodX64BinPath = @"../../../../out/Linux/bin/x64.Debug/ClrInstrumentationEngine/libNaglerInstrumentationEngine.so";
2529

2630
public static string GetAssetsPath()
2731
{

0 commit comments

Comments
 (0)