public static void BasicAuthentication_RoundTrips_Echo()
    {
        BasicHttpBinding basicHttpBinding = null;
        EndpointAddress  endpointAddress  = null;
        ChannelFactory <IWcfCustomUserNameService> factory = null;
        string username = null;
        string password = null;
        IWcfCustomUserNameService serviceProxy = null;
        string testString = null;
        string result     = null;

        try
        {
            // *** SETUP *** \\
            basicHttpBinding = new BasicHttpBinding(BasicHttpSecurityMode.Transport);
            basicHttpBinding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Basic;
            endpointAddress = new EndpointAddress(Endpoints.Https_BasicAuth_Address);
            factory         = new ChannelFactory <IWcfCustomUserNameService>(basicHttpBinding, endpointAddress);
            username        = Guid.NewGuid().ToString("n").Substring(0, 8);
            password        = Guid.NewGuid().ToString("n").Substring(0, 16);
            factory.Credentials.UserName.UserName = username;
            factory.Credentials.UserName.Password = password;
            serviceProxy = factory.CreateChannel();
            testString   = "I am a test";

            // *** EXECUTE *** \\
            using (var scope = new OperationContextScope((IContextChannel)serviceProxy))
            {
                HttpRequestMessageProperty requestMessageProperty;
                if (!OperationContext.Current.OutgoingMessageProperties.ContainsKey(HttpRequestMessageProperty.Name))
                {
                    requestMessageProperty = new HttpRequestMessageProperty();
                    OperationContext.Current.OutgoingMessageProperties[HttpRequestMessageProperty.Name] = requestMessageProperty;
                }
                else
                {
                    requestMessageProperty = (HttpRequestMessageProperty)OperationContext.Current.OutgoingMessageProperties[HttpRequestMessageProperty.Name];
                }

                requestMessageProperty.Headers[BasicUsernameHeaderName] = username;
                requestMessageProperty.Headers[BasicPasswordHeaderName] = password;

                result = serviceProxy.Echo(testString);
            }

            // *** VALIDATE *** \\
            Assert.True(String.Equals(result, testString),
                        String.Format("Basic echo test.\nTest variation:...\n{0}\nUsing address: '{1}'\nError: expected response from service: '{2}' Actual was: '{3}'",
                                      "BasicAuthentication_RoundTrips_Echo",
                                      Endpoints.Https_BasicAuth_Address,
                                      testString,
                                      result));

            // *** CLEANUP *** \\
            factory.Close();
            ((ICommunicationObject)serviceProxy).Close();
        }
        finally
        {
            // *** ENSURE CLEANUP *** \\
            ScenarioTestHelpers.CloseCommunicationObjects((ICommunicationObject)serviceProxy, factory);
        }
    }
    public static void NegotiateStream_Http_With_ExplicitUserNameAndPassword_With_Upn()
    {
#if FULLXUNIT_NOTSUPPORTED
        bool windows_Authentication_Available = Windows_Authentication_Available();
        bool root_Certificate_Installed       = Root_Certificate_Installed();
        bool explicit_Credentials_Available   = Explicit_Credentials_Available();
        bool domain_Available = Domain_Available();
        bool upn_Available    = UPN_Available();

        if (!windows_Authentication_Available ||
            !root_Certificate_Installed ||
            !explicit_Credentials_Available ||
            !domain_Available ||
            !upn_Available)
        {
            Console.WriteLine("---- Test SKIPPED --------------");
            Console.WriteLine("Attempting to run the test in ToF, a ConditionalFact evaluated as FALSE.");
            Console.WriteLine("Windows_Authentication_Available evaluated as {0}", windows_Authentication_Available);
            Console.WriteLine("Root_Certificate_Installed evaluated as {0}", root_Certificate_Installed);
            Console.WriteLine("Explicit_Credentials_Available evaluated as {0}", explicit_Credentials_Available);
            Console.WriteLine("Domain_Available evaluated as {0}", domain_Available);
            Console.WriteLine("UPN_Available evaluated as {0}", upn_Available);
            return;
        }
#endif
        string testString = "Hello";
        ChannelFactory <IWcfService> factory = null;
        IWcfService serviceProxy             = null;

        try
        {
            // *** SETUP *** \\
            BasicHttpBinding binding = new BasicHttpBinding(BasicHttpSecurityMode.Transport);
            binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Windows;
            factory = new ChannelFactory <IWcfService>(
                binding,
                new EndpointAddress(
                    new Uri(Endpoints.Https_WindowsAuth_Address),
                    new UpnEndpointIdentity(GetUPN())
                    ));

            factory.Credentials.Windows.ClientCredential.Domain   = GetDomain();
            factory.Credentials.Windows.ClientCredential.UserName = GetExplicitUserName();
            factory.Credentials.Windows.ClientCredential.Password = GetExplicitPassword();

            serviceProxy = factory.CreateChannel();

            // *** EXECUTE *** \\
            string result = serviceProxy.Echo(testString);

            // *** VALIDATE *** \\
            Assert.Equal(testString, result);

            // *** CLEANUP *** \\
            ((ICommunicationObject)serviceProxy).Close();
            factory.Close();
        }
        finally
        {
            // *** ENSURE CLEANUP *** \\
            ScenarioTestHelpers.CloseCommunicationObjects((ICommunicationObject)serviceProxy, factory);
        }
    }
Esempio n. 3
0
    private static void RunVariation(string serviceAddress, bool isMultiNs = false)
    {
        BasicHttpBinding             binding         = null;
        EndpointAddress              endpointAddress = null;
        ChannelFactory <ICalculator> factory1        = null;
        ChannelFactory <IHelloWorld> factory2        = null;
        ICalculator serviceProxy1 = null;
        IHelloWorld serviceProxy2 = null;

        // *** SETUP *** \\
        binding         = new BasicHttpBinding();
        endpointAddress = new EndpointAddress(serviceAddress);
        factory1        = new ChannelFactory <ICalculator>(binding, endpointAddress);
        serviceProxy1   = factory1.CreateChannel();
        if (isMultiNs)
        {
            factory2      = new ChannelFactory <IHelloWorld>(binding, endpointAddress);
            serviceProxy2 = factory2.CreateChannel();
        }

        // *** EXECUTE Variation *** \\
        try
        {
            var    dateTime  = DateTime.Now;
            string testStr   = "test string";
            var    intParams = new IntParams()
            {
                P1 = 5, P2 = 10
            };
            var floatParams = new FloatParams()
            {
                P1 = 5.0f, P2 = 10.0f
            };
            var byteParams = new ByteParams()
            {
                P1 = 5, P2 = 10
            };

            Assert.Equal(3, serviceProxy1.Sum2(1, 2));
            Assert.Equal(intParams.P1 + intParams.P2, serviceProxy1.Sum(intParams));
            Assert.Equal(string.Format("{0}{1}", intParams.P1, intParams.P2), serviceProxy1.Concatenate(intParams));
            Assert.Equal((float)(floatParams.P1 / floatParams.P2), serviceProxy1.Divide(floatParams));
            Assert.Equal((new byte[] { byteParams.P1, byteParams.P2 }), serviceProxy1.CreateSet(byteParams));
            Assert.Equal(dateTime, serviceProxy1.ReturnInputDateTime(dateTime));

            Guid guid = Guid.NewGuid();
            serviceProxy1.AddIntParams(guid, intParams);
            IntParams outputIntParams = serviceProxy1.GetAndRemoveIntParams(guid);
            Assert.NotNull(outputIntParams);
            Assert.Equal(intParams.P1, outputIntParams.P1);
            Assert.Equal(intParams.P2, outputIntParams.P2);

            if (isMultiNs)
            {
                Guid guid2 = Guid.NewGuid();
                serviceProxy2.AddString(guid2, testStr);
                Assert.Equal(testStr, serviceProxy2.GetAndRemoveString(guid2));
            }
        }
        catch (Exception ex)
        {
            Assert.True(false, ex.Message);
        }
        finally
        {
            // *** ENSURE CLEANUP *** \\
            ScenarioTestHelpers.CloseCommunicationObjects((ICommunicationObject)serviceProxy1);
            if (isMultiNs)
            {
                ScenarioTestHelpers.CloseCommunicationObjects((ICommunicationObject)serviceProxy2);
            }
        }
    }
Esempio n. 4
0
    public static void WebSocket_Https_Duplex_TextBuffered_KeepAlive()
    {
        TextMessageEncodingBindingElement textMessageEncodingBindingElement = null;
        HttpsTransportBindingElement      httpsTransportBindingElement      = null;
        CustomBinding   binding        = null;
        ClientReceiver  clientReceiver = null;
        InstanceContext context        = null;
        DuplexChannelFactory <IWSDuplexService> channelFactory = null;
        IWSDuplexService client = null;

        try
        {
            // *** SETUP *** \\
            textMessageEncodingBindingElement = new TextMessageEncodingBindingElement();
            httpsTransportBindingElement      = new HttpsTransportBindingElement()
            {
                MaxReceivedMessageSize = ScenarioTestHelpers.SixtyFourMB,
                MaxBufferSize          = ScenarioTestHelpers.SixtyFourMB
            };
            httpsTransportBindingElement.WebSocketSettings.TransportUsage    = WebSocketTransportUsage.Always;
            httpsTransportBindingElement.WebSocketSettings.KeepAliveInterval = TimeSpan.FromSeconds(2);
            binding = new CustomBinding(textMessageEncodingBindingElement, httpsTransportBindingElement);

            clientReceiver = new ClientReceiver();
            context        = new InstanceContext(clientReceiver);
            channelFactory = new DuplexChannelFactory <IWSDuplexService>(context, binding, new EndpointAddress(Endpoints.WebSocketHttpsDuplexTextBuffered_Address));
            client         = channelFactory.CreateChannel();

            // *** EXECUTE *** \\
            // Invoking UploadData
            client.UploadData(ScenarioTestHelpers.CreateInterestingString(123));

            // Invoking StartPushingData
            client.StartPushingData();
            Assert.True(clientReceiver.ReceiveDataInvoked.WaitOne(ScenarioTestHelpers.TestTimeout),
                        String.Format("Test case timeout was reached while waiting for the buffered response from the Service. Timeout was: {0}", ScenarioTestHelpers.TestTimeout));
            clientReceiver.ReceiveDataInvoked.Reset();
            // Invoking StopPushingData
            client.StopPushingData();
            Assert.True(clientReceiver.ReceiveDataCompleted.WaitOne(ScenarioTestHelpers.TestTimeout),
                        String.Format("Test case timeout was reached while waiting for the buffered response from the Service to be completed. Timeout was: {0}", ScenarioTestHelpers.TestTimeout));
            clientReceiver.ReceiveDataCompleted.Reset();

            // Getting results from server via callback.
            client.GetLog();
            Assert.True(clientReceiver.LogReceived.WaitOne(ScenarioTestHelpers.TestTimeout),
                        String.Format("Test case timeout was reached while waiting for the Logging from the Service to be received. Timeout was: {0}", ScenarioTestHelpers.TestTimeout));

            // *** VALIDATE *** \\
            Assert.True(clientReceiver.ServerLog.Count > 0,
                        "The logging done by the Server was not returned via the Callback.");

            // *** CLEANUP *** \\
            ((ICommunicationObject)client).Close();
            channelFactory.Close();
        }
        finally
        {
            // *** ENSURE CLEANUP *** \\ 
            ScenarioTestHelpers.CloseCommunicationObjects((ICommunicationObject)client, channelFactory);
        }
    }
