Skip to content

Commit

Permalink
tests/user: add tests for operations on opened fids
Browse files Browse the repository at this point in the history
  • Loading branch information
ebfe authored and garlick committed Nov 29, 2018
1 parent 6fbe656 commit f1f1b38
Show file tree
Hide file tree
Showing 4 changed files with 276 additions and 2 deletions.
6 changes: 4 additions & 2 deletions tests/user/Makefile.am
Expand Up @@ -10,7 +10,8 @@ check_PROGRAMS = \
tgetxattr \
tsetxattr \
tremovexattr \
txattr
txattr \
testopenfid

TESTS_ENVIRONMENT = env
TESTS_ENVIRONMENT += "PATH_DIOD=$(top_builddir)/diod/diod"
Expand All @@ -19,7 +20,7 @@ TESTS_ENVIRONMENT += "USER_SRCDIR=$(top_srcdir)/tests/user"
TESTS_ENVIRONMENT += "USER_BUILDDIR=$(top_builddir)/tests/user"
TESTS_ENVIRONMENT += "${srcdir}/runtest"

TESTS = t01 t02 t03 t04 t05 t06 t07 t08 t09 t10 t11 t12 t13 t15 t16 t17 t18 t19
TESTS = t01 t02 t03 t04 t05 t06 t07 t08 t09 t10 t11 t12 t13 t15 t16 t17 t18 t19 t20

$(TESTS): exp.d

Expand Down Expand Up @@ -55,6 +56,7 @@ tflush_SOURCES = tflush.c $(common_sources)
tgetxattr_SOURCES = tgetxattr.c $(common_sources)
tsetxattr_SOURCES = tsetxattr.c $(common_sources)
tremovexattr_SOURCES = tremovexattr.c $(common_sources)
testopenfid_SOURCES = testopenfid.c $(common_sources)

clean: clean-am
-rm -rf exp.d
Expand Down
7 changes: 7 additions & 0 deletions tests/user/t20
@@ -0,0 +1,7 @@
#!/bin/bash -e

./testopenfid "$@" open_walk
./testopenfid "$@" open_remove_read
./testopenfid "$@" open_remove_getattr
./testopenfid "$@" open_remove_setattr
./testopenfid "$@" open_remove_create_setattr
7 changes: 7 additions & 0 deletions tests/user/t20.exp
@@ -0,0 +1,7 @@
testopenfid: testing 'open_walk'
testopenfid: testing 'open_remove_read'
testopenfid: testing 'open_remove_getattr'
testopenfid: testing 'open_remove_setattr'
testopenfid: testing 'open_remove_create_setattr'
conjoin: t20 exited with rc=0
conjoin: diod exited with rc=0
258 changes: 258 additions & 0 deletions tests/user/testopenfid.c
@@ -0,0 +1,258 @@
/* testopenfid.c - test operations on open fids */

#if HAVE_CONFIG_H
#include "config.h"
#endif
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <stdint.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

#include "9p.h"
#include "npfs.h"
#include "npclient.h"

#include "diod_log.h"
#include "diod_auth.h"

static void
usage (void)
{
fprintf (stderr, "Usage: topenfid aname test\n");
exit (1);
}

static int
create_file (Npcfid *root, char *name, u32 mode, char *content, size_t len) {
Npcfid *fid;

fid = npc_create_bypath (root, name, O_TRUNC|O_RDWR, mode, getgid ());
if (fid == NULL) {
return -1;
}
if (npc_write (fid, content, len) != len) {
return -1;
}
if (npc_clunk (fid) == -1) {
return -1;
}

return 0;
}

// Twalk should fail on opened fids
static void
open_walk (Npcfid *root) {
Npcfid *fid;

if (npc_mkdir_bypath (root, "subdir", 0755) == -1) {
errn_exit (np_rerror (), "npc_mkdir_bypath subdir");
}

fid = npc_open_bypath (root, "subdir", O_RDONLY);
if (fid == NULL) {
errn_exit (np_rerror (), "npc_open subdir");
}

if (npc_walk (fid, "..") != NULL) {
msg_exit ("walk succeeded on opened fid");
}

if (npc_clunk (fid) == -1) {
errn_exit (np_rerror (), "npc_clunk fid");
}
}

// Tread should work on opened fids even if the file has been removed
void
open_remove_read(Npcfid *root) {
Npcfid *fid;
char *testfile = "open_remove_read.test";
char buf[3];

if (create_file(root, testfile, 0644, "foo", 3) == -1) {
errn_exit (np_rerror (), "create_file %s", testfile);
}

fid = npc_open_bypath(root, testfile, O_RDONLY);
if (fid == NULL) {
errn_exit (np_rerror (), "npc_open %s", testfile);
}

if (npc_remove_bypath(root, testfile) == -1) {
errn_exit (np_rerror (), "npc_remove_bypath %s", testfile);
}

if (npc_read(fid, buf, sizeof(buf)) != sizeof(buf)) {
errn_exit (np_rerror (), "npc_read fid");
}

if (npc_clunk(fid) == -1) {
errn_exit (np_rerror (), "npc_clunk fid");
}
}

