res_sorcery_realtime: fix bug when successful UPDATE is treated as failed
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 17:16:14 +0000 (12:16 -0500)
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 37c6d3f..26aa17b 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 abf2840..4023654 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 b33031e..033bf5d 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);