diff --git a/keystore2/src/database.rs b/keystore2/src/database.rs
index a9a1c4b..754dd9c 100644
--- a/keystore2/src/database.rs
+++ b/keystore2/src/database.rs
@@ -45,6 +45,9 @@
 pub(crate) mod utils;
 mod versioning;
 
+#[cfg(test)]
+pub mod tests;
+
 use crate::gc::Gc;
 use crate::impl_metadata; // This is in database/utils.rs
 use crate::key_parameter::{KeyParameter, KeyParameterValue, Tag};
@@ -2864,2620 +2867,3 @@
         Ok(app_uids_vec)
     }
 }
-
-#[cfg(test)]
-pub mod tests {
-
-    use super::*;
-    use crate::key_parameter::{
-        Algorithm, BlockMode, Digest, EcCurve, HardwareAuthenticatorType, KeyOrigin, KeyParameter,
-        KeyParameterValue, KeyPurpose, PaddingMode, SecurityLevel,
-    };
-    use crate::key_perm_set;
-    use crate::permission::{KeyPerm, KeyPermSet};
-    use crate::super_key::{SuperKeyManager, USER_AFTER_FIRST_UNLOCK_SUPER_KEY, SuperEncryptionAlgorithm, SuperKeyType};
-    use keystore2_test_utils::TempDir;
-    use android_hardware_security_keymint::aidl::android::hardware::security::keymint::{
-        HardwareAuthToken::HardwareAuthToken,
-        HardwareAuthenticatorType::HardwareAuthenticatorType as kmhw_authenticator_type,
-    };
-    use android_hardware_security_secureclock::aidl::android::hardware::security::secureclock::{
-        Timestamp::Timestamp,
-    };
-    use std::cell::RefCell;
-    use std::collections::BTreeMap;
-    use std::fmt::Write;
-    use std::sync::atomic::{AtomicU8, Ordering};
-    use std::sync::Arc;
-    use std::thread;
-    use std::time::{Duration, SystemTime};
-    use crate::utils::AesGcm;
-    #[cfg(disabled)]
-    use std::time::Instant;
-
-    pub fn new_test_db() -> Result<KeystoreDB> {
-        let conn = KeystoreDB::make_connection("file::memory:")?;
-
-        let mut db = KeystoreDB { conn, gc: None, perboot: Arc::new(perboot::PerbootDB::new()) };
-        db.with_transaction(Immediate("TX_new_test_db"), |tx| {
-            KeystoreDB::init_tables(tx).context("Failed to initialize tables.").no_gc()
-        })?;
-        Ok(db)
-    }
-
-    fn rebind_alias(
-        db: &mut KeystoreDB,
-        newid: &KeyIdGuard,
-        alias: &str,
-        domain: Domain,
-        namespace: i64,
-    ) -> Result<bool> {
-        db.with_transaction(Immediate("TX_rebind_alias"), |tx| {
-            KeystoreDB::rebind_alias(tx, newid, alias, &domain, &namespace, KeyType::Client).no_gc()
-        })
-        .context(ks_err!())
-    }
-
-    #[test]
-    fn datetime() -> Result<()> {
-        let conn = Connection::open_in_memory()?;
-        conn.execute("CREATE TABLE test (ts DATETIME);", [])?;
-        let now = SystemTime::now();
-        let duration = Duration::from_secs(1000);
-        let then = now.checked_sub(duration).unwrap();
-        let soon = now.checked_add(duration).unwrap();
-        conn.execute(
-            "INSERT INTO test (ts) VALUES (?), (?), (?);",
-            params![DateTime::try_from(now)?, DateTime::try_from(then)?, DateTime::try_from(soon)?],
-        )?;
-        let mut stmt = conn.prepare("SELECT ts FROM test ORDER BY ts ASC;")?;
-        let mut rows = stmt.query([])?;
-        assert_eq!(DateTime::try_from(then)?, rows.next()?.unwrap().get(0)?);
-        assert_eq!(DateTime::try_from(now)?, rows.next()?.unwrap().get(0)?);
-        assert_eq!(DateTime::try_from(soon)?, rows.next()?.unwrap().get(0)?);
-        assert!(rows.next()?.is_none());
-        assert!(DateTime::try_from(then)? < DateTime::try_from(now)?);
-        assert!(DateTime::try_from(then)? < DateTime::try_from(soon)?);
-        assert!(DateTime::try_from(now)? < DateTime::try_from(soon)?);
-        Ok(())
-    }
-
-    // Ensure that we're using the "injected" random function, not the real one.
-    #[test]
-    fn test_mocked_random() {
-        let rand1 = random();
-        let rand2 = random();
-        let rand3 = random();
-        if rand1 == rand2 {
-            assert_eq!(rand2 + 1, rand3);
-        } else {
-            assert_eq!(rand1 + 1, rand2);
-            assert_eq!(rand2, rand3);
-        }
-    }
-
-    // Test that we have the correct tables.
-    #[test]
-    fn test_tables() -> Result<()> {
-        let db = new_test_db()?;
-        let tables = db
-            .conn
-            .prepare("SELECT name from persistent.sqlite_master WHERE type='table' ORDER BY name;")?
-            .query_map(params![], |row| row.get(0))?
-            .collect::<rusqlite::Result<Vec<String>>>()?;
-        assert_eq!(tables.len(), 6);
-        assert_eq!(tables[0], "blobentry");
-        assert_eq!(tables[1], "blobmetadata");
-        assert_eq!(tables[2], "grant");
-        assert_eq!(tables[3], "keyentry");
-        assert_eq!(tables[4], "keymetadata");
-        assert_eq!(tables[5], "keyparameter");
-        Ok(())
-    }
-
-    #[test]
-    fn test_auth_token_table_invariant() -> Result<()> {
-        let mut db = new_test_db()?;
-        let auth_token1 = HardwareAuthToken {
-            challenge: i64::MAX,
-            userId: 200,
-            authenticatorId: 200,
-            authenticatorType: kmhw_authenticator_type(kmhw_authenticator_type::PASSWORD.0),
-            timestamp: Timestamp { milliSeconds: 500 },
-            mac: String::from("mac").into_bytes(),
-        };
-        db.insert_auth_token(&auth_token1);
-        let auth_tokens_returned = get_auth_tokens(&db);
-        assert_eq!(auth_tokens_returned.len(), 1);
-
-        // insert another auth token with the same values for the columns in the UNIQUE constraint
-        // of the auth token table and different value for timestamp
-        let auth_token2 = HardwareAuthToken {
-            challenge: i64::MAX,
-            userId: 200,
-            authenticatorId: 200,
-            authenticatorType: kmhw_authenticator_type(kmhw_authenticator_type::PASSWORD.0),
-            timestamp: Timestamp { milliSeconds: 600 },
-            mac: String::from("mac").into_bytes(),
-        };
-
-        db.insert_auth_token(&auth_token2);
-        let mut auth_tokens_returned = get_auth_tokens(&db);
-        assert_eq!(auth_tokens_returned.len(), 1);
-
-        if let Some(auth_token) = auth_tokens_returned.pop() {
-            assert_eq!(auth_token.auth_token.timestamp.milliSeconds, 600);
-        }
-
-        // insert another auth token with the different values for the columns in the UNIQUE
-        // constraint of the auth token table
-        let auth_token3 = HardwareAuthToken {
-            challenge: i64::MAX,
-            userId: 201,
-            authenticatorId: 200,
-            authenticatorType: kmhw_authenticator_type(kmhw_authenticator_type::PASSWORD.0),
-            timestamp: Timestamp { milliSeconds: 600 },
-            mac: String::from("mac").into_bytes(),
-        };
-
-        db.insert_auth_token(&auth_token3);
-        let auth_tokens_returned = get_auth_tokens(&db);
-        assert_eq!(auth_tokens_returned.len(), 2);
-
-        Ok(())
-    }
-
-    // utility function for test_auth_token_table_invariant()
-    fn get_auth_tokens(db: &KeystoreDB) -> Vec<AuthTokenEntry> {
-        db.perboot.get_all_auth_token_entries()
-    }
-
-    fn create_key_entry(
-        db: &mut KeystoreDB,
-        domain: &Domain,
-        namespace: &i64,
-        key_type: KeyType,
-        km_uuid: &Uuid,
-    ) -> Result<KeyIdGuard> {
-        db.with_transaction(Immediate("TX_create_key_entry"), |tx| {
-            KeystoreDB::create_key_entry_internal(tx, domain, namespace, key_type, km_uuid).no_gc()
-        })
-    }
-
-    #[test]
-    fn test_persistence_for_files() -> Result<()> {
-        let temp_dir = TempDir::new("persistent_db_test")?;
-        let mut db = KeystoreDB::new(temp_dir.path(), None)?;
-
-        create_key_entry(&mut db, &Domain::APP, &100, KeyType::Client, &KEYSTORE_UUID)?;
-        let entries = get_keyentry(&db)?;
-        assert_eq!(entries.len(), 1);
-
-        let db = KeystoreDB::new(temp_dir.path(), None)?;
-
-        let entries_new = get_keyentry(&db)?;
-        assert_eq!(entries, entries_new);
-        Ok(())
-    }
-
-    #[test]
-    fn test_create_key_entry() -> Result<()> {
-        fn extractor(ke: &KeyEntryRow) -> (Domain, i64, Option<&str>, Uuid) {
-            (ke.domain.unwrap(), ke.namespace.unwrap(), ke.alias.as_deref(), ke.km_uuid.unwrap())
-        }
-
-        let mut db = new_test_db()?;
-
-        create_key_entry(&mut db, &Domain::APP, &100, KeyType::Client, &KEYSTORE_UUID)?;
-        create_key_entry(&mut db, &Domain::SELINUX, &101, KeyType::Client, &KEYSTORE_UUID)?;
-
-        let entries = get_keyentry(&db)?;
-        assert_eq!(entries.len(), 2);
-        assert_eq!(extractor(&entries[0]), (Domain::APP, 100, None, KEYSTORE_UUID));
-        assert_eq!(extractor(&entries[1]), (Domain::SELINUX, 101, None, KEYSTORE_UUID));
-
-        // Test that we must pass in a valid Domain.
-        check_result_is_error_containing_string(
-            create_key_entry(&mut db, &Domain::GRANT, &102, KeyType::Client, &KEYSTORE_UUID),
-            &format!("Domain {:?} must be either App or SELinux.", Domain::GRANT),
-        );
-        check_result_is_error_containing_string(
-            create_key_entry(&mut db, &Domain::BLOB, &103, KeyType::Client, &KEYSTORE_UUID),
-            &format!("Domain {:?} must be either App or SELinux.", Domain::BLOB),
-        );
-        check_result_is_error_containing_string(
-            create_key_entry(&mut db, &Domain::KEY_ID, &104, KeyType::Client, &KEYSTORE_UUID),
-            &format!("Domain {:?} must be either App or SELinux.", Domain::KEY_ID),
-        );
-
-        Ok(())
-    }
-
-    #[test]
-    fn test_rebind_alias() -> Result<()> {
-        fn extractor(
-            ke: &KeyEntryRow,
-        ) -> (Option<Domain>, Option<i64>, Option<&str>, Option<Uuid>) {
-            (ke.domain, ke.namespace, ke.alias.as_deref(), ke.km_uuid)
-        }
-
-        let mut db = new_test_db()?;
-        create_key_entry(&mut db, &Domain::APP, &42, KeyType::Client, &KEYSTORE_UUID)?;
-        create_key_entry(&mut db, &Domain::APP, &42, KeyType::Client, &KEYSTORE_UUID)?;
-        let entries = get_keyentry(&db)?;
-        assert_eq!(entries.len(), 2);
-        assert_eq!(
-            extractor(&entries[0]),
-            (Some(Domain::APP), Some(42), None, Some(KEYSTORE_UUID))
-        );
-        assert_eq!(
-            extractor(&entries[1]),
-            (Some(Domain::APP), Some(42), None, Some(KEYSTORE_UUID))
-        );
-
-        // Test that the first call to rebind_alias sets the alias.
-        rebind_alias(&mut db, &KEY_ID_LOCK.get(entries[0].id), "foo", Domain::APP, 42)?;
-        let entries = get_keyentry(&db)?;
-        assert_eq!(entries.len(), 2);
-        assert_eq!(
-            extractor(&entries[0]),
-            (Some(Domain::APP), Some(42), Some("foo"), Some(KEYSTORE_UUID))
-        );
-        assert_eq!(
-            extractor(&entries[1]),
-            (Some(Domain::APP), Some(42), None, Some(KEYSTORE_UUID))
-        );
-
-        // Test that the second call to rebind_alias also empties the old one.
-        rebind_alias(&mut db, &KEY_ID_LOCK.get(entries[1].id), "foo", Domain::APP, 42)?;
-        let entries = get_keyentry(&db)?;
-        assert_eq!(entries.len(), 2);
-        assert_eq!(extractor(&entries[0]), (None, None, None, Some(KEYSTORE_UUID)));
-        assert_eq!(
-            extractor(&entries[1]),
-            (Some(Domain::APP), Some(42), Some("foo"), Some(KEYSTORE_UUID))
-        );
-
-        // Test that we must pass in a valid Domain.
-        check_result_is_error_containing_string(
-            rebind_alias(&mut db, &KEY_ID_LOCK.get(0), "foo", Domain::GRANT, 42),
-            &format!("Domain {:?} must be either App or SELinux.", Domain::GRANT),
-        );
-        check_result_is_error_containing_string(
-            rebind_alias(&mut db, &KEY_ID_LOCK.get(0), "foo", Domain::BLOB, 42),
-            &format!("Domain {:?} must be either App or SELinux.", Domain::BLOB),
-        );
-        check_result_is_error_containing_string(
-            rebind_alias(&mut db, &KEY_ID_LOCK.get(0), "foo", Domain::KEY_ID, 42),
-            &format!("Domain {:?} must be either App or SELinux.", Domain::KEY_ID),
-        );
-
-        // Test that we correctly handle setting an alias for something that does not exist.
-        check_result_is_error_containing_string(
-            rebind_alias(&mut db, &KEY_ID_LOCK.get(0), "foo", Domain::SELINUX, 42),
-            "Expected to update a single entry but instead updated 0",
-        );
-        // Test that we correctly abort the transaction in this case.
-        let entries = get_keyentry(&db)?;
-        assert_eq!(entries.len(), 2);
-        assert_eq!(extractor(&entries[0]), (None, None, None, Some(KEYSTORE_UUID)));
-        assert_eq!(
-            extractor(&entries[1]),
-            (Some(Domain::APP), Some(42), Some("foo"), Some(KEYSTORE_UUID))
-        );
-
-        Ok(())
-    }
-
-    #[test]
-    fn test_grant_ungrant() -> Result<()> {
-        const CALLER_UID: u32 = 15;
-        const GRANTEE_UID: u32 = 12;
-        const SELINUX_NAMESPACE: i64 = 7;
-
-        let mut db = new_test_db()?;
-        db.conn.execute(
-            "INSERT INTO persistent.keyentry (id, key_type, domain, namespace, alias, state, km_uuid)
-                VALUES (1, 0, 0, 15, 'key', 1, ?), (2, 0, 2, 7, 'yek', 1, ?);",
-            params![KEYSTORE_UUID, KEYSTORE_UUID],
-        )?;
-        let app_key = KeyDescriptor {
-            domain: super::Domain::APP,
-            nspace: 0,
-            alias: Some("key".to_string()),
-            blob: None,
-        };
-        const PVEC1: KeyPermSet = key_perm_set![KeyPerm::Use, KeyPerm::GetInfo];
-        const PVEC2: KeyPermSet = key_perm_set![KeyPerm::Use];
-
-        // Reset totally predictable random number generator in case we
-        // are not the first test running on this thread.
-        reset_random();
-        let next_random = 0i64;
-
-        let app_granted_key = db
-            .grant(&app_key, CALLER_UID, GRANTEE_UID, PVEC1, |k, a| {
-                assert_eq!(*a, PVEC1);
-                assert_eq!(
-                    *k,
-                    KeyDescriptor {
-                        domain: super::Domain::APP,
-                        // namespace must be set to the caller_uid.
-                        nspace: CALLER_UID as i64,
-                        alias: Some("key".to_string()),
-                        blob: None,
-                    }
-                );
-                Ok(())
-            })
-            .unwrap();
-
-        assert_eq!(
-            app_granted_key,
-            KeyDescriptor {
-                domain: super::Domain::GRANT,
-                // The grantid is next_random due to the mock random number generator.
-                nspace: next_random,
-                alias: None,
-                blob: None,
-            }
-        );
-
-        let selinux_key = KeyDescriptor {
-            domain: super::Domain::SELINUX,
-            nspace: SELINUX_NAMESPACE,
-            alias: Some("yek".to_string()),
-            blob: None,
-        };
-
-        let selinux_granted_key = db
-            .grant(&selinux_key, CALLER_UID, 12, PVEC1, |k, a| {
-                assert_eq!(*a, PVEC1);
-                assert_eq!(
-                    *k,
-                    KeyDescriptor {
-                        domain: super::Domain::SELINUX,
-                        // namespace must be the supplied SELinux
-                        // namespace.
-                        nspace: SELINUX_NAMESPACE,
-                        alias: Some("yek".to_string()),
-                        blob: None,
-                    }
-                );
-                Ok(())
-            })
-            .unwrap();
-
-        assert_eq!(
-            selinux_granted_key,
-            KeyDescriptor {
-                domain: super::Domain::GRANT,
-                // The grantid is next_random + 1 due to the mock random number generator.
-                nspace: next_random + 1,
-                alias: None,
-                blob: None,
-            }
-        );
-
-        // This should update the existing grant with PVEC2.
-        let selinux_granted_key = db
-            .grant(&selinux_key, CALLER_UID, 12, PVEC2, |k, a| {
-                assert_eq!(*a, PVEC2);
-                assert_eq!(
-                    *k,
-                    KeyDescriptor {
-                        domain: super::Domain::SELINUX,
-                        // namespace must be the supplied SELinux
-                        // namespace.
-                        nspace: SELINUX_NAMESPACE,
-                        alias: Some("yek".to_string()),
-                        blob: None,
-                    }
-                );
-                Ok(())
-            })
-            .unwrap();
-
-        assert_eq!(
-            selinux_granted_key,
-            KeyDescriptor {
-                domain: super::Domain::GRANT,
-                // Same grant id as before. The entry was only updated.
-                nspace: next_random + 1,
-                alias: None,
-                blob: None,
-            }
-        );
-
-        {
-            // Limiting scope of stmt, because it borrows db.
-            let mut stmt = db
-                .conn
-                .prepare("SELECT id, grantee, keyentryid, access_vector FROM persistent.grant;")?;
-            let mut rows = stmt.query_map::<(i64, u32, i64, KeyPermSet), _, _>([], |row| {
-                Ok((row.get(0)?, row.get(1)?, row.get(2)?, KeyPermSet::from(row.get::<_, i32>(3)?)))
-            })?;
-
-            let r = rows.next().unwrap().unwrap();
-            assert_eq!(r, (next_random, GRANTEE_UID, 1, PVEC1));
-            let r = rows.next().unwrap().unwrap();
-            assert_eq!(r, (next_random + 1, GRANTEE_UID, 2, PVEC2));
-            assert!(rows.next().is_none());
-        }
-
-        debug_dump_keyentry_table(&mut db)?;
-        println!("app_key {:?}", app_key);
-        println!("selinux_key {:?}", selinux_key);
-
-        db.ungrant(&app_key, CALLER_UID, GRANTEE_UID, |_| Ok(()))?;
-        db.ungrant(&selinux_key, CALLER_UID, GRANTEE_UID, |_| Ok(()))?;
-
-        Ok(())
-    }
-
-    static TEST_KEY_BLOB: &[u8] = b"my test blob";
-    static TEST_CERT_BLOB: &[u8] = b"my test cert";
-    static TEST_CERT_CHAIN_BLOB: &[u8] = b"my test cert_chain";
-
-    #[test]
-    fn test_set_blob() -> Result<()> {
-        let key_id = KEY_ID_LOCK.get(3000);
-        let mut db = new_test_db()?;
-        let mut blob_metadata = BlobMetaData::new();
-        blob_metadata.add(BlobMetaEntry::KmUuid(KEYSTORE_UUID));
-        db.set_blob(
-            &key_id,
-            SubComponentType::KEY_BLOB,
-            Some(TEST_KEY_BLOB),
-            Some(&blob_metadata),
-        )?;
-        db.set_blob(&key_id, SubComponentType::CERT, Some(TEST_CERT_BLOB), None)?;
-        db.set_blob(&key_id, SubComponentType::CERT_CHAIN, Some(TEST_CERT_CHAIN_BLOB), None)?;
-        drop(key_id);
-
-        let mut stmt = db.conn.prepare(
-            "SELECT subcomponent_type, keyentryid, blob, id FROM persistent.blobentry
-                ORDER BY subcomponent_type ASC;",
-        )?;
-        let mut rows = stmt
-            .query_map::<((SubComponentType, i64, Vec<u8>), i64), _, _>([], |row| {
-                Ok(((row.get(0)?, row.get(1)?, row.get(2)?), row.get(3)?))
-            })?;
-        let (r, id) = rows.next().unwrap().unwrap();
-        assert_eq!(r, (SubComponentType::KEY_BLOB, 3000, TEST_KEY_BLOB.to_vec()));
-        let (r, _) = rows.next().unwrap().unwrap();
-        assert_eq!(r, (SubComponentType::CERT, 3000, TEST_CERT_BLOB.to_vec()));
-        let (r, _) = rows.next().unwrap().unwrap();
-        assert_eq!(r, (SubComponentType::CERT_CHAIN, 3000, TEST_CERT_CHAIN_BLOB.to_vec()));
-
-        drop(rows);
-        drop(stmt);
-
-        assert_eq!(
-            db.with_transaction(Immediate("TX_test"), |tx| {
-                BlobMetaData::load_from_db(id, tx).no_gc()
-            })
-            .expect("Should find blob metadata."),
-            blob_metadata
-        );
-        Ok(())
-    }
-
-    static TEST_ALIAS: &str = "my super duper key";
-
-    #[test]
-    fn test_insert_and_load_full_keyentry_domain_app() -> Result<()> {
-        let mut db = new_test_db()?;
-        let key_id = make_test_key_entry(&mut db, Domain::APP, 1, TEST_ALIAS, None)
-            .context("test_insert_and_load_full_keyentry_domain_app")?
-            .0;
-        let (_key_guard, key_entry) = db
-            .load_key_entry(
-                &KeyDescriptor {
-                    domain: Domain::APP,
-                    nspace: 0,
-                    alias: Some(TEST_ALIAS.to_string()),
-                    blob: None,
-                },
-                KeyType::Client,
-                KeyEntryLoadBits::BOTH,
-                1,
-                |_k, _av| Ok(()),
-            )
-            .unwrap();
-        assert_eq!(key_entry, make_test_key_entry_test_vector(key_id, None));
-
-        db.unbind_key(
-            &KeyDescriptor {
-                domain: Domain::APP,
-                nspace: 0,
-                alias: Some(TEST_ALIAS.to_string()),
-                blob: None,
-            },
-            KeyType::Client,
-            1,
-            |_, _| Ok(()),
-        )
-        .unwrap();
-
-        assert_eq!(
-            Some(&KsError::Rc(ResponseCode::KEY_NOT_FOUND)),
-            db.load_key_entry(
-                &KeyDescriptor {
-                    domain: Domain::APP,
-                    nspace: 0,
-                    alias: Some(TEST_ALIAS.to_string()),
-                    blob: None,
-                },
-                KeyType::Client,
-                KeyEntryLoadBits::NONE,
-                1,
-                |_k, _av| Ok(()),
-            )
-            .unwrap_err()
-            .root_cause()
-            .downcast_ref::<KsError>()
-        );
-
-        Ok(())
-    }
-
-    #[test]
-    fn test_insert_and_load_certificate_entry_domain_app() -> Result<()> {
-        let mut db = new_test_db()?;
-
-        db.store_new_certificate(
-            &KeyDescriptor {
-                domain: Domain::APP,
-                nspace: 1,
-                alias: Some(TEST_ALIAS.to_string()),
-                blob: None,
-            },
-            KeyType::Client,
-            TEST_CERT_BLOB,
-            &KEYSTORE_UUID,
-        )
-        .expect("Trying to insert cert.");
-
-        let (_key_guard, mut key_entry) = db
-            .load_key_entry(
-                &KeyDescriptor {
-                    domain: Domain::APP,
-                    nspace: 1,
-                    alias: Some(TEST_ALIAS.to_string()),
-                    blob: None,
-                },
-                KeyType::Client,
-                KeyEntryLoadBits::PUBLIC,
-                1,
-                |_k, _av| Ok(()),
-            )
-            .expect("Trying to read certificate entry.");
-
-        assert!(key_entry.pure_cert());
-        assert!(key_entry.cert().is_none());
-        assert_eq!(key_entry.take_cert_chain(), Some(TEST_CERT_BLOB.to_vec()));
-
-        db.unbind_key(
-            &KeyDescriptor {
-                domain: Domain::APP,
-                nspace: 1,
-                alias: Some(TEST_ALIAS.to_string()),
-                blob: None,
-            },
-            KeyType::Client,
-            1,
-            |_, _| Ok(()),
-        )
-        .unwrap();
-
-        assert_eq!(
-            Some(&KsError::Rc(ResponseCode::KEY_NOT_FOUND)),
-            db.load_key_entry(
-                &KeyDescriptor {
-                    domain: Domain::APP,
-                    nspace: 1,
-                    alias: Some(TEST_ALIAS.to_string()),
-                    blob: None,
-                },
-                KeyType::Client,
-                KeyEntryLoadBits::NONE,
-                1,
-                |_k, _av| Ok(()),
-            )
-            .unwrap_err()
-            .root_cause()
-            .downcast_ref::<KsError>()
-        );
-
-        Ok(())
-    }
-
-    #[test]
-    fn test_insert_and_load_full_keyentry_domain_selinux() -> Result<()> {
-        let mut db = new_test_db()?;
-        let key_id = make_test_key_entry(&mut db, Domain::SELINUX, 1, TEST_ALIAS, None)
-            .context("test_insert_and_load_full_keyentry_domain_selinux")?
-            .0;
-        let (_key_guard, key_entry) = db
-            .load_key_entry(
-                &KeyDescriptor {
-                    domain: Domain::SELINUX,
-                    nspace: 1,
-                    alias: Some(TEST_ALIAS.to_string()),
-                    blob: None,
-                },
-                KeyType::Client,
-                KeyEntryLoadBits::BOTH,
-                1,
-                |_k, _av| Ok(()),
-            )
-            .unwrap();
-        assert_eq!(key_entry, make_test_key_entry_test_vector(key_id, None));
-
-        db.unbind_key(
-            &KeyDescriptor {
-                domain: Domain::SELINUX,
-                nspace: 1,
-                alias: Some(TEST_ALIAS.to_string()),
-                blob: None,
-            },
-            KeyType::Client,
-            1,
-            |_, _| Ok(()),
-        )
-        .unwrap();
-
-        assert_eq!(
-            Some(&KsError::Rc(ResponseCode::KEY_NOT_FOUND)),
-            db.load_key_entry(
-                &KeyDescriptor {
-                    domain: Domain::SELINUX,
-                    nspace: 1,
-                    alias: Some(TEST_ALIAS.to_string()),
-                    blob: None,
-                },
-                KeyType::Client,
-                KeyEntryLoadBits::NONE,
-                1,
-                |_k, _av| Ok(()),
-            )
-            .unwrap_err()
-            .root_cause()
-            .downcast_ref::<KsError>()
-        );
-
-        Ok(())
-    }
-
-    #[test]
-    fn test_insert_and_load_full_keyentry_domain_key_id() -> Result<()> {
-        let mut db = new_test_db()?;
-        let key_id = make_test_key_entry(&mut db, Domain::SELINUX, 1, TEST_ALIAS, None)
-            .context("test_insert_and_load_full_keyentry_domain_key_id")?
-            .0;
-        let (_, key_entry) = db
-            .load_key_entry(
-                &KeyDescriptor { domain: Domain::KEY_ID, nspace: key_id, alias: None, blob: None },
-                KeyType::Client,
-                KeyEntryLoadBits::BOTH,
-                1,
-                |_k, _av| Ok(()),
-            )
-            .unwrap();
-
-        assert_eq!(key_entry, make_test_key_entry_test_vector(key_id, None));
-
-        db.unbind_key(
-            &KeyDescriptor { domain: Domain::KEY_ID, nspace: key_id, alias: None, blob: None },
-            KeyType::Client,
-            1,
-            |_, _| Ok(()),
-        )
-        .unwrap();
-
-        assert_eq!(
-            Some(&KsError::Rc(ResponseCode::KEY_NOT_FOUND)),
-            db.load_key_entry(
-                &KeyDescriptor { domain: Domain::KEY_ID, nspace: key_id, alias: None, blob: None },
-                KeyType::Client,
-                KeyEntryLoadBits::NONE,
-                1,
-                |_k, _av| Ok(()),
-            )
-            .unwrap_err()
-            .root_cause()
-            .downcast_ref::<KsError>()
-        );
-
-        Ok(())
-    }
-
-    #[test]
-    fn test_check_and_update_key_usage_count_with_limited_use_key() -> Result<()> {
-        let mut db = new_test_db()?;
-        let key_id = make_test_key_entry(&mut db, Domain::SELINUX, 1, TEST_ALIAS, Some(123))
-            .context("test_check_and_update_key_usage_count_with_limited_use_key")?
-            .0;
-        // Update the usage count of the limited use key.
-        db.check_and_update_key_usage_count(key_id)?;
-
-        let (_key_guard, key_entry) = db.load_key_entry(
-            &KeyDescriptor { domain: Domain::KEY_ID, nspace: key_id, alias: None, blob: None },
-            KeyType::Client,
-            KeyEntryLoadBits::BOTH,
-            1,
-            |_k, _av| Ok(()),
-        )?;
-
-        // The usage count is decremented now.
-        assert_eq!(key_entry, make_test_key_entry_test_vector(key_id, Some(122)));
-
-        Ok(())
-    }
-
-    #[test]
-    fn test_check_and_update_key_usage_count_with_exhausted_limited_use_key() -> Result<()> {
-        let mut db = new_test_db()?;
-        let key_id = make_test_key_entry(&mut db, Domain::SELINUX, 1, TEST_ALIAS, Some(1))
-            .context("test_check_and_update_key_usage_count_with_exhausted_limited_use_key")?
-            .0;
-        // Update the usage count of the limited use key.
-        db.check_and_update_key_usage_count(key_id).expect(concat!(
-            "In test_check_and_update_key_usage_count_with_exhausted_limited_use_key: ",
-            "This should succeed."
-        ));
-
-        // Try to update the exhausted limited use key.
-        let e = db.check_and_update_key_usage_count(key_id).expect_err(concat!(
-            "In test_check_and_update_key_usage_count_with_exhausted_limited_use_key: ",
-            "This should fail."
-        ));
-        assert_eq!(
-            &KsError::Km(ErrorCode::INVALID_KEY_BLOB),
-            e.root_cause().downcast_ref::<KsError>().unwrap()
-        );
-
-        Ok(())
-    }
-
-    #[test]
-    fn test_insert_and_load_full_keyentry_from_grant() -> Result<()> {
-        let mut db = new_test_db()?;
-        let key_id = make_test_key_entry(&mut db, Domain::APP, 1, TEST_ALIAS, None)
-            .context("test_insert_and_load_full_keyentry_from_grant")?
-            .0;
-
-        let granted_key = db
-            .grant(
-                &KeyDescriptor {
-                    domain: Domain::APP,
-                    nspace: 0,
-                    alias: Some(TEST_ALIAS.to_string()),
-                    blob: None,
-                },
-                1,
-                2,
-                key_perm_set![KeyPerm::Use],
-                |_k, _av| Ok(()),
-            )
-            .unwrap();
-
-        debug_dump_grant_table(&mut db)?;
-
-        let (_key_guard, key_entry) = db
-            .load_key_entry(&granted_key, KeyType::Client, KeyEntryLoadBits::BOTH, 2, |k, av| {
-                assert_eq!(Domain::GRANT, k.domain);
-                assert!(av.unwrap().includes(KeyPerm::Use));
-                Ok(())
-            })
-            .unwrap();
-
-        assert_eq!(key_entry, make_test_key_entry_test_vector(key_id, None));
-
-        db.unbind_key(&granted_key, KeyType::Client, 2, |_, _| Ok(())).unwrap();
-
-        assert_eq!(
-            Some(&KsError::Rc(ResponseCode::KEY_NOT_FOUND)),
-            db.load_key_entry(
-                &granted_key,
-                KeyType::Client,
-                KeyEntryLoadBits::NONE,
-                2,
-                |_k, _av| Ok(()),
-            )
-            .unwrap_err()
-            .root_cause()
-            .downcast_ref::<KsError>()
-        );
-
-        Ok(())
-    }
-
-    // This test attempts to load a key by key id while the caller is not the owner
-    // but a grant exists for the given key and the caller.
-    #[test]
-    fn test_insert_and_load_full_keyentry_from_grant_by_key_id() -> Result<()> {
-        let mut db = new_test_db()?;
-        const OWNER_UID: u32 = 1u32;
-        const GRANTEE_UID: u32 = 2u32;
-        const SOMEONE_ELSE_UID: u32 = 3u32;
-        let key_id = make_test_key_entry(&mut db, Domain::APP, OWNER_UID as i64, TEST_ALIAS, None)
-            .context("test_insert_and_load_full_keyentry_from_grant_by_key_id")?
-            .0;
-
-        db.grant(
-            &KeyDescriptor {
-                domain: Domain::APP,
-                nspace: 0,
-                alias: Some(TEST_ALIAS.to_string()),
-                blob: None,
-            },
-            OWNER_UID,
-            GRANTEE_UID,
-            key_perm_set![KeyPerm::Use],
-            |_k, _av| Ok(()),
-        )
-        .unwrap();
-
-        debug_dump_grant_table(&mut db)?;
-
-        let id_descriptor =
-            KeyDescriptor { domain: Domain::KEY_ID, nspace: key_id, ..Default::default() };
-
-        let (_, key_entry) = db
-            .load_key_entry(
-                &id_descriptor,
-                KeyType::Client,
-                KeyEntryLoadBits::BOTH,
-                GRANTEE_UID,
-                |k, av| {
-                    assert_eq!(Domain::APP, k.domain);
-                    assert_eq!(OWNER_UID as i64, k.nspace);
-                    assert!(av.unwrap().includes(KeyPerm::Use));
-                    Ok(())
-                },
-            )
-            .unwrap();
-
-        assert_eq!(key_entry, make_test_key_entry_test_vector(key_id, None));
-
-        let (_, key_entry) = db
-            .load_key_entry(
-                &id_descriptor,
-                KeyType::Client,
-                KeyEntryLoadBits::BOTH,
-                SOMEONE_ELSE_UID,
-                |k, av| {
-                    assert_eq!(Domain::APP, k.domain);
-                    assert_eq!(OWNER_UID as i64, k.nspace);
-                    assert!(av.is_none());
-                    Ok(())
-                },
-            )
-            .unwrap();
-
-        assert_eq!(key_entry, make_test_key_entry_test_vector(key_id, None));
-
-        db.unbind_key(&id_descriptor, KeyType::Client, OWNER_UID, |_, _| Ok(())).unwrap();
-
-        assert_eq!(
-            Some(&KsError::Rc(ResponseCode::KEY_NOT_FOUND)),
-            db.load_key_entry(
-                &id_descriptor,
-                KeyType::Client,
-                KeyEntryLoadBits::NONE,
-                GRANTEE_UID,
-                |_k, _av| Ok(()),
-            )
-            .unwrap_err()
-            .root_cause()
-            .downcast_ref::<KsError>()
-        );
-
-        Ok(())
-    }
-
-    // Creates a key migrates it to a different location and then tries to access it by the old
-    // and new location.
-    #[test]
-    fn test_migrate_key_app_to_app() -> Result<()> {
-        let mut db = new_test_db()?;
-        const SOURCE_UID: u32 = 1u32;
-        const DESTINATION_UID: u32 = 2u32;
-        static SOURCE_ALIAS: &str = "SOURCE_ALIAS";
-        static DESTINATION_ALIAS: &str = "DESTINATION_ALIAS";
-        let key_id_guard =
-            make_test_key_entry(&mut db, Domain::APP, SOURCE_UID as i64, SOURCE_ALIAS, None)
-                .context("test_insert_and_load_full_keyentry_from_grant_by_key_id")?;
-
-        let source_descriptor: KeyDescriptor = KeyDescriptor {
-            domain: Domain::APP,
-            nspace: -1,
-            alias: Some(SOURCE_ALIAS.to_string()),
-            blob: None,
-        };
-
-        let destination_descriptor: KeyDescriptor = KeyDescriptor {
-            domain: Domain::APP,
-            nspace: -1,
-            alias: Some(DESTINATION_ALIAS.to_string()),
-            blob: None,
-        };
-
-        let key_id = key_id_guard.id();
-
-        db.migrate_key_namespace(key_id_guard, &destination_descriptor, DESTINATION_UID, |_k| {
-            Ok(())
-        })
-        .unwrap();
-
-        let (_, key_entry) = db
-            .load_key_entry(
-                &destination_descriptor,
-                KeyType::Client,
-                KeyEntryLoadBits::BOTH,
-                DESTINATION_UID,
-                |k, av| {
-                    assert_eq!(Domain::APP, k.domain);
-                    assert_eq!(DESTINATION_UID as i64, k.nspace);
-                    assert!(av.is_none());
-                    Ok(())
-                },
-            )
-            .unwrap();
-
-        assert_eq!(key_entry, make_test_key_entry_test_vector(key_id, None));
-
-        assert_eq!(
-            Some(&KsError::Rc(ResponseCode::KEY_NOT_FOUND)),
-            db.load_key_entry(
-                &source_descriptor,
-                KeyType::Client,
-                KeyEntryLoadBits::NONE,
-                SOURCE_UID,
-                |_k, _av| Ok(()),
-            )
-            .unwrap_err()
-            .root_cause()
-            .downcast_ref::<KsError>()
-        );
-
-        Ok(())
-    }
-
-    // Creates a key migrates it to a different location and then tries to access it by the old
-    // and new location.
-    #[test]
-    fn test_migrate_key_app_to_selinux() -> Result<()> {
-        let mut db = new_test_db()?;
-        const SOURCE_UID: u32 = 1u32;
-        const DESTINATION_UID: u32 = 2u32;
-        const DESTINATION_NAMESPACE: i64 = 1000i64;
-        static SOURCE_ALIAS: &str = "SOURCE_ALIAS";
-        static DESTINATION_ALIAS: &str = "DESTINATION_ALIAS";
-        let key_id_guard =
-            make_test_key_entry(&mut db, Domain::APP, SOURCE_UID as i64, SOURCE_ALIAS, None)
-                .context("test_insert_and_load_full_keyentry_from_grant_by_key_id")?;
-
-        let source_descriptor: KeyDescriptor = KeyDescriptor {
-            domain: Domain::APP,
-            nspace: -1,
-            alias: Some(SOURCE_ALIAS.to_string()),
-            blob: None,
-        };
-
-        let destination_descriptor: KeyDescriptor = KeyDescriptor {
-            domain: Domain::SELINUX,
-            nspace: DESTINATION_NAMESPACE,
-            alias: Some(DESTINATION_ALIAS.to_string()),
-            blob: None,
-        };
-
-        let key_id = key_id_guard.id();
-
-        db.migrate_key_namespace(key_id_guard, &destination_descriptor, DESTINATION_UID, |_k| {
-            Ok(())
-        })
-        .unwrap();
-
-        let (_, key_entry) = db
-            .load_key_entry(
-                &destination_descriptor,
-                KeyType::Client,
-                KeyEntryLoadBits::BOTH,
-                DESTINATION_UID,
-                |k, av| {
-                    assert_eq!(Domain::SELINUX, k.domain);
-                    assert_eq!(DESTINATION_NAMESPACE, k.nspace);
-                    assert!(av.is_none());
-                    Ok(())
-                },
-            )
-            .unwrap();
-
-        assert_eq!(key_entry, make_test_key_entry_test_vector(key_id, None));
-
-        assert_eq!(
-            Some(&KsError::Rc(ResponseCode::KEY_NOT_FOUND)),
-            db.load_key_entry(
-                &source_descriptor,
-                KeyType::Client,
-                KeyEntryLoadBits::NONE,
-                SOURCE_UID,
-                |_k, _av| Ok(()),
-            )
-            .unwrap_err()
-            .root_cause()
-            .downcast_ref::<KsError>()
-        );
-
-        Ok(())
-    }
-
-    // Creates two keys and tries to migrate the first to the location of the second which
-    // is expected to fail.
-    #[test]
-    fn test_migrate_key_destination_occupied() -> Result<()> {
-        let mut db = new_test_db()?;
-        const SOURCE_UID: u32 = 1u32;
-        const DESTINATION_UID: u32 = 2u32;
-        static SOURCE_ALIAS: &str = "SOURCE_ALIAS";
-        static DESTINATION_ALIAS: &str = "DESTINATION_ALIAS";
-        let key_id_guard =
-            make_test_key_entry(&mut db, Domain::APP, SOURCE_UID as i64, SOURCE_ALIAS, None)
-                .context("test_insert_and_load_full_keyentry_from_grant_by_key_id")?;
-        make_test_key_entry(&mut db, Domain::APP, DESTINATION_UID as i64, DESTINATION_ALIAS, None)
-            .context("test_insert_and_load_full_keyentry_from_grant_by_key_id")?;
-
-        let destination_descriptor: KeyDescriptor = KeyDescriptor {
-            domain: Domain::APP,
-            nspace: -1,
-            alias: Some(DESTINATION_ALIAS.to_string()),
-            blob: None,
-        };
-
-        assert_eq!(
-            Some(&KsError::Rc(ResponseCode::INVALID_ARGUMENT)),
-            db.migrate_key_namespace(
-                key_id_guard,
-                &destination_descriptor,
-                DESTINATION_UID,
-                |_k| Ok(())
-            )
-            .unwrap_err()
-            .root_cause()
-            .downcast_ref::<KsError>()
-        );
-
-        Ok(())
-    }
-
-    #[test]
-    fn test_upgrade_0_to_1() {
-        const ALIAS1: &str = "test_upgrade_0_to_1_1";
-        const ALIAS2: &str = "test_upgrade_0_to_1_2";
-        const ALIAS3: &str = "test_upgrade_0_to_1_3";
-        const UID: u32 = 33;
-        let temp_dir = Arc::new(TempDir::new("test_upgrade_0_to_1").unwrap());
-        let mut db = KeystoreDB::new(temp_dir.path(), None).unwrap();
-        let key_id_untouched1 =
-            make_test_key_entry(&mut db, Domain::APP, UID as i64, ALIAS1, None).unwrap().id();
-        let key_id_untouched2 =
-            make_bootlevel_key_entry(&mut db, Domain::APP, UID as i64, ALIAS2, false).unwrap().id();
-        let key_id_deleted =
-            make_bootlevel_key_entry(&mut db, Domain::APP, UID as i64, ALIAS3, true).unwrap().id();
-
-        let (_, key_entry) = db
-            .load_key_entry(
-                &KeyDescriptor {
-                    domain: Domain::APP,
-                    nspace: -1,
-                    alias: Some(ALIAS1.to_string()),
-                    blob: None,
-                },
-                KeyType::Client,
-                KeyEntryLoadBits::BOTH,
-                UID,
-                |k, av| {
-                    assert_eq!(Domain::APP, k.domain);
-                    assert_eq!(UID as i64, k.nspace);
-                    assert!(av.is_none());
-                    Ok(())
-                },
-            )
-            .unwrap();
-        assert_eq!(key_entry, make_test_key_entry_test_vector(key_id_untouched1, None));
-        let (_, key_entry) = db
-            .load_key_entry(
-                &KeyDescriptor {
-                    domain: Domain::APP,
-                    nspace: -1,
-                    alias: Some(ALIAS2.to_string()),
-                    blob: None,
-                },
-                KeyType::Client,
-                KeyEntryLoadBits::BOTH,
-                UID,
-                |k, av| {
-                    assert_eq!(Domain::APP, k.domain);
-                    assert_eq!(UID as i64, k.nspace);
-                    assert!(av.is_none());
-                    Ok(())
-                },
-            )
-            .unwrap();
-        assert_eq!(key_entry, make_bootlevel_test_key_entry_test_vector(key_id_untouched2, false));
-        let (_, key_entry) = db
-            .load_key_entry(
-                &KeyDescriptor {
-                    domain: Domain::APP,
-                    nspace: -1,
-                    alias: Some(ALIAS3.to_string()),
-                    blob: None,
-                },
-                KeyType::Client,
-                KeyEntryLoadBits::BOTH,
-                UID,
-                |k, av| {
-                    assert_eq!(Domain::APP, k.domain);
-                    assert_eq!(UID as i64, k.nspace);
-                    assert!(av.is_none());
-                    Ok(())
-                },
-            )
-            .unwrap();
-        assert_eq!(key_entry, make_bootlevel_test_key_entry_test_vector(key_id_deleted, true));
-
-        db.with_transaction(Immediate("TX_test"), |tx| KeystoreDB::from_0_to_1(tx).no_gc())
-            .unwrap();
-
-        let (_, key_entry) = db
-            .load_key_entry(
-                &KeyDescriptor {
-                    domain: Domain::APP,
-                    nspace: -1,
-                    alias: Some(ALIAS1.to_string()),
-                    blob: None,
-                },
-                KeyType::Client,
-                KeyEntryLoadBits::BOTH,
-                UID,
-                |k, av| {
-                    assert_eq!(Domain::APP, k.domain);
-                    assert_eq!(UID as i64, k.nspace);
-                    assert!(av.is_none());
-                    Ok(())
-                },
-            )
-            .unwrap();
-        assert_eq!(key_entry, make_test_key_entry_test_vector(key_id_untouched1, None));
-        let (_, key_entry) = db
-            .load_key_entry(
-                &KeyDescriptor {
-                    domain: Domain::APP,
-                    nspace: -1,
-                    alias: Some(ALIAS2.to_string()),
-                    blob: None,
-                },
-                KeyType::Client,
-                KeyEntryLoadBits::BOTH,
-                UID,
-                |k, av| {
-                    assert_eq!(Domain::APP, k.domain);
-                    assert_eq!(UID as i64, k.nspace);
-                    assert!(av.is_none());
-                    Ok(())
-                },
-            )
-            .unwrap();
-        assert_eq!(key_entry, make_bootlevel_test_key_entry_test_vector(key_id_untouched2, false));
-        assert_eq!(
-            Some(&KsError::Rc(ResponseCode::KEY_NOT_FOUND)),
-            db.load_key_entry(
-                &KeyDescriptor {
-                    domain: Domain::APP,
-                    nspace: -1,
-                    alias: Some(ALIAS3.to_string()),
-                    blob: None,
-                },
-                KeyType::Client,
-                KeyEntryLoadBits::BOTH,
-                UID,
-                |k, av| {
-                    assert_eq!(Domain::APP, k.domain);
-                    assert_eq!(UID as i64, k.nspace);
-                    assert!(av.is_none());
-                    Ok(())
-                },
-            )
-            .unwrap_err()
-            .root_cause()
-            .downcast_ref::<KsError>()
-        );
-    }
-
-    static KEY_LOCK_TEST_ALIAS: &str = "my super duper locked key";
-
-    #[test]
-    fn test_insert_and_load_full_keyentry_domain_app_concurrently() -> Result<()> {
-        let handle = {
-            let temp_dir = Arc::new(TempDir::new("id_lock_test")?);
-            let temp_dir_clone = temp_dir.clone();
-            let mut db = KeystoreDB::new(temp_dir.path(), None)?;
-            let key_id = make_test_key_entry(&mut db, Domain::APP, 33, KEY_LOCK_TEST_ALIAS, None)
-                .context("test_insert_and_load_full_keyentry_domain_app")?
-                .0;
-            let (_key_guard, key_entry) = db
-                .load_key_entry(
-                    &KeyDescriptor {
-                        domain: Domain::APP,
-                        nspace: 0,
-                        alias: Some(KEY_LOCK_TEST_ALIAS.to_string()),
-                        blob: None,
-                    },
-                    KeyType::Client,
-                    KeyEntryLoadBits::BOTH,
-                    33,
-                    |_k, _av| Ok(()),
-                )
-                .unwrap();
-            assert_eq!(key_entry, make_test_key_entry_test_vector(key_id, None));
-            let state = Arc::new(AtomicU8::new(1));
-            let state2 = state.clone();
-
-            // Spawning a second thread that attempts to acquire the key id lock
-            // for the same key as the primary thread. The primary thread then
-            // waits, thereby forcing the secondary thread into the second stage
-            // of acquiring the lock (see KEY ID LOCK 2/2 above).
-            // The test succeeds if the secondary thread observes the transition
-            // of `state` from 1 to 2, despite having a whole second to overtake
-            // the primary thread.
-            let handle = thread::spawn(move || {
-                let temp_dir = temp_dir_clone;
-                let mut db = KeystoreDB::new(temp_dir.path(), None).unwrap();
-                assert!(db
-                    .load_key_entry(
-                        &KeyDescriptor {
-                            domain: Domain::APP,
-                            nspace: 0,
-                            alias: Some(KEY_LOCK_TEST_ALIAS.to_string()),
-                            blob: None,
-                        },
-                        KeyType::Client,
-                        KeyEntryLoadBits::BOTH,
-                        33,
-                        |_k, _av| Ok(()),
-                    )
-                    .is_ok());
-                // We should only see a 2 here because we can only return
-                // from load_key_entry when the `_key_guard` expires,
-                // which happens at the end of the scope.
-                assert_eq!(2, state2.load(Ordering::Relaxed));
-            });
-
-            thread::sleep(std::time::Duration::from_millis(1000));
-
-            assert_eq!(Ok(1), state.compare_exchange(1, 2, Ordering::Relaxed, Ordering::Relaxed));
-
-            // Return the handle from this scope so we can join with the
-            // secondary thread after the key id lock has expired.
-            handle
-            // This is where the `_key_guard` goes out of scope,
-            // which is the reason for concurrent load_key_entry on the same key
-            // to unblock.
-        };
-        // Join with the secondary thread and unwrap, to propagate failing asserts to the
-        // main test thread. We will not see failing asserts in secondary threads otherwise.
-        handle.join().unwrap();
-        Ok(())
-    }
-
-    #[test]
-    fn test_database_busy_error_code() {
-        let temp_dir =
-            TempDir::new("test_database_busy_error_code_").expect("Failed to create temp dir.");
-
-        let mut db1 = KeystoreDB::new(temp_dir.path(), None).expect("Failed to open database1.");
-        let mut db2 = KeystoreDB::new(temp_dir.path(), None).expect("Failed to open database2.");
-
-        let _tx1 = db1
-            .conn
-            .transaction_with_behavior(rusqlite::TransactionBehavior::Immediate)
-            .expect("Failed to create first transaction.");
-
-        let error = db2
-            .conn
-            .transaction_with_behavior(rusqlite::TransactionBehavior::Immediate)
-            .context("Transaction begin failed.")
-            .expect_err("This should fail.");
-        let root_cause = error.root_cause();
-        if let Some(rusqlite::ffi::Error { code: rusqlite::ErrorCode::DatabaseBusy, .. }) =
-            root_cause.downcast_ref::<rusqlite::ffi::Error>()
-        {
-            return;
-        }
-        panic!(
-            "Unexpected error {:?} \n{:?} \n{:?}",
-            error,
-            root_cause,
-            root_cause.downcast_ref::<rusqlite::ffi::Error>()
-        )
-    }
-
-    #[cfg(disabled)]
-    #[test]
-    fn test_large_number_of_concurrent_db_manipulations() -> Result<()> {
-        let temp_dir = Arc::new(
-            TempDir::new("test_large_number_of_concurrent_db_manipulations_")
-                .expect("Failed to create temp dir."),
-        );
-
-        let test_begin = Instant::now();
-
-        const KEY_COUNT: u32 = 500u32;
-        let mut db =
-            new_test_db_with_gc(temp_dir.path(), |_, _| Ok(())).expect("Failed to open database.");
-        const OPEN_DB_COUNT: u32 = 50u32;
-
-        let mut actual_key_count = KEY_COUNT;
-        // First insert KEY_COUNT keys.
-        for count in 0..KEY_COUNT {
-            if Instant::now().duration_since(test_begin) >= Duration::from_secs(15) {
-                actual_key_count = count;
-                break;
-            }
-            let alias = format!("test_alias_{}", count);
-            make_test_key_entry(&mut db, Domain::APP, 1, &alias, None)
-                .expect("Failed to make key entry.");
-        }
-
-        // Insert more keys from a different thread and into a different namespace.
-        let temp_dir1 = temp_dir.clone();
-        let handle1 = thread::spawn(move || {
-            let mut db = new_test_db_with_gc(temp_dir1.path(), |_, _| Ok(()))
-                .expect("Failed to open database.");
-
-            for count in 0..actual_key_count {
-                if Instant::now().duration_since(test_begin) >= Duration::from_secs(40) {
-                    return;
-                }
-                let alias = format!("test_alias_{}", count);
-                make_test_key_entry(&mut db, Domain::APP, 2, &alias, None)
-                    .expect("Failed to make key entry.");
-            }
-
-            // then unbind them again.
-            for count in 0..actual_key_count {
-                if Instant::now().duration_since(test_begin) >= Duration::from_secs(40) {
-                    return;
-                }
-                let key = KeyDescriptor {
-                    domain: Domain::APP,
-                    nspace: -1,
-                    alias: Some(format!("test_alias_{}", count)),
-                    blob: None,
-                };
-                db.unbind_key(&key, KeyType::Client, 2, |_, _| Ok(())).expect("Unbind Failed.");
-            }
-        });
-
-        // And start unbinding the first set of keys.
-        let temp_dir2 = temp_dir.clone();
-        let handle2 = thread::spawn(move || {
-            let mut db = new_test_db_with_gc(temp_dir2.path(), |_, _| Ok(()))
-                .expect("Failed to open database.");
-
-            for count in 0..actual_key_count {
-                if Instant::now().duration_since(test_begin) >= Duration::from_secs(40) {
-                    return;
-                }
-                let key = KeyDescriptor {
-                    domain: Domain::APP,
-                    nspace: -1,
-                    alias: Some(format!("test_alias_{}", count)),
-                    blob: None,
-                };
-                db.unbind_key(&key, KeyType::Client, 1, |_, _| Ok(())).expect("Unbind Failed.");
-            }
-        });
-
-        // While a lot of inserting and deleting is going on we have to open database connections
-        // successfully and use them.
-        // This clone is not redundant, because temp_dir needs to be kept alive until db goes
-        // out of scope.
-        #[allow(clippy::redundant_clone)]
-        let temp_dir4 = temp_dir.clone();
-        let handle4 = thread::spawn(move || {
-            for count in 0..OPEN_DB_COUNT {
-                if Instant::now().duration_since(test_begin) >= Duration::from_secs(40) {
-                    return;
-                }
-                let mut db = new_test_db_with_gc(temp_dir4.path(), |_, _| Ok(()))
-                    .expect("Failed to open database.");
-
-                let alias = format!("test_alias_{}", count);
-                make_test_key_entry(&mut db, Domain::APP, 3, &alias, None)
-                    .expect("Failed to make key entry.");
-                let key = KeyDescriptor {
-                    domain: Domain::APP,
-                    nspace: -1,
-                    alias: Some(alias),
-                    blob: None,
-                };
-                db.unbind_key(&key, KeyType::Client, 3, |_, _| Ok(())).expect("Unbind Failed.");
-            }
-        });
-
-        handle1.join().expect("Thread 1 panicked.");
-        handle2.join().expect("Thread 2 panicked.");
-        handle4.join().expect("Thread 4 panicked.");
-
-        Ok(())
-    }
-
-    #[test]
-    fn list() -> Result<()> {
-        let temp_dir = TempDir::new("list_test")?;
-        let mut db = KeystoreDB::new(temp_dir.path(), None)?;
-        static LIST_O_ENTRIES: &[(Domain, i64, &str)] = &[
-            (Domain::APP, 1, "test1"),
-            (Domain::APP, 1, "test2"),
-            (Domain::APP, 1, "test3"),
-            (Domain::APP, 1, "test4"),
-            (Domain::APP, 1, "test5"),
-            (Domain::APP, 1, "test6"),
-            (Domain::APP, 1, "test7"),
-            (Domain::APP, 2, "test1"),
-            (Domain::APP, 2, "test2"),
-            (Domain::APP, 2, "test3"),
-            (Domain::APP, 2, "test4"),
-            (Domain::APP, 2, "test5"),
-            (Domain::APP, 2, "test6"),
-            (Domain::APP, 2, "test8"),
-            (Domain::SELINUX, 100, "test1"),
-            (Domain::SELINUX, 100, "test2"),
-            (Domain::SELINUX, 100, "test3"),
-            (Domain::SELINUX, 100, "test4"),
-            (Domain::SELINUX, 100, "test5"),
-            (Domain::SELINUX, 100, "test6"),
-            (Domain::SELINUX, 100, "test9"),
-        ];
-
-        let list_o_keys: Vec<(i64, i64)> = LIST_O_ENTRIES
-            .iter()
-            .map(|(domain, ns, alias)| {
-                let entry =
-                    make_test_key_entry(&mut db, *domain, *ns, alias, None).unwrap_or_else(|e| {
-                        panic!("Failed to insert {:?} {} {}. Error {:?}", domain, ns, alias, e)
-                    });
-                (entry.id(), *ns)
-            })
-            .collect();
-
-        for (domain, namespace) in
-            &[(Domain::APP, 1i64), (Domain::APP, 2i64), (Domain::SELINUX, 100i64)]
-        {
-            let mut list_o_descriptors: Vec<KeyDescriptor> = LIST_O_ENTRIES
-                .iter()
-                .filter_map(|(domain, ns, alias)| match ns {
-                    ns if *ns == *namespace => Some(KeyDescriptor {
-                        domain: *domain,
-                        nspace: *ns,
-                        alias: Some(alias.to_string()),
-                        blob: None,
-                    }),
-                    _ => None,
-                })
-                .collect();
-            list_o_descriptors.sort();
-            let mut list_result = db.list_past_alias(*domain, *namespace, KeyType::Client, None)?;
-            list_result.sort();
-            assert_eq!(list_o_descriptors, list_result);
-
-            let mut list_o_ids: Vec<i64> = list_o_descriptors
-                .into_iter()
-                .map(|d| {
-                    let (_, entry) = db
-                        .load_key_entry(
-                            &d,
-                            KeyType::Client,
-                            KeyEntryLoadBits::NONE,
-                            *namespace as u32,
-                            |_, _| Ok(()),
-                        )
-                        .unwrap();
-                    entry.id()
-                })
-                .collect();
-            list_o_ids.sort_unstable();
-            let mut loaded_entries: Vec<i64> = list_o_keys
-                .iter()
-                .filter_map(|(id, ns)| match ns {
-                    ns if *ns == *namespace => Some(*id),
-                    _ => None,
-                })
-                .collect();
-            loaded_entries.sort_unstable();
-            assert_eq!(list_o_ids, loaded_entries);
-        }
-        assert_eq!(
-            Vec::<KeyDescriptor>::new(),
-            db.list_past_alias(Domain::SELINUX, 101, KeyType::Client, None)?
-        );
-
-        Ok(())
-    }
-
-    // Helpers
-
-    // Checks that the given result is an error containing the given string.
-    fn check_result_is_error_containing_string<T>(result: Result<T>, target: &str) {
-        let error_str = format!(
-            "{:#?}",
-            result.err().unwrap_or_else(|| panic!("Expected the error: {}", target))
-        );
-        assert!(
-            error_str.contains(target),
-            "The string \"{}\" should contain \"{}\"",
-            error_str,
-            target
-        );
-    }
-
-    #[derive(Debug, PartialEq)]
-    struct KeyEntryRow {
-        id: i64,
-        key_type: KeyType,
-        domain: Option<Domain>,
-        namespace: Option<i64>,
-        alias: Option<String>,
-        state: KeyLifeCycle,
-        km_uuid: Option<Uuid>,
-    }
-
-    fn get_keyentry(db: &KeystoreDB) -> Result<Vec<KeyEntryRow>> {
-        db.conn
-            .prepare("SELECT * FROM persistent.keyentry;")?
-            .query_map([], |row| {
-                Ok(KeyEntryRow {
-                    id: row.get(0)?,
-                    key_type: row.get(1)?,
-                    domain: row.get::<_, Option<_>>(2)?.map(Domain),
-                    namespace: row.get(3)?,
-                    alias: row.get(4)?,
-                    state: row.get(5)?,
-                    km_uuid: row.get(6)?,
-                })
-            })?
-            .map(|r| r.context("Could not read keyentry row."))
-            .collect::<Result<Vec<_>>>()
-    }
-
-    fn make_test_params(max_usage_count: Option<i32>) -> Vec<KeyParameter> {
-        make_test_params_with_sids(max_usage_count, &[42])
-    }
-
-    // Note: The parameters and SecurityLevel associations are nonsensical. This
-    // collection is only used to check if the parameters are preserved as expected by the
-    // database.
-    fn make_test_params_with_sids(
-        max_usage_count: Option<i32>,
-        user_secure_ids: &[i64],
-    ) -> Vec<KeyParameter> {
-        let mut params = vec![
-            KeyParameter::new(KeyParameterValue::Invalid, SecurityLevel::TRUSTED_ENVIRONMENT),
-            KeyParameter::new(
-                KeyParameterValue::KeyPurpose(KeyPurpose::SIGN),
-                SecurityLevel::TRUSTED_ENVIRONMENT,
-            ),
-            KeyParameter::new(
-                KeyParameterValue::KeyPurpose(KeyPurpose::DECRYPT),
-                SecurityLevel::TRUSTED_ENVIRONMENT,
-            ),
-            KeyParameter::new(
-                KeyParameterValue::Algorithm(Algorithm::RSA),
-                SecurityLevel::TRUSTED_ENVIRONMENT,
-            ),
-            KeyParameter::new(KeyParameterValue::KeySize(1024), SecurityLevel::TRUSTED_ENVIRONMENT),
-            KeyParameter::new(
-                KeyParameterValue::BlockMode(BlockMode::ECB),
-                SecurityLevel::TRUSTED_ENVIRONMENT,
-            ),
-            KeyParameter::new(
-                KeyParameterValue::BlockMode(BlockMode::GCM),
-                SecurityLevel::TRUSTED_ENVIRONMENT,
-            ),
-            KeyParameter::new(KeyParameterValue::Digest(Digest::NONE), SecurityLevel::STRONGBOX),
-            KeyParameter::new(
-                KeyParameterValue::Digest(Digest::MD5),
-                SecurityLevel::TRUSTED_ENVIRONMENT,
-            ),
-            KeyParameter::new(
-                KeyParameterValue::Digest(Digest::SHA_2_224),
-                SecurityLevel::TRUSTED_ENVIRONMENT,
-            ),
-            KeyParameter::new(
-                KeyParameterValue::Digest(Digest::SHA_2_256),
-                SecurityLevel::STRONGBOX,
-            ),
-            KeyParameter::new(
-                KeyParameterValue::PaddingMode(PaddingMode::NONE),
-                SecurityLevel::TRUSTED_ENVIRONMENT,
-            ),
-            KeyParameter::new(
-                KeyParameterValue::PaddingMode(PaddingMode::RSA_OAEP),
-                SecurityLevel::TRUSTED_ENVIRONMENT,
-            ),
-            KeyParameter::new(
-                KeyParameterValue::PaddingMode(PaddingMode::RSA_PSS),
-                SecurityLevel::STRONGBOX,
-            ),
-            KeyParameter::new(
-                KeyParameterValue::PaddingMode(PaddingMode::RSA_PKCS1_1_5_SIGN),
-                SecurityLevel::TRUSTED_ENVIRONMENT,
-            ),
-            KeyParameter::new(KeyParameterValue::CallerNonce, SecurityLevel::TRUSTED_ENVIRONMENT),
-            KeyParameter::new(KeyParameterValue::MinMacLength(256), SecurityLevel::STRONGBOX),
-            KeyParameter::new(
-                KeyParameterValue::EcCurve(EcCurve::P_224),
-                SecurityLevel::TRUSTED_ENVIRONMENT,
-            ),
-            KeyParameter::new(KeyParameterValue::EcCurve(EcCurve::P_256), SecurityLevel::STRONGBOX),
-            KeyParameter::new(
-                KeyParameterValue::EcCurve(EcCurve::P_384),
-                SecurityLevel::TRUSTED_ENVIRONMENT,
-            ),
-            KeyParameter::new(
-                KeyParameterValue::EcCurve(EcCurve::P_521),
-                SecurityLevel::TRUSTED_ENVIRONMENT,
-            ),
-            KeyParameter::new(
-                KeyParameterValue::RSAPublicExponent(3),
-                SecurityLevel::TRUSTED_ENVIRONMENT,
-            ),
-            KeyParameter::new(
-                KeyParameterValue::IncludeUniqueID,
-                SecurityLevel::TRUSTED_ENVIRONMENT,
-            ),
-            KeyParameter::new(KeyParameterValue::BootLoaderOnly, SecurityLevel::STRONGBOX),
-            KeyParameter::new(KeyParameterValue::RollbackResistance, SecurityLevel::STRONGBOX),
-            KeyParameter::new(
-                KeyParameterValue::ActiveDateTime(1234567890),
-                SecurityLevel::STRONGBOX,
-            ),
-            KeyParameter::new(
-                KeyParameterValue::OriginationExpireDateTime(1234567890),
-                SecurityLevel::TRUSTED_ENVIRONMENT,
-            ),
-            KeyParameter::new(
-                KeyParameterValue::UsageExpireDateTime(1234567890),
-                SecurityLevel::TRUSTED_ENVIRONMENT,
-            ),
-            KeyParameter::new(
-                KeyParameterValue::MinSecondsBetweenOps(1234567890),
-                SecurityLevel::TRUSTED_ENVIRONMENT,
-            ),
-            KeyParameter::new(
-                KeyParameterValue::MaxUsesPerBoot(1234567890),
-                SecurityLevel::TRUSTED_ENVIRONMENT,
-            ),
-            KeyParameter::new(KeyParameterValue::UserID(1), SecurityLevel::STRONGBOX),
-            KeyParameter::new(
-                KeyParameterValue::NoAuthRequired,
-                SecurityLevel::TRUSTED_ENVIRONMENT,
-            ),
-            KeyParameter::new(
-                KeyParameterValue::HardwareAuthenticatorType(HardwareAuthenticatorType::PASSWORD),
-                SecurityLevel::TRUSTED_ENVIRONMENT,
-            ),
-            KeyParameter::new(KeyParameterValue::AuthTimeout(1234567890), SecurityLevel::SOFTWARE),
-            KeyParameter::new(KeyParameterValue::AllowWhileOnBody, SecurityLevel::SOFTWARE),
-            KeyParameter::new(
-                KeyParameterValue::TrustedUserPresenceRequired,
-                SecurityLevel::TRUSTED_ENVIRONMENT,
-            ),
-            KeyParameter::new(
-                KeyParameterValue::TrustedConfirmationRequired,
-                SecurityLevel::TRUSTED_ENVIRONMENT,
-            ),
-            KeyParameter::new(
-                KeyParameterValue::UnlockedDeviceRequired,
-                SecurityLevel::TRUSTED_ENVIRONMENT,
-            ),
-            KeyParameter::new(
-                KeyParameterValue::ApplicationID(vec![1u8, 2u8, 3u8, 4u8]),
-                SecurityLevel::SOFTWARE,
-            ),
-            KeyParameter::new(
-                KeyParameterValue::ApplicationData(vec![4u8, 3u8, 2u8, 1u8]),
-                SecurityLevel::SOFTWARE,
-            ),
-            KeyParameter::new(
-                KeyParameterValue::CreationDateTime(12345677890),
-                SecurityLevel::SOFTWARE,
-            ),
-            KeyParameter::new(
-                KeyParameterValue::KeyOrigin(KeyOrigin::GENERATED),
-                SecurityLevel::TRUSTED_ENVIRONMENT,
-            ),
-            KeyParameter::new(
-                KeyParameterValue::RootOfTrust(vec![3u8, 2u8, 1u8, 4u8]),
-                SecurityLevel::TRUSTED_ENVIRONMENT,
-            ),
-            KeyParameter::new(KeyParameterValue::OSVersion(1), SecurityLevel::TRUSTED_ENVIRONMENT),
-            KeyParameter::new(KeyParameterValue::OSPatchLevel(2), SecurityLevel::SOFTWARE),
-            KeyParameter::new(
-                KeyParameterValue::UniqueID(vec![4u8, 3u8, 1u8, 2u8]),
-                SecurityLevel::SOFTWARE,
-            ),
-            KeyParameter::new(
-                KeyParameterValue::AttestationChallenge(vec![4u8, 3u8, 1u8, 2u8]),
-                SecurityLevel::TRUSTED_ENVIRONMENT,
-            ),
-            KeyParameter::new(
-                KeyParameterValue::AttestationApplicationID(vec![4u8, 3u8, 1u8, 2u8]),
-                SecurityLevel::TRUSTED_ENVIRONMENT,
-            ),
-            KeyParameter::new(
-                KeyParameterValue::AttestationIdBrand(vec![4u8, 3u8, 1u8, 2u8]),
-                SecurityLevel::TRUSTED_ENVIRONMENT,
-            ),
-            KeyParameter::new(
-                KeyParameterValue::AttestationIdDevice(vec![4u8, 3u8, 1u8, 2u8]),
-                SecurityLevel::TRUSTED_ENVIRONMENT,
-            ),
-            KeyParameter::new(
-                KeyParameterValue::AttestationIdProduct(vec![4u8, 3u8, 1u8, 2u8]),
-                SecurityLevel::TRUSTED_ENVIRONMENT,
-            ),
-            KeyParameter::new(
-                KeyParameterValue::AttestationIdSerial(vec![4u8, 3u8, 1u8, 2u8]),
-                SecurityLevel::TRUSTED_ENVIRONMENT,
-            ),
-            KeyParameter::new(
-                KeyParameterValue::AttestationIdIMEI(vec![4u8, 3u8, 1u8, 2u8]),
-                SecurityLevel::TRUSTED_ENVIRONMENT,
-            ),
-            KeyParameter::new(
-                KeyParameterValue::AttestationIdSecondIMEI(vec![4u8, 3u8, 1u8, 2u8]),
-                SecurityLevel::TRUSTED_ENVIRONMENT,
-            ),
-            KeyParameter::new(
-                KeyParameterValue::AttestationIdMEID(vec![4u8, 3u8, 1u8, 2u8]),
-                SecurityLevel::TRUSTED_ENVIRONMENT,
-            ),
-            KeyParameter::new(
-                KeyParameterValue::AttestationIdManufacturer(vec![4u8, 3u8, 1u8, 2u8]),
-                SecurityLevel::TRUSTED_ENVIRONMENT,
-            ),
-            KeyParameter::new(
-                KeyParameterValue::AttestationIdModel(vec![4u8, 3u8, 1u8, 2u8]),
-                SecurityLevel::TRUSTED_ENVIRONMENT,
-            ),
-            KeyParameter::new(
-                KeyParameterValue::VendorPatchLevel(3),
-                SecurityLevel::TRUSTED_ENVIRONMENT,
-            ),
-            KeyParameter::new(
-                KeyParameterValue::BootPatchLevel(4),
-                SecurityLevel::TRUSTED_ENVIRONMENT,
-            ),
-            KeyParameter::new(
-                KeyParameterValue::AssociatedData(vec![4u8, 3u8, 1u8, 2u8]),
-                SecurityLevel::TRUSTED_ENVIRONMENT,
-            ),
-            KeyParameter::new(
-                KeyParameterValue::Nonce(vec![4u8, 3u8, 1u8, 2u8]),
-                SecurityLevel::TRUSTED_ENVIRONMENT,
-            ),
-            KeyParameter::new(
-                KeyParameterValue::MacLength(256),
-                SecurityLevel::TRUSTED_ENVIRONMENT,
-            ),
-            KeyParameter::new(
-                KeyParameterValue::ResetSinceIdRotation,
-                SecurityLevel::TRUSTED_ENVIRONMENT,
-            ),
-            KeyParameter::new(
-                KeyParameterValue::ConfirmationToken(vec![5u8, 5u8, 5u8, 5u8]),
-                SecurityLevel::TRUSTED_ENVIRONMENT,
-            ),
-        ];
-        if let Some(value) = max_usage_count {
-            params.push(KeyParameter::new(
-                KeyParameterValue::UsageCountLimit(value),
-                SecurityLevel::SOFTWARE,
-            ));
-        }
-
-        for sid in user_secure_ids.iter() {
-            params.push(KeyParameter::new(
-                KeyParameterValue::UserSecureID(*sid),
-                SecurityLevel::STRONGBOX,
-            ));
-        }
-        params
-    }
-
-    pub fn make_test_key_entry(
-        db: &mut KeystoreDB,
-        domain: Domain,
-        namespace: i64,
-        alias: &str,
-        max_usage_count: Option<i32>,
-    ) -> Result<KeyIdGuard> {
-        make_test_key_entry_with_sids(db, domain, namespace, alias, max_usage_count, &[42])
-    }
-
-    pub fn make_test_key_entry_with_sids(
-        db: &mut KeystoreDB,
-        domain: Domain,
-        namespace: i64,
-        alias: &str,
-        max_usage_count: Option<i32>,
-        sids: &[i64],
-    ) -> Result<KeyIdGuard> {
-        let key_id = create_key_entry(db, &domain, &namespace, KeyType::Client, &KEYSTORE_UUID)?;
-        let mut blob_metadata = BlobMetaData::new();
-        blob_metadata.add(BlobMetaEntry::EncryptedBy(EncryptedBy::Password));
-        blob_metadata.add(BlobMetaEntry::Salt(vec![1, 2, 3]));
-        blob_metadata.add(BlobMetaEntry::Iv(vec![2, 3, 1]));
-        blob_metadata.add(BlobMetaEntry::AeadTag(vec![3, 1, 2]));
-        blob_metadata.add(BlobMetaEntry::KmUuid(KEYSTORE_UUID));
-
-        db.set_blob(
-            &key_id,
-            SubComponentType::KEY_BLOB,
-            Some(TEST_KEY_BLOB),
-            Some(&blob_metadata),
-        )?;
-        db.set_blob(&key_id, SubComponentType::CERT, Some(TEST_CERT_BLOB), None)?;
-        db.set_blob(&key_id, SubComponentType::CERT_CHAIN, Some(TEST_CERT_CHAIN_BLOB), None)?;
-
-        let params = make_test_params_with_sids(max_usage_count, sids);
-        db.insert_keyparameter(&key_id, &params)?;
-
-        let mut metadata = KeyMetaData::new();
-        metadata.add(KeyMetaEntry::CreationDate(DateTime::from_millis_epoch(123456789)));
-        db.insert_key_metadata(&key_id, &metadata)?;
-        rebind_alias(db, &key_id, alias, domain, namespace)?;
-        Ok(key_id)
-    }
-
-    fn make_test_key_entry_test_vector(key_id: i64, max_usage_count: Option<i32>) -> KeyEntry {
-        let params = make_test_params(max_usage_count);
-
-        let mut blob_metadata = BlobMetaData::new();
-        blob_metadata.add(BlobMetaEntry::EncryptedBy(EncryptedBy::Password));
-        blob_metadata.add(BlobMetaEntry::Salt(vec![1, 2, 3]));
-        blob_metadata.add(BlobMetaEntry::Iv(vec![2, 3, 1]));
-        blob_metadata.add(BlobMetaEntry::AeadTag(vec![3, 1, 2]));
-        blob_metadata.add(BlobMetaEntry::KmUuid(KEYSTORE_UUID));
-
-        let mut metadata = KeyMetaData::new();
-        metadata.add(KeyMetaEntry::CreationDate(DateTime::from_millis_epoch(123456789)));
-
-        KeyEntry {
-            id: key_id,
-            key_blob_info: Some((TEST_KEY_BLOB.to_vec(), blob_metadata)),
-            cert: Some(TEST_CERT_BLOB.to_vec()),
-            cert_chain: Some(TEST_CERT_CHAIN_BLOB.to_vec()),
-            km_uuid: KEYSTORE_UUID,
-            parameters: params,
-            metadata,
-            pure_cert: false,
-        }
-    }
-
-    pub fn make_bootlevel_key_entry(
-        db: &mut KeystoreDB,
-        domain: Domain,
-        namespace: i64,
-        alias: &str,
-        logical_only: bool,
-    ) -> Result<KeyIdGuard> {
-        let key_id = create_key_entry(db, &domain, &namespace, KeyType::Client, &KEYSTORE_UUID)?;
-        let mut blob_metadata = BlobMetaData::new();
-        if !logical_only {
-            blob_metadata.add(BlobMetaEntry::MaxBootLevel(3));
-        }
-        blob_metadata.add(BlobMetaEntry::KmUuid(KEYSTORE_UUID));
-
-        db.set_blob(
-            &key_id,
-            SubComponentType::KEY_BLOB,
-            Some(TEST_KEY_BLOB),
-            Some(&blob_metadata),
-        )?;
-        db.set_blob(&key_id, SubComponentType::CERT, Some(TEST_CERT_BLOB), None)?;
-        db.set_blob(&key_id, SubComponentType::CERT_CHAIN, Some(TEST_CERT_CHAIN_BLOB), None)?;
-
-        let mut params = make_test_params(None);
-        params.push(KeyParameter::new(KeyParameterValue::MaxBootLevel(3), SecurityLevel::KEYSTORE));
-
-        db.insert_keyparameter(&key_id, &params)?;
-
-        let mut metadata = KeyMetaData::new();
-        metadata.add(KeyMetaEntry::CreationDate(DateTime::from_millis_epoch(123456789)));
-        db.insert_key_metadata(&key_id, &metadata)?;
-        rebind_alias(db, &key_id, alias, domain, namespace)?;
-        Ok(key_id)
-    }
-
-    // Creates an app key that is marked as being superencrypted by the given
-    // super key ID and that has the given authentication and unlocked device
-    // parameters. This does not actually superencrypt the key blob.
-    fn make_superencrypted_key_entry(
-        db: &mut KeystoreDB,
-        namespace: i64,
-        alias: &str,
-        requires_authentication: bool,
-        requires_unlocked_device: bool,
-        super_key_id: i64,
-    ) -> Result<KeyIdGuard> {
-        let domain = Domain::APP;
-        let key_id = create_key_entry(db, &domain, &namespace, KeyType::Client, &KEYSTORE_UUID)?;
-
-        let mut blob_metadata = BlobMetaData::new();
-        blob_metadata.add(BlobMetaEntry::KmUuid(KEYSTORE_UUID));
-        blob_metadata.add(BlobMetaEntry::EncryptedBy(EncryptedBy::KeyId(super_key_id)));
-        db.set_blob(
-            &key_id,
-            SubComponentType::KEY_BLOB,
-            Some(TEST_KEY_BLOB),
-            Some(&blob_metadata),
-        )?;
-
-        let mut params = vec![];
-        if requires_unlocked_device {
-            params.push(KeyParameter::new(
-                KeyParameterValue::UnlockedDeviceRequired,
-                SecurityLevel::TRUSTED_ENVIRONMENT,
-            ));
-        }
-        if requires_authentication {
-            params.push(KeyParameter::new(
-                KeyParameterValue::UserSecureID(42),
-                SecurityLevel::TRUSTED_ENVIRONMENT,
-            ));
-        }
-        db.insert_keyparameter(&key_id, &params)?;
-
-        let mut metadata = KeyMetaData::new();
-        metadata.add(KeyMetaEntry::CreationDate(DateTime::from_millis_epoch(123456789)));
-        db.insert_key_metadata(&key_id, &metadata)?;
-
-        rebind_alias(db, &key_id, alias, domain, namespace)?;
-        Ok(key_id)
-    }
-
-    fn make_bootlevel_test_key_entry_test_vector(key_id: i64, logical_only: bool) -> KeyEntry {
-        let mut params = make_test_params(None);
-        params.push(KeyParameter::new(KeyParameterValue::MaxBootLevel(3), SecurityLevel::KEYSTORE));
-
-        let mut blob_metadata = BlobMetaData::new();
-        if !logical_only {
-            blob_metadata.add(BlobMetaEntry::MaxBootLevel(3));
-        }
-        blob_metadata.add(BlobMetaEntry::KmUuid(KEYSTORE_UUID));
-
-        let mut metadata = KeyMetaData::new();
-        metadata.add(KeyMetaEntry::CreationDate(DateTime::from_millis_epoch(123456789)));
-
-        KeyEntry {
-            id: key_id,
-            key_blob_info: Some((TEST_KEY_BLOB.to_vec(), blob_metadata)),
-            cert: Some(TEST_CERT_BLOB.to_vec()),
-            cert_chain: Some(TEST_CERT_CHAIN_BLOB.to_vec()),
-            km_uuid: KEYSTORE_UUID,
-            parameters: params,
-            metadata,
-            pure_cert: false,
-        }
-    }
-
-    fn debug_dump_keyentry_table(db: &mut KeystoreDB) -> Result<()> {
-        let mut stmt = db.conn.prepare(
-            "SELECT id, key_type, domain, namespace, alias, state, km_uuid FROM persistent.keyentry;",
-        )?;
-        let rows = stmt.query_map::<(i64, KeyType, i32, i64, String, KeyLifeCycle, Uuid), _, _>(
-            [],
-            |row| {
-                Ok((
-                    row.get(0)?,
-                    row.get(1)?,
-                    row.get(2)?,
-                    row.get(3)?,
-                    row.get(4)?,
-                    row.get(5)?,
-                    row.get(6)?,
-                ))
-            },
-        )?;
-
-        println!("Key entry table rows:");
-        for r in rows {
-            let (id, key_type, domain, namespace, alias, state, km_uuid) = r.unwrap();
-            println!(
-                "    id: {} KeyType: {:?} Domain: {} Namespace: {} Alias: {} State: {:?} KmUuid: {:?}",
-                id, key_type, domain, namespace, alias, state, km_uuid
-            );
-        }
-        Ok(())
-    }
-
-    fn debug_dump_grant_table(db: &mut KeystoreDB) -> Result<()> {
-        let mut stmt = db
-            .conn
-            .prepare("SELECT id, grantee, keyentryid, access_vector FROM persistent.grant;")?;
-        let rows = stmt.query_map::<(i64, i64, i64, i64), _, _>([], |row| {
-            Ok((row.get(0)?, row.get(1)?, row.get(2)?, row.get(3)?))
-        })?;
-
-        println!("Grant table rows:");
-        for r in rows {
-            let (id, gt, ki, av) = r.unwrap();
-            println!("    id: {} grantee: {} key_id: {} access_vector: {}", id, gt, ki, av);
-        }
-        Ok(())
-    }
-
-    // Use a custom random number generator that repeats each number once.
-    // This allows us to test repeated elements.
-
-    thread_local! {
-        static RANDOM_COUNTER: RefCell<i64> = const { RefCell::new(0) };
-    }
-
-    fn reset_random() {
-        RANDOM_COUNTER.with(|counter| {
-            *counter.borrow_mut() = 0;
-        })
-    }
-
-    pub fn random() -> i64 {
-        RANDOM_COUNTER.with(|counter| {
-            let result = *counter.borrow() / 2;
-            *counter.borrow_mut() += 1;
-            result
-        })
-    }
-
-    #[test]
-    fn test_unbind_keys_for_user() -> Result<()> {
-        let mut db = new_test_db()?;
-        db.unbind_keys_for_user(1)?;
-
-        make_test_key_entry(&mut db, Domain::APP, 210000, TEST_ALIAS, None)?;
-        make_test_key_entry(&mut db, Domain::APP, 110000, TEST_ALIAS, None)?;
-        db.unbind_keys_for_user(2)?;
-
-        assert_eq!(1, db.list_past_alias(Domain::APP, 110000, KeyType::Client, None)?.len());
-        assert_eq!(0, db.list_past_alias(Domain::APP, 210000, KeyType::Client, None)?.len());
-
-        db.unbind_keys_for_user(1)?;
-        assert_eq!(0, db.list_past_alias(Domain::APP, 110000, KeyType::Client, None)?.len());
-
-        Ok(())
-    }
-
-    #[test]
-    fn test_unbind_keys_for_user_removes_superkeys() -> Result<()> {
-        let mut db = new_test_db()?;
-        let super_key = keystore2_crypto::generate_aes256_key()?;
-        let pw: keystore2_crypto::Password = (&b"xyzabc"[..]).into();
-        let (encrypted_super_key, metadata) =
-            SuperKeyManager::encrypt_with_password(&super_key, &pw)?;
-
-        let key_name_enc = SuperKeyType {
-            alias: "test_super_key_1",
-            algorithm: SuperEncryptionAlgorithm::Aes256Gcm,
-            name: "test_super_key_1",
-        };
-
-        let key_name_nonenc = SuperKeyType {
-            alias: "test_super_key_2",
-            algorithm: SuperEncryptionAlgorithm::Aes256Gcm,
-            name: "test_super_key_2",
-        };
-
-        // Install two super keys.
-        db.store_super_key(
-            1,
-            &key_name_nonenc,
-            &super_key,
-            &BlobMetaData::new(),
-            &KeyMetaData::new(),
-        )?;
-        db.store_super_key(1, &key_name_enc, &encrypted_super_key, &metadata, &KeyMetaData::new())?;
-
-        // Check that both can be found in the database.
-        assert!(db.load_super_key(&key_name_enc, 1)?.is_some());
-        assert!(db.load_super_key(&key_name_nonenc, 1)?.is_some());
-
-        // Install the same keys for a different user.
-        db.store_super_key(
-            2,
-            &key_name_nonenc,
-            &super_key,
-            &BlobMetaData::new(),
-            &KeyMetaData::new(),
-        )?;
-        db.store_super_key(2, &key_name_enc, &encrypted_super_key, &metadata, &KeyMetaData::new())?;
-
-        // Check that the second pair of keys can be found in the database.
-        assert!(db.load_super_key(&key_name_enc, 2)?.is_some());
-        assert!(db.load_super_key(&key_name_nonenc, 2)?.is_some());
-
-        // Delete all keys for user 1.
-        db.unbind_keys_for_user(1)?;
-
-        // All of user 1's keys should be gone.
-        assert!(db.load_super_key(&key_name_enc, 1)?.is_none());
-        assert!(db.load_super_key(&key_name_nonenc, 1)?.is_none());
-
-        // User 2's keys should not have been touched.
-        assert!(db.load_super_key(&key_name_enc, 2)?.is_some());
-        assert!(db.load_super_key(&key_name_nonenc, 2)?.is_some());
-
-        Ok(())
-    }
-
-    fn app_key_exists(db: &mut KeystoreDB, nspace: i64, alias: &str) -> Result<bool> {
-        db.key_exists(Domain::APP, nspace, alias, KeyType::Client)
-    }
-
-    // Tests the unbind_auth_bound_keys_for_user() function.
-    #[test]
-    fn test_unbind_auth_bound_keys_for_user() -> Result<()> {
-        let mut db = new_test_db()?;
-        let user_id = 1;
-        let nspace: i64 = (user_id * AID_USER_OFFSET).into();
-        let other_user_id = 2;
-        let other_user_nspace: i64 = (other_user_id * AID_USER_OFFSET).into();
-        let super_key_type = &USER_AFTER_FIRST_UNLOCK_SUPER_KEY;
-
-        // Create a superencryption key.
-        let super_key = keystore2_crypto::generate_aes256_key()?;
-        let pw: keystore2_crypto::Password = (&b"xyzabc"[..]).into();
-        let (encrypted_super_key, blob_metadata) =
-            SuperKeyManager::encrypt_with_password(&super_key, &pw)?;
-        db.store_super_key(
-            user_id,
-            super_key_type,
-            &encrypted_super_key,
-            &blob_metadata,
-            &KeyMetaData::new(),
-        )?;
-        let super_key_id = db.load_super_key(super_key_type, user_id)?.unwrap().0 .0;
-
-        // Store 4 superencrypted app keys, one for each possible combination of
-        // (authentication required, unlocked device required).
-        make_superencrypted_key_entry(&mut db, nspace, "noauth_noud", false, false, super_key_id)?;
-        make_superencrypted_key_entry(&mut db, nspace, "noauth_ud", false, true, super_key_id)?;
-        make_superencrypted_key_entry(&mut db, nspace, "auth_noud", true, false, super_key_id)?;
-        make_superencrypted_key_entry(&mut db, nspace, "auth_ud", true, true, super_key_id)?;
-        assert!(app_key_exists(&mut db, nspace, "noauth_noud")?);
-        assert!(app_key_exists(&mut db, nspace, "noauth_ud")?);
-        assert!(app_key_exists(&mut db, nspace, "auth_noud")?);
-        assert!(app_key_exists(&mut db, nspace, "auth_ud")?);
-
-        // Also store a key for a different user that requires authentication.
-        make_superencrypted_key_entry(
-            &mut db,
-            other_user_nspace,
-            "auth_ud",
-            true,
-            true,
-            super_key_id,
-        )?;
-
-        db.unbind_auth_bound_keys_for_user(user_id)?;
-
-        // Verify that only the user's app keys that require authentication were
-        // deleted. Keys that require an unlocked device but not authentication
-        // should *not* have been deleted, nor should the super key have been
-        // deleted, nor should other users' keys have been deleted.
-        assert!(db.load_super_key(super_key_type, user_id)?.is_some());
-        assert!(app_key_exists(&mut db, nspace, "noauth_noud")?);
-        assert!(app_key_exists(&mut db, nspace, "noauth_ud")?);
-        assert!(!app_key_exists(&mut db, nspace, "auth_noud")?);
-        assert!(!app_key_exists(&mut db, nspace, "auth_ud")?);
-        assert!(app_key_exists(&mut db, other_user_nspace, "auth_ud")?);
-
-        Ok(())
-    }
-
-    #[test]
-    fn test_store_super_key() -> Result<()> {
-        let mut db = new_test_db()?;
-        let pw: keystore2_crypto::Password = (&b"xyzabc"[..]).into();
-        let super_key = keystore2_crypto::generate_aes256_key()?;
-        let secret_bytes = b"keystore2 is great.";
-        let (encrypted_secret, iv, tag) =
-            keystore2_crypto::aes_gcm_encrypt(secret_bytes, &super_key)?;
-
-        let (encrypted_super_key, metadata) =
-            SuperKeyManager::encrypt_with_password(&super_key, &pw)?;
-        db.store_super_key(
-            1,
-            &USER_AFTER_FIRST_UNLOCK_SUPER_KEY,
-            &encrypted_super_key,
-            &metadata,
-            &KeyMetaData::new(),
-        )?;
-
-        // Check if super key exists.
-        assert!(db.key_exists(
-            Domain::APP,
-            1,
-            USER_AFTER_FIRST_UNLOCK_SUPER_KEY.alias,
-            KeyType::Super
-        )?);
-
-        let (_, key_entry) = db.load_super_key(&USER_AFTER_FIRST_UNLOCK_SUPER_KEY, 1)?.unwrap();
-        let loaded_super_key = SuperKeyManager::extract_super_key_from_key_entry(
-            USER_AFTER_FIRST_UNLOCK_SUPER_KEY.algorithm,
-            key_entry,
-            &pw,
-            None,
-        )?;
-
-        let decrypted_secret_bytes = loaded_super_key.decrypt(&encrypted_secret, &iv, &tag)?;
-        assert_eq!(secret_bytes, &*decrypted_secret_bytes);
-
-        Ok(())
-    }
-
-    fn get_valid_statsd_storage_types() -> Vec<MetricsStorage> {
-        vec![
-            MetricsStorage::KEY_ENTRY,
-            MetricsStorage::KEY_ENTRY_ID_INDEX,
-            MetricsStorage::KEY_ENTRY_DOMAIN_NAMESPACE_INDEX,
-            MetricsStorage::BLOB_ENTRY,
-            MetricsStorage::BLOB_ENTRY_KEY_ENTRY_ID_INDEX,
-            MetricsStorage::KEY_PARAMETER,
-            MetricsStorage::KEY_PARAMETER_KEY_ENTRY_ID_INDEX,
-            MetricsStorage::KEY_METADATA,
-            MetricsStorage::KEY_METADATA_KEY_ENTRY_ID_INDEX,
-            MetricsStorage::GRANT,
-            MetricsStorage::AUTH_TOKEN,
-            MetricsStorage::BLOB_METADATA,
-            MetricsStorage::BLOB_METADATA_BLOB_ENTRY_ID_INDEX,
-        ]
-    }
-
-    /// Perform a simple check to ensure that we can query all the storage types
-    /// that are supported by the DB. Check for reasonable values.
-    #[test]
-    fn test_query_all_valid_table_sizes() -> Result<()> {
-        const PAGE_SIZE: i32 = 4096;
-
-        let mut db = new_test_db()?;
-
-        for t in get_valid_statsd_storage_types() {
-            let stat = db.get_storage_stat(t)?;
-            // AuthToken can be less than a page since it's in a btree, not sqlite
-            // TODO(b/187474736) stop using if-let here
-            if let MetricsStorage::AUTH_TOKEN = t {
-            } else {
-                assert!(stat.size >= PAGE_SIZE);
-            }
-            assert!(stat.size >= stat.unused_size);
-        }
-
-        Ok(())
-    }
-
-    fn get_storage_stats_map(db: &mut KeystoreDB) -> BTreeMap<i32, StorageStats> {
-        get_valid_statsd_storage_types()
-            .into_iter()
-            .map(|t| (t.0, db.get_storage_stat(t).unwrap()))
-            .collect()
-    }
-
-    fn assert_storage_increased(
-        db: &mut KeystoreDB,
-        increased_storage_types: Vec<MetricsStorage>,
-        baseline: &mut BTreeMap<i32, StorageStats>,
-    ) {
-        for storage in increased_storage_types {
-            // Verify the expected storage increased.
-            let new = db.get_storage_stat(storage).unwrap();
-            let old = &baseline[&storage.0];
-            assert!(new.size >= old.size, "{}: {} >= {}", storage.0, new.size, old.size);
-            assert!(
-                new.unused_size <= old.unused_size,
-                "{}: {} <= {}",
-                storage.0,
-                new.unused_size,
-                old.unused_size
-            );
-
-            // Update the baseline with the new value so that it succeeds in the
-            // later comparison.
-            baseline.insert(storage.0, new);
-        }
-
-        // Get an updated map of the storage and verify there were no unexpected changes.
-        let updated_stats = get_storage_stats_map(db);
-        assert_eq!(updated_stats.len(), baseline.len());
-
-        for &k in baseline.keys() {
-            let stringify = |map: &BTreeMap<i32, StorageStats>| -> String {
-                let mut s = String::new();
-                for &k in map.keys() {
-                    writeln!(&mut s, "  {}: {}, {}", &k, map[&k].size, map[&k].unused_size)
-                        .expect("string concat failed");
-                }
-                s
-            };
-
-            assert!(
-                updated_stats[&k].size == baseline[&k].size
-                    && updated_stats[&k].unused_size == baseline[&k].unused_size,
-                "updated_stats:\n{}\nbaseline:\n{}",
-                stringify(&updated_stats),
-                stringify(baseline)
-            );
-        }
-    }
-
-    #[test]
-    fn test_verify_key_table_size_reporting() -> Result<()> {
-        let mut db = new_test_db()?;
-        let mut working_stats = get_storage_stats_map(&mut db);
-
-        let key_id = create_key_entry(&mut db, &Domain::APP, &42, KeyType::Client, &KEYSTORE_UUID)?;
-        assert_storage_increased(
-            &mut db,
-            vec![
-                MetricsStorage::KEY_ENTRY,
-                MetricsStorage::KEY_ENTRY_ID_INDEX,
-                MetricsStorage::KEY_ENTRY_DOMAIN_NAMESPACE_INDEX,
-            ],
-            &mut working_stats,
-        );
-
-        let mut blob_metadata = BlobMetaData::new();
-        blob_metadata.add(BlobMetaEntry::EncryptedBy(EncryptedBy::Password));
-        db.set_blob(&key_id, SubComponentType::KEY_BLOB, Some(TEST_KEY_BLOB), None)?;
-        assert_storage_increased(
-            &mut db,
-            vec![
-                MetricsStorage::BLOB_ENTRY,
-                MetricsStorage::BLOB_ENTRY_KEY_ENTRY_ID_INDEX,
-                MetricsStorage::BLOB_METADATA,
-                MetricsStorage::BLOB_METADATA_BLOB_ENTRY_ID_INDEX,
-            ],
-            &mut working_stats,
-        );
-
-        let params = make_test_params(None);
-        db.insert_keyparameter(&key_id, &params)?;
-        assert_storage_increased(
-            &mut db,
-            vec![MetricsStorage::KEY_PARAMETER, MetricsStorage::KEY_PARAMETER_KEY_ENTRY_ID_INDEX],
-            &mut working_stats,
-        );
-
-        let mut metadata = KeyMetaData::new();
-        metadata.add(KeyMetaEntry::CreationDate(DateTime::from_millis_epoch(123456789)));
-        db.insert_key_metadata(&key_id, &metadata)?;
-        assert_storage_increased(
-            &mut db,
-            vec![MetricsStorage::KEY_METADATA, MetricsStorage::KEY_METADATA_KEY_ENTRY_ID_INDEX],
-            &mut working_stats,
-        );
-
-        let mut sum = 0;
-        for stat in working_stats.values() {
-            sum += stat.size;
-        }
-        let total = db.get_storage_stat(MetricsStorage::DATABASE)?.size;
-        assert!(sum <= total, "Expected sum <= total. sum: {}, total: {}", sum, total);
-
-        Ok(())
-    }
-
-    #[test]
-    fn test_verify_auth_table_size_reporting() -> Result<()> {
-        let mut db = new_test_db()?;
-        let mut working_stats = get_storage_stats_map(&mut db);
-        db.insert_auth_token(&HardwareAuthToken {
-            challenge: 123,
-            userId: 456,
-            authenticatorId: 789,
-            authenticatorType: kmhw_authenticator_type::ANY,
-            timestamp: Timestamp { milliSeconds: 10 },
-            mac: b"mac".to_vec(),
-        });
-        assert_storage_increased(&mut db, vec![MetricsStorage::AUTH_TOKEN], &mut working_stats);
-        Ok(())
-    }
-
-    #[test]
-    fn test_verify_grant_table_size_reporting() -> Result<()> {
-        const OWNER: i64 = 1;
-        let mut db = new_test_db()?;
-        make_test_key_entry(&mut db, Domain::APP, OWNER, TEST_ALIAS, None)?;
-
-        let mut working_stats = get_storage_stats_map(&mut db);
-        db.grant(
-            &KeyDescriptor {
-                domain: Domain::APP,
-                nspace: 0,
-                alias: Some(TEST_ALIAS.to_string()),
-                blob: None,
-            },
-            OWNER as u32,
-            123,
-            key_perm_set![KeyPerm::Use],
-            |_, _| Ok(()),
-        )?;
-
-        assert_storage_increased(&mut db, vec![MetricsStorage::GRANT], &mut working_stats);
-
-        Ok(())
-    }
-
-    #[test]
-    fn find_auth_token_entry_returns_latest() -> Result<()> {
-        let mut db = new_test_db()?;
-        db.insert_auth_token(&HardwareAuthToken {
-            challenge: 123,
-            userId: 456,
-            authenticatorId: 789,
-            authenticatorType: kmhw_authenticator_type::ANY,
-            timestamp: Timestamp { milliSeconds: 10 },
-            mac: b"mac0".to_vec(),
-        });
-        std::thread::sleep(std::time::Duration::from_millis(1));
-        db.insert_auth_token(&HardwareAuthToken {
-            challenge: 123,
-            userId: 457,
-            authenticatorId: 789,
-            authenticatorType: kmhw_authenticator_type::ANY,
-            timestamp: Timestamp { milliSeconds: 12 },
-            mac: b"mac1".to_vec(),
-        });
-        std::thread::sleep(std::time::Duration::from_millis(1));
-        db.insert_auth_token(&HardwareAuthToken {
-            challenge: 123,
-            userId: 458,
-            authenticatorId: 789,
-            authenticatorType: kmhw_authenticator_type::ANY,
-            timestamp: Timestamp { milliSeconds: 3 },
-            mac: b"mac2".to_vec(),
-        });
-        // All three entries are in the database
-        assert_eq!(db.perboot.auth_tokens_len(), 3);
-        // It selected the most recent timestamp
-        assert_eq!(db.find_auth_token_entry(|_| true).unwrap().auth_token.mac, b"mac2".to_vec());
-        Ok(())
-    }
-
-    #[test]
-    fn test_load_key_descriptor() -> Result<()> {
-        let mut db = new_test_db()?;
-        let key_id = make_test_key_entry(&mut db, Domain::APP, 1, TEST_ALIAS, None)?.0;
-
-        let key = db.load_key_descriptor(key_id)?.unwrap();
-
-        assert_eq!(key.domain, Domain::APP);
-        assert_eq!(key.nspace, 1);
-        assert_eq!(key.alias, Some(TEST_ALIAS.to_string()));
-
-        // No such id
-        assert_eq!(db.load_key_descriptor(key_id + 1)?, None);
-        Ok(())
-    }
-
-    #[test]
-    fn test_get_list_app_uids_for_sid() -> Result<()> {
-        let uid: i32 = 1;
-        let uid_offset: i64 = (uid as i64) * (AID_USER_OFFSET as i64);
-        let first_sid = 667;
-        let second_sid = 669;
-        let first_app_id: i64 = 123 + uid_offset;
-        let second_app_id: i64 = 456 + uid_offset;
-        let third_app_id: i64 = 789 + uid_offset;
-        let unrelated_app_id: i64 = 1011 + uid_offset;
-        let mut db = new_test_db()?;
-        make_test_key_entry_with_sids(
-            &mut db,
-            Domain::APP,
-            first_app_id,
-            TEST_ALIAS,
-            None,
-            &[first_sid],
-        )
-        .context("test_get_list_app_uids_for_sid")?;
-        make_test_key_entry_with_sids(
-            &mut db,
-            Domain::APP,
-            second_app_id,
-            "alias2",
-            None,
-            &[first_sid],
-        )
-        .context("test_get_list_app_uids_for_sid")?;
-        make_test_key_entry_with_sids(
-            &mut db,
-            Domain::APP,
-            second_app_id,
-            TEST_ALIAS,
-            None,
-            &[second_sid],
-        )
-        .context("test_get_list_app_uids_for_sid")?;
-        make_test_key_entry_with_sids(
-            &mut db,
-            Domain::APP,
-            third_app_id,
-            "alias3",
-            None,
-            &[second_sid],
-        )
-        .context("test_get_list_app_uids_for_sid")?;
-        make_test_key_entry_with_sids(
-            &mut db,
-            Domain::APP,
-            unrelated_app_id,
-            TEST_ALIAS,
-            None,
-            &[],
-        )
-        .context("test_get_list_app_uids_for_sid")?;
-
-        let mut first_sid_apps = db.get_app_uids_affected_by_sid(uid, first_sid)?;
-        first_sid_apps.sort();
-        assert_eq!(first_sid_apps, vec![first_app_id, second_app_id]);
-        let mut second_sid_apps = db.get_app_uids_affected_by_sid(uid, second_sid)?;
-        second_sid_apps.sort();
-        assert_eq!(second_sid_apps, vec![second_app_id, third_app_id]);
-        Ok(())
-    }
-
-    #[test]
-    fn test_get_list_app_uids_with_multiple_sids() -> Result<()> {
-        let uid: i32 = 1;
-        let uid_offset: i64 = (uid as i64) * (AID_USER_OFFSET as i64);
-        let first_sid = 667;
-        let second_sid = 669;
-        let third_sid = 772;
-        let first_app_id: i64 = 123 + uid_offset;
-        let second_app_id: i64 = 456 + uid_offset;
-        let mut db = new_test_db()?;
-        make_test_key_entry_with_sids(
-            &mut db,
-            Domain::APP,
-            first_app_id,
-            TEST_ALIAS,
-            None,
-            &[first_sid, second_sid],
-        )
-        .context("test_get_list_app_uids_for_sid")?;
-        make_test_key_entry_with_sids(
-            &mut db,
-            Domain::APP,
-            second_app_id,
-            "alias2",
-            None,
-            &[second_sid, third_sid],
-        )
-        .context("test_get_list_app_uids_for_sid")?;
-
-        let first_sid_apps = db.get_app_uids_affected_by_sid(uid, first_sid)?;
-        assert_eq!(first_sid_apps, vec![first_app_id]);
-
-        let mut second_sid_apps = db.get_app_uids_affected_by_sid(uid, second_sid)?;
-        second_sid_apps.sort();
-        assert_eq!(second_sid_apps, vec![first_app_id, second_app_id]);
-
-        let third_sid_apps = db.get_app_uids_affected_by_sid(uid, third_sid)?;
-        assert_eq!(third_sid_apps, vec![second_app_id]);
-        Ok(())
-    }
-}
