diff options
| author | Edward Shishkin <edward@redhat.com> | 2013-12-13 21:17:44 +0100 | 
|---|---|---|
| committer | Anand Avati <avati@redhat.com> | 2014-02-27 22:33:32 -0800 | 
| commit | 2010fb2bc620e6f66ed769b140d92e1d94da1439 (patch) | |
| tree | 7c292bba671fccd58d20cf222ab49a166664fa86 /tests/encryption | |
| parent | b0515e2a4a08b657ef7e9715fb8c6222c700e78c (diff) | |
Added test case for crypt translator
Change-Id: I7a28a1285c19c3279c2f71e9d9914cf14c761858
BUG: 1030058
Signed-off-by: Edward Shishkin <edward@redhat.com>
Reviewed-on: http://review.gluster.org/6504
Tested-by: Gluster Build System <jenkins@build.gluster.com>
Reviewed-by: Anand Avati <avati@redhat.com>
Diffstat (limited to 'tests/encryption')
| -rwxr-xr-x | tests/encryption/crypt.t | 87 | ||||
| -rw-r--r-- | tests/encryption/frag.c | 328 | 
2 files changed, 415 insertions, 0 deletions
diff --git a/tests/encryption/crypt.t b/tests/encryption/crypt.t new file mode 100755 index 00000000000..aa46bd42985 --- /dev/null +++ b/tests/encryption/crypt.t @@ -0,0 +1,87 @@ +#!/bin/bash + +. $(dirname $0)/../include.rc +. $(dirname $0)/../volume.rc + +cleanup; + +TEST glusterd +TEST pidof glusterd + +## Create a volume with one brick +TEST $CLI volume create $V0 $H0:$B0/${V0}1; +EXPECT "$V0" volinfo_field $V0 'Volume Name'; +EXPECT 'Created' volinfo_field $V0 'Status'; +EXPECT '1' brick_count $V0 + +## Turn off performance translators + +TEST $CLI volume set $V0 performance.quick-read off +EXPECT 'off' volinfo_field $V0 'performance.quick-read' +TEST $CLI volume set $V0 performance.write-behind off +EXPECT 'off' volinfo_field $V0 'performance.write-behind' +TEST $CLI volume set $V0 performance.open-behind off +EXPECT 'off' volinfo_field $V0 'performance.open-behind' + +## Turn on crypt xlator by setting features.encryption to on +TEST $CLI volume set $V0 encryption on +EXPECT 'on' volinfo_field $V0 'features.encryption' + +## Specify location of master key +TEST $CLI volume set $V0 encryption.master-key /tmp/$V0-master-key + +## Create a file with master key + +echo "0000111122223333444455556666777788889999aaaabbbbccccddddeeeeffff" > /tmp/$V0-master-key + +## Start the volume +TEST $CLI volume start $V0; +EXPECT 'Started' volinfo_field $V0 'Status'; + +## Mount the volume +TEST glusterfs --volfile-server=$H0 --volfile-id=$V0 $M0; + +## Testing writev, readv, ftruncate: +## Create fragmented files and compare them with the reference files + +build_tester $(dirname $0)/frag.c +TEST $(dirname $0)/frag $M0/testfile /tmp/$V0-goodfile 262144 500 + +## Testing link, unlink, symlink, rename + +TEST ln $M0/testfile $M0/testfile-link +TEST mv $M0/testfile $M0/testfile-renamed +TEST ln -s $M0/testfile-link $M0/testfile-symlink +TEST rm -f $M0/testfile-renamed + +## Remount the volume +TEST umount $M0 +TEST glusterfs --volfile-server=$H0 --volfile-id=$V0 $M0; + +TEST diff -u $M0/testfile-symlink /tmp/$V0-goodfile +EXPECT '' + +TEST rm -f $M0/testfile-symlink +TEST rm -f $M0/testfile-link + +## Cleanup files + +TEST rm -f /tmp/$V0-master-key +TEST rm -f /tmp/$V0-goodfile + +TEST umount $M0 + +## Reset crypt options +TEST $CLI volume reset $V0 encryption.block-size +TEST $CLI volume reset $V0 encryption.data-key-size + +## Stop the volume +TEST $CLI volume stop $V0; +EXPECT 'Stopped' volinfo_field $V0 'Status'; + +## Delete the volume +TEST $CLI volume delete $V0; +TEST ! $CLI volume info $V0; + +TEST rm -rf $(dirname $0)/frag +cleanup; diff --git a/tests/encryption/frag.c b/tests/encryption/frag.c new file mode 100644 index 00000000000..86da037c607 --- /dev/null +++ b/tests/encryption/frag.c @@ -0,0 +1,328 @@ +/* +  Copyright (c) 2008-2013 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 <stdlib.h> +#include <stdio.h> +#include <sys/types.h> +#include <string.h> +#include <sys/stat.h> +#include <sys/syscall.h> +#include <unistd.h> +#include <fcntl.h> + +#define MAX_NUM_OPS (1 << 20) +#define MAX_FILE_SIZE (1 << 30) + +typedef enum { +	READ_OP, +	WRITE_OP, +	TRUNC_OP, +	LAST_OP +} frag_op; + +struct frag_ctx { +	int test_fd; +	int good_fd; +	char *test_buf; +	char *good_buf; +	char *content; +	int max_file_size; +}; + +typedef int (*frag_op_t)(struct frag_ctx *ctx, off_t offset, size_t count); + +static int doread(int fd, off_t offset, size_t count, +		  char *buf, int max_file_size) +{ +	int ret = 0; +	int was_read = 0; + +	if (lseek(fd, offset, SEEK_SET) == -1) { +		perror("lseek failed"); +                return -1; +	} +	while (count) { +		ret = read(fd, buf + offset + was_read, count); +		if (ret < 0) +			return -1; +		if (ret == 0) +			break; +		if (ret > count) { +			fprintf(stderr, "READ: read more than asked\n"); +			return -1; +		} +		count -= ret; +		was_read += ret; +	} +	return ret; +} + +static int dowrite(int fd, off_t offset, size_t count, char *buf) +{ +	int ret; + +	ret = lseek(fd, offset, SEEK_SET); +	if (ret == -1) +                return ret; +	return write(fd, buf, count); +} + +static int dotrunc(int fd, off_t offset) +{ +	int ret; + +	ret = ftruncate(fd, offset); +	if (ret == -1) +		perror("truncate failed"); +	return ret; +} + +static int prepare_file(char *filename, int *fd, char **buf, int max_file_size) +{ +	int ret; + +	*buf = malloc(max_file_size); +	if (*buf == NULL) { +		perror("malloc failed"); +	        return -1; +	} +	*fd = open(filename, O_CREAT | O_RDWR, S_IRWXU); +	if (*fd == -1) { +		perror("open failed"); +		free(*buf); +		*buf = NULL; +		return -1; +	} +	return 0; +} + +/* + * @offset, @count: random values from [0, max_file_size - 1] + */ +static int frag_write(struct frag_ctx *ctx, off_t offset, size_t count) +{ +	int ret; +	struct stat test_stbuf; +	struct stat good_stbuf; + +	if (offset + count > ctx->max_file_size) +		offset = offset / 2; +	if (offset + count > ctx->max_file_size) +		count = count / 2; + +	if (fstat(ctx->test_fd, &test_stbuf)) { +		fprintf(stderr, "WRITE: fstat of test file failed\n"); +		return -1; +	} +	if (offset > test_stbuf.st_size) +		printf("writing hole\n"); + +	ret = dowrite(ctx->test_fd, offset, count, ctx->content); +	if (ret < 0 || ret != count){ +		fprintf(stderr, "WRITE: failed to write test file\n"); +		return -1; +	} +	ret = dowrite(ctx->good_fd, offset, count, ctx->content); +	if (ret < 0 || ret != count) { +		fprintf(stderr, "WRITE: failed to write test file\n"); +		return -1; +	}	 +	if (fstat(ctx->test_fd, &test_stbuf)) { +                fprintf(stderr, "WRITE: fstat of test file failed\n"); +		return -1; +	} +	if (fstat(ctx->good_fd, &good_stbuf)) { +                fprintf(stderr, "WRITE: fstat of good file failed\n"); +		return -1; +	} +	if (test_stbuf.st_size != good_stbuf.st_size) { +		fprintf(stderr, +			"READ: Bad file size %d (expected %d)\n", +			(int)test_stbuf.st_size, +			(int)good_stbuf.st_size); +		return -1; +	} +	return 0; +} + +/* + * @offset, @count: random values from [0, max_file_size - 1] + */ +static int frag_read(struct frag_ctx *ctx, off_t offset, size_t count) +{ +	ssize_t test_ret; +	ssize_t good_ret; + +	test_ret = doread(ctx->test_fd, +			  offset, count, ctx->test_buf, ctx->max_file_size); +	if (test_ret < 0) { +		fprintf(stderr, "READ: failed to read test file\n"); +		return -1; +	} +	good_ret = doread(ctx->good_fd, +			  offset, count, ctx->good_buf, ctx->max_file_size); +	if (good_ret < 0) { +		fprintf(stderr, "READ: failed to read good file\n"); +		return -1; +	} +	if (test_ret != good_ret) { +		fprintf(stderr, +			"READ: Bad return value %d (expected %d\n)", +			test_ret, good_ret); +		return -1; +	} +	if (memcmp(ctx->test_buf + offset, ctx->good_buf + offset, good_ret)) { +		fprintf(stderr, "READ: bad data\n"); +		return -1; +	} +	return 0; +} + +/* + * @offset: random value from [0, max_file_size - 1] + */ +static int frag_truncate(struct frag_ctx *ctx, +			 off_t offset, __attribute__((unused))size_t count) +{ +	int ret; +	struct stat test_stbuf; +	struct stat good_stbuf; + +	if (fstat(ctx->test_fd, &test_stbuf)) { +		fprintf(stderr, "TRUNCATE: fstat of test file failed\n"); +		return -1; +	} +	if (offset > test_stbuf.st_size) +		printf("expanding truncate to %d\n", offset); +	else if (offset < test_stbuf.st_size) +		printf("shrinking truncate to %d\n", offset); +	else +		printf("trivial truncate\n"); +	 +	ret = dotrunc(ctx->test_fd, offset); +	if (ret == -1) { +		fprintf(stderr, "TRUNCATE: failed for test file\n"); +		return -1; +	} +	ret = dotrunc(ctx->good_fd, offset); +	if (ret == -1) { +		fprintf(stderr, "TRUNCATE: failed for good file\n"); +		return -1; +	} +	if (fstat(ctx->test_fd, &test_stbuf)) { +		fprintf(stderr, "TRUNCATE: fstat of test file failed\n"); +		return -1; +	} +	if (fstat(ctx->good_fd, &good_stbuf)) { +		fprintf(stderr, "TRUNCATE: fstat of good file failed\n"); +		return -1; +	} +	if (test_stbuf.st_size != good_stbuf.st_size) { +		fprintf(stderr, +			"TRUNCATE: bad test file size %d (expected %d)\n", +			test_stbuf.st_size, +			good_stbuf.st_size); +		return -1; +	} +	return 0; +} + +frag_op_t frag_ops[LAST_OP] = { +	[READ_OP]  = frag_read, +	[WRITE_OP] = frag_write, +	[TRUNC_OP] = frag_truncate +}; + +static void put_ctx(struct frag_ctx *ctx) +{ +	if (ctx->test_buf) +		free(ctx->test_buf); +	if (ctx->good_buf) +		free(ctx->good_buf); +	if (ctx->content) +		free(ctx->content); +} + +main (int argc, char *argv[]) +{ +	int i; +	int ret = 0; +	struct frag_ctx ctx; +	char *test_filename = NULL; +	char *good_filename = NULL; +	int num_ops; +	int max_file_size; + +	memset(&ctx, 0, sizeof(ctx)); +	if (argc != 5) { +                fprintf(stderr, +			"usage: %s <test-file-name> <good-file-name> <max-file-size> <number-of-operations>\n", +			argv[0]); +		ret = -1; +                goto exit; +        } +	test_filename = argv[1]; +	good_filename = argv[2]; +	max_file_size = atoi(argv[3]); +	if (max_file_size > MAX_FILE_SIZE) +		max_file_size = MAX_FILE_SIZE; +	num_ops = atoi(argv[4]); +	if (num_ops > MAX_NUM_OPS) +		num_ops = MAX_NUM_OPS; + +	ret = prepare_file(test_filename, +			   &ctx.test_fd, &ctx.test_buf, max_file_size); +	if (ret) +		goto exit; +	ret = prepare_file(good_filename, +			   &ctx.good_fd, &ctx.good_buf, max_file_size); +	if (ret) { +		if (close(ctx.test_fd) == -1) +			perror("close test_buf failed"); +		goto exit; +	} +	ctx.content = malloc(max_file_size); +	if (!ctx.content) { +		perror("malloc failed"); +		goto close; +	} +	ctx.max_file_size = max_file_size; +	for (i = 0; i < max_file_size; i++) +                ctx.content[i] = random() % 256; + +	for (i = 0; i < num_ops; i++) { +		ret = frag_ops[random() % LAST_OP](&ctx, +					random() % max_file_size, /* offset */ +					random() % max_file_size  /* count */); +		if (ret) +			break; +	} + close: +	if (close(ctx.test_fd) == -1) +		perror("close test_fd failed"); +	if (close(ctx.good_fd) == -1) +		perror("close good_fd failed");	 + exit: +	put_ctx(&ctx); +	if (ret) +		exit(1); +	exit(0); +} + +/* +  Local variables: +  c-indentation-style: "K&R" +  mode-name: "LC" +  c-basic-offset: 8 +  tab-width: 8 +  fill-column: 80 +  scroll-step: 1 +  End: +*/  | 
