runtime: HttpClientUsesSslCertEnvironmentVariables() test will fail on Linux with SocketsHttpHandler
The HttpClientUsesSslCertEnvironmentVariables test will fail on Linux with SocketsHttpHandler for these two test data:
[InlineData(false, false, true, true, true)]
[InlineData(false, false, true, false, true)]
[Theory]
[PlatformSpecific(~TestPlatforms.OSX)] // Not implemented
[InlineData(false, false, false, false, false)] // system -> ok
[InlineData(true, true, true, true, true)] // empty dir, empty bundle file -> fail
// It is enough to override the bundle, since all tested platforms don't have a default dir:
[InlineData(false, false, true, true, true)] // empty bundle -> fail
[InlineData(false, false, true, false, true)] // non-existing bundle -> fail
public void HttpClientUsesSslCertEnvironmentVariables(bool setSslCertDir, bool createSslCertDir,
bool setSslCertFile, bool createSslCertFile, bool expectedFailure)
{
// This test sets SSL_CERT_DIR and SSL_CERT_FILE to empty/non-existing locations and then
// checks the http request fails.
// Some platforms will use the system default when not specifying a value, while others
// will not use those certificates. Due to these platform differences, we only check specific
// combinations that are expected to work the same cross-platform.
var psi = new ProcessStartInfo();
if (setSslCertDir)
{
string sslCertDir = GetTestFilePath();
if (createSslCertDir)
{
Directory.CreateDirectory(sslCertDir);
}
psi.Environment.Add("SSL_CERT_DIR", sslCertDir);
}
if (setSslCertFile)
{
string sslCertFile = GetTestFilePath();
if (createSslCertFile)
{
File.WriteAllText(sslCertFile, "");
}
psi.Environment.Add("SSL_CERT_FILE", sslCertFile);
}
RemoteInvoke(async arg =>
{
bool shouldFail = bool.Parse(arg);
const string Url = "https://www.microsoft.com";
+ // Here, if we change to client = CreateHttpClient(useSocketsHttpHandlerBoolString: "true"), the test will always fail. Test will pass if client = CreateHttpClient(useSocketsHttpHandlerBoolString: "false"). (Not using SocketsHttpHandler)
+ using (HttpClient client = new HttpClient())
{
if (shouldFail)
{
await Assert.ThrowsAsync<HttpRequestException>(() => client.GetAsync(Url));
}
else
{
await client.GetAsync(Url);
}
}
return SuccessExitCode;
}, expectedFailure.ToString(), new RemoteInvokeOptions { StartInfo = psi }).Dispose();
}
Callstack:
Unhandled Exception: Xunit.Sdk.ThrowsException: Assert.Throws() Failure
2018-03-12 22:36:11,472: INFO: proc(54): run_and_log_output: Output: Expected: typeof(System.Net.Http.HttpRequestException)
2018-03-12 22:36:11,472: INFO: proc(54): run_and_log_output: Output: Actual: (No exception was thrown)
2018-03-12 22:36:11,472: INFO: proc(54): run_and_log_output: Output: at Xunit.Assert.Throws(Type exceptionType, Exception exception)
2018-03-12 22:36:11,472: INFO: proc(54): run_and_log_output: Output: at Xunit.Assert.ThrowsAsync[T](Func`1 testCode)
2018-03-12 22:36:11,473: INFO: proc(54): run_and_log_output: Output: at System.Net.Http.Functional.Tests.HttpClientHandler_ServerCertificates_Test.<>c.<<HttpClientUsesSslCertEnvironmentVariables>b__29_0>d.MoveNext() in /mnt/j/workspace/dotnet_corefx/master/linux-TGroup_netcoreapp+CGroup_Release+AGroup_x64+TestOuter_true_prtest/src/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTest.ServerCertificates.Unix.cs:line 117
2018-03-12 22:36:11,474: INFO: proc(54): run_and_log_output: Output: --- End of stack trace from previous location where exception was thrown ---
2018-03-12 22:36:11,474: INFO: proc(54): run_and_log_output: Output: at RemoteExecutorConsoleApp.Program.Main(String[] args) in /mnt/j/workspace/dotnet_corefx/master/linux-TGroup_netcoreapp+CGroup_Release+AGroup_x64+TestOuter_true_prtest/src/Common/tests/System/Diagnostics/RemoteExecutorConsoleApp/RemoteExecutorConsoleApp.cs:line 63
2018-03-12 22:36:11,475: INFO: proc(54): run_and_log_output: Output: --- End of stack trace from previous location where exception was thrown ---
2018-03-12 22:36:11,475: INFO: proc(54): run_and_log_output: Output: at RemoteExecutorConsoleApp.Program.Main(String[] args) in /mnt/j/workspace/dotnet_corefx/master/linux-TGroup_netcoreapp+CGroup_Release+AGroup_x64+TestOuter_true_prtest/src/Common/tests/System/Diagnostics/RemoteExecutorConsoleApp/RemoteExecutorConsoleApp.cs:line 92
2018-03-12 22:36:12,308: INFO: proc(54): run_and_log_output: Output: System.Net.Http.Functional.Tests.PlatformHandler_HttpClientHandler_ServerCertificates_Test.HttpClientUsesSslCertEnvironmentVariables(setSslCertDir: False, createSslCertDir: False, setSslCertFile: True, createSslCertFile: True, expectedFailure: True) [FAIL]
2018-03-12 22:36:12,310: INFO: proc(54): run_and_log_output: Output: System.Diagnostics.RemoteExecutorTestBase+RemoteInvokeHandle+RemoteExecutionException : Remote process failed with an unhandled exception.
2018-03-12 22:36:12,342: INFO: proc(54): run_and_log_output: Output: Stack Trace:
2018-03-12 22:36:12,767: INFO: proc(54): run_and_log_output: Output:
2018-03-12 22:36:12,768: INFO: proc(54): run_and_log_output: Output: Child exception:
2018-03-12 22:36:12,778: INFO: proc(54): run_and_log_output: Output: Xunit.Sdk.ThrowsException: Assert.Throws() Failure
2018-03-12 22:36:12,779: INFO: proc(54): run_and_log_output: Output: Expected: typeof(System.Net.Http.HttpRequestException)
2018-03-12 22:36:12,779: INFO: proc(54): run_and_log_output: Output: Actual: (No exception was thrown)
2018-03-12 22:36:12,796: INFO: proc(54): run_and_log_output: Output: /mnt/j/workspace/dotnet_corefx/master/linux-TGroup_netcoreapp+CGroup_Release+AGroup_x64+TestOuter_true_prtest/src/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTest.ServerCertificates.Unix.cs(117,0): at System.Net.Http.Functional.Tests.HttpClientHandler_ServerCertificates_Test.<>c.<<HttpClientUsesSslCertEnvironmentVariables>b__29_0>d.MoveNext()
2018-03-12 22:36:12,797: INFO: proc(54): run_and_log_output: Output: --- End of stack trace from previous location where exception was thrown ---
2018-03-12 22:36:12,797: INFO: proc(54): run_and_log_output: Output: /mnt/j/workspace/dotnet_corefx/master/linux-TGroup_netcoreapp+CGroup_Release+AGroup_x64+TestOuter_true_prtest/src/Common/tests/System/Diagnostics/RemoteExecutorConsoleApp/RemoteExecutorConsoleApp.cs(63,0): at RemoteExecutorConsoleApp.Program.Main(String[] args)
2018-03-12 22:36:12,798: INFO: proc(54): run_and_log_output: Output:
2018-03-12 22:36:12,798: INFO: proc(54): run_and_log_output: Output: Child process:
2018-03-12 22:36:12,798: INFO: proc(54): run_and_log_output: Output: System.Net.Http.Functional.Tests, Version=4.2.1.0, Culture=neutral, PublicKeyToken=9d77cc7ad39b68eb System.Net.Http.Functional.Tests.HttpClientHandler_ServerCertificates_Test+<>c System.Threading.Tasks.Task`1[System.Int32] <HttpClientUsesSslCertEnvironmentVariables>b__29_0(System.String)
2018-03-12 22:36:12,799: INFO: proc(54): run_and_log_output: Output:
2018-03-12 22:36:12,799: INFO: proc(54): run_and_log_output: Output: Child arguments:
2018-03-12 22:36:12,799: INFO: proc(54): run_and_log_output: Output: True
2018-03-12 22:36:12,799: INFO: proc(54): run_and_log_output: Output:
About this issue
- Original URL
- State: closed
- Created 6 years ago
- Comments: 26 (26 by maintainers)
It depends on the goal of the user.
The platform uses additive behaviors. That is, a certificate is considered trusted if it is in either the SSL_CERT_FILE file or the SSL_CERT_DIR directory. The test assumes that by setting just SSL_CERT_FILE that it has replaced the entire store, when in reality it has (depending on the particular distro’s certificate configurations, “probably”) just added to the store.
Another way of expressing the correct actions is