diff --git a/include/stellar/module_manager.h b/include/stellar/module_manager.h index a626575..82c000c 100644 --- a/include/stellar/module_manager.h +++ b/include/stellar/module_manager.h @@ -15,6 +15,7 @@ void * stellar_module_get_ctx(struct stellar_module *mod); void stellar_module_set_ctx(struct stellar_module *mod, void *ctx); const char *stellar_module_get_name(struct stellar_module* mod); +void stellar_module_set_name(struct stellar_module* mod, const char *name); struct stellar_module_manager; @@ -24,10 +25,10 @@ typedef void module_on_exit_func(struct stellar_module_manager *mod_mgr, struct struct stellar_module_manager *stellar_module_manager_new(const char *module_spec_toml_path, int max_thread_num, struct mq_schema *mq_schema); void stellar_module_manager_free(struct stellar_module_manager *mod_mgr); -struct stellar_module *stellar_module_manager_get_module(struct stellar_module_manager *mod_mgr, const char *module_name); - void stellar_module_manager_register_thread(struct stellar_module_manager* mod_mgr, int thread_id, struct mq_runtime *mq_rt); +struct stellar_module *stellar_module_manager_get_module(struct stellar_module_manager *mod_mgr, const char *module_name); + // return -1 on error int stellar_module_manager_get_thread_id(struct stellar_module_manager* mod_mgr); int stellar_module_manager_get_max_thread_num(struct stellar_module_manager* mod_mgr); diff --git a/infra/module_manager/module_manager.c b/infra/module_manager/module_manager.c index 53f906c..077231e 100644 --- a/infra/module_manager/module_manager.c +++ b/infra/module_manager/module_manager.c @@ -2,25 +2,32 @@ #include "stellar/module_manager.h" #include "stellar/utils.h" -#include "toml/toml.h" #include #include UT_icd module_specs_icd = {sizeof(struct module_specific), NULL, NULL, NULL}; -static struct module_specific *module_specs_load(const char *toml_conf_path, int *mod_num) +/******************************************* + * module manager internal API * + *******************************************/ + +toml_table_t *toml_parse_file_path(const char *toml_conf_path) { - *mod_num = 0; + if(toml_conf_path==NULL)return NULL; FILE* fp = fopen(toml_conf_path, "r"); if(fp==NULL)return NULL; char errbuf[256]; toml_table_t* conf = toml_parse_file(fp, errbuf, sizeof(errbuf)); fclose(fp); - if (!conf) { - fprintf(stderr, "Error parsing toml: %s\n", errbuf); - return NULL; - } + if(conf==NULL) fprintf(stderr, "Error parsing toml: %s\n", errbuf); + return conf; +} + +struct module_specific *module_specs_load(toml_table_t* conf, int *mod_num) +{ + if(conf==NULL|| mod_num==NULL) return NULL; + *mod_num = 0; struct module_specific* mod_spec=NULL; toml_array_t* mod_array = toml_array_in(conf, "module"); if(mod_array==NULL)goto MODULE_SPEC_LOAD_ERROR; @@ -47,62 +54,62 @@ static struct module_specific *module_specs_load(const char *toml_conf_path, int goto MODULE_SPEC_LOAD_ERROR; } - mod_spec[i].load_cb = (module_on_init_func *) dlsym(handle, init_func_name); - if (!mod_spec[i].load_cb) { + mod_spec[i].on_init_cb = (module_on_init_func *) dlsym(handle, init_func_name); + if (!mod_spec[i].on_init_cb) { fprintf(stderr, "Could not load init function %s: %s\n", init_func_name, dlerror()); } - mod_spec[i].unload_cb = (module_on_exit_func *) dlsym(handle, exit_func_name); - if (!mod_spec[i].unload_cb) { + mod_spec[i].on_exit_cb = (module_on_exit_func *) dlsym(handle, exit_func_name); + if (!mod_spec[i].on_exit_cb) { fprintf(stderr, "Could not load exit function %s: %s\n", exit_func_name, dlerror()); } FREE(path); FREE(init_func_name); FREE(exit_func_name); } - toml_free(conf); return mod_spec; MODULE_SPEC_LOAD_ERROR: - toml_free(conf); if(mod_spec)FREE(mod_spec); *mod_num=0; return NULL; } +struct stellar_module_manager *stellar_module_manager_new_with_toml(toml_table_t *conf, int max_thread_num, struct mq_schema *mq_schema) +{ + int spec_num = 0; + struct module_specific *specs = module_specs_load(conf, &spec_num); + struct stellar_module_manager *mod_mgr = CALLOC(struct stellar_module_manager, 1); + if(spec_num > 0) + { + utarray_new(mod_mgr->schema.module_specs_array,&module_specs_icd); + utarray_reserve(mod_mgr->schema.module_specs_array, spec_num); + } + mod_mgr->schema.max_thread_num=max_thread_num; + mod_mgr->schema.mq_schema=mq_schema; + + // TODO: store module specific data in hash + for(int i = 0; i < spec_num; i++) + { + if (specs[i].on_init_cb != NULL) + { + //TODO: duplicate check mod_name + specs[i].mod=specs[i].on_init_cb(mod_mgr); + utarray_push_back(mod_mgr->schema.module_specs_array, &specs[i]); + } + } + FREE(specs); + return mod_mgr; +} + /******************************************* * stellar module manager API * *******************************************/ struct stellar_module_manager *stellar_module_manager_new(const char *module_spec_toml_path, int max_thread_num, struct mq_schema *mq_schema) { - int spec_num; - struct module_specific *specs = module_specs_load(module_spec_toml_path, &spec_num); - if(spec_num < 0) - { - return NULL; - } - struct stellar_module_manager *mod_mgr = CALLOC(struct stellar_module_manager, 1); - if(spec_num > 0) - { - utarray_new(mod_mgr->schema.module_specs_array,&module_specs_icd); - utarray_reserve(mod_mgr->schema.module_specs_array, spec_num); - } - - mod_mgr->schema.max_thread_num=max_thread_num; - mod_mgr->schema.mq_schema=mq_schema; - - // TODO: store module specific data in hash - - for(int i = 0; i < spec_num; i++) - { - if (specs[i].load_cb != NULL) - { - //TODO: duplicate check mod_name - specs[i].mod=specs[i].load_cb(mod_mgr); - utarray_push_back(mod_mgr->schema.module_specs_array, &specs[i]); - } - } - FREE(specs); + toml_table_t *conf = toml_parse_file_path(module_spec_toml_path); + struct stellar_module_manager *mod_mgr=stellar_module_manager_new_with_toml(conf, max_thread_num, mq_schema); + if(conf)toml_free(conf); return mod_mgr; } @@ -114,8 +121,8 @@ void stellar_module_manager_free(struct stellar_module_manager *mod_mgr) { while ((p = (struct module_specific *)utarray_next(mod_mgr->schema.module_specs_array, p))) { - if (p->unload_cb) - p->unload_cb(mod_mgr, p->mod); + if (p->on_exit_cb) + p->on_exit_cb(mod_mgr, p->mod); } utarray_free(mod_mgr->schema.module_specs_array); } @@ -180,17 +187,20 @@ void stellar_module_manager_register_thread(struct stellar_module_manager* mod_m struct stellar_module *stellar_module_manager_get_module(struct stellar_module_manager *mod_mgr, const char *module_name) { - if(mod_mgr==NULL)return NULL; + if(mod_mgr==NULL || module_name == NULL)return NULL; struct module_specific *p=NULL; if (mod_mgr->schema.module_specs_array) { while ((p = (struct module_specific *)utarray_next(mod_mgr->schema.module_specs_array, p))) { - if(strcmp(p->mod->name, module_name)==0) - { - return p->mod; - } - } + if (p->mod) + { + if (strcmp(p->mod->name, module_name) == 0) + { + return p->mod; + } + } + } } return NULL; } @@ -232,3 +242,10 @@ const char *stellar_module_get_name(struct stellar_module* mod) if(mod==NULL)return NULL; return mod->name; } + +void stellar_module_set_name(struct stellar_module* mod, const char *name) +{ + if(mod==NULL)return; + strncpy(mod->name, name, NAME_MAX); + return; +} \ No newline at end of file diff --git a/infra/module_manager/module_manager_interna.h b/infra/module_manager/module_manager_interna.h index af045e4..6ab1558 100644 --- a/infra/module_manager/module_manager_interna.h +++ b/infra/module_manager/module_manager_interna.h @@ -32,10 +32,15 @@ struct stellar_module_manager struct module_specific { struct stellar_module *mod; - module_on_init_func *load_cb; - module_on_exit_func *unload_cb; + module_on_init_func *on_init_cb; + module_on_exit_func *on_exit_cb; }__attribute__((aligned(sizeof(void*)))); +#include "toml/toml.h" + +toml_table_t *toml_parse_file_path(const char *toml_conf_path) __attribute__((visibility("hidden"))); +struct module_specific *module_specs_load(toml_table_t* conf, int *mod_num) __attribute__((visibility("hidden"))); +struct stellar_module_manager *stellar_module_manager_new_with_toml(toml_table_t *conf, int max_thread_num, struct mq_schema *mq_schema) __attribute__((visibility("hidden"))); #ifdef __cplusplus } #endif \ No newline at end of file diff --git a/infra/module_manager/test/CMakeLists.txt b/infra/module_manager/test/CMakeLists.txt index d1aae36..98be279 100644 --- a/infra/module_manager/test/CMakeLists.txt +++ b/infra/module_manager/test/CMakeLists.txt @@ -3,8 +3,7 @@ add_executable(gtest_module_manager ) -include_directories(${CMAKE_SOURCE_DIR}/infra/plugin_manager/) -include_directories(${CMAKE_SOURCE_DIR}/infra/tuple/) +include_directories(${CMAKE_SOURCE_DIR}/infra/module_manager/) target_link_libraries( gtest_module_manager diff --git a/infra/module_manager/test/gtest_module_manager_main.cpp b/infra/module_manager/test/gtest_module_manager_main.cpp index de5dfa7..625ec1b 100644 --- a/infra/module_manager/test/gtest_module_manager_main.cpp +++ b/infra/module_manager/test/gtest_module_manager_main.cpp @@ -6,23 +6,195 @@ #include "module_manager/module_manager_interna.h" /*********************************** - * TEST PLUGIN MANAGER INIT & EXIT * + * TEST MODUEL MANAGER INTERNAL API * + ***********************************/ +TEST(module_manager_internal, toml_parse_filepath_null) { + toml_table_t *conf = toml_parse_file_path(""); + EXPECT_TRUE(conf==NULL); +} + +TEST(module_manager_internal, toml_parse_filepath_dev_null) { + toml_table_t *conf = toml_parse_file_path("/dev/null"); + EXPECT_TRUE(conf!=NULL); + toml_free(conf); +} + +extern "C" struct stellar_module *gtest_mock_init(struct stellar_module_manager *mod_mgr){return NULL;} +extern "C" void gtest_mock_exit(struct stellar_module_manager *mod_mgr, struct stellar_module *mod){} +const char *gtest_mock_spec_toml = + "[[module]]\n" + "path = \"\"\n" + "init = \"gtest_mock_init\"\n" + "exit = \"gtest_mock_exit\"\n"; + +TEST(module_manager_internal, module_specs_load) { + + toml_table_t *conf = toml_parse((char*)gtest_mock_spec_toml, NULL, 0); + EXPECT_TRUE(conf!=NULL); + + int mod_num=0; + struct module_specific *specs=module_specs_load(conf, &mod_num); + EXPECT_EQ(mod_num, 1); + + EXPECT_EQ(specs[0].on_init_cb, gtest_mock_init); + EXPECT_EQ(specs[0].on_exit_cb, gtest_mock_exit); + + free(specs); + toml_free(conf); + +} + +TEST(module_manager_internal, stellar_module_manager_new_with_toml) { + + struct mq_schema *mq_schema=NULL; + toml_table_t *conf = toml_parse((char*)gtest_mock_spec_toml, NULL, 0); + EXPECT_TRUE(conf!=NULL); + + struct stellar_module_manager *mod_mgr=stellar_module_manager_new_with_toml(conf, 10, mq_schema); + + EXPECT_TRUE(mod_mgr!=NULL); + EXPECT_TRUE(stellar_module_manager_get_module(mod_mgr, "test")==NULL); + EXPECT_EQ(stellar_module_manager_get_max_thread_num(mod_mgr), 10); + EXPECT_EQ(stellar_module_get_mq_schema(mod_mgr), mq_schema); + + EXPECT_EQ(stellar_module_manager_get_thread_id(mod_mgr), -1);// no thread registered + EXPECT_TRUE(stellar_module_get_mq_runtime(mod_mgr)==NULL); + + stellar_module_manager_free(mod_mgr); + toml_free(conf); + +} + +/*********************************** + * TEST STELLAR MODULE API * ***********************************/ -//TODO: test case, plugin_specs_load +TEST(stellar_module, basic_new_and_free) { + + struct stellar_module *mod = stellar_module_new("test"); + EXPECT_TRUE(mod!=NULL); + + stellar_module_set_name(mod, "test1"); + EXPECT_STREQ(stellar_module_get_name(mod), "test1"); + + stellar_module_set_ctx(mod, (void*)1); + EXPECT_EQ((long)stellar_module_get_ctx(mod), 1); + + stellar_module_free(mod); +} + +/*********************************** + * TEST MODULE MANAGER API * + ***********************************/ TEST(stellar_module_manager, new_with_null_toml) { - struct stellar_module_manager *mod_mgr = stellar_module_manager_new("", 1, NULL); + struct mq_schema *mq_schema=NULL; + struct stellar_module_manager *mod_mgr = stellar_module_manager_new(NULL, 10, mq_schema); + EXPECT_TRUE(mod_mgr!=NULL); + EXPECT_TRUE(stellar_module_manager_get_module(mod_mgr, "test")==NULL); + EXPECT_EQ(stellar_module_manager_get_max_thread_num(mod_mgr), 10); + EXPECT_EQ(stellar_module_get_mq_schema(mod_mgr), mq_schema); + + EXPECT_TRUE(stellar_module_get_mq_runtime(mod_mgr)==NULL); + EXPECT_EQ(stellar_module_manager_get_thread_id(mod_mgr), -1);// no thread registered + stellar_module_manager_free(mod_mgr); } TEST(stellar_module_manager, new_with_empty_toml) { - struct stellar_module_manager *mod_mgr = stellar_module_manager_new("/dev/null", 1, NULL); + struct mq_schema *mq_schema=NULL; + struct stellar_module_manager *mod_mgr = stellar_module_manager_new("/dev/null", 10, mq_schema); + EXPECT_TRUE(mod_mgr!=NULL); + EXPECT_TRUE(stellar_module_manager_get_module(mod_mgr, "test")==NULL); + EXPECT_EQ(stellar_module_manager_get_max_thread_num(mod_mgr), 10); + EXPECT_EQ(stellar_module_get_mq_schema(mod_mgr), mq_schema); + + EXPECT_EQ(stellar_module_manager_get_thread_id(mod_mgr), -1);// no thread registered + EXPECT_TRUE(stellar_module_get_mq_runtime(mod_mgr)==NULL); + stellar_module_manager_free(mod_mgr); } +TEST(stellar_module_manager, register_thread) { + + struct mq_schema *mq_schema=(struct mq_schema*)1; + struct stellar_module_manager *mod_mgr=stellar_module_manager_new(NULL, 10, mq_schema); + + EXPECT_TRUE(mod_mgr!=NULL); + + EXPECT_EQ((long)stellar_module_get_mq_schema(mod_mgr), 1); + + EXPECT_EQ(stellar_module_manager_get_thread_id(mod_mgr), -1);// no thread registered + EXPECT_TRUE(stellar_module_get_mq_runtime(mod_mgr)==NULL); + + struct mq_runtime *mq_rt = (struct mq_runtime*)2; + stellar_module_manager_register_thread(mod_mgr, 1, mq_rt); + + EXPECT_EQ(stellar_module_manager_get_thread_id(mod_mgr), 1); + EXPECT_EQ((long)stellar_module_get_mq_runtime(mod_mgr), 2); + + stellar_module_manager_free(mod_mgr); + +} + +/*********************************** + * TEST MODULE MANAGER API * + ***********************************/ + +extern "C" struct stellar_module *gtest_module_init(struct stellar_module_manager *mod_mgr) +{ + struct stellar_module *mod = stellar_module_new("gtest"); + EXPECT_STREQ(stellar_module_get_name(mod), "gtest"); + stellar_module_set_ctx(mod, (void*)1); + + return mod; +} + +extern "C" void gtest_module_exit(struct stellar_module_manager *mod_mgr, struct stellar_module *mod) +{ + EXPECT_STREQ(stellar_module_get_name(mod), "gtest"); + EXPECT_EQ((long)stellar_module_get_ctx(mod), 1); + + EXPECT_EQ(stellar_module_manager_get_module(mod_mgr, "gtest"), mod); + + EXPECT_EQ(stellar_module_manager_get_thread_id(mod_mgr), 1); + EXPECT_EQ((long)stellar_module_get_mq_runtime(mod_mgr), 2); + + stellar_module_free(mod); +} + +const char *gtest_module_spec_toml = + "[[module]]\n" + "path = \"\"\n" + "init = \"gtest_module_init\"\n" + "exit = \"gtest_module_exit\"\n"; + +TEST(module_manager, basic_module) { + + struct mq_schema *mq_schema=(struct mq_schema *)1; + toml_table_t *conf = toml_parse((char*)gtest_module_spec_toml, NULL, 0); + EXPECT_TRUE(conf!=NULL); + + struct stellar_module_manager *mod_mgr=stellar_module_manager_new_with_toml(conf, 10, mq_schema); + EXPECT_TRUE(mod_mgr!=NULL); + + EXPECT_TRUE(stellar_module_manager_get_module(mod_mgr, "gtest")!=NULL); + + EXPECT_EQ(stellar_module_manager_get_max_thread_num(mod_mgr), 10); + EXPECT_EQ((long)stellar_module_get_mq_schema(mod_mgr), 1); + + struct mq_runtime *mq_rt = (struct mq_runtime*)2; + stellar_module_manager_register_thread(mod_mgr, 1, mq_rt); + + EXPECT_EQ((long)stellar_module_manager_get_thread_id(mod_mgr), 1); + EXPECT_EQ((long)stellar_module_get_mq_runtime(mod_mgr), 2); + + stellar_module_manager_free(mod_mgr); + toml_free(conf); + +} /********************************************** * GTEST MAIN * diff --git a/infra/version.map b/infra/version.map index 5e87ff7..ea3336d 100644 --- a/infra/version.map +++ b/infra/version.map @@ -21,19 +21,9 @@ global: tcp_segment_get_data; tcp_segment_get_len; - session_exdata_free; - stellar_exdata_new_index; - session_exdata_set; - session_exdata_get; - - stellar_mq_create_topic; - stellar_mq_get_topic_id; - stellar_mq_update_topic; - stellar_mq_destroy_topic; - stellar_session_mq_subscribe; - session_mq_publish_message; - session_mq_ignore_message; - session_mq_unignore_message; + exdata_*; + mq_*; + stellar_module_*; session_is_symmetric; session_has_duplicate_traffic;