Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[FIX] avoid UnreachableBrowserException when creating WebDriver instance #14

Closed
wants to merge 1 commit into from
Closed

[FIX] avoid UnreachableBrowserException when creating WebDriver instance #14

wants to merge 1 commit into from

Conversation

curva
Copy link

@curva curva commented Feb 12, 2013

Summary:
Avoid multiple call for org.webbitserver.HttpResponse#end(), which flushes http response to tcp stream in rare cases. This causes UnreachableBrowserException when creating WebDriver instance (see exception message below [*1]).

Detail:
When a test code creates WebDriver instance, WebDriver(client) sends new session request. If WebDriver(server) receives that request, server renders response using RedirectResult#render() and flushes it using WebbitHttpResponse#end().
But there's a issue that WebbitHttpResponse#end() is called two times (see below[*2]).
WebbitHttpResponse#end() calls Webbit's NettyHttpResponse#end() that flushes http response to tcp stream. So WebDriver client gets same response two times as described below:

HTTP/1.1 303 See Other
Location: /wd/hub/session/

If WebDriver client gets redirect response two times, a CircularRedirectException will be thrown by apache http client which results in UnreachableBrowserException.
That's why WebbitHttpResponse should call webbit's HttpResponse#end() just one time.

Remarks:
(*1) UnreachableBrowserException Stacktrace

org.openqa.selenium.remote.UnreachableBrowserException: Could not start a new session. Possible causes are invalid address of the remote server or browser start-up failure.
Build info: version: '2.29.0', revision: '58258c3', time: '2013-01-17 22:47:00'
System info: os.name: 'Mac OS X', os.arch: 'x86_64', os.version: '10.6.8', java.version: '1.6.0_39'
Driver info: driver.version: AndroidDriver
    at org.openqa.selenium.remote.RemoteWebDriver.execute(RemoteWebDriver.java:527)
    at org.openqa.selenium.remote.RemoteWebDriver.startSession(RemoteWebDriver.java:216)
    at org.openqa.selenium.remote.RemoteWebDriver.<init>(RemoteWebDriver.java:111)
    at org.openqa.selenium.remote.RemoteWebDriver.<init>(RemoteWebDriver.java:129)
    at org.openqa.selenium.android.AndroidDriver.<init>(AndroidDriver.java:81)
    at org.openqa.selenium.android.AndroidDriver.<init>(AndroidDriver.java:73)
    at ReproductionTest.setup(ReproductionTest.java:42)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:45)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:42)
    at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:27)
    at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:30)
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:263)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:68)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:47)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:231)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:60)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:229)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:50)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:222)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:300)
    at org.junit.runners.Suite.runChild(Suite.java:128)
    at org.junit.runners.Suite.runChild(Suite.java:24)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:231)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:60)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:229)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:50)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:222)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:300)
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
    at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
Caused by: org.apache.http.client.ClientProtocolException
    at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:909)
    at org.openqa.selenium.remote.HttpCommandExecutor.fallBackExecute(HttpCommandExecutor.java:331)
    at org.openqa.selenium.remote.HttpCommandExecutor.execute(HttpCommandExecutor.java:310)
    at org.openqa.selenium.remote.RemoteWebDriver.execute(RemoteWebDriver.java:506)
    ... 38 more
Caused by: org.apache.http.client.CircularRedirectException: Circular redirect to 'http://192.168.0.7:8080/wd/hub/session/5559153d-0123-446d-9be4-02e01c8a33c3'
    at org.apache.http.impl.client.DefaultRedirectStrategy.getLocationURI(DefaultRedirectStrategy.java:175)
    at org.apache.http.impl.client.DefaultRedirectStrategy.getRedirect(DefaultRedirectStrategy.java:209)
    at org.apache.http.impl.client.DefaultRequestDirector.handleResponse(DefaultRequestDirector.java:1068)
    at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:545)
    at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:906)
    ... 41 more

(*2) Caller of WebbitHttpResponse#end()
first one is:

  • org.openqa.selenium.remote.server.rest.ResultConfig#handle()

second one is either of them below:

  • org.openqa.selenium.remote.server.renderer.JsonResult#render()
  • org.openqa.selenium.remote.server.renderer.RedirectResult#render()
    -> org.openqa.selenium.remote.server.WebbitHttpResponse#sendRedirect()

Reproduction Code:

import java.util.ArrayList;
import java.util.List;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.android.AndroidDriver;
import org.openqa.selenium.remote.UnreachableBrowserException;

@RunWith(Parameterized.class)
public class ReproductionTest {
    WebDriver driver = null;

    public ReproductionTest(String dummy) {
    }

    @Parameters
    public static List<String[]> dummyData() {
        // Dummy parameter method.
        // This is just for calling setup/tearDown method many times.

        int params = 1000;

        List<String[]> dummy = new ArrayList<String[]>();
        for(int i = 0; i < params; i++) {
            dummy.add(new String[] { "" });
        }

        return dummy;
    }

    @Before
    public void setup() throws Exception {
        try {
            driver = new AndroidDriver();
        } catch(UnreachableBrowserException e) {
            e.printStackTrace();

            // sleep for a while to stop junit
            Thread.sleep(10 * 60 * 1000);
        }
    }

    @After
    public void tearDown() {
        driver.quit();
    }

    @Test
    public void testDummy() throws Throwable {
        // do nothing
    }
}

Verified

This commit was signed with the committer’s verified signature.
Doctor-wu Doctor Wu
…end() method flushes response to tcp stream.
@shs96c
Copy link
Member

shs96c commented Jun 20, 2013

@alex-savchuk
Copy link
Contributor

It was fixed by similar code at revision 2f2cdf3

IlyaNaumovich added a commit to IlyaNaumovich/selenium that referenced this pull request Feb 11, 2018

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
yiming-tang-cs pushed a commit to ponder-lab/selenium that referenced this pull request Jan 2, 2020
yiming-tang-cs pushed a commit to ponder-lab/selenium that referenced this pull request Jan 2, 2020
SeleniumHQ#14:  reply with notify_close even if "we are a client"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants