mirror of
https://gitlab.freedesktop.org/dbus/dbus.git
synced 2026-05-09 10:48:26 +02:00
test: Unembed hash test from libdbus and move it into test/
This required exposing one additional internal symbol: _dbus_hash_table_ref(). I think that's a reasonable trade-off for not compiling this test into the library. Signed-off-by: Simon McVittie <smcv@collabora.com>
This commit is contained in:
parent
10a5a2c695
commit
053a62122b
4 changed files with 487 additions and 443 deletions
440
dbus/dbus-hash.c
440
dbus/dbus-hash.c
|
|
@ -1592,443 +1592,3 @@ _dbus_hash_table_to_array (DBusHashTable *table, char delimiter)
|
|||
}
|
||||
|
||||
/** @} */
|
||||
|
||||
#ifdef DBUS_ENABLE_EMBEDDED_TESTS
|
||||
#include "dbus-test.h"
|
||||
#include <stdio.h>
|
||||
|
||||
/* If you're wondering why the hash table test takes
|
||||
* forever to run, it's because we call this function
|
||||
* in inner loops thus making things quadratic.
|
||||
*/
|
||||
static int
|
||||
count_entries (DBusHashTable *table)
|
||||
{
|
||||
DBusHashIter iter;
|
||||
int count;
|
||||
|
||||
count = 0;
|
||||
_dbus_hash_iter_init (table, &iter);
|
||||
while (_dbus_hash_iter_next (&iter))
|
||||
++count;
|
||||
|
||||
_dbus_assert (count == _dbus_hash_table_get_n_entries (table));
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static inline void *
|
||||
steal (void *ptr)
|
||||
{
|
||||
/* @ptr is passed in as void* to avoid casting in the call */
|
||||
void **_ptr = (void **) ptr;
|
||||
void *val;
|
||||
|
||||
val = *_ptr;
|
||||
*_ptr = NULL;
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
/**
|
||||
* @ingroup DBusHashTableInternals
|
||||
* Unit test for DBusHashTable
|
||||
* @returns #TRUE on success.
|
||||
*/
|
||||
dbus_bool_t
|
||||
_dbus_hash_test (const char *test_data_dir _DBUS_GNUC_UNUSED)
|
||||
{
|
||||
int i;
|
||||
DBusHashTable *table1;
|
||||
DBusHashTable *table2;
|
||||
DBusHashTable *table3;
|
||||
DBusHashIter iter;
|
||||
#define N_HASH_KEYS 5000
|
||||
char **keys;
|
||||
dbus_bool_t ret = FALSE;
|
||||
char *str_key = NULL;
|
||||
char *str_value = NULL;
|
||||
|
||||
keys = dbus_new (char *, N_HASH_KEYS);
|
||||
if (keys == NULL)
|
||||
_dbus_test_fatal ("no memory");
|
||||
|
||||
for (i = 0; i < N_HASH_KEYS; i++)
|
||||
{
|
||||
keys[i] = dbus_malloc (128);
|
||||
|
||||
if (keys[i] == NULL)
|
||||
_dbus_test_fatal ("no memory");
|
||||
}
|
||||
|
||||
_dbus_test_diag ("Computing test hash keys...");
|
||||
i = 0;
|
||||
while (i < N_HASH_KEYS)
|
||||
{
|
||||
int len;
|
||||
|
||||
len = sprintf (keys[i], "Hash key %d", i);
|
||||
_dbus_assert (*(keys[i] + len) == '\0');
|
||||
++i;
|
||||
}
|
||||
_dbus_test_diag ("... done.");
|
||||
|
||||
table1 = _dbus_hash_table_new (DBUS_HASH_STRING,
|
||||
dbus_free, dbus_free);
|
||||
if (table1 == NULL)
|
||||
goto out;
|
||||
|
||||
table2 = _dbus_hash_table_new (DBUS_HASH_INT,
|
||||
NULL, dbus_free);
|
||||
if (table2 == NULL)
|
||||
goto out;
|
||||
|
||||
table3 = _dbus_hash_table_new (DBUS_HASH_UINTPTR,
|
||||
NULL, dbus_free);
|
||||
if (table3 == NULL)
|
||||
goto out;
|
||||
|
||||
/* Insert and remove a bunch of stuff, counting the table in between
|
||||
* to be sure it's not broken and that iteration works
|
||||
*/
|
||||
i = 0;
|
||||
while (i < 3000)
|
||||
{
|
||||
const void *out_value;
|
||||
|
||||
str_key = _dbus_strdup (keys[i]);
|
||||
if (str_key == NULL)
|
||||
goto out;
|
||||
str_value = _dbus_strdup ("Value!");
|
||||
if (str_value == NULL)
|
||||
goto out;
|
||||
|
||||
if (!_dbus_hash_table_insert_string (table1,
|
||||
steal (&str_key),
|
||||
steal (&str_value)))
|
||||
goto out;
|
||||
|
||||
str_value = _dbus_strdup (keys[i]);
|
||||
if (str_value == NULL)
|
||||
goto out;
|
||||
|
||||
if (!_dbus_hash_table_insert_int (table2,
|
||||
i, steal (&str_value)))
|
||||
goto out;
|
||||
|
||||
str_value = _dbus_strdup (keys[i]);
|
||||
if (str_value == NULL)
|
||||
goto out;
|
||||
|
||||
if (!_dbus_hash_table_insert_uintptr (table3,
|
||||
i, steal (&str_value)))
|
||||
goto out;
|
||||
|
||||
_dbus_assert (count_entries (table1) == i + 1);
|
||||
_dbus_assert (count_entries (table2) == i + 1);
|
||||
_dbus_assert (count_entries (table3) == i + 1);
|
||||
|
||||
out_value = _dbus_hash_table_lookup_string (table1, keys[i]);
|
||||
_dbus_assert (out_value != NULL);
|
||||
_dbus_assert (strcmp (out_value, "Value!") == 0);
|
||||
|
||||
out_value = _dbus_hash_table_lookup_int (table2, i);
|
||||
_dbus_assert (out_value != NULL);
|
||||
_dbus_assert (strcmp (out_value, keys[i]) == 0);
|
||||
|
||||
out_value = _dbus_hash_table_lookup_uintptr (table3, i);
|
||||
_dbus_assert (out_value != NULL);
|
||||
_dbus_assert (strcmp (out_value, keys[i]) == 0);
|
||||
|
||||
++i;
|
||||
}
|
||||
|
||||
--i;
|
||||
while (i >= 0)
|
||||
{
|
||||
_dbus_hash_table_remove_string (table1,
|
||||
keys[i]);
|
||||
|
||||
_dbus_hash_table_remove_int (table2, i);
|
||||
|
||||
_dbus_hash_table_remove_uintptr (table3, i);
|
||||
|
||||
_dbus_assert (count_entries (table1) == i);
|
||||
_dbus_assert (count_entries (table2) == i);
|
||||
_dbus_assert (count_entries (table3) == i);
|
||||
|
||||
--i;
|
||||
}
|
||||
|
||||
_dbus_hash_table_ref (table1);
|
||||
_dbus_hash_table_ref (table2);
|
||||
_dbus_hash_table_ref (table3);
|
||||
_dbus_hash_table_unref (table1);
|
||||
_dbus_hash_table_unref (table2);
|
||||
_dbus_hash_table_unref (table3);
|
||||
_dbus_hash_table_unref (table1);
|
||||
_dbus_hash_table_unref (table2);
|
||||
_dbus_hash_table_unref (table3);
|
||||
table3 = NULL;
|
||||
|
||||
/* Insert a bunch of stuff then check
|
||||
* that iteration works correctly (finds the right
|
||||
* values, iter_set_value works, etc.)
|
||||
*/
|
||||
table1 = _dbus_hash_table_new (DBUS_HASH_STRING,
|
||||
dbus_free, dbus_free);
|
||||
if (table1 == NULL)
|
||||
goto out;
|
||||
|
||||
table2 = _dbus_hash_table_new (DBUS_HASH_INT,
|
||||
NULL, dbus_free);
|
||||
if (table2 == NULL)
|
||||
goto out;
|
||||
|
||||
i = 0;
|
||||
while (i < 5000)
|
||||
{
|
||||
str_key = _dbus_strdup (keys[i]);
|
||||
if (str_key == NULL)
|
||||
goto out;
|
||||
str_value = _dbus_strdup ("Value!");
|
||||
if (str_value == NULL)
|
||||
goto out;
|
||||
|
||||
if (!_dbus_hash_table_insert_string (table1,
|
||||
steal (&str_key),
|
||||
steal (&str_value)))
|
||||
goto out;
|
||||
|
||||
str_value = _dbus_strdup (keys[i]);
|
||||
if (str_value == NULL)
|
||||
goto out;
|
||||
|
||||
if (!_dbus_hash_table_insert_int (table2,
|
||||
i, steal (&str_value)))
|
||||
goto out;
|
||||
|
||||
_dbus_assert (count_entries (table1) == i + 1);
|
||||
_dbus_assert (count_entries (table2) == i + 1);
|
||||
|
||||
++i;
|
||||
}
|
||||
|
||||
_dbus_hash_iter_init (table1, &iter);
|
||||
while (_dbus_hash_iter_next (&iter))
|
||||
{
|
||||
const char *key;
|
||||
const void *value;
|
||||
|
||||
key = _dbus_hash_iter_get_string_key (&iter);
|
||||
value = _dbus_hash_iter_get_value (&iter);
|
||||
|
||||
_dbus_assert (_dbus_hash_table_lookup_string (table1, key) == value);
|
||||
|
||||
str_value = _dbus_strdup ("Different value!");
|
||||
if (str_value == NULL)
|
||||
goto out;
|
||||
|
||||
value = str_value;
|
||||
_dbus_hash_iter_set_value (&iter, steal (&str_value));
|
||||
_dbus_assert (_dbus_hash_table_lookup_string (table1, key) == value);
|
||||
}
|
||||
|
||||
_dbus_hash_iter_init (table1, &iter);
|
||||
while (_dbus_hash_iter_next (&iter))
|
||||
{
|
||||
_dbus_hash_iter_remove_entry (&iter);
|
||||
_dbus_assert (count_entries (table1) == i - 1);
|
||||
--i;
|
||||
}
|
||||
|
||||
_dbus_hash_iter_init (table2, &iter);
|
||||
while (_dbus_hash_iter_next (&iter))
|
||||
{
|
||||
int key;
|
||||
const void *value;
|
||||
|
||||
key = _dbus_hash_iter_get_int_key (&iter);
|
||||
value = _dbus_hash_iter_get_value (&iter);
|
||||
|
||||
_dbus_assert (_dbus_hash_table_lookup_int (table2, key) == value);
|
||||
|
||||
str_value = _dbus_strdup ("Different value!");
|
||||
if (str_value == NULL)
|
||||
goto out;
|
||||
|
||||
value = str_value;
|
||||
_dbus_hash_iter_set_value (&iter, steal (&str_value));
|
||||
_dbus_assert (_dbus_hash_table_lookup_int (table2, key) == value);
|
||||
}
|
||||
|
||||
i = count_entries (table2);
|
||||
_dbus_hash_iter_init (table2, &iter);
|
||||
while (_dbus_hash_iter_next (&iter))
|
||||
{
|
||||
_dbus_hash_iter_remove_entry (&iter);
|
||||
_dbus_assert (count_entries (table2) + 1 == i);
|
||||
--i;
|
||||
}
|
||||
|
||||
/* add/remove interleaved, to check that we grow/shrink the table
|
||||
* appropriately
|
||||
*/
|
||||
i = 0;
|
||||
while (i < 1000)
|
||||
{
|
||||
str_key = _dbus_strdup (keys[i]);
|
||||
if (str_key == NULL)
|
||||
goto out;
|
||||
|
||||
str_value = _dbus_strdup ("Value!");
|
||||
if (str_value == NULL)
|
||||
goto out;
|
||||
|
||||
if (!_dbus_hash_table_insert_string (table1,
|
||||
steal (&str_key),
|
||||
steal (&str_value)))
|
||||
goto out;
|
||||
|
||||
++i;
|
||||
}
|
||||
|
||||
--i;
|
||||
while (i >= 0)
|
||||
{
|
||||
str_key = _dbus_strdup (keys[i]);
|
||||
if (str_key == NULL)
|
||||
goto out;
|
||||
str_value = _dbus_strdup ("Value!");
|
||||
if (str_value == NULL)
|
||||
goto out;
|
||||
|
||||
if (!_dbus_hash_table_remove_string (table1, keys[i]))
|
||||
goto out;
|
||||
|
||||
if (!_dbus_hash_table_insert_string (table1,
|
||||
steal (&str_key),
|
||||
steal (&str_value)))
|
||||
goto out;
|
||||
|
||||
if (!_dbus_hash_table_remove_string (table1, keys[i]))
|
||||
goto out;
|
||||
|
||||
_dbus_assert (_dbus_hash_table_get_n_entries (table1) == i);
|
||||
|
||||
--i;
|
||||
}
|
||||
|
||||
/* nuke these tables */
|
||||
_dbus_hash_table_unref (table1);
|
||||
_dbus_hash_table_unref (table2);
|
||||
|
||||
|
||||
/* Now do a bunch of things again using _dbus_hash_iter_lookup() to
|
||||
* be sure that interface works.
|
||||
*/
|
||||
table1 = _dbus_hash_table_new (DBUS_HASH_STRING,
|
||||
dbus_free, dbus_free);
|
||||
if (table1 == NULL)
|
||||
goto out;
|
||||
|
||||
table2 = _dbus_hash_table_new (DBUS_HASH_INT,
|
||||
NULL, dbus_free);
|
||||
if (table2 == NULL)
|
||||
goto out;
|
||||
|
||||
i = 0;
|
||||
while (i < 3000)
|
||||
{
|
||||
const void *out_value;
|
||||
|
||||
str_key = _dbus_strdup (keys[i]);
|
||||
if (str_key == NULL)
|
||||
goto out;
|
||||
str_value = _dbus_strdup ("Value!");
|
||||
if (str_value == NULL)
|
||||
goto out;
|
||||
|
||||
if (!_dbus_hash_iter_lookup (table1,
|
||||
steal (&str_key), TRUE, &iter))
|
||||
goto out;
|
||||
_dbus_assert (_dbus_hash_iter_get_value (&iter) == NULL);
|
||||
_dbus_hash_iter_set_value (&iter, steal (&str_value));
|
||||
|
||||
str_value = _dbus_strdup (keys[i]);
|
||||
if (str_value == NULL)
|
||||
goto out;
|
||||
|
||||
if (!_dbus_hash_iter_lookup (table2,
|
||||
_DBUS_INT_TO_POINTER (i), TRUE, &iter))
|
||||
goto out;
|
||||
_dbus_assert (_dbus_hash_iter_get_value (&iter) == NULL);
|
||||
_dbus_hash_iter_set_value (&iter, steal (&str_value));
|
||||
|
||||
_dbus_assert (count_entries (table1) == i + 1);
|
||||
_dbus_assert (count_entries (table2) == i + 1);
|
||||
|
||||
if (!_dbus_hash_iter_lookup (table1, keys[i], FALSE, &iter))
|
||||
goto out;
|
||||
|
||||
out_value = _dbus_hash_iter_get_value (&iter);
|
||||
_dbus_assert (out_value != NULL);
|
||||
_dbus_assert (strcmp (out_value, "Value!") == 0);
|
||||
|
||||
/* Iterate just to be sure it works, though
|
||||
* it's a stupid thing to do
|
||||
*/
|
||||
while (_dbus_hash_iter_next (&iter))
|
||||
;
|
||||
|
||||
if (!_dbus_hash_iter_lookup (table2, _DBUS_INT_TO_POINTER (i), FALSE, &iter))
|
||||
goto out;
|
||||
|
||||
out_value = _dbus_hash_iter_get_value (&iter);
|
||||
_dbus_assert (out_value != NULL);
|
||||
_dbus_assert (strcmp (out_value, keys[i]) == 0);
|
||||
|
||||
/* Iterate just to be sure it works, though
|
||||
* it's a stupid thing to do
|
||||
*/
|
||||
while (_dbus_hash_iter_next (&iter))
|
||||
;
|
||||
|
||||
++i;
|
||||
}
|
||||
|
||||
--i;
|
||||
while (i >= 0)
|
||||
{
|
||||
if (!_dbus_hash_iter_lookup (table1, keys[i], FALSE, &iter))
|
||||
_dbus_test_fatal ("hash entry should have existed");
|
||||
_dbus_hash_iter_remove_entry (&iter);
|
||||
|
||||
if (!_dbus_hash_iter_lookup (table2, _DBUS_INT_TO_POINTER (i), FALSE, &iter))
|
||||
_dbus_test_fatal ("hash entry should have existed");
|
||||
_dbus_hash_iter_remove_entry (&iter);
|
||||
|
||||
_dbus_assert (count_entries (table1) == i);
|
||||
_dbus_assert (count_entries (table2) == i);
|
||||
|
||||
--i;
|
||||
}
|
||||
|
||||
_dbus_hash_table_unref (table1);
|
||||
_dbus_hash_table_unref (table2);
|
||||
|
||||
ret = TRUE;
|
||||
|
||||
out:
|
||||
for (i = 0; i < N_HASH_KEYS; i++)
|
||||
dbus_free (keys[i]);
|
||||
|
||||
dbus_free (keys);
|
||||
|
||||
dbus_free (str_key);
|
||||
dbus_free (str_value);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif /* DBUS_ENABLE_EMBEDDED_TESTS */
|
||||
|
|
|
|||
|
|
@ -75,6 +75,7 @@ DBUS_PRIVATE_EXPORT
|
|||
DBusHashTable* _dbus_hash_table_new (DBusHashType type,
|
||||
DBusFreeFunction key_free_function,
|
||||
DBusFreeFunction value_free_function);
|
||||
DBUS_PRIVATE_EXPORT
|
||||
DBusHashTable* _dbus_hash_table_ref (DBusHashTable *table);
|
||||
DBUS_PRIVATE_EXPORT
|
||||
void _dbus_hash_table_unref (DBusHashTable *table);
|
||||
|
|
|
|||
|
|
@ -37,9 +37,6 @@
|
|||
* then you have added too many.
|
||||
*/
|
||||
|
||||
DBUS_PRIVATE_EXPORT
|
||||
dbus_bool_t _dbus_hash_test (const char *test_data_dir);
|
||||
|
||||
DBUS_PRIVATE_EXPORT
|
||||
dbus_bool_t _dbus_list_test (const char *test_data_dir);
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,9 @@
|
|||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
|
||||
/*
|
||||
* Copyright 1991-1993 The Regents of the University of California
|
||||
* Copyright 1994 Sun Microsystems, Inc.
|
||||
* Copyright 2002-2009 Red Hat, Inc.
|
||||
* Copyright 2003 Joe Shaw
|
||||
* Copyright 2011-2018 Collabora Ltd.
|
||||
*
|
||||
* Licensed under the Academic Free License version 2.1
|
||||
|
|
@ -19,14 +22,497 @@
|
|||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* The following license applies to code from the Tcl distribution,
|
||||
* if there is any in this file:
|
||||
*
|
||||
* Copyright (c) 1991-1993 The Regents of the University of California.
|
||||
* Copyright (c) 1994 Sun Microsystems, Inc.
|
||||
*
|
||||
* This software is copyrighted by the Regents of the University of
|
||||
* California, Sun Microsystems, Inc., Scriptics Corporation, and
|
||||
* other parties. The following terms apply to all files associated
|
||||
* with the software unless explicitly disclaimed in individual files.
|
||||
*
|
||||
* The authors hereby grant permission to use, copy, modify,
|
||||
* distribute, and license this software and its documentation for any
|
||||
* purpose, provided that existing copyright notices are retained in
|
||||
* all copies and that this notice is included verbatim in any
|
||||
* distributions. No written agreement, license, or royalty fee is
|
||||
* required for any of the authorized uses. Modifications to this
|
||||
* software may be copyrighted by their authors and need not follow
|
||||
* the licensing terms described here, provided that the new terms are
|
||||
* clearly indicated on the first page of each file where they apply.
|
||||
*
|
||||
* IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY
|
||||
* PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL
|
||||
* DAMAGES ARISING OUT OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION,
|
||||
* OR ANY DERIVATIVES THEREOF, EVEN IF THE AUTHORS HAVE BEEN ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES,
|
||||
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND
|
||||
* NON-INFRINGEMENT. THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS,
|
||||
* AND THE AUTHORS AND DISTRIBUTORS HAVE NO OBLIGATION TO PROVIDE
|
||||
* MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
|
||||
*
|
||||
* GOVERNMENT USE: If you are acquiring this software on behalf of the
|
||||
* U.S. government, the Government shall have only "Restricted Rights"
|
||||
* in the software and related documentation as defined in the Federal
|
||||
* Acquisition Regulations (FARs) in Clause 52.227.19 (c) (2). If you
|
||||
* are acquiring the software on behalf of the Department of Defense,
|
||||
* the software shall be classified as "Commercial Computer Software"
|
||||
* and the Government shall have only "Restricted Rights" as defined
|
||||
* in Clause 252.227-7013 (c) (1) of DFARs. Notwithstanding the
|
||||
* foregoing, the authors grant the U.S. Government and others acting
|
||||
* in its behalf permission to use and distribute the software in
|
||||
* accordance with the terms specified in this license.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "dbus/dbus-hash.h"
|
||||
#include "dbus/dbus-internals.h"
|
||||
#include "dbus/dbus-test.h"
|
||||
#include "dbus/dbus-test-tap.h"
|
||||
#include "test/test-utils.h"
|
||||
|
||||
/* If you're wondering why the hash table test takes
|
||||
* forever to run, it's because we call this function
|
||||
* in inner loops thus making things quadratic.
|
||||
*/
|
||||
static int
|
||||
count_entries (DBusHashTable *table)
|
||||
{
|
||||
DBusHashIter iter;
|
||||
int count;
|
||||
|
||||
count = 0;
|
||||
_dbus_hash_iter_init (table, &iter);
|
||||
while (_dbus_hash_iter_next (&iter))
|
||||
++count;
|
||||
|
||||
_dbus_assert (count == _dbus_hash_table_get_n_entries (table));
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static inline void *
|
||||
steal (void *ptr)
|
||||
{
|
||||
/* @ptr is passed in as void* to avoid casting in the call */
|
||||
void **_ptr = (void **) ptr;
|
||||
void *val;
|
||||
|
||||
val = *_ptr;
|
||||
*_ptr = NULL;
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
/**
|
||||
* @ingroup DBusHashTableInternals
|
||||
* Unit test for DBusHashTable
|
||||
* @returns #TRUE on success.
|
||||
*/
|
||||
static dbus_bool_t
|
||||
_dbus_hash_test (const char *test_data_dir _DBUS_GNUC_UNUSED)
|
||||
{
|
||||
int i;
|
||||
DBusHashTable *table1;
|
||||
DBusHashTable *table2;
|
||||
DBusHashTable *table3;
|
||||
DBusHashIter iter;
|
||||
#define N_HASH_KEYS 5000
|
||||
char **keys;
|
||||
dbus_bool_t ret = FALSE;
|
||||
char *str_key = NULL;
|
||||
char *str_value = NULL;
|
||||
|
||||
keys = dbus_new (char *, N_HASH_KEYS);
|
||||
if (keys == NULL)
|
||||
_dbus_test_fatal ("no memory");
|
||||
|
||||
for (i = 0; i < N_HASH_KEYS; i++)
|
||||
{
|
||||
keys[i] = dbus_malloc (128);
|
||||
|
||||
if (keys[i] == NULL)
|
||||
_dbus_test_fatal ("no memory");
|
||||
}
|
||||
|
||||
_dbus_test_diag ("Computing test hash keys...");
|
||||
i = 0;
|
||||
while (i < N_HASH_KEYS)
|
||||
{
|
||||
int len;
|
||||
|
||||
len = sprintf (keys[i], "Hash key %d", i);
|
||||
_dbus_assert (*(keys[i] + len) == '\0');
|
||||
++i;
|
||||
}
|
||||
_dbus_test_diag ("... done.");
|
||||
|
||||
table1 = _dbus_hash_table_new (DBUS_HASH_STRING,
|
||||
dbus_free, dbus_free);
|
||||
if (table1 == NULL)
|
||||
goto out;
|
||||
|
||||
table2 = _dbus_hash_table_new (DBUS_HASH_INT,
|
||||
NULL, dbus_free);
|
||||
if (table2 == NULL)
|
||||
goto out;
|
||||
|
||||
table3 = _dbus_hash_table_new (DBUS_HASH_UINTPTR,
|
||||
NULL, dbus_free);
|
||||
if (table3 == NULL)
|
||||
goto out;
|
||||
|
||||
/* Insert and remove a bunch of stuff, counting the table in between
|
||||
* to be sure it's not broken and that iteration works
|
||||
*/
|
||||
i = 0;
|
||||
while (i < 3000)
|
||||
{
|
||||
const void *out_value;
|
||||
|
||||
str_key = _dbus_strdup (keys[i]);
|
||||
if (str_key == NULL)
|
||||
goto out;
|
||||
str_value = _dbus_strdup ("Value!");
|
||||
if (str_value == NULL)
|
||||
goto out;
|
||||
|
||||
if (!_dbus_hash_table_insert_string (table1,
|
||||
steal (&str_key),
|
||||
steal (&str_value)))
|
||||
goto out;
|
||||
|
||||
str_value = _dbus_strdup (keys[i]);
|
||||
if (str_value == NULL)
|
||||
goto out;
|
||||
|
||||
if (!_dbus_hash_table_insert_int (table2,
|
||||
i, steal (&str_value)))
|
||||
goto out;
|
||||
|
||||
str_value = _dbus_strdup (keys[i]);
|
||||
if (str_value == NULL)
|
||||
goto out;
|
||||
|
||||
if (!_dbus_hash_table_insert_uintptr (table3,
|
||||
i, steal (&str_value)))
|
||||
goto out;
|
||||
|
||||
_dbus_assert (count_entries (table1) == i + 1);
|
||||
_dbus_assert (count_entries (table2) == i + 1);
|
||||
_dbus_assert (count_entries (table3) == i + 1);
|
||||
|
||||
out_value = _dbus_hash_table_lookup_string (table1, keys[i]);
|
||||
_dbus_assert (out_value != NULL);
|
||||
_dbus_assert (strcmp (out_value, "Value!") == 0);
|
||||
|
||||
out_value = _dbus_hash_table_lookup_int (table2, i);
|
||||
_dbus_assert (out_value != NULL);
|
||||
_dbus_assert (strcmp (out_value, keys[i]) == 0);
|
||||
|
||||
out_value = _dbus_hash_table_lookup_uintptr (table3, i);
|
||||
_dbus_assert (out_value != NULL);
|
||||
_dbus_assert (strcmp (out_value, keys[i]) == 0);
|
||||
|
||||
++i;
|
||||
}
|
||||
|
||||
--i;
|
||||
while (i >= 0)
|
||||
{
|
||||
_dbus_hash_table_remove_string (table1,
|
||||
keys[i]);
|
||||
|
||||
_dbus_hash_table_remove_int (table2, i);
|
||||
|
||||
_dbus_hash_table_remove_uintptr (table3, i);
|
||||
|
||||
_dbus_assert (count_entries (table1) == i);
|
||||
_dbus_assert (count_entries (table2) == i);
|
||||
_dbus_assert (count_entries (table3) == i);
|
||||
|
||||
--i;
|
||||
}
|
||||
|
||||
_dbus_hash_table_ref (table1);
|
||||
_dbus_hash_table_ref (table2);
|
||||
_dbus_hash_table_ref (table3);
|
||||
_dbus_hash_table_unref (table1);
|
||||
_dbus_hash_table_unref (table2);
|
||||
_dbus_hash_table_unref (table3);
|
||||
_dbus_hash_table_unref (table1);
|
||||
_dbus_hash_table_unref (table2);
|
||||
_dbus_hash_table_unref (table3);
|
||||
table3 = NULL;
|
||||
|
||||
/* Insert a bunch of stuff then check
|
||||
* that iteration works correctly (finds the right
|
||||
* values, iter_set_value works, etc.)
|
||||
*/
|
||||
table1 = _dbus_hash_table_new (DBUS_HASH_STRING,
|
||||
dbus_free, dbus_free);
|
||||
if (table1 == NULL)
|
||||
goto out;
|
||||
|
||||
table2 = _dbus_hash_table_new (DBUS_HASH_INT,
|
||||
NULL, dbus_free);
|
||||
if (table2 == NULL)
|
||||
goto out;
|
||||
|
||||
i = 0;
|
||||
while (i < 5000)
|
||||
{
|
||||
str_key = _dbus_strdup (keys[i]);
|
||||
if (str_key == NULL)
|
||||
goto out;
|
||||
str_value = _dbus_strdup ("Value!");
|
||||
if (str_value == NULL)
|
||||
goto out;
|
||||
|
||||
if (!_dbus_hash_table_insert_string (table1,
|
||||
steal (&str_key),
|
||||
steal (&str_value)))
|
||||
goto out;
|
||||
|
||||
str_value = _dbus_strdup (keys[i]);
|
||||
if (str_value == NULL)
|
||||
goto out;
|
||||
|
||||
if (!_dbus_hash_table_insert_int (table2,
|
||||
i, steal (&str_value)))
|
||||
goto out;
|
||||
|
||||
_dbus_assert (count_entries (table1) == i + 1);
|
||||
_dbus_assert (count_entries (table2) == i + 1);
|
||||
|
||||
++i;
|
||||
}
|
||||
|
||||
_dbus_hash_iter_init (table1, &iter);
|
||||
while (_dbus_hash_iter_next (&iter))
|
||||
{
|
||||
const char *key;
|
||||
const void *value;
|
||||
|
||||
key = _dbus_hash_iter_get_string_key (&iter);
|
||||
value = _dbus_hash_iter_get_value (&iter);
|
||||
|
||||
_dbus_assert (_dbus_hash_table_lookup_string (table1, key) == value);
|
||||
|
||||
str_value = _dbus_strdup ("Different value!");
|
||||
if (str_value == NULL)
|
||||
goto out;
|
||||
|
||||
value = str_value;
|
||||
_dbus_hash_iter_set_value (&iter, steal (&str_value));
|
||||
_dbus_assert (_dbus_hash_table_lookup_string (table1, key) == value);
|
||||
}
|
||||
|
||||
_dbus_hash_iter_init (table1, &iter);
|
||||
while (_dbus_hash_iter_next (&iter))
|
||||
{
|
||||
_dbus_hash_iter_remove_entry (&iter);
|
||||
_dbus_assert (count_entries (table1) == i - 1);
|
||||
--i;
|
||||
}
|
||||
|
||||
_dbus_hash_iter_init (table2, &iter);
|
||||
while (_dbus_hash_iter_next (&iter))
|
||||
{
|
||||
int key;
|
||||
const void *value;
|
||||
|
||||
key = _dbus_hash_iter_get_int_key (&iter);
|
||||
value = _dbus_hash_iter_get_value (&iter);
|
||||
|
||||
_dbus_assert (_dbus_hash_table_lookup_int (table2, key) == value);
|
||||
|
||||
str_value = _dbus_strdup ("Different value!");
|
||||
if (str_value == NULL)
|
||||
goto out;
|
||||
|
||||
value = str_value;
|
||||
_dbus_hash_iter_set_value (&iter, steal (&str_value));
|
||||
_dbus_assert (_dbus_hash_table_lookup_int (table2, key) == value);
|
||||
}
|
||||
|
||||
i = count_entries (table2);
|
||||
_dbus_hash_iter_init (table2, &iter);
|
||||
while (_dbus_hash_iter_next (&iter))
|
||||
{
|
||||
_dbus_hash_iter_remove_entry (&iter);
|
||||
_dbus_assert (count_entries (table2) + 1 == i);
|
||||
--i;
|
||||
}
|
||||
|
||||
/* add/remove interleaved, to check that we grow/shrink the table
|
||||
* appropriately
|
||||
*/
|
||||
i = 0;
|
||||
while (i < 1000)
|
||||
{
|
||||
str_key = _dbus_strdup (keys[i]);
|
||||
if (str_key == NULL)
|
||||
goto out;
|
||||
|
||||
str_value = _dbus_strdup ("Value!");
|
||||
if (str_value == NULL)
|
||||
goto out;
|
||||
|
||||
if (!_dbus_hash_table_insert_string (table1,
|
||||
steal (&str_key),
|
||||
steal (&str_value)))
|
||||
goto out;
|
||||
|
||||
++i;
|
||||
}
|
||||
|
||||
--i;
|
||||
while (i >= 0)
|
||||
{
|
||||
str_key = _dbus_strdup (keys[i]);
|
||||
if (str_key == NULL)
|
||||
goto out;
|
||||
str_value = _dbus_strdup ("Value!");
|
||||
if (str_value == NULL)
|
||||
goto out;
|
||||
|
||||
if (!_dbus_hash_table_remove_string (table1, keys[i]))
|
||||
goto out;
|
||||
|
||||
if (!_dbus_hash_table_insert_string (table1,
|
||||
steal (&str_key),
|
||||
steal (&str_value)))
|
||||
goto out;
|
||||
|
||||
if (!_dbus_hash_table_remove_string (table1, keys[i]))
|
||||
goto out;
|
||||
|
||||
_dbus_assert (_dbus_hash_table_get_n_entries (table1) == i);
|
||||
|
||||
--i;
|
||||
}
|
||||
|
||||
/* nuke these tables */
|
||||
_dbus_hash_table_unref (table1);
|
||||
_dbus_hash_table_unref (table2);
|
||||
|
||||
|
||||
/* Now do a bunch of things again using _dbus_hash_iter_lookup() to
|
||||
* be sure that interface works.
|
||||
*/
|
||||
table1 = _dbus_hash_table_new (DBUS_HASH_STRING,
|
||||
dbus_free, dbus_free);
|
||||
if (table1 == NULL)
|
||||
goto out;
|
||||
|
||||
table2 = _dbus_hash_table_new (DBUS_HASH_INT,
|
||||
NULL, dbus_free);
|
||||
if (table2 == NULL)
|
||||
goto out;
|
||||
|
||||
i = 0;
|
||||
while (i < 3000)
|
||||
{
|
||||
const void *out_value;
|
||||
|
||||
str_key = _dbus_strdup (keys[i]);
|
||||
if (str_key == NULL)
|
||||
goto out;
|
||||
str_value = _dbus_strdup ("Value!");
|
||||
if (str_value == NULL)
|
||||
goto out;
|
||||
|
||||
if (!_dbus_hash_iter_lookup (table1,
|
||||
steal (&str_key), TRUE, &iter))
|
||||
goto out;
|
||||
_dbus_assert (_dbus_hash_iter_get_value (&iter) == NULL);
|
||||
_dbus_hash_iter_set_value (&iter, steal (&str_value));
|
||||
|
||||
str_value = _dbus_strdup (keys[i]);
|
||||
if (str_value == NULL)
|
||||
goto out;
|
||||
|
||||
if (!_dbus_hash_iter_lookup (table2,
|
||||
_DBUS_INT_TO_POINTER (i), TRUE, &iter))
|
||||
goto out;
|
||||
_dbus_assert (_dbus_hash_iter_get_value (&iter) == NULL);
|
||||
_dbus_hash_iter_set_value (&iter, steal (&str_value));
|
||||
|
||||
_dbus_assert (count_entries (table1) == i + 1);
|
||||
_dbus_assert (count_entries (table2) == i + 1);
|
||||
|
||||
if (!_dbus_hash_iter_lookup (table1, keys[i], FALSE, &iter))
|
||||
goto out;
|
||||
|
||||
out_value = _dbus_hash_iter_get_value (&iter);
|
||||
_dbus_assert (out_value != NULL);
|
||||
_dbus_assert (strcmp (out_value, "Value!") == 0);
|
||||
|
||||
/* Iterate just to be sure it works, though
|
||||
* it's a stupid thing to do
|
||||
*/
|
||||
while (_dbus_hash_iter_next (&iter))
|
||||
;
|
||||
|
||||
if (!_dbus_hash_iter_lookup (table2, _DBUS_INT_TO_POINTER (i), FALSE, &iter))
|
||||
goto out;
|
||||
|
||||
out_value = _dbus_hash_iter_get_value (&iter);
|
||||
_dbus_assert (out_value != NULL);
|
||||
_dbus_assert (strcmp (out_value, keys[i]) == 0);
|
||||
|
||||
/* Iterate just to be sure it works, though
|
||||
* it's a stupid thing to do
|
||||
*/
|
||||
while (_dbus_hash_iter_next (&iter))
|
||||
;
|
||||
|
||||
++i;
|
||||
}
|
||||
|
||||
--i;
|
||||
while (i >= 0)
|
||||
{
|
||||
if (!_dbus_hash_iter_lookup (table1, keys[i], FALSE, &iter))
|
||||
_dbus_test_fatal ("hash entry should have existed");
|
||||
_dbus_hash_iter_remove_entry (&iter);
|
||||
|
||||
if (!_dbus_hash_iter_lookup (table2, _DBUS_INT_TO_POINTER (i), FALSE, &iter))
|
||||
_dbus_test_fatal ("hash entry should have existed");
|
||||
_dbus_hash_iter_remove_entry (&iter);
|
||||
|
||||
_dbus_assert (count_entries (table1) == i);
|
||||
_dbus_assert (count_entries (table2) == i);
|
||||
|
||||
--i;
|
||||
}
|
||||
|
||||
_dbus_hash_table_unref (table1);
|
||||
_dbus_hash_table_unref (table2);
|
||||
|
||||
ret = TRUE;
|
||||
|
||||
out:
|
||||
for (i = 0; i < N_HASH_KEYS; i++)
|
||||
dbus_free (keys[i]);
|
||||
|
||||
dbus_free (keys);
|
||||
|
||||
dbus_free (str_key);
|
||||
dbus_free (str_value);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static DBusTestCase test = { "hash", _dbus_hash_test };
|
||||
|
||||
int
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue