Почему мой функциональный тест Arquillian Drone не работает на GitLab CI?

Тест, который работает нормально локально, не проходит на общих участниках GitLab CI gitlab.com (MCVE находится по адресу https://gitlab.com/krichter/gitlab-ci-file-creation, журнал - по адресу https://gitlab.com/krichter/gitlab-ci-file-creation/-/jobs/40064276), поскольку во время извлечения веб-драйвера Arquillian каталог не может быть создан или считается не существующим в Java (подробности см. ниже):

Nov 13, 2017 7:31:32 AM org.glassfish.deployment.admin.DeployCommand execute
INFO: 664320b4-384a-414a-b0b4-546937428842 was successfully deployed in 7,496 milliseconds.
Nov 13, 2017 7:31:33 AM org.arquillian.spacelift.Spacelift$SpaceliftInstance <init>
INFO: Initialized Spacelift from defaults, workspace: /builds/krichter/gitlab-ci-file-creation, cache: /root/.spacelift/cache
Drone: downloading phantomjs-2.1.1-linux-x86_64.tar.bz2 from https://bitbucket.org/ariya/phantomjs/downloads/phantomjs-2.1.1-linux-x86_64.tar.bz2 to /root/.arquillian/drone/phantomjs/2.1.1/phantomjs-2.1.1-linux-x86_64.tar.bz2 
................
Nov 13, 2017 7:31:34 AM org.jboss.arquillian.core.impl.ObserverImpl resolveArguments
WARNING: Argument 1 for UpdateTestResultBeforeAfter.update is null. It won't be invoked.
Nov 13, 2017 7:31:34 AM org.jboss.arquillian.core.impl.ObserverImpl resolveArguments
WARNING: Argument 1 for UpdateTestResultBeforeAfter.update is null. It won't be invoked.
Nov 13, 2017 7:31:34 AM org.jboss.arquillian.core.impl.ObserverImpl resolveArguments
WARNING: Argument 1 for ReusableRemoteWebDriverExtension.destroyLastRemoteWebDriver is null. It won't be invoked.
Nov 13, 2017 7:31:35 AM com.sun.enterprise.admin.cli.embeddable.DeployerImpl undeploy
INFO: 664320b4-384a-414a-b0b4-546937428842 was successfully undeployed
Tests run: 1, Failures: 0, Errors: 1, Skipped: 0, Time elapsed: 19.022 sec <<< FAILURE! - in richtercloud.gitlab.ci.file.creation.GitLabCIIT
testSomething(richtercloud.gitlab.ci.file.creation.GitLabCIIT)  Time elapsed: 2.195 sec  <<< ERROR!
java.lang.IllegalStateException: Something bad happened when Drone was trying to download and prepare a binary. For more information see the cause.
    at org.jboss.arquillian.drone.webdriver.binary.handler.AbstractBinaryHandler.checkAndSetBinary(AbstractBinaryHandler.java:62)
    at org.jboss.arquillian.drone.webdriver.factory.PhantomJSDriverFactory.getCapabilities(PhantomJSDriverFactory.java:99)
    at org.jboss.arquillian.drone.webdriver.factory.PhantomJSDriverFactory.createInstance(PhantomJSDriverFactory.java:72)
    at org.jboss.arquillian.drone.webdriver.factory.PhantomJSDriverFactory.createInstance(PhantomJSDriverFactory.java:37)
    at org.jboss.arquillian.drone.webdriver.factory.WebDriverFactory.createInstance(WebDriverFactory.java:127)
    at org.jboss.arquillian.drone.webdriver.factory.WebDriverFactory.createInstance(WebDriverFactory.java:38)
    at org.jboss.arquillian.drone.impl.DroneConfigurator$1.createInstance(DroneConfigurator.java:112)
    at org.jboss.arquillian.drone.impl.CachingCallableImpl.call(CachingCallableImpl.java:44)
    at org.jboss.arquillian.core.impl.threading.ThreadedExecutorService$ContextualCallable.call(ThreadedExecutorService.java:89)
    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)
Caused by: java.lang.IllegalStateException: The phantomJS binary is not present on the expected path target/drone/1c947d57fce2f21ce0b43fe2ed7cd361/phantomjs-2.1.1-linux-x86_64/bin/phantomjs
    at org.jboss.arquillian.drone.webdriver.binary.handler.PhantomJSDriverBinaryHandler.prepare(PhantomJSDriverBinaryHandler.java:56)
    at org.jboss.arquillian.drone.webdriver.binary.handler.AbstractBinaryHandler.downloadAndPrepare(AbstractBinaryHandler.java:226)
    at org.jboss.arquillian.drone.webdriver.binary.handler.AbstractBinaryHandler.downloadAndPrepare(AbstractBinaryHandler.java:208)
    at org.jboss.arquillian.drone.webdriver.binary.handler.AbstractBinaryHandler.downloadAndPrepare(AbstractBinaryHandler.java:175)
    at org.jboss.arquillian.drone.webdriver.binary.handler.AbstractBinaryHandler.checkAndSetBinary(AbstractBinaryHandler.java:60)
    ... 12 more

