Password Realm no longer auto-enables parliament (keeps task/worker tools); finished jobs fan out to agent notes + TUI; raise PAR_MAX/grep caps and tag truncations. Co-authored-by: Cursor <cursoragent@cursor.com>
127 lines
4.5 KiB
C
127 lines
4.5 KiB
C
#define _POSIX_C_SOURCE 200809L
|
|
#include "cst_parliament.h"
|
|
#include "cst_realm.h"
|
|
#include "cst_test_util.h"
|
|
#include "os_compat.h"
|
|
|
|
#include <assert.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
|
|
int main(void) {
|
|
char dir[2048], cfg[512];
|
|
assert(!test_tmpdir(dir, sizeof(dir), "parliament"));
|
|
assert(snprintf(cfg, sizeof(cfg), "%s/cfg", dir) < (int)sizeof(cfg));
|
|
assert(!os_mkdir_p(cfg, 0700));
|
|
setenv("XDG_CONFIG_HOME", cfg, 1);
|
|
|
|
char realm[OS_PATH_MAX];
|
|
assert(cst_realm_dir(realm, sizeof(realm)) == 0);
|
|
assert(cst_realm_init_password(realm, "correct horse battery") == 0);
|
|
assert(cst_realm_is_password_mode(realm));
|
|
|
|
cst_realm_keys_t bad, good;
|
|
assert(cst_realm_unlock_password(realm, "wrong", &bad) != 0);
|
|
assert(cst_realm_unlock_password(realm, "correct horse battery", &good) == 0);
|
|
/* Password Realm alone must not force parliament (solo keeps workers). */
|
|
unsetenv("CST_COLLABORATION");
|
|
assert(!cst_parliament_is_active());
|
|
|
|
char err[128];
|
|
char *hand = cst_parliament_login("correct horse battery", "phone-1", "pixel",
|
|
err, sizeof(err));
|
|
assert(hand && strstr(hand, "LOGIN_OK") && strstr(hand, "chair=phone-1"));
|
|
free(hand);
|
|
assert(cst_parliament_is_chair());
|
|
assert(cst_parliament_sync_pending()); /* login bumps context path request */
|
|
|
|
cst_parliament_meta_t m;
|
|
assert(cst_parliament_load(&m) == 0);
|
|
assert(!strcmp(m.chair_instance, "phone-1"));
|
|
|
|
assert(cst_parliament_context_put("shared agenda v1") == 0);
|
|
assert(cst_parliament_sync_pending());
|
|
cst_parliament_sync_ack();
|
|
assert(!cst_parliament_sync_pending());
|
|
|
|
hand = cst_parliament_login("correct horse battery", "laptop-2", "thinkpad",
|
|
err, sizeof(err));
|
|
assert(hand && strstr(hand, "handover_from=phone-1"));
|
|
assert(strstr(hand, "shared agenda v1"));
|
|
free(hand);
|
|
assert(cst_parliament_load(&m) == 0);
|
|
assert(!strcmp(m.chair_instance, "laptop-2"));
|
|
assert(cst_parliament_is_chair());
|
|
|
|
assert(cst_parliament_session_ok(NULL, 0));
|
|
|
|
/* Member seat can join without stealing the chair. */
|
|
hand = cst_parliament_seat_join("correct horse battery", "tablet-3", "pad",
|
|
err, sizeof(err));
|
|
assert(hand && strstr(hand, "JOIN_OK") && strstr(hand, "role=member"));
|
|
assert(strstr(hand, "chair=laptop-2"));
|
|
free(hand);
|
|
/* Join rewrote the local seat ticket to tablet-3 (this process). */
|
|
{
|
|
char sid[64] = {0};
|
|
assert(cst_parliament_session_ok(sid, sizeof(sid)));
|
|
assert(!strcmp(sid, "tablet-3"));
|
|
assert(!cst_parliament_is_chair());
|
|
}
|
|
assert(cst_parliament_load(&m) == 0);
|
|
assert(!strcmp(m.chair_instance, "laptop-2"));
|
|
|
|
assert(cst_parliament_context_append("tablet-3", "status",
|
|
"ready to take the UI slice") == 0);
|
|
char *ctx = cst_parliament_context_get();
|
|
assert(ctx && strstr(ctx, "shared agenda v1"));
|
|
assert(strstr(ctx, "seat=tablet-3") && strstr(ctx, "ready to take the UI"));
|
|
free(ctx);
|
|
assert(cst_parliament_sync_pending());
|
|
cst_parliament_sync_ack();
|
|
|
|
assert(cst_parliament_new_project("proj-b") == 0);
|
|
ctx = cst_parliament_context_get();
|
|
assert(ctx && ctx[0] == 0);
|
|
free(ctx);
|
|
assert(cst_parliament_load(&m) == 0);
|
|
assert(!strcmp(m.project_id, "proj-b"));
|
|
assert(m.chair_instance[0] == 0);
|
|
assert(!cst_parliament_session_ok(NULL, 0));
|
|
|
|
hand = cst_parliament_login("correct horse battery", "local-a", "dev", err,
|
|
sizeof(err));
|
|
assert(hand && strstr(hand, "LOGIN_OK"));
|
|
free(hand);
|
|
assert(cst_parliament_is_chair());
|
|
assert(cst_parliament_session_ok(NULL, 0));
|
|
assert(cst_parliament_apply_sync(9, "parl-x", "proj-c", "chair-z",
|
|
"synced-body") == 0);
|
|
ctx = cst_parliament_context_get();
|
|
assert(ctx && strstr(ctx, "synced-body"));
|
|
free(ctx);
|
|
assert(cst_parliament_load(&m) == 0);
|
|
assert(m.revision == 9);
|
|
assert(!strcmp(m.chair_instance, "chair-z"));
|
|
/* Remote chair takeover clears the demoted chair's local ticket. */
|
|
assert(!cst_parliament_session_ok(NULL, 0));
|
|
|
|
char *st = cst_parliament_status_text();
|
|
assert(st && strstr(st, "parliament"));
|
|
assert(strstr(st, "service"));
|
|
assert(strstr(st, "peer_sync") && strstr(st, "sealed"));
|
|
assert(strstr(st, "role"));
|
|
free(st);
|
|
assert(cst_parliament_is_active());
|
|
assert(cst_parliament_daemon_info(NULL, NULL, 0, NULL) != 0);
|
|
|
|
char def[64];
|
|
assert(cst_parliament_default_instance(def, sizeof(def)) == 0);
|
|
assert(def[0]);
|
|
|
|
test_rmrf(dir);
|
|
puts("test_parliament: OK");
|
|
return 0;
|
|
}
|