Esempio n. 5
0
    public static void WebSocket_Https_Duplex_Streamed(NetHttpMessageEncoding messageEncoding)
    {
        string          endpointAddress;
        NetHttpsBinding binding        = null;
        ClientReceiver  clientReceiver = null;
        InstanceContext context        = null;
        DuplexChannelFactory <IWSDuplexService> channelFactory = null;
        IWSDuplexService     client       = null;
        FlowControlledStream uploadStream = null;

        try
        {
            // *** SETUP *** \\
            binding = new NetHttpsBinding()
            {
                MaxReceivedMessageSize = ScenarioTestHelpers.SixtyFourMB,
                MaxBufferSize          = ScenarioTestHelpers.SixtyFourMB,
            };
            binding.WebSocketSettings.TransportUsage = WebSocketTransportUsage.Always;
            binding.TransferMode    = TransferMode.Streamed;
            binding.MessageEncoding = messageEncoding;

            clientReceiver  = new ClientReceiver();
            context         = new InstanceContext(clientReceiver);
            endpointAddress = Endpoints.WebSocketHttpsDuplexStreamed_Address + Enum.GetName(typeof(NetHttpMessageEncoding), messageEncoding);
            channelFactory  = new DuplexChannelFactory <IWSDuplexService>(context, binding, endpointAddress);
            client          = channelFactory.CreateChannel();

            // *** EXECUTE *** \\
            using (Stream stream = client.DownloadStream())
            {
                int readResult;
                // Read from the stream, 1000 bytes at a time.
                byte[] buffer = new byte[1000];
                do
                {
                    readResult = stream.Read(buffer, 0, buffer.Length);
                }while (readResult != 0);
            }

            uploadStream = new FlowControlledStream();
            uploadStream.ReadThrottle   = TimeSpan.FromMilliseconds(500);
            uploadStream.StreamDuration = TimeSpan.FromSeconds(1);

            client.UploadStream(uploadStream);
            client.StartPushingStream();
            // Wait for the callback to get invoked before telling the service to stop streaming.
            // This ensures we can read from the stream on the callback while the NCL layer at the service
            // is still writing the bytes from the stream to the wire.
            // This will deadlock if the transfer mode is buffered because the callback will wait for the
            // stream, and the NCL layer will continue to buffer the stream until it reaches the end.

            Assert.True(clientReceiver.ReceiveStreamInvoked.WaitOne(ScenarioTestHelpers.TestTimeout),
                        String.Format("Test case timeout was reached while waiting for the stream response from the Service. Timeout was: {0}", ScenarioTestHelpers.TestTimeout));
            clientReceiver.ReceiveStreamInvoked.Reset();

            // Upload the stream while we are downloading a different stream
            uploadStream = new FlowControlledStream();
            uploadStream.ReadThrottle   = TimeSpan.FromMilliseconds(500);
            uploadStream.StreamDuration = TimeSpan.FromSeconds(1);
            client.UploadStream(uploadStream);

            client.StopPushingStream();
            // Waiting on ReceiveStreamCompleted from the ClientReceiver.
            Assert.True(clientReceiver.ReceiveStreamCompleted.WaitOne(ScenarioTestHelpers.TestTimeout),
                        String.Format("Test case timeout was reached while waiting for the stream response from the Service to be completed. Timeout was: {0}", ScenarioTestHelpers.TestTimeout));
            clientReceiver.ReceiveStreamCompleted.Reset();

            // Getting results from server via callback.
            client.GetLog();
            Assert.True(clientReceiver.LogReceived.WaitOne(ScenarioTestHelpers.TestTimeout),
                        String.Format("Test case timeout was reached while waiting for the Logging from the Service to be received. Timeout was: {0}", ScenarioTestHelpers.TestTimeout));

            // *** VALIDATE *** \\
            Assert.True(clientReceiver.ServerLog.Count > 0,
                        "The logging done by the Server was not returned via the Callback.");

            // *** CLEANUP *** \\
            ((ICommunicationObject)client).Close();
            channelFactory.Close();
        }
        finally
        {
            // *** ENSURE CLEANUP *** \\
            ScenarioTestHelpers.CloseCommunicationObjects((ICommunicationObject)client, channelFactory);
            clientReceiver.Dispose();
        }
    }
Esempio n. 6
0
    public static void NetTcp_TransportSecurity_Streamed_MultipleReads()
    {
#if FULLXUNIT_NOTSUPPORTED
        bool root_Certificate_Installed       = Root_Certificate_Installed();
        bool client_Certificate_Installed     = Client_Certificate_Installed();
        bool windows_Authentication_Available = Windows_Authentication_Available();
        bool ambient_Credentials_Available    = Ambient_Credentials_Available();

        if (!root_Certificate_Installed ||
            !client_Certificate_Installed ||
            !windows_Authentication_Available ||
            !ambient_Credentials_Available)
        {
            Console.WriteLine("---- Test SKIPPED --------------");
            Console.WriteLine("Attempting to run the test in ToF, a ConditionalFact evaluated as FALSE.");
            Console.WriteLine("Root_Certificate_Installed evaluated as {0}", root_Certificate_Installed);
            Console.WriteLine("Client_Certificate_Installed evaluated as {0}", client_Certificate_Installed);
            Console.WriteLine("Windows_Authentication_Available evaluated as {0}", windows_Authentication_Available);
            Console.WriteLine("Ambient_Credentials_Available evaluated as {0}", ambient_Credentials_Available);
            return;
        }
#endif
        string        testString             = ScenarioTestHelpers.CreateInterestingString(20001);
        NetTcpBinding binding                = null;
        ChannelFactory <IWcfService> factory = null;
        IWcfService serviceProxy             = null;
        Stream      stream = null;

        try
        {
            // *** SETUP *** \\
            binding = new NetTcpBinding(SecurityMode.Transport);
            binding.TransferMode = TransferMode.Streamed;
            factory      = new ChannelFactory <IWcfService>(binding, new EndpointAddress(Endpoints.Tcp_Transport_Security_Streamed_Address));
            serviceProxy = factory.CreateChannel();
            stream       = StringToStream(testString);

            // *** EXECUTE *** \\
            var returnStream = serviceProxy.EchoStream(stream);
            var ms           = new MemoryStream((int)stream.Length);
            var buffer       = new byte[10];
            int bytesRead    = 0;
            while ((bytesRead = returnStream.ReadAsync(buffer, 0, buffer.Length).Result) != 0)
            {
                ms.Write(buffer, 0, bytesRead);
            }

            ms.Position = 0;
            var result = StreamToString(ms);

            // *** VALIDATE *** \\
            Assert.Equal(testString, result);

            // *** CLEANUP *** \\
            ((ICommunicationObject)serviceProxy).Close();
            factory.Close();
        }
        finally
        {
            // *** ENSURE CLEANUP *** \\
            ScenarioTestHelpers.CloseCommunicationObjects((ICommunicationObject)serviceProxy, factory);
        }
    }
Esempio n. 7
0
    public static void ClientBaseOfT_Async_Open_Close_TimeSpan_Factory_And_Proxy_CommunicationState()
    {
        MyClientBase         client                   = null;
        IWcfServiceGenerated serviceProxy             = null;
        ChannelFactory <IWcfServiceGenerated> factory = null;
        TimeSpan timeout = ScenarioTestHelpers.TestTimeout;

        try
        {
            // *** SETUP *** \\
            CustomBinding customBinding = new CustomBinding();
            customBinding.Elements.Add(new TextMessageEncodingBindingElement());
            customBinding.Elements.Add(new HttpTransportBindingElement());

            string endpoint = Endpoints.HttpSoap12_Address;
            client  = new MyClientBase(customBinding, new EndpointAddress(endpoint));
            factory = client.ChannelFactory;

            // *** VALIDATE *** \\
            Assert.True(CommunicationState.Created == client.State,
                        String.Format("Expected client state to be Created but actual was '{0}'", client.State));

            Assert.True(CommunicationState.Created == factory.State,
                        String.Format("Expected channel factory state to be Created but actual was '{0}'", factory.State));

            // Note: both the full framework and this NET Core version open the channel factory
            // when asking for the internal channel.  Attempting to Open the ClientBase
            // after obtaining the internal channel with throw InvalidOperationException attempting
            // to reopen the channel factory.  Customers don't encounter this situation in normal use
            // because access to the internal channel is protected and cannot be acquired.  So we
            // defer asking for the internal channel in this test to allow the Open() to follow the
            // same code path as customer code.

            // *** EXECUTE *** \\
            // Explicitly async open the ClientBase to follow general WCF guidelines
            IAsyncResult ar = ((ICommunicationObject)client).BeginOpen(timeout, null, null);
            ((ICommunicationObject)client).EndOpen(ar);

            // Use the internal proxy generated by ClientBase to most resemble how svcutil-generated code works.
            // This test defers asking for it until the ClientBase is open to avoid the issue described above.
            serviceProxy = client.Proxy;

            Assert.True(CommunicationState.Opened == client.State,
                        String.Format("Expected client state to be Opened but actual was '{0}'", client.State));

            Assert.True(CommunicationState.Opened == factory.State,
                        String.Format("Expected channel factory state to be Opened but actual was '{0}'", factory.State));

            Assert.True(CommunicationState.Opened == ((ICommunicationObject)serviceProxy).State,
                        String.Format("Expected proxy state to be Opened but actual was '{0}'", ((ICommunicationObject)serviceProxy).State));

            // *** EXECUTE *** \\
            // Explicitly close the ClientBase to follow general WCF guidelines
            ar = ((ICommunicationObject)client).BeginClose(timeout, null, null);
            ((ICommunicationObject)client).EndClose(ar);

            // *** VALIDATE *** \\
            // Closing the ClientBase closes the internal channel and factory
            Assert.True(CommunicationState.Closed == client.State,
                        String.Format("Expected client state to be Closed but actual was '{0}'", client.State));

            // Closing the ClientBase also closes the internal channel
            Assert.True(CommunicationState.Closed == ((ICommunicationObject)serviceProxy).State,
                        String.Format("Expected proxy state to be Closed but actual was '{0}'", ((ICommunicationObject)serviceProxy).State));

            // Closing the ClientBase also closes the channel factory
            Assert.True(CommunicationState.Closed == factory.State,
                        String.Format("Expected channel factory state to be Closed but actual was '{0}'", factory.State));
        }
        finally
        {
            // *** ENSURE CLEANUP *** \\
            ScenarioTestHelpers.CloseCommunicationObjects((ICommunicationObject)serviceProxy, client, factory);
        }
    }
