示例#1
0
CommandLineProgramContext &initForCommandLine(int *argc, char ***argv)
{
    gmx::init(argc, argv);
    GMX_RELEASE_ASSERT(!g_commandLineContext,
                       "initForCommandLine() calls cannot be nested");
#ifdef GMX_LIB_MPI
    // TODO: Rewrite this to not use t_commrec once there is clarity on
    // the approach for MPI in C++ code.
    // TODO: Consider whether the argument broadcast would better be done
    // in CommandLineModuleManager.
    t_commrec cr;
    std::memset(&cr, 0, sizeof(cr));

    gmx_fill_commrec_from_mpi(&cr);
    if (PAR(&cr))
    {
        broadcastArguments(&cr, argc, argv);
    }
#endif
    try
    {
        g_commandLineContext.reset(new CommandLineProgramContext(*argc, *argv));
        setProgramContext(g_commandLineContext.get());
    }
    catch (const std::exception &ex)
    {
        printFatalErrorMessage(stderr, ex);
        std::exit(processExceptionAtExit(ex));
    }
    return *g_commandLineContext;
}
void initTestUtils(const char *dataPath, const char *tempPath, int *argc, char ***argv)
{
    gmx::initForCommandLine(argc, argv);
    try
    {
        ::testing::InitGoogleMock(argc, *argv);
        if (dataPath != NULL)
        {
            TestFileManager::setInputDataDirectory(dataPath);
        }
        if (tempPath != NULL)
        {
            TestFileManager::setGlobalOutputTempDirectory(tempPath);
        }
        bool    bHelp = false;
        Options options(NULL, NULL);
        // TODO: A single option that accepts multiple names would be nicer.
        // Also, we recognize -help, but GTest doesn't, which leads to a bit
        // unintuitive behavior.
        options.addOption(BooleanOption("h").store(&bHelp)
                          .description("Print GROMACS-specific unit test options"));
        options.addOption(BooleanOption("help").store(&bHelp).hidden());
        options.addOption(BooleanOption("?").store(&bHelp).hidden());
        // TODO: Consider removing this option from test binaries that do not need it.
        initReferenceData(&options);
        TestOptionsRegistry::getInstance().initOptions(&options);
        try
        {
            CommandLineParser(&options).parse(argc, *argv);
            options.finish();
        }
        catch (const UserInputError &)
        {
            printHelp(options);
            throw;
        }
        if (bHelp)
        {
            printHelp(options);
        }
        setFatalErrorHandler(NULL);
        initMPIOutput();
    }
    catch (const std::exception &ex)
    {
        printFatalErrorMessage(stderr, ex);
        std::exit(processExceptionAtExit(ex));
    }
}
// static
int CommandLineModuleManager::runAsMainSingleModule(
        int argc, char *argv[], CommandLineModuleInterface *module)
{
    CommandLineProgramContext &programContext = gmx::initForCommandLine(&argc, &argv);
    try
    {
        CommandLineModuleManager manager(NULL, &programContext);
        manager.setSingleModule(module);
        int rc = manager.run(argc, argv);
        gmx::finalizeForCommandLine();
        return rc;
    }
    catch (const std::exception &ex)
    {
        printFatalErrorMessage(stderr, ex);
        return processExceptionAtExitForCommandLine(ex);
    }
}
示例#4
0
// static
const ProgramInfo &ProgramInfo::init(const char *realBinaryName,
                                     int argc, const char *const argv[])
{
    try
    {
        tMPI::lock_guard<tMPI::mutex> lock(g_programInfoMutex);
        if (g_programInfo.get() == NULL)
        {
            g_programInfo.reset(new ProgramInfo(realBinaryName, argc, argv));
        }
        return *g_programInfo;
    }
    catch (const std::exception &ex)
    {
        printFatalErrorMessage(stderr, ex);
        std::exit(1);
    }
}
示例#5
0
CommandLineProgramContext &initForCommandLine(int *argc, char ***argv)
{
    gmx::init(argc, argv);
    GMX_RELEASE_ASSERT(!g_commandLineContext,
                       "initForCommandLine() calls cannot be nested");
    // TODO: Consider whether the argument broadcast would better be done
    // in CommandLineModuleManager.
    broadcastArguments(argc, argv);
    try
    {
        g_commandLineContext = compat::make_unique<CommandLineProgramContext>(*argc, *argv);
        setProgramContext(g_commandLineContext.get());
        g_libFileFinder = compat::make_unique<DataFileFinder>();
        g_libFileFinder->setSearchPathFromEnv("GMXLIB");
        setLibraryFileFinder(g_libFileFinder.get());
    }
    catch (const std::exception &ex)
    {
        printFatalErrorMessage(stderr, ex);
        std::exit(processExceptionAtExit(ex));
    }
    return *g_commandLineContext;
}
示例#6
0
//! \cond internal
void initTestUtils(const char *dataPath, const char *tempPath, bool usesMpi,
                   bool usesHardwareDetection, int *argc, char ***argv)
{
#if !defined NDEBUG &&                                                  \
    !((defined __clang__ || (defined(__GNUC__) && !defined(__ICC) && __GNUC__ == 7)) \
    && defined __OPTIMIZE__)
    gmx_feenableexcept();
#endif
    const CommandLineProgramContext &context = initForCommandLine(argc, argv);
    try
    {
        if (!usesMpi && gmx_node_num() > 1)
        {
            // We cannot continue, since some tests might be using
            // MPI_COMM_WORLD, which could deadlock if we would only
            // continue with the master rank here.
            if (gmx_node_rank() == 0)
            {
                fprintf(stderr, "NOTE: You are running %s on %d MPI ranks, "
                        "but it is does not contain MPI-enabled tests. "
                        "The test will now exit.\n",
                        context.programName(), gmx_node_num());
            }
            finalizeForCommandLine();
            std::exit(1);
        }
        if (usesHardwareDetection)
        {
            callAddGlobalTestEnvironment();
        }
        g_testContext = gmx::compat::make_unique<TestProgramContext>(context);
        setProgramContext(g_testContext.get());
        // Use the default finder that does not respect GMXLIB, since the tests
        // generally can only get confused by a different set of data files.
        setLibraryFileFinder(nullptr);
        ::testing::InitGoogleMock(argc, *argv);
        if (dataPath != nullptr)
        {
            TestFileManager::setInputDataDirectory(
                    Path::join(CMAKE_SOURCE_DIR, dataPath));
        }
        if (tempPath != nullptr)
        {
            TestFileManager::setGlobalOutputTempDirectory(tempPath);
        }
        bool        bHelp = false;
        std::string sourceRoot;
        Options     options;
        // TODO: A single option that accepts multiple names would be nicer.
        // Also, we recognize -help, but GTest doesn't, which leads to a bit
        // unintuitive behavior.
        options.addOption(BooleanOption("h").store(&bHelp)
                              .description("Print GROMACS-specific unit test options"));
        options.addOption(BooleanOption("help").store(&bHelp).hidden());
        options.addOption(BooleanOption("?").store(&bHelp).hidden());
        // TODO: Make this into a FileNameOption (or a DirectoryNameOption).
        options.addOption(StringOption("src-root").store(&sourceRoot)
                              .description("Override source tree location (for data files)"));
        // The potential MPI test event listener must be initialized first,
        // because it should appear in the start of the event listener list,
        // before other event listeners that may generate test failures
        // (currently, such an event listener is used by the reference data
        // framework).
        if (usesMpi)
        {
            initMPIOutput();
        }
        // TODO: Consider removing this option from test binaries that do not need it.
        initReferenceData(&options);
        initTestOptions(&options);
        try
        {
            CommandLineParser(&options).parse(argc, *argv);
            options.finish();
        }
        catch (const UserInputError &)
        {
            printHelp(options);
            throw;
        }
        if (bHelp)
        {
            printHelp(options);
        }
        if (!sourceRoot.empty())
        {
            g_testContext->overrideSourceRoot(sourceRoot);
            TestFileManager::setInputDataDirectory(
                    Path::join(sourceRoot, dataPath));
        }
    }
    catch (const std::exception &ex)
    {
        printFatalErrorMessage(stderr, ex);
        int retcode = processExceptionAtExitForCommandLine(ex);
        // TODO: It could be nice to destroy things in proper order such that
        // g_testContext would not contain hanging references at this point,
        // but in practice that should not matter.
        g_testContext.reset();
        std::exit(retcode);
    }
}
示例#7
0
//! \cond internal
void initTestUtils(const char *dataPath, const char *tempPath, int *argc, char ***argv)
{
#ifndef NDEBUG
    gmx_feenableexcept();
#endif
    const CommandLineProgramContext &context = initForCommandLine(argc, argv);
    try
    {
        g_testContext.reset(new TestProgramContext(context));
        setProgramContext(g_testContext.get());
        // Use the default finder that does not respect GMXLIB, since the tests
        // generally can only get confused by a different set of data files.
        setLibraryFileFinder(NULL);
        ::testing::InitGoogleMock(argc, *argv);
        if (dataPath != NULL)
        {
            TestFileManager::setInputDataDirectory(
                    Path::join(CMAKE_SOURCE_DIR, dataPath));
        }
        if (tempPath != NULL)
        {
            TestFileManager::setGlobalOutputTempDirectory(tempPath);
        }
        bool        bHelp = false;
        std::string sourceRoot;
        Options     options(NULL, NULL);
        // TODO: A single option that accepts multiple names would be nicer.
        // Also, we recognize -help, but GTest doesn't, which leads to a bit
        // unintuitive behavior.
        options.addOption(BooleanOption("h").store(&bHelp)
                              .description("Print GROMACS-specific unit test options"));
        options.addOption(BooleanOption("help").store(&bHelp).hidden());
        options.addOption(BooleanOption("?").store(&bHelp).hidden());
        // TODO: Make this into a FileNameOption (or a DirectoryNameOption).
        options.addOption(StringOption("src-root").store(&sourceRoot)
                              .description("Override source tree location (for data files)"));
        // The potential MPI test event listener must be initialized first,
        // because it should appear in the start of the event listener list,
        // before other event listeners that may generate test failures
        // (currently, such an event listener is used by the reference data
        // framework).
        initMPIOutput();
        // TODO: Consider removing this option from test binaries that do not need it.
        initReferenceData(&options);
        initTestOptions(&options);
        try
        {
            CommandLineParser(&options).parse(argc, *argv);
            options.finish();
        }
        catch (const UserInputError &)
        {
            printHelp(options);
            throw;
        }
        if (bHelp)
        {
            printHelp(options);
        }
        if (!sourceRoot.empty())
        {
            g_testContext->overrideSourceRoot(sourceRoot);
            TestFileManager::setInputDataDirectory(
                    Path::join(sourceRoot, dataPath));
        }
    }
    catch (const std::exception &ex)
    {
        printFatalErrorMessage(stderr, ex);
        int retcode = processExceptionAtExitForCommandLine(ex);
        // TODO: It could be nice to destroy things in proper order such that
        // g_testContext would not contain hanging references at this point,
        // but in practice that should not matter.
        g_testContext.reset();
        std::exit(retcode);
    }
}
示例#8
0
void processExceptionAsFatalError(const std::exception &ex)
{
    printFatalErrorMessage(stderr, ex);
    gmx_exit_on_fatal_error(ExitType_Abort, 1);
}