postgres hook 测试成功
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
SUBDIRS := ioengine_test hook
|
||||
SUBDIRS := hook_test daemon_test
|
||||
|
||||
.PHONY: all clean $(SUBDIRS)
|
||||
|
||||
|
||||
12
tests/daemon_test/Makefile
Normal file
12
tests/daemon_test/Makefile
Normal file
@@ -0,0 +1,12 @@
|
||||
|
||||
BIN_DIR := $(abspath $(CURDIR)/../bin)
|
||||
PROTO_DIR := $(abspath $(CURDIR)/../../src/proto)
|
||||
|
||||
CFLAGS := -I$(abspath $(CURDIR)/../../src)
|
||||
|
||||
all:
|
||||
gcc -g -o $(BIN_DIR)/ipc_echo_test ipc_echo_test.c
|
||||
gcc -g $(CFLAGS) -o $(BIN_DIR)/ipc_zvfs_test ipc_zvfs_test.c $(PROTO_DIR)/ipc_proto.c
|
||||
|
||||
clean:
|
||||
rm -rf $(BIN_DIR)/ipc_echo_test $(BIN_DIR)/ipc_zvfs_test
|
||||
33
tests/daemon_test/ipc_echo_test.c
Normal file
33
tests/daemon_test/ipc_echo_test.c
Normal file
@@ -0,0 +1,33 @@
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/un.h>
|
||||
|
||||
|
||||
int main()
|
||||
{
|
||||
int fd = socket(AF_UNIX, SOCK_STREAM, 0);
|
||||
|
||||
struct sockaddr_un addr;
|
||||
|
||||
memset(&addr, 0, sizeof(addr));
|
||||
addr.sun_family = AF_UNIX;
|
||||
strcpy(addr.sun_path, "/tmp/zvfs.sock");
|
||||
|
||||
connect(fd, (struct sockaddr*)&addr, sizeof(addr));
|
||||
|
||||
char *msg = "hello reactor\n";
|
||||
|
||||
write(fd, msg, strlen(msg));
|
||||
|
||||
char buf[4096];
|
||||
|
||||
int n = read(fd, buf, sizeof(buf));
|
||||
|
||||
printf("echo: %.*s\n", n, buf);
|
||||
|
||||
close(fd);
|
||||
|
||||
return 0;
|
||||
}
|
||||
265
tests/daemon_test/ipc_zvfs_test.c
Normal file
265
tests/daemon_test/ipc_zvfs_test.c
Normal file
@@ -0,0 +1,265 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/un.h>
|
||||
#include "proto/ipc_proto.h"
|
||||
|
||||
#define SOCKET_PATH "/tmp/zvfs.sock"
|
||||
#define BUF_SIZE 4096
|
||||
|
||||
int connect_to_server() {
|
||||
int fd = socket(AF_UNIX, SOCK_STREAM, 0);
|
||||
if (fd < 0) {
|
||||
perror("socket");
|
||||
return -1;
|
||||
}
|
||||
|
||||
struct sockaddr_un addr;
|
||||
memset(&addr, 0, sizeof(addr));
|
||||
addr.sun_family = AF_UNIX;
|
||||
strncpy(addr.sun_path, SOCKET_PATH, sizeof(addr.sun_path)-1);
|
||||
|
||||
if (connect(fd, (struct sockaddr*)&addr, sizeof(addr)) < 0) {
|
||||
perror("connect");
|
||||
close(fd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return fd;
|
||||
}
|
||||
|
||||
// -------------------- 操作函数 --------------------
|
||||
|
||||
void do_create(int fd) {
|
||||
struct zvfs_req req;
|
||||
memset(&req, 0, sizeof(req));
|
||||
req.opcode = ZVFS_OP_CREATE;
|
||||
req.size_hint = 1024; // 1KB
|
||||
|
||||
uint8_t buf[BUF_SIZE];
|
||||
size_t n = zvfs_serialize_req(&req, buf, sizeof(buf));
|
||||
if (n == 0) { fprintf(stderr,"serialize failed\n"); return; }
|
||||
|
||||
if (write(fd, buf, n) != n) { perror("write"); return; }
|
||||
|
||||
uint8_t resp_buf[BUF_SIZE];
|
||||
ssize_t r = read(fd, resp_buf, sizeof(resp_buf));
|
||||
if (r <= 0) { perror("read"); return; }
|
||||
|
||||
struct zvfs_resp resp;
|
||||
memset(&resp, 0, sizeof(resp));
|
||||
size_t consumed = zvfs_deserialize_resp(resp_buf, r, &resp);
|
||||
if (consumed == 0) { fprintf(stderr, "deserialize failed\n"); return; }
|
||||
|
||||
printf("Received CREATE response: status=%d, blob_id=%lu, handle_id=%lu\n",
|
||||
resp.status, resp.blob_id, resp.handle_id);
|
||||
|
||||
if(resp.data) free(resp.data);
|
||||
}
|
||||
|
||||
void do_open(int fd, uint64_t blob_id) {
|
||||
struct zvfs_req req;
|
||||
memset(&req,0,sizeof(req));
|
||||
req.opcode = ZVFS_OP_OPEN;
|
||||
req.blob_id = blob_id;
|
||||
|
||||
uint8_t buf[BUF_SIZE];
|
||||
size_t n = zvfs_serialize_req(&req, buf, sizeof(buf));
|
||||
if (n == 0) { fprintf(stderr,"serialize failed\n"); return; }
|
||||
|
||||
if (write(fd, buf, n) != n) { perror("write"); return; }
|
||||
|
||||
uint8_t resp_buf[BUF_SIZE];
|
||||
ssize_t r = read(fd, resp_buf, sizeof(resp_buf));
|
||||
if (r <= 0) { perror("read"); return; }
|
||||
|
||||
struct zvfs_resp resp;
|
||||
memset(&resp,0,sizeof(resp));
|
||||
size_t consumed = zvfs_deserialize_resp(resp_buf, r, &resp);
|
||||
if (consumed == 0) { fprintf(stderr, "deserialize failed\n"); return; }
|
||||
|
||||
printf("Received OPEN response: status=%d, handle_id=%lu, size=%lu\n",
|
||||
resp.status, resp.handle_id, resp.size);
|
||||
|
||||
if(resp.data) free(resp.data);
|
||||
}
|
||||
|
||||
void do_read(int fd, uint64_t handle_id, uint64_t offset, uint64_t length) {
|
||||
struct zvfs_req req;
|
||||
memset(&req,0,sizeof(req));
|
||||
req.opcode = ZVFS_OP_READ;
|
||||
req.handle_id = handle_id;
|
||||
req.offset = offset;
|
||||
req.length = length;
|
||||
|
||||
uint8_t buf[BUF_SIZE];
|
||||
size_t n = zvfs_serialize_req(&req, buf, sizeof(buf));
|
||||
if (n == 0) { fprintf(stderr,"serialize failed\n"); return; }
|
||||
|
||||
if (write(fd, buf, n) != n) { perror("write"); return; }
|
||||
|
||||
uint8_t resp_buf[BUF_SIZE];
|
||||
ssize_t r = read(fd, resp_buf, sizeof(resp_buf));
|
||||
if (r <= 0) { perror("read"); return; }
|
||||
|
||||
struct zvfs_resp resp;
|
||||
memset(&resp,0,sizeof(resp));
|
||||
size_t consumed = zvfs_deserialize_resp(resp_buf, r, &resp);
|
||||
if (consumed == 0) { fprintf(stderr, "deserialize failed\n"); return; }
|
||||
|
||||
printf("Received READ response: status=%d, length=%lu\n",
|
||||
resp.status, resp.length);
|
||||
|
||||
if(resp.data) {
|
||||
printf("Data: ");
|
||||
for(size_t i=0;i<resp.length;i++)
|
||||
printf("%02x ", ((uint8_t*)resp.data)[i]);
|
||||
printf("\n");
|
||||
free(resp.data);
|
||||
}
|
||||
}
|
||||
|
||||
void do_write(int fd, uint64_t handle_id, uint64_t offset,
|
||||
const char *data, size_t len, uint32_t write_flags) {
|
||||
struct zvfs_req req;
|
||||
memset(&req,0,sizeof(req));
|
||||
req.opcode = ZVFS_OP_WRITE;
|
||||
req.handle_id = handle_id;
|
||||
req.offset = offset;
|
||||
req.length = len;
|
||||
req.write_flags = write_flags;
|
||||
req.data = (void*)data;
|
||||
|
||||
uint8_t buf[BUF_SIZE];
|
||||
size_t n = zvfs_serialize_req(&req, buf, sizeof(buf));
|
||||
if (n == 0) { fprintf(stderr,"serialize failed\n"); return; }
|
||||
|
||||
if (write(fd, buf, n) != n) { perror("write"); return; }
|
||||
|
||||
uint8_t resp_buf[BUF_SIZE];
|
||||
ssize_t r = read(fd, resp_buf, sizeof(resp_buf));
|
||||
if (r <= 0) { perror("read"); return; }
|
||||
|
||||
struct zvfs_resp resp;
|
||||
memset(&resp,0,sizeof(resp));
|
||||
size_t consumed = zvfs_deserialize_resp(resp_buf, r, &resp);
|
||||
if (consumed == 0) { fprintf(stderr, "deserialize failed\n"); return; }
|
||||
|
||||
printf("Received WRITE response: status=%d, bytes_written=%lu\n",
|
||||
resp.status, resp.bytes_written);
|
||||
|
||||
if(resp.data) free(resp.data);
|
||||
}
|
||||
|
||||
void do_close(int fd, uint64_t handle_id) {
|
||||
struct zvfs_req req;
|
||||
memset(&req,0,sizeof(req));
|
||||
req.opcode = ZVFS_OP_CLOSE;
|
||||
req.handle_id = handle_id;
|
||||
|
||||
uint8_t buf[BUF_SIZE];
|
||||
size_t n = zvfs_serialize_req(&req, buf, sizeof(buf));
|
||||
if (n == 0) { fprintf(stderr,"serialize failed\n"); return; }
|
||||
if (write(fd, buf, n) != n) { perror("write"); return; }
|
||||
|
||||
uint8_t resp_buf[BUF_SIZE];
|
||||
ssize_t r = read(fd, resp_buf, sizeof(resp_buf));
|
||||
if (r <= 0) { perror("read"); return; }
|
||||
|
||||
struct zvfs_resp resp;
|
||||
memset(&resp,0,sizeof(resp));
|
||||
size_t consumed = zvfs_deserialize_resp(resp_buf, r, &resp);
|
||||
if (consumed == 0) { fprintf(stderr, "deserialize failed\n"); return; }
|
||||
|
||||
printf("Received CLOSE response: status=%d\n", resp.status);
|
||||
if(resp.data) free(resp.data);
|
||||
}
|
||||
|
||||
void do_delete(int fd, uint64_t blob_id) {
|
||||
struct zvfs_req req;
|
||||
memset(&req,0,sizeof(req));
|
||||
req.opcode = ZVFS_OP_DELETE;
|
||||
req.blob_id = blob_id;
|
||||
|
||||
uint8_t buf[BUF_SIZE];
|
||||
size_t n = zvfs_serialize_req(&req, buf, sizeof(buf));
|
||||
if (n == 0) { fprintf(stderr,"serialize failed\n"); return; }
|
||||
if (write(fd, buf, n) != n) { perror("write"); return; }
|
||||
|
||||
uint8_t resp_buf[BUF_SIZE];
|
||||
ssize_t r = read(fd, resp_buf, sizeof(resp_buf));
|
||||
if (r <= 0) { perror("read"); return; }
|
||||
|
||||
struct zvfs_resp resp;
|
||||
memset(&resp,0,sizeof(resp));
|
||||
size_t consumed = zvfs_deserialize_resp(resp_buf, r, &resp);
|
||||
if (consumed == 0) { fprintf(stderr, "deserialize failed\n"); return; }
|
||||
|
||||
printf("Received DELETE response: status=%d\n", resp.status);
|
||||
if(resp.data) free(resp.data);
|
||||
}
|
||||
|
||||
void do_resize(int fd, uint64_t handle_id, uint64_t new_size) {
|
||||
struct zvfs_req req;
|
||||
memset(&req,0,sizeof(req));
|
||||
req.opcode = ZVFS_OP_RESIZE;
|
||||
req.handle_id = handle_id;
|
||||
req.size_hint = new_size;
|
||||
|
||||
uint8_t buf[BUF_SIZE];
|
||||
size_t n = zvfs_serialize_req(&req, buf, sizeof(buf));
|
||||
if (n == 0) { fprintf(stderr,"serialize failed\n"); return; }
|
||||
if (write(fd, buf, n) != n) { perror("write"); return; }
|
||||
|
||||
uint8_t resp_buf[BUF_SIZE];
|
||||
ssize_t r = read(fd, resp_buf, sizeof(resp_buf));
|
||||
if (r <= 0) { perror("read"); return; }
|
||||
|
||||
struct zvfs_resp resp;
|
||||
memset(&resp,0,sizeof(resp));
|
||||
size_t consumed = zvfs_deserialize_resp(resp_buf, r, &resp);
|
||||
if (consumed == 0) { fprintf(stderr, "deserialize failed\n"); return; }
|
||||
|
||||
printf("Received RESIZE response: status=%d\n", resp.status);
|
||||
if(resp.data) free(resp.data);
|
||||
}
|
||||
|
||||
// -------------------- main --------------------
|
||||
|
||||
int main() {
|
||||
int fd = connect_to_server();
|
||||
if(fd < 0) return 1;
|
||||
|
||||
printf("Connected to server at %s\n", SOCKET_PATH);
|
||||
printf("Commands:\n create\n open <blob>\n read <handle> <offset> <len>\n write <handle> <offset> <data>\n writeg <handle> <offset> <data>\n close <handle>\n delete <blob>\n resize <handle> <size>\n quit\n");
|
||||
|
||||
char line[256];
|
||||
while (1) {
|
||||
printf("> ");
|
||||
if(!fgets(line, sizeof(line), stdin)) break;
|
||||
|
||||
char cmd[32];
|
||||
uint64_t a,b,c;
|
||||
char data[128];
|
||||
|
||||
if (sscanf(line, "%31s", cmd) != 1) continue;
|
||||
|
||||
if (strcmp(cmd,"quit")==0) break;
|
||||
else if (strcmp(cmd,"create")==0) do_create(fd);
|
||||
else if (strcmp(cmd,"open")==0 && sscanf(line,"%*s %lu",&a)==1) do_open(fd,a);
|
||||
else if (strcmp(cmd,"read")==0 && sscanf(line,"%*s %lu %lu %lu",&a,&b,&c)==3) do_read(fd,a,b,c);
|
||||
else if (strcmp(cmd,"write")==0 && sscanf(line,"%*s %lu %lu %127s",&a,&b,data)==3)
|
||||
do_write(fd, a, b, data, strlen(data), 0);
|
||||
else if (strcmp(cmd,"writeg")==0 && sscanf(line,"%*s %lu %lu %127s",&a,&b,data)==3)
|
||||
do_write(fd, a, b, data, strlen(data), ZVFS_WRITE_F_AUTO_GROW);
|
||||
else if (strcmp(cmd,"close")==0 && sscanf(line,"%*s %lu",&a)==1) do_close(fd,a);
|
||||
else if (strcmp(cmd,"delete")==0 && sscanf(line,"%*s %lu",&a)==1) do_delete(fd,a);
|
||||
else if (strcmp(cmd,"resize")==0 && sscanf(line,"%*s %lu %lu",&a,&b)==2) do_resize(fd,a,b);
|
||||
else printf("Unknown or invalid command\n");
|
||||
}
|
||||
|
||||
close(fd);
|
||||
return 0;
|
||||
}
|
||||
@@ -1,43 +0,0 @@
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
SPDK_ROOT_DIR := $(abspath $(CURDIR)/../../spdk)
|
||||
include $(SPDK_ROOT_DIR)/mk/spdk.common.mk
|
||||
include $(SPDK_ROOT_DIR)/mk/spdk.modules.mk
|
||||
include $(SPDK_ROOT_DIR)/mk/spdk.app_vars.mk
|
||||
|
||||
# 输出目录
|
||||
BIN_DIR := $(abspath $(CURDIR)/../bin)
|
||||
|
||||
TEST_BINS := \
|
||||
ioengine_single_blob_test \
|
||||
ioengine_multi_blob_test \
|
||||
ioengine_same_blob_mt_test
|
||||
|
||||
COMMON_SRCS := \
|
||||
test_common.c \
|
||||
../../src/spdk_engine/io_engine.c \
|
||||
../../src/common/utils.c
|
||||
|
||||
SPDK_LIB_LIST = $(ALL_MODULES_LIST) event event_bdev
|
||||
LIBS += $(SPDK_LIB_LINKER_ARGS)
|
||||
|
||||
CFLAGS += -I$(abspath $(CURDIR)/../../src) -I$(CURDIR)
|
||||
|
||||
.PHONY: all clean
|
||||
all: $(BIN_DIR) $(addprefix $(BIN_DIR)/,$(TEST_BINS))
|
||||
|
||||
# 创建 bin 目录
|
||||
$(BIN_DIR):
|
||||
mkdir -p $(BIN_DIR)
|
||||
|
||||
$(BIN_DIR)/ioengine_single_blob_test: ioengine_single_blob_test.c $(COMMON_SRCS) $(SPDK_LIB_FILES) $(ENV_LIBS)
|
||||
$(CC) $(CFLAGS) -o $@ $< $(COMMON_SRCS) $(LDFLAGS) $(LIBS) $(ENV_LDFLAGS) $(SYS_LIBS)
|
||||
|
||||
$(BIN_DIR)/ioengine_multi_blob_test: ioengine_multi_blob_test.c $(COMMON_SRCS) $(SPDK_LIB_FILES) $(ENV_LIBS)
|
||||
$(CC) $(CFLAGS) -o $@ $< $(COMMON_SRCS) $(LDFLAGS) $(LIBS) $(ENV_LDFLAGS) $(SYS_LIBS)
|
||||
|
||||
$(BIN_DIR)/ioengine_same_blob_mt_test: ioengine_same_blob_mt_test.c $(COMMON_SRCS) $(SPDK_LIB_FILES) $(ENV_LIBS)
|
||||
$(CC) $(CFLAGS) -o $@ $< $(COMMON_SRCS) $(LDFLAGS) $(LIBS) $(ENV_LDFLAGS) $(SYS_LIBS)
|
||||
|
||||
clean:
|
||||
rm -f $(addprefix $(BIN_DIR)/,$(TEST_BINS))
|
||||
@@ -1,106 +0,0 @@
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "spdk_engine/io_engine.h"
|
||||
#include "test_common.h"
|
||||
|
||||
#define MULTI_BLOB_COUNT 3
|
||||
|
||||
int main(void) {
|
||||
int rc = 0;
|
||||
const char *bdev_name = getenv("SPDK_BDEV_NAME");
|
||||
struct zvfs_blob_handle *handles[MULTI_BLOB_COUNT] = {0};
|
||||
uint64_t ids[MULTI_BLOB_COUNT] = {0};
|
||||
uint64_t cluster = 0;
|
||||
void *wbuf = NULL;
|
||||
void *rbuf = NULL;
|
||||
int i = 0;
|
||||
|
||||
if (!bdev_name) {
|
||||
bdev_name = "Malloc0";
|
||||
}
|
||||
if (io_engine_init(bdev_name) != 0) {
|
||||
fprintf(stderr, "TEST2: io_engine_init failed (bdev=%s)\n", bdev_name);
|
||||
return 1;
|
||||
}
|
||||
|
||||
printf("[TEST2] single thread / multi blob\n");
|
||||
|
||||
handles[0] = blob_create(0);
|
||||
if (!handles[0]) {
|
||||
fprintf(stderr, "TEST2: create first blob failed\n");
|
||||
return 1;
|
||||
}
|
||||
ids[0] = handles[0]->id;
|
||||
cluster = handles[0]->size;
|
||||
if (cluster == 0) {
|
||||
fprintf(stderr, "TEST2: invalid cluster size\n");
|
||||
rc = 1;
|
||||
goto out;
|
||||
}
|
||||
if (blob_resize(handles[0], cluster * 2) != 0) {
|
||||
fprintf(stderr, "TEST2: resize first blob failed\n");
|
||||
rc = 1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
for (i = 1; i < MULTI_BLOB_COUNT; i++) {
|
||||
handles[i] = blob_create(cluster * 2);
|
||||
if (!handles[i]) {
|
||||
fprintf(stderr, "TEST2: create blob %d failed\n", i);
|
||||
rc = 1;
|
||||
goto out;
|
||||
}
|
||||
ids[i] = handles[i]->id;
|
||||
}
|
||||
|
||||
if (alloc_aligned_buf(&wbuf, cluster) != 0 || alloc_aligned_buf(&rbuf, cluster) != 0) {
|
||||
fprintf(stderr, "TEST2: alloc aligned buffer failed\n");
|
||||
rc = 1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
for (i = 0; i < MULTI_BLOB_COUNT; i++) {
|
||||
fill_pattern((uint8_t *)wbuf, cluster, (uint8_t)(0x20 + i));
|
||||
memset(rbuf, 0, cluster);
|
||||
|
||||
if (blob_write(handles[i], 0, wbuf, cluster) != 0) {
|
||||
fprintf(stderr, "TEST2: blob_write[%d] failed\n", i);
|
||||
rc = 1;
|
||||
goto out;
|
||||
}
|
||||
if (blob_read(handles[i], 0, rbuf, cluster) != 0) {
|
||||
fprintf(stderr, "TEST2: blob_read[%d] failed\n", i);
|
||||
rc = 1;
|
||||
goto out;
|
||||
}
|
||||
if (memcmp(wbuf, rbuf, cluster) != 0) {
|
||||
fprintf(stderr, "TEST2: blob[%d] readback mismatch\n", i);
|
||||
rc = 1;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
out:
|
||||
for (i = 0; i < MULTI_BLOB_COUNT; i++) {
|
||||
if (handles[i]) {
|
||||
(void)blob_close(handles[i]);
|
||||
}
|
||||
}
|
||||
for (i = 0; i < MULTI_BLOB_COUNT; i++) {
|
||||
if (ids[i] != 0) {
|
||||
(void)blob_delete(ids[i]);
|
||||
}
|
||||
}
|
||||
free(wbuf);
|
||||
free(rbuf);
|
||||
|
||||
if (rc == 0) {
|
||||
printf("[TEST2] PASS\n");
|
||||
return 0;
|
||||
}
|
||||
printf("[TEST2] FAIL\n");
|
||||
return 1;
|
||||
}
|
||||
@@ -1,147 +0,0 @@
|
||||
#include <pthread.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "spdk_engine/io_engine.h"
|
||||
#include "test_common.h"
|
||||
|
||||
#define THREAD_COUNT 4
|
||||
|
||||
struct mt_case_arg {
|
||||
struct zvfs_blob_handle *handle;
|
||||
uint64_t cluster_size;
|
||||
uint64_t offset;
|
||||
uint8_t seed;
|
||||
pthread_barrier_t *barrier;
|
||||
int rc;
|
||||
};
|
||||
|
||||
static void *mt_case_worker(void *arg) {
|
||||
struct mt_case_arg *ctx = (struct mt_case_arg *)arg;
|
||||
void *wbuf = NULL;
|
||||
void *rbuf = NULL;
|
||||
|
||||
if (alloc_aligned_buf(&wbuf, ctx->cluster_size) != 0 ||
|
||||
alloc_aligned_buf(&rbuf, ctx->cluster_size) != 0) {
|
||||
free(wbuf);
|
||||
free(rbuf);
|
||||
ctx->rc = 1;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
fill_pattern((uint8_t *)wbuf, ctx->cluster_size, ctx->seed);
|
||||
(void)pthread_barrier_wait(ctx->barrier);
|
||||
|
||||
if (blob_write(ctx->handle, ctx->offset, wbuf, ctx->cluster_size) != 0) {
|
||||
ctx->rc = 1;
|
||||
goto out;
|
||||
}
|
||||
if (blob_read(ctx->handle, ctx->offset, rbuf, ctx->cluster_size) != 0) {
|
||||
ctx->rc = 1;
|
||||
goto out;
|
||||
}
|
||||
if (memcmp(wbuf, rbuf, ctx->cluster_size) != 0) {
|
||||
ctx->rc = 1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
ctx->rc = 0;
|
||||
|
||||
out:
|
||||
free(wbuf);
|
||||
free(rbuf);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
int rc = 0;
|
||||
const char *bdev_name = getenv("SPDK_BDEV_NAME");
|
||||
int i = 0;
|
||||
struct zvfs_blob_handle *h = NULL;
|
||||
uint64_t blob_id = 0;
|
||||
uint64_t cluster = 0;
|
||||
pthread_t tids[THREAD_COUNT];
|
||||
struct mt_case_arg args[THREAD_COUNT];
|
||||
pthread_barrier_t barrier;
|
||||
int barrier_inited = 0;
|
||||
|
||||
if (!bdev_name) {
|
||||
bdev_name = "Malloc0";
|
||||
}
|
||||
if (io_engine_init(bdev_name) != 0) {
|
||||
fprintf(stderr, "TEST3: io_engine_init failed (bdev=%s)\n", bdev_name);
|
||||
return 1;
|
||||
}
|
||||
|
||||
printf("[TEST3] multi thread / same blob\n");
|
||||
|
||||
h = blob_create(0);
|
||||
if (!h) {
|
||||
fprintf(stderr, "TEST3: blob_create failed\n");
|
||||
return 1;
|
||||
}
|
||||
blob_id = h->id;
|
||||
cluster = h->size;
|
||||
if (cluster == 0) {
|
||||
fprintf(stderr, "TEST3: invalid cluster size\n");
|
||||
rc = 1;
|
||||
goto out;
|
||||
}
|
||||
if (blob_resize(h, cluster * THREAD_COUNT) != 0) {
|
||||
fprintf(stderr, "TEST3: blob_resize failed\n");
|
||||
rc = 1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (pthread_barrier_init(&barrier, NULL, THREAD_COUNT) != 0) {
|
||||
fprintf(stderr, "TEST3: barrier init failed\n");
|
||||
rc = 1;
|
||||
goto out;
|
||||
}
|
||||
barrier_inited = 1;
|
||||
|
||||
for (i = 0; i < THREAD_COUNT; i++) {
|
||||
args[i].handle = h;
|
||||
args[i].cluster_size = cluster;
|
||||
args[i].offset = cluster * (uint64_t)i;
|
||||
args[i].seed = (uint8_t)(0x40 + i);
|
||||
args[i].barrier = &barrier;
|
||||
args[i].rc = 1;
|
||||
if (pthread_create(&tids[i], NULL, mt_case_worker, &args[i]) != 0) {
|
||||
fprintf(stderr, "TEST3: pthread_create[%d] failed\n", i);
|
||||
rc = 1;
|
||||
while (--i >= 0) {
|
||||
pthread_join(tids[i], NULL);
|
||||
}
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < THREAD_COUNT; i++) {
|
||||
pthread_join(tids[i], NULL);
|
||||
if (args[i].rc != 0) {
|
||||
fprintf(stderr, "TEST3: worker[%d] failed\n", i);
|
||||
rc = 1;
|
||||
}
|
||||
}
|
||||
|
||||
out:
|
||||
if (barrier_inited) {
|
||||
(void)pthread_barrier_destroy(&barrier);
|
||||
}
|
||||
if (h) {
|
||||
(void)blob_close(h);
|
||||
}
|
||||
if (blob_id != 0) {
|
||||
(void)blob_delete(blob_id);
|
||||
}
|
||||
|
||||
if (rc == 0) {
|
||||
printf("[TEST3] PASS\n");
|
||||
return 0;
|
||||
}
|
||||
printf("[TEST3] FAIL\n");
|
||||
return 1;
|
||||
}
|
||||
@@ -1,136 +0,0 @@
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "spdk_engine/io_engine.h"
|
||||
#include "test_common.h"
|
||||
|
||||
int main(void) {
|
||||
int rc = 0;
|
||||
const char *bdev_name = getenv("SPDK_BDEV_NAME");
|
||||
struct zvfs_blob_handle *h = NULL;
|
||||
struct zvfs_blob_handle *reopen = NULL;
|
||||
uint64_t blob_id = 0;
|
||||
uint64_t cluster = 0;
|
||||
void *wbuf = NULL;
|
||||
void *rbuf = NULL;
|
||||
|
||||
if (!bdev_name) {
|
||||
bdev_name = "Malloc0";
|
||||
}
|
||||
if (io_engine_init(bdev_name) != 0) {
|
||||
fprintf(stderr, "TEST1: io_engine_init failed (bdev=%s)\n", bdev_name);
|
||||
return 1;
|
||||
}
|
||||
|
||||
printf("[TEST1] single thread / single blob\n");
|
||||
|
||||
h = blob_create(0);
|
||||
if (!h) {
|
||||
fprintf(stderr, "TEST1: blob_create failed\n");
|
||||
return 1;
|
||||
}
|
||||
blob_id = h->id;
|
||||
cluster = h->size;
|
||||
if (cluster == 0) {
|
||||
fprintf(stderr, "TEST1: invalid cluster size\n");
|
||||
rc = 1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
rc = blob_resize(h, cluster * 2);
|
||||
if (rc != 0) {
|
||||
fprintf(stderr, "TEST1: blob_resize failed: %d\n", rc);
|
||||
rc = 1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
rc = alloc_aligned_buf(&wbuf, cluster);
|
||||
if (rc != 0) {
|
||||
fprintf(stderr, "TEST1: alloc write buf failed: %d\n", rc);
|
||||
rc = 1;
|
||||
goto out;
|
||||
}
|
||||
rc = alloc_aligned_buf(&rbuf, cluster);
|
||||
if (rc != 0) {
|
||||
fprintf(stderr, "TEST1: alloc read buf failed: %d\n", rc);
|
||||
rc = 1;
|
||||
goto out;
|
||||
}
|
||||
fill_pattern((uint8_t *)wbuf, cluster, 0x11);
|
||||
|
||||
rc = blob_write(h, 0, wbuf, cluster);
|
||||
if (rc != 0) {
|
||||
fprintf(stderr, "TEST1: blob_write failed: %d\n", rc);
|
||||
rc = 1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
rc = blob_read(h, 0, rbuf, cluster);
|
||||
if (rc != 0) {
|
||||
fprintf(stderr, "TEST1: blob_read failed: %d\n", rc);
|
||||
rc = 1;
|
||||
goto out;
|
||||
}
|
||||
if (memcmp(wbuf, rbuf, cluster) != 0) {
|
||||
fprintf(stderr, "TEST1: readback mismatch\n");
|
||||
rc = 1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
rc = blob_sync_md(h);
|
||||
if (rc != 0) {
|
||||
fprintf(stderr, "TEST1: blob_sync_md failed: %d\n", rc);
|
||||
rc = 1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
rc = blob_close(h);
|
||||
if (rc != 0) {
|
||||
fprintf(stderr, "TEST1: blob_close failed: %d\n", rc);
|
||||
rc = 1;
|
||||
goto out;
|
||||
}
|
||||
h = NULL;
|
||||
|
||||
reopen = blob_open(blob_id);
|
||||
if (!reopen) {
|
||||
fprintf(stderr, "TEST1: blob_open(reopen) failed\n");
|
||||
rc = 1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
memset(rbuf, 0, cluster);
|
||||
rc = blob_read(reopen, 0, rbuf, cluster);
|
||||
if (rc != 0) {
|
||||
fprintf(stderr, "TEST1: reopen blob_read failed: %d\n", rc);
|
||||
rc = 1;
|
||||
goto out;
|
||||
}
|
||||
if (memcmp(wbuf, rbuf, cluster) != 0) {
|
||||
fprintf(stderr, "TEST1: reopen readback mismatch\n");
|
||||
rc = 1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
out:
|
||||
if (reopen) {
|
||||
(void)blob_close(reopen);
|
||||
}
|
||||
if (h) {
|
||||
(void)blob_close(h);
|
||||
}
|
||||
if (blob_id != 0) {
|
||||
(void)blob_delete(blob_id);
|
||||
}
|
||||
free(wbuf);
|
||||
free(rbuf);
|
||||
|
||||
if (rc == 0) {
|
||||
printf("[TEST1] PASS\n");
|
||||
return 0;
|
||||
}
|
||||
printf("[TEST1] FAIL\n");
|
||||
return 1;
|
||||
}
|
||||
@@ -1,20 +0,0 @@
|
||||
#include "test_common.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
int alloc_aligned_buf(void **buf, size_t len) {
|
||||
int rc = posix_memalign(buf, 4096, len);
|
||||
if (rc != 0) {
|
||||
return -rc;
|
||||
}
|
||||
memset(*buf, 0, len);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void fill_pattern(uint8_t *buf, size_t len, uint8_t seed) {
|
||||
size_t i = 0;
|
||||
for (i = 0; i < len; i++) {
|
||||
buf[i] = (uint8_t)(seed + (uint8_t)i);
|
||||
}
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
#ifndef __IOENGINE_TEST_COMMON_H__
|
||||
#define __IOENGINE_TEST_COMMON_H__
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
int alloc_aligned_buf(void **buf, size_t len);
|
||||
void fill_pattern(uint8_t *buf, size_t len, uint8_t seed);
|
||||
|
||||
#endif // __IOENGINE_TEST_COMMON_H__
|
||||
Reference in New Issue
Block a user