Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 8 additions & 2 deletions scripts/test_databases.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,14 @@
set -euo pipefail

if [[ $# -lt 1 || $# -gt 2 ]]; then
printf 'Usage: %s BUILD_DIR [local|redis|mysql|redis-awaitable|mysql-awaitable|public-redis|public-mysql|public-services|all]\n' "$0" >&2
printf 'Usage: %s BUILD_DIR [local|redis|mysql|redis-awaitable|mysql-awaitable|public-redis|public-mysql|public-services|public-redis-failures|public-mysql-failures|all]\n' "$0" >&2
exit 2
fi

database_test_dir=$(cd -- "$1" && pwd)/tests/database
database_test_mode=${2:-local}
case "$database_test_mode" in
local|redis|mysql|redis-awaitable|mysql-awaitable|public-redis|public-mysql|public-services|all) ;;
local|redis|mysql|redis-awaitable|mysql-awaitable|public-redis|public-mysql|public-services|public-redis-failures|public-mysql-failures|all) ;;
*) printf 'Unknown database test mode: %s\n' "$database_test_mode" >&2; exit 2 ;;
esac

Expand Down Expand Up @@ -56,3 +56,9 @@ fi
if [[ "$database_test_mode" == public-mysql || "$database_test_mode" == public-services || "$database_test_mode" == all ]]; then
run_database_test ark_database_public_service_tests mysql
fi
if [[ "$database_test_mode" == public-redis-failures ]]; then
run_database_test ark_database_public_failure_service_tests redis
fi
if [[ "$database_test_mode" == public-mysql-failures ]]; then
run_database_test ark_database_public_failure_service_tests mysql
fi
12 changes: 10 additions & 2 deletions tests/database/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,13 @@ target_link_libraries(ark_database_redis_stop_tests PRIVATE arknet::arknet)
ark_database_test(ark_database_public_redis_tests main.cpp public_redis_module.cpp
"${ROOT_DIR}/src/plugins/redis/redis_module_impl.cpp")
target_link_libraries(ark_database_public_redis_tests PRIVATE ark::core arknet::arknet)
# Explicit real-service acceptance; deliberately excluded from check-database.
# Real-service programs are compiled by check-database, but never run there.
ark_database_test(ark_database_public_service_tests public_service.cpp
"${ROOT_DIR}/src/plugins/redis/redis_module_impl.cpp")
target_link_libraries(ark_database_public_service_tests PRIVATE ark::core arknet::arknet)
ark_database_test(ark_database_public_failure_service_tests public_failure_service.cpp
"${ROOT_DIR}/src/plugins/redis/redis_module_impl.cpp")
target_link_libraries(ark_database_public_failure_service_tests PRIVATE ark::core arknet::arknet)
add_library(ark_database_redis_plugin SHARED
"${ROOT_DIR}/src/plugins/redis/redis_plugin.cpp" "${ROOT_DIR}/src/plugins/redis/redis_module_impl.cpp")
target_include_directories(ark_database_redis_plugin PRIVATE "${ROOT_DIR}/src/plugins")
Expand Down Expand Up @@ -72,9 +75,14 @@ add_custom_target(check-database
USES_TERMINAL)

# Compile real-service acceptance in ordinary CI without running any server work.
add_dependencies(check-database ark_database_redis_sample_check ark_database_public_service_tests)
add_dependencies(check-database ark_database_redis_sample_check ark_database_public_service_tests
ark_database_public_failure_service_tests)

