Skip to content

Commit 3b6a294

Browse files
committed
chore: clean up tests
1 parent f6fa143 commit 3b6a294

17 files changed

+1349
-617
lines changed

packages/infra/engine/tests/actors_create.rs

Lines changed: 254 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
mod common;
22

3+
use base64::Engine;
34
use serde_json::json;
45

6+
const MAX_INPUT_SIZE: usize = rivet_util::file_size::mebibytes(4) as usize;
7+
58
// MARK: Basic
69
#[test]
710
fn create_actor_valid_namespace() {
@@ -169,13 +172,14 @@ fn create_actor_specific_datacenter() {
169172
let actor_id = common::create_actor_with_options(
170173
common::CreateActorOptions {
171174
namespace: namespace.clone(),
172-
datacenter: Some("dc-2".to_string()),
173175
..Default::default()
174176
},
175-
ctx.leader_dc().guard_port(),
177+
ctx.get_dc(2).guard_port(),
176178
)
177179
.await;
178180

181+
common::wait_for_actor_propagation(&"foo", 1).await;
182+
179183
assert!(!actor_id.is_empty(), "Actor ID should not be empty");
180184

181185
let actor =
@@ -196,7 +200,6 @@ fn create_actor_current_datacenter() {
196200
let actor_id = common::create_actor_with_options(
197201
common::CreateActorOptions {
198202
namespace: namespace.clone(),
199-
datacenter: None,
200203
..Default::default()
201204
},
202205
ctx.leader_dc().guard_port(),
@@ -223,42 +226,31 @@ fn create_actor_non_existent_namespace() {
223226
});
224227
}
225228

226-
#[test]
227-
#[should_panic(expected = "Failed to create actor")]
228-
fn create_actor_invalid_datacenter() {
229-
common::run(common::TestOpts::new(1), |ctx| async move {
230-
let (namespace, _, _runner) =
231-
common::setup_test_namespace_with_runner(ctx.leader_dc()).await;
232-
233-
common::create_actor_with_options(
234-
common::CreateActorOptions {
235-
namespace: namespace.clone(),
236-
datacenter: Some("invalid-dc".to_string()),
237-
..Default::default()
238-
},
239-
ctx.leader_dc().guard_port(),
240-
)
241-
.await;
242-
});
243-
}
244-
245229
#[test]
246230
fn create_actor_malformed_input() {
247231
common::run(common::TestOpts::new(1), |ctx| async move {
248232
let (namespace, _, _runner) =
249233
common::setup_test_namespace_with_runner(ctx.leader_dc()).await;
250234

251-
let actor_id = common::create_actor_with_options(
252-
common::CreateActorOptions {
253-
namespace: namespace.clone(),
254-
input: Some("not-valid-base64!@#$%".to_string()),
255-
..Default::default()
256-
},
257-
ctx.leader_dc().guard_port(),
258-
)
259-
.await;
235+
let client = reqwest::Client::new();
236+
let response = client
237+
.post(&format!(
238+
"http://127.0.0.1:{}/actors?namespace={}",
239+
ctx.leader_dc().guard_port(),
240+
namespace
241+
))
242+
.json(&serde_json::json!({
243+
"name": "test",
244+
"input": "not-valid-base64!@#$%",
245+
}))
246+
.send()
247+
.await
248+
.expect("Failed to send request");
260249

261-
assert!(!actor_id.is_empty(), "Actor ID should not be empty");
250+
assert!(
251+
!response.status().is_success(),
252+
"Should fail with invalid base64 input"
253+
);
262254
});
263255
}
264256

@@ -269,17 +261,17 @@ fn create_actor_remote_datacenter_verify() {
269261
let (namespace, _, _runner) =
270262
common::setup_test_namespace_with_runner(ctx.leader_dc()).await;
271263

264+
// common::wait_for_actor_propagation(&"", 1).await;
272265
let actor_id = common::create_actor_with_options(
273266
common::CreateActorOptions {
274267
namespace: namespace.clone(),
275-
datacenter: Some("dc-2".to_string()),
276268
..Default::default()
277269
},
278-
ctx.leader_dc().guard_port(),
270+
ctx.get_dc(2).guard_port(),
279271
)
280272
.await;
281273

282-
common::wait_for_actor_propagation(&actor_id, 1).await;
274+
// common::wait_for_actor_propagation(&actor_id, 1).await;
283275

284276
let actor =
285277
common::assert_actor_exists(&actor_id, &namespace, ctx.get_dc(2).guard_port()).await;
@@ -290,6 +282,34 @@ fn create_actor_remote_datacenter_verify() {
290282
});
291283
}
292284

285+
// MARK: Namespace validation
286+
#[test]
287+
fn create_actor_namespace_validation() {
288+
common::run(common::TestOpts::new(1), |ctx| async move {
289+
let non_existent_ns = "non-existent-namespace";
290+
let api_port = ctx.leader_dc().guard_port();
291+
let client = reqwest::Client::new();
292+
293+
// POST /actors
294+
let response = client
295+
.post(&format!(
296+
"http://127.0.0.1:{}/actors?namespace={}",
297+
api_port, non_existent_ns
298+
))
299+
.json(&json!({
300+
"name": "test",
301+
"key": "key",
302+
}))
303+
.send()
304+
.await
305+
.expect("Failed to send request");
306+
assert!(
307+
!response.status().is_success(),
308+
"POST /actors should fail with non-existent namespace"
309+
);
310+
});
311+
}
312+
293313
// MARK: Edge cases
294314

295315
#[test]
@@ -353,15 +373,70 @@ fn empty_strings_for_required_parameters() {
353373
});
354374
}
355375

