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

google / alioth / 17119523075

21 Aug 2025 01:27AM UTC coverage: 11.963% (+1.6%) from 10.411%
17119523075

push

github

Lencerf
feat(virtio): support packed queue

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

91 of 132 new or added lines in 5 files covered. (68.94%)

155 existing lines in 8 files now uncovered.

838 of 7005 relevant lines covered (11.96%)

17.32 hits per line

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

100.0
/alioth/src/virtio/queue/split_test.rs
1
// Copyright 2025 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
use std::ptr::eq as ptr_eq;
16
use std::sync::atomic::Ordering;
17

18
use assert_matches::assert_matches;
19
use rstest::rstest;
20

21
use crate::mem::mapped::RamBus;
22
use crate::virtio::queue::private::VirtQueuePrivate;
23
use crate::virtio::queue::split::{Desc, DescFlag, SplitQueue};
24
use crate::virtio::queue::tests::{DATA_ADDR, fixture_queue, fixture_ram_bus};
25
use crate::virtio::queue::{Queue, QueueReg, VirtQueue};
26

27
impl<'r, 'm> SplitQueue<'r, 'm> {
28
    pub fn add_desc(&mut self, id: u16, readable: &[(u64, u32)], writable: &[(u64, u32)]) {
25✔
29
        let readable_count = readable.len();
73✔
30
        let total_count = readable.len() + writable.len();
97✔
31
        for (i, (addr, len)) in readable.iter().chain(writable.iter()).enumerate() {
179✔
UNCOV
32
            let mut flag = DescFlag::empty();
1✔
33
            if i < total_count - 1 {
10✔
34
                flag |= DescFlag::NEXT;
9✔
35
            }
36
            if i >= readable_count {
13✔
37
                flag |= DescFlag::WRITE;
13✔
38
            }
39
            let desc = Desc {
UNCOV
40
                addr: *addr,
1✔
41
                len: *len,
1✔
42
                flag: flag.bits(),
1✔
43
                next: id + i as u16 + 1,
2✔
44
            };
UNCOV
45
            *unsafe { &mut *self.desc.offset((id + i as u16) as isize) } = desc;
3✔
46
        }
47
        let avail_idx = self.avail_index();
73✔
48
        *unsafe { &mut *self.avail_ring.offset((avail_idx % self.size) as isize) } = id;
73✔
49
        unsafe { &mut *self.avail_hdr }.idx = avail_idx.wrapping_add(1);
50✔
50
    }
51
}
52

53
impl<'r, 'm> Queue<'m, SplitQueue<'r, 'm>> {
54
    pub fn add_desc(&mut self, id: u16, readable: &[(u64, u32)], writable: &[(u64, u32)]) {
21✔
55
        self.q.add_desc(id, readable, writable);
101✔
56
    }
57
}
58

59
#[rstest]
60
fn disabled_queue(fixture_ram_bus: RamBus, fixture_queue: QueueReg) {
61
    let ram = fixture_ram_bus.lock_layout();
62
    fixture_queue.enabled.store(false, Ordering::Relaxed);
63
    let split_queue = SplitQueue::new(&fixture_queue, &*ram, false);
64
    assert_matches!(split_queue, Ok(None));
65
}
66

67
#[rstest]
68
fn enabled_queue(fixture_ram_bus: RamBus, fixture_queue: QueueReg) {
69
    let ram = fixture_ram_bus.lock_layout();
70
    let mut q = SplitQueue::new(&fixture_queue, &*ram, false)
71
        .unwrap()
72
        .unwrap();
73
    assert!(ptr_eq(q.reg(), &fixture_queue));
74

75
    let str_0 = "Hello, World!";
76
    let str_1 = "Goodbye, World!";
77
    let str_2 = "Bose-Einstein condensate";
78
    let addr_0 = DATA_ADDR;
79
    let addr_1 = addr_0 + str_0.len() as u64;
80
    let addr_2 = addr_1 + str_1.len() as u64;
81
    ram.write(addr_0, str_0.as_bytes()).unwrap();
82
    ram.write(addr_1, str_1.as_bytes()).unwrap();
83

84
    q.add_desc(
85
        0,
86
        &[(addr_0, str_0.len() as u32), (addr_1, str_1.len() as u32)],
87
        &[],
88
    );
89

90
    assert_eq!(q.avail_index(), 1);
91
    assert!(q.desc_avail(0));
92
    let chain = q.get_desc_chain(0).unwrap().unwrap();
93
    assert_eq!(chain.id, 0);
94
    assert_eq!(&*chain.readable[0], str_0.as_bytes());
95
    assert_eq!(&*chain.readable[1], str_1.as_bytes());
96
    assert_eq!(chain.writable.len(), 0);
97
    q.push_used(chain, 0);
98
    assert!(!q.desc_avail(1));
99

100
    q.add_desc(2, &[], &[(addr_2, str_2.len() as u32)]);
101
    let mut chain = q.get_desc_chain(1).unwrap().unwrap();
102
    assert_eq!(chain.id, 2);
103
    assert_eq!(chain.readable.len(), 0);
104
    let buffer = chain.writable[0].as_mut();
105
    buffer.copy_from_slice(str_2.as_bytes());
106
    q.push_used(chain, str_2.len() as u32);
107
    let mut b = vec![0u8; str_2.len()];
108
    ram.read(addr_2, b.as_mut()).unwrap();
109
    assert_eq!(&b, str_2.as_bytes());
110
}
111

112
#[rstest]
113
fn event_idx_enabled(fixture_ram_bus: RamBus, fixture_queue: QueueReg) {
114
    let ram = fixture_ram_bus.lock_layout();
115
    let q = SplitQueue::new(&fixture_queue, &*ram, true)
116
        .unwrap()
117
        .unwrap();
118
    unsafe { *q.used_event.unwrap() = 1 };
119
    assert_eq!(q.used_event(), Some(1));
120

121
    assert!(q.set_avail_event(|event| *event = 12));
122
    assert_eq!(unsafe { *q.avail_event.unwrap() }, 12);
123
}
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