From 6e428d1b48dc07e1f6366e1bf8eb1d17f909b394 Mon Sep 17 00:00:00 2001 From: Albert Chu Date: Tue, 10 Apr 2018 19:06:29 -0700 Subject: [PATCH 1/4] t/t1004-kvs-namespace.t: Remove duplicate test --- t/t1004-kvs-namespace.t | 8 -------- 1 file changed, 8 deletions(-) diff --git a/t/t1004-kvs-namespace.t b/t/t1004-kvs-namespace.t index b51666531134..b28e7065013f 100755 --- a/t/t1004-kvs-namespace.t +++ b/t/t1004-kvs-namespace.t @@ -402,14 +402,6 @@ test_expect_success 'kvs: put - fails across multiple namespaces' ' ! flux kvs put ns:${NAMESPACEPREFIX}-1/$DIR.puttest.a=1 ns:${NAMESPACEPREFIX}-2/$DIR.puttest.b=2 ' -test_expect_success 'kvs: namespace prefix works with ls' ' - flux kvs ls ns:${NAMESPACEPREFIX}-1/. | sort >output && - cat >expected <output && From 2603717d361a53f52e45d3b8bab9bad4eba1f4e4 Mon Sep 17 00:00:00 2001 From: Albert Chu Date: Tue, 10 Apr 2018 11:34:02 -0700 Subject: [PATCH 2/4] cmd/flux-kvs: Update dir and ls usage With the dir and ls commands in flux-kvs, if a user specifies a namespace prefix without a key, assume the user desires the root (i.e. ".") directory within that namespace. Update/adjust unit tests appropriately. Fixes #1434 --- src/cmd/flux-kvs.c | 54 ++++++++++++++++++++++------------------- t/t1004-kvs-namespace.t | 19 +++++++++++++-- 2 files changed, 46 insertions(+), 27 deletions(-) diff --git a/src/cmd/flux-kvs.c b/src/cmd/flux-kvs.c index b3605da24187..a53607a7e201 100644 --- a/src/cmd/flux-kvs.c +++ b/src/cmd/flux-kvs.c @@ -1054,6 +1054,27 @@ int cmd_dropcache (optparse_t *p, int argc, char **argv) return (0); } +static char *process_key (const char *key, char **key_suffix) +{ + char *nkey; + char *ptr; + + if (!(nkey = malloc (strlen (key) + 2))) // room for decoration char + null + log_err_exit ("malloc"); + strcpy (nkey, key); + + if (!strncmp (nkey, "ns:", 3) + && (ptr = strchr (nkey + 3, '/'))) { + /* No key suffix, decorate with default '.' */ + if (*(ptr + 1) == '\0') + strcat (nkey, "."); + if (key_suffix) + (*key_suffix) = ptr + 1; + } + + return nkey; +} + static void dump_kvs_val (const char *key, int maxcol, const char *value) { json_t *o; @@ -1130,7 +1151,7 @@ int cmd_dir (optparse_t *p, int argc, char **argv) int maxcol = get_window_width (p, STDOUT_FILENO); bool Ropt; bool dopt; - const char *key; + char *key; flux_future_t *f; const flux_kvsdir_t *dir; int optindex; @@ -1139,9 +1160,9 @@ int cmd_dir (optparse_t *p, int argc, char **argv) Ropt = optparse_hasopt (p, "recursive"); dopt = optparse_hasopt (p, "directory"); if (optindex == argc) - key = "."; + key = process_key (".", NULL); else if (optindex == (argc - 1)) - key = argv[optindex]; + key = process_key (argv[optindex], NULL); else log_msg_exit ("dir: specify zero or one directory"); @@ -1158,6 +1179,7 @@ int cmd_dir (optparse_t *p, int argc, char **argv) log_err_exit ("%s", key); dump_kvs_dir (dir, maxcol, Ropt, dopt); flux_future_destroy (f); + free (key); return (0); } @@ -1347,21 +1369,6 @@ static int sort_cmp (void *item1, void *item2) return strcmp (item1, item2); } -static void contains_namespace_prefix (const char *key, char **key_suffix) -{ - char *ptr; - - if (!strncmp (key, "ns:", 3) - && (ptr = strchr (key, '/'))) { - - /* No key suffix */ - if (*(ptr + 1) == '\0') - log_err_exit ("%s: %s\n", key, flux_strerror (EINVAL)); - - (*key_suffix) = ptr + 1; - } -} - /* Put key in 'dirs' or 'singles' list, depending on whether * its contents are to be listed or not. If -F is specified, * 'singles' key names are decorated based on their type. @@ -1375,15 +1382,12 @@ static int categorize_key (optparse_t *p, const char *key, char *nkey; json_t *treeobj = NULL; bool require_directory = false; - char *key_ptr; - - if (!(nkey = malloc (strlen (key) + 2))) // room for decoration char + null - log_err_exit ("malloc"); - strcpy (nkey, key); + char *key_ptr = NULL; - key_ptr = nkey; + nkey = process_key (key, &key_ptr); - contains_namespace_prefix (nkey, &key_ptr); + if (!key_ptr) + key_ptr = nkey; /* If the key has a "." suffix, strip it off, but require * that the key be a directory type. diff --git a/t/t1004-kvs-namespace.t b/t/t1004-kvs-namespace.t index b28e7065013f..5ab6623fc782 100755 --- a/t/t1004-kvs-namespace.t +++ b/t/t1004-kvs-namespace.t @@ -419,11 +419,26 @@ EOF test_cmp expected output ' +# Note double period, will be resolved in issue #1391 fix +test_expect_success 'kvs: namespace prefix works with dir, no key specified' ' + flux kvs dir ns:${NAMESPACEPREFIX}-1/ | sort >output && + cat >expected <output && + cat >expected < Date: Tue, 10 Apr 2018 17:00:14 -0700 Subject: [PATCH 3/4] common/libkvs: Fix period output corner cases Fix output corner cases where double periods or errant additional period could be output. Fixes #1391 --- src/common/libkvs/kvs_dir.c | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/src/common/libkvs/kvs_dir.c b/src/common/libkvs/kvs_dir.c index 4bbc07febaed..63f012ddd14d 100644 --- a/src/common/libkvs/kvs_dir.c +++ b/src/common/libkvs/kvs_dir.c @@ -213,15 +213,34 @@ bool flux_kvsdir_issymlink (const flux_kvsdir_t *dir, const char *name) char *flux_kvsdir_key_at (const flux_kvsdir_t *dir, const char *name) { + char *ptr; char *s; + int len; if (!strcmp (dir->key, ".")) { if (!(s = strdup (name))) goto nomem; } - else { - if (asprintf (&s, "%s.%s", dir->key, name) < 0) + else if (!strncmp (dir->key, "ns:", 3) + && (ptr = strchr (dir->key + 3, '/')) + && !strcmp (ptr + 1, ".")) { + if (!(s = malloc (strlen (dir->key) + strlen (name) + 1))) goto nomem; + len = strlen (dir->key); + strcpy (s, dir->key); + s[len - 1] = '\0'; + strcat (s, name); + } + else { + len = strlen (dir->key); + if (dir->key[len - 1] == '.') { + if (asprintf (&s, "%s%s", dir->key, name) < 0) + goto nomem; + } + else { + if (asprintf (&s, "%s.%s", dir->key, name) < 0) + goto nomem; + } } return s; nomem: From 15638ebfc8fde33f1779c58bc86ff9575368dec5 Mon Sep 17 00:00:00 2001 From: Albert Chu Date: Tue, 10 Apr 2018 17:01:17 -0700 Subject: [PATCH 4/4] t/kvs: Add period output corner case tests Also adjust older tests to remove double periods. --- t/t1000-kvs.t | 79 +++++++++++++++++++++++++++++++++++++++-- t/t1004-kvs-namespace.t | 66 +++++++++++++++++++++++++++++++--- 2 files changed, 139 insertions(+), 6 deletions(-) diff --git a/t/t1000-kvs.t b/t/t1000-kvs.t index f91880954f98..4214403ad770 100755 --- a/t/t1000-kvs.t +++ b/t/t1000-kvs.t @@ -152,7 +152,7 @@ $DIR.d. EOF test_cmp expected output ' -test_expect_success 'kvs: dir -R' ' +test_expect_success 'kvs: dir -R DIR' ' flux kvs put --json $DIR.a=42 $DIR.b=3.14 $DIR.c=foo $DIR.d=true $DIR.e="[1,3,5]" $DIR.f="{\"a\":42}" && flux kvs dir -R $DIR | sort >output && cat >expected <output && cat >expected <output && + cat >expected <output && + cat >expected <output && + cat >expected <output && + cat >expected <output && + cat >expected <<-EOF && + test. + EOF + test_cmp expected output +' +test_expect_success 'kvs: ls -1F . works' ' + flux kvs ls -1F . >output && + cat >expected <<-EOF && + test. + EOF + test_cmp expected output +' test_expect_success 'kvs: ls -1F DIR works' ' flux kvs unlink -Rf $DIR && flux kvs put --json $DIR.a=69 && @@ -553,6 +619,15 @@ test_expect_success 'kvs: ls -1F DIR works' ' EOF test_cmp expected output ' +test_expect_success 'kvs: ls -1F DIR. works' ' + flux kvs ls -1F $DIR. >output && + cat >expected <<-EOF && + a + b. + c@ + EOF + test_cmp expected output +' test_expect_success 'kvs: ls -1Fd DIR.a DIR.b DIR.c works' ' flux kvs unlink -Rf $DIR && flux kvs put --json $DIR.a=69 && diff --git a/t/t1004-kvs-namespace.t b/t/t1004-kvs-namespace.t index 5ab6623fc782..10b4023ccfe9 100755 --- a/t/t1004-kvs-namespace.t +++ b/t/t1004-kvs-namespace.t @@ -402,11 +402,10 @@ test_expect_success 'kvs: put - fails across multiple namespaces' ' ! flux kvs put ns:${NAMESPACEPREFIX}-1/$DIR.puttest.a=1 ns:${NAMESPACEPREFIX}-2/$DIR.puttest.b=2 ' -# Note double period, will be resolved in issue #1391 fix test_expect_success 'kvs: namespace prefix works with dir' ' flux kvs dir ns:${NAMESPACEPREFIX}-1/. | sort >output && cat >expected <output && cat >expected <output && + cat >expected <output && + cat >expected <output && + cat >expected <output && + cat >expected <output && + cat >expected <output && + cat >expected <