Skip to content

Commit

Permalink
Merge pull request dotnet#294 from StephenBonikowsky/Issue250and251
Browse files Browse the repository at this point in the history
Adding test cases to resolve Issues 250 and 251
  • Loading branch information
StephenBonikowsky committed Aug 31, 2015
2 parents e299bba + e56de4b commit c674a2a
Show file tree
Hide file tree
Showing 11 changed files with 451 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -128,4 +128,14 @@ public static string Tcp_NoSecurity_DuplexCallback_Address
{
get { return BridgeClient.GetResourceAddress("WcfService.TestResources.DuplexCallbackResource"); }
}

public static string Tcp_NoSecurity_DataContractDuplexCallback_Address
{
get { return BridgeClient.GetResourceAddress("WcfService.TestResources.DuplexCallbackDataContractComplexTypeResource"); }
}

public static string Tcp_NoSecurity_XmlDuplexCallback_Address
{
get { return BridgeClient.GetResourceAddress("WcfService.TestResources.DuplexCallbackXmlComplexTypeResource"); }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -688,6 +688,61 @@ public string StringValue
}
}

// This type should only be used by test Contract.DataContractTests.NetTcpBinding_DuplexCallback_ReturnsDataContractComplexType
// It tests a narrow scenario that returns a DataContract attributed type in the callback method that is not known by the ServiceContract attributed interface
// This test is designed to make sure the NET Native toolchain creates the needed serializer
[DataContract(Namespace = "http://www.contoso.com/wcfnamespace")]
public class ComplexCompositeTypeDuplexCallbackOnly : IEquatable<ComplexCompositeTypeDuplexCallbackOnly>
{
private Guid _guidValue;

[DataMember]
public Guid GuidValue
{
get { return _guidValue; }
set { _guidValue = value; }
}

public bool Equals(ComplexCompositeTypeDuplexCallbackOnly other)
{
if (other == null) { return false; }
if (object.ReferenceEquals(this, other)) { return true; }

if (_guidValue != other._guidValue) { return false; }

return true;
}

public override string ToString()
{
StringBuilder sb = new StringBuilder();
sb.AppendLine("GuidValue: " + _guidValue);

return sb.ToString();
}
}

// This type should only be used by test Contract.DataContractTests.NetTcpBinding_DuplexCallback_ReturnsXmlComplexType
// It tests a narrow scenario that returns an Xml attributed type in the callback method that is not known by the ServiceContract attributed interface
// This test is designed to make sure the NET Native toolchain creates the needed serializer
public class XmlCompositeTypeDuplexCallbackOnly
{
private bool _boolValue = true;
private string _stringValue = "Hello ";

public bool BoolValue
{
get { return _boolValue; }
set { _boolValue = value; }
}

public string StringValue
{
get { return _stringValue; }
set { _stringValue = value; }
}
}

public class DuplexTaskReturnServiceCallback : IWcfDuplexTaskReturnCallback
{
private bool _wrapExceptionInTask;
Expand Down Expand Up @@ -772,13 +827,17 @@ public MyDuplexClientBase(InstanceContext callbackInstance, Binding binding, End
}
}

public class WcfDuplexServiceCallback : IWcfDuplexServiceCallback
public class WcfDuplexServiceCallback : IWcfDuplexServiceCallback, IWcfDuplexService_DataContract_Callback, IWcfDuplexService_Xml_Callback
{
private TaskCompletionSource<Guid> _tcs;
private TaskCompletionSource<XmlCompositeTypeDuplexCallbackOnly> _xml_tcs;
private TaskCompletionSource<ComplexCompositeTypeDuplexCallbackOnly> _datacontract_tcs;

public WcfDuplexServiceCallback()
{
_tcs = new TaskCompletionSource<Guid>();
_xml_tcs = new TaskCompletionSource<XmlCompositeTypeDuplexCallbackOnly>();
_datacontract_tcs = new TaskCompletionSource<ComplexCompositeTypeDuplexCallbackOnly>();
}

public Guid CallbackGuid
Expand All @@ -793,6 +852,30 @@ public Guid CallbackGuid
}
}

public XmlCompositeTypeDuplexCallbackOnly XmlCallbackGuid
{
get
{
if (_xml_tcs.Task.Wait(ScenarioTestHelpers.TestTimeout))
{
return _xml_tcs.Task.Result;
}
throw new TimeoutException(string.Format("Not completed within the alloted time of {0}", ScenarioTestHelpers.TestTimeout));
}
}

public ComplexCompositeTypeDuplexCallbackOnly DataContractCallbackGuid
{
get
{
if (_datacontract_tcs.Task.Wait(ScenarioTestHelpers.TestTimeout))
{
return _datacontract_tcs.Task.Result;
}
throw new TimeoutException(string.Format("Not completed within the alloted time of {0}", ScenarioTestHelpers.TestTimeout));
}
}

public void OnPingCallback(Guid guid)
{
// Set the result in an async task with a 100ms delay to prevent a race condition
Expand All @@ -803,4 +886,26 @@ public void OnPingCallback(Guid guid)
_tcs.SetResult(guid);
});
}

public void OnXmlPingCallback(XmlCompositeTypeDuplexCallbackOnly xmlCompositeType)
{
// Set the result in an async task with a 100ms delay to prevent a race condition
// where the OnPingCallback hasn't sent the reply to the server before the channel is closed.
Task.Run(async () =>
{
await Task.Delay(100);
_xml_tcs.SetResult(xmlCompositeType);
});
}

