use quote::quote;
use crate::{analyze::Ownership, Settings};
#[test]
fn unused_resource() {
let (_app, analysis) = crate::parse2(
quote!(),
quote!(
const APP: () = {
struct Resources {
#[init(0)]
x: i32,
}
};
),
Settings::default(),
)
.unwrap();
assert!(analysis.locations.is_empty());
}
#[test]
fn unused_task() {
crate::parse2(
quote!(),
quote!(
const APP: () = {
#[task]
fn foo(_: foo::Context) {}
};
),
Settings::default(),
)
.unwrap();
}
#[test]
fn resource_owned() {
let (_app, analysis) = crate::parse2(
quote!(),
quote!(
const APP: () = {
struct Resources {
#[init(0)]
x: i32,
}
#[task(resources = [x])]
fn foo(_: foo::Context) {}
};
),
Settings::default(),
)
.unwrap();
let (res, ownership) = analysis.ownerships.iter().next().unwrap();
assert_eq!(res.to_string(), "x");
assert_eq!(*ownership, Ownership::Owned { priority: 1 });
}
#[test]
fn resource_coowned() {
let (_app, analysis) = crate::parse2(
quote!(),
quote!(
const APP: () = {
struct Resources {
#[init(0)]
x: i32,
}
#[task(resources = [x])]
fn foo(_: foo::Context) {}
#[task(resources = [x])]
fn bar(_: bar::Context) {}
};
),
Settings::default(),
)
.unwrap();
let (res, ownership) = analysis.ownerships.iter().next().unwrap();
assert_eq!(res.to_string(), "x");
assert_eq!(*ownership, Ownership::CoOwned { priority: 1 });
}
#[test]
fn resource_contended() {
let (_app, analysis) = crate::parse2(
quote!(),
quote!(
const APP: () = {
struct Resources {
#[init(0)]
x: i32,
}
#[task(resources = [x])]
fn foo(_: foo::Context) {}
#[task(priority = 2, resources = [x])]
fn bar(_: bar::Context) {}
};
),
Settings::default(),
)
.unwrap();
let (res, ownership) = analysis.ownerships.iter().next().unwrap();
assert_eq!(res.to_string(), "x");
assert_eq!(*ownership, Ownership::Contended { ceiling: 2 });
}
#[test]
fn no_send_late_resources_idle() {
let (_app, analysis) = crate::parse2(
quote!(),
quote!(
const APP: () = {
struct Resources {
x: i32,
}
#[init]
fn init(_: init::Context) -> init::LateResources {
..
}
#[idle(resources = [x])]
fn idle(_: idle::Context) -> ! {
loop {}
}
};
),
Settings::default(),
)
.unwrap();
assert!(analysis.send_types.is_empty());
}
#[test]
fn no_send_spawn() {
let (_app, analysis) = crate::parse2(
quote!(),
quote!(
const APP: () = {
#[task(spawn = [bar])]
fn foo(_: foo::Context) {}
#[task]
fn bar(_: bar::Context, _: X) {}
};
),
Settings::default(),
)
.unwrap();
assert!(analysis.send_types.is_empty());
}
#[test]
fn no_send_schedule() {
let (_app, analysis) = crate::parse2(
quote!(),
quote!(
const APP: () = {
#[task(schedule = [bar])]
fn foo(_: foo::Context) {}
#[task]
fn bar(_: bar::Context, _: X) {}
#[task(priority = 2, schedule = [baz])]
fn baz(_: baz::Context) {}
};
),
Settings {
parse_schedule: true,
..Settings::default()
},
)
.unwrap();
assert!(analysis.send_types.is_empty());
assert_eq!(analysis.timer_queues[&0].priority, 2);
}
#[test]
fn send_spawn() {
let (_app, analysis) = crate::parse2(
quote!(),
quote!(
const APP: () = {
#[task(priority = 2, spawn = [bar])]
fn foo(_: foo::Context) {}
#[task]
fn bar(_: bar::Context, _: X) {}
};
),
Settings::default(),
)
.unwrap();
let ty = analysis.send_types[&0].iter().next().unwrap();
assert_eq!(quote!(#ty).to_string(), "X");
}
#[test]
fn send_schedule() {
let (_app, analysis) = crate::parse2(
quote!(),
quote!(
const APP: () = {
#[task(priority = 2, schedule = [bar])]
fn foo(_: foo::Context) {}
#[task]
fn bar(_: bar::Context, _: X) {}
};
),
Settings {
parse_schedule: true,
..Settings::default()
},
)
.unwrap();
let ty = analysis.send_types[&0].iter().next().unwrap();
assert_eq!(quote!(#ty).to_string(), "X");
}
#[test]
fn send_late_resource() {
let (_app, analysis) = crate::parse2(
quote!(),
quote!(
const APP: () = {
struct Resources {
a: X,
}
#[init]
fn init(_: init::Context) -> init::LateResources {
..
}
#[task(resources = [a])]
fn foo(_: foo::Context) {}
};
),
Settings::default(),
)
.unwrap();
let ty = analysis.send_types[&0].iter().next().unwrap();
assert_eq!(quote!(#ty).to_string(), "X");
}
#[test]
fn send_shared_with_init() {
let (_app, analysis) = crate::parse2(
quote!(),
quote!(
const APP: () = {
struct Resources {
#[init(0)]
x: i32,
}
#[init(resources = [x])]
fn init(_: init::Context) {}
#[task(resources = [x])]
fn foo(_: foo::Context) {}
};
),
Settings::default(),
)
.unwrap();
let ty = analysis.send_types[&0].iter().next().unwrap();
assert_eq!(quote!(#ty).to_string(), "i32");
}
#[test]
fn not_sync() {
let (_app, analysis) = crate::parse2(
quote!(),
quote!(
const APP: () = {
struct Resources {
#[init(0)]
x: i32,
}
#[task(resources = [x])]
fn foo(_: foo::Context) {}
#[task(resources = [x])]
fn bar(_: bar::Context) {}
};
),
Settings::default(),
)
.unwrap();
assert!(analysis.sync_types.is_empty());
}
#[test]
fn sync() {
let (_app, analysis) = crate::parse2(
quote!(),
quote!(
const APP: () = {
struct Resources {
#[init(0)]
x: i32,
}
#[task(resources = [&x])]
fn foo(_: foo::Context) {}
#[task(priority = 2, resources = [&x])]
fn bar(_: bar::Context) {}
};
),
Settings::default(),
)
.unwrap();
let ty = analysis.sync_types[&0].iter().next().unwrap();
assert_eq!(quote!(#ty).to_string(), "i32");
}
#[test]
fn late_resources() {
let (_app, analysis) = crate::parse2(
quote!(),
quote!(
const APP: () = {
struct Resources {
x: i32,
}
#[init]
fn init(_: init::Context) -> init::LateResources {
..
}
};
),
Settings::default(),
)
.unwrap();
let late = &analysis.late_resources[&0];
assert_eq!(late.len(), 1);
}
#[test]
fn tq1() {
let (_app, analysis) = crate::parse2(
quote!(),
quote!(
const APP: () = {
#[task]
fn foo(_: foo::Context) {}
#[task(priority = 2, schedule = [bar])]
fn bar(_: bar::Context) {}
};
),
Settings {
parse_schedule: true,
..Settings::default()
},
)
.unwrap();
let tq = &analysis.timer_queues[&0];
assert_eq!(tq.priority, 2);
assert_eq!(tq.ceiling, 2);
assert_eq!(tq.tasks.len(), 1);
assert_eq!(tq.tasks.iter().next().unwrap().to_string(), "bar");
}
#[test]
fn tq2() {
let (_app, analysis) = crate::parse2(
quote!(),
quote!(
const APP: () = {
#[task]
fn foo(_: foo::Context) {}
#[task(priority = 2, schedule = [foo])]
fn bar(_: bar::Context) {}
};
),
Settings {
parse_schedule: true,
..Settings::default()
},
)
.unwrap();
let tq = &analysis.timer_queues[&0];
assert_eq!(tq.priority, 1);
assert_eq!(tq.ceiling, 2);
assert_eq!(tq.tasks.len(), 1);
assert_eq!(tq.tasks.iter().next().unwrap().to_string(), "foo");
}
#[test]
fn tq3() {
let (_app, analysis) = crate::parse2(
quote!(),
quote!(
const APP: () = {
#[task]
fn foo(_: foo::Context) {}
#[task(priority = 2, schedule = [baz])]
fn bar(_: bar::Context) {}
#[task(priority = 3)]
fn baz(_: baz::Context) {}
};
),
Settings {
parse_schedule: true,
..Settings::default()
},
)
.unwrap();
let tq = &analysis.timer_queues[&0];
assert_eq!(tq.priority, 3);
assert_eq!(tq.ceiling, 3);
assert_eq!(tq.tasks.len(), 1);
assert_eq!(tq.tasks.iter().next().unwrap().to_string(), "baz");
}
#[test]
fn gh183() {
let (_app, analysis) = crate::parse2(
quote!(),
quote!(
const APP: () = {
#[task(priority = 2)]
fn foo(_: foo::Context) {}
#[task(schedule = [foo])]
fn bar(_: bar::Context) {}
};
),
Settings {
parse_schedule: true,
..Settings::default()
},
)
.unwrap();
let tq = &analysis.timer_queues[&0];
assert_eq!(tq.priority, 2);
assert_eq!(tq.ceiling, 2);
}