diff options
| author | Havoc Pennington <hp@redhat.com> | 2003-08-30 17:09:24 +0000 | 
|---|---|---|
| committer | Havoc Pennington <hp@redhat.com> | 2003-08-30 17:09:24 +0000 | 
| commit | 9a0e83f509bd927b555ff75319f8df66ca61087e (patch) | |
| tree | c173277218f93d6e5d634b61eaeb12e4e9e4abb2 | |
| parent | ce969c6347b69180088c592e9184f05d0d3525c4 (diff) | |
2003-08-30  Havoc Pennington  <hp@pobox.com>
	* dbus/dbus-object-tree.c: write tests and fix the discovered bugs
| -rw-r--r-- | ChangeLog | 4 | ||||
| -rw-r--r-- | dbus/dbus-object-tree.c | 303 | 
2 files changed, 283 insertions, 24 deletions
| @@ -1,3 +1,7 @@ +2003-08-30  Havoc Pennington  <hp@pobox.com> + +	* dbus/dbus-object-tree.c: write tests and fix the discovered bugs +  2003-08-29  Havoc Pennington  <hp@pobox.com>  	* dbus/dbus-object-tree.c: modify to allow overlapping paths to be diff --git a/dbus/dbus-object-tree.c b/dbus/dbus-object-tree.c index a2fc49e2..379e2f04 100644 --- a/dbus/dbus-object-tree.c +++ b/dbus/dbus-object-tree.c @@ -254,18 +254,22 @@ find_subtree (DBusObjectTree *tree,        v = path_cmp (path,                      (const char**) tree->subtrees[i]->path); +              if (v == 0)          {            if (idx_p)              *idx_p = i; +                      return TRUE;          } -      else if (v > 0) -        return FALSE; +      else if (v < 0) +        { +          return FALSE; +        }        ++i;      } - +      return FALSE;  } @@ -366,12 +370,13 @@ _dbus_object_tree_register (DBusObjectTree              *tree,                                 new_n_subtrees * sizeof (DBusObjectSubtree*));    if (new_subtrees == NULL)      { -      subtree->unregister_function = NULL;  /* to avoid assertion in unref() */ +      subtree->unregister_function = NULL; +      subtree->message_function = NULL;        _dbus_object_subtree_unref (subtree);        return FALSE;      } -  tree->subtrees[tree->n_subtrees] = subtree; +  new_subtrees[tree->n_subtrees] = subtree;    tree->subtrees_sorted = FALSE;    tree->n_subtrees = new_n_subtrees;    tree->subtrees = new_subtrees; @@ -396,15 +401,15 @@ _dbus_object_tree_unregister_and_unlock (DBusObjectTree          *tree,    _dbus_assert (path != NULL);    _dbus_assert (path[0] != NULL); -#ifndef DBUS_DISABLE_CHECKS    if (!find_subtree (tree, path, &i))      { -      _dbus_warn ("Attempted to unregister subtree (path[0] = %s) which isn't registered\n", -                  path[0]); +      _dbus_warn ("Attempted to unregister path (path[0] = %s path[1] = %s) which isn't registered\n", +                  path[0], path[1] ? path[1] : "null");        return;      } -#endif +  _dbus_assert (i >= 0); +      subtree = tree->subtrees[i];    /* assumes a 0-byte memmove is OK */ @@ -416,7 +421,10 @@ _dbus_object_tree_unregister_and_unlock (DBusObjectTree          *tree,    subtree->message_function = NULL;    /* Unlock and call application code */ -  _dbus_connection_unlock (tree->connection); +#ifdef DBUS_BUILD_TESTS +  if (tree->connection) +#endif +    _dbus_connection_unlock (tree->connection);    if (subtree->unregister_function)      { @@ -449,6 +457,8 @@ _dbus_object_tree_free_all_unlocked (DBusObjectTree *tree)        subtree = tree->subtrees[tree->n_subtrees - 1];        tree->subtrees[tree->n_subtrees - 1] = NULL; +      tree->n_subtrees -= 1; +        subtree->message_function = NULL; /* it's been removed */        /* Call application code */ @@ -527,7 +537,10 @@ _dbus_object_tree_dispatch_and_unlock (DBusObjectTree          *tree,        /* message_function is NULL if we're unregistered */        if (subtree->message_function)          { -          _dbus_connection_unlock (tree->connection); +#ifdef DBUS_BUILD_TESTS +          if (tree->connection) +#endif +            _dbus_connection_unlock (tree->connection);            /* FIXME you could unregister the subtree in another thread             * before we invoke the callback, and I can't figure out a @@ -539,14 +552,20 @@ _dbus_object_tree_dispatch_and_unlock (DBusObjectTree          *tree,            if (result == DBUS_HANDLER_RESULT_HANDLED)              goto free_and_return; -           -          _dbus_connection_lock (tree->connection); + +#ifdef DBUS_BUILD_TESTS +          if (tree->connection) +#endif +            _dbus_connection_lock (tree->connection);          }               link = next;      } -   -  _dbus_connection_unlock (tree->connection); + +#ifdef DBUS_BUILD_TESTS +  if (tree->connection) +#endif +    _dbus_connection_unlock (tree->connection);   free_and_return:    while (list != NULL) @@ -703,6 +722,29 @@ flatten_path (const char **path)    return NULL;  } +static void +spew_tree (DBusObjectTree *tree) +{ +  int i; + +  printf ("Tree of %d subpaths\n", +          tree->n_subtrees); +   +  i = 0; +  while (i < tree->n_subtrees) +    { +      char *s; + +      s = flatten_path ((const char **) tree->subtrees[i]->path); + +      printf ("  %d path = %s\n", i, s); + +      dbus_free (s); +       +      ++i; +    } +} +  static dbus_bool_t  test_subtree_cmp (const char **path1,                    const char **path2, @@ -818,6 +860,56 @@ test_path_copy (const char **path)    dbus_free (subtree);  } +typedef struct +{ +  dbus_bool_t message_handled; +  dbus_bool_t handler_unregistered; + +} TreeTestData; + + +static void +test_unregister_function (DBusConnection  *connection, +                          const char     **path, +                          void            *user_data) +{ +  TreeTestData *ttd = user_data; + +  ttd->handler_unregistered = TRUE; +} + +static DBusHandlerResult +test_message_function (DBusConnection  *connection, +                       DBusMessage     *message, +                       void            *user_data) +{ +  TreeTestData *ttd = user_data; + +  ttd->message_handled = TRUE; +   +  return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; +} + +static dbus_bool_t +do_register (DBusObjectTree *tree, +             const char    **path, +             int             i, +             TreeTestData   *tree_test_data) +{ +  DBusObjectPathVTable vtable = { test_unregister_function, +                                  test_message_function, NULL }; + +  tree_test_data[i].message_handled = FALSE; +  tree_test_data[i].handler_unregistered = FALSE; +   +  if (!_dbus_object_tree_register (tree, path, +                                   &vtable, +                                   &tree_test_data[i])) +    return FALSE; + +  return TRUE; +} +  static dbus_bool_t  object_tree_test_iteration (void *data)  { @@ -827,10 +919,10 @@ object_tree_test_iteration (void *data)    const char *path4[] = { "foo", "bar", "boo", NULL };    const char *path5[] = { "blah", NULL };    const char *path6[] = { "blah", "boof", NULL }; -  DBusObjectSubtree *subtree1; -  DBusObjectSubtree *subtree2;    DBusObjectTree *tree; - +  TreeTestData tree_test_data[6]; +  int i; +      test_path_copy (path1);    test_path_copy (path2);    test_path_copy (path3); @@ -839,8 +931,6 @@ object_tree_test_iteration (void *data)    test_path_copy (path6);    tree = NULL; -  subtree1 = NULL; -  subtree2 = NULL;    test_path_contains (path1, path1, TRUE);    test_path_contains (path1, path2, TRUE); @@ -905,12 +995,177 @@ object_tree_test_iteration (void *data)    tree = _dbus_object_tree_new (NULL);    if (tree == NULL)      goto out; +   +  if (!do_register (tree, path1, 0, tree_test_data)) +    goto out; +   +  _dbus_assert (find_subtree (tree, path1, NULL)); +  _dbus_assert (!find_subtree (tree, path2, NULL)); +  _dbus_assert (!find_subtree (tree, path3, NULL)); +  _dbus_assert (!find_subtree (tree, path4, NULL)); +  _dbus_assert (!find_subtree (tree, path5, NULL)); +  _dbus_assert (!find_subtree (tree, path6, NULL)); +   +  if (!do_register (tree, path2, 1, tree_test_data)) +    goto out; +   +  _dbus_assert (find_subtree (tree, path1, NULL));   +  _dbus_assert (find_subtree (tree, path2, NULL)); +  _dbus_assert (!find_subtree (tree, path3, NULL)); +  _dbus_assert (!find_subtree (tree, path4, NULL)); +  _dbus_assert (!find_subtree (tree, path5, NULL)); +  _dbus_assert (!find_subtree (tree, path6, NULL)); +   +  if (!do_register (tree, path3, 2, tree_test_data)) +    goto out; + +  _dbus_assert (find_subtree (tree, path1, NULL)); +  _dbus_assert (find_subtree (tree, path2, NULL)); +  _dbus_assert (find_subtree (tree, path3, NULL)); +  _dbus_assert (!find_subtree (tree, path4, NULL)); +  _dbus_assert (!find_subtree (tree, path5, NULL)); +  _dbus_assert (!find_subtree (tree, path6, NULL)); +   +  if (!do_register (tree, path4, 3, tree_test_data)) +    goto out; + + +  _dbus_assert (find_subtree (tree, path1, NULL)); +  _dbus_assert (find_subtree (tree, path2, NULL)); +  _dbus_assert (find_subtree (tree, path3, NULL)); +  _dbus_assert (find_subtree (tree, path4, NULL)); +  _dbus_assert (!find_subtree (tree, path5, NULL)); +  _dbus_assert (!find_subtree (tree, path6, NULL)); +   +  if (!do_register (tree, path5, 4, tree_test_data)) +    goto out; + +  _dbus_assert (find_subtree (tree, path1, NULL)); +  _dbus_assert (find_subtree (tree, path2, NULL)); +  _dbus_assert (find_subtree (tree, path3, NULL)); +  _dbus_assert (find_subtree (tree, path4, NULL)); +  _dbus_assert (find_subtree (tree, path5, NULL)); +  _dbus_assert (!find_subtree (tree, path6, NULL)); +   +  if (!do_register (tree, path6, 5, tree_test_data)) +    goto out; + +  _dbus_assert (find_subtree (tree, path1, NULL)); +  _dbus_assert (find_subtree (tree, path2, NULL)); +  _dbus_assert (find_subtree (tree, path3, NULL)); +  _dbus_assert (find_subtree (tree, path4, NULL)); +  _dbus_assert (find_subtree (tree, path5, NULL)); +  _dbus_assert (find_subtree (tree, path6, NULL)); + +  /* Check that destroying tree calls unregister funcs */ +  _dbus_object_tree_unref (tree); + +  i = 0; +  while (i < (int) _DBUS_N_ELEMENTS (tree_test_data)) +    { +      _dbus_assert (tree_test_data[i].handler_unregistered); +      _dbus_assert (!tree_test_data[i].message_handled); +      ++i; +    } +  /* Now start again and try the individual unregister function */ +  tree = _dbus_object_tree_new (NULL); +  if (tree == NULL) +    goto out; +   +  if (!do_register (tree, path1, 0, tree_test_data)) +    goto out; +  if (!do_register (tree, path2, 1, tree_test_data)) +    goto out; +  if (!do_register (tree, path3, 2, tree_test_data)) +    goto out; +  if (!do_register (tree, path4, 3, tree_test_data)) +    goto out; +  if (!do_register (tree, path5, 4, tree_test_data)) +    goto out; +  if (!do_register (tree, path6, 5, tree_test_data)) +    goto out; + +  _dbus_object_tree_unregister_and_unlock (tree, path1); + +  _dbus_assert (!find_subtree (tree, path1, NULL)); +  _dbus_assert (find_subtree (tree, path2, NULL)); +  _dbus_assert (find_subtree (tree, path3, NULL)); +  _dbus_assert (find_subtree (tree, path4, NULL)); +  _dbus_assert (find_subtree (tree, path5, NULL)); +  _dbus_assert (find_subtree (tree, path6, NULL)); +   +  _dbus_object_tree_unregister_and_unlock (tree, path2); + +  _dbus_assert (!find_subtree (tree, path1, NULL)); +  _dbus_assert (!find_subtree (tree, path2, NULL)); +  _dbus_assert (find_subtree (tree, path3, NULL)); +  _dbus_assert (find_subtree (tree, path4, NULL)); +  _dbus_assert (find_subtree (tree, path5, NULL)); +  _dbus_assert (find_subtree (tree, path6, NULL)); + +  _dbus_object_tree_unregister_and_unlock (tree, path3); + +  _dbus_assert (!find_subtree (tree, path1, NULL)); +  _dbus_assert (!find_subtree (tree, path2, NULL)); +  _dbus_assert (!find_subtree (tree, path3, NULL)); +  _dbus_assert (find_subtree (tree, path4, NULL)); +  _dbus_assert (find_subtree (tree, path5, NULL)); +  _dbus_assert (find_subtree (tree, path6, NULL)); +   +  _dbus_object_tree_unregister_and_unlock (tree, path4); + +  _dbus_assert (!find_subtree (tree, path1, NULL)); +  _dbus_assert (!find_subtree (tree, path2, NULL)); +  _dbus_assert (!find_subtree (tree, path3, NULL)); +  _dbus_assert (!find_subtree (tree, path4, NULL)); +  _dbus_assert (find_subtree (tree, path5, NULL)); +  _dbus_assert (find_subtree (tree, path6, NULL)); +   +  _dbus_object_tree_unregister_and_unlock (tree, path5); + +  _dbus_assert (!find_subtree (tree, path1, NULL)); +  _dbus_assert (!find_subtree (tree, path2, NULL)); +  _dbus_assert (!find_subtree (tree, path3, NULL)); +  _dbus_assert (!find_subtree (tree, path4, NULL)); +  _dbus_assert (!find_subtree (tree, path5, NULL)); +  _dbus_assert (find_subtree (tree, path6, NULL)); +   +  _dbus_object_tree_unregister_and_unlock (tree, path6); + +  _dbus_assert (!find_subtree (tree, path1, NULL)); +  _dbus_assert (!find_subtree (tree, path2, NULL)); +  _dbus_assert (!find_subtree (tree, path3, NULL)); +  _dbus_assert (!find_subtree (tree, path4, NULL)); +  _dbus_assert (!find_subtree (tree, path5, NULL)); +  _dbus_assert (!find_subtree (tree, path6, NULL)); +   +  i = 0; +  while (i < (int) _DBUS_N_ELEMENTS (tree_test_data)) +    { +      _dbus_assert (tree_test_data[i].handler_unregistered); +      _dbus_assert (!tree_test_data[i].message_handled); +      ++i; +    } + +  /* Register it all again, and test dispatch */ +   +  if (!do_register (tree, path1, 0, tree_test_data)) +    goto out; +  if (!do_register (tree, path2, 1, tree_test_data)) +    goto out; +  if (!do_register (tree, path3, 2, tree_test_data)) +    goto out; +  if (!do_register (tree, path4, 3, tree_test_data)) +    goto out; +  if (!do_register (tree, path5, 4, tree_test_data)) +    goto out; +  if (!do_register (tree, path6, 5, tree_test_data)) +    goto out; +   +  /* FIXME (once messages have an object path field) */ +     out: -  if (subtree1) -    _dbus_object_subtree_unref (subtree1); -  if (subtree2) -    _dbus_object_subtree_unref (subtree2);    if (tree)      _dbus_object_tree_unref (tree); | 
