使用ant运行单元测试的mpirun。

问题描述 投票:1回答:1

我试图通过mpirun使用蚂蚁来运行我的单元测试。我已经指定了任务为

<target name="unitTest" depends="buildUnitTest">
    <mkdir dir="reports"/>
    <junit fork="yes" jvm="mpirun java" printsummary="yes" haltonfailure="yes">
        <classpath>
            <pathelement location="./bin"/>
            <pathelement location="/usr/share/java/junit4.jar"/>
        </classpath>
        <jvmarg value="-DDIM=3"/>
        <jvmarg value="-ea"/>
        <formatter type="plain"/>
        <batchtest todir="reports">
            <fileset dir="test">
                <include name="haparanda/utils/*Test.java"/>
                <include name="haparanda/iterators/*Test.java"/>
                <exclude name="haparanda/iterators/FieldIteratorTest.java"/>
                <include name="haparanda/grid/*Test.java"/>
            </fileset>
        </batchtest>
    </junit>
</target>

从命令行运行eg:

 mpirun java -ea -DDIM=3 -cp ./bin:/usr/share/java/junit4.jar org.junit.runner.JUnitCore haparanda.grid.ComputationalComposedBlockTest

从命令行运行就可以了。然而,当我运行时。

ant unitTest

我得到了以下错误。

BUILD FAILED
.../build.xml:28: Process fork failed.

用 verbose 标志运行 ant,我被告知我得到了一个带有错误信息的 IOException。

Cannot run program "mpirun java": error=2, No such file or directory

当我指定了mpirun和Java的完整路径时也是如此。

<junit fork="yes" jvm="/home/malin/bin/openmpi/bin/mpirun /usr/bin/java" printsummary="yes" haltonfailure="yes">

给我。

.../build.xml:28: Process fork failed.
at ...
Caused by: java.io.IOException: Cannot run program "/home/malin/bin/openmpi/bin/mpirun /usr/bin/java": error=2, No such file or directory

我怎样才能让它工作?

junit ant mpi
1个回答
0
投票

这个问题很老了,似乎已经在Gilles Gouaillardet的评论中被成功解决了。在我工作的学术环境中,我也尝试使用Junit与Java和MPI。我无法成功地使用Gilles Gouaillardet提出的技巧,我最终采用了一个完全不同的解决方案。

自定义Junit4运行器--总体思路

使用MPI运行Junit测试的另一种方式包括实现一个自定义的Junit运行器。

在这个自定义的Junit运行器中,你可以使用ProcessLauncher启动你的自定义命令,而不是 "直接 "调用测试方法。在我的实现中,我让每个MPI进程都使用正常的Junit4运行时来运行测试方法。然而,我并没有使用正常的 RunNotifier 运行时,MPI进程使用我自定义的 RunNotifier 它将收到的调用写入一个文件。一个文件中包含了

在我的自定义运行程序中,一旦mpirun进程完成,我将每个MPI进程的每个测试方法的结果汇总,并将这些结果传送到正常的 RunNotifier.

效益

有了这个系统,你就可以呆在 "正常的 "Junit4框架内。在我的案例中,我试图从Maven运行Junit测试。我也可以成功地将测试结果与Eclipse Junit视图集成在一起(这需要一些技巧,下面的代码摘录中没有显示)。

下面是我的Eclipse环境在运行测试后的捕获(由于我的特定环境的一些额外的复杂情况,类名与下面摘录中所呈现的略有不同)。

eclipse_junitview

一些选定的代码细节

只有最重要的定制部分 MpiRunnerMpiTestLauncher 显示。导入、trycatch结构和众多细节都已被删除。我最终会在GitHub上提供整个代码,但目前还没有完全准备好。

/** A test class using the custom "MpiRunner" */
@RunWith(MpiRunner.class)
public class TestUsingMpi {
    @Test
    public void test() {
        assertTrue("Should run with multiple processes", MPI.COMM_WORLD.Size() > 1);
    }

}
/** Curstom Junit4 Runner */
public class MpiRunner extends Runner {
    // some methods skipped, try/catch blocks have been removed
    @Override
    public void run(RunNotifier notifier) {
        // Build the command
        final ArrayList<String> command = new ArrayList<>();
        command.add("mpirun");
        command.add("-np");
        command.add(String.valueOf(processCount));
        command.add("java");
        // Classpath, UserDirectory, JavaLibraryPath ...
        command.add("MpiTestLauncher "); // Class with main 
        command.add(testClass.getCanonicalName()); // Class under test as argument
        ProcessBuilder pb = new ProcessBuilder(command);
        File mpirunOutFile = new File("MpirunCommandOutput.txt"); 
        pb.redirectOutput(Redirect.appendTo(mpirunOutFile));
        pb.redirectError(Redirect.appendTo(mpirunOutFile));

        Process p = pb.start(); // Launch the mpirun command
        p.waitFor(); // Wait for termination

        // Parse the notifications of each MPI process
        for (int i = o; i < NbProcesses; i++) {
            List<Notification> mpiRankNotifs = parse(i);
            //Re-run those notifications on the parameter "notifier" of this method
            for (Notification n : notifications) {
                //Reconstitute the method call made in the mpi process
                Class<?> paramClass = n.parameters[0].getClass();
                Method m = RunNotifier.class.getDeclaredMethod(n.method, paramClass);
                m.invoke(notifier, n.parameters);
            }
        }
    }
}

/** Main class of the Mpirun java processes */
public class MpiTestLauncher {
    public static void main(String[] args) throws Exception {
        MPI.Init(args);
        commRank = MPI.COMM_WORLD.Rank();
        commSize = MPI.COMM_WORLD.Size();

        Class<?> testClass = Class.forName(args[0]); // Class that contains the tests
        String notificationFileName = testClass.getCanonicalName() + "_" + 
              commRank;
        File f = new File(notificationFileName);
        CustomNotifier notifier = new MpiApgasRunNotifier(f);
        BlockJUnit4ClassRunner junitDefaultRunner = new BlockJUnit4ClassRunner(testClass);
        junitDefaultRunner.run(notifier);
        notifier.close(); //Flushes the underlying buffer

        MPI.Finalize();
    }
}

© www.soinside.com 2019 - 2024. All rights reserved.