Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/Firefox/third_party/rust/rkv/tests/   (Firefox Browser Version 136.0.1©)  Datei vom 10.2.2025 mit Größe 14 kB image not shown  

Impressum manager.rs

  Sprache: Rust
 

// Copyright 2018-2019 Mozilla
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use
// this file except in compliance with the License. You may obtain a copy of the
// License at http://www.apache.org/licenses/LICENSE-2.0
// Unless required by applicable law or agreed to in writing, software distributed
// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
// specific language governing permissions and limitations under the License.

use std::{fs, sync::Arc};

use tempfile::Builder;

#[cfg(feature = "lmdb")]
use rkv::backend::{Lmdb, LmdbEnvironment};
use rkv::{
    backend::{BackendEnvironmentBuilder, RecoveryStrategy, SafeMode, SafeModeEnvironment},
    CloseOptions, Rkv, StoreOptions, Value,
};

/// Test that a manager can be created with simple type inference.
#[cfg(feature = "lmdb")]
#[test]
#[allow(clippy::let_underscore_lock)]
fn test_simple() {
    type Manager = rkv::Manager<LmdbEnvironment>;

    let _unused = Manager::singleton().write().unwrap();
}

/// Test that a manager can be created with simple type inference.
#[test]
#[allow(clippy::let_underscore_lock)]
fn test_simple_safe() {
    type Manager = rkv::Manager<SafeModeEnvironment>;

    let _unused = Manager::singleton().write().unwrap();
}

/// Test that a shared Rkv instance can be created with simple type inference.
#[cfg(feature = "lmdb")]
#[test]
fn test_simple_2() {
    type Manager = rkv::Manager<LmdbEnvironment>;

    let root = Builder::new()
        .prefix("test_simple_2")
        .tempdir()
        .expect("tempdir");
    fs::create_dir_all(root.path()).expect("dir created");

    let mut manager = Manager::singleton().write().unwrap();
    let _ = manager
        .get_or_create(root.path(), Rkv::new::<Lmdb>)
        .unwrap();
}

/// Test that a shared Rkv instance can be created with simple type inference.
#[test]
fn test_simple_safe_2() {
    type Manager = rkv::Manager<SafeModeEnvironment>;

    let root = Builder::new()
        .prefix("test_simple_safe_2")
        .tempdir()
        .expect("tempdir");
    fs::create_dir_all(root.path()).expect("dir created");

    let mut manager = Manager::singleton().write().unwrap();
    let _ = manager
        .get_or_create(root.path(), Rkv::new::<SafeMode>)
        .unwrap();
}

/// Test that the manager will return the same Rkv instance each time for each path.
#[cfg(feature = "lmdb")]
#[test]
fn test_same() {
    type Manager = rkv::Manager<LmdbEnvironment>;

    let root = Builder::new()
        .prefix("test_same")
        .tempdir()
        .expect("tempdir");
    fs::create_dir_all(root.path()).expect("dir created");

    let p = root.path();
    assert!(Manager::singleton()
        .read()
        .unwrap()
        .get(p)
        .expect("success")
        .is_none());

    let created_arc = Manager::singleton()
        .write()
        .unwrap()
        .get_or_create(p, Rkv::new::<Lmdb>)
        .expect("created");
    let fetched_arc = Manager::singleton()
        .read()
        .unwrap()
        .get(p)
        .expect("success")
        .expect("existed");
    assert!(Arc::ptr_eq(&created_arc, &fetched_arc));
}

/// Test that the manager will return the same Rkv instance each time for each path.
#[test]
fn test_same_safe() {
    type Manager = rkv::Manager<SafeModeEnvironment>;

    let root = Builder::new()
        .prefix("test_same_safe")
        .tempdir()
        .expect("tempdir");
    fs::create_dir_all(root.path()).expect("dir created");

    let p = root.path();
    assert!(Manager::singleton()
        .read()
        .unwrap()
        .get(p)
        .expect("success")
        .is_none());

    let created_arc = Manager::singleton()
        .write()
        .unwrap()
        .get_or_create(p, Rkv::new::<SafeMode>)
        .expect("created");
    let fetched_arc = Manager::singleton()
        .read()
        .unwrap()
        .get(p)
        .expect("success")
        .expect("existed");
    assert!(Arc::ptr_eq(&created_arc, &fetched_arc));
}