Esempio n. 8
0
    // Asking for PeerTrust alone should throw SecurityNegotiationException
    // if the certificate is not in the TrustedPeople store.  For this test
    // we use a valid chain-trusted certificate that we know is not in the
    // TrustedPeople store.
    public static void NetTcp_SecModeTrans_CertValMode_PeerTrust_Fails_Not_In_TrustedPeople()
    {
#if FULLXUNIT_NOTSUPPORTED
        bool root_Certificate_Installed   = Root_Certificate_Installed();
        bool client_Certificate_Installed = Client_Certificate_Installed();
        bool peer_Certificate_Installed   = Peer_Certificate_Installed();
        bool ssl_Available = SSL_Available();

        if (!root_Certificate_Installed ||
            !client_Certificate_Installed ||
            !peer_Certificate_Installed ||
            !ssl_Available)
        {
            Console.WriteLine("---- Test SKIPPED --------------");
            Console.WriteLine("Attempting to run the test in ToF, a ConditionalFact evaluated as FALSE.");
            Console.WriteLine("Root_Certificate_Installed evaluated as {0}", root_Certificate_Installed);
            Console.WriteLine("Client_Certificate_Installed evaluated as {0}", client_Certificate_Installed);
            Console.WriteLine("Peer_Certificate_Installed evaluated as {0}", peer_Certificate_Installed);
            Console.WriteLine("SSL_Available evaluated as {0}", ssl_Available);
            return;
        }
#endif
        EndpointAddress endpointAddress               = null;
        string          testString                    = "Hello";
        ChannelFactory <IWcfService> factory          = null;
        IWcfService            serviceProxy           = null;
        CommunicationException communicationException = null;

        try
        {
            // *** SETUP *** \\
            NetTcpBinding binding = new NetTcpBinding(SecurityMode.Transport);
            binding.Security.Transport.ClientCredentialType = TcpClientCredentialType.None;

            endpointAddress = new EndpointAddress(new Uri(
                                                      Endpoints.Tcp_CustomBinding_SslStreamSecurity_Address));

            factory = new ChannelFactory <IWcfService>(binding, endpointAddress);
            factory.Credentials.ServiceCertificate.Authentication.CertificateValidationMode = X509CertificateValidationMode.PeerTrust;

            serviceProxy = factory.CreateChannel();

            // *** EXECUTE *** \\
            try
            {
                serviceProxy.Echo(testString);
            }
            catch (CommunicationException ce)
            {
                communicationException = ce;
            }

            // *** VALIDATE *** \\
            Assert.True(communicationException != null, "Expected CommunicationException but no exception was thrown.");
            Assert.True(communicationException.GetType().Name == "SecurityNegotiationException",
                        String.Format("Expected SecurityNegotiationException but received {0}",
                                      communicationException.ToString()));

            // *** CLEANUP *** \\
            // objects are in faulted state and will throw, so only use finally style cleanup
        }
        finally
        {
            // *** ENSURE CLEANUP *** \\
            ScenarioTestHelpers.CloseCommunicationObjects((ICommunicationObject)serviceProxy, factory);
        }
    }
Esempio n. 9
0
    public static void WebSocketHttpDuplexBinaryStreamed()
    {
        NetHttpBinding  binding        = null;
        ClientReceiver  clientReceiver = null;
        InstanceContext context        = null;
        DuplexChannelFactory <IWSDuplexService> channelFactory = null;
        IWSDuplexService     client       = null;
        FlowControlledStream uploadStream = null;

        try
        {
            // *** SETUP *** \\
            binding = new NetHttpBinding();
            binding.WebSocketSettings.TransportUsage = WebSocketTransportUsage.Always;
            binding.MaxReceivedMessageSize           = ScenarioTestHelpers.DefaultMaxReceivedMessageSize;
            binding.MaxBufferSize   = ScenarioTestHelpers.DefaultMaxReceivedMessageSize;
            binding.TransferMode    = TransferMode.Streamed;
            binding.MessageEncoding = NetHttpMessageEncoding.Binary;

            clientReceiver = new ClientReceiver();
            context        = new InstanceContext(clientReceiver);

            channelFactory = new DuplexChannelFactory <IWSDuplexService>(context, binding, Endpoints.WebSocketHttpDuplexBinaryStreamed_Address);
            client         = channelFactory.CreateChannel();

            // *** EXECUTE *** \\
            using (Stream stream = client.DownloadStream())
            {
                int readResult;
                // Read from the stream, 1000 bytes at a time.
                byte[] buffer = new byte[1000];
                do
                {
                    readResult = stream.Read(buffer, 0, buffer.Length);
                }while (readResult != 0);
            }

            uploadStream = new FlowControlledStream();
            uploadStream.ReadThrottle   = TimeSpan.FromMilliseconds(500);
            uploadStream.StreamDuration = TimeSpan.FromSeconds(1);

            client.UploadStream(uploadStream);
            client.StartPushingStream();
            // Wait for the callback to get invoked before telling the service to stop streaming.
            // This ensures we can read from the stream on the callback while the NCL layer at the service
            // is still writing the bytes from the stream to the wire.
            // This will deadlock if the transfer mode is buffered because the callback will wait for the
            // stream, and the NCL layer will continue to buffer the stream until it reaches the end.

            clientReceiver.ReceiveStreamInvoked.WaitOne();
            clientReceiver.ReceiveStreamInvoked.Reset();

            // Upload the stream while we are downloading a different stream
            uploadStream = new FlowControlledStream();
            uploadStream.ReadThrottle   = TimeSpan.FromMilliseconds(500);
            uploadStream.StreamDuration = TimeSpan.FromSeconds(1);
            client.UploadStream(uploadStream);

            client.StopPushingStream();
            // Waiting on ReceiveStreamCompleted from the ClientReceiver.
            clientReceiver.ReceiveStreamCompleted.WaitOne();
            clientReceiver.ReceiveStreamCompleted.Reset();

            // *** VALIDATE *** \\
            // Validation is based on no exceptions being thrown.

            // *** CLEANUP *** \\
            ((ICommunicationObject)client).Close();
            channelFactory.Close();
        }
        finally
        {
            // *** ENSURE CLEANUP *** \\
            ScenarioTestHelpers.CloseCommunicationObjects((ICommunicationObject)client, channelFactory);
            clientReceiver.Dispose();
        }
    }
Esempio n. 10
0
    public static void ClientCertificate_EchoString()
    {
#if FULLXUNIT_NOTSUPPORTED
        bool root_Certificate_Installed   = Root_Certificate_Installed();
        bool client_Certificate_Installed = Client_Certificate_Installed();
        bool server_Accepts_Certificates  = Server_Accepts_Certificates();
        bool ssl_Available = SSL_Available();

        if (!root_Certificate_Installed ||
            !client_Certificate_Installed ||
            !server_Accepts_Certificates ||
            !ssl_Available)
        {
            Console.WriteLine("---- Test SKIPPED --------------");
            Console.WriteLine("Attempting to run the test in ToF, a ConditionalFact evaluated as FALSE.");
            Console.WriteLine("Root_Certificate_Installed evaluated as {0}", root_Certificate_Installed);
            Console.WriteLine("Client_Certificate_Installed evaluated as {0}", client_Certificate_Installed);
            Console.WriteLine("Server_Accepts_Certificates evaluated as {0}", server_Accepts_Certificates);
            Console.WriteLine("SSL_Available evaluated as {0}", ssl_Available);
            return;
        }
#endif
        string          clientCertThumb      = null;
        EndpointAddress endpointAddress      = null;
        string          testString           = "Hello";
        ChannelFactory <IWcfService> factory = null;
        IWcfService serviceProxy             = null;

        try
        {
            // *** SETUP *** \\
            BasicHttpsBinding basicHttpsBinding = new BasicHttpsBinding(BasicHttpsSecurityMode.Transport);
            basicHttpsBinding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Certificate;

            endpointAddress = new EndpointAddress(new Uri(Endpoints.Https_ClientCertificateAuth_Address));
            clientCertThumb = ServiceUtilHelper.ClientCertificate.Thumbprint;

            factory = new ChannelFactory <IWcfService>(basicHttpsBinding, endpointAddress);
            factory.Credentials.ClientCertificate.SetCertificate(
                StoreLocation.CurrentUser,
                StoreName.My,
                X509FindType.FindByThumbprint,
                clientCertThumb);

            serviceProxy = factory.CreateChannel();

            // *** EXECUTE *** \\
            string result = serviceProxy.Echo(testString);

            // *** VALIDATE *** \\
            Assert.Equal(testString, result);

            // *** CLEANUP *** \\
            ((ICommunicationObject)serviceProxy).Close();
            factory.Close();
        }
        finally
        {
            // *** ENSURE CLEANUP *** \\
            ScenarioTestHelpers.CloseCommunicationObjects((ICommunicationObject)serviceProxy, factory);
        }
    }
Esempio n. 11
0
    // Asking for ChainTrust only should succeed if the certificate is
    // chain-trusted.
    public static void NetTcp_SecModeTrans_Duplex_Callback_Succeeds()
    {
#if FULLXUNIT_NOTSUPPORTED
        bool root_Certificate_Installed   = Root_Certificate_Installed();
        bool client_Certificate_Installed = Client_Certificate_Installed();
        bool ssl_Available = SSL_Available();

        if (!root_Certificate_Installed ||
            !client_Certificate_Installed ||
            !ssl_Available)
        {
            Console.WriteLine("---- Test SKIPPED --------------");
            Console.WriteLine("Attempting to run the test in ToF, a ConditionalFact evaluated as FALSE.");
            Console.WriteLine("Root_Certificate_Installed evaluated as {0}", root_Certificate_Installed);
            Console.WriteLine("Client_Certificate_Installed evaluated as {0}", client_Certificate_Installed);
            Console.WriteLine("SSL_Available evaluated as {0}", ssl_Available);
            return;
        }
#endif
        string          clientCertThumb = null;
        EndpointAddress endpointAddress = null;
        DuplexChannelFactory <IWcfDuplexService> factory = null;
        IWcfDuplexService serviceProxy = null;
        Guid guid = Guid.NewGuid();

        try
        {
            // *** SETUP *** \\
            NetTcpBinding binding = new NetTcpBinding(SecurityMode.Transport);
            binding.Security.Transport.ClientCredentialType = TcpClientCredentialType.Certificate;

            endpointAddress = new EndpointAddress(new Uri(
                                                      Endpoints.Tcp_Certificate_Duplex_Address));
            clientCertThumb = ServiceUtilHelper.ClientCertificate.Thumbprint;

            WcfDuplexServiceCallback callbackService = new WcfDuplexServiceCallback();
            InstanceContext          context         = new InstanceContext(callbackService);

            factory = new DuplexChannelFactory <IWcfDuplexService>(context, binding, endpointAddress);
            factory.Credentials.ServiceCertificate.Authentication.CertificateValidationMode = X509CertificateValidationMode.ChainTrust;
            factory.Credentials.ClientCertificate.SetCertificate(
                StoreLocation.CurrentUser,
                StoreName.My,
                X509FindType.FindByThumbprint,
                clientCertThumb);

            serviceProxy = factory.CreateChannel();

            // *** EXECUTE *** \\
            // Ping on another thread.
            Task.Run(() => serviceProxy.Ping(guid));
            Guid returnedGuid = callbackService.CallbackGuid;

            // *** VALIDATE *** \\
            Assert.True(guid == returnedGuid,
                        string.Format("The sent GUID does not match the returned GUID. Sent '{0}', Received: '{1}'", guid, returnedGuid));

            // *** CLEANUP *** \\
            ((ICommunicationObject)serviceProxy).Close();
            ((ICommunicationObject)factory).Close();
        }
        finally
        {
            // *** ENSURE CLEANUP *** \\
            ScenarioTestHelpers.CloseCommunicationObjects((ICommunicationObject)serviceProxy, factory);
        }
    }
