Files

162 lines
6.8 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_bg_keep.c — 批①`background_keepalive` 声明层宿主单测。
*
* 验证 meow_parse_app_json 对 app.json 后台三位(background / background_audio /
* background_keepalive)的解析与 meow_acct_sync 透传,重点覆盖**前缀不串扰**:
* - "background_keepalive":true → a->background_keepalive=='1';且 background/background_audio
* 在该行不被误命中(分别是 0/0);
* - background:true → a->background=='1'(独立键匹配不受影响);
* - background_audio:true → a->background_audio=='1';
* - 一行三键并存:三者各归其位;
* - meow_acct_sync 透传 background_keepalive 到注册表。
* 实现手法同 test_fg_act.c:真实 include app_launcher.c,-ffunction-sections -Wl,--gc-sections
* 只保留 parseInt/acct_sync/upsert/find 触及函数;json_str/meow_parse_depends/logmsg 由本文件提供
* 忠实桩(json_str 复刻 util.c 语义,含键前缀独立 ident_ch + 整体 UTF-8 截断)。
*
* 运行(patch_v2/meow_launcherd 下):
* gcc -D_GNU_SOURCE -Wall -Wextra -ffunction-sections -Wl,--gc-sections \
* -I. -o test_bg_keep test_bg_keep.c && ./test_bg_keep
* 全 PASS -> exit 0。
*/
#ifndef _GNU_SOURCE
#define _GNU_SOURCE
#endif
#include <stdio.h>
#include <string.h>
#include <stdarg.h>
#include <stdlib.h>
/* ---- logmsg:app_launcher.c 依赖,minimal 桩 ---- */
void logmsg(const char *fmt, ...)
{
(void)fmt;
}
/* ---- json_str:复刻 util.c 语义(键前缀独立 + 值提取 + UTF-8 截断)---- */
static int ident_ch(char c)
{
return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') ||
(c >= '0' && c <= '9') || c == '_' || c == '.';
}
static void utf8_trim(char *s)
{
size_t n = strlen(s), i = 0, last_good = 0;
while (i < n) {
unsigned char c = (unsigned char)s[i];
int len = (c < 0x80) ? 1 : (c >= 0xF0) ? 4 : (c >= 0xE0) ? 3 : (c >= 0xC0) ? 2 : 1;
if (i + (size_t)len > n) break;
i += (size_t)len;
last_good = i;
}
s[last_good] = '\0';
}
int json_str(const char *buf, const char *key, char *out, int olen)
{
out[0] = 0;
if (!buf || !key || olen <= 0) return 0;
const char *p = strstr(buf, key);
if (!p) return 0;
if (p > buf && ident_ch((unsigned char)p[-1])) return 0; /* 键前缀需独立 */
p += strlen(key);
if (*p == '"') p++; /* JSON 键自身右引号 */
while (*p && (*p == ':' || *p == '=')) p++;
while (*p == ' ' || *p == '\t') p++;
if (*p == '"') p++; /* 值左引号 */
int i = 0;
while (*p && *p != '"' && *p != ',' && *p != '\n' && *p != '\r' && i < olen - 1)
out[i++] = *p++;
out[i] = 0;
while (i > 0 && (out[i - 1] == ' ' || out[i - 1] == '\t')) out[--i] = 0;
utf8_trim(out);
return (int)strlen(out);
}
#include "app_launcher.c" /* 真实实现:meow_parse_app_json / meow_acct_sync / meow_acct_upsert */
/* meow_parse_depends:本测试 app.json 无 depends 行,桩返回 0(struct meow_dep 此时已可见)。 */
int meow_parse_depends(const char *val, struct meow_dep *deps, int max)
{
(void)val; (void)deps; (void)max;
return 0;
}
static int g_fail = 0;
#define CHECK(cond, msg) do { \
if (!(cond)) { fprintf(stderr, "FAIL: %s (%s:%d)\n", msg, __FILE__, __LINE__); g_fail++; } \
else fprintf(stderr, "ok: %s\n", msg); \
} while (0)
/* 用一段 app.json 内容解析出 struct app。返回 0=成功。 */
static int parse_json(const char *content, struct app *a)
{
FILE *f = tmpfile();
if (!f) return -1;
fputs(content, f);
rewind(f);
memset(a, 0, sizeof *a);
meow_parse_app_json(f, a);
fclose(f);
return 0;
}
int main(void)
{
/* ---- 1) 单独 background_keepalive:true ---- */
{
struct app a;
parse_json("{\n\"name\":\"X\",\n\"exec\":\"/usr/bin/x\",\n\"background_keepalive\":true\n}", &a);
CHECK(a.background_keepalive == '1', "background_keepalive:true -> '1'");
CHECK(a.background == 0, "keepalive 行不误命中 background (==0)");
CHECK(a.background_audio == 0, "keepalive 行不误命中 background_audio (==0)");
}
/* ---- 2) 单独 background:true ---- */
{
struct app a;
parse_json("{\n\"name\":\"X\",\n\"exec\":\"/usr/bin/x\",\n\"background\":true\n}", &a);
CHECK(a.background == '1', "background:true -> '1'(独立键匹配不受影响)");
CHECK(a.background_keepalive == 0, "background 行不串 to keepalive (==0)");
CHECK(a.background_audio == 0, "background 行不串 to background_audio (==0)");
}
/* ---- 3) 单独 background_audio:true ---- */
{
struct app a;
parse_json("{\n\"name\":\"X\",\n\"exec\":\"/usr/bin/x\",\n\"background_audio\":true\n}", &a);
CHECK(a.background_audio == '1', "background_audio:true -> '1'");
CHECK(a.background == 0, "background_audio 行不误命中 background (==0)");
CHECK(a.background_keepalive == 0, "background_audio 行不串 to keepalive (==0)");
}
/* ---- 4) 三键并存:各归其位(逐行格式,值后跟 , 或换行,同真实 app.json) ---- */
{
struct app a;
parse_json("{\n\"name\":\"X\",\n\"exec\":\"/usr/bin/x\",\n\"background\":true,\n"
"\"background_audio\":true,\n\"background_keepalive\":true\n}", &a);
CHECK(a.background == '1', "三键并存 background=='1'");
CHECK(a.background_audio == '1', "三键并存 background_audio=='1'");
CHECK(a.background_keepalive == '1', "三键并存 background_keepalive=='1'");
}
/* ---- 5) 假值 / 前导噪声不应置位 ---- */
{
struct app a;
parse_json("{\n\"name\":\"X\",\n\"exec\":\"/usr/bin/x\",\n\"background_keepalive\":false,\n"
"\"background_audio\":0\n}", &a);
CHECK(a.background_keepalive == 0, "background_keepalive:false -> 0");
CHECK(a.background_audio == 0, "background_audio:0 -> 0");
CHECK(a.background == 0, "无 background 键 -> 0");
}
/* ---- 6) meow_acct_sync 透传 ---- */
{
struct app a;
parse_json("{\n\"name\":\"X\",\n\"exec\":\"/usr/bin/x\",\n"
"\"background_keepalive\":true,\n\"background_audio\":true\n}", &a);
meow_acct_sync("dev.test.keep", &a); /* 以 app_id 建/更注册表项 */
struct meow_acct *ac = meow_acct_find("dev.test.keep");
CHECK(ac != NULL, "meow_acct_sync 建注册表项");
CHECK(ac && ac->background_keepalive == '1', "透传 background_keepalive=='1'");
CHECK(ac && ac->background_audio == '1', "透传 background_audio=='1'");
CHECK(ac && ac->background == 0, "透传 background==0");
}
if (g_fail) { fprintf(stderr, "\n== %d assertion(s) FAILED ==\n", g_fail); return 1; }
fprintf(stderr, "\n== test_bg_keep ALL PASS ==\n");
return 0;
}