]> git.ipfire.org Git - thirdparty/asterisk.git/commitdiff
res_sorcery_realtime: fix bug when successful UPDATE is treated as failed 46/3146/2
authorAlexei Gradinari <alex2grad@gmail.com>
Mon, 4 Jul 2016 21:38:57 +0000 (17:38 -0400)
committerAlexei Gradinari <alex2grad@gmail.com>
Thu, 7 Jul 2016 14:02:45 +0000 (10:02 -0400)
If the SQL UPDATE statement changes nothing then SQLRowCount returns 0.
This value should be treated as success.
But the function sorcery_realtime_update treats it as failed.

This bug was found using stress tests on PJSIP.
If there are 2 consecutive SIP REGISTER requests with the same contact data
during 1 second then res_pjsip_registrar adds contact location on 1st request
and tries to update contact location on 2nd.
The update fails and res_pjsip_registrar even removes correct contact location.

The test "object_update_uncreated" was removed from test_sorcery_realtime.c
because it's now a valid situation.

This patch also adds missing debug of extra SQL parameter.

ASTERISK-26172 #close

Change-Id: I05a7f3051455336c9dda29efc229decf86071303

res/res_config_odbc.c
res/res_sorcery_realtime.c
tests/test_sorcery_realtime.c

index 2888d359734af1fa4e98eb531dac435e17bd54ac..2d991a586dfe7f3ea507c827d4c91bdbf1ccca33 100644 (file)
@@ -137,6 +137,7 @@ static SQLHSTMT custom_prepare(struct odbc_obj *obj, void *data)
 
        if (!ast_strlen_zero(cps->extra)) {
                const char *newval = cps->extra;
+               ast_debug(1, "Parameter %d = '%s'\n", x, newval);
                if (strchr(newval, ';') || strchr(newval, '^')) {
                        ENCODE_CHUNK(encodebuf, newval);
                        ast_string_field_set(cps, encoding[x], encodebuf);
index 2c533ea0b62ae8b4af354e95dc95c006f2939b9c..138d6ea95ea69372d08a52b07bb9c458fd6ce660 100644 (file)
@@ -271,7 +271,7 @@ static int sorcery_realtime_update(const struct ast_sorcery *sorcery, void *data
                return -1;
        }
 
-       return (ast_update_realtime_fields(config->family, UUID_FIELD, ast_sorcery_object_get_id(object), fields) <= 0) ? -1 : 0;
+       return (ast_update_realtime_fields(config->family, UUID_FIELD, ast_sorcery_object_get_id(object), fields) < 0) ? -1 : 0;
 }
 
 static int sorcery_realtime_delete(const struct ast_sorcery *sorcery, void *data, void *object)
index 3ed14623ef973ea8363b595587ce6bd5e944a7f7..64475fb8b3394aa44302e306e812a72656200515 100644 (file)
@@ -711,41 +711,6 @@ AST_TEST_DEFINE(object_update)
        return AST_TEST_PASS;
 }
 
-AST_TEST_DEFINE(object_update_uncreated)
-{
-       RAII_VAR(struct ast_sorcery *, sorcery, NULL, deinitialize_sorcery);
-       RAII_VAR(struct test_sorcery_object *, obj, NULL, ao2_cleanup);
-
-       switch (cmd) {
-       case TEST_INIT:
-               info->name = "object_update_uncreated";
-               info->category = "/res/sorcery_realtime/";
-               info->summary = "sorcery object update unit test";
-               info->description =
-                       "Test updating of an uncreated object in sorcery using realtime wizard";
-               return AST_TEST_NOT_RUN;
-       case TEST_EXECUTE:
-               break;
-       }
-
-       if (!(sorcery = alloc_and_initialize_sorcery("sorcery_realtime_test"))) {
-               ast_test_status_update(test, "Failed to open sorcery structure\n");
-               return AST_TEST_FAIL;
-       }
-
-       if (!(obj = ast_sorcery_alloc(sorcery, "test", "blah"))) {
-               ast_test_status_update(test, "Failed to allocate a known object type\n");
-               return AST_TEST_FAIL;
-       }
-
-       if (!ast_sorcery_update(sorcery, obj)) {
-               ast_test_status_update(test, "Successfully updated an object which has not been created yet\n");
-               return AST_TEST_FAIL;
-       }
-
-       return AST_TEST_PASS;
-}
-
 AST_TEST_DEFINE(object_delete)
 {
        RAII_VAR(struct ast_sorcery *, sorcery, NULL, deinitialize_sorcery);
@@ -942,7 +907,6 @@ static int unload_module(void)
        AST_TEST_UNREGISTER(object_retrieve_regex);
        AST_TEST_UNREGISTER(object_retrieve_regex_nofetch);
        AST_TEST_UNREGISTER(object_update);
-       AST_TEST_UNREGISTER(object_update_uncreated);
        AST_TEST_UNREGISTER(object_delete);
        AST_TEST_UNREGISTER(object_delete_uncreated);
        AST_TEST_UNREGISTER(object_allocate_on_retrieval);
@@ -964,7 +928,6 @@ static int load_module(void)
        AST_TEST_REGISTER(object_retrieve_regex);
        AST_TEST_REGISTER(object_retrieve_regex_nofetch);
        AST_TEST_REGISTER(object_update);
-       AST_TEST_REGISTER(object_update_uncreated);
        AST_TEST_REGISTER(object_delete);
        AST_TEST_REGISTER(object_delete_uncreated);
        AST_TEST_REGISTER(object_allocate_on_retrieval);