t.me/atinfo_chat Telegram группа по автоматизации тестирования

Нестабильный запуск chrome при параллельном запуске через Selenium Grid

Теги: #<Tag:0x00007f9afbf4cd90> #<Tag:0x00007f9afbf4cca0> #<Tag:0x00007f9afbf4cb10>

Добрый день!
Проект на Selenide + TestNG + Maven.
Selenium grid и нода развернуты на Linux: CentOS Linux release 7.4.1708.
Gui: запущен vncserver
Версия selenium-server-standalone-3.8.1.
Chrome 63.0.3239.132
chromedriver 2.33.506092

Стоит задача запускать один тест с разными параметрами параллельно в 150 браузерах Chrome.
При запуске до 100 браузеров все браузеры стартуют, тест отрабатывает.
Больше потоков - часть chromedriver стартует, но запуска браузера не происходит.
Из 132 параллельных потоков сейчас около 30 стабильно не стартуют браузер. При этом chromedriver остается висеть в процессах, на ноде нет открытых сессий.
Логи наводят на мысль что упирается в какое-то ограничение. Но чего?
Что нужно настроить для стабильного запуска браузеров?

Исходя из информации по ссылке, с админом увеличили stack size, с админом увеличили stack size для пользователя под которым запускаются браузеры:
$ ulimit -a
core file size (blocks, -c) 0
data seg size (kbytes, -d) unlimited
scheduling priority (-e) 0
file size (blocks, -f) unlimited
pending signals (-i) 2967130
max locked memory (kbytes, -l) 64
max memory size (kbytes, -m) unlimited
open files (-n) 131070
pipe size (512 bytes, -p) 8
POSIX message queues (bytes, -q) 819200
real-time priority (-r) 0
stack size (kbytes, -s) 131070
cpu time (seconds, -t) unlimited
max user processes (-u) unlimited
virtual memory (kbytes, -v) unlimited
file locks (-x) unlimited

Из обсуждений здесь
Установила параметр DBUS_SESSION_BUS_ADDRESS=/dev/null

Вызов браузера:

 public void setUpBrowser(@Optional("chrome") String browser, @Optional("01")  String threadId, @Optional("адресНоды:6776") String remoteMachine) {
    RemoteWebDriver driver;
    String url = "http://"+remoteMachine + "/wd/hub";

    ChromeOptions chromeOptions = new ChromeOptions();
    chromeOptions.addArguments("--disable-notifications");
    chromeOptions.addArguments("--disable-gpu");
    chromeOptions.addArguments("--no-sandbox");
    new DesiredCapabilities();
    DesiredCapabilities capabilities = DesiredCapabilities.chrome();
    capabilities.setCapability(ChromeOptions.CAPABILITY, chromeOptions);
    capabilities.setBrowserName("chrome");
    capabilities.setPlatform(Platform.LINUX);
    capabilities.setCapability(CapabilityType.UNEXPECTED_ALERT_BEHAVIOUR, UnexpectedAlertBehaviour.IGNORE);
    capabilities.setCapability(CapabilityType.ACCEPT_INSECURE_CERTS, true);
    driver = new RemoteWebDriver(new URL(url), capabilities);
    WebDriverRunner.setWebDriver(driver);
}

Запуск хаба: java -jar selenium-server-standalone-3.8.1.jar -role hub -port 4445 -timeout 30 -browserTimeout 60
Запуск ноды: java -Dwebdriver.chrome.driver=/usr/local/bin/chromedriver -jar selenium-server-standalone-3.8.1.jar -hub http://адресХаба:4445/grid/register -role node -nodeConfig nodeConfig.json

nodeConfig выглядит следующим образом:

{
  "capabilities":
  [
    {
      "browserName": "chrome",
      "maxInstances": 150,
      "seleniumProtocol": "WebDriver",
	  "platform" : "LINUX"
    }
  ],
  "proxy": "org.openqa.grid.selenium.proxy.DefaultRemoteProxy",
  "maxSession": 150,
  "port": 6776,
  "grid_jvm_x_options": "-Xmxg8g -XX:ParallelGCThreads=150",
  "register": true,
  "registerCycle": 5000,
  "nodeStatusCheckTimeout": 5000,
  "nodePolling": 5000,
  "role": "node",
  "unregisterIfStillDownAfter": 60000,
  "downPollingLimit": 2,
  "debug": false,
  "servlets" : [],
  "withoutServlets": [],
  "custom": {}
}

