libgnunetchat

library for GNUnet Messenger
Log | Files | Refs | README | LICENSE

commit 42569e3d32251be923bff7b8176215ec2bdbf69b
parent 77bbded42c50c6d18b4389b0f3672b36e30f86fa
Author: Jacki <jacki@thejackimonster.de>
Date:   Wed, 10 Apr 2024 15:12:31 +0200

Implement test case and adjust implementation for attributes

Signed-off-by: Jacki <jacki@thejackimonster.de>

Diffstat:
Minclude/gnunet/gnunet_chat_lib.h | 10++++++++++
Msrc/gnunet_chat_lib.c | 14++++++++++++--
Msrc/gnunet_chat_lib_intern.c | 46+++++++++++++++++++++++++++++++++++++++-------
Msrc/gnunet_chat_message.h | 5++++-
Mtests/meson.build | 10++++++++++
Atests/test_gnunet_chat_attribute.c | 165+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mtests/test_gnunet_chat_message.c | 10+++++-----
7 files changed, 245 insertions(+), 15 deletions(-)

diff --git a/include/gnunet/gnunet_chat_lib.h b/include/gnunet/gnunet_chat_lib.h @@ -123,6 +123,16 @@ enum GNUNET_CHAT_MessageKind GNUNET_CHAT_KIND_TAG = 13, /**< GNUNET_CHAT_KIND_TAG */ /** + * The kind to inform that attributes were updated. + */ + GNUNET_CHAT_KIND_ATTRIBUTES = 14, + + /** + * The kind to inform that attributes were shared. + */ + GNUNET_CHAT_KIND_SHARED_ATTRIBUTES = 15, + + /** * An unknown kind of message. */ GNUNET_CHAT_KIND_UNKNOWN = 0 /**< GNUNET_CHAT_KIND_UNKNOWN */ diff --git a/src/gnunet_chat_lib.c b/src/gnunet_chat_lib.c @@ -318,7 +318,7 @@ GNUNET_CHAT_set_attribute (struct GNUNET_CHAT_Handle *handle, result = GNUNET_RECLAIM_attribute_string_to_value( GNUNET_RECLAIM_ATTRIBUTE_TYPE_STRING, value, - &data, + &(data), &(attributes->attribute->data_size) ); @@ -329,6 +329,7 @@ GNUNET_CHAT_set_attribute (struct GNUNET_CHAT_Handle *handle, return; } + attributes->attribute->type = GNUNET_RECLAIM_ATTRIBUTE_TYPE_STRING; attributes->attribute->data = data; } @@ -1836,6 +1837,10 @@ GNUNET_CHAT_message_get_kind (const struct GNUNET_CHAT_Message *message) return GNUNET_CHAT_KIND_LOGOUT; case GNUNET_CHAT_FLAG_UPDATE: return GNUNET_CHAT_KIND_UPDATE; + case GNUNET_CHAT_FLAG_ATTRIBUTES: + return GNUNET_CHAT_KIND_ATTRIBUTES; + case GNUNET_CHAT_FLAG_SHARED_ATTRIBUTES: + return GNUNET_CHAT_KIND_SHARED_ATTRIBUTES; default: break; } @@ -2025,11 +2030,16 @@ GNUNET_CHAT_message_get_text (const struct GNUNET_CHAT_Message *message) { GNUNET_CHAT_VERSION_ASSERT(); - if ((!message) || (GNUNET_YES != message_has_msg(message))) + if (!message) return NULL; if (GNUNET_CHAT_FLAG_WARNING == message->flag) return message->warning; + else if (GNUNET_CHAT_FLAG_ATTRIBUTES == message->flag) + return message->attr; + + if (GNUNET_YES != message_has_msg(message)) + return NULL; if (GNUNET_MESSENGER_KIND_TEXT == message->msg->header.kind) return message->msg->body.text.text; diff --git a/src/gnunet_chat_lib_intern.c b/src/gnunet_chat_lib_intern.c @@ -408,24 +408,36 @@ cont_update_attribute_with_status (void *cls, attributes->op = NULL; struct GNUNET_CHAT_Handle *handle = attributes->handle; + const char *attribute_name = NULL; + + if (attributes->attribute) + attribute_name = attributes->attribute->name; if (GNUNET_SYSERR == success) - { handle_send_internal_message( handle, NULL, GNUNET_CHAT_KIND_WARNING, emsg ); - - return; - } + else + handle_send_internal_message( + handle, + NULL, + GNUNET_CHAT_FLAG_ATTRIBUTES, + attribute_name + ); + + if (attributes->attribute) + GNUNET_free(attributes->attribute); GNUNET_CONTAINER_DLL_remove( handle->attributes_head, handle->attributes_tail, attributes ); + + GNUNET_free(attributes); } void @@ -536,6 +548,7 @@ cb_iterate_attribute (void *cls, ); struct GNUNET_CHAT_Handle *handle = attributes->handle; + enum GNUNET_GenericReturnValue result = GNUNET_YES; char *value = GNUNET_RECLAIM_attribute_value_to_string( attribute->type, @@ -544,13 +557,18 @@ cb_iterate_attribute (void *cls, ); if (attributes->callback) - attributes->callback(attributes->closure, handle, attribute->name, value); + result = attributes->callback(attributes->closure, handle, attribute->name, value); if (value) GNUNET_free (value); if (attributes->iter) - GNUNET_RECLAIM_get_attributes_next(attributes->iter); + { + if (GNUNET_YES == result) + GNUNET_RECLAIM_get_attributes_next(attributes->iter); + else + GNUNET_RECLAIM_get_attributes_stop(attributes->iter); + } } void @@ -572,6 +590,13 @@ cb_issue_ticket (void *cls, if ((context) && (context->room) && (ticket)) GNUNET_MESSENGER_send_ticket(context->room, ticket); + handle_send_internal_message( + handle, + NULL, + GNUNET_CHAT_FLAG_SHARED_ATTRIBUTES, + NULL + ); + GNUNET_CONTAINER_DLL_remove( handle->attributes_head, handle->attributes_tail, @@ -719,6 +744,13 @@ cont_revoke_ticket (void *cls, GNUNET_CHAT_FLAG_WARNING, emsg ); + else + handle_send_internal_message( + handle, + NULL, + GNUNET_CHAT_FLAG_SHARED_ATTRIBUTES, + NULL + ); GNUNET_CONTAINER_DLL_remove( handle->tickets_head, @@ -756,7 +788,7 @@ cb_consume_ticket_check (void *cls, GNUNET_free(tickets->name); tickets->name = NULL; } - else if (!key) + else if (key) tickets->op = GNUNET_RECLAIM_ticket_revoke( handle->reclaim, key, diff --git a/src/gnunet_chat_message.h b/src/gnunet_chat_message.h @@ -47,7 +47,9 @@ enum GNUNET_CHAT_MessageFlag GNUNET_CHAT_FLAG_REFRESH = 2, GNUNET_CHAT_FLAG_LOGIN = 3, GNUNET_CHAT_FLAG_LOGOUT = 4, - GNUNET_CHAT_FLAG_UPDATE = 5 + GNUNET_CHAT_FLAG_UPDATE = 5, + GNUNET_CHAT_FLAG_ATTRIBUTES = 6, + GNUNET_CHAT_FLAG_SHARED_ATTRIBUTES = 7 }; struct GNUNET_CHAT_Message @@ -58,6 +60,7 @@ struct GNUNET_CHAT_Message union { const struct GNUNET_MESSENGER_Message *msg; const char *warning; + const char *attr; }; struct GNUNET_HashCode hash; diff --git a/tests/meson.build b/tests/meson.build @@ -59,7 +59,17 @@ test_gnunet_chat_message = executable( extra_files: 'test_gnunet_chat.h', ) +test_gnunet_chat_attribute = executable( + 'test_gnunet_chat_attribute.test', + 'test_gnunet_chat_attribute.c', + dependencies: test_deps, + link_with: gnunetchat_lib, + include_directories: tests_include, + extra_files: 'test_gnunet_chat.h', +) + test('test_gnunet_chat_handle', test_gnunet_chat_handle, depends: gnunetchat_lib) test('test_gnunet_chat_lobby', test_gnunet_chat_lobby, depends: gnunetchat_lib) test('test_gnunet_chat_file', test_gnunet_chat_file, depends: gnunetchat_lib) test('test_gnunet_chat_message', test_gnunet_chat_message, depends: gnunetchat_lib) +test('test_gnunet_chat_attribute', test_gnunet_chat_attribute, depends: gnunetchat_lib) diff --git a/tests/test_gnunet_chat_attribute.c b/tests/test_gnunet_chat_attribute.c @@ -0,0 +1,165 @@ +/* + This file is part of GNUnet. + Copyright (C) 2024 GNUnet e.V. + + GNUnet is free software: you can redistribute it and/or modify it + under the terms of the GNU Affero General Public License as published + by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. + + GNUnet is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + + SPDX-License-Identifier: AGPL3.0-or-later + */ +/* + * @author Tobias Frisch + * @file test_gnunet_chat_attribute.c + */ + +#include "test_gnunet_chat.h" +#include <check.h> +#include <gnunet/gnunet_chat_lib.h> +#include <gnunet/gnunet_time_lib.h> +#include <stdio.h> + +enum GNUNET_GenericReturnValue +on_gnunet_chat_attribute_check_it(void *cls, + const struct GNUNET_CHAT_Handle *handle, + struct GNUNET_CHAT_Account *account) +{ + struct GNUNET_CHAT_Handle *chat = (struct GNUNET_CHAT_Handle*) cls; + + ck_assert_ptr_ne(chat, NULL); + ck_assert_ptr_eq(handle, chat); + ck_assert_ptr_ne(account, NULL); + + const char *name = GNUNET_CHAT_account_get_name(account); + + ck_assert_ptr_ne(name, NULL); + ck_assert_ptr_eq(GNUNET_CHAT_get_connected(handle), NULL); + + if (0 == strcmp(name, "gnunet_chat_attribute_check")) + { + GNUNET_CHAT_connect(chat, account); + return GNUNET_NO; + } + + return GNUNET_YES; +} + +enum GNUNET_GenericReturnValue +on_gnunet_chat_attribute_check_attr(void *cls, + struct GNUNET_CHAT_Handle *handle, + const char *name, + const char *value) +{ + ck_assert_ptr_ne(name, NULL); + if (0 == strcmp(name, "test_attribute_name")) + { + ck_assert_ptr_ne(value, NULL); + ck_assert_int_eq(strcmp(value, "test_attribute_value"), 0); + GNUNET_CHAT_delete_attribute(handle, "test_attribute_name"); + return GNUNET_NO; + } + + return GNUNET_YES; +} + +enum GNUNET_GenericReturnValue +on_gnunet_chat_attribute_check_msg(void *cls, + struct GNUNET_CHAT_Context *context, + const struct GNUNET_CHAT_Message *message) +{ + struct GNUNET_CHAT_Handle *handle = *( + (struct GNUNET_CHAT_Handle**) cls + ); + + const char *text = NULL; + + ck_assert_ptr_ne(handle, NULL); + ck_assert_ptr_ne(message, NULL); + + if (GNUNET_CHAT_get_connected(handle)) + goto skip_search_account; + + GNUNET_CHAT_iterate_accounts( + handle, + on_gnunet_chat_attribute_check_it, + handle + ); + + if (!GNUNET_CHAT_get_connected(handle)) + return GNUNET_YES; + +skip_search_account: + switch (GNUNET_CHAT_message_get_kind(message)) + { + case GNUNET_CHAT_KIND_LOGIN: + ck_assert_ptr_eq(context, NULL); + + GNUNET_CHAT_set_attribute( + handle, + "test_attribute_name", + "test_attribute_value", + GNUNET_TIME_relative_get_forever_() + ); + break; + case GNUNET_CHAT_KIND_LOGOUT: + ck_assert_int_eq(GNUNET_CHAT_account_delete( + handle, + "gnunet_chat_attribute_check" + ), GNUNET_OK); + + GNUNET_CHAT_stop(handle); + break; + case GNUNET_CHAT_KIND_ATTRIBUTES: + ck_assert_ptr_eq(context, NULL); + + text = GNUNET_CHAT_message_get_text(message); + + if (text) + { + ck_assert_int_eq(strcmp(text, "test_attribute_name"), 0); + GNUNET_CHAT_get_attributes( + handle, + on_gnunet_chat_attribute_check_attr, + NULL + ); + } + else + GNUNET_CHAT_disconnect(handle); + + break; + default: + break; + } + + return GNUNET_YES; +} + +void +call_gnunet_chat_attribute_check(const struct GNUNET_CONFIGURATION_Handle *cfg) +{ + static struct GNUNET_CHAT_Handle *handle = NULL; + handle = GNUNET_CHAT_start(cfg, on_gnunet_chat_attribute_check_msg, &handle); + + ck_assert_ptr_ne(handle, NULL); + ck_assert_int_eq(GNUNET_CHAT_account_create( + handle, + "gnunet_chat_attribute_check" + ), GNUNET_OK); +} + +CREATE_GNUNET_TEST(test_gnunet_chat_attribute_check, call_gnunet_chat_attribute_check) + +START_SUITE(handle_suite, "Attribute") +ADD_TEST_TO_SUITE(test_gnunet_chat_attribute_check, "Check") +END_SUITE + +MAIN_SUITE(handle_suite, CK_NORMAL) diff --git a/tests/test_gnunet_chat_message.c b/tests/test_gnunet_chat_message.c @@ -27,7 +27,7 @@ #include <gnunet/gnunet_chat_lib.h> #include <stdio.h> -int +enum GNUNET_GenericReturnValue on_gnunet_chat_message_text_it(void *cls, const struct GNUNET_CHAT_Handle *handle, struct GNUNET_CHAT_Account *account) @@ -52,7 +52,7 @@ on_gnunet_chat_message_text_it(void *cls, return GNUNET_YES; } -int +enum GNUNET_GenericReturnValue on_gnunet_chat_message_text_msg(void *cls, struct GNUNET_CHAT_Context *context, const struct GNUNET_CHAT_Message *message) @@ -61,6 +61,9 @@ on_gnunet_chat_message_text_msg(void *cls, (struct GNUNET_CHAT_Handle**) cls ); + struct GNUNET_CHAT_Group *group = NULL; + const char *text = NULL; + ck_assert_ptr_ne(handle, NULL); ck_assert_ptr_ne(message, NULL); @@ -77,9 +80,6 @@ on_gnunet_chat_message_text_msg(void *cls, return GNUNET_YES; skip_search_account: - struct GNUNET_CHAT_Group *group = NULL; - const char *text = NULL; - switch (GNUNET_CHAT_message_get_kind(message)) { case GNUNET_CHAT_KIND_LOGIN: