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

google / alioth / 17185259678

24 Aug 2025 06:24AM UTC coverage: 13.868% (-0.02%) from 13.887%
17185259678

Pull #277

github

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

62 of 101 new or added lines in 9 files covered. (61.39%)

72 existing lines in 5 files now uncovered.

972 of 7009 relevant lines covered (13.87%)

17.77 hits per line

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

94.12
/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::sync::atomic::Ordering;
16

17
use assert_matches::assert_matches;
18
use rstest::rstest;
19

20
use crate::mem::mapped::RamBus;
21
use crate::virtio::queue::packed::{DescEvent, EventFlag, PackedQueue, WrappedIndex};
22
use crate::virtio::queue::tests::VirtQueueGuest;
23
use crate::virtio::queue::{DescFlag, QueueReg, VirtQueue};
24
use crate::virtio::tests::{DATA_ADDR, QUEUE_SIZE, fixture_queue, fixture_ram_bus};
25

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

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

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

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

94
#[rstest]
95
fn disabled_queue(fixture_ram_bus: RamBus, fixture_queue: QueueReg) {
96
    let ram = fixture_ram_bus.lock_layout();
97
    fixture_queue.enabled.store(false, Ordering::Relaxed);
98
    let split_queue = PackedQueue::new(&fixture_queue, &*ram, false);
99
    assert_matches!(split_queue, Ok(None));
100
}
101

102
#[rstest]
103
fn enabled_queue(fixture_ram_bus: RamBus, fixture_queue: QueueReg) {
104
    let ram = fixture_ram_bus.lock_layout();
105
    let mut q = PackedQueue::new(&fixture_queue, &*ram, false)
106
        .unwrap()
107
        .unwrap();
108

109
    let str_0 = "Hello, World!";
110
    let str_1 = "Goodbye, World!";
111
    let str_2 = "Bose-Einstein condensate";
112
    let addr_0 = DATA_ADDR;
113
    let addr_1 = addr_0 + str_0.len() as u64;
114
    let addr_2 = addr_1 + str_1.len() as u64;
115
    ram.write(addr_0, str_0.as_bytes()).unwrap();
116
    ram.write(addr_1, str_1.as_bytes()).unwrap();
117

118
    let mut avail_index = WrappedIndex::INIT;
119
    let mut used_index = WrappedIndex::INIT;
120
    q.add_desc(
121
        avail_index,
122
        0,
123
        &[(addr_0, str_0.len() as u32), (addr_1, str_1.len() as u32)],
124
        &[],
125
    );
126
    assert!(q.desc_avail(avail_index));
127

128
    let chain = q.get_avail(avail_index, &ram).unwrap().unwrap();
129
    avail_index = q.index_add(avail_index, chain.delta);
130
    assert_eq!(chain.id, 0);
131
    assert_eq!(&*chain.readable[0], str_0.as_bytes());
132
    assert_eq!(&*chain.readable[1], str_1.as_bytes());
133
    assert_eq!(chain.writable.len(), 0);
134
    q.set_used(used_index, chain.id, 0);
135
    used_index = q.index_add(used_index, chain.delta);
136

137
    assert_eq!(avail_index, WrappedIndex(WRAP_COUNTER | 2));
138
    assert_matches!(q.get_avail(avail_index, &ram), Ok(None));
139

140
    q.add_desc(avail_index, 1, &[], &[(addr_2, str_2.len() as u32)]);
141
    let mut chain = q.get_avail(avail_index, &ram).unwrap().unwrap();
142
    assert_eq!(chain.id, 1);
143
    assert_eq!(chain.readable.len(), 0);
144
    let buffer = chain.writable[0].as_mut();
145
    buffer.copy_from_slice(str_2.as_bytes());
146
    q.set_used(used_index, chain.id, str_2.len() as u32);
147
    let mut b = vec![0u8; str_2.len()];
148
    ram.read(addr_2, b.as_mut()).unwrap();
149
    assert_eq!(&b, str_2.as_bytes());
150
}
151

152
#[rstest]
153
fn enable_notification(fixture_ram_bus: RamBus, fixture_queue: QueueReg) {
154
    let ram = fixture_ram_bus.lock_layout();
155
    let q = PackedQueue::new(&fixture_queue, &*ram, false)
156
        .unwrap()
157
        .unwrap();
158

159
    q.enable_notification(false);
160
    assert_eq!(unsafe { &*q.notification }.flag, EventFlag::DISABLE);
161
    q.enable_notification(true);
162
    assert_eq!(unsafe { &*q.notification }.flag, EventFlag::ENABLE);
163
}
164

165
#[rstest]
166
#[case(false, EventFlag::DISABLE, 0, 1, 1, false)]
167
#[case(false, EventFlag::ENABLE, 0, 1, 1, true)]
168
#[case(false, EventFlag::DESC, 0, 1, 1, false)]
169
#[case(true, EventFlag::ENABLE, 0, 1, 1, true)]
170
#[case(true, EventFlag::DISABLE, 0, 1, 1, false)]
171
#[case(true, EventFlag::DESC, 0, 2, 1, false)]
172
#[case(true, EventFlag::DESC, 0, 2, 2, true)]
173
#[case(true, EventFlag::DESC, 0, 2, 3, true)]
174
#[case(true, EventFlag::DESC, WRAP_COUNTER | 0, 2, 3, false)]
175
#[case(true, EventFlag::DESC, WRAP_COUNTER | (QUEUE_SIZE - 1), 2, 2, false)]
176
#[case(true, EventFlag::DESC, WRAP_COUNTER | (QUEUE_SIZE - 1), 2, 3, true)]
177
#[case(true, EventFlag::DESC, QUEUE_SIZE - 1, WRAP_COUNTER | 1, 1, false)]
178
#[case(true, EventFlag::DESC, QUEUE_SIZE - 1, WRAP_COUNTER | 1, 2, true)]
179
fn is_interrupt_enabled(
180
    fixture_ram_bus: RamBus,
181
    fixture_queue: QueueReg,
182
    #[case] enable_event_idx: bool,
183
    #[case] event_flag: EventFlag,
184
    #[case] event_index: u16,
185
    #[case] used_index: u16,
186
    #[case] delta: u16,
187
    #[case] expected: bool,
188
) {
189
    let ram = fixture_ram_bus.lock_layout();
190
    let q = PackedQueue::new(&fixture_queue, &*ram, enable_event_idx)
191
        .unwrap()
192
        .unwrap();
193

194
    *unsafe { &mut *q.interrupt } = DescEvent {
195
        index: WrappedIndex(event_index),
196
        flag: event_flag,
197
    };
198

199
    assert_eq!(
200
        q.interrupt_enabled(WrappedIndex(used_index), delta),
201
        expected
202
    );
203
}
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