nushell/crates/nu-command/tests/commands/job.rs
2025-04-13 00:04:54 -03:00

268 lines
7.1 KiB
Rust

use nu_test_support::{nu, playground::Playground};
#[test]
fn jobs_do_run() {
Playground::setup("job_test_1", |dirs, sandbox| {
sandbox.with_files(&[]);
let actual = nu!(
cwd: dirs.root(),
r#"
rm -f a.txt;
job spawn { sleep 200ms; 'a' | save a.txt };
let before = 'a.txt' | path exists;
sleep 400ms;
let after = 'a.txt' | path exists;
[$before, $after] | to nuon"#
);
assert_eq!(actual.out, "[false, true]");
})
}
#[test]
fn first_job_id_is_one() {
let actual = nu!(r#"job spawn {} | to nuon"#);
assert_eq!(actual.out, "1");
}
#[test]
fn job_list_adds_jobs_correctly() {
let actual = nu!(format!(
r#"
let list0 = job list | get id;
let job1 = job spawn {{ sleep 20ms }};
let list1 = job list | get id;
let job2 = job spawn {{ sleep 20ms }};
let list2 = job list | get id;
let job3 = job spawn {{ sleep 20ms }};
let list3 = job list | get id;
[({}), ({}), ({}), ({})] | to nuon
"#,
"$list0 == []",
"$list1 == [$job1]",
"($list2 | sort) == ([$job1, $job2] | sort)",
"($list3 | sort) == ([$job1, $job2, $job3] | sort)"
));
assert_eq!(actual.out, "[true, true, true, true]");
}
#[test]
fn jobs_get_removed_from_list_after_termination() {
let actual = nu!(format!(
r#"
let job = job spawn {{ sleep 0.5sec }};
let list0 = job list | get id;
sleep 1sec
let list1 = job list | get id;
[({}) ({})] | to nuon
"#,
"$list0 == [$job]", "$list1 == []",
));
assert_eq!(actual.out, "[true, true]");
}
#[test]
fn job_list_shows_pids() {
let actual = nu!(format!(
r#"
let job1 = job spawn {{ nu -c "sleep 1sec" | nu -c "sleep 2sec" }};
sleep 500ms;
let list0 = job list | where id == $job1 | first | get pids;
sleep 1sec;
let list1 = job list | where id == $job1 | first | get pids;
[({}), ({}), ({})] | to nuon
"#,
"($list0 | length) == 2", "($list1 | length) == 1", "$list1.0 in $list0",
));
assert_eq!(actual.out, "[true, true, true]");
}
#[test]
fn killing_job_removes_it_from_table() {
let actual = nu!(format!(
r#"
let job1 = job spawn {{ sleep 100ms }}
let job2 = job spawn {{ sleep 100ms }}
let job3 = job spawn {{ sleep 100ms }}
let list_before = job list | get id
job kill $job1
let list_after_kill_1 = job list | get id
job kill $job2
let list_after_kill_2 = job list | get id
job kill $job3
let list_after_kill_3 = job list | get id
[({}) ({}) ({}) ({})] | to nuon
"#,
"($list_before | sort) == ([$job1 $job2 $job3] | sort)",
"($list_after_kill_1 | sort) == ([$job2 $job3] | sort)",
"($list_after_kill_2 | sort) == ([$job3] | sort)",
"$list_after_kill_3 == []",
));
assert_eq!(actual.out, "[true, true, true, true]");
}
#[test]
fn killing_job_kills_pids() {
let actual = nu!(format!(
r#"
let job1 = job spawn {{ nu -c "sleep 1sec" | nu -c "sleep 1sec" }}
sleep 25ms
let pids = job list | where id == $job1 | get pids
let child_pids_before = ps | where ppid == $nu.pid
job kill $job1
sleep 25ms
let child_pids_after = ps | where ppid == $nu.pid
[({}) ({})] | to nuon
"#,
"($child_pids_before | length) == 2", "$child_pids_after == []",
));
assert_eq!(actual.out, "[true, true]");
}
#[test]
fn exiting_nushell_kills_jobs() {
let actual = nu!(r#"
let result = nu -c "let job = job spawn { nu -c 'sleep 1sec' };
sleep 100ms;
let child_pid = job list | where id == $job | get pids | first;
[$nu.pid $child_pid] | to nuon"
let info = $result | from nuon
let child_pid = $info.0
let grandchild_pid = $info.1
ps | where pid == $grandchild_pid | filter { $in.ppid in [$child_pid, 1] } | length | to nuon
"#);
assert_eq!(actual.out, "0");
}
#[cfg(unix)]
#[test]
fn jobs_get_group_id_right() {
let actual = nu!(r#"
let job1 = job spawn { nu -c "sleep 0.5sec" | nu -c "sleep 0.5sec"; }
sleep 25ms
let pids = job list | where id == $job1 | first | get pids
let pid1 = $pids.0
let pid2 = $pids.1
let groups = ^ps -ax -o pid,pgid | from ssv -m 1 | update PID {|it| $it.PID | into int} | update PGID {|it| $it.PGID | into int}
let my_group = $groups | where PID == $nu.pid | first | get PGID
let group1 = $groups | where PID == $pid1 | first | get PGID
let group2 = $groups | where PID == $pid2 | first | get PGID
[($my_group != $group1) ($my_group != $group2) ($group1 == $group2)] | to nuon
"#,);
assert_eq!(actual.out, "[true, true, true]");
}
#[test]
fn job_extern_output_is_silent() {
let actual = nu!(r#" job spawn { nu -c "'hi'" }; sleep 1sec"#);
assert_eq!(actual.out, "");
assert_eq!(actual.err, "");
}
#[test]
fn job_print_is_not_silent() {
let actual = nu!(r#" job spawn { print "hi" }; sleep 1sec"#);
assert_eq!(actual.out, "hi");
assert_eq!(actual.err, "");
}
#[test]
fn job_extern_into_value_is_not_silent() {
let actual = nu!(r#" job spawn { print (nu -c "'hi'") }; sleep 1sec"#);
assert_eq!(actual.out, "hi");
assert_eq!(actual.err, "");
}
#[test]
fn job_extern_into_pipe_is_not_silent() {
let actual = nu!(r#"
job spawn {
print (nu -c "10" | nu --stdin -c "($in | into int) + 1")
}
sleep 1sec"#);
assert_eq!(actual.out, "11");
assert_eq!(actual.err, "");
}
#[test]
fn job_list_returns_no_tag_when_job_is_untagged() {
let actual = nu!(r#"
job spawn { sleep 10sec }
job spawn { sleep 10sec }
job spawn { sleep 10sec }
('tag' in (job list | columns)) | to nuon"#);
assert_eq!(actual.out, "false");
assert_eq!(actual.err, "");
}
#[test]
fn job_list_returns_tag_when_job_is_spawned_with_tag() {
let actual = nu!(r#"
job spawn { sleep 10sec } --tag abc
job list | where id == 1 | get tag.0
"#);
assert_eq!(actual.out, "abc");
assert_eq!(actual.err, "");
}
#[test]
fn job_tag_modifies_untagged_job_tag() {
let actual = nu!(r#"
job spawn { sleep 10sec }
job tag 1 beep
job list | where id == 1 | get tag.0"#);
assert_eq!(actual.out, "beep");
assert_eq!(actual.err, "");
}
#[test]
fn job_tag_modifies_tagged_job_tag() {
let actual = nu!(r#"
job spawn { sleep 10sec } --tag abc
job tag 1 beep
job list | where id == 1 | get tag.0"#);
assert_eq!(actual.out, "beep");
assert_eq!(actual.err, "");
}