• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2022 The ChromiumOS Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #[cfg(test)]
6 mod tests {
7     use std::fs::File;
8 
9     use cros_async::Executor;
10     use tempfile::tempfile;
11 
12     use crate::virtio::descriptor_utils::*;
13 
14     #[test]
region_reader_failing_io()15     fn region_reader_failing_io() {
16         let ex = Executor::new().unwrap();
17         ex.run_until(region_reader_failing_io_async(&ex)).unwrap();
18     }
region_reader_failing_io_async(ex: &Executor)19     async fn region_reader_failing_io_async(ex: &Executor) {
20         use DescriptorType::*;
21 
22         let memory_start_addr = GuestAddress(0x0);
23         let memory = GuestMemory::new(&[(memory_start_addr, 0x10000)]).unwrap();
24 
25         let chain = create_descriptor_chain(
26             &memory,
27             GuestAddress(0x0),
28             GuestAddress(0x100),
29             vec![(Readable, 256), (Readable, 256)],
30             0,
31         )
32         .expect("create_descriptor_chain failed");
33 
34         let mut reader = Reader::new(memory.clone(), chain).expect("failed to create Reader");
35 
36         // TODO(b/235104127): Potentially use tempfile for ro_file so that this
37         // test can run on Windows.
38         // Open a file in read-only mode so writes to it to trigger an I/O error.
39         let ro_file = File::open("/dev/zero").expect("failed to open /dev/zero");
40         let async_ro_file = disk::SingleFileDisk::new(ro_file, ex).expect("Failed to crate SFD");
41 
42         reader
43             .read_exact_to_at_fut(&async_ro_file, 512, 0)
44             .await
45             .expect_err("successfully read more bytes than SharedMemory size");
46 
47         // The write above should have failed entirely, so we end up not writing any bytes at all.
48         assert_eq!(reader.available_bytes(), 512);
49         assert_eq!(reader.bytes_read(), 0);
50     }
51 
52     #[test]
region_writer_failing_io()53     fn region_writer_failing_io() {
54         let ex = Executor::new().unwrap();
55         ex.run_until(region_writer_failing_io_async(&ex)).unwrap()
56     }
region_writer_failing_io_async(ex: &Executor)57     async fn region_writer_failing_io_async(ex: &Executor) {
58         use DescriptorType::*;
59 
60         let memory_start_addr = GuestAddress(0x0);
61         let memory = GuestMemory::new(&[(memory_start_addr, 0x10000)]).unwrap();
62 
63         let chain = create_descriptor_chain(
64             &memory,
65             GuestAddress(0x0),
66             GuestAddress(0x100),
67             vec![(Writable, 256), (Writable, 256)],
68             0,
69         )
70         .expect("create_descriptor_chain failed");
71 
72         let mut writer = Writer::new(memory.clone(), chain).expect("failed to create Writer");
73 
74         let file = tempfile().expect("failed to create temp file");
75 
76         file.set_len(384).unwrap();
77         let async_file = disk::SingleFileDisk::new(file, ex).expect("Failed to crate SFD");
78 
79         writer
80             .write_all_from_at_fut(&async_file, 512, 0)
81             .await
82             .expect_err("successfully wrote more bytes than in SharedMemory");
83 
84         assert_eq!(writer.available_bytes(), 128);
85         assert_eq!(writer.bytes_written(), 384);
86     }
87 }
88