简体   繁体   中英

Simulate network connectivity issues on Linux using Java

I would like to have an automated test for the following scenario:

  1. User logs in and performs some "lengthy" operation. For example tries to upload a file.
  2. In the middle of that lengthy operation, the connection to the server is lost for a period of time, and then restored.
  3. Application does whatever it's supposed to do in this case. For example shows a message to the user asking if they want to retry.

I want steps 1. and 3. to be done by Selenium. Question is: how can I do the step 2. as part of the automated test?

Details on the tools and environment:

  1. Selenium is on Java with Junit
  2. Test must run on Linux and Windows
  3. It will also run on 3 browsers: Firefox, Chrome, IE 11

Couple of solutions I was thinking about:

  • Call some script that manipulates a connection on the machine.
  • Manipulate proxy settings of the browser (proxy points to fake address, thus connection is broken).
  • Use a real proxy, which could be controlled from the code (eg by some commands), so it can behave as "working" or "broken" connection.

None of these solutions is ideal for various reasons.

So: did anyone try to solve a similar problem? Would like to hear your solution or alternative ideas, that you think may work. Thanks.

You can execute the following commands on windows on cmd to disconnect and reconnect network.

> ipconfig /release
> ipconfig /renew

Using this you can use the Java Runtime class to execute the command.

Runtime.getRuntime().exec("ipconfig /release");

I have tested this on windows and it works. The Linux equivalent of the cmd commands are as follows

> sudo ifconfig eth0 up
> sudo ifconfig eth0 down

Note that eth0 here is the name of my Ethernet connection. You can list the names of all the connections using

> ifconfig -a

You can look at the following thread to execute bash through Java - How to execute bash command with sudo privileges in Java?

Option 1

Stubbing

You'll have to identify what would be the exception thrown and what will be the component that throws it in a real case scenario. You can do that easily, simulate the scenario in your machine and when the exception is thrown, the stack-trace will tell you exactly what component thrown it.

Then you'll have to extend the component that throws the exception and inject it in the proper place and, ultimately, create an API to trigger that exception.

If you think you need a framework to automate this kind of tests, have a look to to Fitnesse .


Option 2

Simulation

Simulating a real network problem, would be overly complicated and the benefits are not worth the effort in this case (imo).

Anyway... Linux has an excellent built in network emulation layer called netem that allows any kind of seamless interaction with the network traffic. This kernel module is controlled by the tc command line interface.

It's not very easy to get it right when you want to apply those condition to a single port because you'll have to:

  • Netfilter rule to mark the packets that we want to limit
  • Traffic Control policy
  • Filter to bind the packets to the policy

A simple example would be if you want to have 10% packet loss on the whole eth0, in which case you'll use:

tc qdisc change dev eth0 root netem loss 10%

Then you'll have to wrap this functionality in some java controllable way. If I failed on discouraging you, here is a good guide: TrafficControl

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM