xamarin-macios/tests/monotouch-test/Network/NWParametersTest.cs

399 строки
12 KiB
C#
Исходник Обычный вид История

#if !__WATCHOS__
using System;
using System.Collections.Generic;
using System.Threading;
using CoreFoundation;
using Foundation;
using Network;
using ObjCRuntime;
using Security;
using NUnit.Framework;
using MonoTests.System.Net.Http;
namespace MonoTouchFixtures.Network {
[TestFixture]
[Preserve (AllMembers = true)]
public class NWParametersTest {
AutoResetEvent secureEvent; // used to let us know the handler was indeed called.
AutoResetEvent configureEvent; // used to let us know the handler was indeed called.
AutoResetEvent connectedEvent; // used to let us know when the connection was established so that we can access the NWPath
bool secureConnectionWasSet = false;
bool protocolConfigured = false;
List<NWInterface> interfaces = new List<NWInterface> ();
string host;
NWConnection connection;
[OneTimeSetUp]
public void Init ()
{
TestRuntime.AssertXcodeVersion (10, 0);
// we want to use a single connection, since it is expensive
connectedEvent = new AutoResetEvent(false);
host = NetworkResources.MicrosoftUri.Host;
interfaces = new List<NWInterface> ();
using (var parameters = NWParameters.CreateUdp ())
using (var endpoint = NWEndpoint.Create (host, "80")) {
connection = new NWConnection (endpoint, parameters);
connection.SetQueue (DispatchQueue.DefaultGlobalQueue); // important, else we will get blocked
connection.SetStateChangeHandler (ConnectionStateHandler);
connection.Start ();
Assert.True (connectedEvent.WaitOne (20000), "Connection timed out.");
using (var path = connection.CurrentPath)
{
path.EnumerateInterfaces (EnumerateInterfacesHandler);
}
}
}
[OneTimeTearDown]
public void Dispose()
{
Bump to mono:2019-10 (#7192) ## Miscellaneous fixes * Fixed `/Users/builder/jenkins/workspace/xamarin-macios/xamarin-macios/builds/mono-ios-sdk-destdir/ios-sources/external/linker/src/linker/Linker.Steps/OutputStep.cs(110,15): error CS0246: The type or namespace name ‘OutputException’ could not be found (are you missing a using directive or an assembly reference?) [/Users/builder/jenkins/workspace/xamarin-macios/xamarin-macios/tools/mmp/mmp.csproj]` * Changed the name of the method that is used from linker. Because of this commit https://github.com/mono/linker/commit/6be26771b9bc6d40305a8f005d38f08dfa423252 * Added `OutputException.cs` file on `mtouch.csproj`. * Removing enter_gc_safe and exit_gc_safe because now it's already gc_safe in this part of code, after a mono change. * Added known exceptions to LLVM exception list. * Needs `ifdef` because of this https://github.com/mono/mono/pull/17260. * Bump MIN_MONO_VERSION to 6.8.0.41 and point MIN_MONO_URL to the PR. * Add ENABLE_IOS=1 and ENABLE_MAC=1. * Added switch to disable packaged mono build * [Tests] Ignore tests that fail on 32b. Ignore the test on 32b, and filled issue: https://github.com/mono/mono/issues/17752 * [Tests] Ignore a couple of tests causing OOM. Hopefully fixes https://github.com/xamarin/maccore/issues/1659 for good. * Ignore `MM0135` test on Catalina+ because it needs Xcode 9.4. * [monotouch-test] Add null checks for teardown when test didn't run because of a too early OS version. * [CFNetwork]: Http 2.0 requires OS X 10.11 or later. Check whether `_HTTPVersion2_0` is available and fallback to HTTP 1.1 otherwise. ## Bring HttpClient from CoreFX * #7346 * This bumps Mono to use https://github.com/mono/mono/pull/17645 (which is the 2019-10 backport of https://github.com/mono/mono/pull/17628). * The big user-visible change is in regards to certificate validation, everything below are just some minor adjustments to tests. ### SocketsHttpHandler CoreFX uses a completely new `HttpClientHandler` implementation called `SocketsHttpHandler`, which you can find at https://github.com/dotnet/corefx/tree/release/3.0/src/System.Net.Http/src/System/Net/Http/SocketsHttpHandler. Since this is not based on the web stack anymore, it does not use any of the related APIs such as `ServicePointManager` or `WebException`. ### Certificate Validation Changes There is a new API called `HttpClientHandler.ServerCertificateCustomValidationCallback`. - https://docs.microsoft.com/en-us/dotnet/api/system.net.http.httpclienthandler.servercertificatecustomvalidationcallback?view=netframework-4.8 - https://github.com/dotnet/corefx/blob/c1778515a3bee34cc09c757b5563d0af0c8b1e99/src/System.Net.Http/src/System/Net/Http/HttpClientHandler.Unix.cs#L154 - https://github.com/dotnet/corefx/blob/c1778515a3bee34cc09c757b5563d0af0c8b1e99/src/System.Net.Http/src/System/Net/Http/HttpClientHandler.Windows.cs#L383 The `ServicePointManager.ServerCertificateValidationCallback` is no longer invoked and on certificate validation failure, `AuthenticationException` (from `System.Security.Authentication`) is thrown instead of `WebException`. At the moment, the `NSUrlSessionHandler` still uses it's own validation callback and also still throws `WebException` on failure; we should probably look into making this consistent with the other handlers. ### Minor adjustments related to internal Mono APIs * `HttpContent.SerializeToStreamAsync()` is now `protected` (changed from `protected internal`). - src/Foundation/NSUrlSessionHandler.cs: changed overload accordingly. - src/System.Net.Http/CFContentStream.cs: likewise. * `HttpHeaders.GetKnownHeaderKind()` is an internal Mono API. There is a new internal API called `System.Net.Http.PlatformHelper.IsContentHeader(key)` which exists in both the old as well as the new implementation. The correct way of doing it with the CoreFX handler is `HeaderDescriptor.TryGet (key, out var descriptor) && descriptor.HeaderType == HttpHeaderType.Content` ### Minor adjustments to tests. * `HttpClientHandler.MaxRequestContentBufferSize` is now longer supported, you can set it to any non-negative value, the getter will always return 0. See https://github.com/dotnet/corefx/blob/c1778515a3bee34cc09c757b5563d0af0c8b1e99/src/System.Net.Http/src/System/Net/Http/HttpClientHandler.Core.cs#L18. - tests/linker/ios/link sdk/HttpClientHandlerTest.cs: removed assertion from test. * `HttpMessageInvoker.handler` is a `protected private` field - in the CoreFX handler, it is called `_handler` and `private`. This is accessed via reflection by some of the tests, which are now using the new name. - tests/mmptest/src/MMPTest.cs: here - tests/mtouch/MTouch.cs: here * tests/monotouch-test/System.Net.Http/MessageHandlers.cs: Adjust `RejectSslCertificatesServicePointManager` to reflect the certificate validation changes described above. - FIXME: There was an `Assert.Ignore()` related to `NSUrlSessionHandler` and macOS 10.10; I removed that to reenable the test because the description linked to an old issue in the private repo that was referenced by several "Merged" PR's, so it looked to me that this might have already been fixed - and I also didn't see why it would fail there.
2019-12-04 23:10:32 +03:00
connection?.Dispose ();
if (interfaces != null) {
foreach (var i in interfaces)
i.Dispose ();
}
}
[SetUp]
public void SetUp ()
{
secureEvent = new AutoResetEvent(false);
configureEvent = new AutoResetEvent(false);
secureConnectionWasSet = false;
protocolConfigured = false;
}
void ConnectionStateHandler (NWConnectionState state, NWError error)
{
switch (state){
case NWConnectionState.Ready:
connectedEvent.Set ();
break;
case NWConnectionState.Cancelled:
break;
case NWConnectionState.Invalid:
case NWConnectionState.Failed:
Assert.Inconclusive ("Network connection could not be performed.");
break;
}
}
[TearDown]
public void TearDown ()
{
secureEvent = null;
secureConnectionWasSet = false;
protocolConfigured = false;
}
void EnumerateInterfacesHandler (NWInterface nwInterface)
{
interfaces.Add (nwInterface);
}
Action<NWProtocolOptions> CreateTlsHandler ()
{
return (NWProtocolOptions options) => {
secureConnectionWasSet = true;
secureEvent.Set ();
};
}
Action<NWProtocolOptions> CreateConfigureProtocolHandler ()
{
return (NWProtocolOptions options) => {
protocolConfigured = true;
configureEvent.Set ();
};
}
[Test]
public void CreateSecureUpdTest ()
{
var setUpTls = CreateTlsHandler ();
var setUpProtocol = CreateConfigureProtocolHandler ();
using (var parameters = NWParameters.CreateSecureUdp (configureTls: setUpTls, configureUdp: setUpProtocol))
using (var endpoint = NWEndpoint.Create (NetworkResources.MicrosoftUri.Host, "80")) {
secureEvent.WaitOne ();
configureEvent.WaitOne ();
Assert.True (secureConnectionWasSet, "Configure TLS handler was not called.");
Assert.True (protocolConfigured, "Protocol configure handler was not called.");
}
}
[Test]
public void CreateSecureUpdTestDoNotSetUpProtocol ()
{
var setUpTls = CreateTlsHandler ();
using (var parameters = NWParameters.CreateSecureUdp (configureTls: setUpTls))
using (var endpoint = NWEndpoint.Create (NetworkResources.MicrosoftUri.Host, "80")) {
secureEvent.WaitOne ();
Assert.True (secureConnectionWasSet, "Configure TLS handler was not called.");
Assert.False (protocolConfigured, "Protocol configure handler was called.");
}
}
[Test]
public void CreateSecureUpdTestDoNotSetUpTls ()
{
var setUpProtocol = CreateConfigureProtocolHandler ();
using (var parameters = NWParameters.CreateSecureUdp (configureTls: null, configureUdp: setUpProtocol))
using (var endpoint = NWEndpoint.Create (NetworkResources.MicrosoftUri.Host, "80")) {
configureEvent.WaitOne ();
Assert.False (secureConnectionWasSet, "Configure TLS handler was not called.");
Assert.True (protocolConfigured, "Protocol configure handler was not called.");
}
}
[Test]
public void CreateSecureTcpTest ()
{
var setUpTls = CreateTlsHandler ();
var setUpProtocol = CreateConfigureProtocolHandler ();
using (var parameters = NWParameters.CreateSecureTcp (configureTls: setUpTls, configureTcp: setUpProtocol))
using (var endpoint = NWEndpoint.Create (NetworkResources.MicrosoftUri.Host, "80")) {
secureEvent.WaitOne ();
configureEvent.WaitOne ();
Assert.True (secureConnectionWasSet, "Configure TLS handler was not called.");
Assert.True (protocolConfigured, "Protocol configure handler was not called.");
}
}
[Test]
public void CreateSecureTcpTestDoNotSetUpProtocol ()
{
var setUpTls = CreateTlsHandler ();
var setUpProtocol = CreateConfigureProtocolHandler ();
using (var parameters = NWParameters.CreateSecureTcp (configureTls: setUpTls))
using (var endpoint = NWEndpoint.Create (NetworkResources.MicrosoftUri.Host, "80")) {
secureEvent.WaitOne ();
Assert.True (secureConnectionWasSet, "Configure TLS handler was not called.");
Assert.False (protocolConfigured, "Protocol configure handler was called.");
}
}
[Test]
public void CreateSecureTcpTestDoNotSetUpTls ()
{
var setUpProtocol = CreateConfigureProtocolHandler ();
using (var parameters = NWParameters.CreateSecureTcp (configureTls: null, configureTcp: setUpProtocol))
using (var endpoint = NWEndpoint.Create (NetworkResources.MicrosoftUri.Host, "80")) {
configureEvent.WaitOne ();
Assert.False (secureConnectionWasSet, "Configure TLS handler was called.");
Assert.True (protocolConfigured, "Protocol configure handler was not called.");
}
}
#if MONOMAC
[Test]
public void CreateCustomIP ()
{
TestRuntime.AssertXcodeVersion (11, 0);
byte ipVersion = 10;
var setUpProtocol = CreateConfigureProtocolHandler ();
using (var parameters = NWParameters.CreateCustomIP (ipVersion, setUpProtocol))
using (var endpoint = NWEndpoint.Create ("wwww.google.com", "80")) {
configureEvent.WaitOne ();
Assert.True (protocolConfigured, "Protocol configure handler was not called.");
}
}
#endif
[Test]
public void MultiPathServicePropertyTest ()
{
using (var parameters = new NWParameters ())
{
var defaultValue = parameters.MultipathService;
Assert.AreEqual (defaultValue, NWMultiPathService.Disabled, "Default value changed.");
var newValue = NWMultiPathService.Aggregate;
parameters.MultipathService = newValue;
Assert.AreEqual (newValue, parameters.MultipathService, "New value was not stored.");
}
}
[Test]
public void ProtocolStackPropertyTest ()
{
using (var parameters = new NWParameters ())
{
var stack = parameters.ProtocolStack;
Assert.AreNotEqual (IntPtr.Zero, stack.Handle);
}
}
[Test]
public void LocalOnlyPropertyTest ()
{
using (var parameters = new NWParameters ())
{
var defaultValue = parameters.LocalOnly;
Assert.False (defaultValue, "Default value changed.");
parameters.LocalOnly = true;
Assert.True (parameters.LocalOnly, "New value was not stored.");
}
}
[Test]
public void PreferNoProxyPropertyTest ()
{
using (var parameters = new NWParameters ())
{
var defaultValue = parameters.PreferNoProxy;
Assert.False (defaultValue, "Default value changed.");
parameters.PreferNoProxy = true;
Assert.True (parameters.PreferNoProxy, "New value was not stored.");
}
}
[Test]
public void ExpiredDnsBehaviorPropertyTest ()
{
using (var parameters = new NWParameters ())
{
var defaultValue = parameters.ExpiredDnsBehavior;
Assert.AreEqual (NWParametersExpiredDnsBehavior.Default, defaultValue, "Default value changed.");
parameters.ExpiredDnsBehavior = NWParametersExpiredDnsBehavior.Allow;
Assert.AreEqual (NWParametersExpiredDnsBehavior.Allow, parameters.ExpiredDnsBehavior, "New value was not stored.");
}
}
[Test]
public void RequiredInterfacePropertyTest ()
{
using (var parameters = new NWParameters ())
{
var defaultValue = parameters.RequiredInterface;
Assert.IsNull (defaultValue, "Default value changed.");
// try to set a null value, we should have no issues
parameters.RequiredInterface = null;
Assert.IsNull (parameters.RequiredInterface, "Value should still be null.");
parameters.RequiredInterface = interfaces[0];
Assert.AreNotEqual (IntPtr.Zero, parameters.RequiredInterface.Handle, "New value was not set.");
}
}
[Test]
public void ProhibitInterfaceTest ()
{
using (var parameters = new NWParameters ())
{
Assert.Throws<ArgumentNullException> (() => parameters.ProhibitInterface (null), "");
Assert.AreNotEqual (0, interfaces.Count, "No network interfaces found.");
parameters.ProhibitInterface (interfaces[0]);
}
}
[Test]
public void RequiredInterfaceTypePropertyTest ()
{
using (var parameters = new NWParameters ())
{
var defaultValue = parameters.RequiredInterfaceType;
Assert.AreEqual (NWInterfaceType.Other, defaultValue, "Default value changed.");
parameters.RequiredInterfaceType = NWInterfaceType.Wifi;
Assert.AreEqual (NWInterfaceType.Wifi, parameters.RequiredInterfaceType, "BNe value was not stored.");
}
}
[Test]
public void ProhibitInterfaceTypeTest ()
{
using (var parameters = new NWParameters ())
{
var types = new List<NWInterfaceType> ();
parameters.ProhibitInterfaceType (NWInterfaceType.Wifi);
parameters.IterateProhibitedInterfaces ((type) => {types.Add (type); return true;} );
Assert.True (types.Contains (NWInterfaceType.Wifi), "Type was not prohibited.");
}
}
[Test]
public void ReuseLocalAddressPropertyTest ()
{
using (var parameters = new NWParameters ())
{
var defaultValue = parameters.ReuseLocalAddress;
Assert.False (defaultValue, "Default value changed.");
parameters.ReuseLocalAddress = true;
Assert.True (parameters.ReuseLocalAddress, "New value was not stored.");
}
}
[Test]
public void FastOpenEnabledPropertyTest ()
{
using (var parameters = new NWParameters ())
{
var defaultValue = parameters.FastOpenEnabled;
Assert.False (defaultValue, "Defalue value changed.");
parameters.FastOpenEnabled = true;
Assert.True (parameters.FastOpenEnabled, "New value was not stored.");
}
}
[Test]
public void ServiceClassPropertyTest ()
{
using (var parameters = new NWParameters ())
{
var defaultValue = parameters.ServiceClass;
Assert.AreEqual (NWServiceClass.BestEffort, defaultValue, "Default value changed.");
parameters.ServiceClass = NWServiceClass.InteractiveVideo;
Assert.AreEqual (NWServiceClass.InteractiveVideo, parameters.ServiceClass, "New value was not stored.");
}
}
[Test]
public void LocalEndpointPropertyTest ()
{
Assert.Ignore ("nw_parameters_copy_local_endpoint always return null. Rdar filled 44095278.");
using (var parameters = NWParameters.CreateUdp ())
using (var endpoint = NWEndpoint.Create (NetworkResources.MicrosoftUri.Host, "80"))
{
var defaultValue = parameters.LocalEndpoint;
Assert.IsNull (defaultValue, "Default value changed.");
parameters.LocalEndpoint = endpoint;
Assert.IsNotNull (parameters.LocalEndpoint, "New value was not stored.");
}
}
[Test]
public void IncludePeerToPeerPropertyTest ()
{
using (var parameters = new NWParameters ())
{
var defaultValue = parameters.IncludePeerToPeer;
Assert.False (defaultValue, "Default value changed.");
parameters.IncludePeerToPeer = true;
Assert.True (parameters.IncludePeerToPeer, "New value was not stored.");
}
}
[Test]
public void TestProhibitConstrained ()
{
TestRuntime.AssertXcodeVersion (11, 0);
using (var parameters = new NWParameters ()) {
var defaultValue = false;
Assert.False (defaultValue, "Default value changed.");
parameters.ProhibitConstrained = true;
Assert.True (parameters.ProhibitConstrained, "New value was not stored.");
}
}
}
}
#endif