blob: 07cfd547d6f7cf7963666e3313d433fc88b41b1b [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::{
Alice Wang9a8b39f2023-04-12 15:31:48 +000019 CpuTopology::CpuTopology, DiskImage::DiskImage, Partition::Partition,
Alice Wang17dc76e2023-09-06 09:43:52 +000020 VirtualMachineConfig::VirtualMachineConfig,
David Brazdil66fc1202022-07-04 21:48:45 +010021 VirtualMachineRawConfig::VirtualMachineRawConfig,
22 },
23 binder::{ParcelFileDescriptor, ProcessState},
24};
Alice Wang17dc76e2023-09-06 09:43:52 +000025use anyhow::{Context, Result};
David Brazdil66fc1202022-07-04 21:48:45 +010026use log::info;
Alice Wang1d9a5872023-09-06 14:32:36 +000027use service_vm_comm::{Request, Response, VmType};
Alice Wang17dc76e2023-09-06 09:43:52 +000028use service_vm_manager::ServiceVm;
David Brazdil66fc1202022-07-04 21:48:45 +010029use std::fs::File;
Alice Wang17dc76e2023-09-06 09:43:52 +000030use std::io::{self, BufRead, BufReader};
David Brazdil66fc1202022-07-04 21:48:45 +010031use std::os::unix::io::FromRawFd;
32use std::panic;
Alice Wang17dc76e2023-09-06 09:43:52 +000033use std::path::PathBuf;
David Brazdil66fc1202022-07-04 21:48:45 +010034use std::thread;
Alice Wang17dc76e2023-09-06 09:43:52 +000035use vmclient::VmInstance;
Alice Wang4e082c32023-07-11 07:41:50 +000036
Alice Wang9a8b39f2023-04-12 15:31:48 +000037const SIGNED_RIALTO_PATH: &str = "/data/local/tmp/rialto_test/arm64/rialto.bin";
38const UNSIGNED_RIALTO_PATH: &str = "/data/local/tmp/rialto_test/arm64/rialto_unsigned.bin";
39const INSTANCE_IMG_PATH: &str = "/data/local/tmp/rialto_test/arm64/instance.img";
David Brazdil66fc1202022-07-04 21:48:45 +010040
Alice Wange910b902023-09-07 10:35:12 +000041fn rialto_path(vm_type: VmType) -> &'static str {
42 match vm_type {
43 VmType::ProtectedVm => SIGNED_RIALTO_PATH,
44 VmType::NonProtectedVm => UNSIGNED_RIALTO_PATH,
45 }
Alice Wang9a8b39f2023-04-12 15:31:48 +000046}
47
48#[test]
Alice Wange910b902023-09-07 10:35:12 +000049fn process_requests_in_protected_vm() -> Result<()> {
50 let mut vm = start_service_vm(VmType::ProtectedVm)?;
51
52 check_processing_reverse_request(&mut vm)?;
53 Ok(())
Alice Wang9a8b39f2023-04-12 15:31:48 +000054}
55
Alice Wange910b902023-09-07 10:35:12 +000056#[test]
57fn process_requests_in_non_protected_vm() -> Result<()> {
58 let mut vm = start_service_vm(VmType::NonProtectedVm)?;
59
60 check_processing_reverse_request(&mut vm)?;
61 Ok(())
62}
63
64fn check_processing_reverse_request(vm: &mut ServiceVm) -> Result<()> {
65 // TODO(b/292080257): Test with message longer than the receiver's buffer capacity
66 // 1024 bytes once the guest virtio-vsock driver fixes the credit update in recv().
67 let message = "abc".repeat(166);
68 let request = Request::Reverse(message.as_bytes().to_vec());
69
70 let response = vm.process_request(&request)?;
71 info!("Received response '{response:?}' for the request '{request:?}'.");
72
73 let expected_response: Vec<u8> = message.as_bytes().iter().rev().cloned().collect();
74 assert_eq!(Response::Reverse(expected_response), response);
75 Ok(())
76}
77
78fn start_service_vm(vm_type: VmType) -> Result<ServiceVm> {
David Brazdil66fc1202022-07-04 21:48:45 +010079 android_logger::init_once(
80 android_logger::Config::default().with_tag("rialto").with_min_level(log::Level::Debug),
81 );
David Brazdil66fc1202022-07-04 21:48:45 +010082 // Redirect panic messages to logcat.
83 panic::set_hook(Box::new(|panic_info| {
84 log::error!("{}", panic_info);
85 }));
David Brazdil66fc1202022-07-04 21:48:45 +010086 // We need to start the thread pool for Binder to work properly, especially link_to_death.
87 ProcessState::start_thread_pool();
Alice Wange910b902023-09-07 10:35:12 +000088 ServiceVm::start_vm(vm_instance(vm_type)?, vm_type)
Alice Wang17dc76e2023-09-06 09:43:52 +000089}
90
Alice Wange910b902023-09-07 10:35:12 +000091fn vm_instance(vm_type: VmType) -> Result<VmInstance> {
David Brazdil4b4c5102022-12-19 22:56:20 +000092 let virtmgr =
93 vmclient::VirtualizationService::new().context("Failed to spawn VirtualizationService")?;
94 let service = virtmgr.connect().context("Failed to connect to VirtualizationService")?;
95
Alice Wange910b902023-09-07 10:35:12 +000096 let rialto = File::open(rialto_path(vm_type)).context("Failed to open Rialto kernel binary")?;
David Brazdil66fc1202022-07-04 21:48:45 +010097 let console = android_log_fd()?;
98 let log = android_log_fd()?;
99
Alice Wang1d9a5872023-09-06 14:32:36 +0000100 let disks = match vm_type {
101 VmType::ProtectedVm => {
Alice Wang17dc76e2023-09-06 09:43:52 +0000102 let instance_img = service_vm_manager::instance_img(
103 service.as_ref(),
104 PathBuf::from(INSTANCE_IMG_PATH),
105 )?;
Alice Wang1d9a5872023-09-06 14:32:36 +0000106 let writable_partitions = vec![Partition {
107 label: "vm-instance".to_owned(),
108 image: Some(instance_img),
109 writable: true,
110 }];
111 vec![DiskImage { image: None, partitions: writable_partitions, writable: true }]
112 }
113 VmType::NonProtectedVm => vec![],
Alice Wang9a8b39f2023-04-12 15:31:48 +0000114 };
David Brazdil66fc1202022-07-04 21:48:45 +0100115 let config = VirtualMachineConfig::RawConfig(VirtualMachineRawConfig {
Seungjae Yoo62085c02022-08-12 04:44:52 +0000116 name: String::from("RialtoTest"),
David Brazdil66fc1202022-07-04 21:48:45 +0100117 kernel: None,
118 initrd: None,
119 params: None,
120 bootloader: Some(ParcelFileDescriptor::new(rialto)),
Alice Wang9a8b39f2023-04-12 15:31:48 +0000121 disks,
Alice Wang1d9a5872023-09-06 14:32:36 +0000122 protectedVm: vm_type.is_protected(),
David Brazdil66fc1202022-07-04 21:48:45 +0100123 memoryMib: 300,
David Brazdil7d1e5ec2023-02-06 17:56:29 +0000124 cpuTopology: CpuTopology::ONE_CPU,
David Brazdil66fc1202022-07-04 21:48:45 +0100125 platformVersion: "~1.0".to_string(),
Nikita Ioffe5776f082023-02-10 21:38:26 +0000126 gdbPort: 0, // No gdb
Inseob Kim6ef80972023-07-20 17:23:36 +0900127 ..Default::default()
David Brazdil66fc1202022-07-04 21:48:45 +0100128 });
Alice Wang17dc76e2023-09-06 09:43:52 +0000129 VmInstance::create(
Jiyong Parke6fb1672023-06-26 16:45:55 +0900130 service.as_ref(),
131 &config,
132 Some(console),
133 /* consoleIn */ None,
134 Some(log),
135 None,
136 )
Alice Wang17dc76e2023-09-06 09:43:52 +0000137 .context("Failed to create VM")
David Brazdil66fc1202022-07-04 21:48:45 +0100138}
139
140fn android_log_fd() -> io::Result<File> {
141 let (reader_fd, writer_fd) = nix::unistd::pipe()?;
142
143 // SAFETY: These are new FDs with no previous owner.
144 let reader = unsafe { File::from_raw_fd(reader_fd) };
Andrew Walbranae3350d2023-07-21 19:01:18 +0100145 // SAFETY: These are new FDs with no previous owner.
David Brazdil66fc1202022-07-04 21:48:45 +0100146 let writer = unsafe { File::from_raw_fd(writer_fd) };
147
148 thread::spawn(|| {
149 for line in BufReader::new(reader).lines() {
150 info!("{}", line.unwrap());
151 }
152 });
153 Ok(writer)
154}