tags:

views:

30

answers:

1

I am trying to do something conceptually simple... We have multiple portlets loading on a Dashboard. I need to measure the load time that each takes. I have implemented a simple StopWatch class, and need to run multiple instance of it simultaneously, for each portlet, while the Dashboard is loading. So the parameters supplied will be - 1. The portlet name, 2. The element to be checked, indicating a successful load. Here is the StopWatch class:

 public class StopWatch implements Runnable {
        private long startTime;
        private long stopTime;
        private String tElement;
        private String tPortletName;

        public StopWatch(String portletName,String element) {
         tElement = element;
         tPortletName = portletName;

        }

        public void start() {
     startTime = System.currentTimeMillis();
        }
        public void stop() {
     stopTime = System.currentTimeMillis();
        }
        public long getTime() {
     return stopTime - startTime;
        }

 @Override
 public void run() {
  selenium.selectFrame(tPortletName);
                StopWatch sw = new StopWatch();
  sw.start();
  while (selenium.isElementPresent(tElement)==false)
              try {
     Thread.sleep(10);
    } catch (InterruptedException e) {
     e.printStackTrace();
    }
   sw.stop();
   long time = sw.getTime();
   System.out.println(tPortletName+" load time="+time);
  }
   }

In the calling program,

StopWatch sw1 = new StopWatch(portlet1,element1);
StopWatch sw2 = new StopWatch(portlet2,element2);
ExecutorService threadExecutor = Executors.newFixedThreadPool(3);

threadExecutor.execute(sw1); // start task1
threadExecutor.execute(sw2); // start task2

Upon running this, I get the following exception:

com.thoughtworks.selenium.SeleniumException: ERROR Server Exception: commandHolder got filled during execution of doCommandWithoutWaitingForAReponse

Any clues on what causes this?

Thanks.

+1  A: 

Most likely the reason is that you are sending commands faster then Selenium can process them.

Anyway this approach should not work since DefaulSelenium and other Selenium classes are not synchronized so if you most likely you will get deadlocks or unpredictable results.

I think you will have to test this in two steps: load dashboard, wait for first portlet, then reload dashboard and wait for second portlet. Do all of this in the main thread, something like:

private void waitForPortlet(String portletName, String element) {
    long startTime = System.currentTimeMillis();

    while (selenium.isElementPresent(element) == false)
        try {
            Thread.sleep(10);
        } catch (Exception e) {
            e.printStackTrace();
        }

    long stopTime = System.currentTimeMillis();

    System.out.println(portletName + " load time=" + (stopTime - startTime));
}

And use:

    waitForPortlet(name1, element1);

    selenium.refresh();

    waitForPortlet(name2, element2);
ZloiAdun
That's a great thought. Though, one concern I have is the skewing of the load time due to caching. Clearing the cache at runtime is something I have been researching up within Selenium for a while, but haven't been able to do so...
Rajat
I think that if you wish to get a precise result, you should restart your Selenium session before every measurement, i.e. get statistics from the "cold" start. Such results will be most honest and you should not have a caching issue
ZloiAdun
Thanks. The problem is that in a test environment, we are using an unsecured connection...hence I need to re-use the same browser profile for every Selenium session (so the exception can be stored). This prevents me from creating new instances. I appreciate your advice.
Rajat