pub(crate) fn extract_test_fn_arg(args: &[String]) -> Option<&str> {
let mut iter = args.iter();
while let Some(a) = iter.next() {
if let Some(val) = a.strip_prefix("--ktstr-test-fn=") {
return Some(val);
}
if a == "--ktstr-test-fn" {
return iter.next().map(|s| s.as_str());
}
}
None
}
pub(crate) fn extract_probe_stack_arg(args: &[String]) -> Option<String> {
for a in args {
if let Some(val) = a.strip_prefix("--ktstr-probe-stack=")
&& !val.is_empty()
{
return Some(val.to_string());
}
}
None
}
pub(crate) fn extract_topo_arg(args: &[String]) -> Option<String> {
for a in args {
if let Some(val) = a.strip_prefix("--ktstr-topo=")
&& !val.is_empty()
{
return Some(val.to_string());
}
}
None
}
pub(crate) fn extract_flags_arg(args: &[String]) -> Option<Vec<String>> {
for a in args {
if let Some(val) = a.strip_prefix("--ktstr-flags=")
&& !val.is_empty()
{
return Some(val.split(',').map(|s| s.to_string()).collect());
}
}
None
}
pub(crate) fn extract_work_type_arg(args: &[String]) -> Option<String> {
for a in args {
if let Some(val) = a.strip_prefix("--ktstr-work-type=")
&& !val.is_empty()
{
return Some(val.to_string());
}
}
None
}
pub(crate) fn extract_export_test_arg(args: &[String]) -> Option<&str> {
for a in args {
if let Some(val) = a.strip_prefix("--ktstr-export-test=") {
return Some(val);
}
}
None
}
pub(crate) fn extract_export_output_arg(args: &[String]) -> Option<&str> {
for a in args {
if let Some(val) = a.strip_prefix("--ktstr-export-output=")
&& !val.is_empty()
{
return Some(val);
}
}
None
}
pub(crate) fn resolve_cgroup_root(args: &[String]) -> String {
let sched_args = std::fs::read_to_string("/sched_args").unwrap_or_default();
let parts: Vec<&str> = sched_args.split_whitespace().collect();
for i in 0..parts.len() {
if parts[i] == "--cell-parent-cgroup"
&& let Some(&path) = parts.get(i + 1)
{
return format!("/sys/fs/cgroup{path}");
}
}
let mut iter = args.iter();
while let Some(a) = iter.next() {
if a == "--cell-parent-cgroup"
&& let Some(path) = iter.next()
{
return format!("/sys/fs/cgroup{path}");
}
}
"/sys/fs/cgroup/ktstr".to_string()
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn extract_test_fn_arg_equals() {
let args = vec![
"ktstr".into(),
"run".into(),
"--ktstr-test-fn=my_test".into(),
];
assert_eq!(extract_test_fn_arg(&args), Some("my_test"));
}
#[test]
fn extract_test_fn_arg_space() {
let args = vec![
"ktstr".into(),
"run".into(),
"--ktstr-test-fn".into(),
"my_test".into(),
];
assert_eq!(extract_test_fn_arg(&args), Some("my_test"));
}
#[test]
fn extract_test_fn_arg_missing() {
let args = vec!["ktstr".into(), "run".into()];
assert!(extract_test_fn_arg(&args).is_none());
}
#[test]
fn extract_test_fn_arg_trailing() {
let args = vec!["ktstr".into(), "run".into(), "--ktstr-test-fn".into()];
assert!(extract_test_fn_arg(&args).is_none());
}
#[test]
fn extract_test_fn_arg_empty_value() {
let args = vec!["ktstr".into(), "run".into(), "--ktstr-test-fn=".into()];
assert_eq!(extract_test_fn_arg(&args), Some(""));
}
#[test]
fn extract_test_fn_arg_space_form_empty_args() {
let args: Vec<String> = vec![];
assert!(extract_test_fn_arg(&args).is_none());
}
#[test]
fn extract_probe_stack_arg_equals() {
let args = vec![
"ktstr".into(),
"run".into(),
"--ktstr-probe-stack=func_a,func_b".into(),
];
assert_eq!(
extract_probe_stack_arg(&args),
Some("func_a,func_b".to_string())
);
}
#[test]
fn extract_probe_stack_arg_missing() {
let args = vec!["ktstr".into(), "run".into()];
assert!(extract_probe_stack_arg(&args).is_none());
}
#[test]
fn extract_probe_stack_arg_empty_value() {
let args = vec!["ktstr".into(), "--ktstr-probe-stack=".into()];
assert!(extract_probe_stack_arg(&args).is_none());
}
#[test]
fn extract_topo_arg_equals() {
let args = vec!["bin".into(), "--ktstr-topo=1n2l4c2t".into()];
assert_eq!(extract_topo_arg(&args), Some("1n2l4c2t".to_string()));
}
#[test]
fn extract_topo_arg_missing() {
let args = vec!["bin".into(), "--ktstr-test-fn=test".into()];
assert!(extract_topo_arg(&args).is_none());
}
#[test]
fn extract_topo_arg_empty_value() {
let args = vec!["bin".into(), "--ktstr-topo=".into()];
assert!(extract_topo_arg(&args).is_none());
}
#[test]
fn extract_topo_arg_with_other_args() {
let args = vec![
"bin".into(),
"--ktstr-test-fn=my_test".into(),
"--ktstr-topo=1n1l2c1t".into(),
];
assert_eq!(extract_topo_arg(&args), Some("1n1l2c1t".to_string()));
}
#[test]
fn extract_work_type_arg_equals() {
let args = vec!["ktstr".into(), "--ktstr-work-type=SpinWait".into()];
assert_eq!(extract_work_type_arg(&args), Some("SpinWait".to_string()));
}
#[test]
fn extract_work_type_arg_missing() {
let args = vec!["ktstr".into(), "run".into()];
assert!(extract_work_type_arg(&args).is_none());
}
#[test]
fn extract_work_type_arg_empty_value() {
let args = vec!["ktstr".into(), "--ktstr-work-type=".into()];
assert!(extract_work_type_arg(&args).is_none());
}
#[test]
fn extract_export_test_arg_equals() {
let args = vec![
"test_bin".into(),
"--ktstr-export-test=preempt_regression".into(),
];
assert_eq!(extract_export_test_arg(&args), Some("preempt_regression"),);
}
#[test]
fn extract_export_test_arg_missing() {
let args = vec!["test_bin".into(), "--list".into()];
assert!(extract_export_test_arg(&args).is_none());
}
#[test]
fn extract_export_test_arg_empty_value() {
let args = vec!["test_bin".into(), "--ktstr-export-test=".into()];
assert_eq!(extract_export_test_arg(&args), Some(""));
}
#[test]
fn extract_export_output_arg_equals() {
let args = vec![
"test_bin".into(),
"--ktstr-export-output=/tmp/foo.run".into(),
];
assert_eq!(extract_export_output_arg(&args), Some("/tmp/foo.run"),);
}
#[test]
fn extract_export_output_arg_missing() {
let args = vec!["test_bin".into()];
assert!(extract_export_output_arg(&args).is_none());
}
#[test]
fn extract_export_output_arg_empty_value() {
let args = vec!["test_bin".into(), "--ktstr-export-output=".into()];
assert!(extract_export_output_arg(&args).is_none());
}
}