What the speech cache keeps on disk: the audio and the spans, and not the words or the voice.
3mod fixtures;
5use fixtures::scratch; 6use whiskers_ports::{Audio, AudioMs, LineTiming, Millis, SpeechCache, SpeechLine, TimedAudio, VoiceId, run_ready}; 7use whiskers_store::{SqliteSpeechCache, Store}; 8 9#[test] 10fn the_database_holds_neither_the_words_nor_the_voice() { 11 let path = scratch("speech-words"); 12 let store = Store::open(&path).unwrap(); 13 let cache = SqliteSpeechCache::new(store.clone(), 1 << 20); 14 let text = "Hi Ada, this voice is called Quillfeather"; 15 let (voice, line) = (VoiceId::new("TheVoiceIdentifier123").unwrap(), SpeechLine::new(text.into()).unwrap()); 16 let spans = (0..line.chars()).map(|i| (AudioMs::new(i * 10), AudioMs::new(i * 10 + 10))).collect(); 17 let speech = TimedAudio::new(Audio(vec![9; 64]), LineTiming::new(text.into(), spans).unwrap(), &line).unwrap(); 18 run_ready(cache.keep(&voice, &line, &speech, Millis::new(1))).unwrap(); 19 assert!(run_ready(cache.find(&voice, &line, Millis::new(2))).unwrap().is_some()); 20 store.scrub().unwrap(); 21 drop(cache); 22 drop(store); 23 let mut bytes = std::fs::read(&path).unwrap(); 24 let mut wal = path.clone().into_os_string(); 25 wal.push("-wal"); 26 bytes.extend(std::fs::read(std::path::PathBuf::from(wal)).unwrap_or_default()); 27 for secret in ["Ada", "Quillfeather", "TheVoiceIdentifier123"] { 28 assert!(!bytes.windows(secret.len()).any(|w| w == secret.as_bytes()), "{secret} is in the database files"); 29 } 30} 31 32#[test] 33fn a_cache_over_a_database_from_before_it_existed_is_migrated_and_empty() { 34 let path = scratch("speech-migrate"); 35 drop(Store::open(&path).unwrap()); 36 let store = Store::open(&path).unwrap(); 37 let cache = SqliteSpeechCache::new(store, 1 << 20); 38 assert_eq!(run_ready(cache.size()).unwrap().entries, 0); 39}