Tests: Add garage integration tests #215
1 changed files with 8 additions and 5 deletions
|
@ -1,4 +1,3 @@
|
|||
use std::env::var_os;
|
||||
use std::mem::MaybeUninit;
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::process;
|
||||
|
@ -186,6 +185,8 @@ static INSTANCE_INIT: Once = Once::new();
|
|||
#[static_init::destructor]
|
||||
extern "C" fn terminate_instance() {
|
||||
if INSTANCE_INIT.is_completed() {
|
||||
KokaKiwi marked this conversation as resolved
Outdated
|
||||
// This block is sound as it depends on `INSTANCE_INIT` being completed, meaning `INSTANCE`
|
||||
// is actually initialized.
|
||||
unsafe {
|
||||
INSTANCE.assume_init_mut().terminate();
|
||||
}
|
||||
|
@ -200,15 +201,17 @@ pub fn instance() -> &'static Instance {
|
|||
INSTANCE.write(instance);
|
||||
});
|
||||
|
||||
KokaKiwi marked this conversation as resolved
Outdated
quentin
commented
Do you have any documentation explaining why Do you have any documentation explaining why `unsafe` is required in this function and the previous one?
KokaKiwi
commented
The unsafe blocks here are required because:
I'll add some changes here to document why these unsafe blocks are actually sound ("safe") The unsafe blocks here are required because:
1. `INSTANCE` is a mutable static, accessing/modifying is unsafe by definition: https://doc.rust-lang.org/nomicon/what-unsafe-does.html
2. `INSTANCE` is of `MaybeUninit<T>` type, accessing its value is unsafe it could be uninitialized at the time it's accessed: [`std::mem::MaybeUninit::assume_init_ref`](https://doc.rust-lang.org/std/mem/union.MaybeUninit.html#method.assume_init_ref) (see `Safety` section)
I'll add some changes here to document why these unsafe blocks are actually sound ("safe")
|
||||
// This block is sound as it depends on `INSTANCE_INIT` being completed by calling `call_once` (blocking),
|
||||
// meaning `INSTANCE` is actually initialized.
|
||||
unsafe { INSTANCE.assume_init_ref() }
|
||||
}
|
||||
|
||||
pub fn command(config_path: &Path) -> process::Command {
|
||||
use std::env;
|
||||
|
||||
let mut command = process::Command::new(
|
||||
var_os("GARAGE_TEST_INTEGRATION_EXE")
|
||||
.as_ref()
|
||||
.and_then(|e| e.to_str())
|
||||
.unwrap_or(env!("CARGO_BIN_EXE_garage")),
|
||||
env::var("GARAGE_TEST_INTEGRATION_EXE")
|
||||
.unwrap_or_else(|_| env!("CARGO_BIN_EXE_garage").to_owned()),
|
||||
);
|
||||
|
||||
command.arg("-c").arg(config_path);
|
||||
|
|
Loading…
Reference in a new issue
Why do you need
extern "C"
here?It's required by the
static_init::destructor
attribute, as it register the function to be called by libc global ctor/dtor stuff