Зависание тестов при снятии скриншота (java.net.SocketInputStream.socketRead0(Native Method))

webdriver
testng
java
Теги: #<Tag:0x00007f3d45997c88> #<Tag:0x00007f3d45997a08> #<Tag:0x00007f3d45997800>

(Дмитрий Гордиенко) #1

Доброго времени суток!

Тесты выполняются на Jenkins CI (1.632), который ранится на CentOS 7 . Используется связка TestNg – Selenide – Allure.

Коллеги, столкнулся с проблемой зависания тестов при снятии скриншота, а именно:
абсолютно со случайной частотой возникает ситуация, когда джоба с тестами весит по 3 часа, хотя все тесты ограничены во времени выполнения (@timeOut), часть thread dumpa-a приведена ниже. Может кто-то сталкивался и может поделится решением?

"Forwarding screenshot on session 560b7e75-f39c-4f92-ad21-911cbc8526cc to remote" #327 prio=5 os_prio=0 tid=0x00007f56fc037800 nid=0xc408 runnable [0x00007f5744872000]
   java.lang.Thread.State: RUNNABLE
	at java.net.SocketInputStream.socketRead0(Native Method)
	at java.net.SocketInputStream.socketRead(SocketInputStream.java:116)
	at java.net.SocketInputStream.read(SocketInputStream.java:171)
	at java.net.SocketInputStream.read(SocketInputStream.java:141)
	at org.apache.http.impl.io.SessionInputBufferImpl.streamRead(SessionInputBufferImpl.java:139)
	at org.apache.http.impl.io.SessionInputBufferImpl.fillBuffer(SessionInputBufferImpl.java:155)
	at org.apache.http.impl.io.SessionInputBufferImpl.readLine(SessionInputBufferImpl.java:284)
	at org.apache.http.impl.conn.DefaultHttpResponseParser.parseHead(DefaultHttpResponseParser.java:140)
	at org.apache.http.impl.conn.DefaultHttpResponseParser.parseHead(DefaultHttpResponseParser.java:57)
	at org.apache.http.impl.io.AbstractMessageParser.parse(AbstractMessageParser.java:261)
	at org.apache.http.impl.DefaultBHttpClientConnection.receiveResponseHeader(DefaultBHttpClientConnection.java:165)
	at org.apache.http.impl.conn.CPoolProxy.receiveResponseHeader(CPoolProxy.java:167)
	at org.apache.http.protocol.HttpRequestExecutor.doReceiveResponse(HttpRequestExecutor.java:272)
	at org.apache.http.protocol.HttpRequestExecutor.execute(HttpRequestExecutor.java:124)
	at org.apache.http.impl.execchain.MainClientExec.execute(MainClientExec.java:271)
	at org.apache.http.impl.execchain.ProtocolExec.execute(ProtocolExec.java:184)
	at org.apache.http.impl.execchain.RetryExec.execute(RetryExec.java:88)
	at org.apache.http.impl.execchain.RedirectExec.execute(RedirectExec.java:110)
	at org.apache.http.impl.client.InternalHttpClient.doExecute(InternalHttpClient.java:184)
	at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:71)
	at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:55)
	at org.openqa.selenium.remote.internal.ApacheHttpClient.fallBackExecute(ApacheHttpClient.java:144)
	at org.openqa.selenium.remote.internal.ApacheHttpClient.execute(ApacheHttpClient.java:90)
	at org.openqa.selenium.remote.HttpCommandExecutor.execute(HttpCommandExecutor.java:142)
	at org.openqa.selenium.firefox.internal.NewProfileExtensionConnection.execute(NewProfileExtensionConnection.java:160)
	at org.openqa.selenium.firefox.FirefoxDriver$LazyCommandExecutor.execute(FirefoxDriver.java:380)
	at org.openqa.selenium.remote.RemoteWebDriver.execute(RemoteWebDriver.java:644)
	at org.openqa.selenium.remote.RemoteWebDriver.execute(RemoteWebDriver.java:701)
	at org.openqa.selenium.firefox.FirefoxDriver.getScreenshotAs(FirefoxDriver.java:341)
	at core.modules.ReportAttachments.attachScreenShot(ReportAttachments.java:44)
	at core.services.SelenideImplPage.attachScreenShot(SelenideImplPage.java:70)
	at steps.ААА(AAASteps.java:52)
	at ААА(AAATest.java:33)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at org.testng.internal.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:104)
	at org.testng.internal.InvokeMethodRunnable.runOne(InvokeMethodRunnable.java:54)
	at org.testng.internal.InvokeMethodRunnable.run(InvokeMethodRunnable.java:44)
	at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
	at java.util.concurrent.FutureTask.run(FutureTask.java:266)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
	at java.lang.Thread.run(Thread.java:745)

