Skip to content

Commit 355bb8b

Browse files
: global: close a few test gaps (#2183)
Summary: fill in a few missing tests Differential Revision: D89553139
1 parent 2a70896 commit 355bb8b

File tree

1 file changed

+205
-0
lines changed

1 file changed

+205
-0
lines changed

hyperactor_config/src/global.rs

Lines changed: 205 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -908,6 +908,13 @@ mod tests {
908908
py_name: None,
909909
})
910910
pub attr MESSAGE_TTL_DEFAULT: u8 = 64;
911+
912+
/// A test key with no environment variable mapping
913+
@meta(CONFIG = ConfigAttr {
914+
env_name: None,
915+
py_name: None,
916+
})
917+
pub attr CONFIG_KEY_NO_ENV: u32 = 100;
911918
}
912919

913920
#[test]
@@ -1369,4 +1376,202 @@ mod tests {
13691376

13701377
assert_eq!(get(MESSAGE_TTL_DEFAULT), 42);
13711378
}
1379+
1380+
#[test]
1381+
fn test_clientoverride_precedence_loses_to_all_other_layers() {
1382+
let _lock = lock();
1383+
reset_to_defaults();
1384+
1385+
// ClientOverride sets a baseline value.
1386+
let mut client = Attrs::new();
1387+
client[MESSAGE_TTL_DEFAULT] = 10;
1388+
set(Source::ClientOverride, client);
1389+
assert_eq!(get(MESSAGE_TTL_DEFAULT), 10);
1390+
1391+
// File should beat ClientOverride.
1392+
let mut file = Attrs::new();
1393+
file[MESSAGE_TTL_DEFAULT] = 20;
1394+
set(Source::File, file);
1395+
assert_eq!(get(MESSAGE_TTL_DEFAULT), 20);
1396+
1397+
// Runtime should beat both File and ClientOverride.
1398+
let mut runtime = Attrs::new();
1399+
runtime[MESSAGE_TTL_DEFAULT] = 30;
1400+
set(Source::Runtime, runtime);
1401+
assert_eq!(get(MESSAGE_TTL_DEFAULT), 30);
1402+
1403+
// Env should beat Runtime, File, and ClientOverride.
1404+
let mut env = Attrs::new();
1405+
env[MESSAGE_TTL_DEFAULT] = 40;
1406+
set(Source::Env, env);
1407+
assert_eq!(get(MESSAGE_TTL_DEFAULT), 40);
1408+
1409+
// Clear higher layers one by one to verify fallback.
1410+
clear(Source::Env);
1411+
assert_eq!(get(MESSAGE_TTL_DEFAULT), 30); // Runtime
1412+
1413+
clear(Source::Runtime);
1414+
assert_eq!(get(MESSAGE_TTL_DEFAULT), 20); // File
1415+
1416+
clear(Source::File);
1417+
assert_eq!(get(MESSAGE_TTL_DEFAULT), 10); // ClientOverride
1418+
}
1419+
1420+
#[test]
1421+
fn test_create_or_merge_clientoverride() {
1422+
let _lock = lock();
1423+
reset_to_defaults();
1424+
1425+
// Seed ClientOverride with one key.
1426+
let mut client = Attrs::new();
1427+
client[MESSAGE_TTL_DEFAULT] = 10;
1428+
set(Source::ClientOverride, client);
1429+
1430+
// Merge in a different key.
1431+
let mut update = Attrs::new();
1432+
update[MESSAGE_ACK_EVERY_N_MESSAGES] = 123;
1433+
create_or_merge(Source::ClientOverride, update);
1434+
1435+
// Both keys should now be visible.
1436+
assert_eq!(get(MESSAGE_TTL_DEFAULT), 10);
1437+
assert_eq!(get(MESSAGE_ACK_EVERY_N_MESSAGES), 123);
1438+
}
1439+
1440+
#[test]
1441+
fn test_override_or_global_returns_override_when_present() {
1442+
let _lock = lock();
1443+
reset_to_defaults();
1444+
1445+
// Set a global value via Env.
1446+
let mut env = Attrs::new();
1447+
env[MESSAGE_TTL_DEFAULT] = 99;
1448+
set(Source::Env, env);
1449+
1450+
// Create an override Attrs with a different value.
1451+
let mut overrides = Attrs::new();
1452+
overrides[MESSAGE_TTL_DEFAULT] = 42;
1453+
1454+
// Should return the override value, not global.
1455+
assert_eq!(override_or_global(&overrides, MESSAGE_TTL_DEFAULT), 42);
1456+
}
1457+
1458+
#[test]
1459+
fn test_override_or_global_returns_global_when_not_present() {
1460+
let _lock = lock();
1461+
reset_to_defaults();
1462+
1463+
// Set a global value via Env.
1464+
let mut env = Attrs::new();
1465+
env[MESSAGE_TTL_DEFAULT] = 99;
1466+
set(Source::Env, env);
1467+
1468+
// Empty overrides.
1469+
let overrides = Attrs::new();
1470+
1471+
// Should return the global value.
1472+
assert_eq!(override_or_global(&overrides, MESSAGE_TTL_DEFAULT), 99);
1473+
}
1474+
1475+
#[test]
1476+
fn test_runtime_attrs_returns_only_runtime_layer() {
1477+
let _lock = lock();
1478+
reset_to_defaults();
1479+
1480+
// Set values in multiple layers.
1481+
let mut file = Attrs::new();
1482+
file[MESSAGE_TTL_DEFAULT] = 10;
1483+
set(Source::File, file);
1484+
1485+
let mut env = Attrs::new();
1486+
env[SPLIT_MAX_BUFFER_SIZE] = 20;
1487+
set(Source::Env, env);
1488+
1489+
let mut runtime = Attrs::new();
1490+
runtime[MESSAGE_ACK_EVERY_N_MESSAGES] = 123;
1491+
set(Source::Runtime, runtime);
1492+
1493+
// runtime_attrs() should return only Runtime layer contents.
1494+
let rt = runtime_attrs();
1495+
1496+
// Should have the Runtime key.
1497+
assert_eq!(rt[MESSAGE_ACK_EVERY_N_MESSAGES], 123);
1498+
1499+
// Should NOT have File or Env keys.
1500+
assert!(!rt.contains_key(MESSAGE_TTL_DEFAULT));
1501+
assert!(!rt.contains_key(SPLIT_MAX_BUFFER_SIZE));
1502+
}
1503+
1504+
#[test]
1505+
fn test_override_key_without_env_name_does_not_mirror_to_env() {
1506+
let lock = lock();
1507+
reset_to_defaults();
1508+
1509+
// Verify default value.
1510+
assert_eq!(get(CONFIG_KEY_NO_ENV), 100);
1511+
1512+
// Override the key (which has no env_name).
1513+
let _guard = lock.override_key(CONFIG_KEY_NO_ENV, 999);
1514+
1515+
// Should see the override value.
1516+
assert_eq!(get(CONFIG_KEY_NO_ENV), 999);
1517+
1518+
// No env var should have been set (test doesn't crash,
1519+
// behavior is clean). This test mainly ensures no panic
1520+
// occurs during override/restore.
1521+
1522+
drop(_guard);
1523+
1524+
// Should restore to default.
1525+
assert_eq!(get(CONFIG_KEY_NO_ENV), 100);
1526+
}
1527+
1528+
#[test]
1529+
fn test_multiple_different_keys_overridden_simultaneously() {
1530+
let lock = lock();
1531+
reset_to_defaults();
1532+
1533+
// SAFETY: single-threaded test.
1534+
unsafe {
1535+
std::env::remove_var("HYPERACTOR_CODEC_MAX_FRAME_LENGTH");
1536+
std::env::remove_var("HYPERACTOR_MESSAGE_TTL_DEFAULT");
1537+
}
1538+
1539+
// Override multiple different keys at once.
1540+
let guard1 = lock.override_key(CODEC_MAX_FRAME_LENGTH, 1111);
1541+
let guard2 = lock.override_key(MESSAGE_TTL_DEFAULT, 42);
1542+
let guard3 = lock.override_key(CHANNEL_MULTIPART, false);
1543+
1544+
// All should reflect their override values.
1545+
assert_eq!(get(CODEC_MAX_FRAME_LENGTH), 1111);
1546+
assert_eq!(get(MESSAGE_TTL_DEFAULT), 42);
1547+
assert_eq!(get(CHANNEL_MULTIPART), false);
1548+
1549+
// Env vars should be mirrored.
1550+
assert_eq!(
1551+
std::env::var("HYPERACTOR_CODEC_MAX_FRAME_LENGTH").unwrap(),
1552+
"1111"
1553+
);
1554+
assert_eq!(
1555+
std::env::var("HYPERACTOR_MESSAGE_TTL_DEFAULT").unwrap(),
1556+
"42"
1557+
);
1558+
1559+
// Drop guards in arbitrary order.
1560+
drop(guard2); // Drop MESSAGE_TTL_DEFAULT first
1561+
1562+
// MESSAGE_TTL_DEFAULT should restore, others should remain.
1563+
assert_eq!(get(MESSAGE_TTL_DEFAULT), MESSAGE_TTL_DEFAULT_DEFAULT);
1564+
assert_eq!(get(CODEC_MAX_FRAME_LENGTH), 1111);
1565+
assert_eq!(get(CHANNEL_MULTIPART), false);
1566+
1567+
// Env for MESSAGE_TTL_DEFAULT should be cleared.
1568+
assert!(std::env::var("HYPERACTOR_MESSAGE_TTL_DEFAULT").is_err());
1569+
1570+
drop(guard1);
1571+
drop(guard3);
1572+
1573+
// All should be restored.
1574+
assert_eq!(get(CODEC_MAX_FRAME_LENGTH), CODEC_MAX_FRAME_LENGTH_DEFAULT);
1575+
assert_eq!(get(CHANNEL_MULTIPART), CHANNEL_MULTIPART_DEFAULT);
1576+
}
13721577
}

0 commit comments

Comments
 (0)