mirror of
https://github.com/aydencharles/onionHEN.git
synced 2026-10-22 20:02:59 -05:00
240 lines
7.4 KiB
C
240 lines
7.4 KiB
C
/* Host tests for process-name conflict strategies. */
|
|
#include "test_harness.h"
|
|
|
|
#include <onion/conflict.h>
|
|
#include <onion/proc_query.h>
|
|
|
|
#include <string.h>
|
|
|
|
static const char *g_live[8];
|
|
static size_t g_live_count;
|
|
|
|
static void live_reset(void) { g_live_count = 0; }
|
|
|
|
static void live_add(const char *name) {
|
|
if (g_live_count < sizeof(g_live) / sizeof(g_live[0]))
|
|
g_live[g_live_count++] = name;
|
|
}
|
|
|
|
static pid_t fake_find_pid(const char *name) {
|
|
if (!name)
|
|
return -1;
|
|
for (size_t i = 0; i < g_live_count; ++i) {
|
|
if (strcmp(g_live[i], name) == 0)
|
|
return (pid_t)1000 + (pid_t)i;
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
static int assert_detect(const char *live, const char *family) {
|
|
live_reset();
|
|
if (live)
|
|
live_add(live);
|
|
const char *got = onion_conflict_detect_with(fake_find_pid);
|
|
if (!family) {
|
|
TEST_ASSERT_TRUE(got == NULL);
|
|
return 0;
|
|
}
|
|
TEST_ASSERT_STREQ(family, got);
|
|
return 0;
|
|
}
|
|
|
|
static int test_builtin_hits(void) {
|
|
/* Live names come from kinfo_proc, so they can never be longer than
|
|
* ki_comm (19) or ki_tdname (16). The >19 entries below therefore test the
|
|
* candidate generator, not a state the kernel can actually report; the
|
|
* <=19 ones are what fires on hardware. Both matter: the first catches a
|
|
* dropped candidate, the second catches a broken truncation. */
|
|
static const struct {
|
|
const char *live;
|
|
const char *family;
|
|
} kCases[] = {
|
|
{"etaHEN Utility Daemon", "etaHEN"}, /* generator only */
|
|
{"etaHEN Critical services", "etaHEN"}, /* generator only */
|
|
{"etaHEN Utility Daemon.elf", "etaHEN"}, /* generator only */
|
|
{"etaHEN Utility Daem", "etaHEN"}, /* ki_comm */
|
|
{"etaHEN Critical ser", "etaHEN"}, /* ki_comm */
|
|
{"etaHEN Utility D", "etaHEN"}, /* ki_tdname */
|
|
{"etaHEN Critical ", "etaHEN"}, /* ki_tdname, trailing space */
|
|
{"Yoncore.elf", "Yoncore"},
|
|
{"Yoncore", "Yoncore"},
|
|
{"kylin-core.elf", "kylin-core"},
|
|
{"kylin-core", "kylin-core"},
|
|
{"wmdw-jwm.elf", "wmdw-jwm"},
|
|
{"wmdw-jwm", "wmdw-jwm"},
|
|
{"CheatRunner.elf", "CheatRunner"},
|
|
{"CheatRunner", "CheatRunner"},
|
|
{"daemon.elf", NULL},
|
|
{"util.elf", NULL},
|
|
{"kstuff.elf", NULL},
|
|
{"etaHEN.elf", NULL},
|
|
};
|
|
|
|
for (size_t i = 0; i < sizeof(kCases) / sizeof(kCases[0]); ++i) {
|
|
const int rc = assert_detect(kCases[i].live, kCases[i].family);
|
|
if (rc != 0)
|
|
return rc;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
static int test_no_live_processes(void) {
|
|
live_reset();
|
|
TEST_ASSERT_TRUE(onion_conflict_detect_with(fake_find_pid) == NULL);
|
|
TEST_ASSERT_TRUE(onion_conflict_detect_with(NULL) == NULL);
|
|
TEST_ASSERT_TRUE(onion_conflict_detect() == NULL);
|
|
return 0;
|
|
}
|
|
|
|
static int test_elf_suffix_ignored(void) {
|
|
static const char *with_elf[] = {"foo.elf", NULL};
|
|
static const char *without_elf[] = {"bar", NULL};
|
|
static const OnionConflictStrategy table[] = {
|
|
{"with", with_elf},
|
|
{"without", without_elf},
|
|
};
|
|
|
|
live_reset();
|
|
live_add("foo");
|
|
TEST_ASSERT_STREQ("with", onion_conflict_scan(table, 2, fake_find_pid));
|
|
|
|
live_reset();
|
|
live_add("foo.elf");
|
|
TEST_ASSERT_STREQ("with", onion_conflict_scan(table, 2, fake_find_pid));
|
|
|
|
live_reset();
|
|
live_add("bar.elf");
|
|
TEST_ASSERT_STREQ("without", onion_conflict_scan(table, 2, fake_find_pid));
|
|
|
|
live_reset();
|
|
live_add("bar");
|
|
TEST_ASSERT_STREQ("without", onion_conflict_scan(table, 2, fake_find_pid));
|
|
|
|
live_reset();
|
|
live_add("foo.elf.bak");
|
|
live_add("bar.elfx");
|
|
TEST_ASSERT_TRUE(onion_conflict_scan(table, 2, fake_find_pid) == NULL);
|
|
return 0;
|
|
}
|
|
|
|
static int test_truncation_lengths(void) {
|
|
static const char *names[] = {"etaHEN Utility Daemon", NULL};
|
|
static const OnionConflictStrategy table[] = {{"etaHEN", names}};
|
|
|
|
TEST_ASSERT_TRUE(strlen("etaHEN Utility Daemon") > ONION_PROC_KI_COMM_LEN);
|
|
TEST_ASSERT_TRUE(ONION_PROC_KI_TDNAM_LEN < ONION_PROC_KI_COMM_LEN);
|
|
|
|
/* ki_comm keeps COMMLEN=19 chars. */
|
|
live_reset();
|
|
live_add("etaHEN Utility Daem");
|
|
TEST_ASSERT_STREQ("etaHEN", onion_conflict_scan(table, 1, fake_find_pid));
|
|
|
|
/* ki_tdname keeps only TDNAMLEN=16; a thread-name-only hit must still be
|
|
* detected, otherwise the whole family is missed. */
|
|
live_reset();
|
|
live_add("etaHEN Utility D");
|
|
TEST_ASSERT_STREQ("etaHEN", onion_conflict_scan(table, 1, fake_find_pid));
|
|
|
|
/* A shorter truncation than either field is not a hit. */
|
|
live_reset();
|
|
live_add("etaHEN Utilit");
|
|
TEST_ASSERT_TRUE(onion_conflict_scan(table, 1, fake_find_pid) == NULL);
|
|
return 0;
|
|
}
|
|
|
|
static int test_scan_first_family_wins(void) {
|
|
static const char *alpha_names[] = {"alpha.elf", NULL};
|
|
static const char *beta_names[] = {"beta.elf", NULL};
|
|
static const OnionConflictStrategy table[] = {
|
|
{"alpha", alpha_names},
|
|
{"beta", beta_names},
|
|
};
|
|
|
|
live_reset();
|
|
live_add("beta.elf");
|
|
live_add("alpha.elf");
|
|
TEST_ASSERT_STREQ("alpha", onion_conflict_scan(table, 2, fake_find_pid));
|
|
|
|
live_reset();
|
|
live_add("beta.elf");
|
|
TEST_ASSERT_STREQ("beta", onion_conflict_scan(table, 2, fake_find_pid));
|
|
return 0;
|
|
}
|
|
|
|
static int expect_family_names(const char *family, const char *const *names) {
|
|
size_t count = 0;
|
|
const OnionConflictStrategy *table = onion_conflict_strategies(&count);
|
|
TEST_ASSERT_TRUE(table != NULL);
|
|
TEST_ASSERT_TRUE(count >= 5);
|
|
|
|
const OnionConflictStrategy *found = NULL;
|
|
for (size_t i = 0; i < count; ++i) {
|
|
if (table[i].family && strcmp(table[i].family, family) == 0) {
|
|
found = &table[i];
|
|
break;
|
|
}
|
|
}
|
|
TEST_ASSERT_TRUE(found != NULL);
|
|
TEST_ASSERT_TRUE(found->proc_names != NULL);
|
|
|
|
for (size_t i = 0; names[i]; ++i) {
|
|
TEST_ASSERT_TRUE(found->proc_names[i] != NULL);
|
|
TEST_ASSERT_STREQ(names[i], found->proc_names[i]);
|
|
}
|
|
TEST_ASSERT_TRUE(found->proc_names[0] != NULL);
|
|
size_t got = 0;
|
|
while (found->proc_names[got])
|
|
++got;
|
|
size_t want = 0;
|
|
while (names[want])
|
|
++want;
|
|
TEST_ASSERT_TRUE(got == want);
|
|
return 0;
|
|
}
|
|
|
|
static int test_builtin_table(void) {
|
|
static const char *etahen[] = {
|
|
"etaHEN Utility Daemon",
|
|
"etaHEN Critical services",
|
|
NULL,
|
|
};
|
|
static const char *yoncore[] = {"Yoncore.elf", NULL};
|
|
static const char *kylin[] = {"kylin-core.elf", NULL};
|
|
static const char *wmdw[] = {"wmdw-jwm.elf", NULL};
|
|
static const char *cheat[] = {"CheatRunner.elf", NULL};
|
|
|
|
static const struct {
|
|
const char *family;
|
|
const char *const *names;
|
|
} kFamilies[] = {
|
|
{"etaHEN", etahen},
|
|
{"Yoncore", yoncore},
|
|
{"kylin-core", kylin},
|
|
{"wmdw-jwm", wmdw},
|
|
{"CheatRunner", cheat},
|
|
};
|
|
|
|
for (size_t i = 0; i < sizeof(kFamilies) / sizeof(kFamilies[0]); ++i) {
|
|
const int rc =
|
|
expect_family_names(kFamilies[i].family, kFamilies[i].names);
|
|
if (rc != 0)
|
|
return rc;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
int test_conflict_suite(void) {
|
|
int failures = 0;
|
|
failures += onion_test_run("conflict_builtin_hits", test_builtin_hits);
|
|
failures += onion_test_run("conflict_no_live_processes",
|
|
test_no_live_processes);
|
|
failures += onion_test_run("conflict_elf_suffix_ignored",
|
|
test_elf_suffix_ignored);
|
|
failures += onion_test_run("conflict_truncation_lengths",
|
|
test_truncation_lengths);
|
|
failures += onion_test_run("conflict_scan_first_family_wins",
|
|
test_scan_first_family_wins);
|
|
failures += onion_test_run("conflict_builtin_table", test_builtin_table);
|
|
return failures;
|
|
}
|