Add working test

This commit is contained in:
2025-09-09 22:42:16 +02:00
parent fa00747e80
commit e595fcbdac
4 changed files with 510 additions and 411 deletions

View File

@@ -5,9 +5,18 @@ use crate::utils::{error::*, models::*, DbPool};
use serde::Serialize;
use chrono::{DateTime, Utc};
// Basic snapshot info for listing
#[derive(Debug, Serialize)]
pub struct SnapshotInfo {
pub id: String, // Use UUID string instead of integer
pub struct SnapshotSummary {
pub id: String,
pub snapshot_hash: String,
pub created_at: String,
}
// Detailed snapshot info with disk/partition data
#[derive(Debug, Serialize)]
pub struct SnapshotDetails {
pub id: String,
pub snapshot_hash: String,
pub created_at: String,
pub disks: Vec<DiskInfo>,
@@ -35,7 +44,7 @@ impl SnapshotsController {
pool: &DbPool,
machine_id: i64,
user: &User,
) -> AppResult<Vec<SnapshotInfo>> {
) -> AppResult<Vec<SnapshotSummary>> {
// Verify machine access
let machine = sqlx::query!(
"SELECT id, user_id FROM machines WHERE id = ? AND user_id = ?",
@@ -53,7 +62,7 @@ impl SnapshotsController {
let _machine = machine.unwrap();
let storage = Storage::new("./data");
let mut snapshot_infos = Vec::new();
let mut snapshot_summaries = Vec::new();
// List all snapshots for this machine from storage
match storage.list_snapshots(machine_id).await {
@@ -61,71 +70,29 @@ impl SnapshotsController {
for snapshot_id in snapshot_ids {
// Load snapshot reference to get hash and timestamp
if let Ok(Some((snapshot_hash, created_at_timestamp))) = storage.load_snapshot_ref(machine_id, &snapshot_id).await {
// Load snapshot metadata
if let Ok(Some(snapshot_meta)) = storage.load_meta(MetaType::Snapshot, &snapshot_hash).await {
if let MetaObj::Snapshot(snapshot_obj) = snapshot_meta {
let mut disks = Vec::new();
let created_at = DateTime::from_timestamp(created_at_timestamp as i64, 0)
.unwrap_or_else(|| Utc::now())
.format("%Y-%m-%d %H:%M:%S UTC")
.to_string();
for disk_hash in snapshot_obj.disk_hashes {
if let Ok(Some(disk_meta)) = storage.load_meta(MetaType::Disk, &disk_hash).await {
if let MetaObj::Disk(disk_obj) = disk_meta {
let mut partitions = Vec::new();
for partition_hash in disk_obj.partition_hashes {
if let Ok(Some(partition_meta)) = storage.load_meta(MetaType::Partition, &partition_hash).await {
if let MetaObj::Partition(partition_obj) = partition_meta {
let fs_type_str = match partition_obj.fs_type_code {
FsType::Ext => "ext",
FsType::Ntfs => "ntfs",
FsType::Fat32 => "fat32",
FsType::Unknown => "unknown",
};
partitions.push(PartitionInfo {
fs_type: fs_type_str.to_string(),
start_lba: partition_obj.start_lba,
end_lba: partition_obj.end_lba,
size_bytes: (partition_obj.end_lba - partition_obj.start_lba) * 512,
});
}
}
}
disks.push(DiskInfo {
serial: disk_obj.serial,
size_bytes: disk_obj.disk_size_bytes,
partitions,
});
}
}
}
// Convert timestamp to readable format
let created_at_str = DateTime::<Utc>::from_timestamp(created_at_timestamp as i64, 0)
.map(|dt| dt.format("%Y-%m-%d %H:%M:%S").to_string())
.unwrap_or_else(|| "Unknown".to_string());
snapshot_infos.push(SnapshotInfo {
id: snapshot_id,
snapshot_hash: hex::encode(snapshot_hash),
created_at: created_at_str,
disks,
});
}
}
snapshot_summaries.push(SnapshotSummary {
id: snapshot_id,
snapshot_hash: hex::encode(snapshot_hash),
created_at,
});
}
}
}
},
Err(_) => {
// If no snapshots directory exists, return empty list
return Ok(Vec::new());
}
}
// Sort snapshots by creation time (newest first)
snapshot_infos.sort_by(|a, b| b.created_at.cmp(&a.created_at));
// Sort by creation time (newest first)
snapshot_summaries.sort_by(|a, b| b.created_at.cmp(&a.created_at));
Ok(snapshot_infos)
Ok(snapshot_summaries)
}
pub async fn get_snapshot_details(
@@ -133,7 +100,7 @@ impl SnapshotsController {
machine_id: i64,
snapshot_id: String,
user: &User,
) -> AppResult<SnapshotInfo> {
) -> AppResult<SnapshotDetails> {
// Verify machine access
let machine = sqlx::query!(
"SELECT id, user_id FROM machines WHERE id = ? AND user_id = ?",
@@ -204,7 +171,7 @@ impl SnapshotsController {
.map(|dt| dt.format("%Y-%m-%d %H:%M:%S").to_string())
.unwrap_or_else(|| "Unknown".to_string());
Ok(SnapshotInfo {
Ok(SnapshotDetails {
id: snapshot_id,
snapshot_hash: hex::encode(snapshot_hash),
created_at: created_at_str,

View File

@@ -1,12 +1,12 @@
use axum::{extract::{Path, State}, Json};
use crate::controllers::snapshots::{SnapshotsController, SnapshotInfo};
use crate::controllers::snapshots::{SnapshotsController, SnapshotSummary, SnapshotDetails};
use crate::utils::{auth::AuthUser, error::AppResult, DbPool};
pub async fn get_machine_snapshots(
State(pool): State<DbPool>,
Path(machine_id): Path<i64>,
auth_user: AuthUser,
) -> AppResult<Json<Vec<SnapshotInfo>>> {
) -> AppResult<Json<Vec<SnapshotSummary>>> {
let snapshots = SnapshotsController::get_machine_snapshots(
&pool,
machine_id,
@@ -20,7 +20,7 @@ pub async fn get_snapshot_details(
State(pool): State<DbPool>,
Path((machine_id, snapshot_id)): Path<(i64, String)>,
auth_user: AuthUser,
) -> AppResult<Json<SnapshotInfo>> {
) -> AppResult<Json<SnapshotDetails>> {
let snapshot = SnapshotsController::get_snapshot_details(
&pool,
machine_id,