Skip to content

Validation doesn´t work on fault response messages #17

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
ola70 opened this issue Dec 20, 2018 · 5 comments
Open

Validation doesn´t work on fault response messages #17

ola70 opened this issue Dec 20, 2018 · 5 comments

Comments

@ola70
Copy link

ola70 commented Dec 20, 2018

Hi,

I have tested the latest version and when Biztalk responds with a fault message the test runs as expected. My problem is when I try to make some validations of values in the fault message. It seems that the response is not interpreted as a valid xml document. In the attached test output below you can see that the response has some extra lines of characters and text in the beginning and end. I would appreciate if you could try this and see if you get the same problem. In BizTalk the message looks correctly.


                               S T A R T

Test: Test_SystemException started @ 13:23:45.555 19-12-2018 by Tester

Info: Adding context property: BizUnitTestCaseStartTime, value: 2018-12-19 13:23:45

Setup Stage: started @ 13:23:45.561 19-12-2018

Setup Stage: ended @ 13:23:45.563 19-12-2018

Execute Stage: started @ 13:23:45.563 19-12-2018
Info: Queuing concurrent step: TransMock.Integration.BizUnit.MockSolicitResponseStep for execution

Step: TransMock.Integration.BizUnit.MockSolicitResponseStep started c o n c u r r e n t l y @ 13:23:45.565 19-12-2018, failOnError = True

Data: Reading request content from path TestData\
Info: Waiting to read the response from the endpoint
Info: Reading the response from the endpoint

Data: The response received from the mocked endpoint is:

V���s���a�V�D
�\0??Xhttp://schemas.microsoft.com/net/2005/12/windowscommunicationfoundation/dispatcher/fault�V�V?�V?�V?�?�s?�:?�ReceiverV?�V?�	

�aRhttp://schemas.microsoft.com/net/2005/12/windowscommunicationfoundation/dispatcher?�a?�:?�InternalServiceFault��V?�V?���xml�lang?�sv-SE?
�<ns0:FaultEnvelope 

xmlns:ns0="http://schemas.microsoft.biztalk.practices.esb.com/exceptionhandling">
  <Application>Testapp</Application>
  <Description>There is no value associated with the property 'Test' in the message.</Description>
  <ErrorType>MissingPropertyException</ErrorType>
  <FailureCategory>BizTalk.Orchestration</FailureCategory>
  <FaultCode>GeneralException</FaultCode>
  <FaultDescription>Error description not available</FaultDescription>
  <FaultSeverity>2</FaultSeverity>
  <Scope>Construct Fault Message</Scope>
  <ServiceInstanceID>e4c29c2a-1f0a-4bde-91ca-32df28fb7eaa</ServiceInstanceID>
  <ServiceName>Testapp.Orchestrations.Test</ServiceName>
</ns0:FaultEnvelope>��V?�@�ExceptionDetail�;http://schemas.datacontract.org/2004/07/System.ServiceModel	�i)http://www.w3.org/2001/XMLSchema-

instance@�HelpLink.�nil?�@�InnerException.�nil?�@�Message?
�<ns0:FaultEnvelope xmlns:ns0="http://schemas.microsoft.biztalk.practices.esb.com/exceptionhandling">
  <Application>Testapp</Application>
  <Description>There is no value associated with the property 'Test' in the message.</Description>
  <ErrorType>MissingPropertyException</ErrorType>
  <FailureCategory>BizTalk.Orchestration</FailureCategory>
  <FaultCode>GeneralException</FaultCode>
  <FaultDescription>Error description not available</FaultDescription>
  <FaultSeverity>2</FaultSeverity>
  <Scope>Construct Fault Message</Scope>
  <ServiceInstanceID>e4c29c2a-1f0a-4bde-91ca-32df28fb7eaa</ServiceInstanceID>
  <ServiceName>Testapp.Orchestrations.GranskaDebitering</ServiceName>