if(ARKNET_ENABLE_SSL)
target_sources(ark_database_public_failure_service_tests PRIVATE
"${ROOT_DIR}/src/plugins/mysql/mysql_module_impl.cpp")
target_compile_definitions(ark_database_public_failure_service_tests PRIVATE
ARK_DATABASE_UNTRUSTED_CA="${ARKNET_SOURCE_DIR}/tests/certs/wrong.pem")
target_sources(ark_database_public_service_tests PRIVATE
"${ROOT_DIR}/src/plugins/mysql/mysql_module_impl.cpp")
target_compile_definitions(ark_database_public_redis_tests PRIVATE
Expand Down
48 changes: 48 additions & 0 deletions tests/database/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -238,3 +238,51 @@ configuration or failure, and does not print credentials or arbitrary native err
messages. It never starts or stops servers. `all` also includes both public
real-service modes and therefore requires an SSL-enabled build and both endpoint
configurations.

## Public real-service failure checks

The separate `ark_database_public_failure_service_tests` executable checks wrong
Redis/MySQL passwords, an untrusted MySQL CA, and real slow-command deadlines.
`check-database` compiles it without running it. Choose a failure mode explicitly;
these modes are not included in `all`.

```sh
cmake --build database-build --target ark_database_public_failure_service_tests --parallel 2
bash scripts/test_databases.sh database-build public-redis-failures
bash scripts/test_databases.sh database-build public-mysql-failures
# Or invoke the executable with redis or mysql.
```

Use the same isolated endpoint variables as the public service checks above.
The Redis failure mode additionally requires a nonempty
`ARK_DATABASE_REDIS_PASSWORD` and permission for `CLIENT LIST`. MySQL requires SSL,
a trusted `ARK_DATABASE_MYSQL_CA` and access to the current account's sessions in
`information_schema.processlist`; no PROCESS privilege or extra schema is needed.
The unrelated CA fixture is `ARKNET_SOURCE_DIR/tests/certs/wrong.pem`, already used
by the local TLS regressions. No new environment variable or service management is
introduced. Missing configuration, observer permission errors, or a requested
protocol unavailable in the build fail with nonzero status.

Credential/TLS failures must retain their native error and known-unsent business
command state. Subsequent explicit requests use the valid configuration. The
warmed primary then runs BLPOP on an absent unique `ark_failure_...` key (30-second
server block) or a tagged `SELECT SLEEP(10)`, with a two-second client deadline.
BLPOP never receives producer data; the test first checks that its key is absent.
Both deadlines must be delivered within five seconds.

An independently configured connection observes Redis's named blocked client via
`CLIENT LIST`, or MySQL's tagged sleeping session via `processlist`. Only this
server-visible observation establishes that the request was sent; polling timers
only throttle observations. The timeout must retain its unknown-execution flag.
An explicit new PING/SELECT must recover through the same public connection name.
The observer rejects a second slow client/session, then checks for 500 ms after
the original disappears. This bounds the no-replay evidence to these tagged
slow requests during the observed recovery window; it does not prove write-replay
behavior or absence of later activity outside the window.

All coroutines and task completions must stay on the owner thread/shared manual
runtime. Accepted slow/observer tasks finish during natural manager drain before
native retirement and idempotent stop. These cases do not test cancellation,
server termination, dynamic-library unloading or capacity. Slow-query results
remain owned after module destruction. Native/server error text and credentials
are not printed.
37 changes: 37 additions & 0 deletions tests/database/README_CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -190,3 +190,40 @@ MySQL 要求设置 `ARK_DATABASE_MYSQL_HOST`、`ARK_DATABASE_MYSQL_PORT`、
程序必须显式配置端点;配置缺失、无效或验收失败均返回非零状态,不打印凭据或任意原生错误文本,
也不会启动或停止服务。`all` 也运行这两种公开模块真实服务模式,因此要求启用 SSL,
并配置两种服务的端点。

## 公开模块真实服务负面验收

独立的 `ark_database_public_failure_service_tests` 验证 Redis/MySQL 错误密码、
MySQL 不可信 CA,以及真实慢命令的截止时间。`check-database` 仅编译该程序,不运行。
需显式选择负面验收模式;`all` 不包含这些模式。

```sh
cmake --build database-build --target ark_database_public_failure_service_tests --parallel 2
bash scripts/test_databases.sh database-build public-redis-failures
bash scripts/test_databases.sh database-build public-mysql-failures
# 也可以直接运行程序,参数为 redis 或 mysql。
```

沿用上方公开服务验收的隔离端点环境变量。Redis 负面模式额外要求非空的
`ARK_DATABASE_REDIS_PASSWORD`,账号需有 `CLIENT LIST` 权限。MySQL 要求开启 SSL、
使用可信的 `ARK_DATABASE_MYSQL_CA`,且账号能通过 `information_schema.processlist`
查看自身会话;不需要 PROCESS 权限或额外数据库。不可信 CA 使用本地 TLS 回归已有的
`ARKNET_SOURCE_DIR/tests/certs/wrong.pem`,不引入新的环境变量或服务管理操作。
配置缺失、观察连接权限不足或构建中没有请求的协议时,程序返回非零状态。

认证/TLS 失败必须保留原生错误,以及业务命令尚未发送的已知状态。随后使用正确配置显式发起
新请求。预热后的主连接对不存在的唯一 `ark_failure_...` key 执行 BLPOP(服务端阻塞
30 秒),或执行带唯一注释的 `SELECT SLEEP(10)`,客户端截止时间均为 2 秒。
测试先检查 Redis key 不存在,且不会向该 key 写入数据。两种超时结果均须在 5 秒内交付。

独立配置的观察连接通过 Redis `CLIENT LIST` 确认具名客户端正在阻塞,或通过 MySQL
`processlist` 确认带唯一注释的会话正在休眠。只有服务端可见状态用于确认请求已经发送;
轮询定时器仅控制观察频率。超时结果必须保留执行状态未知标志。随后通过同一公开连接名显式
执行 PING/SELECT,并验证恢复成功。观察连接拒绝出现第二个慢客户端或会话,且在原请求消失后
继续检查 500 毫秒。该证据仅覆盖观察窗口内的慢查询恢复,不证明写操作的重放行为,也不证明
窗口以外没有后续活动。

所有协程及任务完成回调均须在拥有线程及共享手动运行时上执行。管理器进入自然排空状态后,
已受理的慢请求和观察任务继续执行,完成后才退出原生资源,并验证停止操作可重复调用。
这些用例不测试取消、服务端终止、动态库卸载或容量。模块销毁后,慢查询结果仍须有效。
程序不打印凭据、原生错误文本或服务端错误文本。
Loading
Loading