From b791c2738556ceb4432d8b0eb4bc20beda40d76a Mon Sep 17 00:00:00 2001 From: Naveen Albert Date: Thu, 29 Feb 2024 09:27:09 -0500 Subject: [PATCH] app_voicemail: Properly reinitialize config after unit tests. Most app_voicemail unit tests were not properly cleaning up after themselves after running. This led to test mailboxes lingering around in the system. It also meant that if any unit tests in app_voicemail that create mailboxes were executed and the module was not unloaded/loaded again prior to running the test_voicemail_vm_info unit test, Asterisk would segfault due to an attempt to copy a NULL string. The load_config test did actually have logic to reinitialize the config after the test. However, this did not work in practice since load_config() would not reload the config since voicemail.conf had not changed during the test; thus, additional logic has been added to ensure that voicemail.conf is truly reloaded, after any unit tests which modify the users list. This prevents the SEGV due to invalid mailboxes lingering around, and also ensures that the system state is restored to what it was prior to the tests running. Resolves: #629 --- apps/app_voicemail.c | 33 +++++++++++++++++++++++++++++---- 1 file changed, 29 insertions(+), 4 deletions(-) diff --git a/apps/app_voicemail.c b/apps/app_voicemail.c index e5cb58cd51..b06842a38b 100644 --- a/apps/app_voicemail.c +++ b/apps/app_voicemail.c @@ -768,6 +768,18 @@ static const char * const mailbox_folders[] = { "Urgent", }; +/*! + * \brief Reload voicemail.conf + * \param reload Whether this is a reload as opposed to module load + * \param force Forcefully reload the config, even it has not changed + * \retval 0 on success, nonzero on failure + */ +static int load_config_force(int reload, int force); + +/*! \brief Forcibly reload voicemail.conf, even if it has not changed. + * This is necessary after running unit tests. */ +#define force_reload_config() load_config_force(1, 1) + static int load_config(int reload); #ifdef TEST_FRAMEWORK static int load_config_from_memory(int reload, struct ast_config *cfg, struct ast_config *ucfg); @@ -13110,6 +13122,7 @@ AST_TEST_DEFINE(test_voicemail_vmuser) #endif free_user(vmu); + force_reload_config(); /* Restore original config */ return res ? AST_TEST_FAIL : AST_TEST_PASS; } #endif @@ -14202,10 +14215,10 @@ static const char *substitute_escapes(const char *value) return ast_str_buffer(str); } -static int load_config(int reload) +static int load_config_force(int reload, int force) { struct ast_config *cfg, *ucfg; - struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 }; + struct ast_flags config_flags = { reload && !force ? CONFIG_FLAG_FILEUNCHANGED : 0 }; int res; ast_unload_realtime("voicemail"); @@ -14243,6 +14256,11 @@ static int load_config(int reload) return res; } +static int load_config(int reload) +{ + return load_config_force(reload, 0); +} + #ifdef TEST_FRAMEWORK static int load_config_from_memory(int reload, struct ast_config *cfg, struct ast_config *ucfg) { @@ -15417,6 +15435,7 @@ AST_TEST_DEFINE(test_voicemail_msgcount) } free_user(vmu); + force_reload_config(); /* Restore original config */ return res; } @@ -15527,6 +15546,7 @@ AST_TEST_DEFINE(test_voicemail_notify_endl) } fclose(file); free_user(vmu); + force_reload_config(); /* Restore original config */ return res; } @@ -15599,8 +15619,8 @@ AST_TEST_DEFINE(test_voicemail_load_config) #undef CHECK - /* restore config */ - load_config(1); /* this might say "Failed to load configuration file." */ + /* Forcibly restore the original config, to reinitialize after test */ + force_reload_config(); /* this might say "Failed to load configuration file." */ cleanup: unlink(config_filename); @@ -15666,6 +15686,11 @@ AST_TEST_DEFINE(test_voicemail_vm_info) populate_defaults(vmu); vmu->email = ast_strdup("vm-info-test@example.net"); + if (!vmu->email) { + ast_test_status_update(test, "Cannot create vmu email\n"); + chan = ast_channel_unref(chan); + return AST_TEST_FAIL; + } ast_copy_string(vmu->fullname, "Test Framework Mailbox", sizeof(vmu->fullname)); ast_copy_string(vmu->pager, "vm-info-pager-test@example.net", sizeof(vmu->pager)); ast_copy_string(vmu->language, "en", sizeof(vmu->language));