/// Test that the manager will return the same Rkv instance each time for each path.
#[cfg(feature = "lmdb")]
#[test]
fn test_same_with_capacity() {
    type Manager = rkv::Manager<LmdbEnvironment>;

    let root = Builder::new()
        .prefix("test_same_with_capacity")
        .tempdir()
        .expect("tempdir");
    fs::create_dir_all(root.path()).expect("dir created");

    let mut manager = Manager::singleton().write().unwrap();

    let p = root.path();
    assert!(manager.get(p).expect("success").is_none());

    let created_arc = manager
        .get_or_create_with_capacity(p, 10, Rkv::with_capacity::<Lmdb>)
        .expect("created");
    let fetched_arc = manager.get(p).expect("success").expect("existed");
    assert!(Arc::ptr_eq(&created_arc, &fetched_arc));
}

/// Test that the manager will return the same Rkv instance each time for each path.
#[test]
fn test_same_with_capacity_safe() {
    type Manager = rkv::Manager<SafeModeEnvironment>;

    let root = Builder::new()
        .prefix("test_same_with_capacity_safe")
        .tempdir()
        .expect("tempdir");
    fs::create_dir_all(root.path()).expect("dir created");

    let mut manager = Manager::singleton().write().unwrap();

    let p = root.path();
    assert!(manager.get(p).expect("success").is_none());

    let created_arc = manager
        .get_or_create_with_capacity(p, 10, Rkv::with_capacity::<SafeMode>)
        .expect("created");
    let fetched_arc = manager.get(p).expect("success").expect("existed");
    assert!(Arc::ptr_eq(&created_arc, &fetched_arc));
}

/// Some storage drivers are able to discard when the database is corrupted at runtime.
/// Test how these managers can discard corrupted databases and re-open.
#[test]
fn test_safe_mode_corrupt_while_open_1() {
    type Manager = rkv::Manager<SafeModeEnvironment>;

    let root = Builder::new()
        .prefix("test_safe_mode_corrupt_while_open_1")
        .tempdir()
        .expect("tempdir");
    fs::create_dir_all(root.path()).expect("dir created");

    // Create environment.
    let mut manager = Manager::singleton().write().unwrap();
    let shared_env = manager
        .get_or_create(root.path(), Rkv::new::<SafeMode>)
        .expect("created");
    let env = shared_env.read().unwrap();

    // Write some data.
    let store = env
        .open_single("store", StoreOptions::create())
        .expect("opened");
    let mut writer = env.write().expect("writer");
    store
        .put(&mut writer, "foo", &Value::I64(1234))
        .expect("wrote");
    store
        .put(&mut writer, "bar", &Value::Bool(true))
        .expect("wrote");
    store
        .put(&mut writer, "baz", &Value::Str("héllo, yöu"))
        .expect("wrote");
    writer.commit().expect("committed");
    env.sync(true).expect("synced");

    // Verify it was flushed to disk.
    let mut safebin = root.path().to_path_buf();
    safebin.push("data.safe.bin");
    assert!(safebin.exists());

    // Oops, corruption.
    fs::write(&safebin, "bogus").expect("dbfile corrupted");

    // Close everything.
    drop(env);
    drop(shared_env);
    manager
        .try_close(root.path(), CloseOptions::default())
        .expect("closed without deleting");
    assert!(manager.get(root.path()).expect("success").is_none());

    // Recreating environment fails.
    manager
        .get_or_create(root.path(), Rkv::new::<SafeMode>)
        .expect_err("not created");
    assert!(manager.get(root.path()).expect("success").is_none());

    // But we can use a builder and pass `discard_if_corrupted` to deal with it.
    let mut builder = Rkv::environment_builder::<SafeMode>();
    builder.set_corruption_recovery_strategy(RecoveryStrategy::Discard);
    manager
        .get_or_create_from_builder(root.path(), builder, Rkv::from_builder::<SafeMode>)
        .expect("created");
    assert!(manager.get(root.path()).expect("success").is_some());
}

