diff options
Diffstat (limited to 'tests/basic/gfapi')
| -rw-r--r-- | tests/basic/gfapi/bug-1507896.c | 49 | ||||
| -rw-r--r-- | tests/basic/gfapi/bug-1507896.t | 33 | ||||
| -rw-r--r-- | tests/basic/gfapi/gfapi-async-calls-test.c | 358 | ||||
| -rw-r--r-- | tests/basic/gfapi/gfapi-copy-file-range.t | 82 | ||||
| -rw-r--r-- | tests/basic/gfapi/gfapi-graph-switch-open-fd.t | 44 | ||||
| -rw-r--r-- | tests/basic/gfapi/gfapi-keep-writing.c | 129 | ||||
| -rw-r--r-- | tests/basic/gfapi/gfapi-ssl-load-volfile-test.c | 127 | ||||
| -rwxr-xr-x | tests/basic/gfapi/gfapi-ssl-load-volfile-test.t | 76 | ||||
| -rw-r--r-- | tests/basic/gfapi/gfapi-statx-basic.c | 184 | ||||
| -rwxr-xr-x | tests/basic/gfapi/gfapi-statx-basic.t | 30 | ||||
| -rw-r--r-- | tests/basic/gfapi/glfs-copy-file-range.c | 180 | ||||
| -rw-r--r-- | tests/basic/gfapi/glfs_h_creat_open.c | 118 | ||||
| -rwxr-xr-x | tests/basic/gfapi/glfs_h_creat_open.t | 27 | ||||
| -rw-r--r-- | tests/basic/gfapi/glfsxmp-coverage.c | 1900 | ||||
| -rw-r--r-- | tests/basic/gfapi/glfsxmp.t | 30 | ||||
| -rw-r--r-- | tests/basic/gfapi/protocol-client-ssl.vol.in | 15 |
16 files changed, 3364 insertions, 18 deletions
diff --git a/tests/basic/gfapi/bug-1507896.c b/tests/basic/gfapi/bug-1507896.c new file mode 100644 index 00000000000..1cc20849c2b --- /dev/null +++ b/tests/basic/gfapi/bug-1507896.c @@ -0,0 +1,49 @@ +#include <stdio.h> +#include <string.h> +#include <errno.h> +#include <glusterfs/api/glfs.h> +#include <glusterfs/api/glfs-handles.h> + +#define VALIDATE_AND_GOTO_LABEL_ON_ERROR(func, ret, label) \ + do { \ + if (ret < 0) { \ + fprintf(stderr, "%s : returned error %d (%s)\n", func, ret, \ + strerror(errno)); \ + goto label; \ + } \ + } while (0) + +int +main(int argc, char *argv[]) +{ + int ret = -1; + glfs_t *fs = NULL; + char *volname = NULL; + char *logfile = NULL; + char *hostname = NULL; + + hostname = argv[1]; + volname = argv[2]; + logfile = argv[3]; + + fs = glfs_new(volname); + if (!fs) + VALIDATE_AND_GOTO_LABEL_ON_ERROR("glfs_new(fs)", ret, out); + + ret = glfs_set_volfile_server(fs, "tcp", hostname, 24007); + VALIDATE_AND_GOTO_LABEL_ON_ERROR("glfs_set_volfile_server(fs)", ret, out); + + ret = glfs_set_logging(fs, logfile, 7); + VALIDATE_AND_GOTO_LABEL_ON_ERROR("glfs_set_logging(fs)", ret, out); + + ret = glfs_init(fs); + VALIDATE_AND_GOTO_LABEL_ON_ERROR("glfs_init(fs)", ret, out); + +out: + if (fs) { + ret = glfs_fini(fs); + if (ret) + fprintf(stderr, "glfs_fini(fs) returned %d\n", ret); + } + return ret; +} diff --git a/tests/basic/gfapi/bug-1507896.t b/tests/basic/gfapi/bug-1507896.t new file mode 100644 index 00000000000..4764e650232 --- /dev/null +++ b/tests/basic/gfapi/bug-1507896.t @@ -0,0 +1,33 @@ +#!/bin/bash + +. $(dirname $0)/../../include.rc +. $(dirname $0)/../../volume.rc + +cleanup; + +TEST glusterd + +TEST $CLI volume create $V0 $H0:$B0/brick1; +EXPECT 'Created' volinfo_field $V0 'Status'; + +TEST $CLI volume start $V0; +EXPECT 'Started' volinfo_field $V0 'Status'; + +logdir=`gluster --print-logdir` + +TEST build_tester $(dirname $0)/bug-1507896.c -lgfapi + +TEST ./$(dirname $0)/bug-1507896 $H0 $V0 $logdir/bug-1507896.log + +#volume name precedding with '/' +TEST ! ./$(dirname $0)/bug-1507896 $H0 /$V0 $logdir/bug-1507896.log + +#volume name passed with any special characters +TEST ! ./$(dirname $0)/bug-1507896 $H0 test@_$V0 $logdir/bug-1507896.log + +cleanup_tester $(dirname $0)/bug-1507896 + +TEST $CLI volume stop $V0 +TEST $CLI volume delete $V0 + +cleanup; diff --git a/tests/basic/gfapi/gfapi-async-calls-test.c b/tests/basic/gfapi/gfapi-async-calls-test.c index 5a291c3c76b..55835b14709 100644 --- a/tests/basic/gfapi/gfapi-async-calls-test.c +++ b/tests/basic/gfapi/gfapi-async-calls-test.c @@ -17,6 +17,17 @@ int cbk_complete = 0; int cbk_ret_val = -1; +void +cbk_check() +{ + while (cbk_complete != 1) { + sleep(1); + } + if (cbk_ret_val < 0) { + fprintf(stderr, "cbk_ret_val is -ve\n"); + } +} + int fill_iov(struct iovec *iov, char fillchar, int count) { @@ -76,25 +87,23 @@ out: } void -write_async_cbk(glfs_fd_t *fd, ssize_t ret, struct stat *prestat, - struct stat *poststat, void *cookie) +pwritev_async_cbk(glfs_fd_t *fd, ssize_t ret, struct stat *prestat, + struct stat *poststat, void *cookie) { if (ret < 0) { - LOG_ERR("glfs_write failed"); + LOG_ERR("glfs_pwritev failed"); } cbk_ret_val = ret; cbk_complete = 1; } int -write_async(glfs_t *fs, glfs_fd_t *glfd, int char_count) +pwritev_async(glfs_t *fs, glfs_fd_t *glfd, int char_count) { ssize_t ret = -1; int flags = O_RDWR; - const char *buff = "This is from my prog\n"; struct iovec iov = {0}; void *write_cookie = NULL; - void *read_cookie = NULL; ret = fill_iov(&iov, 'a', char_count); if (ret) { @@ -103,7 +112,7 @@ write_async(glfs_t *fs, glfs_fd_t *glfd, int char_count) } write_cookie = strdup("write_cookie"); - ret = glfs_pwritev_async(glfd, &iov, 1, 0, flags, write_async_cbk, + ret = glfs_pwritev_async(glfd, &iov, 1, 0, flags, pwritev_async_cbk, &write_cookie); out: if (ret < 0) { @@ -112,6 +121,252 @@ out: return ret; } +void +pwrite_async_cbk(glfs_fd_t *fd, ssize_t ret, struct stat *prestat, + struct stat *poststat, void *cookie) +{ + if (ret < 0) { + LOG_ERR("glfs_pwrite_cbk failed"); + } + cbk_ret_val = ret; + cbk_complete = 1; +} + +int +pwrite_async(glfs_fd_t *glfd) +{ + ssize_t ret = -1; + int flags = O_RDWR; + char buf1[10]; + char *buf2 = "ten bytes!"; + void *write_cookie = strdup("write_cookie"); + ret = glfs_pwrite_async(glfd, buf1, 10, 0, flags, pwrite_async_cbk, + &write_cookie); + + if (ret < 0) { + LOG_ERR("glfs_pwrite_async failed"); + } + return ret; +} + +void +writev_async_cbk(glfs_fd_t *fd, ssize_t ret, struct stat *prestat, + struct stat *poststat, void *cookie) +{ + if (ret < 0) { + LOG_ERR("glfs_writev_cbk failed"); + } + cbk_ret_val = ret; + cbk_complete = 1; +} + +int +writev_async(glfs_t *fs, glfs_fd_t *glfd, int char_count) +{ + ssize_t ret = -1; + int flags = O_RDWR; + struct iovec iov = {0}; + void *write_cookie = NULL; + + ret = fill_iov(&iov, 'a', char_count); + if (ret) { + LOG_ERR("failed to create iov"); + goto out; + } + + write_cookie = strdup("write_cookie"); + ret = glfs_writev_async(glfd, &iov, 1, flags, writev_async_cbk, + &write_cookie); +out: + if (ret < 0) { + LOG_ERR("glfs_writev_async failed"); + } + return ret; +} + +void +write_async_cbk(glfs_fd_t *fd, ssize_t ret, struct stat *prestat, + struct stat *poststat, void *cookie) +{ + if (ret < 0) { + LOG_ERR("glfs_write_cbk failed"); + } + cbk_ret_val = ret; + cbk_complete = 1; +} + +int +write_async(glfs_fd_t *glfd) +{ + ssize_t ret = -1; + int flags = O_RDWR; + char buf1[10]; + char *buf2 = "ten bytes!"; + void *write_cookie = strdup("write_cookie"); + ret = glfs_write_async(glfd, buf1, 10, flags, write_async_cbk, + &write_cookie); + + if (ret < 0) { + LOG_ERR("glfs_write_async failed"); + } + return ret; +} + +void +preadv_async_cbk(glfs_fd_t *fd, ssize_t ret, struct stat *prestat, + struct stat *poststat, void *cookie) +{ + if (ret < 0) { + LOG_ERR("glfs_preadv_cbk failed"); + } + cbk_ret_val = ret; + cbk_complete = 1; +} + +int +preadv_async(glfs_t *fs, glfs_fd_t *glfd, int char_count) +{ + ssize_t ret = -1; + int flags = O_RDWR; + struct iovec iov = {0}; + void *read_cookie = NULL; + + ret = fill_iov(&iov, 'a', char_count); + if (ret) { + LOG_ERR("failed to create iov"); + goto out; + } + + read_cookie = strdup("preadv_cookie"); + ret = glfs_preadv_async(glfd, &iov, 1, 0, flags, preadv_async_cbk, + &read_cookie); +out: + if (ret < 0) { + LOG_ERR("glfs_preadv async failed"); + } + return ret; +} + +void +pread_async_cbk(glfs_fd_t *fd, ssize_t ret, struct stat *prestat, + struct stat *poststat, void *cookie) +{ + if (ret < 0) { + LOG_ERR("glfs_pread_cbk failed"); + } + cbk_ret_val = ret; + cbk_complete = 1; +} + +int +pread_async(glfs_fd_t *glfd) +{ + ssize_t ret = -1; + int flags = O_RDWR; + char buf1[10]; + void *read_cookie = strdup("read_cookie"); + ret = glfs_pread_async(glfd, buf1, 10, 0, flags, pread_async_cbk, + &read_cookie); + if (ret < 0) { + LOG_ERR("glfs_pread_async failed"); + } + + return ret; +} + +void +readv_async_cbk(glfs_fd_t *fd, ssize_t ret, struct stat *prestat, + struct stat *poststat, void *cookie) +{ + if (ret < 0) { + LOG_ERR("glfs_readv_cbk failed"); + } + cbk_ret_val = ret; + cbk_complete = 1; +} + +int +readv_async(glfs_t *fs, glfs_fd_t *glfd, int char_count) +{ + ssize_t ret = -1; + int flags = O_RDWR; + struct iovec iov = {0}; + void *read_cookie = NULL; + + ret = fill_iov(&iov, 'a', char_count); + if (ret) { + LOG_ERR("failed to create iov"); + goto out; + } + + read_cookie = strdup("read_cookie"); + ret = glfs_readv_async(glfd, &iov, 1, flags, readv_async_cbk, &read_cookie); +out: + if (ret < 0) { + LOG_ERR("glfs_readv_async failed"); + } + return ret; +} + +void +read_async_cbk(glfs_fd_t *fd, ssize_t ret, struct stat *prestat, + struct stat *poststat, void *cookie) +{ + if (ret < 0) { + LOG_ERR("glfs_read_cbk failed"); + } + cbk_ret_val = ret; + cbk_complete = 1; +} + +int +read_async(glfs_fd_t *glfd) +{ + ssize_t ret = -1; + int flags = O_RDWR; + char buf1[10]; + void *read_cookie = strdup("read_cookie"); + ret = glfs_read_async(glfd, buf1, 10, flags, read_async_cbk, &read_cookie); + + if (ret < 0) { + LOG_ERR("glfs_read_async failed"); + } + return ret; +} + +void +fsync_async_cbk(glfs_fd_t *fd, ssize_t ret, struct stat *prestat, + struct stat *poststat, void *cookie) +{ + if (ret < 0) { + LOG_ERR("glfs_fsync_async_cbk failed"); + } + cbk_ret_val = ret; + cbk_complete = 1; +} + +void +fdatasync_async_cbk(glfs_fd_t *fd, ssize_t ret, struct stat *prestat, + struct stat *poststat, void *cookie) +{ + if (ret < 0) { + LOG_ERR("glfs_fdatasync_async_cbk failed"); + } + cbk_ret_val = ret; + cbk_complete = 1; +} + +void +ftruncate_async_cbk(glfs_fd_t *fd, ssize_t ret, struct stat *prestat, + struct stat *poststat, void *cookie) +{ + if (ret < 0) { + LOG_ERR("glfs_ftruncate_async_cbk failed"); + } + cbk_ret_val = ret; + cbk_complete = 1; +} + int main(int argc, char *argv[]) { @@ -124,6 +379,7 @@ main(int argc, char *argv[]) int flags = (O_RDWR | O_CREAT); glfs_fd_t *glfd = NULL; int count = 200; + void *data = strdup("Sample_text"); if (argc != 4) { fprintf(stderr, "Invalid argument\n"); @@ -146,14 +402,85 @@ main(int argc, char *argv[]) exit(1); } - ret = write_async(fs, glfd, count); + ret = pwritev_async(fs, glfd, count); if (ret) { - LOG_ERR("glfs_test_function failed"); + LOG_ERR("glfs_pwritev_async_test failed"); exit(1); } + cbk_check(); - while (cbk_complete != 1) { - sleep(1); + ret = writev_async(fs, glfd, count); + if (ret) { + LOG_ERR("glfs_writev_async_test failed"); + exit(1); + } + cbk_check(); + + ret = write_async(glfd); + if (ret) { + LOG_ERR("glfs_write_async_test failed"); + exit(1); + } + cbk_check(); + + ret = preadv_async(fs, glfd, count); + if (ret) { + LOG_ERR("glfs_preadv_async_test failed"); + exit(1); + } + cbk_check(); + + ret = pread_async(glfd); + if (ret) { + LOG_ERR("glfs_pread_async_test failed"); + exit(1); + } + cbk_check(); + + ret = readv_async(fs, glfd, count); + if (ret) { + LOG_ERR("glfs_readv_async_test failed"); + exit(1); + } + cbk_check(); + + ret = read_async(glfd); + if (ret) { + LOG_ERR("glfs_read_async_test failed"); + exit(1); + } + cbk_check(); + + ret = glfs_fsync(glfd, NULL, NULL); + if (ret < 0) { + LOG_ERR("glfs_fsync failed"); + exit(1); + } + + ret = glfs_fdatasync(glfd, NULL, NULL); + if (ret < 0) { + LOG_ERR("glfs_fdatasync failed"); + exit(1); + } + + ret = glfs_fsync_async(glfd, fsync_async_cbk, data); + if (ret < 0) { + LOG_ERR("glfs_fsync_async failed"); + exit(1); + } + cbk_check(); + + ret = glfs_fdatasync_async(glfd, fdatasync_async_cbk, data); + if (ret < 0) { + LOG_ERR("glfs_fdatasync_async failed"); + exit(1); + } + cbk_check(); + + ret = glfs_ftruncate_async(glfd, 4, ftruncate_async_cbk, data); + if (ret < 0) { + LOG_ERR("glfs_ftruncate_async failed"); + exit(1); } ret = glfs_close(glfd); @@ -161,12 +488,7 @@ main(int argc, char *argv[]) LOG_ERR("glfs close failed"); } - /* - * skipping fini - */ + ret = glfs_fini(fs); - if (cbk_ret_val == count) - return 0; - else - return -1; + return ret; } diff --git a/tests/basic/gfapi/gfapi-copy-file-range.t b/tests/basic/gfapi/gfapi-copy-file-range.t new file mode 100644 index 00000000000..a56d3a58e07 --- /dev/null +++ b/tests/basic/gfapi/gfapi-copy-file-range.t @@ -0,0 +1,82 @@ +#!/bin/bash + +. $(dirname $0)/../../include.rc +. $(dirname $0)/../../volume.rc + +cleanup; + +mkfs.xfs 2>&1 | grep reflink +if [ $? -ne 0 ]; then + SKIP_TESTS + exit +fi + + +TEST glusterd + +TEST truncate -s 2G $B0/xfs_image +# for now, a xfs filesystem with reflink support is created. +# In future, better to make changes in MKFS_LOOP so that, +# once can create a xfs filesystem with reflink enabled in +# generic and simple way, instead of doing below steps each +# time. +TEST mkfs.xfs -f -i size=512 -m reflink=1 $B0/xfs_image; + +TEST mkdir $B0/bricks +TEST mount -t xfs -o loop $B0/xfs_image $B0/bricks + +# Just a single brick volume. More test cases need to be +# added in future for distribute, replicate, +# distributed replicate and distributed replicated sharded +# volumes. +TEST $CLI volume create $V0 $H0:$B0/bricks/brick1; +EXPECT 'Created' volinfo_field $V0 'Status'; + +TEST $CLI volume start $V0; +EXPECT 'Started' volinfo_field $V0 'Status'; + +TEST glusterfs --volfile-id=/$V0 --volfile-server=$H0 $M0 + +TEST dd if=/dev/urandom of=$M0/file bs=1M count=555; + +# check for the existence of the created file +TEST stat $M0/file; + +# grab the size of the file +SRC_SIZE=$(stat -c %s $M0/file); + +logdir=`gluster --print-logdir` + +# TODO: +# For now, do not call copy-file-range utility. This is because, +# the regression machines are centos-7 based which does not have +# copy_file_range API available. So, instead of this testcase +# causing regression failures, for now, this is just a dummy test +# case. Uncomment the below tests (until volume stop) when there +# is support for copy_file_range in the regression machines. +# + +TEST build_tester $(dirname $0)/glfs-copy-file-range.c -lgfapi + +TEST ./$(dirname $0)/glfs-copy-file-range $H0 $V0 $logdir/gfapi-copy-file-range.log /file /new + +# check whether the destination file is created or not +TEST stat $M0/new + +# check the size of the destination file +DST_SIZE=$(stat -c %s $M0/new); + +# The sizes of the source and destination should be same. +# Atleast it ensures that, copy_file_range API is working +# as expected. Whether the actual cloning happened via reflink +# or a read/write happened is different matter. +TEST [ $SRC_SIZE == $DST_SIZE ]; + +cleanup_tester $(dirname $0)/glfs-copy-file-range + +TEST $CLI volume stop $V0 +TEST $CLI volume delete $V0 + +UMOUNT_LOOP $B0/bricks; + +cleanup; diff --git a/tests/basic/gfapi/gfapi-graph-switch-open-fd.t b/tests/basic/gfapi/gfapi-graph-switch-open-fd.t new file mode 100644 index 00000000000..2e666be7ec7 --- /dev/null +++ b/tests/basic/gfapi/gfapi-graph-switch-open-fd.t @@ -0,0 +1,44 @@ +#!/bin/bash + +. $(dirname $0)/../../include.rc +. $(dirname $0)/../../volume.rc + +cleanup; + +TEST glusterd + +TEST $CLI volume create $V0 replica 3 ${H0}:$B0/brick{0..2}; +EXPECT 'Created' volinfo_field $V0 'Status'; + +TEST $CLI volume start $V0; +EXPECT 'Started' volinfo_field $V0 'Status'; + +TEST $GFS --volfile-id=$V0 --volfile-server=$H0 $M0; +TEST touch $M0/sync +logdir=`gluster --print-logdir` + +TEST build_tester $(dirname $0)/gfapi-keep-writing.c -lgfapi + + +#Launch a program to keep doing writes on an fd +./$(dirname $0)/gfapi-keep-writing ${H0} $V0 $logdir/gfapi-async-calls-test.log sync & +p=$! +sleep 1 #Let some writes go through +#Check if graph switch will lead to any pending markers for ever +TEST $CLI volume set $V0 performance.quick-read off +TEST $CLI volume set $V0 performance.io-cache off +TEST $CLI volume set $V0 performance.stat-prefetch off +TEST $CLI volume set $V0 performance.read-ahead off + + +TEST rm -f $M0/sync #Make sure the glfd is closed +TEST wait #Wait for background process to die +#Goal is to check if there is permanent FOOL changelog +sleep 5 +EXPECT "0x000000000000000000000000" afr_get_changelog_xattr $B0/brick0/glfs_test.txt trusted.afr.dirty +EXPECT "0x000000000000000000000000" afr_get_changelog_xattr $B0/brick1/glfs_test.txt trusted.afr.dirty +EXPECT "0x000000000000000000000000" afr_get_changelog_xattr $B0/brick2/glfs_test.txt trusted.afr.dirty + +cleanup_tester $(dirname $0)/gfapi-async-calls-test + +cleanup; diff --git a/tests/basic/gfapi/gfapi-keep-writing.c b/tests/basic/gfapi/gfapi-keep-writing.c new file mode 100644 index 00000000000..91b59cea02b --- /dev/null +++ b/tests/basic/gfapi/gfapi-keep-writing.c @@ -0,0 +1,129 @@ +#include <fcntl.h> +#include <unistd.h> +#include <time.h> +#include <limits.h> +#include <string.h> +#include <stdio.h> +#include <stdlib.h> +#include <errno.h> +#include <glusterfs/api/glfs.h> +#include <glusterfs/api/glfs-handles.h> + +#define LOG_ERR(msg) \ + do { \ + fprintf(stderr, "%s : Error (%s)\n", msg, strerror(errno)); \ + } while (0) + +glfs_t * +init_glfs(const char *hostname, const char *volname, const char *logfile) +{ + int ret = -1; + glfs_t *fs = NULL; + + fs = glfs_new(volname); + if (!fs) { + LOG_ERR("glfs_new failed"); + return NULL; + } + + ret = glfs_set_volfile_server(fs, "tcp", hostname, 24007); + if (ret < 0) { + LOG_ERR("glfs_set_volfile_server failed"); + goto out; + } + + ret = glfs_set_logging(fs, logfile, 7); + if (ret < 0) { + LOG_ERR("glfs_set_logging failed"); + goto out; + } + + ret = glfs_init(fs); + if (ret < 0) { + LOG_ERR("glfs_init failed"); + goto out; + } + + ret = 0; +out: + if (ret) { + glfs_fini(fs); + fs = NULL; + } + + return fs; +} + +int +glfs_test_function(const char *hostname, const char *volname, + const char *logfile, const char *syncfile) +{ + int ret = -1; + int flags = O_CREAT | O_RDWR; + glfs_t *fs = NULL; + glfs_fd_t *glfd = NULL; + const char *buff = "This is from my prog\n"; + const char *filename = "glfs_test.txt"; + struct stat buf = {0}; + + fs = init_glfs(hostname, volname, logfile); + if (fs == NULL) { + LOG_ERR("init_glfs failed"); + return -1; + } + + glfd = glfs_creat(fs, filename, flags, 0644); + if (glfd == NULL) { + LOG_ERR("glfs_creat failed"); + goto out; + } + + while (glfs_stat(fs, syncfile, &buf) == 0) { + ret = glfs_write(glfd, buff, strlen(buff), flags); + if (ret < 0) { + LOG_ERR("glfs_write failed"); + goto out; + } + } + + ret = glfs_close(glfd); + if (ret < 0) { + LOG_ERR("glfs_write failed"); + goto out; + } + +out: + ret = glfs_fini(fs); + if (ret) { + LOG_ERR("glfs_fini failed"); + } + + return ret; +} + +int +main(int argc, char *argv[]) +{ + int ret = 0; + char *hostname = NULL; + char *volname = NULL; + char *logfile = NULL; + char *syncfile = NULL; + + if (argc != 5) { + fprintf(stderr, "Invalid argument\n"); + exit(1); + } + + hostname = argv[1]; + volname = argv[2]; + logfile = argv[3]; + syncfile = argv[4]; + + ret = glfs_test_function(hostname, volname, logfile, syncfile); + if (ret) { + LOG_ERR("glfs_test_function failed"); + } + + return ret; +} diff --git a/tests/basic/gfapi/gfapi-ssl-load-volfile-test.c b/tests/basic/gfapi/gfapi-ssl-load-volfile-test.c new file mode 100644 index 00000000000..7beb8dd1fe4 --- /dev/null +++ b/tests/basic/gfapi/gfapi-ssl-load-volfile-test.c @@ -0,0 +1,127 @@ +#include <fcntl.h> +#include <unistd.h> +#include <time.h> +#include <limits.h> +#include <string.h> +#include <stdio.h> +#include <stdlib.h> +#include <errno.h> +#include <glusterfs/api/glfs.h> +#include <glusterfs/api/glfs-handles.h> + +#define LOG_ERR(msg) \ + do { \ + fprintf(stderr, "%s : Error (%s)\n", msg, strerror(errno)); \ + } while (0) + +glfs_t * +init_glfs(const char *hostname, const char *volname, const char *volfile, + const char *logfile) +{ + int ret = -1; + glfs_t *fs = NULL; + + fs = glfs_new(volname); + if (!fs) { + LOG_ERR("glfs_new failed"); + return NULL; + } + + ret = glfs_set_volfile(fs, volfile); + if (ret < 0) { + LOG_ERR("glfs_set_volfile failed"); + goto out; + } + + ret = glfs_set_logging(fs, logfile, 7); + if (ret < 0) { + LOG_ERR("glfs_set_logging failed"); + goto out; + } + + ret = glfs_init(fs); + if (ret < 0) { + LOG_ERR("glfs_init failed"); + goto out; + } + + ret = 0; +out: + if (ret) { + glfs_fini(fs); + fs = NULL; + } + + return fs; +} + +int +glfs_test_function(const char *hostname, const char *volname, + const char *volfile, const char *logfile) +{ + int ret = -1; + int flags = O_CREAT | O_RDWR; + glfs_t *fs = NULL; + glfs_fd_t *glfd = NULL; + const char *buff = "This is from my prog\n"; + const char *filename = "glfs_test.txt"; + + fs = init_glfs(hostname, volname, volfile, logfile); + if (fs == NULL) { + LOG_ERR("init_glfs failed"); + return -1; + } + + glfd = glfs_creat(fs, filename, flags, 0644); + if (glfd == NULL) { + LOG_ERR("glfs_creat failed"); + goto out; + } + + ret = glfs_write(glfd, buff, strlen(buff), flags); + if (ret < 0) { + LOG_ERR("glfs_write failed"); + goto out; + } + + ret = glfs_close(glfd); + if (ret < 0) { + LOG_ERR("glfs_write failed"); + goto out; + } + +out: + ret = glfs_fini(fs); + if (ret) { + LOG_ERR("glfs_fini failed"); + } + + return ret; +} + +int +main(int argc, char *argv[]) +{ + int ret = 0; + char *hostname = NULL; + char *volname = NULL; + char *volfile = NULL; + char *logfile = NULL; + + if (argc != 5) { + fprintf(stderr, "Invalid argument\n"); + exit(1); + } + + hostname = argv[1]; + volname = argv[2]; + volfile = argv[3]; + logfile = argv[4]; + + ret = glfs_test_function(hostname, volname, volfile, logfile); + if (ret) { + LOG_ERR("glfs_test_function failed"); + } + + return ret; +} diff --git a/tests/basic/gfapi/gfapi-ssl-load-volfile-test.t b/tests/basic/gfapi/gfapi-ssl-load-volfile-test.t new file mode 100755 index 00000000000..8e94df9d321 --- /dev/null +++ b/tests/basic/gfapi/gfapi-ssl-load-volfile-test.t @@ -0,0 +1,76 @@ +#!/bin/bash + +. $(dirname $0)/../../include.rc +. $(dirname $0)/../../volume.rc +. $(dirname $0)/../../traps.rc +. $(dirname $0)/../../ssl.rc + +cleanup; + +sed -e "s,@@HOSTNAME@@,${H0},g" -e "s,@@BRICKPATH@@,${B0}/brick1,g" \ + -e "s,@@SSL@@,off,g" \ + $(dirname ${0})/protocol-client-ssl.vol.in \ + > $(dirname ${0})/protocol-client-ssl.vol + +TEST create_self_signed_certs + +TEST glusterd + +TEST $CLI volume create $V0 $H0:$B0/brick1; +EXPECT 'Created' volinfo_field $V0 'Status'; + +TEST $CLI volume start $V0; +EXPECT 'Started' volinfo_field $V0 'Status'; +EXPECT_WITHIN $CHILD_UP_TIMEOUT "1" online_brick_count + +logdir=`gluster --print-logdir` + +TEST build_tester $(dirname $0)/gfapi-ssl-load-volfile-test.c -lgfapi + +# Run test without I/O or management encryption +TEST $(dirname $0)/gfapi-ssl-load-volfile-test $H0 $V0 \ + $(dirname ${0})/protocol-client-ssl.vol \ + $logdir/gfapi-ssl-load-volfile-test.log + +# Enable management encryption +touch $GLUSTERD_WORKDIR/secure-access + +killall_gluster + +TEST glusterd +EXPECT_WITHIN $CHILD_UP_TIMEOUT "1" online_brick_count + +# Run test with management encryption (No I/O encryption) +TEST $(dirname $0)/gfapi-ssl-load-volfile-test $H0 $V0 \ + $(dirname ${0})/protocol-client-ssl.vol \ + $logdir/gfapi-ssl-load-volfile-test.log + +# Enable I/O encryption +TEST $CLI volume set $V0 server.ssl on + +killall_gluster + +sed -e "s,@@HOSTNAME@@,${H0},g" -e "s,@@BRICKPATH@@,${B0}/brick1,g" \ + -e "s,@@SSL@@,on,g" \ + $(dirname ${0})/protocol-client-ssl.vol.in \ + > $(dirname ${0})/protocol-client-ssl.vol + +TEST glusterd +EXPECT_WITHIN $CHILD_UP_TIMEOUT "1" online_brick_count + +# Run test without I/O or management encryption +TEST $(dirname $0)/gfapi-ssl-load-volfile-test $H0 $V0 \ + $(dirname ${0})/protocol-client-ssl.vol \ + $logdir/gfapi-ssl-load-volfile-test.log + +cleanup_tester $(dirname $0)/gfapi-ssl-load-volfile-test + +TEST $CLI volume stop $V0 +TEST $CLI volume delete $V0 + +cleanup; + +# NetBSD build scripts are not up to date therefore this test +# is failing in NetBSD. Therefore skipping the test in NetBSD +# as of now. +#G_TESTDEF_TEST_STATUS_NETBSD7=KNOWN_ISSUE,BUG=000000 diff --git a/tests/basic/gfapi/gfapi-statx-basic.c b/tests/basic/gfapi/gfapi-statx-basic.c new file mode 100644 index 00000000000..a4943fa0fd1 --- /dev/null +++ b/tests/basic/gfapi/gfapi-statx-basic.c @@ -0,0 +1,184 @@ +#include <stdio.h> +#include <errno.h> +#include <string.h> +#include <stdbool.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <unistd.h> +#include <glusterfs/api/glfs.h> + +#define VALIDATE_AND_GOTO_LABEL_ON_ERROR(func, ret, label) \ + do { \ + if (ret < 0) { \ + fprintf(stderr, "%s : returned error %d (%s)\n", func, ret, \ + strerror(errno)); \ + goto label; \ + } \ + } while (0) + +#define GOTO_LABEL_ON_FALSE(compstr, ret, label) \ + do { \ + if (ret == false) { \ + fprintf(stderr, "%s : comparison failed!\n", compstr); \ + goto label; \ + } \ + } while (0) + +#define WRITE_SIZE 513 +#define TRUNC_SIZE 4096 + +/* Using private function and hence providing a forward declation in sync with +code in glfs-internal.h */ +int +glfs_statx(struct glfs *fs, const char *path, unsigned int mask, + struct glfs_stat *statxbuf); + +int +main(int argc, char *argv[]) +{ + int ret = -1; + int flags = O_RDWR | O_SYNC; + glfs_t *fs = NULL; + glfs_fd_t *fd1 = NULL; + char *volname = NULL; + char *logfile = NULL; + const char *filename = "file_tmp"; + const char buff[WRITE_SIZE]; + struct stat sb; + unsigned int mask; + struct glfs_stat statx; + bool bret; + + if (argc != 3) { + fprintf(stderr, "Invalid argument\n"); + fprintf(stderr, "Usage: %s <volname> <logfile>\n", argv[0]); + return 1; + } + + volname = argv[1]; + logfile = argv[2]; + + fs = glfs_new(volname); + if (!fs) + VALIDATE_AND_GOTO_LABEL_ON_ERROR("glfs_new", ret, out); + + ret = glfs_set_volfile_server(fs, "tcp", "localhost", 24007); + VALIDATE_AND_GOTO_LABEL_ON_ERROR("glfs_set_volfile_server", ret, out); + + ret = glfs_set_logging(fs, logfile, 7); + VALIDATE_AND_GOTO_LABEL_ON_ERROR("glfs_set_logging", ret, out); + + ret = glfs_init(fs); + VALIDATE_AND_GOTO_LABEL_ON_ERROR("glfs_init", ret, out); + + fd1 = glfs_creat(fs, filename, flags, 0644); + if (fd1 == NULL) { + ret = -1; + VALIDATE_AND_GOTO_LABEL_ON_ERROR("glfs_creat", ret, out); + } + + ret = glfs_truncate(fs, filename, TRUNC_SIZE); + VALIDATE_AND_GOTO_LABEL_ON_ERROR("glfs_truncate", ret, out); + + ret = glfs_write(fd1, buff, WRITE_SIZE, flags); + VALIDATE_AND_GOTO_LABEL_ON_ERROR("glfs_write", ret, out); + + ret = glfs_fstat(fd1, &sb); + VALIDATE_AND_GOTO_LABEL_ON_ERROR("glfs_fstat", ret, out); + + if (sb.st_size != TRUNC_SIZE) { + fprintf(stderr, "wrong size %jd should be %jd\n", (intmax_t)sb.st_size, + (intmax_t)2048); + ret = -1; + goto out; + } + + glfs_close(fd1); + fd1 = NULL; + + /* TEST 1: Invalid mask to statx */ + mask = 0xfafadbdb; + ret = glfs_statx(fs, filename, mask, NULL); + if (ret == 0 || ((ret == -1) && (errno != EINVAL))) { + fprintf(stderr, + "Invalid args passed, but error returned is" + " incorrect (ret - %d, errno - %d)\n", + ret, errno); + ret = -1; + goto out; + } + ret = 0; + + /* TEST 2: Call statx and validate fields against prior fstat data */ + /* NOTE: This fails, as iatt->ia_flags are not carried through the stack, + * for example if mdc_to_iatt is invoked to serve cached stat, we will loose + * the flags. */ + mask = GLFS_STAT_ALL; + ret = glfs_statx(fs, filename, mask, &statx); + VALIDATE_AND_GOTO_LABEL_ON_ERROR("glfs_statx", ret, out); + + if ((statx.glfs_st_mask & GLFS_STAT_BASIC_STATS) != GLFS_STAT_BASIC_STATS) { + fprintf(stderr, "Invalid glfs_st_mask, expecting 0x%x got 0x%x\n", + GLFS_STAT_ALL, statx.glfs_st_mask); + ret = -1; + goto out; + } + + bret = (sb.st_ino == statx.glfs_st_ino); + GOTO_LABEL_ON_FALSE("(sb.st_ino == statx.glfs_st_ino)", bret, out); + + bret = (sb.st_mode == statx.glfs_st_mode); + GOTO_LABEL_ON_FALSE("(sb.st_mode == statx.glfs_st_mode)", bret, out); + + bret = (sb.st_nlink == statx.glfs_st_nlink); + GOTO_LABEL_ON_FALSE("(sb.st_nlink == statx.glfs_st_nlink)", bret, out); + + bret = (sb.st_uid == statx.glfs_st_uid); + GOTO_LABEL_ON_FALSE("(sb.st_uid == statx.glfs_st_uid)", bret, out); + + bret = (sb.st_gid == statx.glfs_st_gid); + GOTO_LABEL_ON_FALSE("(sb.st_gid == statx.glfs_st_gid)", bret, out); + + bret = (sb.st_size == statx.glfs_st_size); + GOTO_LABEL_ON_FALSE("(sb.st_size == statx.glfs_st_size)", bret, out); + + bret = (sb.st_blksize == statx.glfs_st_blksize); + GOTO_LABEL_ON_FALSE("(sb.st_blksize == statx.glfs_st_blksize)", bret, out); + + bret = (sb.st_blocks == statx.glfs_st_blocks); + GOTO_LABEL_ON_FALSE("(sb.st_blocks == statx.glfs_st_blocks)", bret, out); + + bret = (!memcmp(&sb.st_atim, &statx.glfs_st_atime, + sizeof(struct timespec))); + GOTO_LABEL_ON_FALSE("(sb.st_atim == statx.glfs_st_atime)", bret, out); + + bret = (!memcmp(&sb.st_mtim, &statx.glfs_st_mtime, + sizeof(struct timespec))); + GOTO_LABEL_ON_FALSE("(sb.st_mtim == statx.glfs_st_mtime)", bret, out); + + bret = (!memcmp(&sb.st_ctim, &statx.glfs_st_ctime, + sizeof(struct timespec))); + GOTO_LABEL_ON_FALSE("(sb.st_ctim == statx.glfs_st_ctime)", bret, out); + + /* TEST 3: Check if partial masks are accepted */ + mask = GLFS_STAT_TYPE | GLFS_STAT_UID | GLFS_STAT_GID; + ret = glfs_statx(fs, filename, mask, &statx); + VALIDATE_AND_GOTO_LABEL_ON_ERROR("glfs_statx", ret, out); + + /* We currently still return all stats, as is acceptable based on the API + * definition in the header (and in statx as well) */ + if ((statx.glfs_st_mask & GLFS_STAT_BASIC_STATS) != GLFS_STAT_BASIC_STATS) { + fprintf(stderr, "Invalid glfs_st_mask, expecting 0x%x got 0x%x\n", + GLFS_STAT_ALL, statx.glfs_st_mask); + ret = -1; + goto out; + } +out: + if (fd1 != NULL) + glfs_close(fd1); + if (fs) { + (void)glfs_fini(fs); + } + + return ret; +} diff --git a/tests/basic/gfapi/gfapi-statx-basic.t b/tests/basic/gfapi/gfapi-statx-basic.t new file mode 100755 index 00000000000..d9acbce2f99 --- /dev/null +++ b/tests/basic/gfapi/gfapi-statx-basic.t @@ -0,0 +1,30 @@ +#!/bin/bash + +. $(dirname $0)/../../include.rc +. $(dirname $0)/../../volume.rc + +cleanup; + +TEST glusterd + +TEST $CLI volume create $V0 ${H0}:$B0/brick1; +EXPECT 'Created' volinfo_field $V0 'Status'; + +TEST $CLI volume start $V0; +EXPECT 'Started' volinfo_field $V0 'Status'; + +# NOTE: Test is passing due to very specific volume configuration +# Disable md-cache, as it does not save and return ia_flags from iatt +# This is possibly going to be true of other xlators as well (ec/afr), need to +# ensure these are fixed, or hack statx to return all basic attrs anyway. +TEST $CLI volume set $V0 performance.md-cache-timeout 0 + +logdir=`gluster --print-logdir` + +build_tester $(dirname $0)/gfapi-statx-basic.c -lgfapi + +TEST ./$(dirname $0)/gfapi-statx-basic $V0 $logdir/gfapi-statx-basic.log + +cleanup_tester $(dirname $0)/gfapi-statx-basic + +cleanup; diff --git a/tests/basic/gfapi/glfs-copy-file-range.c b/tests/basic/gfapi/glfs-copy-file-range.c new file mode 100644 index 00000000000..1c5fd81fc87 --- /dev/null +++ b/tests/basic/gfapi/glfs-copy-file-range.c @@ -0,0 +1,180 @@ +/* + Copyright (c) 2018 Red Hat, Inc. <http://www.redhat.com> + This file is part of GlusterFS. + + This file is licensed to you under your choice of the GNU Lesser + General Public License, version 3 or any later version (LGPLv3 or + later), or the GNU General Public License, version 2 (GPLv2), in all + cases as published by the Free Software Foundation. +*/ + +#include <stdio.h> +#include <stdlib.h> +#include <errno.h> +#include <glusterfs/api/glfs.h> +#include <glusterfs/api/glfs-handles.h> +#include <string.h> +#include <time.h> +#include <libgen.h> + +static void +cleanup(glfs_t *fs) +{ + if (!fs) + return; +#if 0 + /* glfs fini path is still racy and crashing the program. Since + * this program any way has to die, we are not going to call fini + * in the released versions. i.e. final builds. For all + * internal testing lets enable this so that glfs_fini code + * path becomes stable. */ + glfs_fini (fs); +#endif +} + +int +main(int argc, char **argv) +{ + glfs_t *fs = NULL; + int ret = -1; + char *volname = NULL; + char *logfilepath = NULL; + char *path_src = NULL; + char *path_dst = NULL; + glfs_fd_t *glfd_in = NULL; + glfs_fd_t *glfd_out = NULL; + char *volfile_server = NULL; + + struct stat stbuf = { + 0, + }; + struct glfs_stat stat_src = { + 0, + }; + struct glfs_stat prestat_dst = { + 0, + }; + struct glfs_stat poststat_dst = { + 0, + }; + size_t len; + + if (argc < 6) { + printf("%s <volume> <log file path> <source> <destination>", argv[0]); + ret = -1; + goto out; + } + + volfile_server = argv[1]; + volname = argv[2]; + logfilepath = argv[3]; + path_src = argv[4]; + path_dst = argv[5]; + + if (path_src[0] != '/') { + fprintf(stderr, "source path %s is not absolute", path_src); + errno = EINVAL; + goto out; + } + + if (path_dst[0] != '/') { + fprintf(stderr, "destination path %s is not absolute", path_dst); + errno = EINVAL; + goto out; + } + + fs = glfs_new(volname); + if (!fs) { + ret = -errno; + fprintf(stderr, "Not able to initialize volume '%s'", volname); + goto out; + } + + ret = glfs_set_volfile_server(fs, "tcp", volfile_server, 24007); + if (ret < 0) { + ret = -errno; + fprintf(stderr, + "Failed to set the volfile server, " + "%s", + strerror(errno)); + goto out; + } + + ret = glfs_set_logging(fs, logfilepath, 7); + if (ret < 0) { + ret = -errno; + fprintf(stderr, + "Failed to set the log file path, " + "%s", + strerror(errno)); + goto out; + } + + ret = glfs_init(fs); + if (ret < 0) { + ret = -errno; + if (errno == ENOENT) { + fprintf(stderr, "Volume %s does not exist", volname); + } else { + fprintf(stderr, + "%s: Not able to fetch " + "volfile from glusterd", + volname); + } + goto out; + } + + glfd_in = glfs_open(fs, path_src, O_RDONLY | O_NONBLOCK); + if (!glfd_in) { + ret = -errno; + goto out; + } else { + printf("OPEN_SRC: opening %s is success\n", path_src); + } + + glfd_out = glfs_creat(fs, path_dst, O_RDWR, 0644); + if (!glfd_out) { + fprintf(stderr, + "FAILED_DST_OPEN: failed to " + "open (create) %s (%s)\n", + path_dst, strerror(errno)); + ret = -errno; + goto out; + } else { + printf("OPEN_DST: opening %s is success\n", path_dst); + } + + ret = glfs_fstat(glfd_in, &stbuf); + if (ret < 0) { + ret = -errno; + goto out; + } else { + printf("FSTAT_SRC: fstat on %s is success\n", path_dst); + } + + len = stbuf.st_size; + + do { + ret = glfs_copy_file_range(glfd_in, NULL, glfd_out, NULL, len, 0, + &stat_src, &prestat_dst, &poststat_dst); + if (ret == -1) { + fprintf(stderr, "copy_file_range failed with %s\n", + strerror(errno)); + ret = -errno; + break; + } else { + printf("copy_file_range successful\n"); + len -= ret; + } + } while (len > 0); + +out: + if (glfd_in) + glfs_close(glfd_in); + if (glfd_out) + glfs_close(glfd_out); + + cleanup(fs); + + return ret; +} diff --git a/tests/basic/gfapi/glfs_h_creat_open.c b/tests/basic/gfapi/glfs_h_creat_open.c new file mode 100644 index 00000000000..7672561e73f --- /dev/null +++ b/tests/basic/gfapi/glfs_h_creat_open.c @@ -0,0 +1,118 @@ +#include <fcntl.h> +#include <unistd.h> +#include <time.h> +#include <limits.h> +#include <string.h> +#include <stdio.h> +#include <errno.h> +#include <stdlib.h> +#include <glusterfs/api/glfs.h> +#include <glusterfs/api/glfs-handles.h> + +#define LOG_ERR(func, ret) \ + do { \ + if (ret != 0) { \ + fprintf(stderr, "%s : returned error ret(%d), errno(%d)\n", func, \ + ret, errno); \ + exit(1); \ + } else { \ + fprintf(stderr, "%s : returned %d\n", func, ret); \ + } \ + } while (0) +#define LOG_IF_NO_ERR(func, ret) \ + do { \ + if (ret == 0) { \ + fprintf(stderr, "%s : hasn't returned error %d\n", func, ret); \ + exit(1); \ + } else { \ + fprintf(stderr, "%s : returned %d\n", func, ret); \ + } \ + } while (0) +int +main(int argc, char *argv[]) +{ + glfs_t *fs = NULL; + int ret = 0; + struct glfs_object *root = NULL, *leaf = NULL; + glfs_fd_t *fd = NULL; + char *filename = "/ro-file"; + struct stat sb = { + 0, + }; + char *logfile = NULL; + char *volname = NULL; + char *hostname = NULL; + char buf[32] = "abcdefghijklmnopqrstuvwxyz012345"; + + fprintf(stderr, "Starting glfs_h_creat_open\n"); + + if (argc != 4) { + fprintf(stderr, "Invalid argument\n"); + exit(1); + } + + hostname = argv[1]; + volname = argv[2]; + logfile = argv[3]; + + fs = glfs_new(volname); + if (!fs) { + fprintf(stderr, "glfs_new: returned NULL\n"); + return 1; + } + + ret = glfs_set_volfile_server(fs, "tcp", hostname, 24007); + LOG_ERR("glfs_set_volfile_server", ret); + + ret = glfs_set_logging(fs, logfile, 7); + LOG_ERR("glfs_set_logging", ret); + + ret = glfs_init(fs); + LOG_ERR("glfs_init", ret); + + sleep(2); + root = glfs_h_lookupat(fs, NULL, "/", &sb, 0); + if (!root) { + ret = -1; + LOG_ERR("glfs_h_lookupat root", ret); + } + leaf = glfs_h_lookupat(fs, root, filename, &sb, 0); + if (!leaf) { + ret = -1; + LOG_IF_NO_ERR("glfs_h_lookupat leaf", ret); + } + + leaf = glfs_h_creat_open(fs, root, filename, O_RDONLY, 00444, &sb, &fd); + if (!leaf || !fd) { + ret = -1; + LOG_ERR("glfs_h_creat leaf", ret); + } + fprintf(stderr, "glfs_h_create_open leaf - %p\n", leaf); + + ret = glfs_write(fd, buf, 32, 0); + if (ret < 0) { + fprintf(stderr, "glfs_write: error writing to file %s, %s\n", filename, + strerror(errno)); + goto out; + } + + ret = glfs_h_getattrs(fs, leaf, &sb); + LOG_ERR("glfs_h_getattrs", ret); + + if (sb.st_size != 32) { + fprintf(stderr, "glfs_write: post size mismatch\n"); + goto out; + } + + fprintf(stderr, "Successfully opened and written to a read-only file \n"); +out: + if (fd) + glfs_close(fd); + + ret = glfs_fini(fs); + LOG_ERR("glfs_fini", ret); + + fprintf(stderr, "End of libgfapi_fini\n"); + + exit(0); +} diff --git a/tests/basic/gfapi/glfs_h_creat_open.t b/tests/basic/gfapi/glfs_h_creat_open.t new file mode 100755 index 00000000000..f24ae7395be --- /dev/null +++ b/tests/basic/gfapi/glfs_h_creat_open.t @@ -0,0 +1,27 @@ +#!/bin/bash + +. $(dirname $0)/../../include.rc +. $(dirname $0)/../../volume.rc + +cleanup; + +TEST glusterd + +TEST $CLI volume create $V0 $H0:$B0/brick1; +EXPECT 'Created' volinfo_field $V0 'Status'; + +TEST $CLI volume start $V0; +EXPECT 'Started' volinfo_field $V0 'Status'; + +logdir=`gluster --print-logdir` + +TEST build_tester $(dirname $0)/glfs_h_creat_open.c -lgfapi + +TEST ./$(dirname $0)/glfs_h_creat_open $H0 $V0 $logdir/glfs.log + +cleanup_tester $(dirname $0)/glfs_h_creat_open + +TEST $CLI volume stop $V0 +TEST $CLI volume delete $V0 + +cleanup; diff --git a/tests/basic/gfapi/glfsxmp-coverage.c b/tests/basic/gfapi/glfsxmp-coverage.c new file mode 100644 index 00000000000..51650023efd --- /dev/null +++ b/tests/basic/gfapi/glfsxmp-coverage.c @@ -0,0 +1,1900 @@ +#include <stdio.h> +#include <stdlib.h> +#include <errno.h> +#include <glusterfs/api/glfs.h> +#include <glusterfs/api/glfs-handles.h> +#include <string.h> +#include <time.h> + +#define TEST_STR_LEN 2048 + +int +test_dirops(glfs_t *fs) +{ + glfs_fd_t *fd = NULL; + char buf[2048]; + struct dirent *entry = NULL; + + fd = glfs_opendir(fs, "/"); + if (!fd) { + fprintf(stderr, "/: %s\n", strerror(errno)); + return -1; + } + + fprintf(stderr, "Entries:\n"); + while (glfs_readdir_r(fd, (struct dirent *)buf, &entry), entry) { + fprintf(stderr, "%s: %lu\n", entry->d_name, glfs_telldir(fd)); + } + + /* Should internally call fsyncdir(), hopefully */ + glfs_fsync(fd, NULL, NULL); + + glfs_closedir(fd); + return 0; +} + +int +test_xattr(glfs_t *fs) +{ + char *filename = "/filename2"; + char *linkfile = "/linkfile"; + glfs_fd_t *fd = NULL; + char buf[512]; + char *ptr; + int ret; + + ret = glfs_setxattr(fs, filename, "user.testkey", "testval", 8, 0); + fprintf(stderr, "setxattr(%s): %d (%s)\n", filename, ret, strerror(errno)); + + ret = glfs_setxattr(fs, filename, "user.testkey2", "testval", 8, 0); + fprintf(stderr, "setxattr(%s): %d (%s)\n", filename, ret, strerror(errno)); + + ret = glfs_getxattr(fs, filename, "user.testkey", buf, 512); + fprintf(stderr, "getxattr(%s): %d (%s)\n", filename, ret, strerror(errno)); + if (ret < 0) + return -1; + + ret = glfs_listxattr(fs, filename, buf, 512); + fprintf(stderr, "listxattr(%s): %d (%s)\n", filename, ret, strerror(errno)); + if (ret < 0) + return -1; + + ret = glfs_symlink(fs, "filename", linkfile); + fprintf(stderr, "symlink(%s %s): %s\n", filename, linkfile, + strerror(errno)); + if (ret < 0) + return -1; + + ret = glfs_readlink(fs, linkfile, buf, 512); + fprintf(stderr, "readlink(%s) : %d (%s)\n", filename, ret, strerror(errno)); + if (ret < 0) + return -1; + + ret = glfs_lsetxattr(fs, filename, "user.testkey3", "testval", 8, 0); + fprintf(stderr, "lsetxattr(%s) : %d (%s)\n", linkfile, ret, + strerror(errno)); + if (ret < 0) + return -1; + + ret = glfs_llistxattr(fs, linkfile, buf, 512); + fprintf(stderr, "llistxattr(%s): %d (%s)\n", filename, ret, + strerror(errno)); + if (ret < 0) + return -1; + + ret = glfs_lgetxattr(fs, filename, "user.testkey3", buf, 512); + fprintf(stderr, "lgetxattr(%s): %d (%s)\n", linkfile, ret, strerror(errno)); + if (ret < 0) + return -1; + + for (ptr = buf; ptr < buf + ret; ptr++) { + printf("key=%s\n", ptr); + ptr += strlen(ptr); + } + + ret = glfs_removexattr(fs, filename, "user.testkey2"); + fprintf(stderr, "removexattr(%s): %d (%s)\n", filename, ret, + strerror(errno)); + + fd = glfs_open(fs, filename, O_RDWR); + fprintf(stderr, "open(%s): (%p) %s\n", filename, fd, strerror(errno)); + + ret = glfs_fsetxattr(fd, "user.testkey2", "testval", 8, 0); + fprintf(stderr, "fsetxattr(%s): %d (%s)\n", filename, ret, strerror(errno)); + + ret = glfs_fgetxattr(fd, "user.testkey2", buf, 512); + fprintf(stderr, "fgetxattr(%s): %d (%s)\n", filename, ret, strerror(errno)); + + ret = glfs_flistxattr(fd, buf, 512); + fprintf(stderr, "flistxattr(%s): %d (%s)\n", filename, ret, + strerror(errno)); + if (ret < 0) + return -1; + + for (ptr = buf; ptr < buf + ret; ptr++) { + printf("key=%s\n", ptr); + ptr += strlen(ptr); + } + + ret = glfs_fremovexattr(fd, "user.testkey2"); + fprintf(stderr, "fremovexattr(%s): %d (%s)\n", filename, ret, + strerror(errno)); + + glfs_close(fd); + + return 0; +} + +int +test_chdir(glfs_t *fs) +{ + int ret = -1; + char *dir = "/dir"; + char *topdir = "/topdir"; + char *linkdir = "/linkdir"; + char *linkdir2 = "/linkdir2"; + char *subdir = "./subdir"; + char *respath = NULL; + char pathbuf[4096]; + + ret = glfs_mkdir(fs, topdir, 0755); + fprintf(stderr, "mkdir(%s): %s\n", topdir, strerror(errno)); + if (ret) + return -1; + + ret = glfs_mkdir(fs, dir, 0755); + fprintf(stderr, "mkdir(%s): %s\n", dir, strerror(errno)); + if (ret) + return -1; + + respath = glfs_getcwd(fs, pathbuf, 4096); + fprintf(stdout, "getcwd() = %s\n", respath); + + ret = glfs_symlink(fs, "topdir", linkdir); + if (ret) { + fprintf(stderr, "symlink(%s, %s): %s\n", topdir, linkdir, + strerror(errno)); + return -1; + } + + ret = glfs_chdir(fs, linkdir); + if (ret) { + fprintf(stderr, "chdir(%s): %s\n", linkdir, strerror(errno)); + return -1; + } + + respath = glfs_getcwd(fs, pathbuf, 4096); + fprintf(stdout, "getcwd() = %s\n", respath); + + respath = glfs_realpath(fs, subdir, pathbuf); + if (respath) { + fprintf(stderr, "realpath(%s) worked unexpectedly: %s\n", subdir, + respath); + return -1; + } + + ret = glfs_mkdir(fs, subdir, 0755); + if (ret) { + fprintf(stderr, "mkdir(%s): %s\n", subdir, strerror(errno)); + return -1; + } + + respath = glfs_realpath(fs, subdir, pathbuf); + if (!respath) { + fprintf(stderr, "realpath(%s): %s\n", subdir, strerror(errno)); + } else { + fprintf(stdout, "realpath(%s) = %s\n", subdir, respath); + } + + ret = glfs_chdir(fs, subdir); + if (ret) { + fprintf(stderr, "chdir(%s): %s\n", subdir, strerror(errno)); + return -1; + } + + respath = glfs_getcwd(fs, pathbuf, 4096); + fprintf(stdout, "getcwd() = %s\n", respath); + + respath = glfs_realpath(fs, "/linkdir/subdir", pathbuf); + if (!respath) { + fprintf(stderr, "realpath(/linkdir/subdir): %s\n", strerror(errno)); + } else { + fprintf(stdout, "realpath(/linkdir/subdir) = %s\n", respath); + } + + return 0; +} + +#ifdef DEBUG +static void +peek_stat(struct stat *sb) +{ + printf("Dumping stat information:\n"); + printf("File type: "); + + switch (sb->st_mode & S_IFMT) { + case S_IFBLK: + printf("block device\n"); + break; + case S_IFCHR: + printf("character device\n"); + break; + case S_IFDIR: + printf("directory\n"); + break; + case S_IFIFO: + printf("FIFO/pipe\n"); + break; + case S_IFLNK: + printf("symlink\n"); + break; + case S_IFREG: + printf("regular file\n"); + break; + case S_IFSOCK: + printf("socket\n"); + break; + default: + printf("unknown?\n"); + break; + } + + printf("I-node number: %ld\n", (long)sb->st_ino); + + printf("Mode: %lo (octal)\n", + (unsigned long)sb->st_mode); + + printf("Link count: %ld\n", (long)sb->st_nlink); + printf("Ownership: UID=%ld GID=%ld\n", (long)sb->st_uid, + (long)sb->st_gid); + + printf("Preferred I/O block size: %ld bytes\n", (long)sb->st_blksize); + printf("File size: %lld bytes\n", (long long)sb->st_size); + printf("Blocks allocated: %lld\n", (long long)sb->st_blocks); + + printf("Last status change: %s", ctime(&sb->st_ctime)); + printf("Last file access: %s", ctime(&sb->st_atime)); + printf("Last file modification: %s", ctime(&sb->st_mtime)); + + return; +} + +static void +peek_handle(unsigned char *glid) +{ + int i; + + for (i = 0; i < GFAPI_HANDLE_LENGTH; i++) { + printf(":%02x:", glid[i]); + } + printf("\n"); +} +#else /* DEBUG */ +static void +peek_stat(struct stat *sb) +{ + return; +} + +static void +peek_handle(unsigned char *id) +{ + return; +} +#endif /* DEBUG */ + +glfs_t *fs = NULL; +char *full_parent_name = "/testdir", *parent_name = "testdir"; + +void +test_h_unlink(void) +{ + char *my_dir = "unlinkdir"; + char *my_file = "file.txt"; + char *my_subdir = "dir1"; + struct glfs_object *parent = NULL, *leaf = NULL, *dir = NULL, + *subdir = NULL, *subleaf = NULL; + struct stat sb; + int ret; + + printf("glfs_h_unlink tests: In Progress\n"); + + /* Prepare tests */ + parent = glfs_h_lookupat(fs, NULL, full_parent_name, &sb, 0); + if (parent == NULL) { + fprintf(stderr, + "glfs_h_lookupat: error on lookup of %s: from (%p),%s\n", + full_parent_name, NULL, strerror(errno)); + printf("glfs_h_lookupat tests: FAILED\n"); + goto out; + } + peek_stat(&sb); + + dir = glfs_h_mkdir(fs, parent, my_dir, 0755, &sb); + if (dir == NULL) { + fprintf(stderr, "glfs_h_mkdir: error creating %s: from (%p),%s\n", + my_dir, parent, strerror(errno)); + printf("glfs_h_unlink tests: FAILED\n"); + goto out; + } + + leaf = glfs_h_creat(fs, dir, my_file, O_CREAT, 0644, &sb); + if (leaf == NULL) { + fprintf(stderr, "glfs_h_creat: error creating %s: from (%p),%s\n", + my_file, dir, strerror(errno)); + printf("glfs_h_unlink tests: FAILED\n"); + goto out; + } + + subdir = glfs_h_mkdir(fs, dir, my_subdir, 0755, &sb); + if (subdir == NULL) { + fprintf(stderr, "glfs_h_mkdir: error creating %s: from (%p),%s\n", + my_subdir, dir, strerror(errno)); + printf("glfs_h_unlink tests: FAILED\n"); + goto out; + } + + subleaf = glfs_h_creat(fs, subdir, my_file, O_CREAT, 0644, &sb); + if (subleaf == NULL) { + fprintf(stderr, "glfs_h_creat: error creating %s: from (%p),%s\n", + my_file, subdir, strerror(errno)); + printf("glfs_h_unlink tests: FAILED\n"); + goto out; + } + + /* unlink non empty directory */ + ret = glfs_h_unlink(fs, dir, my_subdir); + if ((ret && errno != ENOTEMPTY) || (ret == 0)) { + fprintf(stderr, + "glfs_h_unlink: error unlinking %s: it is non empty: %s\n", + my_subdir, strerror(errno)); + printf("glfs_h_unlink tests: FAILED\n"); + goto out; + } + + /* unlink regular file */ + ret = glfs_h_unlink(fs, subdir, my_file); + if (ret) { + fprintf(stderr, "glfs_h_unlink: error unlinking %s: from (%p),%s\n", + my_file, subdir, strerror(errno)); + printf("glfs_h_unlink tests: FAILED\n"); + goto out; + } + + /* unlink directory */ + ret = glfs_h_unlink(fs, dir, my_subdir); + if (ret) { + fprintf(stderr, "glfs_h_unlink: error unlinking %s: from (%p),%s\n", + my_subdir, dir, strerror(errno)); + printf("glfs_h_unlink tests: FAILED\n"); + goto out; + } + + /* unlink regular file */ + ret = glfs_h_unlink(fs, dir, my_file); + if (ret) { + fprintf(stderr, "glfs_h_unlink: error unlinking %s: from (%p),%s\n", + my_file, dir, strerror(errno)); + printf("glfs_h_unlink tests: FAILED\n"); + goto out; + } + + /* unlink non-existent regular file */ + ret = glfs_h_unlink(fs, dir, my_file); + if ((ret && errno != ENOENT) || (ret == 0)) { + fprintf(stderr, + "glfs_h_unlink: error unlinking non-existent %s: invalid errno " + ",%d, %s\n", + my_file, ret, strerror(errno)); + printf("glfs_h_unlink tests: FAILED\n"); + goto out; + } + + /* unlink non-existent directory */ + ret = glfs_h_unlink(fs, dir, my_subdir); + if ((ret && errno != ENOENT) || (ret == 0)) { + fprintf(stderr, + "glfs_h_unlink: error unlinking non-existent %s: invalid " + "errno ,%d, %s\n", + my_subdir, ret, strerror(errno)); + printf("glfs_h_unlink tests: FAILED\n"); + goto out; + } + + /* unlink directory */ + ret = glfs_h_unlink(fs, parent, my_dir); + if (ret) { + fprintf(stderr, "glfs_h_unlink: error unlinking %s: from (%p),%s\n", + my_dir, dir, strerror(errno)); + printf("glfs_h_unlink tests: FAILED\n"); + goto out; + } + + printf("glfs_h_unlink tests: PASSED\n"); + +out: + if (dir) + glfs_h_close(dir); + if (leaf) + glfs_h_close(leaf); + if (subdir) + glfs_h_close(subdir); + if (subleaf) + glfs_h_close(subleaf); + if (parent) + glfs_h_close(parent); + + return; +} + +void +test_h_getsetattrs(void) +{ + char *my_dir = "attrdir"; + char *my_file = "attrfile.txt"; + struct glfs_object *parent = NULL, *leaf = NULL, *dir = NULL; + struct stat sb, retsb; + int ret, valid; + struct timespec timestamp; + + printf("glfs_h_getattrs and setattrs tests: In Progress\n"); + + /* Prepare tests */ + parent = glfs_h_lookupat(fs, NULL, full_parent_name, &sb, 0); + if (parent == NULL) { + fprintf(stderr, + "glfs_h_lookupat: error on lookup of %s: from (%p),%s\n", + full_parent_name, NULL, strerror(errno)); + printf("glfs_h_lookupat tests: FAILED\n"); + goto out; + } + peek_stat(&sb); + + dir = glfs_h_mkdir(fs, parent, my_dir, 0755, &sb); + if (dir == NULL) { + fprintf(stderr, "glfs_h_mkdir: error creating %s: from (%p),%s\n", + my_dir, parent, strerror(errno)); + printf("glfs_h_unlink tests: FAILED\n"); + goto out; + } + peek_stat(&sb); + + leaf = glfs_h_creat(fs, dir, my_file, O_CREAT, 0644, &sb); + if (leaf == NULL) { + fprintf(stderr, "glfs_h_creat: error creating %s: from (%p),%s\n", + my_file, dir, strerror(errno)); + printf("glfs_h_unlink tests: FAILED\n"); + goto out; + } + peek_stat(&sb); + + ret = glfs_h_getattrs(fs, dir, &retsb); + if (ret != 0) { + fprintf(stderr, "glfs_h_getattrs: error %s: from (%p),%s\n", my_dir, + dir, strerror(errno)); + printf("glfs_h_getattrs and setattrs tests: FAILED\n"); + goto out; + } + peek_stat(&retsb); + /* TODO: Compare stat information */ + + retsb.st_mode = 00666; + retsb.st_uid = 1000; + retsb.st_gid = 1001; + ret = clock_gettime(CLOCK_REALTIME, ×tamp); + if (ret != 0) { + fprintf(stderr, "clock_gettime: error %s\n", strerror(errno)); + printf("glfs_h_getattrs and setattrs tests: FAILED\n"); + goto out; + } + retsb.st_atim = timestamp; + retsb.st_mtim = timestamp; + valid = GFAPI_SET_ATTR_MODE | GFAPI_SET_ATTR_UID | GFAPI_SET_ATTR_GID | + GFAPI_SET_ATTR_ATIME | GFAPI_SET_ATTR_MTIME; + peek_stat(&retsb); + + ret = glfs_h_setattrs(fs, dir, &retsb, valid); + if (ret != 0) { + fprintf(stderr, "glfs_h_setattrs: error %s: from (%p),%s\n", my_dir, + dir, strerror(errno)); + printf("glfs_h_getattrs and setattrs tests: FAILED\n"); + goto out; + } + + memset(&retsb, 0, sizeof(struct stat)); + ret = glfs_h_stat(fs, dir, &retsb); + if (ret != 0) { + fprintf(stderr, "glfs_h_stat: error %s: from (%p),%s\n", my_dir, dir, + strerror(errno)); + printf("glfs_h_getattrs and setattrs tests: FAILED\n"); + goto out; + } + peek_stat(&retsb); + + printf("glfs_h_getattrs and setattrs tests: PASSED\n"); +out: + if (parent) + glfs_h_close(parent); + if (leaf) + glfs_h_close(leaf); + if (dir) + glfs_h_close(dir); + + return; +} + +void +test_h_truncate(void) +{ + char *my_dir = "truncatedir"; + char *my_file = "file.txt"; + struct glfs_object *root = NULL, *parent = NULL, *leaf = NULL; + struct stat sb; + glfs_fd_t *fd = NULL; + char buf[32]; + off_t offset = 0; + int ret = 0; + + printf("glfs_h_truncate tests: In Progress\n"); + + /* Prepare tests */ + root = glfs_h_lookupat(fs, NULL, full_parent_name, &sb, 0); + if (root == NULL) { + fprintf(stderr, + "glfs_h_lookupat: error on lookup of %s: from (%p),%s\n", + full_parent_name, NULL, strerror(errno)); + printf("glfs_h_truncate tests: FAILED\n"); + goto out; + } + peek_stat(&sb); + + parent = glfs_h_mkdir(fs, root, my_dir, 0755, &sb); + if (parent == NULL) { + fprintf(stderr, "glfs_h_mkdir: error creating %s: from (%p),%s\n", + my_dir, root, strerror(errno)); + printf("glfs_h_truncate tests: FAILED\n"); + goto out; + } + peek_stat(&sb); + + leaf = glfs_h_creat(fs, parent, my_file, O_CREAT, 0644, &sb); + if (leaf == NULL) { + fprintf(stderr, "glfs_h_creat: error creating %s: from (%p),%s\n", + my_file, parent, strerror(errno)); + printf("glfs_h_truncate tests: FAILED\n"); + goto out; + } + peek_stat(&sb); + + fd = glfs_h_open(fs, leaf, O_RDWR); + if (fd == NULL) { + fprintf(stderr, "glfs_h_open: error on open of %s: %s\n", my_file, + strerror(errno)); + printf("glfs_h_truncate tests: FAILED\n"); + goto out; + } + + memcpy(buf, "abcdefghijklmnopqrstuvwxyz012345", 32); + ret = glfs_write(fd, buf, 32, 0); + + /* run tests */ + /* truncate lower */ + offset = 30; + ret = glfs_h_truncate(fs, leaf, offset); + if (ret != 0) { + fprintf(stderr, "glfs_h_truncate: error creating %s: from (%p),%s\n", + my_file, parent, strerror(errno)); + printf("glfs_h_truncate tests: FAILED\n"); + goto out; + } + ret = glfs_h_getattrs(fs, leaf, &sb); + if (ret != 0) { + fprintf(stderr, "glfs_h_getattrs: error for %s (%p),%s\n", my_file, + leaf, strerror(errno)); + printf("glfs_h_truncate tests: FAILED\n"); + goto out; + } + if (sb.st_size != offset) { + fprintf(stderr, "glfs_h_truncate: post size mismatch\n"); + printf("glfs_h_truncate tests: FAILED\n"); + goto out; + } + + /* truncate higher */ + offset = 32; + ret = glfs_h_truncate(fs, leaf, offset); + if (ret != 0) { + fprintf(stderr, "glfs_h_truncate: error creating %s: from (%p),%s\n", + my_file, parent, strerror(errno)); + printf("glfs_h_truncate tests: FAILED\n"); + goto out; + } + ret = glfs_h_getattrs(fs, leaf, &sb); + if (ret != 0) { + fprintf(stderr, "glfs_h_getattrs: error for %s (%p),%s\n", my_file, + leaf, strerror(errno)); + printf("glfs_h_truncate tests: FAILED\n"); + goto out; + } + if (sb.st_size != offset) { + fprintf(stderr, "glfs_h_truncate: post size mismatch\n"); + printf("glfs_h_truncate tests: FAILED\n"); + goto out; + } + + /* truncate equal */ + offset = 30; + ret = glfs_h_truncate(fs, leaf, offset); + if (ret != 0) { + fprintf(stderr, "glfs_h_truncate: error creating %s: from (%p),%s\n", + my_file, parent, strerror(errno)); + printf("glfs_h_truncate tests: FAILED\n"); + goto out; + } + ret = glfs_h_getattrs(fs, leaf, &sb); + if (ret != 0) { + fprintf(stderr, "glfs_h_getattrs: error for %s (%p),%s\n", my_file, + leaf, strerror(errno)); + printf("glfs_h_truncate tests: FAILED\n"); + goto out; + } + if (sb.st_size != offset) { + fprintf(stderr, "glfs_h_truncate: post size mismatch\n"); + printf("glfs_h_truncate tests: FAILED\n"); + goto out; + } + + printf("glfs_h_truncate tests: PASSED\n"); +out: + if (fd) + glfs_close(fd); + if (root) + glfs_h_close(root); + if (parent) + glfs_h_close(parent); + if (leaf) + glfs_h_close(leaf); + + return; +} + +void +test_h_links(void) +{ + char *my_dir = "linkdir"; + char *my_file = "file.txt"; + char *my_symlnk = "slnk.txt"; + char *my_lnk = "lnk.txt"; + char *linksrc_dir = "dir1"; + char *linktgt_dir = "dir2"; + struct glfs_object *root = NULL, *parent = NULL, *leaf = NULL, + *dirsrc = NULL, *dirtgt = NULL, *dleaf = NULL; + struct glfs_object *ln1 = NULL; + struct stat sb; + int ret; + char *buf = NULL; + + printf("glfs_h_link(s) tests: In Progress\n"); + + /* Prepare tests */ + root = glfs_h_lookupat(fs, NULL, full_parent_name, &sb, 0); + if (root == NULL) { + fprintf(stderr, + "glfs_h_lookupat: error on lookup of %s: from (%p),%s\n", + full_parent_name, NULL, strerror(errno)); + printf("glfs_h_link(s) tests: FAILED\n"); + goto out; + } + peek_stat(&sb); + + parent = glfs_h_mkdir(fs, root, my_dir, 0755, &sb); + if (parent == NULL) { + fprintf(stderr, "glfs_h_mkdir: error creating %s: from (%p),%s\n", + my_dir, root, strerror(errno)); + printf("glfs_h_link(s) tests: FAILED\n"); + goto out; + } + peek_stat(&sb); + + leaf = glfs_h_creat(fs, parent, my_file, O_CREAT, 0644, &sb); + if (leaf == NULL) { + fprintf(stderr, "glfs_h_creat: error creating %s: from (%p),%s\n", + my_file, parent, strerror(errno)); + printf("glfs_h_link(s) tests: FAILED\n"); + goto out; + } + peek_stat(&sb); + + dirsrc = glfs_h_mkdir(fs, parent, linksrc_dir, 0755, &sb); + if (dirsrc == NULL) { + fprintf(stderr, "glfs_h_mkdir: error creating %s: from (%p),%s\n", + linksrc_dir, parent, strerror(errno)); + printf("glfs_h_link(s) tests: FAILED\n"); + goto out; + } + peek_stat(&sb); + + dirtgt = glfs_h_mkdir(fs, parent, linktgt_dir, 0755, &sb); + if (dirtgt == NULL) { + fprintf(stderr, "glfs_h_mkdir: error creating %s: from (%p),%s\n", + linktgt_dir, parent, strerror(errno)); + printf("glfs_h_link(s) tests: FAILED\n"); + goto out; + } + peek_stat(&sb); + + dleaf = glfs_h_creat(fs, dirsrc, my_file, O_CREAT, 0644, &sb); + if (dleaf == NULL) { + fprintf(stderr, "glfs_h_creat: error creating %s: from (%p),%s\n", + my_file, dirsrc, strerror(errno)); + printf("glfs_h_link(s) tests: FAILED\n"); + goto out; + } + peek_stat(&sb); + + /* run tests */ + /* sym link: /testdir/linkdir/file.txt to ./slnk.txt */ + ln1 = glfs_h_symlink(fs, parent, my_symlnk, "./file.txt", &sb); + if (ln1 == NULL) { + fprintf(stderr, "glfs_h_symlink: error creating %s: from (%p),%s\n", + my_symlnk, parent, strerror(errno)); + printf("glfs_h_link(s) tests: FAILED\n"); + goto out; + } + peek_stat(&sb); + + buf = calloc(1024, sizeof(char)); + if (buf == NULL) { + fprintf(stderr, "Error allocating memory\n"); + printf("glfs_h_link(s) tests: FAILED\n"); + goto out; + } + + ret = glfs_h_readlink(fs, ln1, buf, 1024); + if (ret <= 0) { + fprintf(stderr, "glfs_h_readlink: error reading %s: from (%p),%s\n", + my_symlnk, ln1, strerror(errno)); + printf("glfs_h_link(s) tests: FAILED\n"); + goto out; + } + if (!(strncmp(buf, my_symlnk, strlen(my_symlnk)))) { + fprintf(stderr, + "glfs_h_readlink: error mismatch in link name: actual %s: " + "retrieved %s\n", + my_symlnk, buf); + printf("glfs_h_link(s) tests: FAILED\n"); + goto out; + } + + /* link: /testdir/linkdir/file.txt to ./lnk.txt */ + ret = glfs_h_link(fs, leaf, parent, my_lnk); + if (ret != 0) { + fprintf(stderr, "glfs_h_link: error creating %s: from (%p),%s\n", + my_lnk, parent, strerror(errno)); + printf("glfs_h_link(s) tests: FAILED\n"); + goto out; + } + /* TODO: Should write content to a file and read from the link */ + + /* link: /testdir/linkdir/dir1/file.txt to ../dir2/slnk.txt */ + ret = glfs_h_link(fs, dleaf, dirtgt, my_lnk); + if (ret != 0) { + fprintf(stderr, "glfs_h_link: error creating %s: from (%p),%s\n", + my_lnk, dirtgt, strerror(errno)); + printf("glfs_h_link(s) tests: FAILED\n"); + goto out; + } + /* TODO: Should write content to a file and read from the link */ + + printf("glfs_h_link(s) tests: PASSED\n"); + +out: + if (root) + glfs_h_close(root); + if (parent) + glfs_h_close(parent); + if (leaf) + glfs_h_close(leaf); + if (dirsrc) + glfs_h_close(dirsrc); + if (dirtgt) + glfs_h_close(dirtgt); + if (dleaf) + glfs_h_close(dleaf); + if (ln1) + glfs_h_close(ln1); + if (buf) + free(buf); + + return; +} + +void +test_h_rename(void) +{ + char *my_dir = "renamedir"; + char *my_file = "file.txt"; + char *src_dir = "dir1"; + char *tgt_dir = "dir2"; + struct glfs_object *root = NULL, *parent = NULL, *leaf = NULL, + *dirsrc = NULL, *dirtgt = NULL, *dleaf = NULL; + struct stat sb; + int ret; + + printf("glfs_h_rename tests: In Progress\n"); + + /* Prepare tests */ + root = glfs_h_lookupat(fs, NULL, full_parent_name, &sb, 0); + if (root == NULL) { + fprintf(stderr, + "glfs_h_lookupat: error on lookup of %s: from (%p),%s\n", + full_parent_name, NULL, strerror(errno)); + printf("glfs_h_rename tests: FAILED\n"); + goto out; + } + peek_stat(&sb); + + parent = glfs_h_mkdir(fs, root, my_dir, 0755, &sb); + if (parent == NULL) { + fprintf(stderr, "glfs_h_mkdir: error creating %s: from (%p),%s\n", + my_dir, root, strerror(errno)); + printf("glfs_h_rename tests: FAILED\n"); + goto out; + } + peek_stat(&sb); + + leaf = glfs_h_creat(fs, parent, my_file, O_CREAT, 0644, &sb); + if (leaf == NULL) { + fprintf(stderr, "glfs_h_creat: error creating %s: from (%p),%s\n", + my_file, parent, strerror(errno)); + printf("glfs_h_rename tests: FAILED\n"); + goto out; + } + peek_stat(&sb); + + dirsrc = glfs_h_mkdir(fs, parent, src_dir, 0755, &sb); + if (dirsrc == NULL) { + fprintf(stderr, "glfs_h_mkdir: error creating %s: from (%p),%s\n", + src_dir, parent, strerror(errno)); + printf("glfs_h_rename tests: FAILED\n"); + goto out; + } + peek_stat(&sb); + + dirtgt = glfs_h_mkdir(fs, parent, tgt_dir, 0755, &sb); + if (dirtgt == NULL) { + fprintf(stderr, "glfs_h_mkdir: error creating %s: from (%p),%s\n", + tgt_dir, parent, strerror(errno)); + printf("glfs_h_rename tests: FAILED\n"); + goto out; + } + peek_stat(&sb); + + dleaf = glfs_h_creat(fs, dirsrc, my_file, O_CREAT, 0644, &sb); + if (dleaf == NULL) { + fprintf(stderr, "glfs_h_creat: error creating %s: from (%p),%s\n", + my_file, dirsrc, strerror(errno)); + printf("glfs_h_rename tests: FAILED\n"); + goto out; + } + peek_stat(&sb); + + /* run tests */ + /* Rename file.txt -> file1.txt */ + ret = glfs_h_rename(fs, parent, "file.txt", parent, "file1.txt"); + if (ret != 0) { + fprintf(stderr, "glfs_h_rename: error renaming %s to %s (%s)\n", + "file.txt", "file1.txt", strerror(errno)); + printf("glfs_h_rename tests: FAILED\n"); + goto out; + } + + /* rename dir1/file.txt -> file.txt */ + ret = glfs_h_rename(fs, dirsrc, "file.txt", parent, "file.txt"); + if (ret != 0) { + fprintf(stderr, "glfs_h_rename: error renaming %s/%s to %s (%s)\n", + src_dir, "file.txt", "file.txt", strerror(errno)); + printf("glfs_h_rename tests: FAILED\n"); + goto out; + } + + /* rename file1.txt -> file.txt (exists) */ + ret = glfs_h_rename(fs, parent, "file1.txt", parent, "file.txt"); + if (ret != 0) { + fprintf(stderr, "glfs_h_rename: error renaming %s to %s (%s)\n", + "file.txt", "file.txt", strerror(errno)); + printf("glfs_h_rename tests: FAILED\n"); + goto out; + } + + /* rename dir1 -> dir3 */ + ret = glfs_h_rename(fs, parent, "dir1", parent, "dir3"); + if (ret != 0) { + fprintf(stderr, "glfs_h_rename: error renaming %s to %s (%s)\n", "dir1", + "dir3", strerror(errno)); + printf("glfs_h_rename tests: FAILED\n"); + goto out; + } + + /* rename dir2 ->dir3 (exists) */ + ret = glfs_h_rename(fs, parent, "dir2", parent, "dir3"); + if (ret != 0) { + fprintf(stderr, "glfs_h_rename: error renaming %s to %s (%s)\n", "dir2", + "dir3", strerror(errno)); + printf("glfs_h_rename tests: FAILED\n"); + goto out; + } + + /* rename file.txt -> dir3 (fail) */ + ret = glfs_h_rename(fs, parent, "file.txt", parent, "dir3"); + if (ret == 0) { + fprintf(stderr, "glfs_h_rename: NO error renaming %s to %s (%s)\n", + "file.txt", "dir3", strerror(errno)); + printf("glfs_h_rename tests: FAILED\n"); + goto out; + } + + /* rename dir3 -> file.txt (fail) */ + ret = glfs_h_rename(fs, parent, "dir3", parent, "file.txt"); + if (ret == 0) { + fprintf(stderr, "glfs_h_rename: NO error renaming %s to %s (%s)\n", + "dir3", "file.txt", strerror(errno)); + printf("glfs_h_rename tests: FAILED\n"); + goto out; + } + + printf("glfs_h_rename tests: PASSED\n"); + +out: + if (root) + glfs_h_close(root); + if (parent) + glfs_h_close(parent); + if (leaf) + glfs_h_close(leaf); + if (dirsrc) + glfs_h_close(dirsrc); + if (dirtgt) + glfs_h_close(dirtgt); + if (dleaf) + glfs_h_close(dleaf); + + return; +} + +void +assimilatetime(struct timespec *ts, struct timespec ts_st, + struct timespec ts_ed) +{ + if ((ts_ed.tv_nsec - ts_st.tv_nsec) < 0) { + ts->tv_sec += ts_ed.tv_sec - ts_st.tv_sec - 1; + ts->tv_nsec += 1000000000 + ts_ed.tv_nsec - ts_st.tv_nsec; + } else { + ts->tv_sec += ts_ed.tv_sec - ts_st.tv_sec; + ts->tv_nsec += ts_ed.tv_nsec - ts_st.tv_nsec; + } + + if (ts->tv_nsec > 1000000000) { + ts->tv_nsec = ts->tv_nsec - 1000000000; + ts->tv_sec += 1; + } + + return; +} + +#define MAX_FILES_CREATE 10 +#define MAXPATHNAME 512 +void +test_h_performance(void) +{ + char *my_dir = "perftest", *full_dir_path = "/testdir/perftest"; + char *my_file = "file_", my_file_name[MAXPATHNAME]; + struct glfs_object *parent = NULL, *leaf = NULL, *dir = NULL; + struct stat sb; + int ret, i; + struct glfs_fd *fd; + struct timespec c_ts = {0, 0}, c_ts_st, c_ts_ed; + struct timespec o_ts = {0, 0}, o_ts_st, o_ts_ed; + + printf("glfs_h_performance tests: In Progress\n"); + + /* Prepare tests */ + parent = glfs_h_lookupat(fs, NULL, full_parent_name, &sb, 0); + if (parent == NULL) { + fprintf(stderr, + "glfs_h_lookupat: error on lookup of %s: from (%p),%s\n", + full_parent_name, NULL, strerror(errno)); + printf("glfs_h_performance tests: FAILED\n"); + goto out; + } + + dir = glfs_h_mkdir(fs, parent, my_dir, 0755, &sb); + if (dir == NULL) { + fprintf(stderr, "glfs_h_mkdir: error creating %s: from (%p),%s\n", + my_dir, parent, strerror(errno)); + printf("glfs_h_performance tests: FAILED\n"); + goto out; + } + peek_stat(&sb); + + /* create performance */ + ret = clock_gettime(CLOCK_REALTIME, &o_ts_st); + if (ret != 0) { + fprintf(stderr, "clock_gettime: error %s\n", strerror(errno)); + printf("glfs_h_getattrs and setattrs tests: FAILED\n"); + goto out; + } + + for (i = 0; i < MAX_FILES_CREATE; i++) { + sprintf(my_file_name, "%s%d", my_file, i); + + ret = clock_gettime(CLOCK_REALTIME, &c_ts_st); + if (ret != 0) { + fprintf(stderr, "clock_gettime: error %s\n", strerror(errno)); + printf("glfs_h_getattrs and setattrs tests: FAILED\n"); + goto out; + } + + leaf = glfs_h_lookupat(fs, dir, my_file_name, &sb, 0); + if (leaf != NULL) { + fprintf(stderr, "glfs_h_lookup: exists %s\n", my_file_name); + printf("glfs_h_performance tests: FAILED\n"); + goto out; + } + + leaf = glfs_h_creat(fs, dir, my_file_name, O_CREAT, 0644, &sb); + if (leaf == NULL) { + fprintf(stderr, "glfs_h_creat: error creating %s: from (%p),%s\n", + my_file, dir, strerror(errno)); + printf("glfs_h_performance tests: FAILED\n"); + goto out; + } + + ret = clock_gettime(CLOCK_REALTIME, &c_ts_ed); + if (ret != 0) { + fprintf(stderr, "clock_gettime: error %s\n", strerror(errno)); + printf("glfs_h_getattrs and setattrs tests: FAILED\n"); + goto out; + } + + assimilatetime(&c_ts, c_ts_st, c_ts_ed); + glfs_h_close(leaf); + leaf = NULL; + } + + ret = clock_gettime(CLOCK_REALTIME, &o_ts_ed); + if (ret != 0) { + fprintf(stderr, "clock_gettime: error %s\n", strerror(errno)); + printf("glfs_h_getattrs and setattrs tests: FAILED\n"); + goto out; + } + + assimilatetime(&o_ts, o_ts_st, o_ts_ed); + + printf("Creation performance (handle based):\n\t# empty files:%d\n", + MAX_FILES_CREATE); + printf("\tOverall time:\n\t\tSecs:%ld\n\t\tnSecs:%ld\n", o_ts.tv_sec, + o_ts.tv_nsec); + printf("\tcreate call time time:\n\t\tSecs:%ld\n\t\tnSecs:%ld\n", + c_ts.tv_sec, c_ts.tv_nsec); + + /* create using path */ + c_ts.tv_sec = o_ts.tv_sec = 0; + c_ts.tv_nsec = o_ts.tv_nsec = 0; + + sprintf(my_file_name, "%s1", full_dir_path); + ret = glfs_mkdir(fs, my_file_name, 0755); + if (ret != 0) { + fprintf(stderr, "glfs_mkdir: error creating %s: from (%p),%s\n", my_dir, + parent, strerror(errno)); + printf("glfs_h_performance tests: FAILED\n"); + goto out; + } + peek_stat(&sb); + + ret = clock_gettime(CLOCK_REALTIME, &o_ts_st); + if (ret != 0) { + fprintf(stderr, "clock_gettime: error %s\n", strerror(errno)); + printf("glfs_h_getattrs and setattrs tests: FAILED\n"); + goto out; + } + + for (i = 0; i < MAX_FILES_CREATE; i++) { + sprintf(my_file_name, "%s1/%sn%d", full_dir_path, my_file, i); + + ret = clock_gettime(CLOCK_REALTIME, &c_ts_st); + if (ret != 0) { + fprintf(stderr, "clock_gettime: error %s\n", strerror(errno)); + printf("glfs_h_getattrs and setattrs tests: FAILED\n"); + goto out; + } + + ret = glfs_stat(fs, my_file_name, &sb); + if (ret == 0) { + fprintf(stderr, "glfs_stat: exists %s\n", my_file_name); + printf("glfs_h_performance tests: FAILED\n"); + goto out; + } + + fd = glfs_creat(fs, my_file_name, O_CREAT, 0644); + if (fd == NULL) { + fprintf(stderr, "glfs_creat: error creating %s: from (%p),%s\n", + my_file, dir, strerror(errno)); + printf("glfs_h_performance tests: FAILED\n"); + goto out; + } + + ret = clock_gettime(CLOCK_REALTIME, &c_ts_ed); + if (ret != 0) { + fprintf(stderr, "clock_gettime: error %s\n", strerror(errno)); + printf("glfs_h_getattrs and setattrs tests: FAILED\n"); + goto out; + } + + assimilatetime(&c_ts, c_ts_st, c_ts_ed); + glfs_close(fd); + } + + ret = clock_gettime(CLOCK_REALTIME, &o_ts_ed); + if (ret != 0) { + fprintf(stderr, "clock_gettime: error %s\n", strerror(errno)); + printf("glfs_h_getattrs and setattrs tests: FAILED\n"); + goto out; + } + + assimilatetime(&o_ts, o_ts_st, o_ts_ed); + + printf("Creation performance (path based):\n\t# empty files:%d\n", + MAX_FILES_CREATE); + printf("\tOverall time:\n\t\tSecs:%ld\n\t\tnSecs:%ld\n", o_ts.tv_sec, + o_ts.tv_nsec); + printf("\tcreate call time time:\n\t\tSecs:%ld\n\t\tnSecs:%ld\n", + c_ts.tv_sec, c_ts.tv_nsec); +out: + return; +} + +int +test_handleops(int argc, char *argv[]) +{ + int ret = 0; + glfs_fd_t *fd = NULL; + struct stat sb = { + 0, + }; + struct glfs_object *root = NULL, *parent = NULL, *leaf = NULL, *tmp = NULL; + char readbuf[32], writebuf[32]; + unsigned char leaf_handle[GFAPI_HANDLE_LENGTH]; + + char *full_leaf_name = "/testdir/testfile.txt", *leaf_name = "testfile.txt", + *relative_leaf_name = "testdir/testfile.txt"; + char *leaf_name1 = "testfile1.txt"; + char *full_newparent_name = "/testdir/dir1", *newparent_name = "dir1"; + char *full_newnod_name = "/testdir/nod1", *newnod_name = "nod1"; + + /* Initialize test area */ + ret = glfs_mkdir(fs, full_parent_name, 0755); + if (ret != 0 && errno != EEXIST) { + fprintf(stderr, "%s: (%p) %s\n", full_parent_name, fd, strerror(errno)); + printf("Test initialization failed on volume %s\n", argv[1]); + goto out; + } else if (ret != 0) { + printf("Found test directory %s to be existing\n", full_parent_name); + printf("Cleanup test directory and restart tests\n"); + goto out; + } + + fd = glfs_creat(fs, full_leaf_name, O_CREAT, 0644); + if (fd == NULL) { + fprintf(stderr, "%s: (%p) %s\n", full_leaf_name, fd, strerror(errno)); + printf("Test initialization failed on volume %s\n", argv[1]); + goto out; + } + glfs_close(fd); + + printf("Initialized the test area, within volume %s\n", argv[1]); + + /* Handle based APIs test area */ + + /* glfs_lookupat test */ + printf("glfs_h_lookupat tests: In Progress\n"); + /* start at root of the volume */ + root = glfs_h_lookupat(fs, NULL, "/", &sb, 0); + if (root == NULL) { + fprintf(stderr, + "glfs_h_lookupat: error on lookup of %s: from (%p),%s\n", "/", + NULL, strerror(errno)); + printf("glfs_h_lookupat tests: FAILED\n"); + goto out; + } + peek_stat(&sb); + + /* lookup a parent within root */ + parent = glfs_h_lookupat(fs, root, parent_name, &sb, 0); + if (parent == NULL) { + fprintf(stderr, + "glfs_h_lookupat: error on lookup of %s: from (%p),%s\n", + parent_name, root, strerror(errno)); + printf("glfs_h_lookupat tests: FAILED\n"); + goto out; + } + peek_stat(&sb); + + /* lookup a leaf/child within the parent */ + leaf = glfs_h_lookupat(fs, parent, leaf_name, &sb, 0); + if (leaf == NULL) { + fprintf(stderr, + "glfs_h_lookupat: error on lookup of %s: from (%p),%s\n", + leaf_name, parent, strerror(errno)); + printf("glfs_h_lookupat tests: FAILED\n"); + goto out; + } + peek_stat(&sb); + + /* reset */ + glfs_h_close(root); + root = NULL; + glfs_h_close(leaf); + leaf = NULL; + glfs_h_close(parent); + parent = NULL; + + /* check absolute paths */ + root = glfs_h_lookupat(fs, NULL, "/", &sb, 0); + if (root == NULL) { + fprintf(stderr, + "glfs_h_lookupat: error on lookup of %s: from (%p),%s\n", "/", + NULL, strerror(errno)); + printf("glfs_h_lookupat tests: FAILED\n"); + goto out; + } + peek_stat(&sb); + + parent = glfs_h_lookupat(fs, NULL, full_parent_name, &sb, 0); + if (parent == NULL) { + fprintf(stderr, + "glfs_h_lookupat: error on lookup of %s: from (%p),%s\n", + full_parent_name, root, strerror(errno)); + printf("glfs_h_lookupat tests: FAILED\n"); + goto out; + } + peek_stat(&sb); + + leaf = glfs_h_lookupat(fs, NULL, full_leaf_name, &sb, 0); + if (leaf == NULL) { + fprintf(stderr, + "glfs_h_lookupat: error on lookup of %s: from (%p),%s\n", + full_leaf_name, parent, strerror(errno)); + printf("glfs_h_lookupat tests: FAILED\n"); + goto out; + } + peek_stat(&sb); + + /* reset */ + glfs_h_close(leaf); + leaf = NULL; + + /* check multiple component paths */ + leaf = glfs_h_lookupat(fs, root, relative_leaf_name, &sb, 0); + if (leaf == NULL) { + fprintf(stderr, + "glfs_h_lookupat: error on lookup of %s: from (%p),%s\n", + relative_leaf_name, parent, strerror(errno)); + goto out; + } + peek_stat(&sb); + + /* reset */ + glfs_h_close(root); + root = NULL; + glfs_h_close(parent); + parent = NULL; + + /* check symlinks in path */ + + /* TODO: -ve test cases */ + /* parent invalid + * path invalid + * path does not exist after some components + * no parent, but relative path + * parent and full path? -ve? + */ + + printf("glfs_h_lookupat tests: PASSED\n"); + + /* glfs_openat test */ + printf("glfs_h_open tests: In Progress\n"); + fd = glfs_h_open(fs, leaf, O_RDWR); + if (fd == NULL) { + fprintf(stderr, "glfs_h_open: error on open of %s: %s\n", + full_leaf_name, strerror(errno)); + printf("glfs_h_open tests: FAILED\n"); + goto out; + } + + /* test read/write based on fd */ + memcpy(writebuf, "abcdefghijklmnopqrstuvwxyz012345", 32); + ret = glfs_write(fd, writebuf, 32, 0); + + glfs_lseek(fd, 10, SEEK_SET); + + ret = glfs_read(fd, readbuf, 32, 0); + if (memcmp(readbuf, writebuf, 32)) { + printf("Failed to read what I wrote: %s %s\n", readbuf, writebuf); + glfs_close(fd); + printf("glfs_h_open tests: FAILED\n"); + goto out; + } + + glfs_h_close(leaf); + leaf = NULL; + glfs_close(fd); + + printf("glfs_h_open tests: PASSED\n"); + + /* Create tests */ + printf("glfs_h_creat tests: In Progress\n"); + parent = glfs_h_lookupat(fs, NULL, full_parent_name, &sb, 0); + if (parent == NULL) { + fprintf(stderr, + "glfs_h_lookupat: error on lookup of %s: from (%p),%s\n", + full_parent_name, root, strerror(errno)); + printf("glfs_h_creat tests: FAILED\n"); + goto out; + } + peek_stat(&sb); + + leaf = glfs_h_creat(fs, parent, leaf_name1, O_CREAT, 0644, &sb); + if (leaf == NULL) { + fprintf(stderr, "glfs_h_creat: error on create of %s: from (%p),%s\n", + leaf_name1, parent, strerror(errno)); + printf("glfs_h_creat tests: FAILED\n"); + goto out; + } + peek_stat(&sb); + + glfs_h_close(leaf); + leaf = NULL; + + leaf = glfs_h_creat(fs, parent, leaf_name1, O_CREAT | O_EXCL, 0644, &sb); + if (leaf != NULL || errno != EEXIST) { + fprintf(stderr, + "glfs_h_creat: existing file, leaf = (%p), errno = %s\n", leaf, + strerror(errno)); + printf("glfs_h_creat tests: FAILED\n"); + if (leaf != NULL) { + glfs_h_close(leaf); + leaf = NULL; + } + } + + tmp = glfs_h_creat(fs, root, parent_name, O_CREAT, 0644, &sb); + if (tmp != NULL || !(errno == EISDIR || errno == EINVAL)) { + fprintf(stderr, "glfs_h_creat: dir create, tmp = (%p), errno = %s\n", + leaf, strerror(errno)); + printf("glfs_h_creat tests: FAILED\n"); + if (tmp != NULL) { + glfs_h_close(tmp); + tmp = NULL; + } + } + + /* TODO: Other combinations and -ve cases as applicable */ + printf("glfs_h_creat tests: PASSED\n"); + + /* extract handle and create from handle test */ + printf( + "glfs_h_extract_handle and glfs_h_create_from_handle tests: In " + "Progress\n"); + /* TODO: Change the lookup to create below for a GIFD recovery failure, + * that needs to be fixed */ + leaf = glfs_h_lookupat(fs, parent, leaf_name1, &sb, 0); + if (leaf == NULL) { + fprintf(stderr, + "glfs_h_lookupat: error on lookup of %s: from (%p),%s\n", + leaf_name1, parent, strerror(errno)); + printf("glfs_h_extract_handle tests: FAILED\n"); + goto out; + } + peek_stat(&sb); + + ret = glfs_h_extract_handle(leaf, leaf_handle, GFAPI_HANDLE_LENGTH); + if (ret < 0) { + fprintf(stderr, + "glfs_h_extract_handle: error extracting handle of %s: %s\n", + full_leaf_name, strerror(errno)); + printf("glfs_h_extract_handle tests: FAILED\n"); + goto out; + } + peek_handle(leaf_handle); + + glfs_h_close(leaf); + leaf = NULL; + + leaf = glfs_h_create_from_handle(fs, leaf_handle, GFAPI_HANDLE_LENGTH, &sb); + if (leaf == NULL) { + fprintf( + stderr, + "glfs_h_create_from_handle: error on create of %s: from (%p),%s\n", + leaf_name1, leaf_handle, strerror(errno)); + printf("glfs_h_create_from_handle tests: FAILED\n"); + goto out; + } + peek_stat(&sb); + + fd = glfs_h_open(fs, leaf, O_RDWR); + if (fd == NULL) { + fprintf(stderr, "glfs_h_open: error on open of %s: %s\n", + full_leaf_name, strerror(errno)); + printf("glfs_h_create_from_handle tests: FAILED\n"); + goto out; + } + + /* test read/write based on fd */ + memcpy(writebuf, "abcdefghijklmnopqrstuvwxyz012345", 32); + ret = glfs_write(fd, writebuf, 32, 0); + + glfs_lseek(fd, 0, SEEK_SET); + + ret = glfs_read(fd, readbuf, 32, 0); + if (memcmp(readbuf, writebuf, 32)) { + printf("Failed to read what I wrote: %s %s\n", writebuf, writebuf); + printf("glfs_h_create_from_handle tests: FAILED\n"); + glfs_close(fd); + goto out; + } + + glfs_close(fd); + glfs_h_close(leaf); + leaf = NULL; + glfs_h_close(parent); + parent = NULL; + + printf( + "glfs_h_extract_handle and glfs_h_create_from_handle tests: PASSED\n"); + + /* Mkdir tests */ + printf("glfs_h_mkdir tests: In Progress\n"); + + ret = glfs_rmdir(fs, full_newparent_name); + if (ret && errno != ENOENT) { + fprintf(stderr, "glfs_rmdir: Failed for %s: %s\n", full_newparent_name, + strerror(errno)); + printf("glfs_h_mkdir tests: FAILED\n"); + goto out; + } + + parent = glfs_h_lookupat(fs, NULL, full_parent_name, &sb, 0); + if (parent == NULL) { + fprintf(stderr, + "glfs_h_lookupat: error on lookup of %s: from (%p),%s\n", + full_parent_name, root, strerror(errno)); + printf("glfs_h_mkdir tests: FAILED\n"); + goto out; + } + peek_stat(&sb); + + leaf = glfs_h_mkdir(fs, parent, newparent_name, 0755, &sb); + if (leaf == NULL) { + fprintf(stderr, "glfs_h_mkdir: error on mkdir of %s: from (%p),%s\n", + newparent_name, parent, strerror(errno)); + printf("glfs_h_mkdir tests: FAILED\n"); + goto out; + } + peek_stat(&sb); + + glfs_h_close(leaf); + leaf = NULL; + + leaf = glfs_h_mkdir(fs, parent, newparent_name, 0755, &sb); + if (leaf != NULL || errno != EEXIST) { + fprintf(stderr, + "glfs_h_mkdir: existing directory, leaf = (%p), errno = %s\n", + leaf, strerror(errno)); + printf("glfs_h_mkdir tests: FAILED\n"); + if (leaf != NULL) { + glfs_h_close(leaf); + leaf = NULL; + } + } + + glfs_h_close(parent); + parent = NULL; + + printf("glfs_h_mkdir tests: PASSED\n"); + + /* Mknod tests */ + printf("glfs_h_mknod tests: In Progress\n"); + ret = glfs_unlink(fs, full_newnod_name); + if (ret && errno != ENOENT) { + fprintf(stderr, "glfs_unlink: Failed for %s: %s\n", full_newnod_name, + strerror(errno)); + printf("glfs_h_mknod tests: FAILED\n"); + goto out; + } + + parent = glfs_h_lookupat(fs, NULL, full_parent_name, &sb, 0); + if (parent == NULL) { + fprintf(stderr, + "glfs_h_lookupat: error on lookup of %s: from (%p),%s\n", + full_parent_name, root, strerror(errno)); + printf("glfs_h_mknod tests: FAILED\n"); + goto out; + } + peek_stat(&sb); + + leaf = glfs_h_mknod(fs, parent, newnod_name, S_IFIFO, 0, &sb); + if (leaf == NULL) { + fprintf(stderr, "glfs_h_mkdir: error on mkdir of %s: from (%p),%s\n", + newnod_name, parent, strerror(errno)); + printf("glfs_h_mknod tests: FAILED\n"); + goto out; + } + peek_stat(&sb); + + /* TODO: create op on a FIFO node hangs, need to check and fix + tmp = glfs_h_creat (fs, parent, newnod_name, O_CREAT, 0644, &sb); + if (tmp != NULL || errno != EINVAL) { + fprintf (stderr, "glfs_h_creat: node create, tmp = (%p), errno = + %s\n", tmp, strerror (errno)); printf ("glfs_h_creat/mknod tests: + FAILED\n"); if (tmp != NULL) { glfs_h_close(tmp); tmp = NULL; + } + } */ + + glfs_h_close(leaf); + leaf = NULL; + + leaf = glfs_h_mknod(fs, parent, newnod_name, 0644, 0, &sb); + if (leaf != NULL || errno != EEXIST) { + fprintf(stderr, + "glfs_h_mknod: existing node, leaf = (%p), errno = %s\n", leaf, + strerror(errno)); + printf("glfs_h_mknod tests: FAILED\n"); + if (leaf != NULL) { + glfs_h_close(leaf); + leaf = NULL; + } + } + + glfs_h_close(parent); + parent = NULL; + + printf("glfs_h_mknod tests: PASSED\n"); + + /* unlink tests */ + test_h_unlink(); + + /* TODO: opendir tests */ + + /* getattr tests */ + test_h_getsetattrs(); + + /* TODO: setattr tests */ + + /* truncate tests */ + test_h_truncate(); + + /* link tests */ + test_h_links(); + + /* rename tests */ + test_h_rename(); + + /* performance tests */ + test_h_performance(); + + /* END: New APIs test area */ + +out: + /* Cleanup glfs handles */ + if (root) + glfs_h_close(root); + if (parent) + glfs_h_close(parent); + if (leaf) + glfs_h_close(leaf); + + return ret; +} + +int +test_write_apis(glfs_t *fs) +{ + /* Add more content here */ + /* Some apis we can get are */ + /* + 0. glfs_set_xlator_option() + + Read/Write combinations: + . glfs_{p,}readv/{p,}writev + . glfs_pread/pwrite + + tests/basic/gfapi/gfapi-async-calls-test.c + . glfs_read_async/write_async + . glfs_pread_async/pwrite_async + . glfs_readv_async/writev_async + . glfs_preadv_async/pwritev_async + + . ftruncate/ftruncate_async + . fsync/fsync_async + . fdatasync/fdatasync_async + + */ + + glfs_fd_t *fd = NULL; + char *filename = "/filename2"; + int flags = O_RDWR; + char *buf = "some bytes!"; + char writestr[TEST_STR_LEN]; + struct iovec iov = {&writestr, TEST_STR_LEN}; + int ret, i; + + for (i = 0; i < TEST_STR_LEN; i++) + writestr[i] = 0x11; + + fd = glfs_open(fs, filename, flags); + if (!fd) + fprintf(stderr, "open(%s): (%p) %s\n", filename, fd, strerror(errno)); + + ret = glfs_writev(fd, &iov, 1, flags); + if (ret < 0) { + fprintf(stderr, "writev(%s): %d (%s)\n", filename, ret, + strerror(errno)); + } + + ret = glfs_pwrite(fd, buf, 10, 4, flags, NULL, NULL); + if (ret < 0) { + fprintf(stderr, "pwrite(%s): %d (%s)\n", filename, ret, + strerror(errno)); + } + + ret = glfs_pwritev(fd, &iov, 1, 4, flags); + if (ret < 0) { + fprintf(stderr, "pwritev(%s): %d (%s)\n", filename, ret, + strerror(errno)); + } + + ret = glfs_fsync(fd, NULL, NULL); + if (ret < 0) { + fprintf(stderr, "fsync(%s): %d (%s)\n", filename, ret, strerror(errno)); + } + + glfs_close(fd); + + return 0; +} + +int +test_metadata_ops(glfs_t *fs, glfs_t *fs2) +{ + glfs_fd_t *fd = NULL; + glfs_fd_t *fd2 = NULL; + struct stat sb = { + 0, + }; + struct glfs_stat gsb = { + 0, + }; + struct statvfs sfs; + char readbuf[32]; + char writebuf[11] = "helloworld"; + + char *filename = "/filename2"; + int ret; + + ret = glfs_lstat(fs, filename, &sb); + fprintf(stderr, "lstat(%s): (%d) %s\n", filename, ret, strerror(errno)); + + fd = glfs_creat(fs, filename, O_RDWR, 0644); + if (!fd) + fprintf(stderr, "creat(%s): (%p) %s\n", filename, fd, strerror(errno)); + + fd2 = glfs_open(fs2, filename, O_RDWR); + if (!fd2) + fprintf(stderr, "open(%s): (%p) %s\n", filename, fd, strerror(errno)); + + ret = glfs_lstat(fs, filename, &sb); + if (ret) + fprintf(stderr, "lstat(%s): (%d) %s\n", filename, ret, strerror(errno)); + + ret = glfs_write(fd, writebuf, 11, 0); + if (ret < 0) { + fprintf(stderr, "writev(%s): %d (%s)\n", filename, ret, + strerror(errno)); + } + + glfs_fsync(fd, NULL, NULL); + + glfs_lseek(fd2, 5, SEEK_SET); + + ret = glfs_read(fd2, readbuf, 32, 0); + + printf("read %d, %s", ret, readbuf); + + /* get stat */ + ret = glfs_fstat(fd2, &sb); + if (ret) + fprintf(stderr, "fstat(%s): %d (%s)\n", filename, ret, strerror(errno)); + + ret = glfs_access(fs, filename, R_OK); + if (ret) + fprintf(stderr, "access(%s): %d (%s)\n", filename, ret, + strerror(errno)); + + ret = glfs_fallocate(fd2, 1024, 1024, 1024); + if (ret) + fprintf(stderr, "fallocate(%s): %d (%s)\n", filename, ret, + strerror(errno)); + + ret = glfs_discard(fd2, 1024, 512); + if (ret) + fprintf(stderr, "discard(%s): %d (%s)\n", filename, ret, + strerror(errno)); + + ret = glfs_zerofill(fd2, 2048, 1024); + if (ret) + fprintf(stderr, "zerofill(%s): %d (%s)\n", filename, ret, + strerror(errno)); + + /* set stat */ + /* TODO: got some errors, need to fix */ + ret = glfs_fsetattr(fd2, &gsb); + + glfs_close(fd); + glfs_close(fd2); + + filename = "/filename3"; + ret = glfs_mknod(fs, filename, S_IFIFO, 0); + if (ret) + fprintf(stderr, "%s: (%d) %s\n", filename, ret, strerror(errno)); + + ret = glfs_lstat(fs, filename, &sb); + if (ret) + fprintf(stderr, "%s: (%d) %s\n", filename, ret, strerror(errno)); + + ret = glfs_rename(fs, filename, "/filename4"); + if (ret) + fprintf(stderr, "rename(%s): (%d) %s\n", filename, ret, + strerror(errno)); + + ret = glfs_unlink(fs, "/filename4"); + if (ret) + fprintf(stderr, "unlink(%s): (%d) %s\n", "/filename4", ret, + strerror(errno)); + + filename = "/dirname2"; + ret = glfs_mkdir(fs, filename, 0); + if (ret) + fprintf(stderr, "%s: (%d) %s\n", filename, ret, strerror(errno)); + + ret = glfs_lstat(fs, filename, &sb); + if (ret) + fprintf(stderr, "lstat(%s): (%d) %s\n", filename, ret, strerror(errno)); + + ret = glfs_rmdir(fs, filename); + if (ret) + fprintf(stderr, "rmdir(%s): (%d) %s\n", filename, ret, strerror(errno)); +} +int +main(int argc, char *argv[]) +{ + glfs_t *fs2 = NULL; + int ret = 0; + glfs_fd_t *fd = NULL; + glfs_fd_t *fd2 = NULL; + struct stat sb = { + 0, + }; + struct glfs_stat gsb = { + 0, + }; + struct statvfs sfs; + char readbuf[32]; + char writebuf[32]; + char volumeid[64]; + + char *filename = "/filename2"; + + if ((argc < 2) || (argc > 3)) { + printf("Usage:\n\t%s <volname> <hostname>\n\t%s <volfile-path>", + argv[0], argv[0]); + return -1; + } + + if (argc == 2) { + /* Generally glfs_new() requires volume name as an argument */ + fs = glfs_new("test-only"); + if (!fs) { + fprintf(stderr, "glfs_new: returned NULL\n"); + return 1; + } + ret = glfs_set_volfile(fs, argv[1]); + if (ret) + fprintf(stderr, "glfs_set_volfile failed\n"); + } else { + fs = glfs_new(argv[1]); + if (!fs) { + fprintf(stderr, "glfs_new: returned NULL\n"); + return 1; + } + // ret = glfs_set_volfile_server (fs, "unix", "/tmp/gluster.sock", 0); + ret = glfs_set_volfile_server(fs, "tcp", argv[2], 24007); + if (ret) + fprintf(stderr, "glfs_set_volfile_server failed\n"); + } + + /* Change this to relevant file when running locally */ + ret = glfs_set_logging(fs, "/dev/stderr", 5); + if (ret) + fprintf(stderr, "glfs_set_logging failed\n"); + + ret = glfs_init(fs); + if (ret) + fprintf(stderr, "glfs_init: returned %d\n", ret); + + if (ret) + goto out; + + /* no major use for getting the volume id in this test, done for coverage */ + ret = glfs_get_volumeid(fs, volumeid, 64); + if (ret) { + fprintf(stderr, "glfs_get_volumeid: returned %d\n", ret); + } + + sleep(2); + + if (argc == 2) { + /* Generally glfs_new() requires volume name as an argument */ + fs2 = glfs_new("test_only_volume"); + if (!fs2) { + fprintf(stderr, "glfs_new(fs2): returned NULL\n"); + return 1; + } + ret = glfs_set_volfile(fs2, argv[1]); + if (ret) + fprintf(stderr, "glfs_set_volfile failed(fs2)\n"); + } else { + fs2 = glfs_new(argv[1]); + if (!fs2) { + fprintf(stderr, "glfs_new(fs2): returned NULL\n"); + return 1; + } + ret = glfs_set_volfile_server(fs2, "tcp", argv[2], 24007); + if (ret) + fprintf(stderr, "glfs_set_volfile_server failed(fs2)\n"); + } + + ret = glfs_set_statedump_path(fs2, "/tmp"); + if (ret) { + fprintf(stderr, "glfs_set_statedump_path: %s\n", strerror(errno)); + } + + ret = glfs_init(fs2); + if (ret) + fprintf(stderr, "glfs_init: returned %d\n", ret); + + test_metadata_ops(fs, fs2); + + test_dirops(fs); + + test_xattr(fs); + + test_chdir(fs); + + test_handleops(argc, argv); + // done + + /* Test some extra apis */ + test_write_apis(fs); + + glfs_statvfs(fs, "/", &sfs); + + glfs_unset_volfile_server(fs, "tcp", argv[2], 24007); + + glfs_fini(fs); + glfs_fini(fs2); + + ret = 0; +out: + return ret; +} diff --git a/tests/basic/gfapi/glfsxmp.t b/tests/basic/gfapi/glfsxmp.t new file mode 100644 index 00000000000..b3e6645c0f5 --- /dev/null +++ b/tests/basic/gfapi/glfsxmp.t @@ -0,0 +1,30 @@ +#!/bin/bash + +. $(dirname $0)/../../include.rc +. $(dirname $0)/../../volume.rc + +cleanup + +TEST glusterd + +TEST $CLI volume create $V0 replica 3 $H0:$B0/brick{0,1,2} +EXPECT 'Created' volinfo_field $V0 'Status' + +TEST $CLI volume start $V0 +EXPECT 'Started' volinfo_field $V0 'Status' + +$CLI system getspec $V0 > fubar.vol + +TEST cp $(dirname $0)/glfsxmp-coverage.c ./glfsxmp.c +TEST build_tester ./glfsxmp.c -lgfapi +TEST ./glfsxmp $V0 $H0 + +TEST ./glfsxmp fubar.vol + +TEST cleanup_tester ./glfsxmp +TEST rm ./glfsxmp.c + +TEST $CLI volume stop $V0 +TEST $CLI volume delete $V0 + +cleanup diff --git a/tests/basic/gfapi/protocol-client-ssl.vol.in b/tests/basic/gfapi/protocol-client-ssl.vol.in new file mode 100644 index 00000000000..cdc0c9d0671 --- /dev/null +++ b/tests/basic/gfapi/protocol-client-ssl.vol.in @@ -0,0 +1,15 @@ +# +# This .vol file expects that there is +# +# 1. GlusterD listening on @@HOSTNAME@@ +# 2. a volume that provides a brick on @@BRICKPATH@@ +# 3. the volume with the brick has been started +# +volume test + type protocol/client + option remote-host @@HOSTNAME@@ + option remote-subvolume @@BRICKPATH@@ + option transport-type socket + option transport.socket.ssl-enabled @@SSL@@ +end-volume + |
