blob: 6cd3f2f36344d1e8b2ec91be54e18d22be92d89a [file] [log] [blame]
David Brazdil66fc1202022-07-04 21:48:45 +01001// Copyright 2022, The Android Open Source Project
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15//! Integration test for Rialto.
16
17use android_system_virtualizationservice::{
18 aidl::android::system::virtualizationservice::{
19 VirtualMachineConfig::VirtualMachineConfig,
20 VirtualMachineRawConfig::VirtualMachineRawConfig,
21 },
22 binder::{ParcelFileDescriptor, ProcessState},
23};
24use anyhow::{Context, Error};
25use log::info;
26use std::fs::File;
27use std::io::{self, BufRead, BufReader};
28use std::os::unix::io::FromRawFd;
29use std::panic;
30use std::thread;
31use vmclient::{DeathReason, VmInstance};
32
33const RIALTO_PATH: &str = "/data/local/tmp/rialto_test/arm64/rialto.bin";
34
35/// Runs the Rialto VM as an unprotected VM via VirtualizationService.
36#[test]
37fn test_boots() -> Result<(), Error> {
38 android_logger::init_once(
39 android_logger::Config::default().with_tag("rialto").with_min_level(log::Level::Debug),
40 );
41
42 // Redirect panic messages to logcat.
43 panic::set_hook(Box::new(|panic_info| {
44 log::error!("{}", panic_info);
45 }));
46
47 // We need to start the thread pool for Binder to work properly, especially link_to_death.
48 ProcessState::start_thread_pool();
49
50 let service = vmclient::connect().context("Failed to find VirtualizationService")?;
51 let rialto = File::open(RIALTO_PATH).context("Failed to open Rialto kernel binary")?;
52 let console = android_log_fd()?;
53 let log = android_log_fd()?;
54
55 let config = VirtualMachineConfig::RawConfig(VirtualMachineRawConfig {
56 kernel: None,
57 initrd: None,
58 params: None,
59 bootloader: Some(ParcelFileDescriptor::new(rialto)),
60 disks: vec![],
61 protectedVm: false,
62 memoryMib: 300,
63 numCpus: 1,
64 cpuAffinity: None,
65 platformVersion: "~1.0".to_string(),
66 taskProfiles: vec![],
67 });
68 let vm = VmInstance::create(service.as_ref(), &config, Some(console), Some(log))
69 .context("Failed to create VM")?;
70
71 vm.start().context("Failed to start VM")?;
72
73 // Wait for VM to finish, and check that it shut down cleanly.
74 let death_reason = vm.wait_for_death();
75 assert_eq!(death_reason, DeathReason::Shutdown);
76
77 Ok(())
78}
79
80fn android_log_fd() -> io::Result<File> {
81 let (reader_fd, writer_fd) = nix::unistd::pipe()?;
82
83 // SAFETY: These are new FDs with no previous owner.
84 let reader = unsafe { File::from_raw_fd(reader_fd) };
85 let writer = unsafe { File::from_raw_fd(writer_fd) };
86
87 thread::spawn(|| {
88 for line in BufReader::new(reader).lines() {
89 info!("{}", line.unwrap());
90 }
91 });
92 Ok(writer)
93}