mirror of
https://github.com/vrtmrz/obsidian-livesync.git
synced 2026-08-26 21:37:05 +00:00
test(obsidian): focus adaptive PostgREST journey
This commit is contained in:
@@ -149,6 +149,7 @@ LIVESYNC_CLI_COMMAND="docker run --rm --network host --user $(id -u):$(id -g) --
|
||||
`test:e2e:obsidian:minio-upload` reuses the Object Storage variables from `.test.env` or the process environment. It expects a reachable S3-compatible service and starts with isolated Object Storage settings and the device-local compatibility acknowledgement already in place, keeping the scenario focused on upload rather than unconfigured start-up or setup. It confirms those settings through `obsidian-cli eval`, creates a note in real Obsidian, runs one-shot Journal Sync, and verifies through the AWS SDK that objects were written under a unique bucket prefix. Adapter tests separately observe an in-progress SDK command, while this real-runtime workflow verifies the resulting request counters advance and rebalance.
|
||||
|
||||
`test:e2e:obsidian:adaptive-postgrest` applies the two-device real-Obsidian workflow to the Adaptive-only PostgREST provider. Visible manual onboarding must withhold continuation until the packaged RPC and binary-semantics check succeeds, and it must not expose Opaque or Pack retrieval choices. The first device retains its profile across a real Obsidian restart, generates a Setup URI for the second device, and completes Fast Fetch and a text and binary return journey. This representative native-store journey verifies Host composition and user-observable Vault reflection. Commonlib integration tests own the RPC failure matrix, SQL transaction semantics, repository binding, and remote layout. Rebuild resets all Adaptive data for the supplied Vault ID, so external settings must identify a disposable test Vault. Run `test:e2e:obsidian:adaptive-postgrest:services`, or pass `--manage-postgrest` through the focused wrapper, to start and stop the shared PostgreSQL and PostgREST fixture around this scenario.
|
||||
|
||||
`test:e2e:obsidian:object-storage-setup-uri-workflow` uses the public Commonlib-backed tool to generate the initial Setup URI for a unique MinIO prefix, completes visible initialisation on the first device, and then asks that working real Obsidian device to create a new Setup URI through the registered command. A second real Obsidian device imports only the device-generated URI. The workflow verifies A-to-B and B-to-A notes, captures the documented onboarding choices, and removes the Object Storage prefix only after both sessions have stopped.
|
||||
|
||||
`test:e2e:obsidian:p2p-setup-uri-workflow` runs two concurrent isolated real Obsidian sessions against the local Compose Nostr relay fixture. The first device imports a generated initial Setup URI and completes its signalling test with zero peers, creates a Setup URI for the second device through the registered command, and remains online while the second device imports it. The second device must select the expected online source before Fetch can rebuild its local database. The workflow accepts each connection request visibly on the receiving device, verifies the initial A-to-B fetch, checks that the menu for the three persistent per-peer actions remains within the viewport, reconnects both P2P sessions in join order, and verifies the B-to-A return journey. Every started session remains tracked until teardown completes.
|
||||
|
||||
@@ -183,16 +183,16 @@ export async function captureAndStartInitialisation(
|
||||
? "Setup Complete: Preparing This P2P Device"
|
||||
: p2pAdditionalDevice
|
||||
? "Setup Complete: Preparing to Fetch from Another Device"
|
||||
: mode === "new"
|
||||
? "Setup Complete: Preparing to Initialise Server"
|
||||
: "Setup Complete: Preparing to Fetch Synchronisation Data";
|
||||
: mode === "new"
|
||||
? "Setup Complete: Preparing to Initialise Server"
|
||||
: "Setup Complete: Preparing to Fetch Synchronisation Data";
|
||||
const button = p2pFirstDevice
|
||||
? "Restart and Prepare This Device"
|
||||
: p2pAdditionalDevice
|
||||
? "Restart and Select Source Device"
|
||||
: mode === "new"
|
||||
? "Restart and Initialise Server"
|
||||
: "Restart and Fetch Data";
|
||||
: mode === "new"
|
||||
? "Restart and Initialise Server"
|
||||
: "Restart and Fetch Data";
|
||||
if (p2pAdditionalDevice) {
|
||||
await withObsidianPage(port, async (page) => {
|
||||
const modal = modalByTitle(page, title);
|
||||
|
||||
@@ -27,7 +27,6 @@ if (unsupportedArguments.length > 0) {
|
||||
const managePostgREST = process.argv.includes("--manage-postgrest");
|
||||
const keepPostgRESTFixture = process.argv.includes("--keep-postgrest");
|
||||
const uiTimeoutMs = Number(process.env.E2E_OBSIDIAN_SETUP_URI_TIMEOUT_MS ?? 30000);
|
||||
const remoteTimeoutMs = Number(process.env.E2E_OBSIDIAN_POSTGREST_TIMEOUT_MS ?? 30000);
|
||||
|
||||
function environmentValue(primary: string, legacy: string, fallback: string): string {
|
||||
return process.env[primary] ?? process.env[legacy] ?? fallback;
|
||||
@@ -103,27 +102,6 @@ async function readEstimatedSize(config: PostgRESTConfig): Promise<number> {
|
||||
return estimatedSize;
|
||||
}
|
||||
|
||||
async function readManifestRepositoryId(config: PostgRESTConfig): Promise<string> {
|
||||
const headers = postgRESTHeaders(config);
|
||||
headers.set("Accept", "application/octet-stream");
|
||||
const response = await fetch(`${config.endpoint}/rpc/livesync_adaptive_manifest_get`, {
|
||||
headers,
|
||||
method: "GET",
|
||||
signal: AbortSignal.timeout(5000),
|
||||
});
|
||||
if (!response.ok) {
|
||||
await response.body?.cancel().catch(() => undefined);
|
||||
throw new Error(`Adaptive PostgREST manifest read failed with HTTP ${response.status}.`);
|
||||
}
|
||||
const manifest = JSON.parse(new TextDecoder().decode(await response.arrayBuffer())) as {
|
||||
repositoryId?: unknown;
|
||||
};
|
||||
if (typeof manifest.repositoryId !== "string") {
|
||||
throw new Error("Adaptive PostgREST manifest did not contain a repository ID.");
|
||||
}
|
||||
return manifest.repositoryId;
|
||||
}
|
||||
|
||||
async function assertPostgRESTReachable(config: PostgRESTConfig): Promise<void> {
|
||||
await readEstimatedSize(config);
|
||||
}
|
||||
@@ -254,7 +232,6 @@ function assertAdaptivePostgRESTSettings(state: SetupState, config: PostgRESTCon
|
||||
async function main(): Promise<void> {
|
||||
const config = loadPostgRESTConfig();
|
||||
let shouldStopPostgREST = false;
|
||||
let observedEstimatedSize = 0;
|
||||
|
||||
try {
|
||||
if (managePostgREST) {
|
||||
@@ -269,26 +246,6 @@ async function main(): Promise<void> {
|
||||
enterManualSettings: async (port, vaultPassphrase) =>
|
||||
await enterManualAdaptivePostgRESTSettings(port, config, vaultPassphrase),
|
||||
assertSettings: (state, label) => assertAdaptivePostgRESTSettings(state, config, label),
|
||||
assertPublished: async (minimumWriters, minimumCommits, expectedRepositoryId) => {
|
||||
const deadline = Date.now() + remoteTimeoutMs;
|
||||
let lastSize = 0;
|
||||
while (Date.now() < deadline) {
|
||||
lastSize = await readEstimatedSize(config);
|
||||
if (lastSize > observedEstimatedSize && lastSize > 0) {
|
||||
observedEstimatedSize = lastSize;
|
||||
assertEqual(
|
||||
await readManifestRepositoryId(config),
|
||||
expectedRepositoryId,
|
||||
"Adaptive PostgREST did not retain the preselected repository identity."
|
||||
);
|
||||
return;
|
||||
}
|
||||
await new Promise((resolve) => setTimeout(resolve, 500));
|
||||
}
|
||||
throw new Error(
|
||||
`Timed out waiting for Adaptive PostgREST publication stage ${minimumWriters}/${minimumCommits}; last estimated size was ${lastSize}.`
|
||||
);
|
||||
},
|
||||
});
|
||||
} finally {
|
||||
if (shouldStopPostgREST) {
|
||||
|
||||
Reference in New Issue
Block a user