Implement remaining TestClient service commands (#94)
This commit is contained in:
215
programs/tests/test_client_services_cli.rs
Normal file
215
programs/tests/test_client_services_cli.rs
Normal file
@@ -0,0 +1,215 @@
|
||||
use std::fs;
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::process::{Command, Output, Stdio};
|
||||
use std::sync::atomic::{AtomicU64, Ordering};
|
||||
|
||||
const CLIENT: &str = "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee";
|
||||
const AVATAR: &str = "11111111-2222-3333-4444-555555555555";
|
||||
const BOT: &str = "22222222-3333-4444-5555-666666666666";
|
||||
const GROUP: &str = "33333333-4444-5555-6666-777777777777";
|
||||
const MEMBER: &str = "44444444-5555-6666-7777-888888888888";
|
||||
const ROLE: &str = "55555555-6666-7777-8888-999999999999";
|
||||
const CLASSIFIED: &str = "66666666-7777-8888-9999-aaaaaaaaaaaa";
|
||||
const LAND: &str = "77777777-8888-9999-aaaa-bbbbbbbbbbbb";
|
||||
const SIM: &str = "88888888-9999-aaaa-bbbb-cccccccccccc";
|
||||
const OBJECT: &str = "99999999-aaaa-bbbb-cccc-dddddddddddd";
|
||||
const DANCE1: &str = "b68a3d7c-de9e-fc87-eec8-543d787e5b0d";
|
||||
|
||||
static TEMP_ID: AtomicU64 = AtomicU64::new(0);
|
||||
|
||||
struct TestDir(PathBuf);
|
||||
impl TestDir {
|
||||
fn new() -> Self {
|
||||
let id = TEMP_ID.fetch_add(1, Ordering::Relaxed);
|
||||
let path = std::env::temp_dir().join(format!(
|
||||
"metacrate-test-client-services-{}-{id}",
|
||||
std::process::id()
|
||||
));
|
||||
fs::create_dir(&path).expect("create test directory");
|
||||
Self(path)
|
||||
}
|
||||
fn write(&self, contents: &str) -> PathBuf {
|
||||
let path = self.0.join("session.tsv");
|
||||
fs::write(&path, contents).expect("write script");
|
||||
path
|
||||
}
|
||||
}
|
||||
impl Drop for TestDir {
|
||||
fn drop(&mut self) {
|
||||
let _ = fs::remove_dir_all(&self.0);
|
||||
}
|
||||
}
|
||||
fn path_text(path: &Path) -> &str {
|
||||
path.to_str().expect("UTF-8 test path")
|
||||
}
|
||||
fn run(args: &[&str]) -> Output {
|
||||
Command::new(env!("CARGO_BIN_EXE_test-client"))
|
||||
.args(args)
|
||||
.stdin(Stdio::null())
|
||||
.stdout(Stdio::piped())
|
||||
.stderr(Stdio::piped())
|
||||
.output()
|
||||
.expect("run test-client")
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[allow(clippy::too_many_lines)]
|
||||
fn full_offline_session_exercises_every_remaining_non_voice_command() {
|
||||
let directory = TestDir::new();
|
||||
let script = directory.write(&format!(
|
||||
"!client\t{CLIENT}\tAlice\tBot\n\
|
||||
!service-avatar\t{CLIENT}\t{AVATAR}\tActive Resident\tBuilders\t128\t129\t25\t10\ttrue\n\
|
||||
!service-avatar\t{CLIENT}\t{BOT}\tQuiet Bot\tNone\t130\t131\t25\t11\tfalse\n\
|
||||
!service-friend\t{CLIENT}\t{AVATAR}\tActive Resident\ttrue\t4294967298000\t128\t129\t25\n\
|
||||
!service-group\t{CLIENT}\t{GROUP}\tBuilders Guild\n\
|
||||
!service-group-result\t{CLIENT}\t{GROUP}\tBuilders Guild\t42\n\
|
||||
!service-group-member\t{CLIENT}\t{GROUP}\t{MEMBER}\n\
|
||||
!service-group-role\t{CLIENT}\t{GROUP}\t{ROLE}\tOfficer\tArchitect\n\
|
||||
!service-person\t{CLIENT}\t{AVATAR}\tActive\tResident\ttrue\n\
|
||||
!service-classified\t{CLIENT}\t{CLASSIFIED}\tBuilder Services\t25\n\
|
||||
!service-event\t{CLIENT}\t7\tBuilding Class\tToday\n\
|
||||
!service-event-info\t{CLIENT}\t7\tBuilding Class\tTest Region\t1000\t2000\t25\n\
|
||||
!service-land\t{CLIENT}\t{LAND}\tBuilder Parcel\t1024\t500\n\
|
||||
!service-place\t{CLIENT}\tBuilder Plaza\tTest Region\t128\t128\t25\n\
|
||||
!service-sim\t{CLIENT}\tTest Region\t{SIM}\t4294967298000\t0.98\n\
|
||||
!service-utilization\t{CLIENT}\ttrue\n\
|
||||
!service-utilization-row\t{CLIENT}\tpacket\tAgentUpdate\t2\t3\t2048\t4096\n\
|
||||
!service-utilization-row\t{CLIENT}\tcapability\tEventQueueGet\t1\t4\t512\t8192\n\
|
||||
who\n\
|
||||
bots\n\
|
||||
friends\n\
|
||||
mapfriend {AVATAR}\n\
|
||||
key2name {AVATAR}\n\
|
||||
key2name {GROUP}\n\
|
||||
searchclassifieds Builder\n\
|
||||
searchevents Building\n\
|
||||
searchgroups Builders\n\
|
||||
searchland mainland 1000 512\n\
|
||||
searchpeople Active\n\
|
||||
searchplaces Builder\n\
|
||||
showevent 7\n\
|
||||
groups\n\
|
||||
groupmembers Builders Guild\n\
|
||||
grouproles Builders Guild\n\
|
||||
play list\n\
|
||||
play show\n\
|
||||
dilation\n\
|
||||
netstats\n\
|
||||
regioninfo\n\
|
||||
stats\n\
|
||||
uptime\n\
|
||||
cloneprofile {AVATAR} --confirm\n\
|
||||
sendgeneric test-method alpha beta --confirm\n\
|
||||
play DANCE1 --confirm\n\
|
||||
touch {OBJECT} --confirm\n\
|
||||
activategroup Builders Guild --confirm\n\
|
||||
invitegroup {AVATAR} {GROUP} {ROLE} --confirm\n\
|
||||
joingroup Builders Guild --confirm\n\
|
||||
leavegroup Builders Guild --confirm\n\
|
||||
quit\n"
|
||||
));
|
||||
let output = run(&[
|
||||
"--allow-live-mutations",
|
||||
"--allow-spending",
|
||||
"--fake-script",
|
||||
path_text(&script),
|
||||
]);
|
||||
let stdout = String::from_utf8(output.stdout).expect("UTF-8 stdout");
|
||||
let stderr = String::from_utf8(output.stderr).expect("UTF-8 stderr");
|
||||
assert!(
|
||||
output.status.success(),
|
||||
"stdout:\n{stdout}\nstderr:\n{stderr}"
|
||||
);
|
||||
assert!(stderr.is_empty(), "{stderr}");
|
||||
for expected in [
|
||||
"Active Resident (Group: Builders",
|
||||
"Quiet Bot (Group: None",
|
||||
"Is Probably a bot",
|
||||
"has 1 friends:",
|
||||
"Found Friend 11111111-2222-3333-4444-555555555555",
|
||||
"Avatar: Active Resident",
|
||||
"Group: Builders Guild",
|
||||
"returned 1 classified ads",
|
||||
"matched 1 Events",
|
||||
"matched 1 Groups",
|
||||
"1 results",
|
||||
"matched 1 People",
|
||||
"returned 1 results",
|
||||
"<redacted-url> Region/232/208/0",
|
||||
"got 1 groups",
|
||||
"MemberCount 1",
|
||||
"RoleCount 1",
|
||||
"AFRAID",
|
||||
DANCE1,
|
||||
"Dilation is 0.98",
|
||||
"Capabilities Totals",
|
||||
"Packet Totals",
|
||||
"UUID: 88888888-9999-aaaa-bbbb-cccccccccccc",
|
||||
"Packets in the queue:",
|
||||
"I am Alice Bot, Up Since:",
|
||||
"Synchronized our profile",
|
||||
"Sent generic message with method test-method",
|
||||
"Touched object",
|
||||
"Active group is now Builders Guild",
|
||||
"invited",
|
||||
"Joined the group Builders Guild",
|
||||
"has left the group Builders Guild",
|
||||
"CALL profile-clone",
|
||||
"CALL generic-message",
|
||||
"CALL animation-start",
|
||||
"CALL object-touch",
|
||||
"CALL group-activate",
|
||||
"CALL group-invite",
|
||||
"CALL group-join",
|
||||
"CALL group-leave",
|
||||
] {
|
||||
assert!(stdout.contains(expected), "missing {expected:?}:\n{stdout}");
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn social_mutations_require_startup_and_per_command_confirmation() {
|
||||
let directory = TestDir::new();
|
||||
let script = directory.write(&format!(
|
||||
"!client\t{CLIENT}\tAlice\tBot\nplay {DANCE1} --confirm\nquit\n"
|
||||
));
|
||||
let output = run(&["--fake-script", path_text(&script)]);
|
||||
let stdout = String::from_utf8(output.stdout).expect("UTF-8 stdout");
|
||||
assert!(output.status.success());
|
||||
assert!(stdout.contains("Live mutations are disabled"), "{stdout}");
|
||||
assert!(!stdout.contains("CALL animation-start"), "{stdout}");
|
||||
|
||||
let script = directory.write(&format!(
|
||||
"!client\t{CLIENT}\tAlice\tBot\ntouch {OBJECT}\nquit\n"
|
||||
));
|
||||
let output = run(&[
|
||||
"--allow-live-mutations",
|
||||
"--fake-script",
|
||||
path_text(&script),
|
||||
]);
|
||||
let stdout = String::from_utf8(output.stdout).expect("UTF-8 stdout");
|
||||
assert!(output.status.success());
|
||||
assert!(stdout.contains("append --confirm"), "{stdout}");
|
||||
assert!(!stdout.contains("CALL object-touch"), "{stdout}");
|
||||
|
||||
let script = directory.write(&format!(
|
||||
"!client\t{CLIENT}\tAlice\tBot\njoingroup uuid {GROUP} --confirm\nquit\n"
|
||||
));
|
||||
let output = run(&[
|
||||
"--allow-live-mutations",
|
||||
"--fake-script",
|
||||
path_text(&script),
|
||||
]);
|
||||
let stdout = String::from_utf8(output.stdout).expect("UTF-8 stdout");
|
||||
assert!(output.status.success());
|
||||
assert!(stdout.contains("restart with --allow-spending"), "{stdout}");
|
||||
assert!(!stdout.contains("CALL group-join"), "{stdout}");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn command_inventory_leaves_only_explicit_voice_adapters() {
|
||||
assert_eq!(
|
||||
libremetaverse_programs::test_client::pending_test_client_commands(),
|
||||
["ParcelVoiceInfo", "VoiceAcountCommand"]
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user