1

I have to test that a Flash Player is correctly sending requests over the network. For that, I use BrowserMob Proxy to capture traffic. My issue is I have to wait the end of the video played to test the final request. So as temp solution, in my test, I put a Thread.sleep(videoDuration). But IMO it's not really nice, and overall, the duration can change. BrowserMob allow to add interceptor on the requests. So I think about notify and wait function.

Here my first try:

protected static boolean percent100Done;

protected static final Object percent100lock = new Object();

@BeforeClass
public static void addInterceptor() {
    ProxyServer server = Server.init();
    server.addRequestInterceptor((BrowserMobHttpRequest request, Har har) -> {
        String percent = request.getProxyRequest().getParameter("percent");
        if("100".equals(percent)) {
            percent100Done = true;
            synchronized (percent100lock) {
                percent100lock.notify();
            }
        }
    });
}

@Test
public void testFinalRequest() throws InterruptedException {
    driver.get(myurl);
    synchronized (percent100lock) {
        while (!percent100Done) {
            percent100lock.wait();
        }
    }
    //test continue
}

I test this code, and it works. But it seems a bit dirty, especially the new Object line. What happen if I have to add notification for 25, 50 and 75 percents? I will have to 3 others booleans and lock?

tetienne
  • 369
  • 3
  • 13

1 Answers1

1

Why not store the percentage and have a generic "progress" event, like how XMLHTTPRequest works?

protected static int percent;
protected static final Object progressLock = new Object();

@BeforeClass
public static void addInterceptor() {
    ProxyServer server = Server.init();
    server.addRequestInterceptor((BrowserMobHttpRequest request, Har har) -> {
        synchronized(progressLock) {
            percent = Integer.parseInt(request.getProxyRequest().getParameter("percent"));
            progressLock.notify();
        }
    });
}

@Test
public void testFinalRequest() throws InterruptedException {
    driver.get(myurl);
    synchronized (progressLock) {
        int lastPercent = -1;
        while (percent != 100) {
            if (lastPercent < 50 && percent >= 50) {
                System.out.println("50%");
            }
            lastPercent = percent;
            progressLock.wait();
        }
    }
    //test continue
}

In terms of weirdness, I think your solution is fine. It looks strange, but every Object has a lock, so you might as well use it. If you needed to do something more complicated, you might want to look at Lock and it's subclasses. For example, with a ReadWriteLock, multiple readers can hold the lock at the same time, but only one writer can. It doesn't look like you have multiple readers though (and I wouldn't expect locking to effect the performance of this program much).

Brendan Long
  • 53,280
  • 21
  • 146
  • 188
  • Thanks for your tips. Use a *percent* variable instead of a *100percent* variable is really clever. About Lock and Condition, if I understood correctly, for you it doesn't make sense I use them just for performance reason? If we talk only about readability, does Lock and Condition can help? – tetienne Mar 20 '15 at 13:41
  • @tetienne `synchronized` might be a bit easier to read, since it's a block that Java handles automatically. With a `Lock` object, you'd need to a `try` / `finally` to properly unlock it in case of an `InterruptedException` (or `RuntimeException`s). For performance, it would be best to benchmark it, but I doubt the performance matters in this case. – Brendan Long Mar 20 '15 at 15:29