Testing Software that Runs on Other Software
Recently I've been working on porting some code that used a home-grown HTTP client connector to use the HTTP client connector facilities present in Java 1.4+. Some of the outstanding advantages of using the built-in HTTP client connector is that transport encoding (chunked streaming versus fixed-content-length transfers) and forward-proxy authentication is handled automatically behind the scenes.
During my development, I've been using our suite of unit tests to verify the correctness of my work. The tests are implemented using the JUnit test framework and can be run from within my IntelliJ development environment. I've been using the Jetty Servlet container to host our server-side application during testing. Jetty includes a light-weight HTTP server.
At one point, I had all of the unit tests passing and decided to perform functional testing using the full-blown web application in the Tomcat Servlet container. I quickly learned that something was wrong when I began seeing an EOFException reported in the Tomcat server log. I had been using Java's default HTTP Content-Type header field value (application/x-www-form-urlencoded), which the Tomcat Coyote HTTP connector recognized. Tomcat attempted interpret our proprietary communication protocol rather than simply pass it through. I then specified that the Content-Type should be application/octet-stream (the default type according to the HTTP 1.1 RFC) and was successful in testing against Jetty and Tomcat. The problem was that Jetty had ignored the Content-Type HTTP header in our requests, while the Tomcat Coyote HTTP connector did not. Tomcat was correct in this case and has honored the HTTP 1.1 specification more closely than Jetty, in my experience.
Most developers are encouraged to distrust user input because it introduces unpredictability into the execution of a software program. But what I've learned in this and other projects is that no software program works in isolation. If you're writing software for Windows, then you're dependent on the behavior of the Windows Operating System (OS). And the Windows OS is dependent on the third-party hardware drivers and firmware it uses to interact with the computer's hardware devices. And if you're working on software that communicates over a computer network (i.e. the Internet), then anything can happen.
So, simply distrusting user input is not enough to ensure correct operation of a software program. The vagueness of relatively simple communications protocols like HTTP still provide a lot of room for interpretation. The only way to ensure a high degree of compatibility is to test as many hardware, software, and input permutations as possible. An EMC VMWare virtualization appliance is an excellent platform for such testing, in my opinion :)