3

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 (e.g. 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.

timbre timbre
  • 12,648
  • 10
  • 46
  • 77
  • 1
    just pull out your network cable. – Scary Wombat Dec 16 '15 at 00:32
  • 1
    @Scary Wombat: given I want to do it within automated test, I would need a robot, synchronized with selenium test to do that – timbre timbre Dec 19 '15 at 20:26
  • The problem here is that you said "using JAVA". there is some answer but you'll at least need JNI, because the connectivity issues happens in a layer that is lower than what java can access – snovelli Dec 21 '15 at 17:25
  • @snovelli: I should be able to control it from Java in some way, but it doesn't have to be Java code that breaks the connection. I.e. it's ok if you have another service/component/app that does the actual breaking, as long as I can tell it what to do from Java code. – timbre timbre Dec 21 '15 at 19:36

2 Answers2

2

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

Community
  • 1
  • 1
snovelli
  • 5,804
  • 2
  • 37
  • 50
  • Thanks for detailed answer. We have option 1 on unit test level, but wanted something "more realistic" on user-level testing. – timbre timbre Dec 24 '15 at 03:13
1

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?

Community
  • 1
  • 1
StrikerVillain
  • 3,719
  • 2
  • 24
  • 41
  • Thanks. Although if I will have to do it via script, I'd rather use [tc](http://lartc.org/manpages/tc.txt) or manipulate `iptables`, since disabling network connection or releasing IP is quite different from temporarily losing network connection. – timbre timbre Dec 19 '15 at 20:36