Refactor w3tracecontext integration test (#3563)

This commit is contained in:
Vishwesh Bankwar 2022-08-08 17:04:41 -07:00 committed by GitHub
parent 952c3b17fc
commit 361912efa7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 61 additions and 264 deletions

View File

@ -1,94 +0,0 @@
// <copyright file="InProcessServer.cs" company="OpenTelemetry Authors">
// Copyright The OpenTelemetry Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// </copyright>
using System;
using System.Globalization;
using System.IO;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.DependencyInjection;
using OpenTelemetry.Trace;
#if NET6_0
using TestApp.AspNetCore._6._0;
#endif
#if NET7_0
using TestApp.AspNetCore._7._0;
#endif
using Xunit.Abstractions;
namespace OpenTelemetry.Instrumentation.W3cTraceContext.Tests
{
public class InProcessServer : IDisposable
{
private readonly ITestOutputHelper output;
private readonly string url;
private readonly int port;
private IWebHost hostingEngine;
public InProcessServer(ITestOutputHelper output)
{
this.output = output;
this.port = 5000;
this.url = $"http://localhost:{this.port}";
this.StartServer();
}
public void Dispose()
{
this.DisposeServer();
GC.SuppressFinalize(this);
}
private static string GetTimestamp()
{
return DateTime.UtcNow.ToString("yyyy-MM-ddTHH:mm:ss.fffffffZ", CultureInfo.InvariantCulture);
}
private void StartServer()
{
this.output.WriteLine(string.Format("{0}: Starting application at: {1}", GetTimestamp(), this.url));
var builder = new WebHostBuilder()
.UseContentRoot(Directory.GetCurrentDirectory())
.UseUrls(this.url)
.UseKestrel()
.UseStartup<Startup>()
.UseEnvironment("Production");
builder.ConfigureServices(services =>
{
services.AddOpenTelemetryTracing((builder) => builder
.AddAspNetCoreInstrumentation()
.AddHttpClientInstrumentation());
});
this.hostingEngine = builder.Build();
this.hostingEngine.Start();
}
private void DisposeServer()
{
if (this.hostingEngine != null)
{
this.output.WriteLine(string.Format("{0}: Disposing WebHost starting.....", GetTimestamp()));
this.hostingEngine.Dispose();
this.output.WriteLine(string.Format("{0}: Disposing WebHost completed.", GetTimestamp()));
this.hostingEngine = null;
}
else
{
this.output.WriteLine(string.Format("{0}: Hosting engine is null.", GetTimestamp()));
}
}
}
}

View File

@ -29,14 +29,6 @@
<Compile Include="$(RepoRoot)\src\OpenTelemetry.Api\Internal\SpanAttributeConstants.cs" Link="Includes\SpanAttributeConstants.cs" />
</ItemGroup>
<ItemGroup Condition="'$(TargetFramework)' == 'net6.0'">
<ProjectReference Include="$(RepoRoot)\test\TestApp.AspNetCore.6.0\TestApp.AspNetCore.6.0.csproj" />
</ItemGroup>
<ItemGroup Condition="'$(TargetFramework)' == 'net7.0'">
<ProjectReference Include="$(RepoRoot)\test\TestApp.AspNetCore.7.0\TestApp.AspNetCore.7.0.csproj" />
</ItemGroup>
<ItemGroup>
<Compile Include="$(RepoRoot)\test\OpenTelemetry.Tests\Shared\SkipUnlessEnvVarFoundTheoryAttribute.cs" Link="Implementation\SkipUnlessEnvVarFoundTheoryAttribute.cs" />
</ItemGroup>

View File

@ -13,9 +13,15 @@
// See the License for the specific language governing permissions and
// limitations under the License.
// </copyright>
using System.Diagnostics;
using System.Net.Http;
using System.Text;
using System.Text.Json;
using System.Text.Json.Serialization;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Mvc;
using OpenTelemetry.Tests;
using OpenTelemetry.Trace;
using Xunit;
using Xunit.Abstractions;
@ -27,8 +33,8 @@ namespace OpenTelemetry.Instrumentation.W3cTraceContext.Tests
To run the tests, invoke docker-compose.yml from the root of the repo:
opentelemetry>docker-compose --file=test/OpenTelemetry.Instrumentation.W3cTraceContext.Tests/docker-compose.yml --project-directory=. up --exit-code-from=tests --build
*/
private const string W3cTraceContextEnvVarName = "OTEL_W3CTRACECONTEXT";
private readonly HttpClient httpClient = new HttpClient();
private readonly ITestOutputHelper output;
public W3CTraceContextTests(ITestOutputHelper output)
@ -40,24 +46,57 @@ namespace OpenTelemetry.Instrumentation.W3cTraceContext.Tests
[SkipUnlessEnvVarFoundTheory(W3cTraceContextEnvVarName)]
[InlineData("placeholder")]
[System.Diagnostics.CodeAnalysis.SuppressMessage("Usage", "xUnit1026:Theory methods should use all of their parameters", Justification = "Need to use SkipUnlessEnvVarFoundTheory")]
public void W3CTraceContextTestSuite(string value)
public void W3CTraceContextTestSuiteAsync(string value)
{
// Arrange
using var server = new InProcessServer(this.output);
// configure SDK
using var tracerprovider = Sdk.CreateTracerProviderBuilder()
.AddAspNetCoreInstrumentation()
.Build();
// Act
// Run Python script in test folder of W3C Trace Context repository
string result = RunCommand("python", "trace-context/test/test.py http://127.0.0.1:5000/api/forward");
var builder = WebApplication.CreateBuilder();
var app = builder.Build();
// disabling due to failing dotnet-format
// TODO: investigate why dotnet-format fails.
#pragma warning disable SA1008 // Opening parenthesis should be spaced correctly
app.MapPost("/", async([FromBody]Data[] data) =>
{
var result = string.Empty;
if (data != null)
{
foreach (var argument in data)
{
var request = new HttpRequestMessage(HttpMethod.Post, argument.Url)
{
Content = new StringContent(
JsonSerializer.Serialize(argument.Arguments),
Encoding.UTF8,
"application/json"),
};
await this.httpClient.SendAsync(request);
}
}
else
{
result = "done";
}
return result;
});
#pragma warning restore SA1008 // Opening parenthesis should be spaced correctly
app.RunAsync();
string result = RunCommand("python", "trace-context/test/test.py http://localhost:5000/");
// Assert
// Assert on the last line
// TODO: fix W3C Trace Context test suite
// ASP NET Core 2.1: FAILED (failures=1)
// ASP NET Core 3.1: FAILED (failures=3)
// ASP NET Core 5.0: FAILED (failures=3)
// TODO: Investigate failures:
// 1) harness sends a request with an invalid tracestate header with duplicated keys ... FAIL
// 2) harness sends an invalid traceparent with illegal characters in trace_flags ... FAIL
string lastLine = ParseLastLine(result);
this.output.WriteLine("result:" + result);
Assert.StartsWith("FAILED", lastLine);
Assert.StartsWith("FAILED (failures=2)", lastLine);
}
private static string RunCommand(string command, string args)
@ -78,7 +117,6 @@ namespace OpenTelemetry.Instrumentation.W3cTraceContext.Tests
proc.Start();
// TODO: after W3C Trace Context test suite passes, it might go in standard output
// var results = proc.StandardOutput.ReadToEnd();
var results = proc.StandardError.ReadToEnd();
proc.WaitForExit();
return results;
@ -95,5 +133,14 @@ namespace OpenTelemetry.Instrumentation.W3cTraceContext.Tests
var lastNewLineCharacterPos = output.LastIndexOf('\n', output.Length - 2);
return output.Substring(lastNewLineCharacterPos + 1);
}
public class Data
{
[JsonPropertyName("url")]
public string Url { get; set; }
[JsonPropertyName("arguments")]
public Data[] Arguments { get; set; }
}
}
}

