Reading Time: 5 minutes

The “Man-in-the-Middle” attack is such a well-recognized security risk, with established solutions and preventative measures in place that when I first heard about the recent ruckus around the Apple security flaw, I thought Apple’s trouble was more legal in natural, maybe some sort of royalties dispute between iTunes and the Michael Jackson estate. Only later did I found out what all the fuss was about “in the middle”, not “in the mirror”, and why I had to upgrade the iOS on my iPhone on a beautiful Saturday afternoon.

Regarding the specifics to Apple’s security flaw, there is already plenty of press coverage out there.  For example, David Auerbach wrote a great analysis over at Slate.com.

latest report
Learn why we are the Leaders in API management and iPaaS

In this post, I’d like to illustrate how automated unit testing with appropriate code coverage could have detected that particular kind of error, the one caused by grammatically correct code that inadvertently invalidated the whole logic of the program. We will build the unit tests using the MUnit module, an open source Mule testing framework that significantly streamline and simplify the process of writing unit tests.

We have built a simple,demonstrative application that processes incoming messages differently depending on whether a property of the payload, called “goodguy”, has value of “true” or not. If the value was true, the message would be processed one way and an HTTP 200 status would be returned. If it was not, the message would be processed another way and an HTTP status 400 would be returned:

The key logic for routing the message is shown below:

<choice doc:name="Choice">
  <!-- <when expression="#[payload['goodguy']=true]"> -->
  <when expression="#[payload['goodguy']==true]">
    <set-payload value="#['All Good']" doc:name="set-valid-payload-response"/>
    <http:response-builder status="200" contentType="text/plain" doc:name="HTTP Response 200"/>
  </when>
  <otherwise>
    <set-payload value="#['Invalid Payload']" doc:name="invalid-payload-goes-here"/>
    <http:response-builder status="400" contentType="text/plain" doc:name="HTTP Response 400"/>
  </otherwise>
</choice>

Let’s assume the initial release of the application had passed manual end-to-end testing and UAT and had been deployed to production:

Now let’s pretend that over time, additional features had to be added to the application so the code had to be touched again, and a developer had accidentally changed the double “==” to just a single “=” in the expression in the Choice router. If there was no unit testing, the application would package successfully, deployment would go smoothly, and the application would actually run, but just not processing the messages correctly:


However, if unit testing with sufficient code coverage was put in place:

<!--Beginning of First Test, Generally the Happy Path where payload values are expected / valid-->
<munit:test name="ValidateHappyPath" description="Test when input is as expected">
	<!--Mock inbound endpoint since it is a unit test-->
	<mock:when messageProcessor="http:inbound-endpoint"/>
	<!--Now set the payload to have the valid value-->
	<munit:set payload-ref="#['']">
		<munit:inbound-properties>
			<munit:inbound-property key="flag" value-ref="#['true']"/>
		</munit:inbound-properties>
	</munit:set>
	<!--Pass the payload into the flow to be unit-tested-->
	<flow-ref name="munit-demo-flow"/>
		
	<!-- Assert the flow behaved as designed for a valid payload -->
	<munit:assert-on-equals expected-ref="#[200]" value-ref="#[payload.getStatusCode()]"/>
</munit:test>
<!--End of First Test-->
<!--Beginning of Second Test, Generally the Sad Path where payload values are unexpected / invalid-->
<munit:test name="ValidateSadPath" description="Test when input is not as expected and error should be thrown">
	<!--Mock inbound endpoint since it is a unit test-->
	<mock:when messageProcessor="http:inbound-endpoint"/>
	<!--Now set the payload to have the invalid value-->
	<munit:set payload-ref="#['']">
		<munit:inbound-properties>
			<munit:inbound-property key="flag" value-ref="#['qwerty']"/>
		</munit:inbound-properties>
	</munit:set>
	<!--Pass the payload into the flow to be unit-tested-->
	<flow-ref name="munit-demo-flow"/>
		
	<!-- Assert the flow behaved as designed for an invalid payload -->
	<munit:assert-on-equals expected-ref="#[400]" value-ref="#[payload.getStatusCode()]"/>
</munit:test>
<!--End of Second Test-->

The application would have failed during the build phase and would never have been deployed to production, as illustrated in the screenshot below.  Note that maven displayed how many tests were, how many failed, and the reasons of the failures:

Note that the unit tests covered both the “happy path” and the “sad path” to achieve sufficient code coverage. If the code covered by the unit tests were sparse, erroneous lines could still slip in and remain undetected.

Hopefully this explains the title of this blog entry and it all makes sense now. If not, WTF is the most used abbreviation in the tech industry anyway, and the best part about WTF is that you can sprinkle it all over your code comments, and no amount of automated unit testing will ever catch it.