Files

174 lines
7.7 KiB
C
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/* test_bgmgr.c — 批③ 后台管理页 逻辑层宿主单测(meow_bgmgr)。
*
* 验证:
* 1) bgmgr_collect:enumerate 后台表 → app_meta 补 name/icon/framework/is_fg → proc_sample 补
* pcpu/rss_kb;行 killable 预判正确;name 回退 app_id。
* 2) bgmgr_can_kill 门控矩阵:framework=1 → 0(**框架 App 不 kill**);is_fg=1 → 0(当前前台不 kill);
* pid<=0 → 0(非后台/无进程);普通后台(非框架/非前台/pid>0)→ 1。
* 3) bgmgr_kill_all 一键清:框架 App 不杀、当前前台不杀、非后台不杀;其余逐一 kill;返回 kill 数。
* 4) bgmgr_status_str / bgmgr_mem_str 文案。
* 只依赖 meow_bgmgr.c + meow_ipc.h(纯 C);宿主 gcc 直编:
* gcc -Wall -Wextra -std=gnu99 test_bgmgr.c meow_bgmgr.c -o test_bgmgr
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdint.h>
#include "meow_bgmgr.h"
static int g_fails = 0;
#define CHECK(cond, msg) do { \
if (cond) printf("PASS: %s\n", msg); \
else { printf("FAIL: %s\n", msg); g_fails++; } } while (0)
/* ---- 假件(enumerate/app_meta/proc_sample 注入)---- */
static const char g_meta_app[][24] = {
"os.meow.hello", "os.meow.reader", "os.meow.sysguard", "os.meow.fgapp",
};
static int g_killed_n = 0;
static char g_killed_app[8][40];
static int g_meta_use_unknown = 0; /* 第 4 行 meta 返回 -1(未注册),测 name 回退 */
static int fake_enumerate(void *ctx, bgmgr_row_t *rows, int max)
{
(void)ctx;
if (max < 4) return 0;
/* 4 个后台行:hello=普通、reader=常驻、sysguard=framework、fgapp=当前前台 */
memset(&rows[0], 0, sizeof rows[0]);
snprintf(rows[0].app_id, sizeof rows[0].app_id, "%s", g_meta_app[0]);
rows[0].pid = 1001; rows[0].keepalive = 0; rows[0].on_card = 0; rows[0].bg_since_ms = 1000;
memset(&rows[1], 0, sizeof rows[1]);
snprintf(rows[1].app_id, sizeof rows[1].app_id, "%s", g_meta_app[1]);
rows[1].pid = 1002; rows[1].keepalive = 1; rows[1].on_card = 0; rows[1].bg_since_ms = 2000;
memset(&rows[2], 0, sizeof rows[2]);
snprintf(rows[2].app_id, sizeof rows[2].app_id, "%s", g_meta_app[2]);
rows[2].pid = 1003; rows[2].keepalive = 0; rows[2].on_card = 0; rows[2].bg_since_ms = 3000;
memset(&rows[3], 0, sizeof rows[3]);
snprintf(rows[3].app_id, sizeof rows[3].app_id, "%s", g_meta_app[3]);
rows[3].pid = 1004; rows[3].keepalive = 0; rows[3].on_card = 0; rows[3].bg_since_ms = 4000;
return 4;
}
/* meta:hello/reader/sysguard/fgapp 各给名字;sysguard 标 framework;pid==1004 标前台。 */
static int fake_app_meta(void *ctx, const char *app_id, pid_t pid,
char *name, int nl, char *icon, int il,
char *framework, int *is_fg)
{
(void)ctx;
if (!strcmp(app_id, "os.meow.hello")) snprintf(name, nl, "播放");
else if (!strcmp(app_id, "os.meow.reader")) snprintf(name, nl, "阅读");
else if (!strcmp(app_id, "os.meow.sysguard")) snprintf(name, nl, "系统守护");
else if (!strcmp(app_id, "os.meow.fgapp")) snprintf(name, nl, "前台应用");
else return -1; /* 未注册 → name 回退 app_id */
snprintf(icon, il, "/tmp/icon_%s.png", app_id);
*framework = (!strcmp(app_id, "os.meow.sysguard")) ? '1' : 0;
*is_fg = (pid == 1004) ? 1 : 0; /* fgapp 标前台 */
return 0;
}
static int fake_proc_sample(void *ctx, pid_t pid, double *pcpu, long *rss_kb)
{
(void)ctx;
if (pid <= 0) return -1;
*pcpu = (double)(pid % 100) * 0.5; /* 1001->0.5% ... 1004->2.0% */
*rss_kb = (long)(pid % 10) * 2048; /* 1001->2048 ... 1004->8192 */
return 0;
}
static void fake_log(const char *fmt, ...) { (void)fmt; }
static void fake_kill(const char *app_id)
{
if (g_killed_n < 8) snprintf(g_killed_app[g_killed_n++], 40, "%s", app_id);
}
/* enumerate 只回一行:未注册 app_id,测 name 回退。 */
static int fake_enumerate_unknown(void *ctx, bgmgr_row_t *rows, int max)
{
(void)ctx;
if (max < 1) return 0;
(void)g_meta_use_unknown;
memset(&rows[0], 0, sizeof rows[0]);
snprintf(rows[0].app_id, sizeof rows[0].app_id, "os.meow.noreg");
rows[0].pid = 2001; rows[0].keepalive = 0;
return 1;
}
int main(void)
{
bgmgr_ops_t ops;
memset(&ops, 0, sizeof ops);
ops.enumerate = fake_enumerate;
ops.app_meta = fake_app_meta;
ops.proc_sample = fake_proc_sample;
ops.log = fake_log;
bgmgr_row_t rows[MEOW_BGMR_ROW_MAX];
int n = bgmgr_collect(&ops, rows, MEOW_BGMR_ROW_MAX);
printf("=== 1) collect ===\n");
CHECK(n == 4, "collect returns 4 rows");
CHECK(!strcmp(rows[0].name, "播放") && rows[0].pid == 1001, "row0 hello name/pid");
CHECK(rows[0].framework == 0, "row0 hello not framework");
CHECK(!strcmp(rows[1].name, "阅读") && rows[1].keepalive == 1, "row1 reader keepalive");
CHECK(rows[2].framework == '1', "row2 sysguard framework");
CHECK(rows[3].is_fg == 1, "row3 fgapp is_fg");
CHECK(rows[0].pcpu > 0 && rows[0].rss_kb > 0, "row0 pcpu/rss populated");
CHECK(rows[0].killable == 1 && rows[2].killable == 0, "killable prefilled by can_kill");
CHECK(!strcmp(rows[2].icon, "/tmp/icon_os.meow.sysguard.png"), "icon populated");
/* name 回退:未注册 app_id(app_meta 返回 -1)→ name==app_id */
printf("=== 1b) name fallback ===\n");
{
bgmgr_ops_t o2 = ops; o2.enumerate = fake_enumerate_unknown;
bgmgr_row_t r1[1]; memset(r1, 0, sizeof r1);
int n2 = bgmgr_collect(&o2, r1, 1);
CHECK(n2 == 1, "unknown row collected");
CHECK(!strcmp(r1[0].name, "os.meow.noreg"), "name falls back to app_id");
CHECK(bgmgr_can_kill(&r1[0]) == 1, "unknown bg app still killable");
}
printf("=== 2) can_kill gating ===\n");
CHECK(bgmgr_can_kill(&rows[2]) == 0, "framework app NOT killable");
CHECK(bgmgr_can_kill(&rows[3]) == 0, "fg app NOT killable (is_fg)");
CHECK(bgmgr_can_kill(&rows[0]) == 1, "normal bg app killable");
CHECK(bgmgr_can_kill(&rows[1]) == 1, "keepalive bg app killable");
{
bgmgr_row_t dead; memset(&dead, 0, sizeof dead);
snprintf(dead.app_id, sizeof dead.app_id, "x");
dead.pid = 0;
CHECK(bgmgr_can_kill(&dead) == 0, "pid<=0 NOT killable");
CHECK(bgmgr_can_kill(NULL) == 0, "NULL NOT killable");
}
printf("=== 3) kill_all (one-key clear) ===\n");
g_killed_n = 0;
int k = bgmgr_kill_all(&ops, rows, n, fake_kill);
CHECK(k == 2, "kill_all kills 2 (hello+reader)");
CHECK(g_killed_n == 2, "kill_all actually invoked kill_fn 2x");
int killed_fw = 0, killed_fg = 0, killed_bg = 0;
for (int i = 0; i < g_killed_n; i++) {
if (!strcmp(g_killed_app[i], "os.meow.sysguard")) killed_fw = 1;
if (!strcmp(g_killed_app[i], "os.meow.fgapp")) killed_fg = 1;
if (!strcmp(g_killed_app[i], "os.meow.hello")) killed_bg = 1;
}
CHECK(killed_fw == 0, "kill_all did NOT kill framework app");
CHECK(killed_fg == 0, "kill_all did NOT kill fg app");
CHECK(killed_bg == 1, "kill_all killed a real bg app");
CHECK(bgmgr_kill_all(&ops, rows, n, NULL) == 0, "kill_all NULL kill_fn -> 0");
printf("=== 4) status/mem str ===\n");
CHECK(!strcmp(bgmgr_status_str(&rows[1]), "常驻"), "status_str keepalive=常驻");
CHECK(!strcmp(bgmgr_status_str(&rows[0]), "后台"), "status_str normal=后台");
CHECK(!strcmp(bgmgr_status_str(&rows[3]), "前台"), "status_str is_fg=前台");
CHECK(!strcmp(bgmgr_mem_str(512), "512KB"), "mem_str(<1MB)=KB");
CHECK(!strcmp(bgmgr_mem_str(2048), "2.0MB"), "mem_str(>=1MB)=MB");
if (g_fails == 0) printf("\nALL PASS (%d checks)\n", 20);
else printf("\n%d FAILED\n", g_fails);
return g_fails ? 1 : 0;
}