</ns0:FaultEnvelope>�@
StackTrace?��   at Microsoft.BizTalk.Adapter.Wcf.Runtime.BizTalkAsyncResult.End()
   at Microsoft.BizTalk.Adapter.Wcf.Runtime.BizTalkServiceInstance.EndOperation(IAsyncResult result)
   at Microsoft.BizTalk.Adapter.Wcf.Runtime.BizTalkServiceInstance.Microsoft.BizTalk.Adapter.Wcf.Runtime.ITwoWayAsync.EndTwoWayMethod(IAsyncResult result)
   at AsyncInvokeEndEndTwoWayMethod(Object , Object[] , IAsyncResult )
   at System.ServiceModel.Dispatcher.AsyncMethodInvoker.InvokeEnd(Object instance, Object[]& outputs, IAsyncResult result)
   at System.ServiceModel.Dispatcher.DispatchOperationRuntime.InvokeEnd(MessageRpc& rpc)
   at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage7(MessageRpc& rpc)
   at System.ServiceModel.Dispatcher.MessageRpc.Process(Boolean isOperationContextSet)�@�Type?:Microsoft.BizTalk.Adapter.Wcf.Runtime.BizTalkNackException�����

Error: Exception caught!
System.Xml.XmlException: Data at the root level is invalid. Line 1, position 1.
at System.Xml.XmlTextReaderImpl.Throw(Exception e)
at System.Xml.XmlTextReaderImpl.Throw(String res, String arg)
at System.Xml.XmlTextReaderImpl.ParseRootLevelWhitespace()
at System.Xml.XmlTextReaderImpl.ParseDocumentContent()
at System.Xml.XmlTextReaderImpl.Read()
at System.Xml.XsdValidatingReader.Read()
at System.Xml.XmlLoader.Load(XmlDocument doc, XmlReader reader, Boolean preserveWhitespace)
at System.Xml.XmlDocument.Load(XmlReader reader)
at BizUnit.TestSteps.ValidationSteps.Xml.XmlValidationStep.ValidateXmlInstance(Stream data, Context context)



Error: Exception caught!
BizUnit.Core.TestBuilder.ValidationStepExecutionException: Failed to validate document instance ---> System.Xml.XmlException: Data at the root level is invalid. Line

1, position 1.
at System.Xml.XmlTextReaderImpl.Throw(Exception e)
at System.Xml.XmlTextReaderImpl.Throw(String res, String arg)
at System.Xml.XmlTextReaderImpl.ParseRootLevelWhitespace()
at System.Xml.XmlTextReaderImpl.ParseDocumentContent()
at System.Xml.XmlTextReaderImpl.Read()
at System.Xml.XsdValidatingReader.Read()
at System.Xml.XmlLoader.Load(XmlDocument doc, XmlReader reader, Boolean preserveWhitespace)
at System.Xml.XmlDocument.Load(XmlReader reader)
at BizUnit.TestSteps.ValidationSteps.Xml.XmlValidationStep.ValidateXmlInstance(Stream data, Context context)
--- End of inner exception stack trace ---
at BizUnit.TestSteps.ValidationSteps.Xml.XmlValidationStep.ValidateXmlInstance(Stream data, Context context)
at BizUnit.TestSteps.ValidationSteps.Xml.XmlValidationStep.Execute(Stream data, Context context)
at TransMock.Integration.BizUnit.MockSolicitResponseStep.Execute(Context context)
at BizUnit.Core.Utilites.ConcurrentTestStepWrapper.Execute()


Step: TransMock.Integration.BizUnit.MockSolicitResponseStep ended @ 13:23:46.569 19-12-2018 with ERRORS, exception:

BizUnit.Core.TestBuilder.ValidationStepExecutionException


Error: Exception caught!
BizUnit.Core.TestBuilder.ValidationStepExecutionException: Failed to validate document instance ---> System.Xml.XmlException: Data at the root level is invalid. Line

