tests.rs (5345B)
1 use super::*; 2 3 fn generation() -> ProjectionGeneration { 4 ProjectionGeneration::new([1; 32]).unwrap() 5 } 6 fn query(limit: u16) -> ProjectionDocumentQuery { 7 ProjectionDocumentQuery::new( 8 ProjectionId::parse("fixture").unwrap(), 9 ProjectionDocumentGenerations::All, 10 limit, 11 ) 12 .unwrap() 13 } 14 fn record(key: &str, size: usize) -> ProjectionDocumentRecord { 15 ProjectionDocumentRecord::new( 16 generation(), 17 ProjectionDocument::new(key.into(), vec![123; size]).unwrap(), 18 ) 19 .unwrap() 20 } 21 22 #[test] 23 fn independent_scope_and_bounded_page_construction() { 24 let q = query(2); 25 for limit in [0, 257] { 26 assert!( 27 ProjectionDocumentQuery::new(q.projection_id().clone(), q.generations(), limit) 28 .is_err() 29 ); 30 } 31 for key in ["", " bad", "bad\n", &"x".repeat(513)] { 32 assert!(ProjectionDocumentRecord::corrupt(generation(), key.into()).is_err()); 33 } 34 let corrupt = ProjectionDocumentRecord::corrupt(generation(), "b".into()).unwrap(); 35 let page = 36 ProjectionDocumentPage::new(&q, vec![record("a", 1), corrupt.clone()], true).unwrap(); 37 let cursor = page.next_cursor().unwrap(); 38 assert!(corrupt.document().is_none()); 39 assert_eq!(corrupt.generation(), generation()); 40 assert_eq!(corrupt.key(), "b"); 41 assert_eq!(page.clone().into_records(), page.records()); 42 assert!(!format!("{:?}", record("redacted", 100)).contains("123")); 43 assert_eq!( 44 q.clone().with_cursor(cursor).unwrap().after(), 45 Some((generation(), "b")) 46 ); 47 for changed in [ 48 ProjectionDocumentQuery::new(ProjectionId::parse("other").unwrap(), q.generations(), 1) 49 .unwrap(), 50 ProjectionDocumentQuery::new( 51 q.projection_id().clone(), 52 ProjectionDocumentGenerations::Exact(generation()), 53 1, 54 ) 55 .unwrap(), 56 ] { 57 assert!(changed.with_cursor(cursor).is_err()); 58 } 59 assert!(ProjectionDocumentPage::new(&q, vec![], true).is_err()); 60 assert!(ProjectionDocumentPage::new(&q, vec![record("a", 1), record("a", 1)], false).is_err()); 61 assert!( 62 ProjectionDocumentPage::new(&query(1), vec![record("a", 1), record("b", 1)], false) 63 .is_err() 64 ); 65 let resumed = q.clone().with_cursor(cursor).unwrap(); 66 assert!(ProjectionDocumentPage::new(&resumed, vec![record("b", 1)], false).is_err()); 67 assert!( 68 ProjectionDocumentPage::new( 69 &q, 70 vec![ 71 record("a", PROJECTION_DOCUMENT_PAGE_BYTES_MAX), 72 record("b", 1) 73 ], 74 false 75 ) 76 .is_err() 77 ); 78 let exact = ProjectionDocumentQuery::new( 79 q.projection_id().clone(), 80 ProjectionDocumentGenerations::Exact(ProjectionGeneration::new([2; 32]).unwrap()), 81 2, 82 ) 83 .unwrap(); 84 assert!(ProjectionDocumentPage::new(&exact, vec![record("a", 1)], false).is_err()); 85 assert!( 86 ProjectionDocumentPage::new(&q, vec![], false) 87 .unwrap() 88 .next_cursor() 89 .is_none() 90 ); 91 } 92 93 #[cfg(feature = "serde")] 94 #[test] 95 fn unchecked_legacy_serde_values_cannot_enter_queries_or_records() { 96 let invalid_id: ProjectionId = serde_json::from_str("\"bad id\"").unwrap(); 97 let zero: ProjectionGeneration = 98 serde_json::from_str(&serde_json::to_string(&[0; 32]).unwrap()).unwrap(); 99 assert!( 100 ProjectionDocumentQuery::new(invalid_id, ProjectionDocumentGenerations::All, 1).is_err() 101 ); 102 assert!( 103 ProjectionDocumentQuery::new( 104 query(1).projection_id().clone(), 105 ProjectionDocumentGenerations::Exact(zero), 106 1 107 ) 108 .is_err() 109 ); 110 assert!(ProjectionDocumentRecord::corrupt(zero, "key".into()).is_err()); 111 assert!( 112 ProjectionDocumentRecord::new( 113 zero, 114 ProjectionDocument::new("key".into(), vec![1]).unwrap() 115 ) 116 .is_err() 117 ); 118 } 119 120 #[cfg(feature = "memory")] 121 #[test] 122 fn memory_inventory_continues_after_byte_exhaustion_and_reports_closed_store() { 123 use crate::{ProjectionStore, event::SourceGeneration, memory::MemoryStorage}; 124 futures_executor::block_on(async { 125 let store = MemoryStorage::new(SourceGeneration::new([1; 32]).unwrap()); 126 let q = query(256); 127 for (key, size) in [("a", PROJECTION_DOCUMENT_PAGE_BYTES_MAX), ("b", 1)] { 128 store 129 .put_projection_document( 130 q.projection_id().clone(), 131 generation(), 132 ProjectionDocument::new(key.into(), vec![1; size]).unwrap(), 133 ) 134 .await 135 .unwrap(); 136 } 137 let first = store.query_projection_documents(q.clone()).await.unwrap(); 138 assert_eq!(first.records().len(), 1); 139 let second = store 140 .query_projection_documents(q.with_cursor(first.next_cursor().unwrap()).unwrap()) 141 .await 142 .unwrap(); 143 assert_eq!(second.records()[0].key(), "b"); 144 assert!(second.next_cursor().is_none()); 145 crate::backup::StorageReliability::close(&store) 146 .await 147 .unwrap(); 148 assert_eq!( 149 store.query_projection_documents(query(1)).await, 150 Err(Error::BackendUnavailable) 151 ); 152 }); 153 }