Почему Maven Surefire 3 не может выполнить мой тест на огурец в Дженкинс с помощью Docker? - PullRequest
0 голосов
/ 07 мая 2019

У меня есть проект Java с некоторыми тестами Cucumber и некоторыми обычными тестами JUnit, управляемыми Maven.

Я хочу запустить тесты в Jenkins, используя Docker, поэтому я написал это Jenkinsfile:

pipeline {
    agent {
        docker {
            image 'maven:3.6.1'
        }
    }
    stages {
        stage('build') {
            steps {
                sh 'mvn clean verify -Dmaven.test.failure.ignore=true'
            }
            post {
                success {
                    junit 'target/surefire-reports/**/*.xml'
                }
            }
        }
    }
}

Когда я запускаю сборку, обычные тесты проходят, но тесты Cucumber терпят неудачу с:

Сообщение об ошибке

URI имеет компонент запроса

StackTrace

java.lang.IllegalArgumentException: URI имеет компонент запроса

Только когда я отключу trimStackTrace для maven-surefire-plugin, я также получу детали:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-surefire-plugin</artifactId>
    <configuration>
        <trimStackTrace>false</trimStackTrace>
    </configuration>
</plugin>
java.lang.IllegalArgumentException: URI has a query component
    at java.base/java.io.File.<init>(File.java:427)
    at cucumber.runtime.io.ZipResourceIterator.<init>(ZipResourceIterator.java:22)
    at cucumber.runtime.io.ZipResourceIteratorFactory.createIterator(ZipResourceIteratorFactory.java:24)
    at cucumber.runtime.io.ZipThenFileResourceIteratorFactory.createIterator(ZipThenFileResourceIteratorFactory.java:22)
    at cucumber.runtime.io.DelegatingResourceIteratorFactory.createIterator(DelegatingResourceIteratorFactory.java:49)
    at cucumber.runtime.io.ClasspathResourceIterable.iterator(ClasspathResourceIterable.java:35)
    at cucumber.runtime.io.ResourceLoaderClassFinder.getDescendants(ResourceLoaderClassFinder.java:25)
    at cucumber.runtime.Reflections.instantiateSubclasses(Reflections.java:34)
    at cucumber.runtime.BackendModuleBackendSupplier.loadBackends(BackendModuleBackendSupplier.java:52)
    at cucumber.runtime.BackendModuleBackendSupplier.get(BackendModuleBackendSupplier.java:39)
    at cucumber.runner.ThreadLocalRunnerSupplier.createRunner(ThreadLocalRunnerSupplier.java:42)
    at cucumber.runner.ThreadLocalRunnerSupplier.access$000(ThreadLocalRunnerSupplier.java:13)
    at cucumber.runner.ThreadLocalRunnerSupplier$1.initialValue(ThreadLocalRunnerSupplier.java:22)
    at cucumber.runner.ThreadLocalRunnerSupplier$1.initialValue(ThreadLocalRunnerSupplier.java:19)
    at java.base/java.lang.ThreadLocal.setInitialValue(ThreadLocal.java:195)
    at java.base/java.lang.ThreadLocal.get(ThreadLocal.java:172)
    at cucumber.runner.ThreadLocalRunnerSupplier.get(ThreadLocalRunnerSupplier.java:38)
    at cucumber.api.junit.Cucumber$RunCucumber.evaluate(Cucumber.java:146)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
    at org.apache.maven.surefire.junit4.JUnit4Provider.execute(JUnit4Provider.java:365)
    at org.apache.maven.surefire.junit4.JUnit4Provider.executeWithRerun(JUnit4Provider.java:273)
    at org.apache.maven.surefire.junit4.JUnit4Provider.executeTestSet(JUnit4Provider.java:238)
    at org.apache.maven.surefire.junit4.JUnit4Provider.invoke(JUnit4Provider.java:159)
    at org.apache.maven.surefire.booter.ForkedBooter.invokeProviderInSameClassLoader(ForkedBooter.java:384)
    at org.apache.maven.surefire.booter.ForkedBooter.runSuitesInProcess(ForkedBooter.java:345)
    at org.apache.maven.surefire.booter.ForkedBooter.execute(ForkedBooter.java:126)
    at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:418)

Это довольно загадочно, потому что:

  • при локальном запуске mvn verify работает
  • при использовании agent any в Dockerfile вместо образа Maven Docker работает
  • при использовании maven-surefire-plugin версии 2.22.2 вместо 3.0.0-M3 работает

Я вошел как Дженкинс и посмотрел в рабочем пространстве:

$ sudo su - jenkins

$ ls /var/lib/jenkins/workspace/question-mark-dir_master
'?'   Jenkinsfile   LICENSE   pom.xml   README.md   src   target

Там находится каталог с вопросительным знаком (?), и он содержит каталог .m2 со всеми артефактами, необходимыми для проекта. Я подозреваю, что это может быть причиной исключения, потому что тогда в пути к классам есть вопросительные знаки, и именно те, которые представляют компонент запроса URI.

На данный момент я могу понизиться до maven-surefire-plugin версии 2.22.2 в качестве обходного пути. Но в чем здесь проблема?

  • Может ли это быть ошибкой в ​​новом maven-surefire-plugin? Судя по трассировке стека, я бы на это не ставил.
  • Это проблема в Jenkins или в образе докера Maven (какой?), Из-за которой у каталога такое неудачное имя?
  • Я что-то не так делаю?

Если вы хотите попробовать это, у меня есть MVCE . В моей локальной установке Jenkins я создал новый проект типа «Многоотраслевой конвейер», а в «Источники веток» я добавил в качестве репозитория проекта git свой локальный проект git. Других изменений нет.

screenshot

1 Ответ

2 голосов
/ 08 мая 2019

Объединив комментарий TYY к вопросу и документацию образа maven docker , я смог настроить Jenkinsfile таким образом, чтобы избежать создания каталога с вопросительным знаком.

Нам нужно сообщить Maven о домашнем каталоге пользователя и сопоставить его с каталогом вне контейнера.

pipeline {
    agent {
        docker {
            image 'maven:3.6.1'
            args '-v /var/lib/jenkins:/usr/src/mymaven -w /usr/src/mymaven'
        }
    }
    stages {
        stage('build') {
            steps {
                sh 'MAVEN_OPTS="-Duser.home=/usr/src/mymaven" mvn clean verify -Dmaven.test.failure.ignore=true'
            }
            // ...
        }
    }
}
  • -v /var/lib/jenkins:/usr/src/mymaven отображает каталог /var/lib/jenkins вхост для каталога /usr/src/mymaven внутри контейнера
  • -w /usr/src/mymaven устанавливает рабочий каталог внутри контейнера
  • MAVEN_OPTS="-Duser.home=/usr/src/mymaven" устанавливает свойство Java user.home для Maven

Доказательство того, что оно работает, на ветке MCVE.

...