backup_tests.rs (4411B)
1 use super::*; 2 use radroots_storage::backup::{BackupFormatVersion, BackupSecretPolicy}; 3 4 fn plan() -> BackupPlan { 5 BackupPlan::new( 6 BackupId::new([6; 16]).unwrap(), 7 BackupFormatVersion::V1, 8 BackupSecretPolicy::IncludeProtectedStorage, 9 100, 10 ) 11 .unwrap() 12 } 13 14 #[cfg(feature = "memory")] 15 #[tokio::test] 16 async fn reliability_metadata_never_substitutes_for_actual_backup_capability() { 17 use radroots_storage::backup::{BackupMember, BackupMemberKind, MemberDigest}; 18 let client = crate::ClientBuilder::memory_default().build().unwrap(); 19 let operations = client.storage_operations().unwrap(); 20 assert_eq!( 21 operations.settle_backup_writes().await, 22 Err(BackupCapabilityError::Unsupported) 23 ); 24 let plan = plan(); 25 operations.begin_backup(plan.clone()).await.unwrap(); 26 let manifest = BackupManifest::new( 27 plan.format_version(), 28 plan.backup_id(), 29 plan.requested_at_unix_ms(), 30 plan.secret_policy(), 31 vec![ 32 BackupMember::new( 33 "runtime/events.bin", 34 BackupMemberKind::Runtime, 35 1, 36 MemberDigest::new([8; 32]), 37 ) 38 .unwrap(), 39 ], 40 ) 41 .unwrap(); 42 assert_eq!( 43 operations.capture_backup(plan.clone()).await, 44 Err(BackupCapabilityError::Unsupported) 45 ); 46 assert_eq!( 47 operations 48 .verify_backup(plan.clone(), manifest.clone()) 49 .await, 50 Err(BackupCapabilityError::Unsupported) 51 ); 52 assert_eq!( 53 operations.finalize_backup(plan, manifest).await, 54 Err(BackupCapabilityError::Unsupported) 55 ); 56 client.close().await.unwrap(); 57 } 58 59 #[cfg(feature = "sqlite")] 60 #[tokio::test] 61 async fn sdk_delegates_real_backup_and_close_to_one_canonical_owner() { 62 use radroots_storage::{ 63 authored_draft::{AuthoredDraft, AuthoredDraftId, AuthoredDraftStage}, 64 event::SourceGeneration, 65 }; 66 let root = tempfile::tempdir().unwrap(); 67 let backup = tempfile::tempdir().unwrap(); 68 let options = SqliteOptions::new( 69 SqlitePaths::from_directory(root.path()).unwrap(), 70 SqliteOpenMode::Create, 71 ) 72 .with_source_generation(SourceGeneration::new([9; 32]).unwrap(), 100) 73 .unwrap() 74 .with_backup_root(backup.path()) 75 .unwrap(); 76 let client = crate::ClientBuilder::sqlite(options) 77 .await 78 .unwrap() 79 .build() 80 .unwrap(); 81 let draft = AuthoredDraft::initial( 82 AuthoredDraftId::new([7; 16]).unwrap(), 83 [3; 32], 84 "fixture.backup.v1", 85 b"retained authored work".to_vec(), 86 AuthoredDraftStage::Draft, 87 None, 88 100, 89 ) 90 .unwrap(); 91 client 92 .storage() 93 .unwrap() 94 .append_authored_draft(draft.clone(), None) 95 .await 96 .unwrap(); 97 let operations = client.storage_operations().unwrap(); 98 let plan = plan(); 99 drop(operations.capture_backup(plan.clone())); 100 operations.settle_backup_writes().await.unwrap(); 101 assert_eq!(std::fs::read_dir(backup.path()).unwrap().count(), 0); 102 let manifest = operations.capture_backup(plan.clone()).await.unwrap(); 103 assert_eq!(manifest.backup_id(), plan.backup_id()); 104 assert_eq!(manifest.members().len(), 2); 105 assert!( 106 manifest 107 .members() 108 .iter() 109 .all(|member| member.byte_length() > 0) 110 ); 111 operations 112 .verify_backup(plan.clone(), manifest.clone()) 113 .await 114 .unwrap(); 115 for _ in 0..2 { 116 operations 117 .finalize_backup(plan.clone(), manifest.clone()) 118 .await 119 .unwrap(); 120 } 121 assert_eq!(std::fs::read_dir(backup.path()).unwrap().count(), 1); 122 assert_eq!( 123 client 124 .storage() 125 .unwrap() 126 .authored_draft_head(draft.draft_id()) 127 .await 128 .unwrap(), 129 Some(draft) 130 ); 131 client.close().await.unwrap(); 132 assert_eq!( 133 operations.capture_backup(plan.clone()).await, 134 Err(BackupCapabilityError::Unavailable) 135 ); 136 assert_eq!( 137 operations 138 .verify_backup(plan.clone(), manifest.clone()) 139 .await, 140 Err(BackupCapabilityError::Unavailable) 141 ); 142 assert_eq!( 143 operations.finalize_backup(plan, manifest).await, 144 Err(BackupCapabilityError::Unavailable) 145 ); 146 }