1, position 1.
at System.Xml.XmlTextReaderImpl.Throw(Exception e)
at System.Xml.XmlTextReaderImpl.Throw(String res, String arg)
at System.Xml.XmlTextReaderImpl.ParseRootLevelWhitespace()
at System.Xml.XmlTextReaderImpl.ParseDocumentContent()
at System.Xml.XmlTextReaderImpl.Read()
at System.Xml.XsdValidatingReader.Read()
at System.Xml.XmlLoader.Load(XmlDocument doc, XmlReader reader, Boolean preserveWhitespace)
at System.Xml.XmlDocument.Load(XmlReader reader)
at BizUnit.TestSteps.ValidationSteps.Xml.XmlValidationStep.ValidateXmlInstance(Stream data, Context context)
--- End of inner exception stack trace ---
at BizUnit.Core.TestRunner.FlushConcurrentQueue(Boolean waitingToFinish, TestStage stage)
at BizUnit.Core.TestRunner.ExecuteSteps(IEnumerable`1 testSteps, TestStage stage)


Execution Stage: ended @ 13:23:46.570 19-12-2018 with ERROR's

Cleanup Stage: started @ 13:23:46.570 19-12-2018


Error: Exception caught!
BizUnit.Core.TestBuilder.ValidationStepExecutionException: Failed to validate document instance ---> System.Xml.XmlException: Data at the root level is invalid. Line

1, position 1.
at System.Xml.XmlTextReaderImpl.Throw(Exception e)
at System.Xml.XmlTextReaderImpl.Throw(String res, String arg)
at System.Xml.XmlTextReaderImpl.ParseRootLevelWhitespace()
at System.Xml.XmlTextReaderImpl.ParseDocumentContent()
at System.Xml.XmlTextReaderImpl.Read()
at System.Xml.XsdValidatingReader.Read()
at System.Xml.XmlLoader.Load(XmlDocument doc, XmlReader reader, Boolean preserveWhitespace)
at System.Xml.XmlDocument.Load(XmlReader reader)
at BizUnit.TestSteps.ValidationSteps.Xml.XmlValidationStep.ValidateXmlInstance(Stream data, Context context)
--- End of inner exception stack trace ---
at BizUnit.Core.TestRunner.FlushConcurrentQueue(Boolean waitingToFinish, TestStage stage)
at BizUnit.Core.TestRunner.ExecuteSteps(IEnumerable`1 testSteps, TestStage stage)


Cleanup Stage: ended @ 13:23:46.570 19-12-2018 with ERROR's

Debug Trace:
TransMock.Communication.NamedPipes.StreamingNamedPipeClient: Connect() called
TransMock.Communication.NamedPipe.StreamingNamedPipeServer: Connecting to named pipe server at: localhost//Test_ReceiveAddress
TransMock.Communication.NamedPipes.StreamingNamedPipeClient: WriteStream() called
TransMock.Communication.NamedPipes: WriteStream() succeeded. Message read by the server
TransMock.Communication.NamedPipes: WriteMessage() succeeded. Message read by the server
TransMock.Integration.BizUnit.MockSolicitResponseStep: Reading the response from the endpoint
TransMock.Communication.NamedPipes.StreamingNamedPipeClient: ReadMessage() called
TransMock.Communication.NamedPipes.StreamingNamedPipeClient: ReadStream() called
TransMock.Communication.NamedPipes.StreamingNamedPipeClient: ReadStream() succeeded
TransMock.Communication.NamedPipes.StreamingNamedPipeClient: Deserializing message from the pipe.
TransMock.Communication.NamedPipes.StreamingNamedPipeClient: ReadMessage() succeeded and returning data
TransMock.Communication.NamedPipes.StreamingNamedPipeClient: Disconnect() called
TransMock.Communication.NamedPipes.StreamingNamedPipeClient: Disconnect() succeeded
TransMock.Integration.BizUnit.MockSendStep: PipeClient closed

Originally posted by @ola70 in #16 (comment)

@svetvasilev
Copy link
Owner