// Tgetattr should work on opened fids even if the file has been removed
void
open_remove_getattr (Npcfid *root) {
Npcfid *fid;
char *testfile = "open_remove_getattr.test";
struct stat sb, osb;

if (create_file (root, testfile, 0644, "foo", 3) == -1) {
errn_exit (np_rerror (), "create_file %s", testfile);
}

if (npc_stat (root, testfile, &sb) == -1) {
errn_exit (np_rerror (), "npc_stat %s", testfile);
}

fid = npc_open_bypath (root, testfile, O_RDONLY);
if (fid == NULL) {
errn_exit (np_rerror (), "npc_open %s", testfile);
}

if (npc_remove_bypath (root, testfile) == -1) {
errn_exit (np_rerror (), "npc_remove %s", testfile);
}

if (npc_fstat (fid, &osb) == -1) {
errn_exit (np_rerror (), "npc_dstat fid");
}

if (npc_clunk (fid) == -1) {
errn_exit (np_rerror (), "npc_clunk fid");
}
}

// Tsetattr should work on opened fids even if the file has been removed
void
open_remove_setattr (Npcfid *root) {
Npcfid *fid;
char *testfile = "open_remove_setattr.test";
struct stat sb;

if (create_file (root, testfile, 0644, "foo", 3) == -1) {
errn_exit (np_rerror (), "create_file %s", testfile);
}

if (npc_stat (root, testfile, &sb) == -1) {
errn_exit (np_rerror (), "npc_stat %s", testfile);
}

fid = npc_open_bypath (root, testfile, O_RDONLY);
if (fid == NULL) {
errn_exit (np_rerror (), "npc_open %s", testfile);
}

if (npc_remove_bypath (root, testfile) == -1) {
errn_exit (np_rerror (), "npc_remove %s", testfile);
}

if (npc_fchmod (fid, 0444) == -1) {
errn_exit (np_rerror (), "npc_fchmod fid");
}

if (npc_clunk (fid) == -1) {
errn_exit (np_rerror (), "npc_clunk fid");
}
}

// Tsetattr on a fid opened from path should not affect path when path is no longer the same file
void
open_remove_create_setattr (Npcfid *root) {
Npcfid *fid;
char *testfile = "open_remove_create_setattr.test";
struct stat sb;

if (create_file (root, testfile, 0644, "foo", 3) == -1) {
errn_exit (np_rerror (), "create_file %s", testfile);
}

fid = npc_open_bypath (root, testfile, O_RDONLY);
if (fid == NULL) {
errn_exit (np_rerror (), "npc_open %s", testfile);
}

if (npc_remove_bypath (root, testfile) == -1) {
errn_exit (np_rerror (), "npc_remove %s", testfile);
}
if (create_file (root, testfile, 0644, "foo", 3) == -1) {
errn_exit (np_rerror (), "create_file %s", testfile);
}

if (npc_fchmod (fid, 0444) == -1) {
errn_exit (np_rerror (), "npc_fchmod fid");
}
if (npc_fstat (fid, &sb) == -1) {
errn_exit (np_rerror (), "npc_fstat fid");
}
if ((sb.st_mode & 0x777) != 0444) {
msg_exit ("fchmod didn't change sb.st_mode");
}

if (npc_stat (root, testfile, &sb) == -1) {
errn_exit (np_rerror (), "npc_stat %s", testfile);
}
if ((sb.st_mode & 0777) != 0644) {
msg_exit ("stat changed %o", sb.st_mode);
}

if (npc_clunk (fid) == -1) {
errn_exit (np_rerror (), "npc_clunk fid");
}
}

int
main (int argc, char *argv[])
{
Npcfsys *fs;
Npcfid *afid, *root;
uid_t uid = geteuid ();
char *aname, *test;
int fd = 0; /* stdin */

diod_log_init (argv[0]);

if (argc < 3)
usage ();
aname = argv[1];
test = argv[2];

if (!(fs = npc_start (fd, fd, 65536+24, 0)))
errn_exit (np_rerror (), "npc_start");
if (!(afid = npc_auth (fs, aname, uid, diod_auth)) && np_rerror () != 0)
errn_exit (np_rerror (), "npc_auth");
if (!(root = npc_attach (fs, afid, aname, uid)))
errn_exit (np_rerror (), "npc_attach");
if (afid && npc_clunk (afid) < 0)
errn (np_rerror (), "npc_clunk afid");

msg("testing '%s'", test);
if (strcmp(test, "open_walk") == 0) {
open_walk (root);
} else if (strcmp (test, "open_remove_read") == 0) {
open_remove_read (root);
} else if (strcmp (test, "open_remove_getattr") == 0) {
open_remove_getattr (root);
} else if (strcmp (test, "open_remove_setattr") == 0) {
open_remove_setattr (root);
} else if (strcmp (test, "open_remove_create_setattr") == 0) {
open_remove_create_setattr (root);
} else {
fprintf (stderr, "unknown test %s\n", test);
exit (1);
}
npc_finish (fs);

exit(0);
}

/*
* vi:tabstop=4 shiftwidth=4 expandtab
*/

0 comments on commit f1f1b38

Please sign in to comment.