Skip to content

Commit

Permalink
[π˜€π—½π—Ώ] initial version
Browse files Browse the repository at this point in the history
Created using spr 1.3.4
  • Loading branch information
sunshowers committed Oct 5, 2023
1 parent a9104a0 commit 4d670aa
Show file tree
Hide file tree
Showing 9 changed files with 168 additions and 117 deletions.
3 changes: 2 additions & 1 deletion .config/nextest.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,5 @@ setup = 'crdb-seed'
fail-fast = false

[script.crdb-seed]
command = 'cargo run -p crdb-seed'
# --profile test means more build artifacts get reused from tests
command = 'cargo run --profile dev -p crdb-seed'
22 changes: 20 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,7 @@ assert_matches = "1.5.0"
assert_cmd = "2.0.12"
async-bb8-diesel = { git = "https://github.com/oxidecomputer/async-bb8-diesel", rev = "da04c087f835a51e0441addb19c5ef4986e1fcf2" }
async-trait = "0.1.73"
atomicwrites = "0.4.1"
authz-macros = { path = "nexus/authz-macros" }
backoff = { version = "0.4.0", features = [ "tokio" ] }
base64 = "0.21.4"
Expand Down
3 changes: 3 additions & 0 deletions crdb-seed/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,15 @@ edition = "2021"
license = "MPL-2.0"

[dependencies]
atomicwrites.workspace = true
anyhow.workspace = true
camino.workspace = true
camino-tempfile.workspace = true
dropshot.workspace = true
hex.workspace = true
omicron-test-utils.workspace = true
ring.workspace = true
slog.workspace = true
tar.workspace = true
tokio.workspace = true
omicron-workspace-hack.workspace = true
58 changes: 25 additions & 33 deletions crdb-seed/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use anyhow::{Context, Result};
use camino::Utf8PathBuf;
use dropshot::{test_util::LogContext, ConfigLogging, ConfigLoggingLevel};
use omicron_test_utils::dev;
Expand All @@ -18,75 +19,66 @@ fn digest_unique_to_schema() -> String {
hex::encode(digest.as_ref())
}

