使用JUnit 5 TestFactory和大量dynamicTest(DynamicContainer/DynamicNode)时出现Java GC开销限制错误

使用JUnit 5 TestFactory和大量dynamicTest(DynamicContainer/DynamicNode)时出现Java GC开销限制错误,junit,java-8,java-stream,maven-surefire-plugin,junit5,Junit,Java 8,Java Stream,Maven Surefire Plugin,Junit5,在尝试使用maven surefire插件2.21.0创建和运行大量JUnit 5动态测试时,我面临以下问题 [错误]超出了GC开销限制 [错误]org.apache.maven.surefire.booter.SurefireBooterWorkException:分叉进程中出现错误 [错误]超出了GC开销限制 [错误]位于org.apache.maven.plugin.surefire.booterclient.ForkStarter.fork(ForkStarter.java:673) [

在尝试使用maven surefire插件2.21.0创建和运行大量JUnit 5动态测试时,我面临以下问题

[错误]超出了GC开销限制 [错误]org.apache.maven.surefire.booter.SurefireBooterWorkException:分叉进程中出现错误 [错误]超出了GC开销限制 [错误]位于org.apache.maven.plugin.surefire.booterclient.ForkStarter.fork(ForkStarter.java:673) [错误]位于org.apache.maven.plugin.surefire.booterclient.ForkStarter.fork(ForkStarter.java:535) [错误]位于org.apache.maven.plugin.surefire.booterclient.ForkStarter.run(ForkStarter.java:280) [错误]位于org.apache.maven.plugin.surefire.booterclient.ForkStarter.run(ForkStarter.java:245) [错误]位于org.apache.maven.plugin.surefire.AbstractSurefireMojo.executeProvider(AbstractSurefireMojo.java:1124) [错误]位于org.apache.maven.plugin.surefire.AbstractSurefireMojo.ExecuteAfterPremissionSchecked(AbstractSurefireMojo.java:954) [错误]位于org.apache.maven.plugin.surefire.AbstractSurefireMojo.execute(AbstractSurefireMojo.java:832) [错误]位于org.apache.maven.plugin.DefaultBuildPluginManager.executeMojo(DefaultBuildPluginManager.java:134) [错误]位于org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:208) [错误]位于org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:154) [错误]位于org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:146) [错误]位于org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:117) [错误]位于org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:81) [错误]位于org.apache.maven.lifecycle.internal.builder.singlethreaded.SingleThreadedBuilder.build(SingleThreadedBuilder.java:51) [错误]位于org.apache.maven.lifecycle.internal.LifecycleStarter.execute(LifecycleStarter.java:128)

下面是我的代码,它是一个db比较工具。基本上我所做的是,从两个数据库中传输数据并比较记录,如果两个记录中的任何一个存在差异,则测试将失败,因此将创建与数据库中记录数量相同的动态测试(~14M),非常大,不确定动态测试是否打算以这种规模使用。非常感谢您在这方面提供的任何帮助:)

@TestFactory
Stream dynamicTestsWithContainers()引发SQLException{
return tableNameProvider()//数据库表列表~100
.map(tableName->dynamicContainer(tableName,dynamicodestream(tableName));
}
私有流dynamicodestream(字符串tableName){
试一试{
System.out.println(“测试”+表名);
Stream rows=sourceRepo.rows(tableName);
Stream batchRows=批次(行,10000);
可选tableInfo=sourceRepo.getTableSchema(tableName);
最终流dynamicodestream=batchRows
.flatMap(批处理->{
Map sourceRowsMap=buildRowMap(批处理,tableInfo.get());//包含10000个对象的HashMap
Map targetRowsMap=targetReporto.GetTargetBrows(sourceRowsMap,tableInfo.get());//包含10000个对象的HashMap
Set commonKeys=Set.intersection(sourceRowsMap.keySet(),targetRowsMap.keySet());
最终流dynamicTestStream=Streams.concat(
溪流(
dynamicTest(“所有源记录都应该存在于目标数据库中”,()->assertThat(targetRowsMap.keySet())
.as(“将“+sourceRepo.getServerName()+”与“+targetRepo.getServerName()进行比较”)
.hasSameElementsAs(sourceRowsMap.keySet())
),
公用钥匙
.stream()
.map(rowKey->dynamicTest(tableName+“行和#“+rowKey+”在目标数据库中应该是相同的”,
()->assertThat(targetRowMap.get(rowKey.getRowData())
.IseQualToComparingFieldByField递归(sourceRowsMap.get(rowKey.getRowData())
))
);
返回dynamicTestStream;
});
返回dynamicondesteam;
}捕获(例外e){
抛出新的RuntimeException(“在表上运行测试时出错”+tableName,e);
}
}
试试:


org.apache.maven.plugins
maven surefire插件
-XX:+UseConMarkSweepGC

在您的构建配置文件中允许并发垃圾收集。

我们在这里讨论的是什么样的“规模”?换句话说,您的工厂生成了多少个动态测试?~1400万个测试,我正在尝试编写一个DB比较工具,为了比较每一行,我创建了一个动态测试。您能在不涉及maven/surefire的情况下运行测试吗?可能只是控制台启动器?从控制台启动器运行也会导致相同的错误。即使这是两年后的事,您可能会对进展感兴趣:
 @TestFactory
Stream<DynamicNode> dynamicTestsWithContainers() throws SQLException {
    return tableNameProvider()//List of db tables ~100
            .map(tableName -> dynamicContainer(tableName, dynamicNodeStream(tableName)));
}

private Stream<DynamicNode> dynamicNodeStream(String tableName) {

    try {
        System.out.println("Testing " + tableName);
        Stream<Row> rows = sourceRepo.rows(tableName);
        Stream<List<Row>> batchRows = batch(rows, 10000);
        Optional<TableSchema> tableInfo = sourceRepo.getTableSchema(tableName);


        final Stream<DynamicNode> dynamicNodeStream = batchRows
                .flatMap(batch -> {

                    Map<String, Row> sourceRowsMap = buildRowMap(batch, tableInfo.get());//HashMap with 10000 Objects
                    Map<String, Row> targetRowsMap = targetRepo.getTargetDBRows(sourceRowsMap, tableInfo.get());//HashMap with 10000 Objects
                    Set<String> commonKeys = Sets.intersection(sourceRowsMap.keySet(), targetRowsMap.keySet());

                    final Stream<DynamicTest> dynamicTestStream = Streams.concat(
                            Stream.of(
                                    dynamicTest("All source records should be present in target DB", () -> assertThat(targetRowsMap.keySet())
                                            .as("Comparing " + sourceRepo.getServerName() + " against " + targetRepo.getServerName())
                                            .hasSameElementsAs(sourceRowsMap.keySet()))
                            ),
                            commonKeys
                                    .stream()
                                    .map(rowKey -> dynamicTest(tableName + " Row with #" + rowKey + " should be same in target DB",
                                            () -> assertThat(targetRowsMap.get(rowKey).getRowData())
                                                    .isEqualToComparingFieldByFieldRecursively(sourceRowsMap.get(rowKey).getRowData())
                                    ))

                    );

                    return dynamicTestStream;
                });

        return dynamicNodeStream;
    } catch (Exception e) {
        throw new RuntimeException("Error running tests on table " + tableName, e);
    }
}
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-surefire-plugin</artifactId>
            <configuration>
                <argLine>-XX:+UseConcMarkSweepGC</argLine>
            </configuration>
        </plugin>