Skip to content

Commit

Permalink
Fix refreshing paths for wildcards
Browse files Browse the repository at this point in the history
Do not call refresher if we have unresolved wildcards.
Pass an actual wildcard node when recursing _refresh_paths
so that strcmp matches properly.
Fixup test asssertions for cases that should not have
called a refresher and cases that were missing the final /.
Add a bunch of test cases for root path queries and refreshers.
  • Loading branch information
carlgsmith authored and blairsteven committed Feb 19, 2024
1 parent b482c5f commit b4a45cb
Show file tree
Hide file tree
Showing 2 changed files with 197 additions and 51 deletions.
34 changes: 27 additions & 7 deletions apteryxd.c
Original file line number Diff line number Diff line change
Expand Up @@ -456,6 +456,7 @@ get_refresher_path (const char *path, cb_info_t *refresher)
{
const char *rpath = refresher->path;
char *cpath = g_malloc0 (strlen (path) + strlen (rpath) + 1);
const char *wild;
int offset = 0;

/* Resolve any wildcards in either path */
Expand Down Expand Up @@ -498,7 +499,7 @@ get_refresher_path (const char *path, cb_info_t *refresher)
if (*path && rpath[-1] != '/')
{
/* Append any requester path that we do not need to resolve */
while (*path && *path != '*' && g_ascii_strncasecmp (path, "/*", 2) != 0)
while (*path && *path != '*')
{
cpath[offset++] = *path;
path++;
Expand All @@ -512,6 +513,13 @@ get_refresher_path (const char *path, cb_info_t *refresher)
rpath++;
}

/* Check there are not unresolved wildcards */
if ((*rpath && ((wild = strchr (rpath, '*')) != NULL) && wild != &rpath[strlen (rpath)] - 1) ||
(*path && ((wild = strchr (path, '*')) != NULL) && wild != &path[strlen (path)] - 1))
{
free (cpath);
cpath = NULL;
}
return cpath;
}

Expand Down Expand Up @@ -544,8 +552,14 @@ call_refreshers (const char *path, bool dry_run)

pthread_mutex_lock (&refresher->lock);

/* Get a path suitable for passing to the reresher */
/* Get a path suitable for passing to the refresher */
cpath = get_refresher_path (path, refresher);
if (!cpath)
{
DEBUG ("Not enough state to refresh %s for %s\n", refresher->path, path);
goto unlock;
}
DEBUG ("PATH:%s RPATH:%s CPATH:%s\n", path, refresher->path, cpath);

/* We can skip this refresher if the refresher has been called recently AND
* the last call was for a path equal to or less specific than this one */
Expand Down Expand Up @@ -1975,7 +1989,6 @@ static void _refresh_paths (GNode *node, gpointer data)
if (g_node_n_children (node) == 1 && (!node->children->data || g_node_n_children (node->children) == 0))
{
char *path = NULL;
/* Match this exactly and go no further */
_node_to_path (node, &path);
call_refreshers (path, false);
free (path);
Expand All @@ -1989,13 +2002,20 @@ static void _refresh_paths (GNode *node, gpointer data)
GList *paths = db_search (path);
for (GList *iter = paths; iter; iter = iter->next)
{
GNode *fake = g_node_copy (node);
GNode *fake, *child;

if (g_node_n_children (node) == 1 && (!node->children->data || g_node_n_children (node->children) == 0))
fake->data = g_strdup_printf ("%s/*", (char *)iter->data);
{
fake = g_node_new ((char *)iter->data);
child = g_node_prepend_data (fake, (gpointer)"*");
g_node_prepend_data (child, (gpointer)NULL);
}
else
fake->data = g_strdup((char *)iter->data);
{
fake = g_node_copy (node);
fake->data = (gpointer)iter->data;
}
_refresh_paths (fake, NULL);
free (fake->data);
g_node_destroy (fake);
}
g_list_free_full(paths, g_free);
Expand Down
Loading

0 comments on commit b4a45cb

Please sign in to comment.