(Artur Korobeynyk) #2

	at steps.ААА(AAASteps.java:52)
	at ААА(AAATest.java:33)

Шаг и вправду так называется или у вас где-то переполнение буффера символом А идет?
Проверьте создание соккета, сколько байт он может считывать, не блокирует ли его фаервол или прокси, антивирус?


(Дмитрий Гордиенко) #3

"ААА" ето я заминел полное название, всетаки код боевой...
"Симптом зависания" не регулярен, но за совет спс, проверю фаервол.


(Artur Korobeynyk) #4

socket read is a blocking operation. It will block until there is more data, the end of stream is reached or the connection is closed.

Вобщем если вам не придет ответ от сервера, тест будет его ждать. Если сервер не отправил ошибку или ответ, или был сбой сети, ваш тест зависнет. Обработайте как исключение с таймаутом. Джавы не знаю, но наверняка решение есть либо в виде нескольких потоков, либо в самом методе время ожидания можно поставить

Либо

setConnectTimeout()

(Aleksandr) #5

Тоже на днях появилась подобная проблема.

когда джоба с тестами весит по 3 часа

Это потому что в HttpClientFactory в Selenium стоит дефолтный таймаут 3 часа на socket соединения.

private static final int TIMEOUT_THREE_HOURS = (int) SECONDS.toMillis(60 * 60 * 3);

В данном случае это соединение между Selenium и браузером.
Попробуйте задать socketTimeout вручную, например так

private static final int TIMEOUT_TWO_MINUTES = (int) SECONDS.toMillis(60 * 2);
private static final int TIMEOUT_THREE_MINUTES = (int) SECONDS.toMillis(60 * 3);

// Это для Chrome, выдрано из ChromeDriverCommandExecutor
private static final Map<String, CommandInfo> CHROME_COMMAND_NAME_TO_URL =
            ImmutableMap.of("launchApp", new CommandInfo("/session/:sessionId/chromium/launch_app", HttpMethod.POST));

DesiredCapabilities dCaps = DesiredCapabilities.chrome();

ChromeDriverService.Builder builder = new ChromeDriverService.Builder();
builder.withLogFile(new File("chrome.log"));
builder.usingAnyFreePort();
ChromeDriverService service = builder.build();

service.start();

HttpCommandExecutor executor = new HttpCommandExecutor(
	CHROME_COMMAND_NAME_TO_URL,
	service.getUrl(),
	new ApacheHttpClient.Factory(new HttpClientFactory(TIMEOUT_TWO_MINUTES, TIMEOUT_THREE_MINUTES))
);

WebDriver driver = new RemoteWebDriver(executor, dCaps);

(Дмитрий Гордиенко) #6

Спасибо!
Прелесть какая... И "централизованной" настройки для всего Selenium (всех реализаций вебдрайвера) нет? Странно что раньше ета ошибка не появлялась :frowning:


(Aleksandr) #7

Мне не удалось найти. К сожалению это лишь способ не ждать 3 часа, а уронить тест сразу. Плюс после этого браузер перестают отвечать вебдрайверу, так что мне сильно не помогло :unamused: Надо искать первопричину.