Skip to content

Commit 10306e5

Browse files
committed
tests: switch to QueueT
Make all accesses to the underlying QueueState go through the with() function. The function which will take care of locking when testing QueueSync. Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
1 parent 273b933 commit 10306e5

File tree

1 file changed

+108
-98
lines changed

1 file changed

+108
-98
lines changed

crates/virtio-queue/src/lib.rs

Lines changed: 108 additions & 98 deletions
Original file line numberDiff line numberDiff line change
@@ -1033,6 +1033,7 @@ impl<M: GuestAddressSpace> Queue<M> {
10331033
#[cfg(test)]
10341034
mod tests {
10351035
use super::*;
1036+
use generic::QueueT;
10361037
use memoffset::offset_of;
10371038
use mock::{DescriptorTable, MockSplitQueue};
10381039

@@ -1195,96 +1196,98 @@ mod tests {
11951196
assert!(q.is_valid());
11961197

11971198
// shouldn't be valid when not marked as ready
1198-
q.state.ready = false;
1199+
q.with(|mut qstate| qstate.ready = false);
11991200
assert!(!q.is_valid());
1200-
q.state.ready = true;
1201+
q.with(|mut qstate| qstate.ready = true);
1202+
1203+
let max_size = q.with(|qstate| qstate.max_size);
12011204

12021205
// shouldn't be allowed to set a size > max_size
1203-
q.set_size(q.state.max_size << 1);
1204-
assert_eq!(q.state.size, q.state.max_size);
1206+
q.with(|mut qstate| qstate.set_size(max_size << 1));
1207+
assert!(q.with(|qstate| qstate.size) == max_size);
12051208

12061209
// or set the size to 0
1207-
q.set_size(0);
1208-
assert_eq!(q.state.size, q.state.max_size);
1210+
q.with(|mut qstate| qstate.set_size(0));
1211+
assert!(q.with(|qstate| qstate.size) == max_size);
12091212

12101213
// or set a size which is not a power of 2
1211-
q.set_size(11);
1212-
assert_eq!(q.state.size, q.state.max_size);
1214+
q.with(|mut qstate| qstate.set_size(11));
1215+
assert!(q.with(|qstate| qstate.size) == max_size);
12131216

12141217
// but should be allowed to set a size if 0 < size <= max_size and size is a power of two
1215-
q.set_size(4);
1216-
assert_eq!(q.state.size, 4);
1217-
q.state.size = q.state.max_size;
1218+
q.with(|mut qstate| qstate.set_size(4));
1219+
q.with(|qstate| assert_eq!(qstate.size, 4));
1220+
q.with(|mut qstate| qstate.size = qstate.max_size);
12181221

12191222
// shouldn't be allowed to set an address that breaks the alignment constraint
1220-
q.set_desc_table_address(Some(0xf), None);
1221-
assert_eq!(q.state.desc_table.0, vq.desc_table_addr().0);
1223+
q.with(|mut qstate| qstate.set_desc_table_address(Some(0xf), None));
1224+
q.with(|qstate| assert_eq!(qstate.desc_table.0, vq.desc_table_addr().0));
12221225
// should be allowed to set an aligned out of bounds address
1223-
q.set_desc_table_address(Some(0xffff_fff0), None);
1224-
assert_eq!(q.state.desc_table.0, 0xffff_fff0);
1226+
q.with(|mut qstate| qstate.set_desc_table_address(Some(0xffff_fff0), None));
1227+
q.with(|qstate| assert_eq!(qstate.desc_table.0, 0xffff_fff0));
12251228
// but shouldn't be valid
12261229
assert!(!q.is_valid());
12271230
// but should be allowed to set a valid description table address
1228-
q.set_desc_table_address(Some(0x10), None);
1229-
assert_eq!(q.state.desc_table.0, 0x10);
1231+
q.with(|mut qstate| qstate.set_desc_table_address(Some(0x10), None));
1232+
q.with(|qstate| assert_eq!(qstate.desc_table.0, 0x10));
12301233
assert!(q.is_valid());
1231-
q.state.desc_table = vq.desc_table_addr();
1234+
q.with(|mut qstate| qstate.desc_table = vq.desc_table_addr());
12321235

12331236
// shouldn't be allowed to set an address that breaks the alignment constraint
1234-
q.set_avail_ring_address(Some(0x1), None);
1235-
assert_eq!(q.state.avail_ring.0, vq.avail_addr().0);
1237+
q.with(|mut qstate| qstate.set_avail_ring_address(Some(0x1), None));
1238+
q.with(|qstate| assert_eq!(qstate.avail_ring.0, vq.avail_addr().0));
12361239
// should be allowed to set an aligned out of bounds address
1237-
q.set_avail_ring_address(Some(0xffff_fffe), None);
1238-
assert_eq!(q.state.avail_ring.0, 0xffff_fffe);
1240+
q.with(|mut qstate| qstate.set_avail_ring_address(Some(0xffff_fffe), None));
1241+
q.with(|qstate| assert_eq!(qstate.avail_ring.0, 0xffff_fffe));
12391242
// but shouldn't be valid
12401243
assert!(!q.is_valid());
12411244
// but should be allowed to set a valid available ring address
1242-
q.set_avail_ring_address(Some(0x2), None);
1243-
assert_eq!(q.state.avail_ring.0, 0x2);
1245+
q.with(|mut qstate| qstate.set_avail_ring_address(Some(0x2), None));
1246+
q.with(|qstate| assert_eq!(qstate.avail_ring.0, 0x2));
12441247
assert!(q.is_valid());
1245-
q.state.avail_ring = vq.avail_addr();
1248+
q.with(|mut qstate| qstate.avail_ring = vq.avail_addr());
12461249

12471250
// shouldn't be allowed to set an address that breaks the alignment constraint
1248-
q.set_used_ring_address(Some(0x3), None);
1249-
assert_eq!(q.state.used_ring.0, vq.used_addr().0);
1251+
q.with(|mut qstate| qstate.set_used_ring_address(Some(0x3), None));
1252+
q.with(|qstate| assert_eq!(qstate.used_ring.0, vq.used_addr().0));
12501253
// should be allowed to set an aligned out of bounds address
1251-
q.set_used_ring_address(Some(0xffff_fffc), None);
1252-
assert_eq!(q.state.used_ring.0, 0xffff_fffc);
1254+
q.with(|mut qstate| qstate.set_used_ring_address(Some(0xffff_fffc), None));
1255+
q.with(|qstate| assert_eq!(qstate.used_ring.0, 0xffff_fffc));
12531256
// but shouldn't be valid
12541257
assert!(!q.is_valid());
12551258
// but should be allowed to set a valid used ring address
1256-
q.set_used_ring_address(Some(0x4), None);
1257-
assert_eq!(q.state.used_ring.0, 0x4);
1259+
q.with(|mut qstate| qstate.set_used_ring_address(Some(0x4), None));
1260+
q.with(|qstate| assert_eq!(qstate.used_ring.0, 0x4));
12581261
assert!(q.is_valid());
1259-
q.state.used_ring = vq.used_addr();
1262+
q.with(|mut qstate| qstate.used_ring = vq.used_addr());
12601263

1261-
{
1264+
q.with(|mut qstate| {
12621265
// an invalid queue should return an iterator with no next
1263-
q.state.ready = false;
1264-
let mut i = q.iter().unwrap();
1266+
qstate.ready = false;
1267+
let mut i = qstate.iter().unwrap();
12651268
assert!(i.next().is_none());
1266-
}
1269+
});
12671270

1268-
q.state.ready = true;
1271+
q.with(|mut qstate| qstate.ready = true);
12691272

12701273
// now let's create two simple descriptor chains
12711274
// the chains are (0, 1) and (2, 3, 4)
1272-
{
1273-
for j in 0..5u16 {
1274-
let flags = match j {
1275-
1 | 4 => 0,
1276-
_ => VIRTQ_DESC_F_NEXT,
1277-
};
1278-
1279-
let desc = Descriptor::new((0x1000 * (j + 1)) as u64, 0x1000, flags, j + 1);
1280-
vq.desc_table().store(j, desc);
1281-
}
1275+
for j in 0..5u16 {
1276+
let flags = match j {
1277+
1 | 4 => 0,
1278+
_ => VIRTQ_DESC_F_NEXT,
1279+
};
12821280

1283-
vq.avail().ring().ref_at(0).store(0);
1284-
vq.avail().ring().ref_at(1).store(2);
1285-
vq.avail().idx().store(2);
1281+
let desc = Descriptor::new((0x1000 * (j + 1)) as u64, 0x1000, flags, j + 1);
1282+
vq.desc_table().store(j, desc);
1283+
}
1284+
1285+
vq.avail().ring().ref_at(0).store(0);
1286+
vq.avail().ring().ref_at(1).store(2);
1287+
vq.avail().idx().store(2);
12861288

1287-
let mut i = q.iter().unwrap();
1289+
q.with(|mut qstate| {
1290+
let mut i = qstate.iter().unwrap();
12881291

12891292
{
12901293
let mut c = i.next().unwrap();
@@ -1311,13 +1314,13 @@ mod tests {
13111314
{
13121315
assert!(i.next().is_none());
13131316
i.go_to_previous_position();
1314-
let mut c = q.iter().unwrap().next().unwrap();
1317+
let mut c = qstate.iter().unwrap().next().unwrap();
13151318
c.next().unwrap();
13161319
c.next().unwrap();
13171320
c.next().unwrap();
13181321
assert!(c.next().is_none());
13191322
}
1320-
}
1323+
})
13211324
}
13221325

13231326
#[test]
@@ -1347,39 +1350,41 @@ mod tests {
13471350
vq.avail().ring().ref_at(2).store(5);
13481351
vq.avail().idx().store(3);
13491352

1350-
let mut i = q.iter().unwrap();
1353+
q.with(|mut qstate| {
1354+
let mut i = qstate.iter().unwrap();
13511355

1352-
{
1353-
let c = i.next().unwrap();
1354-
assert_eq!(c.head_index(), 0);
1355-
1356-
let mut iter = c;
1357-
assert!(iter.next().is_some());
1358-
assert!(iter.next().is_some());
1359-
assert!(iter.next().is_none());
1360-
assert!(iter.next().is_none());
1361-
}
1356+
{
1357+
let c = i.next().unwrap();
1358+
assert_eq!(c.head_index(), 0);
13621359

1363-
{
1364-
let c = i.next().unwrap();
1365-
assert_eq!(c.head_index(), 2);
1366-
1367-
let mut iter = c.writable();
1368-
assert!(iter.next().is_some());
1369-
assert!(iter.next().is_some());
1370-
assert!(iter.next().is_none());
1371-
assert!(iter.next().is_none());
1372-
}
1360+
let mut iter = c;
1361+
assert!(iter.next().is_some());
1362+
assert!(iter.next().is_some());
1363+
assert!(iter.next().is_none());
1364+
assert!(iter.next().is_none());
1365+
}
13731366

1374-
{
1375-
let c = i.next().unwrap();
1376-
assert_eq!(c.head_index(), 5);
1367+
{
1368+
let c = i.next().unwrap();
1369+
assert_eq!(c.head_index(), 2);
13771370

1378-
let mut iter = c.readable();
1379-
assert!(iter.next().is_some());
1380-
assert!(iter.next().is_none());
1381-
assert!(iter.next().is_none());
1382-
}
1371+
let mut iter = c.writable();
1372+
assert!(iter.next().is_some());
1373+
assert!(iter.next().is_some());
1374+
assert!(iter.next().is_none());
1375+
assert!(iter.next().is_none());
1376+
}
1377+
1378+
{
1379+
let c = i.next().unwrap();
1380+
assert_eq!(c.head_index(), 5);
1381+
1382+
let mut iter = c.readable();
1383+
assert!(iter.next().is_some());
1384+
assert!(iter.next().is_none());
1385+
assert!(iter.next().is_none());
1386+
}
1387+
})
13831388
}
13841389

13851390
#[test]
@@ -1397,7 +1402,7 @@ mod tests {
13971402

13981403
// should be ok
13991404
q.add_used(1, 0x1000).unwrap();
1400-
assert_eq!(q.state.next_used, Wrapping(1));
1405+
q.with(|qstate| assert_eq!(qstate.next_used, Wrapping(1)));
14011406
assert_eq!(vq.used().idx().load(), 1);
14021407

14031408
let x = vq.used().ring().ref_at(0).load();
@@ -1425,11 +1430,13 @@ mod tests {
14251430
let vq = MockSplitQueue::new(m, 16);
14261431

14271432
let mut q: Queue<_> = vq.as_queue(m);
1428-
q.state.size = 8;
1429-
q.state.ready = true;
1430-
q.state.reset();
1431-
assert_eq!(q.state.size, 16);
1432-
assert_eq!(q.state.ready, false);
1433+
q.with(|mut qstate| {
1434+
qstate.size = 8;
1435+
qstate.ready = true;
1436+
qstate.reset();
1437+
assert_eq!(qstate.size, 16);
1438+
assert_eq!(qstate.ready, false);
1439+
})
14331440
}
14341441

14351442
#[test]
@@ -1443,21 +1450,24 @@ mod tests {
14431450

14441451
// It should always return true when EVENT_IDX isn't enabled.
14451452
for i in 0..qsize {
1446-
q.state.next_used = Wrapping(i);
1453+
q.with(|mut qstate| qstate.next_used = Wrapping(i));
14471454
assert_eq!(q.needs_notification().unwrap(), true);
14481455
}
14491456

14501457
m.write_obj::<u16>(4, avail_addr.unchecked_add(4 + qsize as u64 * 2))
14511458
.unwrap();
1452-
q.state.set_event_idx(true);
1459+
q.with(|mut qstate| qstate.set_event_idx(true));
14531460

14541461
// Incrementing up to this value causes an `u16` to wrap back to 0.
14551462
let wrap = u32::from(u16::MAX) + 1;
14561463

14571464
for i in 0..wrap + 12 {
1458-
q.state.next_used = Wrapping(i as u16);
1459-
// Let's test wrapping around the maximum index value as well.
1460-
let expected = i == 5 || i == (5 + wrap) || q.state.signalled_used.is_none();
1465+
let expected = q.with(|mut qstate| {
1466+
qstate.next_used = Wrapping(i as u16);
1467+
// Let's test wrapping around the maximum index value as well.
1468+
i == 5 || i == (5 + wrap) || qstate.signalled_used.is_none()
1469+
});
1470+
14611471
assert_eq!(q.needs_notification().unwrap(), expected);
14621472
}
14631473

@@ -1471,9 +1481,9 @@ mod tests {
14711481
.unwrap();
14721482

14731483
assert_eq!(q.needs_notification().unwrap(), false);
1474-
q.state.next_used = Wrapping(15);
1484+
q.with(|mut qstate| qstate.next_used = Wrapping(15));
14751485
assert_eq!(q.needs_notification().unwrap(), false);
1476-
q.state.next_used = Wrapping(0);
1486+
q.with(|mut qstate| qstate.next_used = Wrapping(0));
14771487
assert_eq!(q.needs_notification().unwrap(), true);
14781488
assert_eq!(q.needs_notification().unwrap(), false);
14791489
}
@@ -1486,7 +1496,7 @@ mod tests {
14861496
let mut q: Queue<_> = vq.as_queue(m);
14871497
let used_addr = vq.used_addr();
14881498

1489-
assert_eq!(q.state.event_idx_enabled, false);
1499+
q.with(|qstate| assert_eq!(qstate.event_idx_enabled, false));
14901500

14911501
q.enable_notification().unwrap();
14921502
let v = m.read_obj::<u16>(used_addr).unwrap();
@@ -1505,13 +1515,13 @@ mod tests {
15051515
m.write_obj::<u16>(2, avail_addr.unchecked_add(2)).unwrap();
15061516

15071517
assert_eq!(q.enable_notification().unwrap(), true);
1508-
q.state.next_avail = Wrapping(2);
1518+
q.with(|mut qstate| qstate.next_avail = Wrapping(2));
15091519
assert_eq!(q.enable_notification().unwrap(), false);
15101520

15111521
m.write_obj::<u16>(8, avail_addr.unchecked_add(2)).unwrap();
15121522

15131523
assert_eq!(q.enable_notification().unwrap(), true);
1514-
q.state.next_avail = Wrapping(8);
1524+
q.with(|mut qstate| qstate.next_avail = Wrapping(8));
15151525
assert_eq!(q.enable_notification().unwrap(), false);
15161526
}
15171527
}

0 commit comments

Comments
 (0)