Skip to content

Commit a13c540

Browse files
fix the README and make the tests run with localhost, as it will fallback to V0
1 parent 430fe51 commit a13c540

3 files changed

Lines changed: 62 additions & 84 deletions

File tree

livekit/src/room/mod.rs

Lines changed: 21 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1062,13 +1062,11 @@ impl RoomSession {
10621062

10631063
let (participant_sid, stream_id) = lk_stream_id.unwrap();
10641064
let mut track_id = track.id();
1065-
if stream_id.starts_with("TR") {
1066-
track_id = stream_id.into();
1067-
}
10681065

1069-
// In single PC mode, try to resolve track ID from mid_to_track_id mapping
1066+
// Resolve track ID based on signaling mode
10701067
let session = self.rtc_engine.session();
1071-
if session.is_single_pc_mode() && !track_id.starts_with("TR") {
1068+
if session.is_single_pc_mode() {
1069+
// In single PC mode, resolve track ID from mid_to_track_id mapping
10721070
if let Some(mid) = transceiver.mid() {
10731071
if let Some(resolved_track_id) = session.get_track_id_for_mid(&mid) {
10741072
log::debug!(
@@ -1079,12 +1077,15 @@ impl RoomSession {
10791077
track_id = resolved_track_id.into();
10801078
} else {
10811079
log::warn!(
1082-
"could not resolve track_id for mid={}, using stream_id={}",
1080+
"could not resolve track_id for mid={}, using track.id()={}",
10831081
mid,
10841082
track_id
10851083
);
10861084
}
10871085
}
1086+
} else if stream_id.starts_with("TR") {
1087+
// In dual PC mode, use stream_id if it's a valid track ID
1088+
track_id = stream_id.into();
10881089
}
10891090

10901091
if !track_id.starts_with("TR") {
@@ -1188,29 +1189,29 @@ impl RoomSession {
11881189
// In dual PC mode, use subscriber's offer/answer
11891190
let (offer, answer) = if single_pc_mode {
11901191
let pub_pc = session.publisher().peer_connection();
1191-
let local_desc = pub_pc.current_local_description();
1192-
let remote_desc = pub_pc.current_remote_description();
1193-
if local_desc.is_none() {
1192+
let Some(local_desc) = pub_pc.current_local_description() else {
11941193
log::warn!("skipping sendSyncState, no publisher offer");
11951194
return;
1196-
}
1195+
};
1196+
let remote_desc = pub_pc.current_remote_description();
11971197
// In single PC mode: offer is local (publisher initiates), answer is remote
1198-
(local_desc.unwrap(), remote_desc)
1198+
(local_desc, remote_desc)
11991199
} else {
1200-
let sub_pc = session.subscriber();
1201-
if sub_pc.is_none() {
1200+
let Some(sub_pc) = session.subscriber() else {
12021201
log::warn!("skipping sendSyncState, no subscriber");
12031202
return;
1204-
}
1205-
let sub_pc = sub_pc.unwrap().peer_connection();
1206-
let local_desc = sub_pc.current_local_description();
1207-
let remote_desc = sub_pc.current_remote_description();
1208-
if local_desc.is_none() {
1203+
};
1204+
let sub_pc = sub_pc.peer_connection();
1205+
let Some(local_desc) = sub_pc.current_local_description() else {
12091206
log::warn!("skipping sendSyncState, no subscriber answer");
12101207
return;
1211-
}
1208+
};
1209+
let Some(remote_desc) = sub_pc.current_remote_description() else {
1210+
log::warn!("skipping sendSyncState, no subscriber offer");
1211+
return;
1212+
};
12121213
// In dual PC mode: answer is local, offer is remote
1213-
(remote_desc.unwrap(), Some(local_desc.unwrap()))
1214+
(remote_desc, Some(local_desc))
12141215
};
12151216

12161217
let mut track_sids = Vec::new();

livekit/tests/README.md

Lines changed: 22 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -15,42 +15,52 @@ cargo test --features default,__lk-e2e-test -- --nocapture
1515

1616
The `peer_connection_signaling_test.rs` tests verify both V0 (dual peer connection) and V1 (single peer connection) signaling modes.
1717

18-
### V0 Tests (Dual PC - works on localhost)
18+
### V0 Tests (Dual Peer Connection)
1919

20-
V0 tests can run against a local LiveKit server:
20+
V0 tests work on localhost with the default LiveKit development server:
2121

2222
```sh
2323
# Start local server
2424
livekit-server --dev
2525

26-
# Run V0 tests only (uses localhost by default)
26+
# Run V0 tests
2727
cargo test -p livekit --features "__lk-e2e-test,native-tls" --test peer_connection_signaling_test v0_ -- --nocapture
2828
```
2929

30-
### V1 Tests (Single PC - requires LiveKit Cloud)
30+
Default localhost configuration:
31+
- URL: `ws://localhost:7880`
32+
- API Key: `devkey`
33+
- API Secret: `secret`
3134

32-
V1 (single peer connection) mode requires a LiveKit Cloud server or a server that supports the `/rtc/v1` endpoint. Local development servers typically don't support V1 signaling.
35+
### V1 Tests (Single Peer Connection)
3336

34-
Set the following environment variables:
37+
**Important:** V1 (single peer connection) mode requires a LiveKit Cloud server or a server that supports the `/rtc/v1` endpoint.
38+
39+
⚠️ **V1 tests will fall back to V0 signaling on localhost**, so to truly test V1 functionality, you **must** set the cloud environment variables:
3540

3641
```sh
3742
export LIVEKIT_URL="wss://your-project.livekit.cloud"
3843
export LIVEKIT_API_KEY="your-api-key"
3944
export LIVEKIT_API_SECRET="your-api-secret"
45+
46+
# Run V1 tests
47+
cargo test -p livekit --features "__lk-e2e-test,native-tls" --test peer_connection_signaling_test v1_ -- --nocapture
4048
```
4149

42-
Then run:
50+
### Running All Tests
4351

4452
```sh
45-
# Run V1 tests only
46-
cargo test -p livekit --features "__lk-e2e-test,native-tls" --test peer_connection_signaling_test v1_ -- --nocapture
53+
# On localhost (V0 will work, V1 falls back to V0)
54+
livekit-server --dev
55+
cargo test -p livekit --features "__lk-e2e-test,native-tls" --test peer_connection_signaling_test -- --nocapture
4756

48-
# Run all signaling tests (both V0 and V1)
57+
# On LiveKit Cloud (both V0 and V1 work correctly)
58+
export LIVEKIT_URL="wss://your-project.livekit.cloud"
59+
export LIVEKIT_API_KEY="your-api-key"
60+
export LIVEKIT_API_SECRET="your-api-secret"
4961
cargo test -p livekit --features "__lk-e2e-test,native-tls" --test peer_connection_signaling_test -- --nocapture
5062
```
5163

52-
**Note:** V1 tests will be skipped if the environment variables are not set.
53-
5464
## VS Code Integration
5565

5666
If you are using Rust Analyzer in Visual Studio Code, you can enable the E2E test feature to get code completion for these tests. Add the following setting to *.vscode/settings.json*:

livekit/tests/peer_connection_signaling_test.rs

Lines changed: 19 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -18,23 +18,25 @@
1818
//! signaling modes work correctly.
1919
//!
2020
//! V0 (Dual PC): Traditional mode with separate publisher and subscriber peer connections
21-
//! Can run on localhost with `livekit-server --dev`
21+
//! Works on localhost with `livekit-server --dev`
2222
//!
2323
//! V1 (Single PC): New mode with a single peer connection for both publish and subscribe
24-
//! Requires LiveKit Cloud or a server supporting /rtc/v1 endpoint
24+
//! Requires LiveKit Cloud or a server that supports /rtc/v1 endpoint.
25+
//! NOTE: V1 tests will fall back to V0 on localhost, so to truly test V1,
26+
//! you must set the cloud environment variables.
2527
//!
26-
//! Environment variables (required for V1, optional for V0):
27-
//! - LIVEKIT_URL: The LiveKit server URL (V0 defaults to ws://localhost:7880)
28-
//! - LIVEKIT_API_KEY: The API key (V0 defaults to "devkey")
29-
//! - LIVEKIT_API_SECRET: The API secret (V0 defaults to "secret")
28+
//! Environment variables:
29+
//! - LIVEKIT_URL: The LiveKit server URL (defaults to ws://localhost:7880)
30+
//! - LIVEKIT_API_KEY: The API key (defaults to "devkey")
31+
//! - LIVEKIT_API_SECRET: The API secret (defaults to "secret")
3032
//!
3133
//! Run all tests:
3234
//! cargo test -p livekit --features "__lk-e2e-test,native-tls" --test peer_connection_signaling_test -- --nocapture
3335
//!
34-
//! Run only V0 tests (works on localhost):
36+
//! Run only V0 tests:
3537
//! cargo test -p livekit --features "__lk-e2e-test,native-tls" --test peer_connection_signaling_test v0_ -- --nocapture
3638
//!
37-
//! Run only V1 tests (requires cloud):
39+
//! Run only V1 tests (set cloud env vars first):
3840
//! cargo test -p livekit --features "__lk-e2e-test,native-tls" --test peer_connection_signaling_test v1_ -- --nocapture
3941
4042
mod common;
@@ -78,55 +80,20 @@ mod signaling_tests {
7880
}
7981
}
8082

81-
/// Default localhost configuration for V0 tests
83+
/// Default localhost configuration
8284
const DEFAULT_LOCALHOST_URL: &str = "ws://localhost:7880";
8385
const DEFAULT_API_KEY: &str = "devkey";
8486
const DEFAULT_API_SECRET: &str = "secret";
8587

86-
/// Get environment variables for V0 tests (uses localhost defaults)
87-
fn get_v0_env() -> (String, String, String) {
88+
/// Get environment for tests (uses localhost defaults if env vars not set)
89+
fn get_env_for_mode(_mode: SignalingMode) -> (String, String, String) {
8890
let url = env::var("LIVEKIT_URL").unwrap_or_else(|_| DEFAULT_LOCALHOST_URL.to_string());
8991
let api_key = env::var("LIVEKIT_API_KEY").unwrap_or_else(|_| DEFAULT_API_KEY.to_string());
9092
let api_secret =
9193
env::var("LIVEKIT_API_SECRET").unwrap_or_else(|_| DEFAULT_API_SECRET.to_string());
9294
(url, api_key, api_secret)
9395
}
9496

95-
/// Check if cloud environment variables are set (required for V1 tests)
96-
fn check_cloud_env_vars() -> Option<(String, String, String)> {
97-
let url = env::var("LIVEKIT_URL").ok()?;
98-
let api_key = env::var("LIVEKIT_API_KEY").ok()?;
99-
let api_secret = env::var("LIVEKIT_API_SECRET").ok()?;
100-
Some((url, api_key, api_secret))
101-
}
102-
103-
/// Get environment for the given signaling mode
104-
/// V0: Uses localhost defaults if env vars not set
105-
/// V1: Requires env vars to be set, returns None if not
106-
fn get_env_for_mode(mode: SignalingMode) -> Option<(String, String, String)> {
107-
match mode {
108-
SignalingMode::DualPC => Some(get_v0_env()),
109-
SignalingMode::SinglePC => check_cloud_env_vars(),
110-
}
111-
}
112-
113-
/// Macro to get environment for the given mode, skipping if V1 and no cloud env
114-
macro_rules! require_env_for_mode {
115-
($mode:expr) => {
116-
match get_env_for_mode($mode) {
117-
Some(env) => env,
118-
None => {
119-
log::warn!(
120-
"Skipping {} test: LIVEKIT_URL, LIVEKIT_API_KEY, LIVEKIT_API_SECRET not set. \
121-
V1 tests require LiveKit Cloud or a server supporting /rtc/v1 endpoint.",
122-
$mode.name()
123-
);
124-
return Ok(());
125-
}
126-
}
127-
};
128-
}
129-
13097
/// Create a token for testing
13198
fn create_token(
13299
api_key: &str,
@@ -251,7 +218,7 @@ mod signaling_tests {
251218

252219
/// Test basic connection
253220
async fn test_connect_impl(mode: SignalingMode) -> Result<()> {
254-
let (url, api_key, api_secret) = require_env_for_mode!(mode);
221+
let (url, api_key, api_secret) = get_env_for_mode(mode);
255222
let room_name = format!("test_{:?}_{}", mode, create_random_uuid());
256223
let token = create_token(&api_key, &api_secret, &room_name, "test_participant")?;
257224

@@ -278,7 +245,7 @@ mod signaling_tests {
278245

279246
/// Test two participants connecting
280247
async fn test_two_participants_impl(mode: SignalingMode) -> Result<()> {
281-
let (url, api_key, api_secret) = require_env_for_mode!(mode);
248+
let (url, api_key, api_secret) = get_env_for_mode(mode);
282249
let room_name = format!("test_{:?}_2p_{}", mode, create_random_uuid());
283250

284251
let token1 = create_token(&api_key, &api_secret, &room_name, "participant_1")?;
@@ -312,7 +279,7 @@ mod signaling_tests {
312279

313280
/// Test publishing and receiving audio tracks
314281
async fn test_audio_track_impl(mode: SignalingMode) -> Result<()> {
315-
let (url, api_key, api_secret) = require_env_for_mode!(mode);
282+
let (url, api_key, api_secret) = get_env_for_mode(mode);
316283
let room_name = format!("test_{:?}_audio_{}", mode, create_random_uuid());
317284

318285
let token_pub = create_token(&api_key, &api_secret, &room_name, "publisher")?;
@@ -383,7 +350,7 @@ mod signaling_tests {
383350

384351
/// Test reconnection - verifies tracks are restored
385352
async fn test_reconnect_impl(mode: SignalingMode) -> Result<()> {
386-
let (url, api_key, api_secret) = require_env_for_mode!(mode);
353+
let (url, api_key, api_secret) = get_env_for_mode(mode);
387354
let room_name = format!("test_{:?}_reconnect_{}", mode, create_random_uuid());
388355

389356
let token_pub = create_token(&api_key, &api_secret, &room_name, "publisher")?;
@@ -491,7 +458,7 @@ mod signaling_tests {
491458

492459
/// Test data channel
493460
async fn test_data_channel_impl(mode: SignalingMode) -> Result<()> {
494-
let (url, api_key, api_secret) = require_env_for_mode!(mode);
461+
let (url, api_key, api_secret) = get_env_for_mode(mode);
495462
let room_name = format!("test_{:?}_data_{}", mode, create_random_uuid());
496463

497464
let token1 = create_token(&api_key, &api_secret, &room_name, "participant_1")?;
@@ -559,7 +526,7 @@ mod signaling_tests {
559526

560527
/// Test node failure reconnection scenario
561528
async fn test_node_failure_impl(mode: SignalingMode) -> Result<()> {
562-
let (url, api_key, api_secret) = require_env_for_mode!(mode);
529+
let (url, api_key, api_secret) = get_env_for_mode(mode);
563530
let room_name = format!("test_{:?}_node_fail_{}", mode, create_random_uuid());
564531

565532
let token = create_token(&api_key, &api_secret, &room_name, "test_participant")?;

0 commit comments

Comments
 (0)