Blame tests/test-repo-finder-avahi.c

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