Simulate slow HTTP connect for Java integration test? - java

is it possible to simulate a slow HTTP connect in a Java integration test, so that I can define how long the server should wait until he confirms the connection? A solution which also supports a JAX-WS webservice would be perfect.
Background:
I have to integration test a central timeout configurator. The configurator itself must be technology-independent. At first it supports JAX-WS webservices, therefore the attribute com.sun.xml.ws.connect.timeout will be set in request context.
(I'll try to convince them, that it is part of JAX-WS and thus we don't need to test it, but this question is my backup plan.)
P.S.: There are other questions which ask about simulating a slow connection in general. This is different because I cannot use external tools in an unit test and I must be able to define a specific connection time.

In one of my unit test, I used NanoHTTPd https://github.com/NanoHttpd/nanohttpd which is a pure Java. It is only one class.

You can go through a proxy (http or socks) which can be embedded in your application. You can then tell the proxy to provide the behavior you need to test.
I had to test a dropped TCP/IP connection (How to reproduce a silently dropped TCP/IP connection?) and ended up going through a SOCKS proxy written in Java, which I just suspended to emulate the behavior I was looking for.

Related

Using embedded gemfire locator and server for integration testing

I have a application that uses gemfire locator and servers. I would like to write an integration test that could help me start a locator & a server within the JVM and also shut them down when ending the tests. I could not find any single documentation which could help me do this.
I have tried starting a locator and a server when the tests start using LocatorLauncher an ServerLauncher. It starts the locator but throws an exception stating IllegalStateException: A connection to a distributed system already exists in this VM.
I am not very good with gemfire and do not understand what am I missing here, or is it that I am trying in a complete wrong direction.
It would be useful to know a bit more about what you're trying to test exactly. We have different levels of testing in the Geode codebase. If you can get away with just a server, I'd suggest using the ServerStarterRule in your JUnits. Here is an example of that: https://github.com/apache/geode/blob/f12055ae3ae4b1f4731c0447af0c4cb9abdd4159/geode-core/src/integrationTest/java/org/apache/geode/management/internal/cli/commands/AlterRegionCommandIntegrationTest.java
This rule will start up a server as part of the JUnit JVM. This means that you won't be able to use a ClientCache at the same time (you cannot have both a ClientCache and a Cache instance in the same JVM instance).
The next level of test is called DUnit testing. This framework allows you to spin up multiple JVMs and form an actual cluster. The best way to use this is with the ClusterStartupRule together with the GfshCommandRule. An example of this would be: https://github.com/apache/geode/blob/10d89ede6f90f046c15e12e3d16aed259d7044b0/geode-cq/src/distributedTest/java/org/apache/geode/management/internal/cli/commands/ListClientCommandDUnitTest.java
Here, various components are being started up including a client VM. The nice thing about using these rules is that they will handle startup and teardown for you in a consistent and safe manner.

How do I use a Spring MVC Controller as a Fake Endpoint for an Integration Test?