Esempio n. 12
0
    public static void BasicHttp_Streamed_Async_Delayed_And_Aborted_Request_Throws_TimeoutException()
    {
        // This test is a regression test that verifies an issue discovered where exceeding the timeout
        // and aborting the channel before the client's Task completed led to incorrect error handling.
        BasicHttpBinding             binding = null;
        ChannelFactory <IWcfService> factory = null;
        IWcfService serviceProxy             = null;
        Stream      stream        = null;
        int         sendTimeoutMs = 3000;

        try
        {
            // *** SETUP *** \\
            binding = new BasicHttpBinding(BasicHttpSecurityMode.None);
            binding.TransferMode = TransferMode.Streamed;
            binding.SendTimeout  = TimeSpan.FromMilliseconds(sendTimeoutMs);
            factory      = new ChannelFactory <IWcfService>(binding, new EndpointAddress(Endpoints.HttpBaseAddress_Basic));
            serviceProxy = factory.CreateChannel();

            // Create a read stream that will both timeout and then abort the proxy channel when the
            // async read is called. We also intercept the synchronous read because that path can also
            // be executed during an async read.
            stream = new TestMockStream()
            {
                CopyToAsyncFunc = (Stream destination, int bufferSize, CancellationToken ct) =>
                {
                    // Abort to force the internal HttpClientChannelAsyncRequest.Cleanup()
                    // to clear its data structures before the client's Task completes.
                    Task.Delay(sendTimeoutMs * 2).Wait();
                    ((ICommunicationObject)serviceProxy).Abort();
                    return(null);
                },

                ReadFunc = (byte[] buffer, int offset, int count) =>
                {
                    // Abort to force the internal HttpClientChannelAsyncRequest.Cleanup()
                    // to clear its data structures before the client's Task completes.
                    Task.Delay(sendTimeoutMs * 2).Wait();
                    ((ICommunicationObject)serviceProxy).Abort();
                    return(-1);
                }
            };

            // *** EXECUTE *** \\
            Assert.Throws <TimeoutException>(() =>
            {
                var unused = serviceProxy.EchoStreamAsync(stream).GetAwaiter().GetResult();
            });

            // *** VALIDATE *** \\

            // *** CLEANUP *** \\
            ((ICommunicationObject)serviceProxy).Close();
            factory.Close();
        }
        finally
        {
            // *** ENSURE CLEANUP *** \\
            ScenarioTestHelpers.CloseCommunicationObjects((ICommunicationObject)serviceProxy, factory);
        }
    }
    public static void ChannelShape_TypedProxy_InvokeIRequestChannelAsync()
    {
        CustomBinding customBinding = null;
        ChannelFactory <IRequestChannel> factory = null;
        EndpointAddress endpointAddress          = null;
        IRequestChannel channel            = null;
        Message         requestMessage     = null;
        Message         replyMessage       = null;
        string          replyMessageAction = null;
        string          actualResponse     = null;

        try
        {
            // *** SETUP *** \\
            customBinding = new CustomBinding(new BindingElement[] {
                new TextMessageEncodingBindingElement(MessageVersion.Default, Encoding.UTF8),
                new HttpTransportBindingElement()
            });
            endpointAddress = new EndpointAddress(Endpoints.DefaultCustomHttp_Address);
            // Create the channel factory for the request-reply message exchange pattern.
            factory = new ChannelFactory <IRequestChannel>(customBinding, endpointAddress);
            // Create the channel.
            channel = factory.CreateChannel();
            channel.Open();
            // Create the Message object to send to the service.
            requestMessage = Message.CreateMessage(
                customBinding.MessageVersion,
                action,
                new CustomBodyWriter(clientMessage));
            string expectedResponse = "[client] This is my request.[service] Request received, this is my Reply.";

            // *** EXECUTE *** \\
            // Send the Message and receive the Response.
            IAsyncResult ar = channel.BeginRequest(requestMessage, null, null);
            replyMessage       = channel.EndRequest(ar);
            replyMessageAction = replyMessage.Headers.Action;

            // *** VALIDATE *** \\
            Assert.True(String.Equals(replyMessageAction, action + "Response"),
                        String.Format("A response was received from the Service but it was not the expected Action, expected: {0} actual: {1}",
                                      action + "Response", replyMessageAction));

            // *** EXECUTE *** \\
            var replyReader = replyMessage.GetReaderAtBodyContents();
            actualResponse = replyReader.ReadElementContentAsString();

            // *** VALIDATE *** \\
            Assert.True(String.Equals(actualResponse, expectedResponse),
                        String.Format("Actual MessageBodyContent from service did not match the expected MessageBodyContent, expected: {0} actual: {1}",
                                      expectedResponse, actualResponse));

            // *** CLEANUP *** \\
            replyMessage.Close();
            channel.Close();
            factory.Close();
        }
        finally
        {
            // *** ENSURE CLEANUP *** \\
            replyMessage.Close();
            ScenarioTestHelpers.CloseCommunicationObjects(channel, factory);
        }
    }