svetvasilev commented Dec 21, 2018

Hi Ola, that is somewhat strange behaviour. It might be caused by the way the message is represented over the wire through the MockMessage class serialization, but somehow i have difficulties in believing this is the case. I can say that great deal of the frameworks' tests are based on message content stream verification, but i might have not covered certain cases and hence this might actually be the case.
That said, all the validations done through the LambdaValidationStep are tested and should work for the case of faults too. If you are not familiar with this technique i will strongly suggest that you take a look at this article on my blog https://bizzitalk.blogspot.com/2018/08/new-features-in-transmock-14.html where an example of using the new delegate signature for validation based on the MockMessage class is given.
I see that your test case is using one of the standard validation steps from BizUnit. I find the BizUnit verification model very cumbersome and difficult to extend so i added this 3 liner validation step called LambdaValidation to TransMock which puts you in the driver seat of validation. It shouldn't take you long to modify your test to use this technique in order to see if it works for you this way. If it does then i definitely have introduced a somewhat breaking change for those who use the standard validation model and will have to look into it.
Cheers, Svet

@ola70
Copy link
Author

ola70 commented Jan 8, 2019

Hi,

Thanks for the reply. Now I have tried to do the validation with the LambdaValidationStep, but I get the same result. It dosen´t seem to matter which validation method I use. Below you can see the validation code in my test.

Regards Ola

receiveStep.SubSteps.Add(SoapExceptionLambdaValidation());

...

public LambdaValidationStep SoapExceptionLambdaValidation()
{
return new LambdaValidationStep()
{
ValidationCallback = (data) =>
{
var document = new XmlDocument();
document.Load(data);

		var valueErrorType = document.SelectSingleNode("/*[local-name()='FaultEnvelope' and namespace-uri()='http://schemas.microsoft.biztalk.practices.esb.com/exceptionhandling']" +
							       "/*[local-name()='ErrorType' and namespace-uri()='']").InnerText;

		try
		{
			Assert.AreEqual("XlangSoapException", valueErrorType);
		}
		catch (Exception e)
		{
			HandleException(e);
		}

		return true;
	}
};

}

@svetvasilev
Copy link
Owner

Hi Ola, Is it the exact same exception that is thrown? Is the exception thrown at the document.Load(data), meaning that the data is not recognized as XML, or is it at the document.SelectSingleNode()? If it is the latter then you have definately different behavior than the first case with the standard BizUnit validation step as per your previous post. And if the Assert.AreEqual() fails it means that the message XML was correctly processed, but the returned node is not as expected. Please clarify this so I can evt. help you further.
Some additional notes - please use the other signature for the validation callback called MessageValidationCallback with param of type MockMessage. This mainly due to the fact that the MockMessage gives you much richer base for validation and is not limited to only the message content. The other reason is that the ValidationCallback signature will become obsolete soon.
Furthermore there is no need to handle exceptions inside validations. In most cases it is considered an anti-pattern. Just let the Assert method throw exception, this should effectively terminate the test execution. But if you have some very specific logic for handling exceptions during test outcome validation, then do as you please.

@ola70
Copy link
Author

ola70 commented Jan 15, 2019

Hi,

I'm sorry if it got confused. It's not the same exception that is thrown, but the behavior is the same. The exception is thrown at document.Load(data). I have tried to use MessageValidationCallback, but it throws exception when I use it with MockSolicitResponseStep. It works with MockRequestResponseStep.

Regards Ola

@svetvasilev
Copy link
Owner

Hi Ola, sorry for the late reply, but busy like there is no tomorrow. Could you pls elaborate on your scenario that you are trying to test as I feel I am not getting the complete picture here. It gets even more confusing when you say that it works with MockRequestResponse step but not with its mirror twin - the SolicitResponse. If you are trying to test the same flow it should definitely fail with one of those steps as they behave completely opposite to one another. And it is not about the validation step as the main step will not execute as expected.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants