Skip to content

Commit 7947ebd

Browse files
committed
disks: Add new mocking types for testing and iteration
We don't ever expose these in the real world. Signed-off-by: Ikey Doherty <[email protected]>
1 parent 837ee04 commit 7947ebd

File tree

4 files changed

+79
-9
lines changed

4 files changed

+79
-9
lines changed

crates/disks/src/disk.rs

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ use std::{
99
path::{Path, PathBuf},
1010
};
1111

12-
use crate::{mmc, nvme, partition::Partition, scsi, sysfs, virt, DEVFS_DIR};
12+
use crate::{mmc, mock, nvme, partition::Partition, scsi, sysfs, virt, DEVFS_DIR};
1313

1414
/// Represents the type of disk device.
1515
#[derive(Debug)]
@@ -22,6 +22,8 @@ pub enum Disk {
2222
Nvme(nvme::Disk),
2323
/// Virtual disk device
2424
Virtual(virt::Disk),
25+
/// Mock disk for testing
26+
Mock(mock::MockDisk),
2527
}
2628

2729
impl Deref for Disk {
@@ -34,26 +36,27 @@ impl Deref for Disk {
3436
Disk::Nvme(disk) => disk,
3537
Disk::Scsi(disk) => disk,
3638
Disk::Virtual(disk) => disk,
39+
Disk::Mock(disk) => disk,
3740
}
3841
}
3942
}
4043

4144
/// A basic disk representation containing common attributes shared by all disk types.
4245
/// This serves as the base structure that specific disk implementations build upon.
43-
#[derive(Debug)]
46+
#[derive(Debug, Default)]
4447
pub struct BasicDisk {
4548
/// Device name (e.g. sda, nvme0n1)
46-
name: String,
49+
pub(crate) name: String,
4750
/// Total number of sectors on the disk
48-
sectors: u64,
51+
pub(crate) sectors: u64,
4952
/// Path to the device in /dev
50-
device: PathBuf,
53+
pub(crate) device: PathBuf,
5154
/// Optional disk model name
52-
model: Option<String>,
55+
pub(crate) model: Option<String>,
5356
/// Optional disk vendor name
54-
vendor: Option<String>,
57+
pub(crate) vendor: Option<String>,
5558
/// Partitions
56-
partitions: Vec<Partition>,
59+
pub(crate) partitions: Vec<Partition>,
5760
}
5861

5962
impl fmt::Display for Disk {
@@ -93,6 +96,11 @@ impl BasicDisk {
9396
&self.partitions
9497
}
9598

99+
/// Helper for MockDisk to modify partitions
100+
pub(crate) fn partitions_mut(&mut self) -> &mut Vec<Partition> {
101+
&mut self.partitions
102+
}
103+
96104
/// Returns the path to the disk device in dev.
97105
pub fn device_path(&self) -> &Path {
98106
&self.device

crates/disks/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ use std::{
1111
pub use disk::*;
1212
pub mod loopback;
1313
pub mod mmc;
14+
pub mod mock;
1415
pub mod nvme;
1516
pub mod partition;
1617
pub mod scsi;

crates/disks/src/mock.rs

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
// SPDX-FileCopyrightText: Copyright © 2025 Serpent OS Developers
2+
//
3+
// SPDX-License-Identifier: MPL-2.0
4+
5+
//! Mock disk device for testing.
6+
//!
7+
//! This module provides a mock disk implementation that can be used for testing
8+
//! disk-related functionality without requiring actual hardware devices.
9+
10+
use std::{ops::Deref, path::PathBuf};
11+
12+
use crate::{partition::Partition, BasicDisk};
13+
14+
/// Represents a mock disk device.
15+
///
16+
/// This struct wraps a BasicDisk to provide mock functionality for testing.
17+
#[derive(Debug)]
18+
pub struct MockDisk(pub BasicDisk);
19+
20+
impl Deref for MockDisk {
21+
type Target = BasicDisk;
22+
23+
fn deref(&self) -> &Self::Target {
24+
&self.0
25+
}
26+
}
27+
28+
impl MockDisk {
29+
/// Creates a new mock disk with the specified size in bytes
30+
pub fn new(size_bytes: u64) -> Self {
31+
let sectors = size_bytes / 512;
32+
let disk = BasicDisk {
33+
name: "mock0".to_string(),
34+
sectors,
35+
device: PathBuf::from("/dev/mock0"),
36+
model: Some("Mock Device".to_string()),
37+
vendor: Some("Mock Vendor".to_string()),
38+
partitions: Vec::new(),
39+
};
40+
Self(disk)
41+
}
42+
43+
/// Add a partition to the mock disk at the specified byte offsets
44+
pub fn add_partition(&mut self, start_bytes: u64, end_bytes: u64) {
45+
let partition_number = self.0.partitions().len() + 1;
46+
let start = start_bytes / 512;
47+
let end = end_bytes / 512;
48+
49+
let partition = Partition {
50+
number: partition_number as u32,
51+
start,
52+
end,
53+
size: end - start,
54+
name: format!("mock0p{}", partition_number),
55+
node: PathBuf::from("/sys/class/block/mock0/mock0p1"),
56+
device: PathBuf::from(format!("/dev/mock0p{}", partition_number)),
57+
};
58+
59+
self.0.partitions_mut().push(partition);
60+
}
61+
}

crates/disks/src/partition.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ use crate::{sysfs, DEVFS_DIR, SYSFS_DIR};
99

1010
/// Represents a partition on a disk device
1111
/// - Size in sectors
12-
#[derive(Debug)]
12+
#[derive(Debug, Default)]
1313
pub struct Partition {
1414
/// Name of the partition
1515
pub name: String,

0 commit comments

Comments
 (0)