Esempio n. 14
0
    public static void MustUnderstand_False_TrueNegative_TruePositive()
    {
        // When a Message arrives it travels through the WCF stack at the end of which it is passed to the ServiceModel layer.
        // The MustUnderstand property for every header in the Message is either true or false.
        // At the end of the stack a check is done, every header with MustUnderstand set to "true" must be found in the...
        // UnderstoodHeaders collection.

        // This test makes three calls to a service opration.
        // The service operation creates a MessageHeader using data passed to it in the call.
        // Each call validates a scenario variation.

        UnderstoodHeadersInspector          inspector = null;
        ChannelFactory <IUnderstoodHeaders> factory   = null;
        BasicHttpBinding   binding = null;
        IUnderstoodHeaders proxy   = null;

        // *** SETUP *** \\
        binding   = new BasicHttpBinding();
        factory   = new ChannelFactory <IUnderstoodHeaders>(binding, new EndpointAddress(Endpoints.UnderstoodHeaders));
        inspector = new UnderstoodHeadersInspector();
        factory.Endpoint.EndpointBehaviors.Add(inspector);
        proxy = factory.CreateChannel();

        // ***  EXECUTE 1st Variation *** \\
        // Custom header with MustUnderstand set to "false", this should just work.
        try
        {
            proxy.CreateMessageHeader(customHeaderMustUnderstand_False.Name, customHeaderMustUnderstand_False.Namespace, customHeaderMustUnderstand_False.MustUnderstand);
        }
        finally
        {
            // *** ENSURE CLEANUP *** \\
            ScenarioTestHelpers.CloseCommunicationObjects((ICommunicationObject)proxy);
        }

        // ***  EXECUTE 2nd Variation *** \\
        // Custom header with MustUnderstand set to "true" this should result in an exception since nothing...
        // on the client side stack is adding this header to UnderstoodHeaders.
        Assert.Throws <ProtocolException>(() =>
        {
            try
            {
                proxy = factory.CreateChannel();
                proxy.CreateMessageHeader(customHeaderMustUnderstand_True.Name, customHeaderMustUnderstand_True.Namespace, customHeaderMustUnderstand_True.MustUnderstand);
            }
            finally
            {
                // *** ENSURE CLEANUP *** \\
                ScenarioTestHelpers.CloseCommunicationObjects((ICommunicationObject)proxy);
            }
        });

        // ***  EXECUTE 3d Variation *** \\
        // Custom header with MustUnderstand set to "True", this should pass because...
        // we are using a Message Inspector to add the header to UnderstoodHeaders.
        // This mimics the scenario where the client was expecting this header, did what it needed to do...
        // and then added it to the UnderstoodHeaders collection as confirmation that it was handled.
        try
        {
            proxy = factory.CreateChannel();
            inspector.DoNothing = false;
            proxy.CreateMessageHeader(customHeaderMustUnderstand_True.Name, customHeaderMustUnderstand_True.Namespace, customHeaderMustUnderstand_True.MustUnderstand);
        }
        finally
        {
            // *** ENSURE CLEANUP *** \\
            ScenarioTestHelpers.CloseCommunicationObjects((ICommunicationObject)proxy, factory);
        }
    }
    public static void BasicAuthenticationInvalidPwd_throw_MessageSecurityException()
    {
        BasicHttpBinding basicHttpBinding = null;
        ChannelFactory <IWcfCustomUserNameService> factory = null;
        EndpointAddress           endpointAddress          = null;
        string                    username     = null;
        string                    password     = null;
        IWcfCustomUserNameService serviceProxy = null;
        string                    testString   = null;
        // Will need to use localized string once it is available
        // On Native retail, the message is stripped to 'HttpAuthorizationForbidden, Basic'
        // On Debug or .Net Core, the entire message is "The HTTP request was forbidden with client authentication scheme 'Basic'."
        // Thus we will only check message contains "forbidden"
        string message = "forbidden";

        // *** VALIDATE *** \\
        MessageSecurityException exception = Assert.Throws <MessageSecurityException>(() =>
        {
            // *** SETUP *** \\
            basicHttpBinding = new BasicHttpBinding(BasicHttpSecurityMode.Transport);
            basicHttpBinding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Basic;
            endpointAddress = new EndpointAddress(Endpoints.Https_BasicAuth_Address);
            factory         = new ChannelFactory <IWcfCustomUserNameService>(basicHttpBinding, endpointAddress);
            username        = Guid.NewGuid().ToString("n").Substring(0, 8);
            password        = Guid.NewGuid().ToString("n").Substring(0, 16);
            factory.Credentials.UserName.UserName = username;
            factory.Credentials.UserName.Password = password + "Invalid";
            serviceProxy = factory.CreateChannel();
            testString   = "I am a test";

            // *** EXECUTE *** \\
            using (var scope = new OperationContextScope((IContextChannel)serviceProxy))
            {
                HttpRequestMessageProperty requestMessageProperty;
                if (!OperationContext.Current.OutgoingMessageProperties.ContainsKey(HttpRequestMessageProperty.Name))
                {
                    requestMessageProperty = new HttpRequestMessageProperty();
                    OperationContext.Current.OutgoingMessageProperties[HttpRequestMessageProperty.Name] = requestMessageProperty;
                }
                else
                {
                    requestMessageProperty = (HttpRequestMessageProperty)OperationContext.Current.OutgoingMessageProperties[HttpRequestMessageProperty.Name];
                }

                requestMessageProperty.Headers[BasicUsernameHeaderName] = username;
                requestMessageProperty.Headers[BasicPasswordHeaderName] = password;

                try
                {
                    string result = serviceProxy.Echo(testString);
                }
                finally
                {
                    // *** ENSURE CLEANUP *** \\
                    ScenarioTestHelpers.CloseCommunicationObjects((ICommunicationObject)serviceProxy, factory);
                }
            }
        });

        // *** ADDITIONAL VALIDATION *** \\
        Assert.True(exception.Message.ToLower().Contains(message), string.Format("Expected exception message to contain: '{0}', actual message is: '{1}'", message, exception.Message));
    }
    public static void Certificate_With_CanonicalName_Fqdn_Address_EchoString()
    {
        bool shouldCallSucceed     = false;
        var  domainNameEndpointUri = new Uri(Endpoints.Tcp_ClientCredentialType_Certificate_With_CanonicalName_DomainName_Address);
        // Get just the hostname part of the domainName Uri
        var domainNameHost = domainNameEndpointUri.Host.Split('.')[0];

        var fqdnEndpointUri = new Uri(Endpoints.Tcp_ClientCredentialType_Certificate_With_CanonicalName_Fqdn_Address);
        var endpointAddress = new EndpointAddress(fqdnEndpointUri);

        // If the WCF service's reported FQDN is the same as the services's reported hostname,
        // it means that there the WCF service is set up on a network where FQDNs aren't used, only hostnames.
        // Since our pass/fail detection logic on whether or not this is an FQDN depends on whether the host name has a '.', we don't test this case
        if (string.Compare(domainNameHost, fqdnEndpointUri.Host, StringComparison.OrdinalIgnoreCase) != 0)
        {
            shouldCallSucceed = fqdnEndpointUri.Host.IndexOf('.') > -1;
        }


        string testString = "Hello";
        ChannelFactory <IWcfService> factory = null;
        IWcfService serviceProxy             = null;

        try
        {
            // *** SETUP *** \\
            NetTcpBinding binding = new NetTcpBinding(SecurityMode.Transport);
            binding.Security.Transport.ClientCredentialType = TcpClientCredentialType.None;

            factory = new ChannelFactory <IWcfService>(binding, endpointAddress);
            factory.Credentials.ServiceCertificate.Authentication.RevocationMode            = X509RevocationMode.NoCheck;
            factory.Credentials.ServiceCertificate.Authentication.CertificateValidationMode = X509CertificateValidationMode.ChainTrust;

            serviceProxy = factory.CreateChannel();

            // *** EXECUTE *** \\
            string result = serviceProxy.Echo(testString);

            // *** VALIDATE *** \\
            Assert.Equal(testString, result);

            // *** CLEANUP *** \\
            ((ICommunicationObject)serviceProxy).Close();
            factory.Close();

            var errorBuilder = new StringBuilder();
            errorBuilder.AppendFormat("The call to '{0}' should have failed but succeeded. ", fqdnEndpointUri.Host);
            errorBuilder.AppendFormat("This means that the certificate validation passed when it should have failed. ");
            errorBuilder.AppendFormat("Check the certificate returned by the endpoint at '{0}' ", fqdnEndpointUri);
            errorBuilder.AppendFormat("to see that it is correct; if it is, there is likely an issue with the identity checking logic.");

            Assert.True(shouldCallSucceed, errorBuilder.ToString());
        }
        catch (MessageSecurityException exception)
        {
            // If there's a MessageSecurityException, we assume that the cert validation failed. Unfortunately checking for the
            // message is really brittle and we can't account for loc and how .NET Native will display the exceptions
            // The exception message should look like:
            //
            // System.ServiceModel.Security.MessageSecurityException : Identity check failed for outgoing message. The expected
            // DNS identity of the remote endpoint was 'localhost' but the remote endpoint provided DNS claim 'example.com'.If this
            // is a legitimate remote endpoint, you can fix the problem by explicitly specifying DNS identity 'example.com' as
            // the Identity property of EndpointAddress when creating channel proxy.

            var errorBuilder = new StringBuilder();
            errorBuilder.AppendFormat("The call to '{0}' should have been successful but failed with a MessageSecurityException. ", fqdnEndpointUri.Host);
            errorBuilder.AppendFormat("This usually means that the certificate validation failed when it should have passed. ");
            errorBuilder.AppendFormat("When connecting to host '{0}', the expectation is that the DNSClaim will be for the same hostname. ", fqdnEndpointUri.Host);
            errorBuilder.AppendFormat("Exception message: {0}{1}", Environment.NewLine, exception.Message);

            Assert.True(!shouldCallSucceed, errorBuilder.ToString());
        }
        finally
        {
            // *** ENSURE CLEANUP *** \\
            ScenarioTestHelpers.CloseCommunicationObjects((ICommunicationObject)serviceProxy, factory);
        }
    }
Esempio n. 17
0
    public static void ServiceRestart_Throws_CommunicationException()
    {
        // This test validates that if the Service were to shut-down, re-start or otherwise die in the
        // middle of an operation the client will not just hang. It should instead receive a CommunicationException.
        string restartServiceAddress = "";
        ChannelFactory <IWcfService> setupHostFactory = null;
        IWcfService setupHostServiceProxy             = null;
        ChannelFactory <IWcfRestartService> factory   = null;
        IWcfRestartService serviceProxy = null;
        BasicHttpBinding   binding      = new BasicHttpBinding();

        // *** Step 1 *** \\
        // We need the Service to create and open a ServiceHost and then give us the endpoint address for it.
        try
        {
            setupHostFactory      = new ChannelFactory <IWcfService>(binding, new EndpointAddress(Endpoints.HttpBaseAddress_Basic));
            setupHostServiceProxy = setupHostFactory.CreateChannel();
            restartServiceAddress = setupHostServiceProxy.GetRestartServiceEndpoint();

            // *** CLEANUP *** \\
            ((ICommunicationObject)setupHostServiceProxy).Close();
            setupHostFactory.Close();
        }
        finally
        {
            // *** ENSURE CLEANUP *** \\
            ScenarioTestHelpers.CloseCommunicationObjects((ICommunicationObject)setupHostServiceProxy, setupHostFactory);
        }

        // *** Additional Setup *** \\
        // The restartServiceAddress we got from the Service used localhost as the host name.
        // We need the actual host name for the client call to work.
        // To make it easier to parse, localhost was replaced with '[HOST]'.

        // Use Endpoints.HttpBaseAddress_Basic only for the purpose of extracting the Service host name.
        // Then update 'restartServiceAddress' with it.
        string hostName = new Uri(Endpoints.HttpBaseAddress_Basic).Host;

        restartServiceAddress = restartServiceAddress.Replace("[HOST]", hostName);

        // Get the last portion of the restart service url which is a Guid and convert it back to a Guid
        // This is needed by the RestartService operation as a Dictionary key to get the ServiceHost
        string uniqueIdentifier = restartServiceAddress.Substring(restartServiceAddress.LastIndexOf("/") + 1);
        Guid   guid             = new Guid(uniqueIdentifier);

        // *** Step 2 *** \\
        // Simple echo call to make sure the newly created endpoint is working.
        try
        {
            factory      = new ChannelFactory <IWcfRestartService>(binding, new EndpointAddress(restartServiceAddress));
            serviceProxy = factory.CreateChannel();

            // *** EXECUTE *** \\
            string result = serviceProxy.NonRestartService(guid);

            Assert.True(result == "Success!", string.Format("Test Case failed, expected the returned string to be: {0}, instead it was: {1}", "Success!", result));
        }
        catch (Exception ex)
        {
            string exceptionMessage      = ex.Message;
            string innerExceptionMessage = ex.InnerException?.Message;
            string testExceptionMessage  = $"The ping to validate the newly created endpoint failed.\nThe endpoint pinged was: {restartServiceAddress}\nThe GUID used to extract the ServiceHost from the server side dictionary was: {guid}";
            string fullExceptionMessage  = $"testExceptionMessage: {testExceptionMessage}\nexceptionMessage: {exceptionMessage}\ninnerExceptionMessage: {innerExceptionMessage}";

            Assert.True(false, fullExceptionMessage);
        }
        finally
        {
            // *** ENSURE CLEANUP *** \\
            ScenarioTestHelpers.CloseCommunicationObjects((ICommunicationObject)serviceProxy, factory);
        }

        // *** Step 3 *** \\
        // The actual part of the test where the host is killed in the middle of the operation.
        // We expect the test should not hang and should receive a CommunicationException.
        CommunicationException exception = Assert.Throws <CommunicationException>(() =>
        {
            factory      = new ChannelFactory <IWcfRestartService>(binding, new EndpointAddress(restartServiceAddress));
            serviceProxy = factory.CreateChannel();

            try
            {
                // *** EXECUTE *** \\
                serviceProxy.RestartService(guid);
            }
            finally
            {
                // *** ENSURE CLEANUP *** \\
                ScenarioTestHelpers.CloseCommunicationObjects((ICommunicationObject)serviceProxy, factory);
            }
        });
    }
    public static void Certificate_With_CanonicalName_Localhost_Address_EchoString()
    {
        var  localhostEndpointUri = new Uri(Endpoints.Tcp_ClientCredentialType_Certificate_With_CanonicalName_Localhost_Address);
        var  endpointAddress      = new EndpointAddress(localhostEndpointUri);
        bool shouldCallSucceed    = string.Compare(localhostEndpointUri.Host, "localhost", StringComparison.OrdinalIgnoreCase) == 0;

        string testString = "Hello";
        ChannelFactory <IWcfService> factory = null;
        IWcfService serviceProxy             = null;

        try
        {
            // *** SETUP *** \\
            NetTcpBinding binding = new NetTcpBinding(SecurityMode.Transport);
            binding.Security.Transport.ClientCredentialType = TcpClientCredentialType.None;

            factory = new ChannelFactory <IWcfService>(binding, endpointAddress);
            factory.Credentials.ServiceCertificate.Authentication.CertificateValidationMode = X509CertificateValidationMode.ChainTrust;

            serviceProxy = factory.CreateChannel();

            // *** EXECUTE *** \\
            string result = serviceProxy.Echo(testString);

            // *** VALIDATE *** \\
            Assert.Equal(testString, result);

            // *** CLEANUP *** \\
            ((ICommunicationObject)serviceProxy).Close();
            factory.Close();

            var errorBuilder = new StringBuilder();
            errorBuilder.AppendFormat("The call to '{0}' should have failed but succeeded. ", localhostEndpointUri.Host);
            errorBuilder.AppendFormat("This means that the certificate validation passed when it should have failed. ");
            errorBuilder.AppendFormat("Check the certificate returned by the endpoint at '{0}' ", localhostEndpointUri);
            errorBuilder.AppendFormat("to see that it is correct; if it is, there is likely an issue with the identity checking logic.");

            Assert.True(shouldCallSucceed, errorBuilder.ToString());
        }
        catch (Exception exception) when(exception is CommunicationException || exception is MessageSecurityException)
        {
            if ((exception is MessageSecurityException) || (exception is CommunicationException) && !string.Equals(exception.InnerException.GetType().ToString(), "System.ServiceModel.Security.MessageSecurityException"))
            {
                // If there's a MessageSecurityException, we assume that the cert validation failed. Unfortunately checking for the
                // message is really brittle and we can't account for loc and how .NET Native will display the exceptions
                // The exception message should look like:
                //
                // System.ServiceModel.Security.MessageSecurityException : Identity check failed for outgoing message. The expected
                // DNS identity of the remote endpoint was 'localhost' but the remote endpoint provided DNS claim 'example.com'.If this
                // is a legitimate remote endpoint, you can fix the problem by explicitly specifying DNS identity 'example.com' as
                // the Identity property of EndpointAddress when creating channel proxy.

                var errorBuilder = new StringBuilder();
                errorBuilder.AppendFormat("The call to '{0}' should have been successful but failed with a MessageSecurityException. ", localhostEndpointUri.Host);
                errorBuilder.AppendFormat("This usually means that the certificate validation failed when it should have passed. ");
                errorBuilder.AppendFormat("When connecting to host '{0}', the expectation is that the DNSClaim will be for the same hostname. ", localhostEndpointUri.Host);
                errorBuilder.AppendFormat("Exception message: {0}{1}", Environment.NewLine, exception.Message);

                Assert.True(!shouldCallSucceed, errorBuilder.ToString());
            }
        }
        finally
        {
            // *** ENSURE CLEANUP *** \\
            ScenarioTestHelpers.CloseCommunicationObjects((ICommunicationObject)serviceProxy, factory);
        }
    }
