Blame test/mpi/errors/cxx/errhan/throwtest.cxx

Packit 0848f5
/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */
Packit 0848f5
/*
Packit 0848f5
 *  (C) 2008 by Argonne National Laboratory.
Packit 0848f5
 *      See COPYRIGHT in top-level directory.
Packit 0848f5
 */
Packit 0848f5
Packit 0848f5
/*
Packit 0848f5
Packit 0848f5
  throwtest.cxx
Packit 0848f5
Packit 0848f5
  This test was based on code provided with a bug report submitted by
Packit 0848f5
  Eric Eidson edeidso@sandia.gov
Packit 0848f5
Packit 0848f5
*/
Packit 0848f5
Packit 0848f5
#include <mpi.h>
Packit 0848f5
#include <iostream>
Packit 0848f5
#include "mpitestconf.h"
Packit 0848f5
#include "mpitestcxx.h"
Packit 0848f5
Packit 0848f5
/* #define VERBOSE */
Packit 0848f5
Packit 0848f5
/* returns number of errors found */
Packit 0848f5
template <class T>
Packit 0848f5
int testCallErrhandler(T &obj, int errorClass, int errorCode, std::string errorString)
Packit 0848f5
{
Packit 0848f5
    int errs = 0;
Packit 0848f5
Packit 0848f5
    try {
Packit 0848f5
        obj.Call_errhandler(errorCode);
Packit 0848f5
        std::cerr << "Do Not See This" << std::endl;
Packit 0848f5
        errs++;
Packit 0848f5
    }
Packit 0848f5
    catch (MPI::Exception &ex) {
Packit 0848f5
#ifdef VERBOSE
Packit 0848f5
        std::cerr << "MPI Exception: " << ex.Get_error_string() << std::endl;
Packit 0848f5
#endif
Packit 0848f5
        if (ex.Get_error_code() != errorCode) {
Packit 0848f5
            std::cout << "errorCode does not match" << std::endl;
Packit 0848f5
            errs++;
Packit 0848f5
        }
Packit 0848f5
        if (ex.Get_error_class() != errorClass) {
Packit 0848f5
            std::cout << "errorClass does not match" << std::endl;
Packit 0848f5
            errs++;
Packit 0848f5
        }
Packit 0848f5
        if (ex.Get_error_string() != errorString) {
Packit 0848f5
            std::cout << "errorString does not match" << std::endl;
Packit 0848f5
            errs++;
Packit 0848f5
        }
Packit 0848f5
    }
Packit 0848f5
    catch (...) {
Packit 0848f5
        std::cerr << "Caught Unknown Exception" << std::endl;
Packit 0848f5
        errs++;
Packit 0848f5
    }
Packit 0848f5
Packit 0848f5
    return errs;
Packit 0848f5
}
Packit 0848f5
Packit 0848f5
int main( int argc, char *argv[] )
Packit 0848f5
{
Packit 0848f5
    int errs = 0;
Packit 0848f5
    MPI::Win win = MPI::WIN_NULL;
Packit 0848f5
Packit 0848f5
    MTest_Init( );
Packit 0848f5
Packit 0848f5
    const unsigned int rank = MPI::COMM_WORLD.Get_rank();
Packit 0848f5
    const unsigned int size = MPI::COMM_WORLD.Get_size();
Packit 0848f5
Packit 0848f5
    int errorClass = MPI::Add_error_class();
Packit 0848f5
    int errorCode = MPI::Add_error_code(errorClass);
Packit 0848f5
    std::string errorString = "Internal-use Error Code";
Packit 0848f5
    MPI::Add_error_string(errorCode, errorString.c_str());
Packit 0848f5
Packit 0848f5
    win = MPI::Win::Create(NULL, 0, 1, MPI::INFO_NULL, MPI_COMM_WORLD);
Packit 0848f5
Packit 0848f5
    // first sanity check that ERRORS_RETURN actually returns in erroneous
Packit 0848f5
    // conditions and doesn't throw an exception
Packit 0848f5
    MPI::COMM_WORLD.Set_errhandler(MPI::ERRORS_RETURN);
Packit 0848f5
    win.Set_errhandler(MPI::ERRORS_RETURN);
Packit 0848f5
Packit 0848f5
    try {
Packit 0848f5
        // Do something that should cause an exception.
Packit 0848f5
        MPI::COMM_WORLD.Get_attr(MPI::KEYVAL_INVALID, NULL);
Packit 0848f5
    }
Packit 0848f5
    catch (...) {
Packit 0848f5
        std::cerr << "comm threw when it shouldn't have" << std::endl;
Packit 0848f5
        ++errs;
Packit 0848f5
    }
Packit 0848f5
Packit 0848f5
    try {
Packit 0848f5
        // Do something that should cause an exception.
Packit 0848f5
        win.Get_attr(MPI::KEYVAL_INVALID, NULL);
Packit 0848f5
    }
Packit 0848f5
    catch (...) {
Packit 0848f5
        std::cerr << "win threw when it shouldn't have" << std::endl;
Packit 0848f5
        ++errs;
Packit 0848f5
    }
Packit 0848f5
Packit 0848f5
    // now test that when ERRORS_THROW_EXCEPTIONS actually throws an exception
Packit 0848f5
    MPI::COMM_WORLD.Set_errhandler(MPI::ERRORS_THROW_EXCEPTIONS);
Packit 0848f5
    win.Set_errhandler(MPI::ERRORS_THROW_EXCEPTIONS);
Packit 0848f5
Packit 0848f5
    if (0 == rank) {
Packit 0848f5
        errs += testCallErrhandler(MPI::COMM_WORLD, errorClass, errorCode, errorString);
Packit 0848f5
        errs += testCallErrhandler(win,             errorClass, errorCode, errorString);
Packit 0848f5
Packit 0848f5
        // induce actual errors and make sure that they throw
Packit 0848f5
        try {
Packit 0848f5
            char buf[10];
Packit 0848f5
            MPI::COMM_WORLD.Send(&buf, 1, MPI::CHAR, size+1, 1);
Packit 0848f5
            std::cout << "Invalid Send did not throw" << std::endl;
Packit 0848f5
            errs++;
Packit 0848f5
        }
Packit 0848f5
        catch (MPI::Exception &ex) {
Packit 0848f5
            // expected
Packit 0848f5
        }
Packit 0848f5
        catch (...) {
Packit 0848f5
            std::cout << "Caught Unknown Exception" << std::endl;
Packit 0848f5
            errs++;
Packit 0848f5
        }
Packit 0848f5
Packit 0848f5
        try {
Packit 0848f5
            char buf[10];
Packit 0848f5
            win.Get(&buf, 0, MPI::CHAR, size+1, 0, 0, MPI::CHAR);
Packit 0848f5
            std::cout << "Invalid Get did not throw" << std::endl;
Packit 0848f5
            errs++;
Packit 0848f5
        }
Packit 0848f5
        catch (MPI::Exception &ex) {
Packit 0848f5
            // expected
Packit 0848f5
        }
Packit 0848f5
        catch (...) {
Packit 0848f5
            std::cout << "Caught Unknown Exception" << std::endl;
Packit 0848f5
            errs++;
Packit 0848f5
        }
Packit 0848f5
    }
Packit 0848f5
Packit 0848f5
    MTest_Finalize( errs );
Packit 0848f5
Packit 0848f5
    win.Free();
Packit 0848f5
Packit 0848f5
    MPI::Finalize();
Packit 0848f5
Packit 0848f5
    return 0;
Packit 0848f5
}