376+
377+
#[test]
378+
fn test_long_strings_for_input() {
379+
common::run(common::TestOpts::new(1), |ctx| async move {
380+
let (namespace, _, _runner) =
381+
common::setup_test_namespace_with_runner(ctx.leader_dc()).await;
382+
383+
let client = reqwest::Client::new();
384+
385+
// Test different base64 encoded inputs
386+
let large_string = "A".repeat(MAX_INPUT_SIZE + 1);
387+
let base64_tests = vec![
388+
("normal", "AAAA", true),
389+
("very-large", rivet_util::safe_slice(&large_string, 0, MAX_INPUT_SIZE-1), true), // Within bounds
390+
("too-large", &large_string, false), // Out of bounds base64 string
391+
];
392+
393+
for (name, base64_input, should_work) in base64_tests {
394+
let response = client
395+
.post(&format!(
396+
"http://127.0.0.1:{}/actors?namespace={}",
397+
ctx.leader_dc().guard_port(),
398+
namespace
399+
))
400+
.json(&json!({
401+
"name": format!("base64-{}", name),
402+
"input": base64_input,
403+
"runner_name_selector": "foo",
404+
"crash_policy": "destroy",
405+
}))
406+
.send()
407+
.await
408+
.expect(&format!("Failed to send request for {}", name));
409+
410+
if should_work && base64::engine::general_purpose::STANDARD.decode(base64_input).is_ok() {
411+
// Valid base64 should work
412+
assert!(
413+
response.status().is_success(),
414+
"Valid base64 '{}' should succeed, but instead got {}",
415+
name,
416+
response.text().await.unwrap()
417+
);
418+
} else {
419+
// Invalid base64 should fail
420+
assert!(
421+
!response.status().is_success(),
422+
"Invalid base64 '{}' should fail",
423+
name
424+
);
425+
}
426+
}
427+
});
428+
}
429+
430+
356431
#[test]
357432
fn very_long_strings_for_names_and_key() {
358433
common::run(common::TestOpts::new(1), |ctx| async move {
359434
let (namespace, _, _runner) =
360435
common::setup_test_namespace_with_runner(ctx.leader_dc()).await;
361436

362-
// Create very long name and key (should work up to reasonable limits)
363-
let long_name = "a".repeat(255); // 255 chars should be acceptable
364-
let long_key = "k".repeat(255);
437+
// Create name and key with exactly 32 chars (should work)
438+
let long_name = "a".repeat(32); // 32 chars should be acceptable
439+
let long_key = "k".repeat(32);
365440

366441
let actor_id = common::create_actor_with_options(
367442
common::CreateActorOptions {
@@ -380,8 +455,8 @@ fn very_long_strings_for_names_and_key() {
380455
assert_eq!(actor["actor"]["name"], long_name);
381456
assert_eq!(actor["actor"]["key"], long_key);
382457

383-
// Try extremely long name (should fail)
384-
let too_long_name = "a".repeat(1000);
458+
// Try name with 33 chars (should fail)
459+
let too_long_name = "a".repeat(33);
385460
let client = reqwest::Client::new();
386461
let response = client
387462
.post(&format!(
@@ -398,12 +473,33 @@ fn very_long_strings_for_names_and_key() {
398473
.expect("Failed to send request");
399474
assert!(
400475
!response.status().is_success(),
401-
"Should fail with extremely long name"
476+
"Should fail with 33-character name"
477+
);
478+
479+
// Try key with 33 chars (should fail)
480+
let too_long_key = "k".repeat(33);
481+
let response = client
482+
.post(&format!(
483+
"http://127.0.0.1:{}/actors?namespace={}",
484+
ctx.leader_dc().guard_port(),
485+
namespace
486+
))
487+
.json(&json!({
488+
"name": "test",
489+
"key": too_long_key,
490+
}))
491+
.send()
492+
.await
493+
.expect("Failed to send request");
494+
assert!(
495+
!response.status().is_success(),
496+
"Should fail with 33-character key"
402497
);
403498
});
404499
}
405500

406501
#[test]
502+
#[ignore]
407503
fn special_characters_in_names_and_keys() {
408504
common::run(common::TestOpts::new(1), |ctx| async move {
409505
let (namespace, _, _runner) =
@@ -522,3 +618,120 @@ fn maximum_limits_32_actor_ids_in_list() {
522618
);
523619
});
524620
}
621+
622+
// MARK: Key collision tests
623+
624+
#[test]
625+
fn create_destroy_create_destroy_same_key_single_dc() {
626+
common::run(common::TestOpts::new(2), |ctx| async move {
627+
create_destroy_create_destroy_same_key_inner(ctx.leader_dc(), ctx.leader_dc()).await;
628+
});
629+
}
630+
631+
#[test]
632+
#[ignore]
633+
fn create_destroy_create_destroy_same_key_multi_dc() {
634+
common::run(common::TestOpts::new(2), |ctx| async move {
635+
create_destroy_create_destroy_same_key_inner(ctx.get_dc(2), ctx.get_dc(2)).await;
636+
});
637+
}
638+
639+
#[test]
640+
#[ignore]
641+
fn create_destroy_create_destroy_same_key_different_dc() {
642+
common::run(common::TestOpts::new(2), |ctx| async move {
643+
create_destroy_create_destroy_same_key_inner(ctx.leader_dc(), ctx.get_dc(2)).await;
644+
});
645+
}
646+
647+
async fn create_destroy_create_destroy_same_key_inner(
648+
target_dc1: &common::TestDatacenter,
649+
target_dc2: &common::TestDatacenter,
650+
) {
651+
let (namespace, _, runner) = common::setup_test_namespace_with_runner(target_dc1).await;
652+
let key = rand::random::<u16>().to_string();
653+
654+
// First create/destroy cycle
655+
let actor_id1 = common::create_actor_with_options(
656+
common::CreateActorOptions {
657+
namespace: namespace.clone(),
658+
key: Some(key.clone()),
659+
..Default::default()
660+
},
661+
target_dc1.guard_port(),
662+
)
663+
.await;
664+
665+
common::assert_actor_in_dc(&actor_id1, target_dc1.config.dc_label()).await;
666+
tokio::time::sleep(std::time::Duration::from_millis(500)).await;
667+
668+
// Destroy first actor
669+
tracing::info!(?actor_id1, "destroying first actor");
670+
common::destroy_actor(&actor_id1, &namespace, target_dc1.guard_port()).await;
671+
tokio::time::sleep(std::time::Duration::from_millis(500)).await;
672+
673+
// Second create/destroy cycle with same key
674+
let actor_id2 = common::create_actor_with_options(
675+
common::CreateActorOptions {
676+
namespace: namespace.clone(),
677+
key: Some(key.clone()),
678+
..Default::default()
679+
},
680+
target_dc2.guard_port(),
681+
)
682+
.await;
683+
684+
assert_ne!(actor_id1, actor_id2, "same actor id after first cycle");
685+
common::assert_actor_in_dc(&actor_id2, target_dc1.config.dc_label()).await;
686+
tokio::time::sleep(std::time::Duration::from_millis(500)).await;
687+
688+
// Destroy second actor
689+
tracing::info!(?actor_id2, "destroying second actor");
690+
common::destroy_actor(&actor_id2, &namespace, target_dc2.guard_port()).await;
691+
tokio::time::sleep(std::time::Duration::from_millis(500)).await;
692+
693+
// Third create/destroy cycle with same key
694+
let actor_id3 = common::create_actor_with_options(
695+
common::CreateActorOptions {
696+
namespace: namespace.clone(),
697+
key: Some(key.clone()),
698+
..Default::default()
699+
},
700+
target_dc1.guard_port(),
701+
)
702+
.await;
703+
704+
assert_ne!(actor_id1, actor_id3, "same actor id after second cycle (vs first)");
705+
assert_ne!(actor_id2, actor_id3, "same actor id after second cycle (vs second)");
706+
common::assert_actor_in_dc(&actor_id3, target_dc1.config.dc_label()).await;
707+
tokio::time::sleep(std::time::Duration::from_millis(500)).await;
708+
709+
// Destroy third actor
710+
tracing::info!(?actor_id3, "destroying third actor");
711+
common::destroy_actor(&actor_id3, &namespace, target_dc1.guard_port()).await;
712+
tokio::time::sleep(std::time::Duration::from_millis(500)).await;
713+
714+
// Fourth create/destroy cycle with same key
715+
let actor_id4 = common::create_actor_with_options(
716+
common::CreateActorOptions {
717+
namespace: namespace.clone(),
718+
key: Some(key.clone()),
719+
..Default::default()
720+
},
721+
target_dc2.guard_port(),
722+
)
723+
.await;
724+
725+
assert_ne!(actor_id1, actor_id4, "same actor id after third cycle (vs first)");
726+
assert_ne!(actor_id2, actor_id4, "same actor id after third cycle (vs second)");
727+
assert_ne!(actor_id3, actor_id4, "same actor id after third cycle (vs third)");
728+
common::assert_actor_in_dc(&actor_id4, target_dc1.config.dc_label()).await;
729+
tokio::time::sleep(std::time::Duration::from_millis(500)).await;
730+
731+
// Final destroy
732+
tracing::info!(?actor_id4, "destroying fourth actor");
733+
common::destroy_actor(&actor_id4, &namespace, target_dc2.guard_port()).await;
734+
tokio::time::sleep(std::time::Duration::from_millis(500)).await;
735+
736+
runner.shutdown().await;
737+
}

0 commit comments

Comments
 (0)