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>
This commit is contained in:
parent
b0515e2a4a
commit
2010fb2bc6
87
tests/encryption/crypt.t
Executable file
87
tests/encryption/crypt.t
Executable file
@ -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;
|
328
tests/encryption/frag.c
Normal file
328
tests/encryption/frag.c
Normal file
@ -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:
|
||||
*/
|
Loading…
x
Reference in New Issue
Block a user