mirror of
https://github.com/vrtmrz/obsidian-livesync.git
synced 2026-10-08 18:32:30 +00:00
add coturn for test
This commit is contained in:
@@ -148,5 +148,5 @@ jobs:
|
|||||||
- name: Stop leftover containers
|
- name: Stop leftover containers
|
||||||
if: always()
|
if: always()
|
||||||
run: |
|
run: |
|
||||||
docker stop couchdb-test minio-test relay-test >/dev/null 2>&1 || true
|
docker stop couchdb-test minio-test relay-test coturn-test >/dev/null 2>&1 || true
|
||||||
docker rm couchdb-test minio-test relay-test >/dev/null 2>&1 || true
|
docker rm couchdb-test minio-test relay-test coturn-test >/dev/null 2>&1 || true
|
||||||
|
|||||||
@@ -627,3 +627,42 @@ export async function startP2pRelay(): Promise<void> {
|
|||||||
export function isLocalP2pRelay(relayUrl: string): boolean {
|
export function isLocalP2pRelay(relayUrl: string): boolean {
|
||||||
return relayUrl === "ws://localhost:4000" || relayUrl === "ws://localhost:4000/";
|
return relayUrl === "ws://localhost:4000" || relayUrl === "ws://localhost:4000/";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
// Coturn (STUN/TURN)
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
const COTURN_CONTAINER = "coturn-test";
|
||||||
|
const COTURN_IMAGE = "coturn/coturn:latest";
|
||||||
|
|
||||||
|
export async function stopCoturn(): Promise<void> {
|
||||||
|
await stopAndRemoveContainer(COTURN_CONTAINER);
|
||||||
|
untrackContainer(COTURN_CONTAINER);
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function startCoturn(
|
||||||
|
port = 3478,
|
||||||
|
user = "testuser",
|
||||||
|
pass = "testpass",
|
||||||
|
realm = "livesync.test"
|
||||||
|
): Promise<void> {
|
||||||
|
console.log("[INFO] stopping leftover Coturn container if present");
|
||||||
|
await stopCoturn().catch(() => {});
|
||||||
|
|
||||||
|
console.log("[INFO] starting local Coturn container");
|
||||||
|
await dockerOrFail(
|
||||||
|
"run",
|
||||||
|
"-d",
|
||||||
|
"--name",
|
||||||
|
COTURN_CONTAINER,
|
||||||
|
"-p",
|
||||||
|
`${port}:${port}`,
|
||||||
|
"-p",
|
||||||
|
`${port}:${port}/udp`,
|
||||||
|
COTURN_IMAGE,
|
||||||
|
"--log-file=stdout",
|
||||||
|
"--external-ip=127.0.0.1",
|
||||||
|
`--user=${user}:${pass}`,
|
||||||
|
`--realm=${realm}`
|
||||||
|
);
|
||||||
|
trackContainer(COTURN_CONTAINER);
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { runCli } from "./cli.ts";
|
import { runCli } from "./cli.ts";
|
||||||
import { isLocalP2pRelay, startP2pRelay, stopP2pRelay } from "./docker.ts";
|
import { isLocalP2pRelay, startP2pRelay, stopP2pRelay, startCoturn, stopCoturn } from "./docker.ts";
|
||||||
import { waitForPort } from "./net.ts";
|
import { waitForPort } from "./net.ts";
|
||||||
|
|
||||||
export type PeerEntry = {
|
export type PeerEntry = {
|
||||||
@@ -95,3 +95,17 @@ export async function stopLocalRelayIfStarted(started: boolean): Promise<void> {
|
|||||||
await stopP2pRelay().catch(() => {});
|
await stopP2pRelay().catch(() => {});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function maybeStartCoturn(turnServers: string): Promise<boolean> {
|
||||||
|
if (turnServers.includes("localhost") || turnServers.includes("127.0.0.1")) {
|
||||||
|
await startCoturn();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function stopCoturnIfStarted(started: boolean): Promise<void> {
|
||||||
|
if (started) {
|
||||||
|
await stopCoturn().catch(() => {});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -172,7 +172,8 @@ export async function applyP2pSettings(
|
|||||||
passphrase: string,
|
passphrase: string,
|
||||||
appId = "self-hosted-livesync-cli-tests",
|
appId = "self-hosted-livesync-cli-tests",
|
||||||
relays = "ws://localhost:4000/",
|
relays = "ws://localhost:4000/",
|
||||||
autoAccept = "~.*"
|
autoAccept = "~.*",
|
||||||
|
turnServers = "turn:127.0.0.1:3478"
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
const data = JSON.parse(await Deno.readTextFile(settingsFile));
|
const data = JSON.parse(await Deno.readTextFile(settingsFile));
|
||||||
data.P2P_Enabled = true;
|
data.P2P_Enabled = true;
|
||||||
@@ -184,7 +185,9 @@ export async function applyP2pSettings(
|
|||||||
data.P2P_relays = relays;
|
data.P2P_relays = relays;
|
||||||
data.P2P_AutoAcceptingPeers = autoAccept;
|
data.P2P_AutoAcceptingPeers = autoAccept;
|
||||||
data.P2P_AutoDenyingPeers = "";
|
data.P2P_AutoDenyingPeers = "";
|
||||||
data.P2P_turnServers = "none";
|
data.P2P_turnServers = turnServers;
|
||||||
|
data.P2P_turnUsername = "testuser";
|
||||||
|
data.P2P_turnCredential = "testpass";
|
||||||
data.P2P_IsHeadless = true;
|
data.P2P_IsHeadless = true;
|
||||||
data.isConfigured = true;
|
data.isConfigured = true;
|
||||||
await Deno.writeTextFile(settingsFile, JSON.stringify(data, null, 2));
|
await Deno.writeTextFile(settingsFile, JSON.stringify(data, null, 2));
|
||||||
|
|||||||
@@ -2,7 +2,13 @@ import { assert } from "@std/assert";
|
|||||||
import { TempDir } from "./helpers/temp.ts";
|
import { TempDir } from "./helpers/temp.ts";
|
||||||
import { initSettingsFile, applyP2pSettings, applyP2pTestTweaks } from "./helpers/settings.ts";
|
import { initSettingsFile, applyP2pSettings, applyP2pTestTweaks } from "./helpers/settings.ts";
|
||||||
import { startCliInBackground } from "./helpers/backgroundCli.ts";
|
import { startCliInBackground } from "./helpers/backgroundCli.ts";
|
||||||
import { discoverPeer, maybeStartLocalRelay, stopLocalRelayIfStarted } from "./helpers/p2p.ts";
|
import {
|
||||||
|
discoverPeer,
|
||||||
|
maybeStartLocalRelay,
|
||||||
|
stopLocalRelayIfStarted,
|
||||||
|
maybeStartCoturn,
|
||||||
|
stopCoturnIfStarted,
|
||||||
|
} from "./helpers/p2p.ts";
|
||||||
|
|
||||||
Deno.test("p2p-peers: discovers host through local relay", async () => {
|
Deno.test("p2p-peers: discovers host through local relay", async () => {
|
||||||
const relay = Deno.env.get("RELAY") ?? "ws://localhost:4000/";
|
const relay = Deno.env.get("RELAY") ?? "ws://localhost:4000/";
|
||||||
@@ -12,6 +18,7 @@ Deno.test("p2p-peers: discovers host through local relay", async () => {
|
|||||||
const nonce = `${Date.now()}-${crypto.randomUUID().slice(0, 8)}`;
|
const nonce = `${Date.now()}-${crypto.randomUUID().slice(0, 8)}`;
|
||||||
const hostPeerName = Deno.env.get("HOST_PEER_NAME") ?? `p2p-host-${nonce}`;
|
const hostPeerName = Deno.env.get("HOST_PEER_NAME") ?? `p2p-host-${nonce}`;
|
||||||
const clientPeerName = Deno.env.get("CLIENT_PEER_NAME") ?? `p2p-client-${nonce}`;
|
const clientPeerName = Deno.env.get("CLIENT_PEER_NAME") ?? `p2p-client-${nonce}`;
|
||||||
|
const turnServers = Deno.env.get("TURN_SERVERS") ?? "turn:127.0.0.1:3478";
|
||||||
|
|
||||||
await using workDir = await TempDir.create("livesync-cli-p2p-peers-local-relay");
|
await using workDir = await TempDir.create("livesync-cli-p2p-peers-local-relay");
|
||||||
const hostVault = workDir.join("vault-host");
|
const hostVault = workDir.join("vault-host");
|
||||||
@@ -22,11 +29,28 @@ Deno.test("p2p-peers: discovers host through local relay", async () => {
|
|||||||
await Deno.mkdir(clientVault, { recursive: true });
|
await Deno.mkdir(clientVault, { recursive: true });
|
||||||
|
|
||||||
const relayStarted = await maybeStartLocalRelay(relay);
|
const relayStarted = await maybeStartLocalRelay(relay);
|
||||||
|
const coturnStarted = await maybeStartCoturn(turnServers);
|
||||||
try {
|
try {
|
||||||
await initSettingsFile(hostSettings);
|
await initSettingsFile(hostSettings);
|
||||||
await initSettingsFile(clientSettings);
|
await initSettingsFile(clientSettings);
|
||||||
await applyP2pSettings(hostSettings, roomId, passphrase, "self-hosted-livesync-cli-tests", relay);
|
await applyP2pSettings(
|
||||||
await applyP2pSettings(clientSettings, roomId, passphrase, "self-hosted-livesync-cli-tests", relay);
|
hostSettings,
|
||||||
|
roomId,
|
||||||
|
passphrase,
|
||||||
|
"self-hosted-livesync-cli-tests",
|
||||||
|
relay,
|
||||||
|
"~.*",
|
||||||
|
turnServers
|
||||||
|
);
|
||||||
|
await applyP2pSettings(
|
||||||
|
clientSettings,
|
||||||
|
roomId,
|
||||||
|
passphrase,
|
||||||
|
"self-hosted-livesync-cli-tests",
|
||||||
|
relay,
|
||||||
|
"~.*",
|
||||||
|
turnServers
|
||||||
|
);
|
||||||
await applyP2pTestTweaks(hostSettings, hostPeerName, passphrase);
|
await applyP2pTestTweaks(hostSettings, hostPeerName, passphrase);
|
||||||
await applyP2pTestTweaks(clientSettings, clientPeerName, passphrase);
|
await applyP2pTestTweaks(clientSettings, clientPeerName, passphrase);
|
||||||
|
|
||||||
@@ -42,5 +66,6 @@ Deno.test("p2p-peers: discovers host through local relay", async () => {
|
|||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
await stopLocalRelayIfStarted(relayStarted);
|
await stopLocalRelayIfStarted(relayStarted);
|
||||||
|
await stopCoturnIfStarted(coturnStarted);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -2,7 +2,13 @@ import { assert } from "@std/assert";
|
|||||||
import { TempDir } from "./helpers/temp.ts";
|
import { TempDir } from "./helpers/temp.ts";
|
||||||
import { initSettingsFile, applyP2pSettings, applyP2pTestTweaks } from "./helpers/settings.ts";
|
import { initSettingsFile, applyP2pSettings, applyP2pTestTweaks } from "./helpers/settings.ts";
|
||||||
import { startCliInBackground } from "./helpers/backgroundCli.ts";
|
import { startCliInBackground } from "./helpers/backgroundCli.ts";
|
||||||
import { discoverPeer, maybeStartLocalRelay, stopLocalRelayIfStarted } from "./helpers/p2p.ts";
|
import {
|
||||||
|
discoverPeer,
|
||||||
|
maybeStartLocalRelay,
|
||||||
|
stopLocalRelayIfStarted,
|
||||||
|
maybeStartCoturn,
|
||||||
|
stopCoturnIfStarted,
|
||||||
|
} from "./helpers/p2p.ts";
|
||||||
import { runCli } from "./helpers/cli.ts";
|
import { runCli } from "./helpers/cli.ts";
|
||||||
|
|
||||||
Deno.test("p2p-sync: discovers peer and completes sync", async () => {
|
Deno.test("p2p-sync: discovers peer and completes sync", async () => {
|
||||||
@@ -14,6 +20,7 @@ Deno.test("p2p-sync: discovers peer and completes sync", async () => {
|
|||||||
const nonce = `${Date.now()}-${crypto.randomUUID().slice(0, 8)}`;
|
const nonce = `${Date.now()}-${crypto.randomUUID().slice(0, 8)}`;
|
||||||
const hostPeerName = Deno.env.get("HOST_PEER_NAME") ?? `p2p-host-${nonce}`;
|
const hostPeerName = Deno.env.get("HOST_PEER_NAME") ?? `p2p-host-${nonce}`;
|
||||||
const clientPeerName = Deno.env.get("CLIENT_PEER_NAME") ?? `p2p-client-${nonce}`;
|
const clientPeerName = Deno.env.get("CLIENT_PEER_NAME") ?? `p2p-client-${nonce}`;
|
||||||
|
const turnServers = Deno.env.get("TURN_SERVERS") ?? "turn:127.0.0.1:3478";
|
||||||
|
|
||||||
await using workDir = await TempDir.create("livesync-cli-p2p-sync");
|
await using workDir = await TempDir.create("livesync-cli-p2p-sync");
|
||||||
const hostVault = workDir.join("vault-host");
|
const hostVault = workDir.join("vault-host");
|
||||||
@@ -24,11 +31,28 @@ Deno.test("p2p-sync: discovers peer and completes sync", async () => {
|
|||||||
await Deno.mkdir(clientVault, { recursive: true });
|
await Deno.mkdir(clientVault, { recursive: true });
|
||||||
|
|
||||||
const relayStarted = await maybeStartLocalRelay(relay);
|
const relayStarted = await maybeStartLocalRelay(relay);
|
||||||
|
const coturnStarted = await maybeStartCoturn(turnServers);
|
||||||
try {
|
try {
|
||||||
await initSettingsFile(hostSettings);
|
await initSettingsFile(hostSettings);
|
||||||
await initSettingsFile(clientSettings);
|
await initSettingsFile(clientSettings);
|
||||||
await applyP2pSettings(hostSettings, roomId, passphrase, "self-hosted-livesync-cli-tests", relay);
|
await applyP2pSettings(
|
||||||
await applyP2pSettings(clientSettings, roomId, passphrase, "self-hosted-livesync-cli-tests", relay);
|
hostSettings,
|
||||||
|
roomId,
|
||||||
|
passphrase,
|
||||||
|
"self-hosted-livesync-cli-tests",
|
||||||
|
relay,
|
||||||
|
"~.*",
|
||||||
|
turnServers
|
||||||
|
);
|
||||||
|
await applyP2pSettings(
|
||||||
|
clientSettings,
|
||||||
|
roomId,
|
||||||
|
passphrase,
|
||||||
|
"self-hosted-livesync-cli-tests",
|
||||||
|
relay,
|
||||||
|
"~.*",
|
||||||
|
turnServers
|
||||||
|
);
|
||||||
await applyP2pTestTweaks(hostSettings, hostPeerName, passphrase);
|
await applyP2pTestTweaks(hostSettings, hostPeerName, passphrase);
|
||||||
await applyP2pTestTweaks(clientSettings, clientPeerName, passphrase);
|
await applyP2pTestTweaks(clientSettings, clientPeerName, passphrase);
|
||||||
|
|
||||||
@@ -58,5 +82,6 @@ Deno.test("p2p-sync: discovers peer and completes sync", async () => {
|
|||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
await stopLocalRelayIfStarted(relayStarted);
|
await stopLocalRelayIfStarted(relayStarted);
|
||||||
|
await stopCoturnIfStarted(coturnStarted);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -2,7 +2,13 @@ import { assert } from "@std/assert";
|
|||||||
import { TempDir } from "./helpers/temp.ts";
|
import { TempDir } from "./helpers/temp.ts";
|
||||||
import { applyP2pSettings, applyP2pTestTweaks, initSettingsFile } from "./helpers/settings.ts";
|
import { applyP2pSettings, applyP2pTestTweaks, initSettingsFile } from "./helpers/settings.ts";
|
||||||
import { startCliInBackground } from "./helpers/backgroundCli.ts";
|
import { startCliInBackground } from "./helpers/backgroundCli.ts";
|
||||||
import { discoverPeer, maybeStartLocalRelay, stopLocalRelayIfStarted } from "./helpers/p2p.ts";
|
import {
|
||||||
|
discoverPeer,
|
||||||
|
maybeStartLocalRelay,
|
||||||
|
stopLocalRelayIfStarted,
|
||||||
|
maybeStartCoturn,
|
||||||
|
stopCoturnIfStarted,
|
||||||
|
} from "./helpers/p2p.ts";
|
||||||
import { jsonStringField, runCliOrFail, runCliWithInputOrFail, sanitiseCatStdout } from "./helpers/cli.ts";
|
import { jsonStringField, runCliOrFail, runCliWithInputOrFail, sanitiseCatStdout } from "./helpers/cli.ts";
|
||||||
|
|
||||||
Deno.test("p2p: three nodes detect and resolve conflicts", async () => {
|
Deno.test("p2p: three nodes detect and resolve conflicts", async () => {
|
||||||
@@ -16,6 +22,7 @@ Deno.test("p2p: three nodes detect and resolve conflicts", async () => {
|
|||||||
const hostPeerName = Deno.env.get("HOST_PEER_NAME") ?? `p2p-host-${nonce}`;
|
const hostPeerName = Deno.env.get("HOST_PEER_NAME") ?? `p2p-host-${nonce}`;
|
||||||
const peerNameB = Deno.env.get("PEER_NAME_B") ?? `p2p-client-b-${nonce}`;
|
const peerNameB = Deno.env.get("PEER_NAME_B") ?? `p2p-client-b-${nonce}`;
|
||||||
const peerNameC = Deno.env.get("PEER_NAME_C") ?? `p2p-client-c-${nonce}`;
|
const peerNameC = Deno.env.get("PEER_NAME_C") ?? `p2p-client-c-${nonce}`;
|
||||||
|
const turnServers = Deno.env.get("TURN_SERVERS") ?? "turn:127.0.0.1:3478";
|
||||||
|
|
||||||
await using workDir = await TempDir.create("livesync-cli-p2p-3nodes");
|
await using workDir = await TempDir.create("livesync-cli-p2p-3nodes");
|
||||||
const vaultA = workDir.join("vault-a");
|
const vaultA = workDir.join("vault-a");
|
||||||
@@ -29,13 +36,14 @@ Deno.test("p2p: three nodes detect and resolve conflicts", async () => {
|
|||||||
await Deno.mkdir(vaultC, { recursive: true });
|
await Deno.mkdir(vaultC, { recursive: true });
|
||||||
|
|
||||||
const relayStarted = await maybeStartLocalRelay(relay);
|
const relayStarted = await maybeStartLocalRelay(relay);
|
||||||
|
const coturnStarted = await maybeStartCoturn(turnServers);
|
||||||
try {
|
try {
|
||||||
await initSettingsFile(settingsA);
|
await initSettingsFile(settingsA);
|
||||||
await initSettingsFile(settingsB);
|
await initSettingsFile(settingsB);
|
||||||
await initSettingsFile(settingsC);
|
await initSettingsFile(settingsC);
|
||||||
await applyP2pSettings(settingsA, roomId, passphrase, appId, relay);
|
await applyP2pSettings(settingsA, roomId, passphrase, appId, relay, "~.*", turnServers);
|
||||||
await applyP2pSettings(settingsB, roomId, passphrase, appId, relay);
|
await applyP2pSettings(settingsB, roomId, passphrase, appId, relay, "~.*", turnServers);
|
||||||
await applyP2pSettings(settingsC, roomId, passphrase, appId, relay);
|
await applyP2pSettings(settingsC, roomId, passphrase, appId, relay, "~.*", turnServers);
|
||||||
await applyP2pTestTweaks(settingsA, hostPeerName, passphrase);
|
await applyP2pTestTweaks(settingsA, hostPeerName, passphrase);
|
||||||
await applyP2pTestTweaks(settingsB, peerNameB, passphrase);
|
await applyP2pTestTweaks(settingsB, peerNameB, passphrase);
|
||||||
await applyP2pTestTweaks(settingsC, peerNameC, passphrase);
|
await applyP2pTestTweaks(settingsC, peerNameC, passphrase);
|
||||||
@@ -123,5 +131,6 @@ Deno.test("p2p: three nodes detect and resolve conflicts", async () => {
|
|||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
await stopLocalRelayIfStarted(relayStarted);
|
await stopLocalRelayIfStarted(relayStarted);
|
||||||
|
await stopCoturnIfStarted(coturnStarted);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user