public void OnDataContractPingCallback(ComplexCompositeTypeDuplexCallbackOnly dataContractCompositeType)
{
// Set the result in an async task with a 100ms delay to prevent a race condition
// where the OnPingCallback hasn't sent the reply to the server before the channel is closed.
Task.Run(async () =>
{
await Task.Delay(100);
_datacontract_tcs.SetResult(dataContractCompositeType);
});
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -275,3 +275,33 @@ public interface IWcfDuplexTaskReturnCallback
Action = "http://tempuri.org/IWcfDuplexTaskReturnCallback/ServicePingFaultCallbackFaultDetailFault")]
Task<Guid> ServicePingFaultCallback(Guid guid);
}

// ********************************************************************************

[ServiceContract(CallbackContract = typeof(IWcfDuplexService_DataContract_Callback))]
public interface IWcfDuplexService_DataContract
{
[OperationContract]
void Ping_DataContract(Guid guid);
}

public interface IWcfDuplexService_DataContract_Callback
{
[OperationContract]
void OnDataContractPingCallback(ComplexCompositeTypeDuplexCallbackOnly complexCompositeType);
}

// ********************************************************************************

[ServiceContract(CallbackContract = typeof(IWcfDuplexService_Xml_Callback))]
public interface IWcfDuplexService_Xml
{
[OperationContract]
void Ping_Xml(Guid guid);
}

public interface IWcfDuplexService_Xml_Callback
{
[OperationContract, XmlSerializerFormat]
void OnXmlPingCallback(XmlCompositeTypeDuplexCallbackOnly xmlCompositeType);
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using System;
using System.ServiceModel;
using System.ServiceModel.Channels;
using TestTypes;
using System.Text;
using Xunit;

Expand Down Expand Up @@ -51,4 +52,81 @@ public static void CustomBinding_DefaultSettings_Echo_RoundTrips_DataContract()

Assert.True(errorBuilder.Length == 0, errorBuilder.ToString());
}

// Verify that a callback contract correctly returns a complex type when this type is not part of the contract with the ServiceContract attribute.
[Fact]
[OuterLoop]
public static void NetTcpBinding_DuplexCallback_ReturnsDataContractComplexType()
{
DuplexChannelFactory<IWcfDuplexService_DataContract> factory = null;
NetTcpBinding binding = null;
WcfDuplexServiceCallback callbackService = null;
InstanceContext context = null;
IWcfDuplexService_DataContract serviceProxy = null;
Guid guid = Guid.NewGuid();

try
{
binding = new NetTcpBinding();
binding.Security.Mode = SecurityMode.None;

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

factory = new DuplexChannelFactory<IWcfDuplexService_DataContract>(context, binding, new EndpointAddress(Endpoints.Tcp_NoSecurity_DataContractDuplexCallback_Address));
serviceProxy = factory.CreateChannel();

serviceProxy.Ping_DataContract(guid);
ComplexCompositeTypeDuplexCallbackOnly returnedType = callbackService.DataContractCallbackGuid;

// validate response
Assert.True((guid == returnedType.GuidValue), String.Format("The Guid sent was not the same as the Guid returned.\nSent: {0}\nReturned: {1}", guid, returnedType.GuidValue));

((ICommunicationObject)serviceProxy).Close();
factory.Close();
}
finally
{
ScenarioTestHelpers.CloseCommunicationObjects((ICommunicationObject)serviceProxy, factory);
}
}

// Verify that a callback contract correctly returns a complex type using Xml instead of DataContract when this type is not part of the contract with the ServiceContract attribute.
[Fact]
[OuterLoop]
[ActiveIssue(292)]
public static void NetTcpBinding_DuplexCallback_ReturnsXmlComplexType()
{
DuplexChannelFactory<IWcfDuplexService_Xml> factory = null;
NetTcpBinding binding = null;
WcfDuplexServiceCallback callbackService = null;
InstanceContext context = null;
IWcfDuplexService_Xml serviceProxy = null;
Guid guid = Guid.NewGuid();

try
{
binding = new NetTcpBinding();
binding.Security.Mode = SecurityMode.None;

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

factory = new DuplexChannelFactory<IWcfDuplexService_Xml>(context, binding, new EndpointAddress(Endpoints.Tcp_NoSecurity_XmlDuplexCallback_Address));
serviceProxy = factory.CreateChannel();

serviceProxy.Ping_Xml(guid);
XmlCompositeTypeDuplexCallbackOnly returnedType = callbackService.XmlCallbackGuid;

// validate response
Assert.True((guid.ToString() == returnedType.StringValue), String.Format("The Guid to string value sent was not the same as what was returned.\nSent: {0}\nReturned: {1}", guid.ToString(), returnedType.StringValue));

((ICommunicationObject)serviceProxy).Close();
factory.Close();
}
finally
{
ScenarioTestHelpers.CloseCommunicationObjects((ICommunicationObject)serviceProxy, factory);
}
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
{
"dependencies": {
"System.Reflection.Emit.Lightweight": "4.0.0",
"System.ServiceModel.Duplex": "4.0.0-beta-*",
"System.ServiceModel.Http": "4.0.10-beta-*",
"System.ServiceModel.NetTcp": "4.0.0-beta-*",
"System.ServiceModel.Primitives": "4.0.0-beta-*",
"xunit": "2.1.0-beta3-*",
"xunit.netcore.extensions": "1.0.0-prerelease-*"
Expand Down
Loading

0 comments on commit c674a2a

Please sign in to comment.