1 package com.atlassian.selenium;
2
3 import com.thoughtworks.selenium.SeleniumCommandTimedOutException;
4 import com.thoughtworks.selenium.SeleniumException;
5
6 import java.lang.reflect.InvocationHandler;
7 import java.lang.reflect.Method;
8 import java.util.ArrayList;
9 import java.util.LinkedList;
10 import java.util.List;
11 import java.util.concurrent.*;
12
13 public class MultiBrowserSeleniumClientInvocationHandler implements InvocationHandler {
14 private List<SeleniumClient> clients;
15 private final long MAX_WAIT;
16 private final boolean VERIFY_RETURN_VALUES;
17 private final boolean PARALLEL;
18
19 private ExecutorService executorService;
20
21 public MultiBrowserSeleniumClientInvocationHandler(List<SeleniumConfiguration> configs, long maxWait,
22 boolean verifyReturnValues, boolean parallel)
23 {
24 clients = new LinkedList<SeleniumClient>();
25
26 for (SeleniumConfiguration config : configs)
27 {
28 SeleniumClient client = new SingleBrowserSeleniumClient(config);
29 client.start();
30 clients.add(client);
31 }
32 this.VERIFY_RETURN_VALUES = verifyReturnValues;
33 this.PARALLEL = parallel;
34
35 if(PARALLEL)
36 {
37 executorService = Executors.newFixedThreadPool(clients.size());
38 this.MAX_WAIT = maxWait;
39 }
40 else
41 {
42
43 executorService = Executors.newSingleThreadExecutor();
44 this.MAX_WAIT = maxWait * clients.size();
45 }
46 }
47
48
49 public synchronized Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
50 Object o;
51
52 List<Future<Object>> futures = new ArrayList(clients.size());
53
54 for (final SeleniumClient client : clients)
55 {
56 futures.add(executorService.submit(new MethodHandlerCallable(method, client, args)));
57 }
58 executorService.awaitTermination(MAX_WAIT, TimeUnit.MILLISECONDS);
59 if(VERIFY_RETURN_VALUES)
60 {
61 verifyReturnValues(futures);
62 }
63
64 return futures.get(0).get();
65 }
66
67 public void verifyReturnValues(List <Future<Object>> futures) throws Throwable
68 {
69 if (futures.size() > 0)
70 {
71 Object first = futures.get(0).get();
72 for(int i = 0; i < clients.size(); i++)
73 {
74 Object value = futures.get(i).get();
75 if (first == null)
76 {
77 if (value != null)
78 {
79 throw createValueMismatchException(clients.get(0), first, clients.get(i), value);
80 }
81 }
82 else
83 {
84 if (!first.equals(value))
85 {
86 throw createValueMismatchException(clients.get(0), first, clients.get(i), value);
87 }
88 }
89 }
90 }
91 }
92
93 protected SeleniumReturnValueMismatch createValueMismatchException(SeleniumClient c1, Object h1,
94 SeleniumClient c2, Object h2) {
95 return new SeleniumReturnValueMismatch(c1.getBrowser(), h1, c2.getBrowser(), h2);
96 }
97
98 }