/// Some storage drivers are able to recover when the database is corrupted at runtime.
/// Test how these managers can recover corrupted databases while open.
#[test]
fn test_safe_mode_corrupt_while_open_2() {
    type Manager = rkv::Manager<SafeModeEnvironment>;

    let root = Builder::new()
        .prefix("test_safe_mode_corrupt_while_open_2")
        .tempdir()
        .expect("tempdir");
    fs::create_dir_all(root.path()).expect("dir created");

    // Create environment.
    let mut manager = Manager::singleton().write().unwrap();
    let shared_env = manager
        .get_or_create(root.path(), Rkv::new::<SafeMode>)
        .expect("created");
    let env = shared_env.read().unwrap();

    // Write some data.
    let store = env
        .open_single("store", StoreOptions::create())
        .expect("opened");
    let mut writer = env.write().expect("writer");
    store
        .put(&mut writer, "foo", &Value::I64(1234))
        .expect("wrote");
    store
        .put(&mut writer, "bar", &Value::Bool(true))
        .expect("wrote");
    store
        .put(&mut writer, "baz", &Value::Str("héllo, yöu"))
        .expect("wrote");
    writer.commit().expect("committed");
    env.sync(true).expect("synced");

    // Verify it was flushed to disk.
    let mut safebin = root.path().to_path_buf();
    safebin.push("data.safe.bin");
    assert!(safebin.exists());

    // Oops, corruption.
    fs::write(&safebin, "bogus").expect("dbfile corrupted");

    // Reading still works. Magic.
    let store = env
        .open_single("store", StoreOptions::default())
        .expect("opened");
    let reader = env.read().expect("reader");
    assert_eq!(
        store.get(&reader, "foo").expect("read"),
        Some(Value::I64(1234))
    );
    assert_eq!(
        store.get(&reader, "bar").expect("read"),
        Some(Value::Bool(true))
    );
    assert_eq!(
        store.get(&reader, "baz").expect("read"),
        Some(Value::Str("héllo, yöu"))
    );
    reader.abort();

    // Writing still works, dbfile will be un-corrupted.
    let store = env
        .open_single("store", StoreOptions::default())
        .expect("opened");
    let mut writer = env.write().expect("writer");
    store
        .put(&mut writer, "foo2", &Value::I64(5678))
        .expect("wrote");
    store
        .put(&mut writer, "bar2", &Value::Bool(false))
        .expect("wrote");
    store
        .put(&mut writer, "baz2", &Value::Str("byé, yöu"))
        .expect("wrote");
    writer.commit().expect("committed");
    env.sync(true).expect("synced");

    // Close everything.
    drop(env);
    drop(shared_env);
    manager
        .try_close(root.path(), CloseOptions::default())
        .expect("closed without deleting");
    assert!(manager.get(root.path()).expect("success").is_none());

    // Recreate environment.
    let shared_env = manager
        .get_or_create(root.path(), Rkv::new::<SafeMode>)
        .expect("created");
    let env = shared_env.read().unwrap();

    // Verify that the dbfile is not corrupted.
    let store = env
        .open_single("store", StoreOptions::default())
        .expect("opened");
    let reader = env.read().expect("reader");
    assert_eq!(
        store.get(&reader, "foo").expect("read"),
        Some(Value::I64(1234))
    );
    assert_eq!(
        store.get(&reader, "bar").expect("read"),
        Some(Value::Bool(true))
    );
    assert_eq!(
        store.get(&reader, "baz").expect("read"),
        Some(Value::Str("héllo, yöu"))
    );
    assert_eq!(
        store.get(&reader, "foo2").expect("read"),
        Some(Value::I64(5678))
    );
    assert_eq!(
        store.get(&reader, "bar2").expect("read"),
        Some(Value::Bool(false))
    );
    assert_eq!(
        store.get(&reader, "baz2").expect("read"),
        Some(Value::Str("byé, yöu"))
    );
}