Логи и ошибка:
682 ERROR -
org.openqa.selenium.WebDriverException: unknown error: Chrome failed to start: exited abnormally
(Driver info: chromedriver=2.33.506092 (733a02544d189eeb751fe0d7ddca79a0ee28cce4),platform=Linux 3.10.0-693.11.1.el7.x86_64 x86_64) (WARNING: The server did not provide any stacktrace information)
Command duration or timeout: 61.81 seconds
Build info: version: ‘3.8.1’, revision: ‘6e95a6684b’, time: ‘2017-12-01T19:05:32.194Z’
System info: host: ‘…’, ip: ‘’, os.name: ‘Linux’, os.arch: ‘amd64’, os.version: ‘3.10.0-693.11.1.el7.x86_64’, java.version: ‘1.8.0_151’
Driver info: driver.version: unknown
Command duration or timeout: 62.89 seconds
at sun.reflect.GeneratedConstructorAccessor14.newInstance(Unknown Source)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
at org.openqa.selenium.remote.ErrorHandler.createThrowable(ErrorHandler.java:215)
at org.openqa.selenium.remote.ErrorHandler.throwIfResponseFailed(ErrorHandler.java:167)
at org.openqa.selenium.remote.JsonWireProtocolResponse.lambda$new$0(JsonWireProtocolResponse.java:53)
at org.openqa.selenium.remote.JsonWireProtocolResponse.lambda$getResponseFunction$2(JsonWireProtocolResponse.java:91)
at org.openqa.selenium.remote.ProtocolHandshake.lambda$createSession$24(ProtocolHandshake.java:359)
at java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:193)
at java.util.Spliterators$ArraySpliterator.tryAdvance(Spliterators.java:958)
at java.util.stream.ReferencePipeline.forEachWithCancel(ReferencePipeline.java:126)
at java.util.stream.AbstractPipeline.copyIntoWithCancel(AbstractPipeline.java:498)
at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:485)
at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:471)
at java.util.stream.FindOps$FindOp.evaluateSequential(FindOps.java:152)
at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
at java.util.stream.ReferencePipeline.findFirst(ReferencePipeline.java:464)
at org.openqa.selenium.remote.ProtocolHandshake.createSession(ProtocolHandshake.java:362)
at org.openqa.selenium.remote.ProtocolHandshake.createSession(ProtocolHandshake.java:136)
at org.openqa.selenium.remote.HttpCommandExecutor.execute(HttpCommandExecutor.java:142)
at org.openqa.selenium.remote.RemoteWebDriver.execute(RemoteWebDriver.java:646)
at org.openqa.selenium.remote.RemoteWebDriver.startSession(RemoteWebDriver.java:255)
at org.openqa.selenium.remote.RemoteWebDriver.startSession(RemoteWebDriver.java:237)
at org.openqa.selenium.remote.RemoteWebDriver.(RemoteWebDriver.java:138)
at org.openqa.selenium.remote.RemoteWebDriver.(RemoteWebDriver.java:175)
at ru.globus.base.TestBase.setUpBrowser(TestBase.java:98)
at sun.reflect.GeneratedMethodAccessor3.invoke(Unknown Source)
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:108)
at org.testng.internal.Invoker.invokeConfigurationMethod(Invoker.java:523)
at org.testng.internal.Invoker.invokeConfigurations(Invoker.java:224)
at org.testng.internal.Invoker.invokeConfigurations(Invoker.java:146)
at org.testng.internal.TestMethodWorker.invokeBeforeClassMethods(TestMethodWorker.java:166)
at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:105)
at org.testng.TestRunner.privateRun(TestRunner.java:744)
at org.testng.TestRunner.run(TestRunner.java:602)
at org.testng.SuiteRunner.runTest(SuiteRunner.java:380)
at org.testng.SuiteRunner.access$000(SuiteRunner.java:39)
at org.testng.SuiteRunner$SuiteWorker.run(SuiteRunner.java:414)
at org.testng.internal.thread.ThreadUtil$1.call(ThreadUtil.java:52)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)