enum SeedDirectoryStatus {
enum SeedTarballStatus {
Created,
Existing,
}

async fn ensure_seed_directory_exists(
async fn ensure_seed_tarball_exists(
log: &Logger,
) -> (Utf8PathBuf, SeedDirectoryStatus) {
) -> Result<(Utf8PathBuf, SeedTarballStatus)> {
let base_seed_dir = Utf8PathBuf::from_path_buf(std::env::temp_dir())
.expect("Not a UTF-8 path")
.join("crdb-base");
std::fs::create_dir_all(&base_seed_dir).unwrap();
let desired_seed_dir = base_seed_dir.join(digest_unique_to_schema());
let mut desired_seed_tar = base_seed_dir.join(digest_unique_to_schema());
desired_seed_tar.set_extension("tar");

if desired_seed_dir.exists() {
return (desired_seed_dir, SeedDirectoryStatus::Existing);
if desired_seed_tar.exists() {
return Ok((desired_seed_tar, SeedTarballStatus::Existing));
}

// The directory didn't exist when we started, so try to create it.
// The tarball didn't exist when we started, so try to create it.
//
// Nextest will execute it just once, but it is possible for a user to start
// up multiple nextest processes to be running at the same time. So we
// should consider it possible for another caller to create this seed
// directory before we finish setting it up ourselves.
let tmp_seed_dir =
camino_tempfile::Utf8TempDir::new_in(base_seed_dir).unwrap();
dev::test_setup_database_seed(log, tmp_seed_dir.path()).await;
// tarball before we finish setting it up ourselves.
dev::test_setup_database_seed(log, &desired_seed_tar)
.await
.context("failed to setup seed tarball")?;

// If we can successfully perform the rename, there was either no
// contention or we won a creation race.
//
// If we couldn't perform the rename, the directory might already exist.
// Check that this is the error we encountered -- otherwise, we're
// struggling.
if let Err(err) = std::fs::rename(tmp_seed_dir.path(), &desired_seed_dir) {
if !desired_seed_dir.exists() {
panic!("Cannot rename seed directory for CockroachDB: {err}");
}
}

(desired_seed_dir, SeedDirectoryStatus::Created)
Ok((desired_seed_tar, SeedTarballStatus::Created))
}

#[tokio::main]
async fn main() {
async fn main() -> Result<()> {
// TODO: dropshot is v heavyweight for this, we should be able to pull in a
// smaller binary
let logctx = LogContext::new(
"crdb_seeding",
&ConfigLogging::StderrTerminal { level: ConfigLoggingLevel::Info },
);
let (dir, status) = ensure_seed_directory_exists(&logctx.log).await;
let (tarball, status) = ensure_seed_tarball_exists(&logctx.log).await?;
match status {
SeedDirectoryStatus::Created => {
slog::info!(logctx.log, "Created seed directory: `{dir}`");
SeedTarballStatus::Created => {
slog::info!(logctx.log, "Created seed tarball: `{tarball}`");
}
SeedDirectoryStatus::Existing => {
slog::info!(logctx.log, "Using existing seed directory: `{dir}`");
SeedTarballStatus::Existing => {
slog::info!(logctx.log, "Using existing seed tarball: `{tarball}`");
}
}
if let Ok(env_path) = std::env::var("NEXTEST_ENV") {
let mut file = std::fs::File::create(&env_path)
.expect("failed to open NEXTEST_ENV file");
writeln!(file, "CRDB_SEED_DIR={dir}")
.expect("failed to write to NEXTEST_ENV file");
.context("failed to open NEXTEST_ENV file")?;
writeln!(file, "CRDB_SEED_TAR={tarball}")
.context("failed to write to NEXTEST_ENV file")?;
} else {
slog::warn!(
logctx.log,
"NEXTEST_ENV not set (is this script running under nextest?)"
);
}

Ok(())
}
12 changes: 6 additions & 6 deletions nexus/test-utils/src/db.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,28 +8,28 @@ use camino::Utf8PathBuf;
use omicron_test_utils::dev;
use slog::Logger;

/// Path to the "seed" CockroachDB directory.
/// Path to the "seed" CockroachDB tarball.
///
/// Populating CockroachDB unfortunately isn't free - creation of
/// tables, indices, and users takes several seconds to complete.
///
/// By creating a "seed" version of the database, we can cut down
/// on the time spent performing this operation. Instead, we opt
/// to copy the database from this seed location.
fn seed_dir() -> Utf8PathBuf {
fn seed_tar() -> Utf8PathBuf {
// The setup script should set this environment variable.
let seed_dir = std::env::var("CRDB_SEED_DIR")
.expect("CRDB_SEED_DIR missing -- are you running this test with `cargo nextest run`?");
let seed_dir = std::env::var("CRDB_SEED_TAR")
.expect("CRDB_SEED_TAR missing -- are you running this test with `cargo nextest run`?");
seed_dir.into()
}

/// Wrapper around [`dev::test_setup_database`] which uses a a
/// seed directory provided at build-time.
pub async fn test_setup_database(log: &Logger) -> dev::db::CockroachInstance {
let dir = seed_dir();
let input_tar = seed_tar();
dev::test_setup_database(
log,
dev::StorageSource::CopyFromSeed { input_dir: dir },
dev::StorageSource::CopyFromSeed { input_tar },
)
.await
}
Expand Down
3 changes: 3 additions & 0 deletions test-utils/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@ license = "MPL-2.0"

[dependencies]
anyhow.workspace = true
atomicwrites.workspace = true
camino.workspace = true
camino-tempfile.workspace = true
dropshot.workspace = true
futures.workspace = true
headers.workspace = true
Expand All @@ -19,6 +21,7 @@ slog.workspace = true
subprocess.workspace = true
tempfile.workspace = true
thiserror.workspace = true
tar.workspace = true
tokio = { workspace = true, features = [ "full" ] }
tokio-postgres.workspace = true
usdt.workspace = true
Expand Down
Loading

0 comments on commit 4d670aa

Please sign in to comment.