Nov 13, 2017 7:31:36 AM org.jboss.arquillian.core.impl.ObserverImpl resolveArguments
WARNING: Argument 1 for SeleniumServerExecutor.stopSeleniumServer is null. It won't be invoked.
Nov 13, 2017 7:31:36 AM org.glassfish.admin.mbeanserver.JMXStartupService shutdown
INFO: JMXStartupService and JMXConnectors have been shut down.
JdbcRuntimeExtension,  getAllSystemRAResourcesAndPools = [GlassFishConfigBean.org.glassfish.jdbc.config.JdbcResource, GlassFishConfigBean.org.glassfish.jdbc.config.JdbcResource, GlassFishConfigBean.org.glassfish.jdbc.config.JdbcConnectionPool, GlassFishConfigBean.org.glassfish.jdbc.config.JdbcConnectionPool, GlassFishConfigBean.org.glassfish.jdbc.config.JdbcConnectionPool, GlassFishConfigBean.org.glassfish.jdbc.config.JdbcResource]
Nov 13, 2017 7:31:36 AM com.sun.enterprise.v3.server.AppServerStartup stop
INFO: Shutdown procedure finished

я использую

<dependencies>
    [...]    
    <dependency>
        <groupId>org.jboss.shrinkwrap.descriptors</groupId>
        <artifactId>shrinkwrap-descriptors-api-javaee</artifactId>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.jboss.arquillian.junit</groupId>
        <artifactId>arquillian-junit-container</artifactId>
        <scope>test</scope>
    </dependency>

    <dependency>
        <groupId>org.jboss.shrinkwrap.resolver</groupId>
        <artifactId>shrinkwrap-resolver-depchain</artifactId>
        <type>pom</type>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.jboss.arquillian.graphene</groupId>
        <artifactId>graphene-webdriver</artifactId>
        <version>2.2.0</version>
        <type>pom</type>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.seleniumhq.selenium</groupId>
        <artifactId>htmlunit-driver</artifactId>
    </dependency>
    <dependency>
        <groupId>net.sourceforge.htmlunit</groupId>
        <artifactId>htmlunit</artifactId>
        <version>2.24</version>
    </dependency>
    <dependency>
        <groupId>org.seleniumhq.selenium</groupId>
        <artifactId>selenium-java</artifactId>
    </dependency>
    <dependency>
        <groupId>org.seleniumhq.selenium</groupId>
        <artifactId>selenium-firefox-driver</artifactId>
    </dependency>
<!--        <dependency>
        <groupId>com.google.guava</groupId>
        <artifactId>guava</artifactId>
        <version>20.0</version>
    </dependency>-->
    <dependency>
        <groupId>ru.yandex.qatools.ashot</groupId>
        <artifactId>ashot</artifactId>
        <version>1.5.3</version>
    </dependency>
    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-core</artifactId>
        <version>2.9.2</version>
    </dependency>
</dependencies>
<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.jboss.arquillian</groupId>
            <artifactId>arquillian-bom</artifactId>
            <version>1.1.13.Final</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
        <dependency>
            <groupId>org.jboss.arquillian.selenium</groupId>
            <artifactId>selenium-bom</artifactId>
            <version>3.7.0</version>
                <!-- - 3.3.1, 3.2.0 and 3.1.0 cause   required: java.util.function.Function<? super org.openqa.selenium.WebDriver,V>
                        found: org.openqa.selenium.support.ui.ExpectedCondition<org.openqa.selenium.WebElement>
                        reason: cannot infer type-variable(s) V
                        (argument mismatch; org.openqa.selenium.support.ui.ExpectedCondition<org.openqa.selenium.WebElement> cannot be converted to java.util.function.Function<? super org.openqa.selenium.WebDriver,V>)
                - 3.0.1 causes java.lang.IllegalAccessError: tried to access class org.openqa.selenium.os.ExecutableFinder from class org.openqa.selenium.phantomjs.PhantomJSDriverService when using phantomjs driver
                - 3.6.0 causes `Unrecognized platform: linux-unknown-64bit`
                    which one is supposed to work around using 3.5.3
                    <ref>https://github.com/SeleniumHQ/selenium/issues/4781</ref>-->
            <type>pom</type>
            <scope>import</scope>
        </dependency>
        <dependency>
            <groupId>org.jboss.arquillian.extension</groupId>
            <artifactId>arquillian-drone-bom</artifactId>
            <version>2.1.0</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

