• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

google / alioth / 16871256879

11 Aug 2025 04:57AM UTC coverage: 10.366% (+1.6%) from 8.754%
16871256879

push

github

Lencerf
test(virtio): inject errors in queue handler tests

Signed-off-by: Changyuan Lyu <changyuanl@google.com>

30 of 56 new or added lines in 1 file covered. (53.57%)

26 existing lines in 5 files now uncovered.

710 of 6849 relevant lines covered (10.37%)

16.03 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

97.5
/alioth/src/virtio/queue/queue.rs
1
// Copyright 2024 Google LLC
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
//     https://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
pub mod split;
16
#[cfg(test)]
17
#[path = "queue_test.rs"]
18
mod tests;
19

20
use std::io::{ErrorKind, IoSlice, IoSliceMut, Read, Write};
21
use std::sync::atomic::{AtomicBool, AtomicU16, AtomicU64, Ordering, fence};
22

23
use crate::virtio::{IrqSender, Result};
24

25
pub const QUEUE_SIZE_MAX: u16 = 256;
26

27
#[derive(Debug, Default)]
28
pub struct Queue {
29
    pub size: AtomicU16,
30
    pub desc: AtomicU64,
31
    pub driver: AtomicU64,
32
    pub device: AtomicU64,
33
    pub enabled: AtomicBool,
34
}
35

36
#[derive(Debug)]
37
pub struct Descriptor<'m> {
38
    pub id: u16,
39
    pub readable: Vec<IoSlice<'m>>,
40
    pub writable: Vec<IoSliceMut<'m>>,
41
}
42

43
pub trait VirtQueue<'m> {
44
    fn reg(&self) -> &Queue;
45
    fn size(&self) -> u16;
46
    fn next_desc(&self) -> Option<Result<Descriptor<'m>>>;
47
    fn avail_index(&self) -> u16;
48
    fn get_descriptor(&self, index: u16) -> Result<Descriptor<'m>>;
49
    fn has_next_desc(&self) -> bool;
50
    fn push_used(&mut self, desc: Descriptor, len: usize) -> u16;
51
    fn enable_notification(&self, enabled: bool);
52
    fn interrupt_enabled(&self) -> bool;
53

54
    fn handle_desc(
30✔
55
        &mut self,
56
        q_index: u16,
57
        irq_sender: &impl IrqSender,
58
        mut op: impl FnMut(&mut Descriptor) -> Result<Option<usize>>,
59
    ) -> Result<()> {
60
        let mut send_irq = false;
58✔
61
        let mut ret = Ok(());
58✔
UNCOV
62
        'out: loop {
×
63
            if !self.has_next_desc() {
40✔
64
                break;
16✔
65
            }
66
            self.enable_notification(false);
42✔
67
            while let Some(desc) = self.next_desc() {
52✔
68
                let mut desc = desc?;
24✔
69
                match op(&mut desc) {
6✔
70
                    Err(e) => {
10✔
71
                        ret = Err(e);
18✔
72
                        self.enable_notification(true);
18✔
73
                        break 'out;
8✔
74
                    }
75
                    Ok(None) => break 'out,
4✔
76
                    Ok(Some(len)) => {
10✔
UNCOV
77
                        self.push_used(desc, len);
2✔
78
                        send_irq = send_irq || self.interrupt_enabled();
10✔
79
                    }
80
                }
81
            }
82
            self.enable_notification(true);
10✔
83
            fence(Ordering::SeqCst);
2✔
84
        }
85
        if send_irq {
30✔
86
            fence(Ordering::SeqCst);
18✔
87
            irq_sender.queue_irq(q_index)
26✔
88
        }
89
        ret
2✔
90
    }
91

92
    fn copy_from_reader(
15✔
93
        &mut self,
94
        q_index: u16,
95
        irq_sender: &impl IrqSender,
96
        mut reader: impl Read,
97
    ) -> Result<()> {
98
        self.handle_desc(q_index, irq_sender, |desc| {
68✔
99
            let ret = reader.read_vectored(&mut desc.writable);
41✔
100
            match ret {
6✔
101
                Ok(0) => Err(std::io::Error::from(ErrorKind::UnexpectedEof))?,
7✔
102
                Ok(len) => Ok(Some(len)),
9✔
103
                Err(e) if e.kind() == ErrorKind::WouldBlock => Ok(None),
13✔
104
                Err(e) => Err(e)?,
7✔
105
            }
106
        })
107
    }
108

109
    fn copy_to_writer(
15✔
110
        &mut self,
111
        q_index: u16,
112
        irq_sender: &impl IrqSender,
113
        mut writer: impl Write,
114
    ) -> Result<()> {
115
        self.handle_desc(q_index, irq_sender, |desc| {
68✔
116
            let ret = writer.write_vectored(&desc.readable);
41✔
117
            match ret {
6✔
118
                Ok(0) => Err(std::io::Error::from(ErrorKind::WriteZero))?,
7✔
119
                Ok(len) => Ok(Some(len)),
9✔
120
                Err(e) if e.kind() == ErrorKind::WouldBlock => Ok(None),
13✔
121
                Err(e) => Err(e)?,
7✔
122
            }
123
        })
124
    }
125
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc