339 lines
6.8 KiB
C
339 lines
6.8 KiB
C
// SPDX-License-Identifier: GPL-2.0-or-later
|
|
/*
|
|
* simple unit test for utils_io.c (blockwise low level functions)
|
|
*
|
|
* Copyright (C) 2018-2024 Red Hat, Inc. All rights reserved.
|
|
*/
|
|
|
|
#include <errno.h>
|
|
#include <fcntl.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <sys/types.h>
|
|
#include <sys/stat.h>
|
|
#include <unistd.h>
|
|
|
|
#include "utils_io.h"
|
|
|
|
enum fn_enum {
|
|
READ_BUFFER = 0,
|
|
WRITE_BUFFER,
|
|
READ_BLOCKWISE,
|
|
WRITE_BLOCKWISE,
|
|
READ_LSEEK_BLOCKWISE,
|
|
WRITE_LSEEK_BLOCKWISE
|
|
} test_fn;
|
|
|
|
char *test_file;
|
|
size_t test_bsize;
|
|
size_t test_alignment;
|
|
size_t test_length;
|
|
off_t test_offset; //FIXME: check for proper 64bit support (and test it!)
|
|
size_t test_mem_alignment = 4096;
|
|
|
|
static int test_read_buffer(void)
|
|
{
|
|
void *buffer = NULL;
|
|
int fd = -1;
|
|
ssize_t ret = -EINVAL;
|
|
|
|
//printf("Entering test_read_buffer\n");
|
|
|
|
if (posix_memalign(&buffer, test_mem_alignment, test_length)) {
|
|
fprintf(stderr, "Failed to allocate aligned buffer.\n");
|
|
goto out;
|
|
}
|
|
|
|
fd = open(test_file, O_RDONLY | O_DIRECT);
|
|
if (fd < 0) {
|
|
fprintf(stderr, "Failed to open %s.\n", test_file);
|
|
goto out;
|
|
}
|
|
|
|
ret = read_buffer(fd, buffer, test_length);
|
|
if (ret < 0)
|
|
goto out;
|
|
|
|
ret = (size_t) ret == test_length ? 0 : -EIO;
|
|
out:
|
|
if (fd >= 0)
|
|
close(fd);
|
|
free(buffer);
|
|
return ret;
|
|
}
|
|
|
|
static int test_write_buffer(void)
|
|
{
|
|
void *buffer = NULL;
|
|
int fd = -1;
|
|
ssize_t ret = -EINVAL;
|
|
|
|
//printf("Entering test_write_buffer\n");
|
|
|
|
if (posix_memalign(&buffer, test_mem_alignment, test_length)) {
|
|
fprintf(stderr, "Failed to allocate aligned buffer.\n");
|
|
goto out;
|
|
}
|
|
|
|
fd = open(test_file, O_WRONLY | O_DIRECT);
|
|
if (fd < 0) {
|
|
fprintf(stderr, "Failed to open %s.\n", test_file);
|
|
goto out;
|
|
}
|
|
|
|
ret = write_buffer(fd, buffer, test_length);
|
|
if (ret < 0)
|
|
goto out;
|
|
|
|
ret = (size_t) ret == test_length ? 0 : -EIO;
|
|
out:
|
|
if (fd >= 0)
|
|
close(fd);
|
|
free(buffer);
|
|
return ret;
|
|
}
|
|
|
|
static int test_read_blockwise(void)
|
|
{
|
|
void *buffer = NULL;
|
|
int fd = -1;
|
|
ssize_t ret = -EINVAL;
|
|
|
|
//printf("Entering test_read_blockwise ");
|
|
//printf("test_bsize: %zu, test_length: %zu\n", test_bsize, test_length);
|
|
|
|
if (posix_memalign(&buffer, test_mem_alignment, test_length)) {
|
|
fprintf(stderr, "Failed to allocate aligned buffer.\n");
|
|
goto out;
|
|
}
|
|
|
|
fd = open(test_file, O_RDONLY | O_DIRECT);
|
|
if (fd < 0) {
|
|
fprintf(stderr, "Failed to open %s.\n", test_file);
|
|
goto out;
|
|
}
|
|
|
|
|
|
ret = read_blockwise(fd, test_bsize, test_mem_alignment, buffer, test_length);
|
|
if (ret < 0)
|
|
goto out;
|
|
|
|
ret = (size_t) ret == test_length ? 0 : -EIO;
|
|
out:
|
|
if (fd >= 0)
|
|
close(fd);
|
|
free(buffer);
|
|
return ret;
|
|
}
|
|
|
|
static int test_write_blockwise(void)
|
|
{
|
|
void *buffer = NULL;
|
|
int fd = -1;
|
|
ssize_t ret = -EINVAL;
|
|
|
|
//printf("Entering test_write_blockwise\n");
|
|
|
|
if (posix_memalign(&buffer, test_mem_alignment, test_length)) {
|
|
fprintf(stderr, "Failed to allocate aligned buffer.\n");
|
|
goto out;
|
|
}
|
|
|
|
fd = open(test_file, O_RDWR | O_DIRECT);
|
|
if (fd < 0) {
|
|
fprintf(stderr, "Failed to open %s.\n", test_file);
|
|
goto out;
|
|
}
|
|
|
|
ret = write_blockwise(fd, test_bsize, test_mem_alignment, buffer, test_length);
|
|
if (ret < 0)
|
|
goto out;
|
|
|
|
ret = (size_t) ret == test_length ? 0 : -EIO;
|
|
out:
|
|
if (fd >= 0)
|
|
close(fd);
|
|
free(buffer);
|
|
return ret;
|
|
}
|
|
|
|
static int test_read_lseek_blockwise(void)
|
|
{
|
|
void *buffer = NULL;
|
|
int fd = -1;
|
|
ssize_t ret = -EINVAL;
|
|
|
|
//printf("Entering test_read_lseek_blockwise\n");
|
|
|
|
if (posix_memalign(&buffer, test_mem_alignment, test_length)) {
|
|
fprintf(stderr, "Failed to allocate aligned buffer.\n");
|
|
goto out;
|
|
}
|
|
|
|
fd = open(test_file, O_RDONLY | O_DIRECT);
|
|
if (fd < 0) {
|
|
fprintf(stderr, "Failed to open %s.\n", test_file);
|
|
goto out;
|
|
}
|
|
|
|
ret = read_lseek_blockwise(fd, test_bsize, test_mem_alignment, buffer, test_length, test_offset);
|
|
if (ret < 0)
|
|
goto out;
|
|
|
|
ret = (size_t) ret == test_length ? 0 : -EIO;
|
|
out:
|
|
if (fd >= 0)
|
|
close(fd);
|
|
free(buffer);
|
|
return ret;
|
|
}
|
|
|
|
static int test_write_lseek_blockwise(void)
|
|
{
|
|
void *buffer = NULL;
|
|
int fd = -1;
|
|
ssize_t ret = -EINVAL;
|
|
|
|
//printf("Entering test_write_lseek_blockwise\n");
|
|
|
|
if (posix_memalign(&buffer, test_mem_alignment, test_length)) {
|
|
fprintf(stderr, "Failed to allocate aligned buffer.\n");
|
|
goto out;
|
|
}
|
|
|
|
fd = open(test_file, O_RDWR | O_DIRECT);
|
|
if (fd < 0) {
|
|
fprintf(stderr, "Failed to open %s.\n", test_file);
|
|
goto out;
|
|
}
|
|
|
|
ret = write_lseek_blockwise(fd, test_bsize, test_mem_alignment, buffer, test_length, test_offset);
|
|
if (ret < 0)
|
|
goto out;
|
|
|
|
ret = (size_t) ret == test_length ? 0 : -EIO;
|
|
out:
|
|
if (fd >= 0)
|
|
close(fd);
|
|
free(buffer);
|
|
return ret;
|
|
}
|
|
|
|
static void usage(void)
|
|
{
|
|
fprintf(stderr, "Use:\tunit-utils-io file/device blockwise_fn length [bsize] [offset].\n");
|
|
}
|
|
|
|
static int parse_input_params(int argc, char **argv)
|
|
{
|
|
struct stat st;
|
|
unsigned long offset;
|
|
|
|
if (argc < 4) {
|
|
usage();
|
|
return 1;
|
|
}
|
|
|
|
if (stat(argv[1], &st)) {
|
|
fprintf(stderr, "File/device %s is missing?\n", argv[1]);
|
|
return 1;
|
|
}
|
|
test_file = argv[1];
|
|
if (sscanf(argv[3], "%zu", &test_length) != 1)
|
|
return 1;
|
|
if (argc >= 5 && sscanf(argv[4], "%zu", &test_bsize) != 1)
|
|
return 1;
|
|
if (argc >= 6) {
|
|
if (sscanf(argv[5], "%ld", &offset) != 1)
|
|
return 1;
|
|
test_offset = offset;
|
|
}
|
|
|
|
if (!strcmp(argv[2], "read_buffer"))
|
|
test_fn = READ_BUFFER;
|
|
else if (!strcmp(argv[2], "write_buffer"))
|
|
test_fn = WRITE_BUFFER;
|
|
else if (!strcmp(argv[2], "read_blockwise")) {
|
|
if (argc < 5) {
|
|
usage();
|
|
return 1;
|
|
}
|
|
test_fn = READ_BLOCKWISE;
|
|
} else if (!strcmp(argv[2], "write_blockwise")) {
|
|
if (argc < 5) {
|
|
usage();
|
|
return 1;
|
|
}
|
|
test_fn = WRITE_BLOCKWISE;
|
|
} else if (!strcmp(argv[2], "read_lseek_blockwise")) {
|
|
if (argc < 6) {
|
|
usage();
|
|
return 1;
|
|
}
|
|
test_fn = READ_LSEEK_BLOCKWISE;
|
|
} else if (!strcmp(argv[2], "write_lseek_blockwise")) {
|
|
if (argc < 6) {
|
|
usage();
|
|
return 1;
|
|
}
|
|
test_fn = WRITE_LSEEK_BLOCKWISE;
|
|
} else {
|
|
usage();
|
|
return 1;
|
|
}
|
|
|
|
/* printf("function '%s': length %zu", argv[2], test_length);
|
|
if (argc >= 5)
|
|
printf(", bsize %zu", test_bsize);
|
|
if (argc >= 6)
|
|
printf(", offset %llu", test_offset);
|
|
printf("\n"); */
|
|
|
|
return 0;
|
|
}
|
|
|
|
int main(int argc, char **argv)
|
|
{
|
|
long ps;
|
|
int r = EXIT_FAILURE;
|
|
|
|
#ifndef NO_CRYPTSETUP_PATH
|
|
if (getenv("CRYPTSETUP_PATH")) {
|
|
printf("Cannot run this test with CRYPTSETUP_PATH set.\n");
|
|
exit(77);
|
|
}
|
|
#endif
|
|
if (parse_input_params(argc, argv))
|
|
return r;
|
|
|
|
ps = sysconf(_SC_PAGESIZE);
|
|
if (ps > 0)
|
|
test_mem_alignment = (size_t)ps;
|
|
|
|
switch (test_fn) {
|
|
case READ_BUFFER:
|
|
r = test_read_buffer();
|
|
break;
|
|
case WRITE_BUFFER:
|
|
r = test_write_buffer();
|
|
break;
|
|
case READ_BLOCKWISE:
|
|
r = test_read_blockwise();
|
|
break;
|
|
case WRITE_BLOCKWISE:
|
|
r = test_write_blockwise();
|
|
break;
|
|
case READ_LSEEK_BLOCKWISE:
|
|
r = test_read_lseek_blockwise();
|
|
break;
|
|
case WRITE_LSEEK_BLOCKWISE:
|
|
r = test_write_lseek_blockwise();
|
|
break;
|
|
default :
|
|
fprintf(stderr, "Internal test error.\n");
|
|
return r;
|
|
}
|
|
|
|
return r == 0 ? EXIT_SUCCESS : EXIT_FAILURE;
|
|
}
|