Esempio n. 19
0
    public static void NetTcp_TransportSecurity_Streamed_TimeOut_Long_Running_Operation()
    {
#if FULLXUNIT_NOTSUPPORTED
        bool root_Certificate_Installed       = Root_Certificate_Installed();
        bool client_Certificate_Installed     = Client_Certificate_Installed();
        bool windows_Authentication_Available = Windows_Authentication_Available();
        bool ambient_Credentials_Available    = Ambient_Credentials_Available();

        if (!root_Certificate_Installed ||
            !client_Certificate_Installed ||
            !windows_Authentication_Available ||
            !ambient_Credentials_Available)
        {
            Console.WriteLine("---- Test SKIPPED --------------");
            Console.WriteLine("Attempting to run the test in ToF, a ConditionalFact evaluated as FALSE.");
            Console.WriteLine("Root_Certificate_Installed evaluated as {0}", root_Certificate_Installed);
            Console.WriteLine("Client_Certificate_Installed evaluated as {0}", client_Certificate_Installed);
            Console.WriteLine("Windows_Authentication_Available evaluated as {0}", windows_Authentication_Available);
            Console.WriteLine("Ambient_Credentials_Available evaluated as {0}", ambient_Credentials_Available);
            return;
        }
#endif
        string        testString = "Hello";
        NetTcpBinding binding    = null;
        TimeSpan      serviceOperationTimeout = TimeSpan.FromMilliseconds(10000);
        ChannelFactory <IWcfService> factory  = null;
        IWcfService serviceProxy = null;

        try
        {
            // *** SETUP *** \\
            binding = new NetTcpBinding(SecurityMode.Transport);
            binding.TransferMode = TransferMode.Streamed;
            binding.SendTimeout  = TimeSpan.FromMilliseconds(5000);
            factory      = new ChannelFactory <IWcfService>(binding, new EndpointAddress(Endpoints.Tcp_Transport_Security_Streamed_Address));
            serviceProxy = factory.CreateChannel();
            Stopwatch watch = new Stopwatch();
            watch.Start();

            // *** EXECUTE *** \\
            try
            {
                Assert.Throws <TimeoutException>(() =>
                {
                    string returnString = serviceProxy.EchoWithTimeout(testString, serviceOperationTimeout);
                });
            }
            finally
            {
                watch.Stop();

                // *** CLEANUP *** \\
                ((ICommunicationObject)serviceProxy).Close();
                factory.Close();
            }

            // *** VALIDATE *** \\
            // want to assert that this completed in > 5 s as an upper bound since the SendTimeout is 5 sec
            // (usual case is around 5001-5005 ms)
            Assert.True(watch.ElapsedMilliseconds >= 4985 && watch.ElapsedMilliseconds < 6000,
                        String.Format("Expected timeout was {0}ms but actual was {1}ms",
                                      serviceOperationTimeout.TotalMilliseconds,
                                      watch.ElapsedMilliseconds));
        }
        finally
        {
            // *** ENSURE CLEANUP *** \\
            ScenarioTestHelpers.CloseCommunicationObjects((ICommunicationObject)serviceProxy, factory);
        }
    }
Esempio n. 20
0
    public static async Task RetryCountApplied(ReliableMessagingVersion rmVersion, bool ordered, string endpointSuffix)
    {
        ChannelFactory <IWcfReliableService> factory = null;
        IWcfReliableService serviceProxy             = null;
        NetHttpBinding      binding = null;

        try
        {
            // *** SETUP *** \\
            binding = new NetHttpBinding(BasicHttpSecurityMode.None, true);
            binding.ReliableSession.Ordered = ordered;
            var customBinding = new CustomBinding(binding);
            var reliableSessionBindingElement = customBinding.Elements.Find <ReliableSessionBindingElement>();
            reliableSessionBindingElement.MaxRetryCount            = 2;
            reliableSessionBindingElement.ReliableMessagingVersion = rmVersion;
            factory = new ChannelFactory <IWcfReliableService>(customBinding, new EndpointAddress(Endpoints.ReliableSession_NetHttp + endpointSuffix));
            var       handlerFactoryBehavior = new HttpMessageHandlerBehavior();
            bool      delayNextCall          = false;
            int       httpRequestCount       = 0;
            Stopwatch sw = null;
            TaskCompletionSource <object> tcs1 = null, tcs2 = new TaskCompletionSource <object>();
            handlerFactoryBehavior.OnSendingAsync = async(request, token) =>
            {
                Interlocked.Increment(ref httpRequestCount);
                // Once the delayNextCall latch is set, all subsequent calls will be on hold until tcs1 is completed.
                if (delayNextCall)
                {
                    if (tcs1 == null) // First delayed call
                    {
                        sw   = Stopwatch.StartNew();
                        tcs1 = new TaskCompletionSource <object>();
                    }
                    else if (sw.IsRunning)
                    {
                        sw.Stop();               // Get time between initial call and 1st retry
                        tcs2.TrySetResult(null); // Signal main test code that stopwatch measurement taken
                    }
                    // All calls will wait on the same TCS as trying to trigger retry;
                    await tcs1.Task;
                }
                return(null);
            };
            factory.Endpoint.Behaviors.Add(handlerFactoryBehavior);
            serviceProxy = factory.CreateChannel();
            // *** EXECUTE *** \\
            ((IClientChannel)serviceProxy).Open(); // This will establish a reliable session
            delayNextCall = true;
            // Reset request count as it would have incremented in the session open handshake
            httpRequestCount = 0;
            var resultTask = serviceProxy.GetNextNumberAsync();
            await tcs2.Task; // Wait for Stopwatch to be stopped

            // *** VALIDATE *** \\
            // There should only be a single retry at this point
            Assert.Equal(2, httpRequestCount);
            // ReliableSessions doubles the wait time between each retry. We know the first retry time. The second retry
            // will be 2X this, then the request will fail after another wait of 4X this delay. We need to wait at LEAST 6X
            // this initial delay for the channel to fault. 10X should be sufficient
            await Task.Delay((int)sw.ElapsedMilliseconds * 10);

            // There should now be the second retry (3 attempts to send the request) as well as the SequenceTerminated fault
            // making a total of 4 requests
            Assert.Equal(4, httpRequestCount);
            // Release the paused Http requests
            tcs1.TrySetResult(null);
            await Assert.ThrowsAsync <CommunicationException>(() => resultTask);

            Assert.Equal(CommunicationState.Faulted, ((ICommunicationObject)serviceProxy).State);
            ((ICommunicationObject)serviceProxy).Abort(); // Remove from factory so factory doesn't throw when closed.

            // *** CLEANUP *** \\
            factory.Close();
        }
        finally
        {
            // *** ENSURE CLEANUP *** \\
            ScenarioTestHelpers.CloseCommunicationObjects((ICommunicationObject)serviceProxy, factory);
        }
    }
Esempio n. 21
0
    public static void CustomTextMessageEncoder_Http_RequestReply_Streamed()
    {
        // 84K, larger than any buffers, but won't allocate in LOH
        int streamKBytes    = 84;
        int streamLength    = 1024 * streamKBytes;
        int lowestPrintable = ' ';
        int printableRange  = '~' - lowestPrintable;
        ChannelFactory <IWcfService> factory = null;
        IWcfService serviceProxy             = null;
        Stream      stream = null;

        try
        {
            // *** SETUP *** \\
            CustomBinding binding = new CustomBinding(new CustomTextMessageBindingElement(Encoding.UTF8.WebName),
                                                      new HttpTransportBindingElement
            {
                MaxReceivedMessageSize = ScenarioTestHelpers.SixtyFourMB,
                MaxBufferSize          = ScenarioTestHelpers.SixtyFourMB,
                TransferMode           = TransferMode.Streamed
            });

            factory      = new ChannelFactory <IWcfService>(binding, new EndpointAddress(Endpoints.CustomTextEncoderStreamed_Address));
            serviceProxy = factory.CreateChannel();
            byte[] requestBytes       = new byte[streamLength];
            RandomNumberGenerator rnd = RandomNumberGenerator.Create();
            int pos = 0;
            for (int i = 0; i < streamKBytes; i++)
            {
                byte[] tempBuffer = new byte[1024];
                rnd.GetBytes(tempBuffer);
                for (int j = 0; j < 1024; j++)
                {
                    byte val = tempBuffer[j];
                    if (val < ' ' || val > '~')
                    {
                        // Force the value to be between ' ' and '~'
                        int temp1 = val % printableRange;
                        val = (byte)(temp1 + lowestPrintable);
                    }

                    requestBytes[pos++] = val;
                }
            }
            stream = new MemoryStream(requestBytes);

            // *** EXECUTE *** \\
            var returnStream = serviceProxy.EchoStream(stream);

            // *** VALIDATE *** \\
            MemoryStream ms = new MemoryStream(streamLength);
            returnStream.CopyTo(ms);

            Assert.True(streamLength == ms.Length,
                        String.Format("Expected returned stream length = {0}, actual = {1}",
                                      streamLength, ms.Length));

            ArraySegment <byte> returnedByteArraySegment;
            ms.TryGetBuffer(out returnedByteArraySegment);
            Assert.True(requestBytes.SequenceEqual(returnedByteArraySegment.Array), "Returned bytes are different than sent bytes");

            // *** CLEANUP *** \\
            ((ICommunicationObject)serviceProxy).Close();
            factory.Close();
        }
        finally
        {
            // *** ENSURE CLEANUP *** \\
            ScenarioTestHelpers.CloseCommunicationObjects((ICommunicationObject)serviceProxy, factory);
        }
    }