В логе ноды встречается: Maximum number of clients reached

В /var/log/messages на период выполнения теста
pulseaudio[32750]: [pulseaudio] protocol-native.c: Warning! Too many connections (64), dropping incoming connection.
kernel: traps: chrome[16787] trap int3 ip:560ddce05e2a sp:7ffd1c693710 error:0
abrt-hook-ccpp: Process 16787 (chrome) of user 1002 killed by SIGTRAP - dumping core
abrt-hook-ccpp: Failed to create core_backtrace: dwfl_getthread_frames failed: No DWARF information found
abrt-server: Package ‘google-chrome-stable’ isn’t signed with proper key
abrt-server: ‘post-create’ on ‘/var/spool/abrt/ccpp-2018-01-19-19:48:58-16787’ exited with 1
abrt-server: Deleting problem directory ‘/var/spool/abrt/ccpp-2018-01-19-19:48:58-16787’
kernel: traps: chrome[18678] trap int3 ip:560ddce05e2a sp:7ffd1c693710 error:0
abrt-hook-ccpp: Process 18678 (chrome) of user 1002 killed by SIGTRAP - ignoring (repeated crash)
kernel: traps: chrome[19050] trap int3 ip:560ddce05e2a sp:7ffd1c693710 error:0
abrt-hook-ccpp: Process 19050 (chrome) of user 1002 killed by SIGTRAP - ignoring (repeated crash)
dbus[1038]: [system] Failed to activate service ‘org.bluez’: timed out
dbus-daemon: dbus[1038]: [system] Failed to activate service ‘org.bluez’: timed out

Это 100 браузеров на одном компе стартуют?

Да, на одном.
Но использование процессоров в это время не более 30% и со свободной памятью проблем нет.

Сделайте 3 ноды вместо одной

Пробовала, аналогично, около 30 браузеров не запускаются.

Смотрите в сторону контейнеризации всего этого добра https://github.com/aerokube/selenoid и https://github.com/aerokube/ggr

2 Симпатий

Чтобы не повторяться посмотрите на мой последний ответ в этом топике(возможно не хватает ресурсов виртуальной машины Java):

В винде иногда бывают проблемы с максимальным количеством одновременно открытых портов, так как порт(сокет) после закрытия не сразу становится доступным для повторного использования, но это, скорее всего, не ваш случай

Чтобы не повторяться посмотрите на мой последний ответ в этом топике(возможно не хватает ресурсов виртуальной машины Java):

Да, тоже об этом думала. Но не помогло.

Есть подозрения, что дело в xorg-server.
https://bbs.archlinux.org/viewtopic.php?id=188052

На что только люди не идут, лишь бы не использовать готовые рабочие инструменты! :slightly_smiling_face:100 браузеров на одной машине это много.Вам выше дали ссылку, Selenoid под ваши задачи идеально подходит - нужно будет выделить несколько мощных виртуалок (32 ядра, 32 гига), связать их GoGridRouter. И все.
Интересно, какая сейчас у вас виртуалка для 100 хром-браузеров? Обычно браузер потребляет минимум 0,5 ядра и 500 Мб, значит 100 браузеров потребуют машину минимум в 50 ядер и 50 гигов - а в реальности еще больше + дисковая подсистема д.б. быстрая.

За Selenoid спасибо, в следующий раз обязательно подумаю о нём.

Пока обошлись тем что есть:

  • параметр DBUS_SESSION_BUS_ADDRESS = /dev/null
  • изменение переменной MAXCLIENTS в xorg-server с 256 до 512.
  • запуск нескольких нод с помощью xvfb-run -a -s “-screen 0 1024x1920x24 -ac +extension RANDR” java -Dwebdriver.chrome.driver=/usr/local/bin/chromedriver -jar selenium-server-standalone-3.8.1.jar -hub http://__/grid/register -role node -nodeConfig nodeConfig.json