/// Test how the manager can discard corrupted databases, while moving the corrupted one aside for
/// later inspection.
#[test]
fn test_safe_mode_corrupt_while_open_3() {
    type Manager = rkv::Manager<SafeModeEnvironment>;

    let root = Builder::new()
        .prefix("test_safe_mode_corrupt_while_open_3")
        .tempdir()
        .expect("tempdir");
    fs::create_dir_all(root.path()).expect("dir created");

    let mut safebin = root.path().to_path_buf();
    safebin.push("data.safe.bin");

    // Oops, corruption.
    fs::write(&safebin, "bogus").expect("dbfile corrupted");
    assert!(safebin.exists(), "Corrupted database file was written to");

    // Create environment.
    let mut manager = Manager::singleton().write().unwrap();

    // Recreating environment fails.
    manager
        .get_or_create(root.path(), Rkv::new::<SafeMode>)
        .expect_err("not created");
    assert!(manager.get(root.path()).expect("success").is_none());

    // But we can use a builder and pass `RecoveryStrategy::Rename` to deal with it.
    let mut builder = Rkv::environment_builder::<SafeMode>();
    builder.set_corruption_recovery_strategy(RecoveryStrategy::Rename);
    manager
        .get_or_create_from_builder(root.path(), builder, Rkv::from_builder::<SafeMode>)
        .expect("created");
    assert!(manager.get(root.path()).expect("success").is_some());

    assert!(!safebin.exists(), "Database file was moved out of the way");

    let mut corruptbin = root.path().to_path_buf();
    corruptbin.push("data.safe.bin.corrupt");
    assert!(corruptbin.exists(), "Corrupted database file exists");

    let shared_env = manager
        .get_or_create(root.path(), Rkv::new::<SafeMode>)
        .expect("created");
    let env = shared_env.read().unwrap();

    // Writing still works.
    let store = env
        .open_single("store", StoreOptions::create())
        .expect("opened");

    let reader = env.read().expect("reader");
    assert_eq!(store.get(&reader, "foo").expect("read"), None, "Nothing to be read");

    // We can write.
    let mut writer = env.write().expect("writer");
    store
        .put(&mut writer, "foo", &Value::I64(5678))
        .expect("wrote");
    writer.commit().expect("committed");
    env.sync(true).expect("synced");

    assert!(safebin.exists(), "Database file exists");

    // Close everything.
    drop(env);
    drop(shared_env);
    manager
        .try_close(root.path(), CloseOptions::default())
        .expect("closed without deleting");
    assert!(manager.get(root.path()).expect("success").is_none());

    // Recreate environment.
    let shared_env = manager
        .get_or_create(root.path(), Rkv::new::<SafeMode>)
        .expect("created");
    let env = shared_env.read().unwrap();

    // Verify that the dbfile is not corrupted.
    let store = env
        .open_single("store", StoreOptions::default())
        .expect("opened");
    let reader = env.read().expect("reader");
    assert_eq!(
        store.get(&reader, "foo").expect("read"),
        Some(Value::I64(5678)),
        "Database contains expected value"
    );
}

Messung V0.5 in Prozent
C=81 H=99 G=90

¤ Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.0.20Bemerkung:  (vorverarbeitet am  2026-06-18) ¤

*Bot Zugriff






Wurzel

Suchen

PVS Prover

Isabelle Prover

NIST Cobol Testsuite

Cephes Mathematical Library

Vienna Development Method

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.