I have a service that calls out to a third-party endpoint using java.net.URLConnection. As part of an integration test that uses this service I would like to use a fake endpoint of my own construction.
I have made a Spring MVC Controller that simulates that behaviour of the endpoint I require. (I know this endpoint works as expected as I included it in my web app's servlet config and hit it from a browser once started).
I am having trouble figuring out how I can get this fake endpoint available for my integration test.
Is there some feature of Spring-Test that would help me here?
Do I somehow need to start up a servlet at the beginning of my test?
Are there any other solutions entirely?
It's a bad idea to use a Spring MVC controller as a fake endpoint. There is no way to simply have the controller available for the integration test and starting a servlet with just that controller alongside whatever you are testing requires a lot of configuration.
It is much better to use a mocking framework like MockServer (http://www.mock-server.com/) to create your fake endpoint. MockServer should be powerful enough to cover even complex responses from the fake endpoint, with relatively little setup.
Check out Spring MVC Test that was added to Spring in version 3.2.
Here are some tutorials: 1, 2, 3
First I think we should get the terminology right. There are two general groups of "fake" objects in testing (simplified): a mock, which returns predefined answers on predefined input and stubs which are a simplified version of the object the SUT (system under test) communicates with. While a mock basically does nothing than to provide a response, a stub might use a live algorithm, but not store it's results in a database or send them to customers via eMail for example. I am no expert in testing, but those two fake objects are rather to be used in unit and depending on their scope in acceptance tests.
So your sut communicates with a remote system during integration test. In my book this is the perfect time to actually test how your software integrates with other systems, so your software should be tested against a test version of the remote system. In case this is not possible (they might not have a test system) you are conceptually in some sort of trouble. You can shape your stub or mock only in a way you expect it to work, very much like the part of the software you have written to communicate with that remote service. This leaves out some important things you want to test with integration tests: Was the client side implemented correctly so that it will work with the live server. Do we have to develop work around as there are implementation errors on the server side? In which scale will the communication with the remote system affect our software's performance? Do our authentication credentials work? Does the authentication mechanism work? What are the technical and conceptual implications of this communication relationship no one has thought of so far? (Believe me, the latter will happen more often than you might expect!)
Generally speaking: What will happen if you do integration tests against a mock or a stub is that you test against your own understanding of how to implement the client and the server side of communication, and you do not test how your client works with the actual remote server or at least the best thing next to that, a test system. I can tell you from experience: never make assumptions on how a remote system should behave - test it. Even when talking of a JMS server: test it!
In case you are working for a company, testing against a provided test system is even more important: if you software works against a test system and you can prove it (selenium is a good helper here, as well as good logging, believe it or not) and your software does not work with a live version, you have a situation which I call "instablame": it is immediately obvious that it is not your fault the software isn't working. I myself hate fingerpointing to the bone, but most suits tend to ask "Who's fault was it?" even before "Can we fix that immediately?" and way before "How can we solve that problem?". And there is a special group of suits called lawyers, you know ... ;)
That being said: if you absolutely have to use those stubs during your integration tests, I would create an own project for them (let's say "MyProject-IT-Stubs" and build and run the latest version of MyProject-IT-Stubs before I run the IT of my main project. When using maven, you could create MyProject-IT-Stubs with war packaging, call it as a dependency during the pre-integration-test phase and fire up a jetty for this war in the same phase. Then your integration tests run, either successful or not and you can tear down the jetty in the post-integration-test phase.
The IMHO best way to organize your project with maven would be to have a project with three modules: MyProject,MyProject-IT-Stubs and MyProject-IT(declaring dependencies on MyProject and MyProject-IT-Stubs. This keeps your projects nice and tidy and the stubs do not pollute your project. You might want to think about organizing MyProject-IT-Stubs into modules as well, one for each remote system you have to talk to. As soon as you have test access, you can simply deactivate the according module in MyProject-IT-Stubs.
I am sure according options exist for InsertYourBuildToolHere.

Know any embeddable NNTP servers?

I'm writing a bit of code that uses the Apache NNTP Client to fetch articles from an NNTP server. Once the code ships, we'll use an Apache James server to read the articles from. But to test the code, I'm looking for an embedded Java NNTP server, so I don't have to mock every server call. Are there any good ones I can use? Google seems to have failed me.
My requirements are as follows:
A server I can start from within the code.
Tests can be run out-of-the-box on different machines without additional setup. (Once I commit the code, a remote build machine needs to be able to run the test cases).
Any other inspired suggestions are also welcome.
There is sonews, which seems to be active and supports a suprising lot of database backends. I didn't look at it further, so I can't tell if you can embed it.

Making a reliable web service unreliable, but in a controlled way?

I have a Java 6 based web service client using the standard Java 6 annotation based approach (i.e. no Axis or other third party web service library), which works very well. So does the web service I am calling, which is nice, but now I need to write error handling code, and I need to be able to make the existing web service unreliable in a controlled way.
There are many mock frameworks, and they may be helpful, but I don't need right now to be able to mock out the service with prerecorded answers or anything, just introduce unreliability causing the web service library to fail so I can handle the situation gracefully. This would probably be a proxy server running locally.
I work with Eclipse Java EE 3.6, but Netbeans, IntelliJ and JDeveloper are also options.
What would be the best way to do this?
Tcpmon, http://ws.apache.org/commons/tcpmon/index.html can be set up to act as a proxy and even simulate slow connections.
That would give you a chance to simulate both "sorry, not here" and "yes, we are here but we time out".
Any introduced instability is likely to lead to operation avenues of instability being missed. Aim to cover all potential error vectors in your code rather than trying to mitigate for specifics.
Since You've not disclosed enough details of your setup, maybe throwing Exception here and there would be enough?
Seriously, for integration tests like this I'd suggest running some subset of a real web service container.
Based on service's logic it may behave unreliably because of:
external system it is using is misbehaving - try to mock the external system and throw faults - different types - from it
database access problem - try mocking DAO layer and throw Exception from there
general hardware problem - depends :) try to stress your code as you see fit
I think rather than introducing unreliability to a running-instance of the web service application, you are better off simulating error conditions in your unit/integration tests and asserting that your top-layer of the service responds the way that you would like.
For example:
How does the service entry-point respond to a request if the data layer reports that it cannot communicate with the backend (if the data layer throws exceptions, or however it indicates failure)
How does the service entry-point behave if other required components are throwing "unavailable"-like exceptions?
Do you have any timeout logic in place, i.e. the service returns an error if it takes more than X seconds to process the request? If so, this can be simulated in a mock test as well.

Best Java supported server/client protocol?

I'm in the process of writing a client/server application which should work message based. I would like re-use as much as possible instead of writing another implementation and curious what others are using.
Features the library should offer:
client and server side functionality
should work message based
support multi-threading
should work behind load balancer / firewalls
I did several tests with HTTPCore, but the bottom line is that one has to implement both client and server, only the transport layer would be covered. RMI is not an option either due to the network related requirements.
Any ideas are highly appreciated.
Details
My idea is to implement a client/server wrapper which handles the client communication (including user/password validation) and writes incoming requests to a JMS queue:
#1 User --> Wrapper (Check for user/password) --> JMS --> "Server"
#2 User polls Wrapper which polls JMS
Separate processes will handle the requests and can reply via wrapper to the clients. I'd like to use JMS because:
it handles persistence quite well
load balancing - it's easy to handle peaks by adding additional servers as consumer
JMSTimeToLive comes in handy too
Unfortunately I don't see a way to use JMS on it's own, because clients should only have access to their messages and the setup of different users on JMS side doesn't sound feasible either.
Well, HTTP is probably the best supported in terms of client and server code implementing it - but it may well be completely inappropriate based on your requirements. We'll need to actually see some requirements (or at least a vague idea of what the application is like) before we can really advise you properly.
RMI works nicely for us. There are limitations, such as not being able to call back to the client unless you can connect directly to that computer (does not work if client is behind a firewall). You can also easily wrap your communication in SSL or tunnel it over HTTP which can be wrapped in SSL.
If you do end up using this remember to always set the serial version of a class that is distributed to the client. You can set it to 1L when you create it, or if the client already has the class use serialver.exe to discover the existing class's serial. Otherwise as soon as you change or add a public method or variable compatibility with existing clients will break.
static final long serialVersionUID = 1L
EDIT: Each RMI request that comes into the server gets its own thread. You don't have to handle this yourself.
EDIT: I think some details were added later in the question. You can tunnel RMI over HTTP, then you could use a load balancer with it.
I've recently started playing with Hessian and it shows a lot of promise. It natively uses HTTP which makes it simpler than RMI over HTTP and it's a binary protocol which means it's faster than all the XML-based protocols. It's very easy to get Hessian going. I recently did this by embedding Jetty in our app, configuring the Hessian Servlet and making it implement our API interface. The great thing about Hessian is it's simplicity... nothing like JMS or RMI over HTTP. There are also libraries for Hessian in other languages.
I'd say the best-supported, if not best-implemented, client/server communications package for Java is Sun's RMI (Remote Method Invocation). It's included with the standard Java class library, and gets the job done, even if it's not the fastest option out there. And, of course, it's supported by Sun. I implemented a turn-based gaming framework with it several years ago, and it was quite stable.
It is difficult to make a suggestion based on the information given but possibly the use of TemporaryQueues e.g. dynamically created PTP destinations on a per client basis might fit the problem?
Here is a reasonable overview.
Did you tried RMI or CORBA? With both of them you can distribute your logic and create Sessions
Use Spring....Then pick and choose the protocol.
We're standardizing on Adobe's AMF as we're using Adobe Flex/AIR in the client-tier and Java6/Tomcat6/BlazeDS/Spring-Framework2.5/iBATIS2.3.4/ActiveMQ-JMS5.2 in our middle-tier stack (Oracle 10g back-end).
Because we're standardizing on Flex client-side development, AMF and BlazeDS (now better coupled to Spring thanks to Adobe and SpringSource cooperating on the integration), are the most efficient and convenient means we can employ to interact with the server-side.
We also heavily build on JMS messaging in the data center - BlazeDS enables us to bridge our Flex clients as JMS topic subscribers. That is extremely powerful and effective.
Our Flex .swf and Java .class code is bundled into the same .jar file for deployment. That way the correct version of the client code will be deployed to interact with the corresponding middle-tier java code that will process client service calls (or messaging operations). That has always been a bane of client-server computing - making sure the correct versions of the respective tiers are hooked up to each other. We've effectively solved that age-old problem with our particular approach to packaging and deployment.
All of our client-server interactions work over HTTP/HTTPS ports 80 and 443. Even the server-side messaging push we do with BlazeDS bridged to our ActiveMQ JMS message broker.

Categories