Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

cmd/flux-kvs: Update dir and ls usage #1444

Merged
merged 4 commits into from
Apr 11, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 29 additions & 25 deletions src/cmd/flux-kvs.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand All @@ -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");

Expand All @@ -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);
}

Expand Down Expand Up @@ -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.
Expand All @@ -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.
Expand Down
23 changes: 21 additions & 2 deletions src/common/libkvs/kvs_dir.c
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
79 changes: 77 additions & 2 deletions t/t1000-kvs.t
Original file line number Diff line number Diff line change
Expand Up @@ -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 <<EOF &&
Expand All @@ -165,7 +165,7 @@ $DIR.f = {"a": 42}
EOF
test_cmp expected output
'
test_expect_success 'kvs: dir -R -d' '
test_expect_success 'kvs: dir -R -d DIR' '
flux kvs dir -R -d $DIR | sort >output &&
cat >expected <<EOF &&
$DIR.a
Expand All @@ -178,6 +178,58 @@ EOF
test_cmp expected output
'

test_expect_success 'kvs: kvs dir -R DIR with period end' '
flux kvs dir -R $DIR. | sort >output &&
cat >expected <<EOF &&
$DIR.a = 42
$DIR.b = 3.140000
$DIR.c = foo
$DIR.d = true
$DIR.e = [1, 3, 5]
$DIR.f = {"a": 42}
EOF
test_cmp expected output
'

test_expect_success 'kvs: kvs dir -R -d DIR with period end' '
flux kvs dir -R -d $DIR. | sort >output &&
cat >expected <<EOF &&
$DIR.a
$DIR.b
$DIR.c
$DIR.d
$DIR.e
$DIR.f
EOF
test_cmp expected output
'

test_expect_success 'kvs: kvs dir -R on root "."' '
flux kvs dir -R "." | sort >output &&
cat >expected <<EOF &&
$DIR.a = 42
$DIR.b = 3.140000
$DIR.c = foo
$DIR.d = true
$DIR.e = [1, 3, 5]
$DIR.f = {"a": 42}
EOF
test_cmp expected output
'

test_expect_success 'kvs: kvs dir -R -d on root "."' '
flux kvs dir -R -d "." | sort >output &&
cat >expected <<EOF &&
$DIR.a
$DIR.b
$DIR.c
$DIR.d
$DIR.e
$DIR.f
EOF
test_cmp expected output
'

test_expect_success 'kvs: unlink dir works' '
flux kvs unlink $SUBDIR1 &&
test_must_fail flux kvs dir $SUBDIR1
Expand Down Expand Up @@ -540,6 +592,20 @@ EOF
#
# ls tests
#
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 . 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 &&
Expand All @@ -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 &&
Expand Down
81 changes: 73 additions & 8 deletions t/t1004-kvs-namespace.t
Original file line number Diff line number Diff line change
Expand Up @@ -402,6 +402,14 @@ 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 dir' '
flux kvs dir ns:${NAMESPACEPREFIX}-1/. | sort >output &&
cat >expected <<EOF &&
ns:${NAMESPACEPREFIX}-1/test.
EOF
test_cmp expected output
'

test_expect_success 'kvs: namespace prefix works with ls' '
flux kvs ls ns:${NAMESPACEPREFIX}-1/. | sort >output &&
cat >expected <<EOF &&
Expand All @@ -410,28 +418,85 @@ EOF
test_cmp expected output
'

# 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 &&
test_expect_success 'kvs: namespace prefix works with dir, no key specified' '
flux kvs dir ns:${NAMESPACEPREFIX}-1/ | sort >output &&
cat >expected <<EOF &&
ns:${NAMESPACEPREFIX}-1/..test.
ns:${NAMESPACEPREFIX}-1/test.
EOF
test_cmp expected output
'

test_expect_success 'kvs: namespace prefix works with ls' '
flux kvs ls ns:${NAMESPACEPREFIX}-1/. | sort >output &&
test_expect_success 'kvs: namespace prefix works with ls, no key specified' '
flux kvs ls ns:${NAMESPACEPREFIX}-1/ | sort >output &&
cat >expected <<EOF &&
test
EOF
test_cmp expected output
'

test_expect_success 'kvs: namespace prefix works with dir -R' '
flux kvs dir -R ns:${NAMESPACEPREFIX}-1/. | sort >output &&
cat >expected <<EOF &&
ns:${NAMESPACEPREFIX}-1/$DIR.prefixtest = 1
EOF
test_cmp expected output
'

test_expect_success 'kvs: namespace prefix works with ls -R' '
flux kvs ls -R ns:${NAMESPACEPREFIX}-1/. >output &&
cat >expected <<EOF &&
ns:namespaceprefix-1/.:
test

ns:namespaceprefix-1/test:
a

ns:namespaceprefix-1/test.a:
b

ns:namespaceprefix-1/test.a.b:
prefixtest
EOF
test_cmp expected output
'

test_expect_success 'kvs: namespace prefix works with dir -R DIR' '
flux kvs dir -R ns:${NAMESPACEPREFIX}-1/$DIR | sort >output &&
cat >expected <<EOF &&
ns:${NAMESPACEPREFIX}-1/$DIR.prefixtest = 1
EOF
test_cmp expected output
'

test_expect_success 'kvs: namespace prefix works with ls -R DIR' '
flux kvs ls -R ns:${NAMESPACEPREFIX}-1/$DIR | sort >output &&
cat >expected <<EOF &&
ns:${NAMESPACEPREFIX}-1/$DIR:
prefixtest
EOF
test_cmp expected output
'

test_expect_success 'kvs: namespace prefix works with dir -R DIR.' '
flux kvs dir -R ns:${NAMESPACEPREFIX}-1/$DIR. | sort >output &&
cat >expected <<EOF &&
ns:${NAMESPACEPREFIX}-1/$DIR.prefixtest = 1
EOF
test_cmp expected output
'

test_expect_success 'kvs: namespace prefix works with ls -R DIR.' '
flux kvs ls -R ns:${NAMESPACEPREFIX}-1/$DIR | sort >output &&
cat >expected <<EOF &&
ns:${NAMESPACEPREFIX}-1/$DIR:
prefixtest
EOF
test_cmp expected output
'

test_expect_success 'kvs: namespace prefix with key suffix fails' '
! flux kvs get ns:${NAMESPACEPREFIX}-1/ &&
! flux kvs put ns:${NAMESPACEPREFIX}-1/ &&
! flux kvs dir ns:${NAMESPACEPREFIX}-1/ &&
! flux kvs ls ns:${NAMESPACEPREFIX}-1/ &&
! flux kvs watch ns:${NAMESPACEPREFIX}-1/
'

Expand Down