diff --git a/Cargo.toml b/Cargo.toml index 864a7fd5abaaf418d1ddc20e8e28b75f9847ace5..ad7aae3cc0007a24635e26eff87268dbc8c54562 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -85,6 +85,7 @@ tonic-build = "0.8.4" [dev-dependencies] mockito = "1.1.0" sea-orm = { version = "0.12.2", features = [ "mock"] } +testcontainers = "0.14.0" [[bin]] name = "client" diff --git a/scripts/db-migration.sh b/scripts/db-migration.sh new file mode 100644 index 0000000000000000000000000000000000000000..ac5c601621a8521eb40cd51331ba855e6cc9b368 --- /dev/null +++ b/scripts/db-migration.sh @@ -0,0 +1,27 @@ +#!/usr/bin/env bash + +if [[ ! -v DATABASE_HOST ]]; then + echo "DATABASE_HOST is not set" + exit 1 +elif [[ ! -v DATABASE_PORT ]]; then + echo "DATABASE_PORT is not set" + exit 1 +elif [[ ! -v DATABASE_USER ]]; then + echo "DATABASE_USER is not set" + exit 1 +elif [[ ! -v DATABASE_PASSWORD ]]; then + echo "DATABASE_PASSWORD is not set" + exit 1 +elif [[ ! -v DATABASE_NAME ]]; then + echo "DATABASE_NAME is not set" + exit 1 +elif [[ ! -d "/app/migrations" ]]; then + echo "/app/migrations folder is not exist" + exit 1 +fi + +export DATABASE_URL="mysql://${DATABASE_USER}:${DATABASE_PASSWORD}@${DATABASE_HOST}:${DATABASE_PORT}/${DATABASE_NAME}" + +cd /app/ || exit 1 +/app/bin/sqlx database create || exit 1 +/app/bin/sqlx migrate run || exit 1 diff --git a/scripts/initialize-database.sh b/scripts/initialize-database.sh index 08652bf232278a077121ae1347f657eed428199c..be7b001cb544d2e3e02483f8d47d81066afca326 100755 --- a/scripts/initialize-database.sh +++ b/scripts/initialize-database.sh @@ -28,37 +28,30 @@ function check-prerequisites { else echo -n "found mysql, " && mysql --version fi - echo "checking sqlx" - which sqlx >/dev/null 2>&1 - if [[ $? -ne 0 ]]; then - echo "sqlx not installed, please refer to https://github.com/launchbadge/sqlx/blob/main/sqlx-cli/README.md#enable-building-in-offline-mode-with-query for installing, exiting." - exit 1 - else - echo -n "found sqlx, " && sqlx --version - fi } function mysql-cluster-up { echo "running up mysql local cluster" docker rm signatrust-database --force docker run --name signatrust-database --rm -p 3306:3306 -e MYSQL_DATABASE=${MYSQL_DATABASE} -e MYSQL_PASSWORD=${MYSQL_PASSWORD} -e MYSQL_USER=${MYSQL_USER} -e MYSQL_ROOT_PASSWORD=root -d ${MYSQL_IMAGE} - echo "mysql is running up with ip address $(docker inspect -f '{{range.NetworkSettings.Networks}}{{.IPAddress}}{{end}}' signatrust-database)" + echo "waiting mysql to be ready" while ! mysql --user=${MYSQL_USER} --password=${MYSQL_PASSWORD} --host=127.0.0.1 -e "select 1;"; do sleep 3 done echo "mysql is ready" + DATABASE_NETWORK_IP=$(docker inspect -f '{{range.NetworkSettings.Networks}}{{.IPAddress}}{{end}}' signatrust-database) + echo "mysql is running up with ip address $DATABASE_NETWORK_IP" echo "Please use command mysql --user=${MYSQL_USER} --password=${MYSQL_PASSWORD} --host=127.0.0.1 to query database" } function prepare-database { echo "running database migrations" export DATABASE_URL=mysql://${MYSQL_USER}:${MYSQL_PASSWORD}@127.0.0.1/${MYSQL_DATABASE} - sqlx database create - sqlx migrate run + docker run --name signatrust-database-migration --rm -v ./migrations/:/app/migrations/ -e DATABASE_HOST="$DATABASE_NETWORK_IP" -e DATABASE_PORT=3306 -e DATABASE_USER=$MYSQL_USER -e DATABASE_PASSWORD=$MYSQL_PASSWORD -e DATABASE_NAME=$MYSQL_DATABASE -it --entrypoint /app/run_migrations.sh tommylike/sqlx-cli:0.7.1.1 } -echo "Preparing mysql environment for signatrust developing......" +echo "Preparing mysql environment for signatrust developing......" check-prerequisites diff --git a/src/infra/database/pool.rs b/src/infra/database/pool.rs index f9d49ca194bf57d2c4bd6474be328b32df36b1e5..a0455e86d7841b6ca0d5254572994ce1a0128ebe 100644 --- a/src/infra/database/pool.rs +++ b/src/infra/database/pool.rs @@ -72,4 +72,36 @@ pub fn get_db_connection() -> Result<&'static DatabaseConnection> { )), Some(pool) => Ok(pool), }; -} \ No newline at end of file +} + +#[cfg(test)] +mod tests { + use testcontainers::clients; + use crate::util::error::Result; + use testcontainers::core::WaitFor; + use testcontainers::images::generic::GenericImage; + + #[tokio::test] + async fn test_database_migration() -> Result<()> { + let docker = clients::Cli::default(); + let image = GenericImage::new("mysql", "8.0") + .with_env_var("MYSQL_DATABASE", "signatrust") + .with_env_var("MYSQL_PASSWORD", "test") + .with_env_var("MYSQL_USER", "test") + .with_env_var("MYSQL_ROOT_PASSWORD", "root") + .with_wait_for(WaitFor::message_on_stderr("ready for connections")); + let database = docker.run(image.clone()); + let port = database.get_host_port_ipv4(3306); + + let sqlx_image = GenericImage::new("tommylike/sqlx-cli", "0.7.1.1") + .with_env_var("DATABASE_HOST", database.get_bridge_ip_address().to_string()) + .with_env_var("DATABASE_PORT", "3306") + .with_env_var("DATABASE_USER", "test") + .with_env_var("DATABASE_PASSWORD", "test") + .with_env_var("DATABASE_NAME", "signatrust") + .with_volume("./migrations/", "/app/migrations/").with_entrypoint("/app/run_migrations.sh") + .with_wait_for(WaitFor::message_on_stdout("Applied 20230727020628/migrate extend-datakey-name")); + let migration = docker.run(sqlx_image.clone()); + Ok(()) + } +}