mirror of
https://github.com/ostreedev/ostree.git
synced 2024-12-23 21:35:26 +03:00
228 lines
8.1 KiB
C
228 lines
8.1 KiB
C
/*
|
|
* Copyright © 2017 Endless Mobile, Inc.
|
|
*
|
|
* SPDX-License-Identifier: LGPL-2.0+
|
|
*
|
|
* This library is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
* License as published by the Free Software Foundation; either
|
|
* version 2 of the License, or (at your option) any later version.
|
|
*
|
|
* This library 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
|
|
* Lesser General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
* License along with this library. If not, see <https://www.gnu.org/licenses/>.
|
|
*
|
|
* Authors:
|
|
* - Philip Withnall <withnall@endlessm.com>
|
|
*/
|
|
|
|
#include "config.h"
|
|
|
|
#include <gio/gio.h>
|
|
#include <glib.h>
|
|
#include <glib-object.h>
|
|
#include <locale.h>
|
|
#include <string.h>
|
|
|
|
#include "ostree-autocleanups.h"
|
|
#include "ostree-repo-finder.h"
|
|
#include "ostree-repo-finder-avahi.h"
|
|
#include "ostree-repo-finder-avahi-private.h"
|
|
|
|
/* FIXME: Upstream this */
|
|
G_DEFINE_AUTOPTR_CLEANUP_FUNC (AvahiStringList, avahi_string_list_free)
|
|
|
|
/* Test the object constructor works at a basic level. */
|
|
static void
|
|
test_repo_finder_avahi_init (void)
|
|
{
|
|
g_autoptr(OstreeRepoFinderAvahi) finder = NULL;
|
|
g_autoptr(GMainContext) context = NULL;
|
|
|
|
/* Default main context. */
|
|
finder = ostree_repo_finder_avahi_new (NULL);
|
|
g_clear_object (&finder);
|
|
|
|
/* Explicit main context. */
|
|
context = g_main_context_new ();
|
|
finder = ostree_repo_finder_avahi_new (context);
|
|
g_clear_object (&finder);
|
|
}
|
|
|
|
/* Test parsing valid and invalid TXT records. */
|
|
static void
|
|
test_repo_finder_avahi_txt_records_parse (void)
|
|
{
|
|
struct
|
|
{
|
|
const guint8 *txt;
|
|
gsize txt_len;
|
|
const gchar *expected_key; /* (nullable) to indicate parse failure */
|
|
const guint8 *expected_value; /* (nullable) to allow for valueless keys */
|
|
gsize expected_value_len;
|
|
}
|
|
vectors[] =
|
|
{
|
|
{ (const guint8 *) "", 0, NULL, NULL, 0 },
|
|
{ (const guint8 *) "\x00", 1, NULL, NULL, 0 },
|
|
{ (const guint8 *) "\xff", 1, NULL, NULL, 0 },
|
|
{ (const guint8 *) "k\x00", 2, NULL, NULL, 0 },
|
|
{ (const guint8 *) "k\xff", 2, NULL, NULL, 0 },
|
|
{ (const guint8 *) "=", 1, NULL, NULL, 0 },
|
|
{ (const guint8 *) "=value", 6, NULL, NULL, 0 },
|
|
{ (const guint8 *) "k=v", 3, "k", (const guint8 *) "v", 1 },
|
|
{ (const guint8 *) "key=value", 9, "key", (const guint8 *) "value", 5 },
|
|
{ (const guint8 *) "k=v=", 4, "k", (const guint8 *) "v=", 2 },
|
|
{ (const guint8 *) "k=", 2, "k", (const guint8 *) "", 0 },
|
|
{ (const guint8 *) "k", 1, "k", NULL, 0 },
|
|
{ (const guint8 *) "k==", 3, "k", (const guint8 *) "=", 1 },
|
|
{ (const guint8 *) "k=\x00\x01\x02", 5, "k", (const guint8 *) "\x00\x01\x02", 3 },
|
|
};
|
|
gsize i;
|
|
|
|
for (i = 0; i < G_N_ELEMENTS (vectors); i++)
|
|
{
|
|
g_autoptr(AvahiStringList) string_list = NULL;
|
|
g_autoptr(GHashTable) attributes = NULL;
|
|
|
|
g_test_message ("Vector %" G_GSIZE_FORMAT, i);
|
|
|
|
string_list = avahi_string_list_add_arbitrary (NULL, vectors[i].txt, vectors[i].txt_len);
|
|
|
|
attributes = _ostree_txt_records_parse (string_list);
|
|
|
|
if (vectors[i].expected_key != NULL)
|
|
{
|
|
GBytes *value;
|
|
g_autoptr(GBytes) expected_value = NULL;
|
|
|
|
g_assert_true (g_hash_table_lookup_extended (attributes,
|
|
vectors[i].expected_key,
|
|
NULL,
|
|
(gpointer *) &value));
|
|
g_assert_cmpuint (g_hash_table_size (attributes), ==, 1);
|
|
|
|
if (vectors[i].expected_value != NULL)
|
|
{
|
|
g_assert_nonnull (value);
|
|
expected_value = g_bytes_new_static (vectors[i].expected_value, vectors[i].expected_value_len);
|
|
g_assert_true (g_bytes_equal (value, expected_value));
|
|
}
|
|
else
|
|
{
|
|
g_assert_null (value);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
g_assert_cmpuint (g_hash_table_size (attributes), ==, 0);
|
|
}
|
|
}
|
|
}
|
|
|
|
/* Test that the first value for a set of duplicate records is returned.
|
|
* See RFC 6763, §6.4. */
|
|
static void
|
|
test_repo_finder_avahi_txt_records_duplicates (void)
|
|
{
|
|
g_autoptr(AvahiStringList) string_list = NULL;
|
|
g_autoptr(GHashTable) attributes = NULL;
|
|
GBytes *value;
|
|
g_autoptr(GBytes) expected_value = NULL;
|
|
|
|
/* Reverse the list before using it, as they are built in reverse order.
|
|
* (See the #AvahiStringList documentation.) */
|
|
string_list = avahi_string_list_new ("k=value1", "k=value2", "k=value3", NULL);
|
|
string_list = avahi_string_list_reverse (string_list);
|
|
attributes = _ostree_txt_records_parse (string_list);
|
|
|
|
g_assert_cmpuint (g_hash_table_size (attributes), ==, 1);
|
|
value = g_hash_table_lookup (attributes, "k");
|
|
g_assert_nonnull (value);
|
|
|
|
expected_value = g_bytes_new_static ("value1", strlen ("value1"));
|
|
g_assert_true (g_bytes_equal (value, expected_value));
|
|
}
|
|
|
|
/* Test that keys are parsed and looked up case insensitively.
|
|
* See RFC 6763, §6.4. */
|
|
static void
|
|
test_repo_finder_avahi_txt_records_case_sensitivity (void)
|
|
{
|
|
g_autoptr(AvahiStringList) string_list = NULL;
|
|
g_autoptr(GHashTable) attributes = NULL;
|
|
GBytes *value1, *value2;
|
|
g_autoptr(GBytes) expected_value1 = NULL, expected_value2 = NULL;
|
|
|
|
/* Reverse the list before using it, as they are built in reverse order.
|
|
* (See the #AvahiStringList documentation.) */
|
|
string_list = avahi_string_list_new ("k=value1",
|
|
"K=value2",
|
|
"KeY2=v",
|
|
NULL);
|
|
string_list = avahi_string_list_reverse (string_list);
|
|
attributes = _ostree_txt_records_parse (string_list);
|
|
|
|
g_assert_cmpuint (g_hash_table_size (attributes), ==, 2);
|
|
|
|
value1 = g_hash_table_lookup (attributes, "k");
|
|
g_assert_nonnull (value1);
|
|
expected_value1 = g_bytes_new_static ("value1", strlen ("value1"));
|
|
g_assert_true (g_bytes_equal (value1, expected_value1));
|
|
|
|
g_assert_null (g_hash_table_lookup (attributes, "K"));
|
|
|
|
value2 = g_hash_table_lookup (attributes, "key2");
|
|
g_assert_nonnull (value2);
|
|
expected_value2 = g_bytes_new_static ("v", 1);
|
|
g_assert_true (g_bytes_equal (value2, expected_value2));
|
|
|
|
g_assert_null (g_hash_table_lookup (attributes, "KeY2"));
|
|
}
|
|
|
|
/* Test that keys which have an empty value can be distinguished from those
|
|
* which have no value. See RFC 6763, §6.4. */
|
|
static void
|
|
test_repo_finder_avahi_txt_records_empty_and_missing (void)
|
|
{
|
|
g_autoptr(AvahiStringList) string_list = NULL;
|
|
g_autoptr(GHashTable) attributes = NULL;
|
|
GBytes *value1, *value2;
|
|
g_autoptr(GBytes) expected_value1 = NULL;
|
|
|
|
string_list = avahi_string_list_new ("empty=",
|
|
"missing",
|
|
NULL);
|
|
attributes = _ostree_txt_records_parse (string_list);
|
|
|
|
g_assert_cmpuint (g_hash_table_size (attributes), ==, 2);
|
|
|
|
value1 = g_hash_table_lookup (attributes, "empty");
|
|
g_assert_nonnull (value1);
|
|
expected_value1 = g_bytes_new_static ("", 0);
|
|
g_assert_true (g_bytes_equal (value1, expected_value1));
|
|
|
|
g_assert_true (g_hash_table_lookup_extended (attributes, "missing", NULL, (gpointer *) &value2));
|
|
g_assert_null (value2);
|
|
}
|
|
|
|
int main (int argc, char **argv)
|
|
{
|
|
setlocale (LC_ALL, "");
|
|
g_test_init (&argc, &argv, NULL);
|
|
|
|
g_test_add_func ("/repo-finder-avahi/init", test_repo_finder_avahi_init);
|
|
g_test_add_func ("/repo-finder-avahi/txt-records/parse", test_repo_finder_avahi_txt_records_parse);
|
|
g_test_add_func ("/repo-finder-avahi/txt-records/duplicates", test_repo_finder_avahi_txt_records_duplicates);
|
|
g_test_add_func ("/repo-finder-avahi/txt-records/case-sensitivity", test_repo_finder_avahi_txt_records_case_sensitivity);
|
|
g_test_add_func ("/repo-finder-avahi/txt-records/empty-and-missing", test_repo_finder_avahi_txt_records_empty_and_missing);
|
|
/* FIXME: Add tests for service processing, probably by splitting the
|
|
* code in OstreeRepoFinderAvahi around found_services. */
|
|
|
|
return g_test_run();
|
|
}
|