Esempio n. 22
0
    public static async Task MaxTransferWindowSizeApplied(ReliableMessagingVersion rmVersion, bool ordered, string endpointSuffix)
    {
        ChannelFactory <IWcfReliableService> factory = null;
        IWcfReliableService serviceProxy             = null;
        NetHttpBinding      binding    = null;
        string secondRequestHeaderName = "SecondRequest";

        try
        {
            // *** SETUP *** \\
            binding = new NetHttpBinding(BasicHttpSecurityMode.None, true);
            binding.ReliableSession.Ordered = ordered;
            var customBinding = new CustomBinding(binding);
            var reliableSessionBindingElement = customBinding.Elements.Find <ReliableSessionBindingElement>();
            reliableSessionBindingElement.MaxTransferWindowSize    = 1;
            reliableSessionBindingElement.ReliableMessagingVersion = rmVersion;
            factory = new ChannelFactory <IWcfReliableService>(customBinding, new EndpointAddress(Endpoints.ReliableSession_NetHttp + endpointSuffix));
            var  handlerFactoryBehavior = new HttpMessageHandlerBehavior();
            bool delayNextCall = false;
            bool secondRequestSent = false;
            TaskCompletionSource <object> tcs1 = null, tcs2 = new TaskCompletionSource <object>();
            handlerFactoryBehavior.OnSendingAsync = async(request, token) =>
            {
                if (request.Headers.Contains(secondRequestHeaderName))
                {
                    secondRequestSent = true;
                }

                // Once the delayNextCall latch is set, all subsequent calls will be on hold until tcs1 is completed.
                if (delayNextCall)
                {
                    if (tcs1 == null) // First delayed call
                    {
                        tcs1 = new TaskCompletionSource <object>();
                        tcs2.TrySetResult(null); // Signal main test code that first request has been attempted
                    }
                    // All calls will wait on the same TCS as trying to prevent requests progressing;
                    await tcs1.Task;
                }
                return(null);
            };
            factory.Endpoint.Behaviors.Add(handlerFactoryBehavior);
            serviceProxy = factory.CreateChannel();
            // *** EXECUTE *** \\
            ((IClientChannel)serviceProxy).Open(); // This will establish a reliable session
            delayNextCall = true;
            Stopwatch sw = Stopwatch.StartNew();
            var       resultTask1 = serviceProxy.GetNextNumberAsync();
            await tcs2.Task; // Wait for first http request to be attempted
            sw.Stop();
            Task <int> resultTask2;
            using (var scope = new OperationContextScope((IContextChannel)serviceProxy))
            {
                // Add marker to second request so we can check if it's been seen by handler
                var httpRequestMessageProperty = new HttpRequestMessageProperty();
                httpRequestMessageProperty.Headers.Add(secondRequestHeaderName, secondRequestHeaderName);
                OperationContext.Current.OutgoingMessageProperties.Add(HttpRequestMessageProperty.Name, httpRequestMessageProperty);
                resultTask2 = serviceProxy.GetNextNumberAsync();
            }

            // Wait 6 times the amount of time it took for the first http request to be made to ensure we've allowed
            // enough time that the second request should have happened by now.
            await Task.Delay((int)sw.ElapsedMilliseconds * 6);

            var secondRequestBlocked = !secondRequestSent;
            tcs1.TrySetResult(null); // Release first request
            int result1 = await resultTask1;
            int result2 = await resultTask2;

            // *** VALIDATE *** \\
            Assert.Equal(1, result1);
            Assert.Equal(2, result2);
            Assert.True(secondRequestBlocked); // Captured before releasing the first request
            Assert.True(secondRequestSent);    // Validate that header was seen

            // *** CLEANUP *** \\
            ((ICommunicationObject)serviceProxy).Close();
            factory.Close();
        }
        finally
        {
            // *** ENSURE CLEANUP *** \\
            ScenarioTestHelpers.CloseCommunicationObjects((ICommunicationObject)serviceProxy, factory);
        }
    }
Esempio n. 23
0
    public static void Abort_During_Implicit_Open_Closes_Async_Waiters()
    {
        // This test is a regression test of an issue with CallOnceManager.
        // When a single proxy is used to make several service calls without
        // explicitly opening it, the CallOnceManager queues up all the requests
        // that happen while it is opening the channel (or handling previously
        // queued service calls.  If the channel was closed or faulted during
        // the handling of any queued requests, it caused a pathological worst
        // case where every queued request waited for its complete SendTimeout
        // before failing.
        //
        // This test operates by making multiple concurrent asynchronous service
        // calls, but stalls the Opening event to allow them to be queued before
        // any of them are allowed to proceed.  It then closes the channel when
        // the first service operation is allowed to proceed.  This causes the
        // CallOnce manager to deal with all its queued operations and cause
        // them to complete other than by timing out.

        BasicHttpBinding             binding = null;
        ChannelFactory <IWcfService> factory = null;
        IWcfService serviceProxy             = null;
        int         timeoutMs        = 20000;
        long        operationsQueued = 0;
        int         operationCount   = 5;

        Task <string>[] tasks               = new Task <string> [operationCount];
        Exception[]     exceptions          = new Exception[operationCount];
        string[]        results             = new string[operationCount];
        bool            isClosed            = false;
        DateTime        endOfOpeningStall   = DateTime.Now;
        int             serverDelayMs       = 100;
        TimeSpan        serverDelayTimeSpan = TimeSpan.FromMilliseconds(serverDelayMs);
        string          testMessage         = "testMessage";

        try
        {
            // *** SETUP *** \\
            binding = new BasicHttpBinding(BasicHttpSecurityMode.None);
            binding.TransferMode = TransferMode.Streamed;
            // SendTimeout is the timeout used for implicit opens
            binding.SendTimeout = TimeSpan.FromMilliseconds(timeoutMs);
            factory             = new ChannelFactory <IWcfService>(binding, new EndpointAddress(Endpoints.HttpBaseAddress_Basic));
            serviceProxy        = factory.CreateChannel();

            // Force the implicit open to stall until we have multiple concurrent calls pending.
            // This forces the CallOnceManager to have a queue of waiters it will need to notify.
            ((ICommunicationObject)serviceProxy).Opening += (s, e) =>
            {
                // Wait until we see sync calls have been queued
                DateTime startOfOpeningStall = DateTime.Now;
                while (true)
                {
                    endOfOpeningStall = DateTime.Now;

                    // Don't wait forever -- if we stall longer than the SendTimeout, it means something
                    // is wrong other than what we are testing, so just fail early.
                    if ((endOfOpeningStall - startOfOpeningStall).TotalMilliseconds > timeoutMs)
                    {
                        Assert.True(false, "The Opening event timed out waiting for operations to queue, which was not expected for this test.");
                    }

                    // As soon as we have all our Tasks at least running, wait a little
                    // longer to allow them finish queuing up their waiters, then stop stalling the Opening
                    if (Interlocked.Read(ref operationsQueued) >= operationCount)
                    {
                        Task.Delay(500).Wait();
                        endOfOpeningStall = DateTime.Now;
                        return;
                    }

                    Task.Delay(100).Wait();
                }
            };

            // Each task will make a synchronous service call, which will cause all but the
            // first to be queued for the implicit open.  The first call to complete then closes
            // the channel so that it is forced to deal with queued waiters.
            Func <string> callFunc = () =>
            {
                // We increment the # ops queued before making the actual sync call, which is
                // technically a short race condition in the test.  But reversing the order would
                // timeout the implicit open and fault the channel.
                Interlocked.Increment(ref operationsQueued);

                // The call of the operation is what creates the entry in the CallOnceManager queue.
                // So as each Task below starts, it increments the count and adds a waiter to the
                // queue.  We ask for a small delay on the server side just to introduce a small
                // stall after the sync request has been made before it can complete.  Otherwise
                // fast machines can finish all the requests before the first one finishes the Close().
                Task <string> t = serviceProxy.EchoWithTimeoutAsync(testMessage, serverDelayTimeSpan);
                lock (tasks)
                {
                    if (!isClosed)
                    {
                        try
                        {
                            isClosed = true;
                            ((ICommunicationObject)serviceProxy).Abort();
                        }
                        catch { }
                    }
                }
                return(t.GetAwaiter().GetResult());
            };

            // *** EXECUTE *** \\

            DateTime startTime = DateTime.Now;
            for (int i = 0; i < operationCount; ++i)
            {
                tasks[i] = Task.Run(callFunc);
            }

            for (int i = 0; i < operationCount; ++i)
            {
                try
                {
                    results[i] = tasks[i].GetAwaiter().GetResult();
                }
                catch (Exception ex)
                {
                    exceptions[i] = ex;
                }
            }

            // *** VALIDATE *** \\
            double elapsedMs = (DateTime.Now - endOfOpeningStall).TotalMilliseconds;

            // Before validating that the issue was fixed, first validate that we received the exceptions or the
            // results we expected. This is to verify the fix did not introduce a behavioral change other than the
            // elimination of the long unnecessary timeouts after the channel was closed.
            int nFailures = 0;
            for (int i = 0; i < operationCount; ++i)
            {
                if (exceptions[i] == null)
                {
                    Assert.True((String.Equals("test", results[i])),
                                String.Format("Expected operation #{0} to return '{1}' but actual was '{2}'",
                                              i, testMessage, results[i]));
                }
                else
                {
                    ++nFailures;

                    TimeoutException toe = exceptions[i] as TimeoutException;
                    Assert.True(toe == null, String.Format("Task [{0}] should not have failed with TimeoutException", i));
                }
            }

            Assert.True(nFailures > 0,
                        String.Format("Expected at least one operation to throw an exception, but none did. Elapsed time = {0} ms.",
                                      elapsedMs));


            // --- Here is the test of the actual bug fix ---
            // The original issue was that sync waiters in the CallOnceManager were not notified when
            // the channel became unusable and therefore continued to time out for the full amount.
            // Additionally, because they were executed sequentially, it was also possible for each one
            // to time out for the full amount.  Given that we closed the channel, we expect all the queued
            // waiters to have been immediately waked up and detected failure.
            int expectedElapsedMs = (operationCount * serverDelayMs) + timeoutMs / 2;
            Assert.True(elapsedMs < expectedElapsedMs,
                        String.Format("The {0} operations took {1} ms to complete which exceeds the expected {2} ms",
                                      operationCount, elapsedMs, expectedElapsedMs));

            // *** CLEANUP *** \\
            ((ICommunicationObject)serviceProxy).Close();
            factory.Close();
        }
        finally
        {
            // *** ENSURE CLEANUP *** \\
            ScenarioTestHelpers.CloseCommunicationObjects((ICommunicationObject)serviceProxy, factory);
        }
    }
