Maven Exec 插件被阻止,HTTP 服务器在执行集成测试后启动

Maven Exec Plugin is Blocked and HTTP Server starts after Integration Tests are executed

我一直在尝试将我们的集成测试转换为使用 Maven Exec 插件来启动服务器,但它只会在集成测试执行后启动 HTTP 服务器,即使我指定了 pre-integration-test .

问题

Q1。之后还有其他方法可以启动集成测试吗?

Q2。有没有办法让集成阶段等待服务器启动?

Q3。 Maven Exec 和 Bazaar Maven Exec 插件有什么区别?

注意: 以前使用 bazaar maven exec plugin 可以正常工作,但现在已经损坏,似乎无法在 JDK 11.0.9 上恢复工作詹金斯

下面是我们的 POM 片段,我们有各种其他插件创建 jar 并启动 MockServer。

        <plugins>
            <plugin>
                <groupId>org.codehaus.mojo</groupId>
                <artifactId>exec-maven-plugin</artifactId>
                <version>3.0.0</version>
                <executions>
                    <execution>
                        <id>exec</id>
                        <phase>pre-integration-test</phase>
                        <goals>
                            <goal>exec</goal>
                        </goals>
                    </execution>
                </executions>
                <configuration>
                    <asyncDestroyOnShutdown>true</asyncDestroyOnShutdown>
                    <executable>java</executable>
                    <commandlineArgs>-Dserver.port=8089 -jar /gitRepos/public-api/target/api-jar-with-dependencies.jar</commandlineArgs>
                    <async>true</async>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-failsafe-plugin</artifactId>
                <version>3.0.0-M5</version>
                <executions>
                    <execution>
                        <goals>
                            <goal>verify</goal>
                        </goals>
                    </execution>
                </executions>
                <configuration>
                    <excludedGroups>${it.excluded}</excludedGroups>
                    <argLine>--add-opens=java.base/jdk.internal.misc=ALL-UNNAMED</argLine>
                    <argLine>
                        --illegal-access=permit
                    </argLine>
                </configuration>
            </plugin>
          </plugins>


<!--            this what was previously working. -->
<!--            <plugin>-->
<!--                <groupId>com.bazaarvoice.maven.plugins</groupId>-->
<!--                <artifactId>process-exec-maven-plugin</artifactId>-->
<!--                <version>0.9</version>-->
<!--                <configuration>-->
<!--                    <processLogFile>${project.build.directory}/my-log.log</processLogFile>-->
<!--                </configuration>-->
<!--            </plugin>-->

对我来说奇怪的部分是 HTTP 服务器在集成测试后启动,就像其他插件阻止服务器启动一样。请参阅下面的日志。

[DEBUG] Freed 4 thread-local buffer(s) from thread: nioEventLoopGroup-3-20
[DEBUG] Freed 4 thread-local buffer(s) from thread: nioEventLoopGroup-3-19
[DEBUG] Freed 5 thread-local buffer(s) from thread: nioEventLoopGroup-3-28
[INFO] [main] 13:13:37.594 [main] INFO  c.i.p.s.Server - Grizzly ThreadPool for listener grizzly set to 24 worker threads.
[INFO] [main] 13:13:37.724 [main] INFO  o.g.g.http.server.NetworkListener - Started listener bound to [0.0.0.0:8089]
[INFO] [main] 13:13:37.726 [main] INFO  o.g.grizzly.http.server.HttpServer - [HttpServer] Started.

感谢您在问题下方发表评论。

在深入了解您的问题后,我决定重现您的怀疑并得出结论,exec-maven-plugin 的一切都按预期工作。

让我解释一下——我没有改变你的 pom.xml 片段,只实现了一个小的 Java main class,它每 100 毫秒打印一行。

public class Ocp {
    public static void main(String[] args) {
        IntStream.range(1, 100).forEach(i -> {
            System.err.println("====== " + i);
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });
    }
}

结果如下:

~/dev/git/so-mvn$ mvn clean verify
[INFO] Scanning for projects...
[INFO] 
[INFO] ---------------------------< de.mle:so-mvn >----------------------------
[INFO] Building Whosebug 0.0.1-SNAPSHOT
[INFO] --------------------------------[ jar ]---------------------------------
[INFO] 

***intentionally left out***

[INFO] --- maven-jar-plugin:2.4:jar (default-jar) @ so-mvn ---
[INFO] Building jar: /home/marco/dev/git/so-mvn/target/so-mvn-0.0.1-SNAPSHOT.jar
[INFO] 
[INFO] --- exec-maven-plugin:3.0.0:exec (exec) @ so-mvn ---
[INFO] 
[INFO] --- maven-failsafe-plugin:3.0.0-M5:integration-test (default) @ so-mvn ---
====== 1
====== 2
====== 3
====== 4
[INFO] 
[INFO] -------------------------------------------------------
[INFO]  T E S T S
[INFO] -------------------------------------------------------
====== 5
====== 6
====== 7
====== 8
[INFO] Running so.mvn.Ocp11IT
====== 9
[INFO] Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.057 s - in so.mvn.Ocp11IT
[INFO] 
[INFO] Results:
[INFO] 
[INFO] Tests run: 1, Failures: 0, Errors: 0, Skipped: 0
[INFO] 
[INFO] 
[INFO] --- maven-failsafe-plugin:3.0.0-M5:verify (default) @ so-mvn ---
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  2.398 s
[INFO] Finished at: 2021-02-12T19:17:24+01:00
[INFO] ------------------------------------------------------------------------

如您所见,该过程明显在集成测试阶段(Q1 和 Q2)之前开始。仅由于您的 async 配置,集成测试根本不会等待我的存根服务器完成启动。所以这里的 Maven 一切都很好。

您提到的 bazaarvoice plugin 只是做了一个小技巧来缓解这种情况。它有两个特性,它们会稍等片刻,直到他们“开始”进行集成测试。他们是:

  • healthcheckUrl:推荐,但可选。您应该提供一个健康检查 url,这样插件会一直等到您的进程的健康检查全部为绿色。如果未提供,插件将等待 waitAfterLaunch 秒后继续。
  • waitAfterLaunch:可选。这指定了启动进程后等待的最长时间(以秒为单位)。如果指定了 healthcheckUrl,那么它将在健康检查通过后立即继续。默认为 30 秒。

总结 在你的例子中,你的 bazaarvoice 插件只等待默认的 30 秒,这似乎足以让你的外部服务器启动。 exec-maven-plugin 中没有这样的“等待”功能,但您可以例如在您的集成测试本身 (Q3) 中以编程方式移动此尚未缺少的健康检查,就像在现实生活中对依赖(微)服务的健康检查一样。另一种选择(我的首选)是,将所有外部服务器依赖项或进程移动到 docker 容器中,然后再次对 (Docker) plugin level.

使用健康检查

如果您看一下我的示例项目及其 little wait for an ES container to come up and the corresponding integration test.

,这对您来说可能是一个很好的开始

在插件级别没有任何等待时间的另一个选项是真正复杂的 Awaitility lib which comes with nice waiting features or polling intervals 就在您的断言中。