Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion nexus/benches/setup_benchmark.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

use criterion::{criterion_group, criterion_main, Criterion};
use dropshot::test_util::LogContext;
use nexus_test_utils::db::test_setup_database;
use omicron_test_utils::dev;

// This is the default wrapper around most Nexus integration tests.
Expand All @@ -19,7 +20,7 @@ async fn do_full_setup() {
async fn do_crdb_setup() {
let cfg = nexus_test_utils::load_test_config();
let logctx = LogContext::new("crdb_setup", &cfg.log);
let mut db = dev::test_setup_database(&logctx.log).await;
let mut db = test_setup_database(&logctx.log).await;
db.cleanup().await.unwrap();
}

Expand Down
5 changes: 3 additions & 2 deletions nexus/src/authz/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,7 @@ mod test {
use crate::authz::DATABASE;
use crate::authz::FLEET;
use crate::db::DataStore;
use nexus_test_utils::db::test_setup_database;
use omicron_test_utils::dev;
use std::sync::Arc;

Expand All @@ -144,7 +145,7 @@ mod test {
#[tokio::test]
async fn test_database() {
let logctx = dev::test_setup_log("test_database");
let mut db = dev::test_setup_database(&logctx.log).await;
let mut db = test_setup_database(&logctx.log).await;
let (opctx, datastore) =
crate::db::datastore::datastore_test(&logctx, &db).await;
let authz_privileged = authz_context_for_actor(
Expand Down Expand Up @@ -190,7 +191,7 @@ mod test {
#[tokio::test]
async fn test_organization() {
let logctx = dev::test_setup_log("test_organization");
let mut db = dev::test_setup_database(&logctx.log).await;
let mut db = test_setup_database(&logctx.log).await;
let (opctx, datastore) =
crate::db::datastore::datastore_test(&logctx, &db).await;

Expand Down
5 changes: 3 additions & 2 deletions nexus/src/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -341,14 +341,15 @@ mod test {
use crate::authn;
use crate::authz;
use authz::Action;
use nexus_test_utils::db::test_setup_database;
use omicron_common::api::external::Error;
use omicron_test_utils::dev;
use std::sync::Arc;

#[tokio::test]
async fn test_background_context() {
let logctx = dev::test_setup_log("test_background_context");
let mut db = dev::test_setup_database(&logctx.log).await;
let mut db = test_setup_database(&logctx.log).await;
let (_, datastore) =
crate::db::datastore::datastore_test(&logctx, &db).await;
let opctx = OpContext::for_background(
Expand Down Expand Up @@ -380,7 +381,7 @@ mod test {
#[tokio::test]
async fn test_test_context() {
let logctx = dev::test_setup_log("test_background_context");
let mut db = dev::test_setup_database(&logctx.log).await;
let mut db = test_setup_database(&logctx.log).await;
let (_, datastore) =
crate::db::datastore::datastore_test(&logctx, &db).await;
let opctx = OpContext::for_unit_tests(logctx.log.new(o!()), datastore);
Expand Down
5 changes: 3 additions & 2 deletions nexus/src/db/collection_insert.rs
Original file line number Diff line number Diff line change
Expand Up @@ -492,6 +492,7 @@ mod test {
use diesel::expression_methods::ExpressionMethods;
use diesel::pg::Pg;
use diesel::QueryDsl;
use nexus_test_utils::db::test_setup_database;
use omicron_test_utils::dev;

table! {
Expand Down Expand Up @@ -634,7 +635,7 @@ mod test {
#[tokio::test]
async fn test_collection_not_present() {
let logctx = dev::test_setup_log("test_collection_not_present");
let mut db = dev::test_setup_database(&logctx.log).await;
let mut db = test_setup_database(&logctx.log).await;
let cfg = db::Config { url: db.pg_config().clone() };
let pool = db::Pool::new(&cfg);

Expand Down Expand Up @@ -699,7 +700,7 @@ mod test {
#[tokio::test]
async fn test_collection_present() {
let logctx = dev::test_setup_log("test_collection_present");
let mut db = dev::test_setup_database(&logctx.log).await;
let mut db = test_setup_database(&logctx.log).await;
let cfg = db::Config { url: db.pg_config().clone() };
let pool = db::Pool::new(&cfg);

Expand Down
5 changes: 3 additions & 2 deletions nexus/src/db/datastore.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2353,14 +2353,15 @@ mod test {
use crate::db::model::{ConsoleSession, Organization, Project};
use crate::external_api::params;
use chrono::{Duration, Utc};
use nexus_test_utils::db::test_setup_database;
use omicron_common::api::external::{Error, IdentityMetadataCreateParams};
use omicron_test_utils::dev;
use uuid::Uuid;

#[tokio::test]
async fn test_project_creation() {
let logctx = dev::test_setup_log("test_project_creation");
let mut db = dev::test_setup_database(&logctx.log).await;
let mut db = test_setup_database(&logctx.log).await;
let (opctx, datastore) = datastore_test(&logctx, &db).await;
let organization = Organization::new(params::OrganizationCreate {
identity: IdentityMetadataCreateParams {
Expand Down Expand Up @@ -2393,7 +2394,7 @@ mod test {
#[tokio::test]
async fn test_session_methods() {
let logctx = dev::test_setup_log("test_session_methods");
let mut db = dev::test_setup_database(&logctx.log).await;
let mut db = test_setup_database(&logctx.log).await;
let (_, datastore) = datastore_test(&logctx, &db).await;
let token = "a_token".to_string();
let session = ConsoleSession {
Expand Down
9 changes: 5 additions & 4 deletions nexus/src/db/pagination.rs
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,7 @@ mod test {
use async_bb8_diesel::{AsyncRunQueryDsl, AsyncSimpleConnection};
use diesel::SelectableHelper;
use dropshot::PaginationOrder;
use nexus_test_utils::db::test_setup_database;
use omicron_common::api::external::DataPageParams;
use omicron_test_utils::dev;
use std::num::NonZeroU32;
Expand Down Expand Up @@ -241,7 +242,7 @@ mod test {
async fn test_paginated_single_column_ascending() {
let logctx =
dev::test_setup_log("test_paginated_single_column_ascending");
let mut db = dev::test_setup_database(&logctx.log).await;
let mut db = test_setup_database(&logctx.log).await;
let cfg = db::Config { url: db.pg_config().clone() };
let pool = db::Pool::new(&cfg);

Expand Down Expand Up @@ -276,7 +277,7 @@ mod test {
async fn test_paginated_single_column_descending() {
let logctx =
dev::test_setup_log("test_paginated_single_column_descending");
let mut db = dev::test_setup_database(&logctx.log).await;
let mut db = test_setup_database(&logctx.log).await;
let cfg = db::Config { url: db.pg_config().clone() };
let pool = db::Pool::new(&cfg);

Expand Down Expand Up @@ -311,7 +312,7 @@ mod test {
async fn test_paginated_multicolumn_ascending() {
let logctx =
dev::test_setup_log("test_paginated_multicolumn_ascending");
let mut db = dev::test_setup_database(&logctx.log).await;
let mut db = test_setup_database(&logctx.log).await;
let cfg = db::Config { url: db.pg_config().clone() };
let pool = db::Pool::new(&cfg);

Expand Down Expand Up @@ -365,7 +366,7 @@ mod test {
async fn test_paginated_multicolumn_descending() {
let logctx =
dev::test_setup_log("test_paginated_multicolumn_descending");
let mut db = dev::test_setup_database(&logctx.log).await;
let mut db = test_setup_database(&logctx.log).await;
let cfg = db::Config { url: db.pg_config().clone() };
let pool = db::Pool::new(&cfg);

Expand Down
3 changes: 2 additions & 1 deletion nexus/src/db/saga_recovery.rs
Original file line number Diff line number Diff line change
Expand Up @@ -333,6 +333,7 @@ mod test {
use crate::context::OpContext;
use crate::db::test_utils::UnpluggableCockroachDbSecStore;
use lazy_static::lazy_static;
use nexus_test_utils::db::test_setup_database;
use omicron_test_utils::dev;
use std::sync::atomic::{AtomicBool, AtomicU32, Ordering};
use steno::{
Expand Down Expand Up @@ -372,7 +373,7 @@ mod test {
async fn new_db(
log: &slog::Logger,
) -> (dev::db::CockroachInstance, Arc<db::DataStore>) {
let db = dev::test_setup_database(&log).await;
let db = test_setup_database(&log).await;
let cfg = crate::db::Config { url: db.pg_config().clone() };
let pool = Arc::new(db::Pool::new(&cfg));
let db_datastore = Arc::new(db::DataStore::new(Arc::clone(&pool)));
Expand Down
7 changes: 6 additions & 1 deletion nexus/test-utils/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@

use dropshot::{test_util::LogContext, ConfigLogging, ConfigLoggingLevel};
use omicron_test_utils::dev::test_setup_database_seed;
use std::env;
use std::path::Path;

// Creates a "pre-populated" CockroachDB storage directory, which
// subsequent tests can copy instead of creating themselves.
Expand All @@ -27,6 +29,9 @@ async fn main() {
&ConfigLogging::StderrTerminal { level: ConfigLoggingLevel::Info },
);

test_setup_database_seed(&logctx.log).await;
let seed =
Path::new(&env::var("OUT_DIR").expect("Missing output directory"))
.join("crdb-base");
test_setup_database_seed(&logctx.log, &seed).await;
logctx.cleanup_successful();
}
28 changes: 28 additions & 0 deletions nexus/test-utils/src/db.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at https://mozilla.org/MPL/2.0/.

//! Database testing facilities.

use omicron_test_utils::dev;
use slog::Logger;
use std::path::PathBuf;

/// Path to the "seed" CockroachDB directory.
///
/// 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() -> PathBuf {
PathBuf::from(concat!(env!("OUT_DIR"), "/crdb-base"))
}

/// 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();
dev::test_setup_database(log, &dir).await
}
3 changes: 2 additions & 1 deletion nexus/test-utils/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ use std::path::Path;
use std::time::Duration;
use uuid::Uuid;

pub mod db;
pub mod http_testing;
pub mod resource_helpers;

Expand Down Expand Up @@ -93,7 +94,7 @@ pub async fn test_setup_with_config(
let log = &logctx.log;

/* Start up CockroachDB. */
let database = dev::test_setup_database(log).await;
let database = db::test_setup_database(log).await;

/* Start ClickHouse database server. */
let clickhouse = dev::clickhouse::ClickHouseInstance::new(0).await.unwrap();
Expand Down
37 changes: 13 additions & 24 deletions test-utils/src/dev/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,19 +18,7 @@ use dropshot::ConfigLogging;
use dropshot::ConfigLoggingIfExists;
use dropshot::ConfigLoggingLevel;
use slog::Logger;
use std::path::{Path, PathBuf};

/// Path to the "seed" CockroachDB directory.
///
/// 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() -> PathBuf {
std::env::temp_dir().join("crdb-base")
}
use std::path::Path;

// Helper for copying all the files in one directory to another.
fn copy_dir(
Expand Down Expand Up @@ -96,11 +84,10 @@ enum StorageSource {
///
/// This is intended to optimize subsequent calls to [`test_setup_database`]
/// by reducing the latency of populating the storage directory.
pub async fn test_setup_database_seed(log: &Logger) {
let dir = seed_dir();
pub async fn test_setup_database_seed(log: &Logger, dir: &Path) {
let _ = std::fs::remove_dir_all(&dir);
std::fs::create_dir_all(&dir).unwrap();
let mut db = setup_database(log, Some(&dir), StorageSource::Populate).await;
let mut db = setup_database(log, dir, StorageSource::Populate).await;
db.cleanup().await.unwrap();

// See https://github.com/cockroachdb/cockroach/issues/74231 for context on
Expand All @@ -117,18 +104,21 @@ pub async fn test_setup_database_seed(log: &Logger) {
}

/// Set up a [`db::CockroachInstance`] for running tests.
pub async fn test_setup_database(log: &Logger) -> db::CockroachInstance {
setup_database(log, None, StorageSource::CopyFromSeed).await
pub async fn test_setup_database(
log: &Logger,
dir: &Path,
) -> db::CockroachInstance {
setup_database(log, dir, StorageSource::CopyFromSeed).await
}

async fn setup_database(
log: &Logger,
store_dir: Option<&Path>,
seed_dir: &Path,
storage_source: StorageSource,
) -> db::CockroachInstance {
let builder = db::CockroachStarterBuilder::new();
let mut builder = if let Some(store_dir) = store_dir {
builder.store_dir(store_dir)
let mut builder = if matches!(storage_source, StorageSource::Populate) {
builder.store_dir(seed_dir)
} else {
builder
};
Expand All @@ -143,12 +133,11 @@ async fn setup_database(
// If we're going to copy the storage directory from the seed,
// it is critical we do so before starting the DB.
if matches!(storage_source, StorageSource::CopyFromSeed) {
let seed = seed_dir();
info!(&log,
"cockroach: copying from seed directory ({}) to storage directory ({})",
seed.to_string_lossy(), starter.store_dir().to_string_lossy(),
seed_dir.to_string_lossy(), starter.store_dir().to_string_lossy(),
);
copy_dir(seed, starter.store_dir())
copy_dir(seed_dir, starter.store_dir())
.expect("Cannot copy storage from seed directory");
}

Expand Down