Commit cef7980f authored by Matthieu Dorier's avatar Matthieu Dorier
Browse files

finished API, started CppUnit testing

parent 5ff11a14
......@@ -13,44 +13,27 @@
#include <bake-server.h>
#include <sdskv-server.h>
#include <yaml-cpp/yaml.h>
#include "hepnos-service-util.hpp"
#include "hepnos-service.h"
#define ASSERT(__cond, __msg, ...) { if(!(__cond)) { fprintf(stderr, "[%s:%d] " __msg, __FILE__, __LINE__, __VA_ARGS__); exit(-1); } }
void usage(void)
{
fprintf(stderr, "Usage: hepnos-service <addr> <config>\n");
fprintf(stderr, " <addr> the Mercury address to listen on (e.g. tcp://)\n");
fprintf(stderr, " <config> path to the YAML file to generate for clients\n");
exit(-1);
}
static void generate_config_file(MPI_Comm comm, const char* addr, const char* config_file);
int main(int argc, char *argv[])
void hepnos_run_service(MPI_Comm comm, const char* listen_addr, const char* config_file)
{
char* listen_addr;
char* config_file;
margo_instance_id mid;
int ret;
/* check args */
if (argc != 3)
usage();
listen_addr = argv[1];
config_file = argv[2];
/* MPI required for SSG bootstrapping */
MPI_Init(&argc, &argv);
int rank;
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
MPI_Comm_rank(comm, &rank);
/* Margo initialization */
mid = margo_init(listen_addr, MARGO_SERVER_MODE, 0, -1);
if (mid == MARGO_INSTANCE_NULL)
{
fprintf(stderr, "Error: Unable to initialize margo\n");
return -1;
MPI_Abort(MPI_COMM_WORLD, -1);
return;
}
margo_enable_remote_shutdown(mid);
......@@ -61,8 +44,6 @@ int main(int argc, char *argv[])
hg_size_t self_addr_str_size = 128;
margo_addr_to_string(mid, self_addr_str, &self_addr_str_size, self_addr);
generate_config_file(MPI_COMM_WORLD, self_addr_str, config_file);
/* Bake provider initialization */
uint16_t bake_mplex_id = 1;
char bake_target_name[128];
......@@ -94,11 +75,9 @@ int main(int argc, char *argv[])
margo_addr_free(mid, self_addr);
margo_wait_for_finalize(mid);
MPI_Finalize();
generate_config_file(MPI_COMM_WORLD, self_addr_str, config_file);
return 0;
margo_wait_for_finalize(mid);
}
static void generate_config_file(MPI_Comm comm, const char* addr, const char* config_file)
......
#!/bin/sh
ctest --output-on-failure
# Move the configuration file used for the configuration test
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/run-test.sh ${CMAKE_CURRENT_BINARY_DIR}/run-test.sh COPYONLY)
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/test-util.sh ${CMAKE_CURRENT_BINARY_DIR}/test-util.sh COPYONLY)
add_executable(example example.cpp)
target_link_libraries(example hepnos ${Boost_LIBRARIES})
set(CTEST_ENVIRONMENT "MKTEMP=mktemp" "TIMEOUT=timeout")
add_executable(DataStoreTest DataStoreTest.cpp HEPnOSTestMain.cpp)
target_link_libraries(DataStoreTest cppunit hepnos hepnos-service)
add_executable(DataSetTest DataSetTest.cpp HEPnOSTestMain.cpp)
target_link_libraries(DataSetTest cppunit hepnos hepnos-service)
add_executable(RunSetTest RunSetTest.cpp HEPnOSTestMain.cpp)
target_link_libraries(RunSetTest cppunit hepnos hepnos-service)
add_test(NAME DataStoreTest COMMAND run-test.sh ./DataStoreTest)
add_test(NAME DataSetTest COMMAND run-test.sh ./DataSetTest)
add_test(NAME RunSetTest COMMAND run-test.sh ./RunSetTest)
#define CPPUNIT_ASSERT_EQUAL_STR(__x,__y) CPPUNIT_ASSERT_EQUAL(std::string(__x), std::string(__y))
#include "DataSetTest.hpp"
#include "CppUnitAdditionalMacros.hpp"
CPPUNIT_TEST_SUITE_REGISTRATION( DataSetTest );
using namespace hepnos;
void DataSetTest::setUp() {}
void DataSetTest::tearDown() {}
void DataSetTest::testFillDataStore() {
auto mds = datastore->createDataSet("matthieu");
datastore->createDataSet("shane");
datastore->createDataSet("phil");
datastore->createDataSet("rob");
// erroneous dataset creations
// "/" is forbidden in the name, will throw an exception
CPPUNIT_ASSERT_THROW(
mds.createDataSet("ds0/AAA"),
hepnos::Exception);
// "%" is forbidden in the name, will throw an exception
CPPUNIT_ASSERT_THROW(
mds.createDataSet("ds0%RRS"),
hepnos::Exception);
// correct dataset creation
DataSet ds1 = mds.createDataSet("ds1");
// assert the characteristics of the created dataset
CPPUNIT_ASSERT(ds1.valid());
CPPUNIT_ASSERT_EQUAL_STR("ds1", ds1.name());
CPPUNIT_ASSERT_EQUAL_STR("matthieu", ds1.container());
CPPUNIT_ASSERT_EQUAL_STR("matthieu/ds1", ds1.fullname());
// assert comparison with a default-constructed dataset
DataSet ds0;
CPPUNIT_ASSERT(ds0 != ds1);
CPPUNIT_ASSERT(!(ds0 == ds1));
// assert that ds1.next() is not valid
DataSet ds2 = ds1.next();
CPPUNIT_ASSERT(!ds2.valid());
// create more datasets
DataSet ds3 = mds.createDataSet("ds3");
ds2 = mds.createDataSet("ds2");
// assert that these are valid
CPPUNIT_ASSERT(ds2.valid());
CPPUNIT_ASSERT(ds3.valid());
// assert that ds1.next() == ds2 and ds2.next() == ds3
CPPUNIT_ASSERT(ds2 == ds1.next());
CPPUNIT_ASSERT(ds3 == ds2.next());
// create more datasets for future tests
DataSet ds4 = mds.createDataSet("dsB");
DataSet ds5 = mds.createDataSet("dsD");
CPPUNIT_ASSERT(ds4.valid());
CPPUNIT_ASSERT(ds5.valid());
}
void DataSetTest::testBraketOperator() {
DataSet mds = (*datastore)["matthieu"];
CPPUNIT_ASSERT(mds.valid());
// check that accessing a dataset that does not exist
// yields a non-valid DataSet
DataSet ds6 = mds["ds6"];
CPPUNIT_ASSERT(!ds6.valid());
// check that accessing a dataset that exists yields
// a valid DataSet instance with correct information
DataSet ds2 = mds["ds2"];
CPPUNIT_ASSERT(ds2.valid());
CPPUNIT_ASSERT_EQUAL_STR("ds2", ds2.name());
CPPUNIT_ASSERT_EQUAL_STR("matthieu", ds2.container());
CPPUNIT_ASSERT_EQUAL_STR("matthieu/ds2", ds2.fullname());
}
void DataSetTest::testFind() {
DataSet mds = (*datastore)["matthieu"];
CPPUNIT_ASSERT(mds.valid());
// test calling find for a DataSet that does not exist
{
auto it = mds.find("ds6");
CPPUNIT_ASSERT(it == mds.end());
CPPUNIT_ASSERT(!(it->valid()));
}
// test calling find for a DataSet that exists
{
auto it = mds.find("ds2");
CPPUNIT_ASSERT(it != mds.end());
CPPUNIT_ASSERT(it->valid());
CPPUNIT_ASSERT_EQUAL_STR("ds2",it->name());
// test iteration
++it;
CPPUNIT_ASSERT(it->valid());
CPPUNIT_ASSERT_EQUAL_STR("ds3",it->name());
}
}
void DataSetTest::testBeginEnd() {
DataSet mds = (*datastore)["matthieu"];
CPPUNIT_ASSERT(mds.valid());
std::vector<std::string> names = {
"ds1", "ds2", "ds3", "dsB", "dsD"};
auto it = mds.begin();
for(int i=0; i < names.size(); i++, it++) {
CPPUNIT_ASSERT_EQUAL(names[i], it->name());
}
CPPUNIT_ASSERT(it == mds.end());
}
void DataSetTest::testLowerUpperBounds() {
DataSet mds = (*datastore)["matthieu"];
CPPUNIT_ASSERT(mds.valid());
{
auto it = mds.lower_bound("dsB");
CPPUNIT_ASSERT(it->valid());
CPPUNIT_ASSERT(it->name() == "dsB");
}
{
auto it = mds.lower_bound("dsC");
CPPUNIT_ASSERT(it->valid());
CPPUNIT_ASSERT(it->name() == "dsD");
}
{
auto it = mds.lower_bound("dsA");
CPPUNIT_ASSERT(it->valid());
CPPUNIT_ASSERT(it->name() == "dsB");
}
{
auto it = mds.lower_bound("dsE");
CPPUNIT_ASSERT(!(it->valid()));
CPPUNIT_ASSERT(it == mds.end());
}
{
auto it = mds.upper_bound("dsB");
CPPUNIT_ASSERT(it->valid());
CPPUNIT_ASSERT(it->name() == "dsD");
}
{
auto it = mds.upper_bound("dsC");
CPPUNIT_ASSERT(it->valid());
CPPUNIT_ASSERT(it->name() == "dsD");
}
{
auto it = mds.upper_bound("dsA");
CPPUNIT_ASSERT(it->valid());
CPPUNIT_ASSERT(it->name() == "dsB");
}
{
auto it = mds.upper_bound("dsD");
CPPUNIT_ASSERT(!(it->valid()));
CPPUNIT_ASSERT(it == mds.end());
}
}
void DataSetTest::testCreateRuns() {
DataSet mds = (*datastore)["matthieu"];
CPPUNIT_ASSERT(mds.valid());
{
Run r = mds(45);
CPPUNIT_ASSERT(!r.valid());
CPPUNIT_ASSERT(r.number() == InvalidRunNumber);
}
{
Run r = mds.createRun(45);
CPPUNIT_ASSERT(r.valid());
CPPUNIT_ASSERT(45 == r.number());
CPPUNIT_ASSERT_EQUAL_STR("matthieu", r.container());
}
}
#ifndef __HEPNOS_TEST_DATASET_H
#define __HEPNOS_TEST_DATASET_H
#include <cppunit/extensions/HelperMacros.h>
#include <hepnos.hpp>
extern hepnos::DataStore* datastore;
class DataSetTest : public CppUnit::TestFixture
{
CPPUNIT_TEST_SUITE( DataSetTest );
CPPUNIT_TEST( testFillDataStore );
CPPUNIT_TEST( testBraketOperator );
CPPUNIT_TEST( testFind );
CPPUNIT_TEST( testBeginEnd );
CPPUNIT_TEST( testCreateRuns );
CPPUNIT_TEST( testLowerUpperBounds );
CPPUNIT_TEST_SUITE_END();
public:
void setUp();
void tearDown();
void testFillDataStore();
void testBraketOperator();
void testFind();
void testBeginEnd();
void testLowerUpperBounds();
void testCreateRuns();
};
#endif
#include "DataStoreTest.hpp"
#include "CppUnitAdditionalMacros.hpp"
CPPUNIT_TEST_SUITE_REGISTRATION( DataStoreTest );
using namespace hepnos;
void DataStoreTest::setUp() {}
void DataStoreTest::tearDown() {}
void DataStoreTest::testFillDataStore() {
// erroneous dataset creations
// "/" is forbidden in the name, will throw an exception
CPPUNIT_ASSERT_THROW(
datastore->createDataSet("ds0/AAA"),
hepnos::Exception);
// "%" is forbidden in the name, will throw an exception
CPPUNIT_ASSERT_THROW(
datastore->createDataSet("ds0%RRS"),
hepnos::Exception);
// correct dataset creation
DataSet ds1 = datastore->createDataSet("ds1");
// assert the characteristics of the created dataset
CPPUNIT_ASSERT(ds1.valid());
CPPUNIT_ASSERT_EQUAL_STR("ds1", ds1.name());
CPPUNIT_ASSERT_EQUAL_STR("", ds1.container());
CPPUNIT_ASSERT_EQUAL_STR("ds1", ds1.fullname());
// assert comparison with a default-constructed dataset
DataSet ds0;
CPPUNIT_ASSERT(ds0 != ds1);
CPPUNIT_ASSERT(!(ds0 == ds1));
// assert that ds1.next() is not valid
DataSet ds2 = ds1.next();
CPPUNIT_ASSERT(!ds2.valid());
// create more datasets
DataSet ds3 = datastore->createDataSet("ds3");
ds2 = datastore->createDataSet("ds2");
// assert that these are valid
CPPUNIT_ASSERT(ds2.valid());
CPPUNIT_ASSERT(ds3.valid());
// assert that ds1.next() == ds2 and ds2.next() == ds3
CPPUNIT_ASSERT(ds2 == ds1.next());
CPPUNIT_ASSERT(ds3 == ds2.next());
// create more datasets for future tests
DataSet ds4 = datastore->createDataSet("dsB");
DataSet ds5 = datastore->createDataSet("dsD");
CPPUNIT_ASSERT(ds4.valid());
CPPUNIT_ASSERT(ds5.valid());
}
void DataStoreTest::testBraketOperator() {
// check that accessing a dataset that does not exist
// yields a non-valid DataSet
DataSet ds6 = (*datastore)["ds6"];
CPPUNIT_ASSERT(!ds6.valid());
// check that accessing a dataset that exists yields
// a valid DataSet instance with correct information
DataSet ds2 = (*datastore)["ds2"];
CPPUNIT_ASSERT(ds2.valid());
CPPUNIT_ASSERT_EQUAL_STR("ds2", ds2.name());
CPPUNIT_ASSERT_EQUAL_STR("", ds2.container());
CPPUNIT_ASSERT_EQUAL_STR("ds2", ds2.fullname());
}
void DataStoreTest::testFind() {
// test calling find for a DataSet that does not exist
{
auto it = datastore->find("ds6");
CPPUNIT_ASSERT(it == datastore->end());
CPPUNIT_ASSERT(!(it->valid()));
}
// test calling find for a DataSet that exists
{
auto it = datastore->find("ds2");
CPPUNIT_ASSERT(it != datastore->end());
CPPUNIT_ASSERT(it->valid());
CPPUNIT_ASSERT_EQUAL_STR("ds2",it->name());
// test iteration
++it;
CPPUNIT_ASSERT(it->valid());
CPPUNIT_ASSERT_EQUAL_STR("ds3",it->name());
}
}
void DataStoreTest::testBeginEnd() {
std::vector<std::string> names = {
"ds1", "ds2", "ds3", "dsB", "dsD"};
auto it = datastore->begin();
for(int i=0; i < names.size(); i++, it++) {
CPPUNIT_ASSERT_EQUAL(names[i], it->name());
}
CPPUNIT_ASSERT(it == datastore->end());
}
void DataStoreTest::testLowerUpperBounds() {
{
auto it = datastore->lower_bound("dsB");
CPPUNIT_ASSERT(it->valid());
CPPUNIT_ASSERT(it->name() == "dsB");
}
{
auto it = datastore->lower_bound("dsC");
CPPUNIT_ASSERT(it->valid());
CPPUNIT_ASSERT(it->name() == "dsD");
}
{
auto it = datastore->lower_bound("dsA");
CPPUNIT_ASSERT(it->valid());
CPPUNIT_ASSERT(it->name() == "dsB");
}
{
auto it = datastore->lower_bound("dsE");
CPPUNIT_ASSERT(!(it->valid()));
CPPUNIT_ASSERT(it == datastore->end());
}
{
auto it = datastore->upper_bound("dsB");
CPPUNIT_ASSERT(it->valid());
CPPUNIT_ASSERT(it->name() == "dsD");
}
{
auto it = datastore->upper_bound("dsC");
CPPUNIT_ASSERT(it->valid());
CPPUNIT_ASSERT(it->name() == "dsD");
}
{
auto it = datastore->upper_bound("dsA");
CPPUNIT_ASSERT(it->valid());
CPPUNIT_ASSERT(it->name() == "dsB");
}
{
auto it = datastore->upper_bound("dsD");
CPPUNIT_ASSERT(!(it->valid()));
CPPUNIT_ASSERT(it == datastore->end());
}
}
#ifndef __HEPNOS_TEST_DATASTORE_H
#define __HEPNOS_TEST_DATASTORE_H
#include <cppunit/extensions/HelperMacros.h>
#include <hepnos.hpp>
extern hepnos::DataStore* datastore;
class DataStoreTest : public CppUnit::TestFixture
{
CPPUNIT_TEST_SUITE( DataStoreTest );
CPPUNIT_TEST( testFillDataStore );
CPPUNIT_TEST( testBraketOperator );
CPPUNIT_TEST( testFind );
CPPUNIT_TEST( testBeginEnd );
CPPUNIT_TEST( testLowerUpperBounds );
CPPUNIT_TEST_SUITE_END();
public:
void setUp();
void tearDown();
void testFillDataStore();
void testBraketOperator();
void testFind();
void testBeginEnd();
void testLowerUpperBounds();
};
#endif
#include <cppunit/CompilerOutputter.h>
#include <cppunit/XmlOutputter.h>
#include <cppunit/extensions/TestFactoryRegistry.h>
#include <cppunit/ui/text/TestRunner.h>
#include <hepnos.hpp>
hepnos::DataStore* datastore;
int main(int argc, char* argv[])
{
if(argc != 2) return 1;
// Create the datastore
datastore = new hepnos::DataStore(argv[1]);
// Get the top level suite from the registry
CppUnit::Test *suite = CppUnit::TestFactoryRegistry::getRegistry().makeTest();
// Adds the test to the list of test to run
CppUnit::TextUi::TestRunner runner;
runner.addTest( suite );
// Change the default outputter to a compiler error format outputter
runner.setOutputter( new CppUnit::XmlOutputter( &runner.result(),
std::cerr ) );
// Run the tests.
bool wasSucessful = runner.run();
datastore->shutdown();
delete datastore;
// Return error code 1 if the one of test failed.
return wasSucessful ? 0 : 1;
}
#include "RunSetTest.hpp"
#include "CppUnitAdditionalMacros.hpp"
CPPUNIT_TEST_SUITE_REGISTRATION( RunSetTest );
using namespace hepnos;
void RunSetTest::setUp() {}
void RunSetTest::tearDown() {}
void RunSetTest::testFillDataStore() {
auto mds = datastore->createDataSet("matthieu");
CPPUNIT_ASSERT(mds.valid());
// erroneous run creation
CPPUNIT_ASSERT_THROW(
mds.createRun(InvalidRunNumber),
hepnos::Exception);
// default-constructed run has InvalidRunNumber number
Run r0;
CPPUNIT_ASSERT(!r0.valid());
CPPUNIT_ASSERT(InvalidRunNumber == r0.number());
// correct run creation
Run r1 = mds.createRun(42);
// assert the characteristics of the created dataset
CPPUNIT_ASSERT(r1.valid());
CPPUNIT_ASSERT(42 == r1.number());
CPPUNIT_ASSERT_EQUAL_STR("matthieu", r1.container());
// assert comparison with a default-constructed run
CPPUNIT_ASSERT(r0 != r1);
CPPUNIT_ASSERT(!(r0 == r1));
// assert that r1.next() is not valid
Run r2 = r1.next();
CPPUNIT_ASSERT(!r2.valid());
// create more runs
Run r3 = mds.createRun(47);
r2 = mds.createRun(45);
// assert that these are valid
CPPUNIT_ASSERT(r2.valid());
CPPUNIT_ASSERT(r3.valid());
// assert that r1.next() == r2 and r2.next() == r3
CPPUNIT_ASSERT(r2 == r1.next());
CPPUNIT_ASSERT(r3 == r2.next());
// create more datasets for future tests
Run r4 = mds.createRun(53);
Run r5 = mds.createRun(59);
CPPUNIT_ASSERT(r4.valid());
CPPUNIT_ASSERT(r5.valid());
}
void RunSetTest::testParenthesisOperator() {
DataSet mds = (*datastore)["matthieu"];
CPPUNIT_ASSERT(mds.valid());
// check that accessing a Run that does not exist
// yields a non-valid Run instance
Run r6 = mds(43);
CPPUNIT_ASSERT(!r6.valid());
// check that accessing a run that exists yields
// a valid Run instance with correct information
Run r2 = mds(45);
CPPUNIT_ASSERT(r2.valid());
CPPUNIT_ASSERT(45 == r2.number());
CPPUNIT_ASSERT_EQUAL_STR("matthieu", r2.container());
// check that we access the same Run using the runs() function
// to go through the RunSet
Run r22 = mds.runs()(45);
CPPUNIT_ASSERT(r2 == r22);
}
void RunSetTest::testFind() {
DataSet mds = (*datastore)["matthieu"];
CPPUNIT_ASSERT(mds.valid());
// test calling find for a Run that does not exist
{
auto it = mds.runs().find(43);
CPPUNIT_ASSERT(it == mds.runs().end());
CPPUNIT_ASSERT(!(it->valid()));
}
// test calling find for a Run that exists
{
auto it = mds.runs().find(45);
CPPUNIT_ASSERT(it != mds.runs().end());
CPPUNIT_ASSERT(it->valid());
CPPUNIT_ASSERT(45 == it->number());
// test iteration
++it;
CPPUNIT_ASSERT(it->valid());
CPPUNIT_ASSERT(47 == it->number());
}
}
void RunSetTest::testBeginEnd() {
DataSet mds = (*datastore)["matthieu"];
CPPUNIT_ASSERT(mds.valid());