<profiles>
    <profile>
        <id>arquillian-glassfish-embedded</id>
        <activation>
            <activeByDefault>true</activeByDefault>
        </activation>
        <dependencies>
            <dependency>
                <groupId>org.jboss.arquillian.container</groupId>
                <artifactId>arquillian-glassfish-embedded-3.1</artifactId>
                <version>1.0.1</version>
            </dependency>
            <dependency>
                <groupId>fish.payara.extras</groupId>
                <artifactId>payara-embedded-all</artifactId>
                <version>4.1.2.174-SNAPSHOT</version>
                    <!-- - 4.1.2.173 causes `java.lang.NoClassDefFoundError: fish/payara/nucleus/healthcheck/stuck/StuckThreadsStore`
                            - 4.1.2.172 causes `Caused by: java.lang.ClassNotFoundException: fish.payara.notification.eventbus.EventbusMessage` -->
                <scope>test</scope>
            </dependency>
        </dependencies>
        <build>
            <testResources>
                <testResource>
                    <directory>src/test/resources</directory>
                </testResource>
                <testResource>
                    <directory>src/test/resources-glassfish-embedded</directory>
                </testResource>
            </testResources>
            <plugins>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-surefire-plugin</artifactId>
                    <version>2.12</version>
                    <configuration>
                    </configuration>
                </plugin>
            </plugins>
        </build>
    </profile>
</profiles>

и активировал профиль.

Я скачал, извлек и исследовал phantomjs-2.1.1-linux-x86_64.tar.bz2 с http://phantomjs.org/download.html и подтвердил, что phantomjs-2.1.1-linux-x86_64/examples/colorwheel.js существует внутри него. Arquillian Drone Webdriver использует сумму MD5 1c947d57fce2f21ce0b43fe2ed7cd361 в качестве целевого каталога, который соответствует одному из загруженных .tar.bz2,

Ошибка находится в Arquillian Spacelift, который используется Arquillian Drone для извлечения драйвера phantomjs и который вы не можете видеть из stacktrace, потому что Spacelift игнорирует сбои создания каталога (см. https://github.com/arquillian/arquillian-spacelift/pull/34 для деталей и предлагаемого исправления, которое вы можете использовать, указав

- git clone --branch file_utils_mkdir https://github.com/krichter722/arquillian-spacelift.git && cd arquillian-spacelift && mvn --batch-mode install && cd ..

в main работа в .gitlab-ci.yml и изменение зависимости Spacelift от 1.0.2 до 1.0.3-SNAPSHOT в POM.

Изменение источника Spacelift таким же образом, как описано выше, добавление явного создания каталога и операторов touch и даже использование Python изнутри Java, чтобы убедиться, что каталог создан с

int pythonDebugReturncode = Runtime.getRuntime().exec(new String[] {"python3",
        "-c",
        String.format("'import os;os.makedirs(\"%s\");'",
                file.getParentFile().getAbsoluteFile().getAbsolutePath())}).waitFor();
System.out.println("pythonDebugReturncode: "+pythonDebugReturncode);
pythonDebugReturncode = Runtime.getRuntime().exec(new String[] {"python3",
        "-c",
        String.format("'from pathlib import Path;Path(\"%s\").touch();'",
                file.getAbsoluteFile().getAbsolutePath())}).waitFor();
System.out.println("pythonDebugReturncode: "+pythonDebugReturncode);

результат в 0печатаются как коды возврата, но каталог используется с относительным путем для сбоя в коде Java.

Я попробовал докер образы ubuntu:xenial, ubuntu:trusty, ubuntu:artful, debian:sid а также debian:buster, В качестве образов докера можно использовать только системы на основе Linux. У меня нет надежды получить больше информации, протестировав больше изображений.

Я испытываю

java.net.UnknownHostException: runner-3bd5f424-project-4630314-concurrent-0: runner-3bd5f424-project-4630314-concurrent-0: Temporary failure in name resolution
    at java.net.InetAddress.getLocalHost(InetAddress.java:1505)

но я предполагаю, что это не имеет значения для проблемы, поскольку сетевые файловые системы не задействованы, и разрешение имен во время получения разрешения не используется, так как сборка выполняется как root пользователь.

1 ответ

Решение

Arquillian Spacelift или Arquillian Drone Webdriver не могут разрешить рабочий каталог, который не изменяется, если Maven запускается в корне проекта агрегатора и последовательно основывается на Maven. Я сообщил об этом по адресу https://issues.jboss.org/browse/ARQ-2154.

Это означает, что нужно разделить нормальный пробег mvn install на бегу, делая компиляцию с -DskipTests=true -DskipITs=true а затем измените каталог на каталог подмодуля и запустите mvn verify,

Другие вопросы по тегам