whiskers.git / crates / whiskers-store / tests / speech_cache.rs

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}