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

google / alioth / 17185532172

24 Aug 2025 06:54AM UTC coverage: 13.756% (-0.1%) from 13.887%
17185532172

Pull #277

github

web-flow
Merge 537ca0404 into 861f19073
Pull Request #277: feat: Unix domain socket based vsock device

118 of 562 new or added lines in 19 files covered. (21.0%)

4 existing lines in 4 files now uncovered.

1023 of 7437 relevant lines covered (13.76%)

17.37 hits per line

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

93.55
/alioth/src/virtio/queue/packed_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::collections::HashMap;
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::packed::{DescEvent, EventFlag, PackedQueue, WrappedIndex};
23
use crate::virtio::queue::tests::{GuestQueue, UsedDesc, VirtQueueGuest};
24
use crate::virtio::queue::{DescFlag, QueueReg, VirtQueue};
25
use crate::virtio::tests::{DATA_ADDR, QUEUE_SIZE, fixture_queues, fixture_ram_bus};
26

27
const WRAP_COUNTER: u16 = 1 << 15;
28

29
#[rstest]
30
#[case(3, 0, 1, 1)]
31
#[case(5, 4, 4, WRAP_COUNTER | 3)]
32
#[case(3, WRAP_COUNTER | 0, 1, WRAP_COUNTER | 1)]
33
#[case(5, WRAP_COUNTER | 4, 1, 0)]
34
fn index_wrapping_add(
35
    #[case] size: u16,
36
    #[case] index: u16,
37
    #[case] delta: u16,
38
    #[case] expected: u16,
39
) {
40
    assert_eq!(
41
        WrappedIndex(index).wrapping_add(delta, size),
42
        WrappedIndex(expected)
43
    );
44
}
45

46
#[rstest]
47
#[case(3, 1, 1, 0)]
48
#[case(5, WRAP_COUNTER | 3, 4, 4)]
49
#[case(3, WRAP_COUNTER | 1, 1, WRAP_COUNTER | 0)]
50
#[case(5, 0, 1, WRAP_COUNTER | 4)]
51
fn index_wrapping_sub(
52
    #[case] size: u16,
53
    #[case] index: u16,
54
    #[case] delta: u16,
55
    #[case] expected: u16,
56
) {
57
    assert_eq!(
58
        WrappedIndex(index).wrapping_sub(delta, size),
59
        WrappedIndex(expected)
60
    );
61
}
62

63
impl<'m> PackedQueue<'m> {
64
    fn flag_is_used(&self, flag: DescFlag, wrap_counter: bool) -> bool {
5✔
65
        flag.contains(DescFlag::AVAIL) == wrap_counter
9✔
66
            && flag.contains(DescFlag::USED) == wrap_counter
9✔
67
    }
68
}
69

70
impl<'m> VirtQueueGuest<'m> for PackedQueue<'m> {
71
    fn add_desc(
5✔
72
        &mut self,
73
        index: WrappedIndex,
74
        ids: &[u16],
75
        readable: &[(u64, u32)],
76
        writable: &[(u64, u32)],
77
    ) -> u16 {
78
        let writable_count = writable.len();
12✔
79
        let total_count = readable.len() + writable.len();
17✔
80
        let id = ids[0];
10✔
81
        for (i, (addr, len)) in readable.iter().chain(writable).rev().enumerate() {
33✔
NEW
82
            let index = index.wrapping_add((total_count - 1 - i) as u16, self.size);
2✔
UNCOV
83
            let mut flag = if index.wrap_counter() {
1✔
84
                DescFlag::AVAIL
7✔
85
            } else {
86
                DescFlag::USED
×
87
            };
88
            if i > 0 {
3✔
89
                flag |= DescFlag::NEXT;
3✔
90
            }
91
            if i < writable_count {
3✔
92
                flag |= DescFlag::WRITE;
3✔
93
            }
NEW
94
            let desc = unsafe { &mut *self.desc.offset(index.offset() as isize) };
3✔
NEW
95
            desc.addr = *addr;
1✔
NEW
96
            desc.len = *len;
1✔
NEW
97
            desc.id = id;
1✔
NEW
98
            desc.flag = flag.bits();
1✔
99
        }
100
        ids.len() as u16
4✔
101
    }
102

103
    fn get_used(
5✔
104
        &mut self,
105
        index: Self::Index,
106
        chains: &HashMap<u16, Vec<u16>>,
107
    ) -> Option<UsedDesc> {
108
        let desc = unsafe { &mut *self.desc.offset(index.offset() as isize) };
18✔
109
        let flag = DescFlag::from_bits_retain(desc.flag);
13✔
110
        if !self.flag_is_used(flag, index.wrap_counter()) {
17✔
NEW
111
            return None;
×
112
        }
113
        Some(UsedDesc {
5✔
114
            id: desc.id,
9✔
115
            len: desc.len,
9✔
116
            delta: chains[&desc.id].len() as u16,
5✔
117
        })
118
    }
119
}
120

121
#[rstest]
122
fn disabled_queue(fixture_ram_bus: RamBus, fixture_queues: Box<[QueueReg]>) {
123
    let ram = fixture_ram_bus.lock_layout();
124
    let reg = &fixture_queues[0];
125
    reg.enabled.store(false, Ordering::Relaxed);
126
    let split_queue = PackedQueue::new(reg, &*ram, false);
127
    assert_matches!(split_queue, Ok(None));
128
}
129