View File

@ -1,73 +0,0 @@
// <copyright file="ForwardController.cs" company="OpenTelemetry Authors">
// Copyright The OpenTelemetry Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// </copyright>
using System.Net.Http;
using System.Text;
using System.Text.Json;
using System.Text.Json.Serialization;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
namespace TestApp.AspNetCore._6._0.Controllers
{
[Route("api/[controller]")]
public class ForwardController : Controller
{
private readonly HttpClient httpClient;
public ForwardController(HttpClient httpClient)
{
this.httpClient = httpClient;
}
// POST api/test
[HttpPost]
public async Task<string> Post([FromBody] Data[] data)
{
var result = string.Empty;
if (data != null)
{
foreach (var argument in data)
{
var request = new HttpRequestMessage(HttpMethod.Post, argument.Url)
{
Content = new StringContent(
JsonSerializer.Serialize(argument.Arguments),
Encoding.UTF8,
"application/json"),
};
await this.httpClient.SendAsync(request);
}
}
else
{
result = "done";
}
return result;
}
public class Data
{
[JsonPropertyName("url")]
public string Url { get; set; }
[JsonPropertyName("arguments")]
public Data[] Arguments { get; set; }
}
}
}

View File

@ -1,75 +0,0 @@
// <copyright file="ForwardController.cs" company="OpenTelemetry Authors">
// Copyright The OpenTelemetry Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// </copyright>
using System.Net.Http;
using System.Text;
using System.Text.Json;
using System.Text.Json.Serialization;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
#pragma warning disable SA1300 // Element should begin with upper-case letter
namespace TestApp.AspNetCore._7._0.Controllers
#pragma warning restore SA1300 // Element should begin with upper-case letter
{
[Route("api/[controller]")]
public class ForwardController : Controller
{
private readonly HttpClient httpClient;
public ForwardController(HttpClient httpClient)
{
this.httpClient = httpClient;
}
// POST api/test
[HttpPost]
public async Task<string> Post([FromBody] Data[] data)
{
var result = string.Empty;
if (data != null)
{
foreach (var argument in data)
{
var request = new HttpRequestMessage(HttpMethod.Post, argument.Url)
{
Content = new StringContent(
JsonSerializer.Serialize(argument.Arguments),
Encoding.UTF8,
"application/json"),
};
await this.httpClient.SendAsync(request);
}
}
else
{
result = "done";
}
return result;
}
public class Data
{
[JsonPropertyName("url")]
public string Url { get; set; }
[JsonPropertyName("arguments")]
public Data[] Arguments { get; set; }
}
}
}