Skip to content
This repository was archived by the owner on Jul 17, 2025. It is now read-only.

Commit aec1c7a

Browse files
committed
tests: fixing a few things in the sharded nros case
Signed-off-by: Reto Achermann <achreto@gmail.com>
1 parent 0015958 commit aec1c7a

File tree

2 files changed

+69
-53
lines changed

2 files changed

+69
-53
lines changed

kernel/tests/s11_rackscale_benchmarks.rs

Lines changed: 47 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ fn rackscale_fxmark_benchmark(transport: RackscaleTransport) {
129129
test.file_name = file_name.clone();
130130
test.arg = Some(config);
131131

132-
fn cmd_fn(num_cores: usize, arg: Option<FxmarkConfig>) -> String {
132+
fn cmd_fn(num_cores: usize, _num_clients: usize, arg: Option<FxmarkConfig>) -> String {
133133
// TODO: add in arg with formatting.
134134
//1XmixX0 is - mix benchmark for 0% writes with 1 open file
135135
let config = arg.expect("Missing fxmark config");
@@ -296,7 +296,7 @@ fn rackscale_vmops_benchmark(transport: RackscaleTransport, benchtype: VMOpsBenc
296296
test.file_name = file_name.clone();
297297
test.arg = Some(benchtype);
298298

299-
fn cmd_fn(num_cores: usize, _arg: Option<VMOpsBench>) -> String {
299+
fn cmd_fn(num_cores: usize, _num_clients: usize, _arg: Option<VMOpsBench>) -> String {
300300
format!("initargs={}", num_cores)
301301
}
302302
fn baseline_timeout_fn(num_cores: usize) -> u64 {
@@ -427,7 +427,7 @@ fn s11_rackscale_shmem_leveldb_benchmark() {
427427
test.arg = Some(config);
428428
test.run_dhcpd_for_baseline = true;
429429

430-
fn cmd_fn(num_cores: usize, arg: Option<LevelDBConfig>) -> String {
430+
fn cmd_fn(num_cores: usize, _num_clients: usize, arg: Option<LevelDBConfig>) -> String {
431431
let config = arg.expect("missing leveldb config");
432432
format!(
433433
r#"init=dbbench.bin initargs={} appcmd='--threads={} --benchmarks=fillseq,readrandom --reads={} --num={} --value_size={}'"#,
@@ -630,7 +630,11 @@ fn rackscale_memcached_benchmark(transport: RackscaleTransport) {
630630
);
631631
}
632632

633-
fn cmd_fn(num_cores: usize, arg: Option<MemcachedInternalConfig>) -> String {
633+
fn cmd_fn(
634+
num_cores: usize,
635+
_num_clients: usize,
636+
arg: Option<MemcachedInternalConfig>,
637+
) -> String {
634638
let config = arg.expect("missing leveldb config");
635639
format!(
636640
r#"init=memcachedbench.bin initargs={} appcmd='--x-benchmark-mem={} --x-benchmark-queries={}'"#,
@@ -1018,9 +1022,6 @@ fn s11_rackscale_memcached_benchmark_sharded_linux() {
10181022

10191023
let r = pty.process.kill(SIGKILL);
10201024

1021-
1022-
println!("{:?}", res);
1023-
10241025
// single node
10251026
for protocol in &["tcp", "unix"] {
10261027
config.protocol = protocol;
@@ -1114,6 +1115,8 @@ fn s11_rackscale_memcached_benchmark_sharded_linux() {
11141115
#[test]
11151116
#[cfg(not(feature = "baremetal"))]
11161117
fn s11_rackscale_memcached_benchmark_sharded_nros() {
1118+
use rexpect::process::signal::Signal::SIGKILL;
1119+
11171120
let out_dir_path = PathBuf::from(env!("CARGO_TARGET_TMPDIR")).join("sharded-memcached");
11181121
let is_smoke = cfg!(feature = "smoke");
11191122

@@ -1148,7 +1151,7 @@ fn s11_rackscale_memcached_benchmark_sharded_nros() {
11481151
command.args(&["--binary"]);
11491152
command.arg(format!("--num-queries={}", config.num_queries).as_str());
11501153
command.arg(format!("--num-threads={}", config.num_threads).as_str());
1151-
command.arg(format!("--max-memory={}", config.mem_size).as_str());
1154+
command.arg(format!("--max-memory={}", config.mem_size / 8).as_str());
11521155
let mut servers = String::from("--servers=");
11531156
for i in 0..config.num_servers {
11541157
if i > 0 {
@@ -1206,14 +1209,16 @@ fn s11_rackscale_memcached_benchmark_sharded_nros() {
12061209
fn controller_run_fun(
12071210
config: Option<&MemcachedShardedConfig>,
12081211
num_servers: usize,
1212+
num_threads: usize,
12091213
timeout_ms: u64,
12101214
) -> Result<PtySession> {
12111215
// here we should wait
1212-
std::thread::sleep(Duration::from_secs(15));
1216+
std::thread::sleep(Duration::from_secs(15 + 2 * num_servers as u64));
12131217

12141218
let mut config = config.unwrap().clone();
12151219

12161220
config.num_servers = num_servers;
1221+
config.num_threads = num_servers * num_threads;
12171222
spawn_loadbalancer(&config, timeout_ms)
12181223
}
12191224

@@ -1245,7 +1250,7 @@ fn s11_rackscale_memcached_benchmark_sharded_nros() {
12451250
return Err(Error(Timeout(expected, got, timeout), st));
12461251
}
12471252
Err(err) => {
1248-
println!("Failed: {:?}", err);
1253+
// println!("Failed: {:?}", err);
12491254
return Err(err);
12501255
}
12511256
};
@@ -1259,7 +1264,6 @@ fn s11_rackscale_memcached_benchmark_sharded_nros() {
12591264
let r = csv_file.write(out.as_bytes());
12601265
assert!(r.is_ok());
12611266

1262-
println!("{:?}", res);
12631267
Ok(())
12641268
}
12651269

@@ -1272,22 +1276,6 @@ fn s11_rackscale_memcached_benchmark_sharded_nros() {
12721276
_is_baseline: bool,
12731277
_arg: Option<MemcachedShardedConfig>,
12741278
) -> Result<()> {
1275-
match proc.exp_regex(r#"\[ INFO\]: bootloader/src/kernel.rs"#) {
1276-
Ok(_) => (),
1277-
Err(rexpect::errors::Error(
1278-
rexpect::errors::ErrorKind::EOF(_expected, _s, _),
1279-
_state,
1280-
)) => {
1281-
// for l in s.lines() {
1282-
// println!("MEMCACHED-OUTPUT: {}", l);
1283-
// }
1284-
}
1285-
Err(e) => {
1286-
println!("{e:?}");
1287-
panic!("error")
1288-
}
1289-
}
1290-
12911279
match proc.exp_regex(r#"dhcp: vioif0: adding IP address (\d+).(\d+).(\d+).(\d+)/(\d+)"#) {
12921280
Ok((_prev, matched)) => {
12931281
println!(" > Networking setup succeeded. {matched}");
@@ -1311,7 +1299,7 @@ fn s11_rackscale_memcached_benchmark_sharded_nros() {
13111299
}
13121300

13131301
let (prev, matched) = proc.exp_regex(r#"x_benchmark_mem = (\d+) MB"#).unwrap();
1314-
println!("C> {}", matched);
1302+
println!("> {}", matched);
13151303
// let b_mem = matched.replace("x_benchmark_mem = ", "").replace(" MB", "");
13161304

13171305
*output += prev.as_str();
@@ -1334,16 +1322,21 @@ fn s11_rackscale_memcached_benchmark_sharded_nros() {
13341322

13351323
if !is_smoke {
13361324
test.shmem_size = std::cmp::max(
1337-
MEMCACHED_MEM_SIZE_MB * 8,
1338-
testutils::helpers::SHMEM_SIZE * 4,
1325+
MEMCACHED_MEM_SIZE_MB * 2,
1326+
testutils::helpers::SHMEM_SIZE * 2,
13391327
);
13401328
}
13411329

1342-
fn cmd_fn(num_cores: usize, arg: Option<MemcachedShardedConfig>) -> String {
1330+
fn cmd_fn(num_cores: usize, num_clients: usize, arg: Option<MemcachedShardedConfig>) -> String {
13431331
let config = arg.expect("missing configuration");
1332+
let num_threads = num_cores / num_clients;
1333+
13441334
format!(
13451335
r#"init=memcachedbench.bin initargs={} appcmd='--x-benchmark-no-run --disable-evictions --conn-limit=1024 --threads={} --x-benchmark-mem={} --memory-limit={}'"#,
1346-
num_cores, num_cores, config.mem_size, config.mem_size
1336+
num_threads,
1337+
num_threads,
1338+
config.mem_size,
1339+
config.mem_size * 2
13471340
)
13481341
}
13491342

@@ -1355,22 +1348,34 @@ fn s11_rackscale_memcached_benchmark_sharded_nros() {
13551348
1200_000 + 60_000 * num_cores as u64
13561349
}
13571350

1358-
fn mem_fn(num_cores: usize, _num_clients: usize, is_smoke: bool) -> usize {
1351+
fn mem_fn(_num_cores: usize, num_clients: usize, is_smoke: bool) -> usize {
13591352
if is_smoke {
13601353
8192
13611354
} else {
13621355
// Memory must also be divisible by number of nodes, which could be 1, 2, 3, or 4
1363-
(8192
1364-
+ std::cmp::max(
1365-
MEMCACHED_MEM_SIZE_MB * 8,
1366-
testutils::helpers::SHMEM_SIZE * 4,
1356+
// mem = result of this function / num_clients - shmem_size
1357+
(8092
1358+
+ 2 * std::cmp::max(
1359+
MEMCACHED_MEM_SIZE_MB * 2,
1360+
testutils::helpers::SHMEM_SIZE * 2,
13671361
))
1368-
* (((((num_cores + 1) / 2) + 3 - 1) / 3) * 3)
1362+
* num_clients
13691363
}
13701364
}
13711365

13721366
println!("----------------------------------------------------------");
13731367

1368+
let machine = Machine::determine();
1369+
1370+
let mut pings = Vec::new();
1371+
for i in 0..machine.max_numa_nodes() {
1372+
let mut command = Command::new("ping");
1373+
command.arg(&format!("172.31.0.{}", 10 + i + 1));
1374+
1375+
let proc = spawn_command(command, None).unwrap();
1376+
pings.push(proc);
1377+
}
1378+
13741379
// construct bench and run it!
13751380
let bench = RackscaleBench {
13761381
test,
@@ -1380,6 +1385,9 @@ fn s11_rackscale_memcached_benchmark_sharded_nros() {
13801385
mem_fn,
13811386
};
13821387
bench.run_bench(false, is_smoke);
1388+
for mut ping in pings.into_iter() {
1389+
ping.process.kill(SIGKILL);
1390+
}
13831391
}
13841392

13851393
#[test]
@@ -1428,7 +1436,7 @@ fn rackscale_monetdb_benchmark(transport: RackscaleTransport) {
14281436
test.arg = None;
14291437
test.run_dhcpd_for_baseline = true;
14301438

1431-
fn cmd_fn(num_cores: usize, _arg: Option<()>) -> String {
1439+
fn cmd_fn(num_cores: usize, _num_clients: usize, _arg: Option<()>) -> String {
14321440
format!(
14331441
r#"init=monetdbd.bin initargs={} appcmd='create dbfarm'"#,
14341442
num_cores

kernel/testutils/src/rackscale_runner.rs

Lines changed: 22 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
1+
use std::sync::atomic::{AtomicUsize, Ordering};
12
use std::sync::mpsc::{Receiver, Sender, TryRecvError};
23
use std::sync::{mpsc::channel, Arc, Mutex};
3-
use std::thread;
4+
use std::thread::{self, sleep};
45
use std::time::Duration;
56

67
use rexpect::errors::*;
@@ -47,8 +48,12 @@ type RackscaleMatchFn<T> = fn(
4748
arg: Option<T>,
4849
) -> Result<()>;
4950

50-
type ControllerRunFn<T> =
51-
fn(config: Option<&T>, num_clients: usize, timeout_ms: u64) -> Result<PtySession>;
51+
type ControllerRunFn<T> = fn(
52+
config: Option<&T>,
53+
num_clients: usize,
54+
num_threas: usize,
55+
timeout_ms: u64,
56+
) -> Result<PtySession>;
5257

5358
#[derive(Clone)]
5459
pub struct RackscaleRun<T>
@@ -457,6 +462,8 @@ impl<T: Clone + Send + 'static> RackscaleRun<T> {
457462
let (tx_build_timer, _rx_build_timer) = channel();
458463
let tx_build_timer_mut = Arc::new(Mutex::new(tx_build_timer));
459464

465+
let boot_counter = Arc::new(AtomicUsize::new(0));
466+
460467
// Run client in separate thead. Wait a bit to make sure controller started
461468
let mut client_procs = Vec::new();
462469
for i in 0..self.num_clients {
@@ -467,6 +474,7 @@ impl<T: Clone + Send + 'static> RackscaleRun<T> {
467474
let client_file_name = self.file_name.clone();
468475
let client_cmd = self.cmd.clone();
469476
let client_placement_cores = placement_cores.clone();
477+
let client_boot_counter = boot_counter.clone();
470478
let state = self.clone();
471479
let client_tx_build_timer = tx_build_timer_mut.clone();
472480
let use_large_pages = self.use_qemu_huge_pages;
@@ -495,14 +503,8 @@ impl<T: Clone + Send + 'static> RackscaleRun<T> {
495503
let mut output = String::new();
496504
let qemu_run = || -> Result<WaitStatus> {
497505
let mut p = spawn_nrk(&cmdline_client)?;
498-
499-
// output += p.exp_string("CLIENT READY")?.as_str();
500-
// {
501-
// let tx = client_tx_build_timer
502-
// .lock()
503-
// .expect("Failed to get build timer lock");
504-
// send_signal(&tx);
505-
// }
506+
output += p.exp_string("NRK booting on")?.as_str();
507+
client_boot_counter.fetch_add(1, Ordering::SeqCst);
506508

507509
// User-supplied function to check output
508510
(state.client_match_fn)(
@@ -552,6 +554,11 @@ impl<T: Clone + Send + 'static> RackscaleRun<T> {
552554
);
553555
})
554556
.expect("Client thread failed to spawn");
557+
558+
while i == boot_counter.load(Ordering::Relaxed) {
559+
thread::sleep(Duration::from_millis(500));
560+
}
561+
555562
client_procs.push(client);
556563
}
557564

@@ -576,6 +583,7 @@ impl<T: Clone + Send + 'static> RackscaleRun<T> {
576583
let mut p = run_fn(
577584
controller_arg.as_ref(),
578585
state.num_clients,
586+
state.cores_per_client,
579587
state.controller_timeout,
580588
)?;
581589

@@ -779,8 +787,8 @@ impl<T: Clone + Send + 'static> RackscaleRun<T> {
779787
pub struct RackscaleBench<T: Clone + Send + 'static> {
780788
// Test to run
781789
pub test: RackscaleRun<T>,
782-
// Function to calculate the command. Takes as argument number of application cores
783-
pub cmd_fn: fn(usize, Option<T>) -> String,
790+
// Function to calculate the command. Takes as argument number of application cores and the number of clients
791+
pub cmd_fn: fn(usize, usize, Option<T>) -> String,
784792
// Function to calculate the timeout. Takes as argument number of application cores
785793
pub rackscale_timeout_fn: fn(usize) -> u64,
786794
// Function to calculate the timeout. Takes as argument number of application cores
@@ -873,7 +881,7 @@ impl<T: Clone + Send + 'static> RackscaleBench<T> {
873881
test_run.num_clients = num_clients;
874882

875883
// Calculate command based on the number of cores
876-
test_run.cmd = (self.cmd_fn)(total_cores, test_run.arg.clone());
884+
test_run.cmd = (self.cmd_fn)(total_cores, num_clients, test_run.arg.clone());
877885

878886
// Caclulate memory for each component
879887
if !is_baseline {

0 commit comments

Comments
 (0)