View Javadoc

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              // i.e. sequential execution
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<Future<Object>>(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  }