Esempio n. 24
0
    public static async Task ResendFailedRequest(ReliableMessagingVersion rmVersion, bool ordered, string endpointSuffix)
    {
        ChannelFactory <IWcfReliableService> factory = null;
        IWcfReliableService serviceProxy             = null;
        NetHttpBinding      binding = null;

        try
        {
            // *** SETUP *** \\
            binding = new NetHttpBinding(BasicHttpSecurityMode.None, true);
            binding.ReliableSession.Ordered = ordered;
            var customBinding = new CustomBinding(binding);
            var reliableSessionBindingElement = customBinding.Elements.Find <ReliableSessionBindingElement>();
            reliableSessionBindingElement.ReliableMessagingVersion = rmVersion;
            factory = new ChannelFactory <IWcfReliableService>(customBinding, new EndpointAddress(Endpoints.ReliableSession_NetHttp + endpointSuffix));
            var  handlerFactoryBehavior = new HttpMessageHandlerBehavior();
            bool delayNextCall          = false;
            int  callCount = 0;
            TaskCompletionSource <object> tcs1 = null, tcs2 = null;
            handlerFactoryBehavior.OnSendingAsync = async(request, token) =>
            {
                Interlocked.Increment(ref callCount);
                // Once the delayNextCall latch is set, the next call will be held back until after
                // it has been retried.
                if (delayNextCall)
                {
                    delayNextCall = false;
                    tcs1          = new TaskCompletionSource <object>();
                    await tcs1.Task;
                }
                return(null);
            };
            handlerFactoryBehavior.OnSentAsync = (response, token) =>
            {
                if (tcs2 != null)
                {
                    // Let the main test code know that the original held back call has returned from the service
                    tcs2.TrySetResult(null);
                }
                if (tcs1 != null)
                {
                    // This is the retry of the first service call. Release the held back initial call
                    tcs1.TrySetResult(null);
                    tcs1 = null;
                    tcs2 = new TaskCompletionSource <object>();
                }
                return(Task.FromResult(response));
            };
            factory.Endpoint.Behaviors.Add(handlerFactoryBehavior);
            serviceProxy = factory.CreateChannel();
            // *** EXECUTE *** \\
            ((IClientChannel)serviceProxy).Open(); // This will establish a reliable session
            delayNextCall = true;
            // Reset call count as it would have incremented in the session open handshake
            callCount = 0;
            var result1 = await serviceProxy.GetNextNumberAsync();

            // Wait for the first attempt for first call to complete before making second call
            await tcs2.Task;
            // This check ensures that the sequence number on the retry was the same as the original. If they
            // were different, the call on the retry would have been dispatched on the service and an extra
            // increment would have happened.
            var result2 = await serviceProxy.GetNextNumberAsync();

            // *** VALIDATE *** \\
            Assert.Equal(1, result1);
            Assert.Equal(2, result2);
            // Validate that 3 http calls were made as first call should have retried.
            Assert.Equal(3, callCount);

            // *** CLEANUP *** \\
            ((IClientChannel)serviceProxy).Close();
            factory.Close();
            ((ICommunicationObject)serviceProxy).Close();
        }
        finally
        {
            // *** ENSURE CLEANUP *** \\
            ScenarioTestHelpers.CloseCommunicationObjects((ICommunicationObject)serviceProxy, factory);
        }
    }
Esempio n. 25
0
    public static void WebSocket_Https_Duplex_Buffered(NetHttpMessageEncoding messageEncoding)
    {
        EndpointAddress endpointAddress;
        NetHttpsBinding binding        = null;
        ClientReceiver  clientReceiver = null;
        InstanceContext context        = null;
        DuplexChannelFactory <IWSDuplexService> channelFactory = null;
        IWSDuplexService client = null;

        try
        {
            // *** SETUP *** \\
            binding = new NetHttpsBinding()
            {
                MaxReceivedMessageSize = ScenarioTestHelpers.SixtyFourMB,
                MaxBufferSize          = ScenarioTestHelpers.SixtyFourMB,
            };
            binding.WebSocketSettings.TransportUsage = WebSocketTransportUsage.Always;
            binding.TransferMode    = TransferMode.Buffered;
            binding.MessageEncoding = messageEncoding;

            clientReceiver  = new ClientReceiver();
            context         = new InstanceContext(clientReceiver);
            endpointAddress = new EndpointAddress(Endpoints.WebSocketHttpsDuplexBuffered_Address + Enum.GetName(typeof(NetHttpMessageEncoding), messageEncoding));
            channelFactory  = new DuplexChannelFactory <IWSDuplexService>(context, binding, endpointAddress);
            client          = channelFactory.CreateChannel();

            // *** EXECUTE *** \\
            // Invoking UploadData
            client.UploadData(ScenarioTestHelpers.CreateInterestingString(123));

            // Invoking StartPushingData
            client.StartPushingData();
            Assert.True(clientReceiver.ReceiveDataInvoked.WaitOne(ScenarioTestHelpers.TestTimeout),
                        String.Format("Test case timeout was reached while waiting for the buffered response from the Service. Timeout was: {0}", ScenarioTestHelpers.TestTimeout));
            clientReceiver.ReceiveDataInvoked.Reset();
            // Invoking StopPushingData
            client.StopPushingData();
            Assert.True(clientReceiver.ReceiveDataCompleted.WaitOne(ScenarioTestHelpers.TestTimeout),
                        String.Format("Test case timeout was reached while waiting for the buffered response from the Service to be completed. Timeout was: {0}", ScenarioTestHelpers.TestTimeout));
            clientReceiver.ReceiveDataCompleted.Reset();

            // Getting results from server via callback.
            client.GetLog();
            Assert.True(clientReceiver.LogReceived.WaitOne(ScenarioTestHelpers.TestTimeout),
                        String.Format("Test case timeout was reached while waiting for the Logging from the Service to be received. Timeout was: {0}", ScenarioTestHelpers.TestTimeout));

            // *** VALIDATE *** \\
            Assert.True(clientReceiver.ServerLog.Count > 0,
                        "The logging done by the Server was not returned via the Callback.");

            // *** CLEANUP *** \\
            ((ICommunicationObject)client).Close();
            channelFactory.Close();
        }
        finally
        {
            // *** ENSURE CLEANUP *** \\
            ScenarioTestHelpers.CloseCommunicationObjects((ICommunicationObject)client, channelFactory);
        }
    }
Esempio n. 26
0
    public static void BasicHttp_Async_Close_ChannelFactory_Operations_Active()
    {
        // Test creates 2 channels from a single channel factory and
        // asynchronously closes the channel factory while both channels are
        // executing operations.  This verifies the operations are cancelled and
        // the channel factory is in the correct state.
        BasicHttpBinding             binding        = null;
        TimeSpan                     delayOperation = TimeSpan.FromSeconds(3);
        ChannelFactory <IWcfService> factory        = null;
        IWcfService                  serviceProxy1  = null;
        IWcfService                  serviceProxy2  = null;
        string expectedEcho1 = "first";
        string expectedEcho2 = "second";

        try
        {
            // *** SETUP *** \\
            binding = new BasicHttpBinding(BasicHttpSecurityMode.None);
            binding.CloseTimeout = ScenarioTestHelpers.TestTimeout;
            binding.SendTimeout  = ScenarioTestHelpers.TestTimeout;
            factory       = new ChannelFactory <IWcfService>(binding, new EndpointAddress(Endpoints.HttpBaseAddress_Basic));
            serviceProxy1 = factory.CreateChannel();
            serviceProxy2 = factory.CreateChannel();

            // *** EXECUTE *** \\
            Task <string> t1          = serviceProxy1.EchoWithTimeoutAsync(expectedEcho1, delayOperation);
            Task <string> t2          = serviceProxy2.EchoWithTimeoutAsync(expectedEcho2, delayOperation);
            Task          factoryTask = Task.Factory.FromAsync(factory.BeginClose, factory.EndClose, TaskCreationOptions.None);

            // *** VALIDATE *** \\
            factoryTask.GetAwaiter().GetResult();
            Assert.True(factory.State == CommunicationState.Closed,
                        String.Format("Expected factory state 'Closed', actual was '{0}'", factory.State));

            Exception exception1  = null;
            Exception exception2  = null;
            string    actualEcho1 = null;
            string    actualEcho2 = null;

            // Verification is slightly more complex for the close with active operations because
            // we don't know which might have completed first and whether the channel factory
            // was able to close and dispose either channel before it completed.  So we just
            // ensure the Tasks complete with an exception or a successful return and have
            // been closed by the factory.
            try
            {
                actualEcho1 = t1.GetAwaiter().GetResult();
            }
            catch (Exception e)
            {
                exception1 = e;
            }

            try
            {
                actualEcho2 = t2.GetAwaiter().GetResult();
            }
            catch (Exception e)
            {
                exception2 = e;
            }

            Assert.True(exception1 != null || actualEcho1 != null, "First operation should have thrown Exception or returned an echo");
            Assert.True(exception2 != null || actualEcho2 != null, "Second operation should have thrown Exception or returned an echo");

            Assert.True(actualEcho1 == null || String.Equals(expectedEcho1, actualEcho1),
                        String.Format("First operation returned '{0}' but expected '{1}'.", expectedEcho1, actualEcho1));

            Assert.True(actualEcho2 == null || String.Equals(expectedEcho2, actualEcho2),
                        String.Format("Second operation returned '{0}' but expected '{1}'.", expectedEcho2, actualEcho2));

            Assert.True(((ICommunicationObject)serviceProxy1).State == CommunicationState.Closed,
                        String.Format("Expected channel 1 state 'Closed', actual was '{0}'", ((ICommunicationObject)serviceProxy1).State));
            Assert.True(((ICommunicationObject)serviceProxy2).State == CommunicationState.Closed,
                        String.Format("Expected channel 2 state 'Closed', actual was '{0}'", ((ICommunicationObject)serviceProxy2).State));

            // *** CLEANUP *** \\
            ((ICommunicationObject)serviceProxy1).Abort();
            ((ICommunicationObject)serviceProxy2).Abort();
        }
        finally
        {
            // *** ENSURE CLEANUP *** \\
            ScenarioTestHelpers.CloseCommunicationObjects((ICommunicationObject)serviceProxy1,
                                                          (ICommunicationObject)serviceProxy2,
                                                          factory);
        }
    }