130
#[rstest]
131
fn enabled_queue(fixture_ram_bus: RamBus, fixture_queues: Box<[QueueReg]>) {
132
    let ram = fixture_ram_bus.lock_layout();
133
    let reg = &fixture_queues[0];
134
    let q = PackedQueue::new(reg, &*ram, false).unwrap().unwrap();
135
    let mut guest_q = GuestQueue::new(PackedQueue::new(reg, &*ram, false).unwrap().unwrap(), reg);
136

137
    let str_0 = "Hello, World!";
138
    let str_1 = "Goodbye, World!";
139
    let str_2 = "Bose-Einstein condensate";
140
    let addr_0 = DATA_ADDR;
141
    let addr_1 = addr_0 + str_0.len() as u64;
142
    let addr_2 = addr_1 + str_1.len() as u64;
143
    ram.write(addr_0, str_0.as_bytes()).unwrap();
144
    ram.write(addr_1, str_1.as_bytes()).unwrap();
145

146
    let mut avail_index = WrappedIndex::INIT;
147
    let mut used_index = WrappedIndex::INIT;
148

149
    let id = guest_q.add_desc(
150
        &[(addr_0, str_0.len() as u32), (addr_1, str_1.len() as u32)],
151
        &[],
152
    );
153
    assert!(q.desc_avail(avail_index));
154
    let chain = q.get_avail(avail_index, &ram).unwrap().unwrap();
155
    avail_index = q.index_add(avail_index, chain.delta);
156
    assert_eq!(chain.id, 0);
157
    assert_eq!(&*chain.readable[0], str_0.as_bytes());
158
    assert_eq!(&*chain.readable[1], str_1.as_bytes());
159
    assert_eq!(chain.writable.len(), 0);
160

161
    q.set_used(used_index, chain.id, 0);
162
    used_index = q.index_add(used_index, chain.delta);
163

164
    assert_eq!(avail_index, WrappedIndex(WRAP_COUNTER | 2));
165
    assert_matches!(q.get_avail(avail_index, &ram), Ok(None));
166
    let used = guest_q.get_used().unwrap();
167
    assert_eq!(used.id, id);
168
    assert_eq!(used.delta, 2);
169
    assert_eq!(used.len, 0);
170

171
    let id = guest_q.add_desc(&[], &[(addr_2, str_2.len() as u32)]);
172
    let mut chain = q.get_avail(avail_index, &ram).unwrap().unwrap();
173
    assert_eq!(chain.id, 2);
174
    assert_eq!(chain.readable.len(), 0);
175
    let buffer = chain.writable[0].as_mut();
176
    buffer.copy_from_slice(str_2.as_bytes());
177
    q.set_used(used_index, chain.id, str_2.len() as u32);
178

179
    let used = guest_q.get_used().unwrap();
180
    assert_eq!(used.id, id);
181
    assert_eq!(used.delta, 1);
182
    assert_eq!(used.len, str_2.len() as u32);
183

184
    let mut b = vec![0u8; str_2.len()];
185
    ram.read(addr_2, b.as_mut()).unwrap();
186
    assert_eq!(&b, str_2.as_bytes());
187
}
188

189
#[rstest]
190
fn enable_notification(fixture_ram_bus: RamBus, fixture_queues: Box<[QueueReg]>) {
191
    let ram = fixture_ram_bus.lock_layout();
192
    let reg = &fixture_queues[0];
193
    let q = PackedQueue::new(reg, &*ram, false).unwrap().unwrap();
194

195
    q.enable_notification(false);
196
    assert_eq!(unsafe { &*q.notification }.flag, EventFlag::DISABLE);
197
    q.enable_notification(true);
198
    assert_eq!(unsafe { &*q.notification }.flag, EventFlag::ENABLE);
199
}
200

201
#[rstest]
202
#[case(false, EventFlag::DISABLE, 0, 1, 1, false)]
203
#[case(false, EventFlag::ENABLE, 0, 1, 1, true)]
204
#[case(false, EventFlag::DESC, 0, 1, 1, false)]
205
#[case(true, EventFlag::ENABLE, 0, 1, 1, true)]
206
#[case(true, EventFlag::DISABLE, 0, 1, 1, false)]
207
#[case(true, EventFlag::DESC, 0, 2, 1, false)]
208
#[case(true, EventFlag::DESC, 0, 2, 2, true)]
209
#[case(true, EventFlag::DESC, 0, 2, 3, true)]
210
#[case(true, EventFlag::DESC, WRAP_COUNTER | 0, 2, 3, false)]
211
#[case(true, EventFlag::DESC, WRAP_COUNTER | (QUEUE_SIZE - 1), 2, 2, false)]
212
#[case(true, EventFlag::DESC, WRAP_COUNTER | (QUEUE_SIZE - 1), 2, 3, true)]
213
#[case(true, EventFlag::DESC, QUEUE_SIZE - 1, WRAP_COUNTER | 1, 1, false)]
214
#[case(true, EventFlag::DESC, QUEUE_SIZE - 1, WRAP_COUNTER | 1, 2, true)]
215
fn is_interrupt_enabled(
216
    fixture_ram_bus: RamBus,
217
    fixture_queues: Box<[QueueReg]>,
218
    #[case] enable_event_idx: bool,
219
    #[case] event_flag: EventFlag,
220
    #[case] event_index: u16,
221
    #[case] used_index: u16,
222
    #[case] delta: u16,
223
    #[case] expected: bool,
224
) {
225
    let ram = fixture_ram_bus.lock_layout();
226
    let reg = &fixture_queues[0];
227
    let q = PackedQueue::new(reg, &*ram, enable_event_idx)
228
        .unwrap()
229
        .unwrap();
230

231
    *unsafe { &mut *q.interrupt } = DescEvent {
232
        index: WrappedIndex(event_index),
233
        flag: event_flag,
234
    };
235

236
    assert_eq!(
237
        q.interrupt_enabled(WrappedIndex(used_index), delta),
238
        expected
239
    );
240
}
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