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:
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: