Skip to content

Commit d909eb2

Browse files
committed
redis-db: Database trait test + tests
1 parent 0745ed8 commit d909eb2

File tree

2 files changed

+178
-0
lines changed

2 files changed

+178
-0
lines changed

.github/workflows/rust-test.yml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,10 @@ jobs:
3535
ports:
3636
# Maps tcp port 5432 on service container to the host
3737
- 5432:5432
38+
redis:
39+
image: redis
40+
ports:
41+
- 6379:6379
3842

3943
steps:
4044
- uses: actions/checkout@v4
@@ -57,4 +61,5 @@ jobs:
5761
export POSTGRES_USER="postgres"
5862
export POSTGRES_PASSWORD="postgres"
5963
export POSTGRES_DBNAME="test"
64+
export REDIS_URL="redis://127.0.0.1:6379"
6065
cargo test --verbose

common/src/database/redis.rs

Lines changed: 173 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -619,3 +619,176 @@ impl Database for RedisDatabase {
619619
Ok(result)
620620
}
621621
}
622+
623+
624+
#[cfg(test)]
625+
mod tests {
626+
627+
use tempfile::TempPath;
628+
use std::env;
629+
630+
use crate::{
631+
database::schema::{self, Migrator},
632+
migration,
633+
};
634+
635+
use super::*;
636+
use std::{fs, future::IntoFuture, net::Shutdown, process::{Child, Command, Stdio}};
637+
use std::path::PathBuf;
638+
use tempfile::NamedTempFile;
639+
use std::io::{self, BufRead, Write};
640+
use std::fs::{File, OpenOptions};
641+
use std::time::Duration;
642+
use tokio::{net::TcpListener, sync::{oneshot, Notify}, time::sleep};
643+
use tokio::sync::Mutex;
644+
use std::net::SocketAddr;
645+
use serial_test::serial;
646+
647+
#[allow(unused)]
648+
async fn cleanup_db(db: &RedisDatabase) -> Result<()> {
649+
let mut con = db.pool.get().await?;
650+
let _ : () = deadpool_redis::redis::cmd("FLUSHALL").query_async(&mut con).await?;
651+
Ok(())
652+
}
653+
654+
async fn drop_migrations_table(db: &RedisDatabase) -> Result<()> {
655+
let mut conn = db.pool.get().await.context("Failed to get Redis connection")?;
656+
let key = MIGRATION_TABLE_NAME;
657+
let _:() = conn.del(key).await?;
658+
Ok(())
659+
}
660+
661+
async fn redis_db() -> Result<RedisDatabase> {
662+
let connection_string = env::var("REDIS_URL").unwrap_or("redis://127.0.0.1:6379".to_string());
663+
RedisDatabase::new(connection_string.as_str()).await
664+
}
665+
666+
async fn db_with_migrations() -> Result<Arc<dyn Database>> {
667+
let mut db = redis_db().await?;
668+
schema::redis::register_migrations(&mut db);
669+
drop_migrations_table(&db).await?;
670+
Ok(Arc::new(db))
671+
}
672+
673+
#[tokio::test]
674+
#[serial]
675+
async fn test_open_and_close() -> Result<()> {
676+
redis_db()
677+
.await
678+
.expect("Could not connect to database");
679+
Ok(())
680+
}
681+
682+
#[tokio::test]
683+
#[serial]
684+
async fn test_bookmarks() -> Result<()> {
685+
crate::database::tests::test_bookmarks(db_with_migrations().await?).await?;
686+
Ok(())
687+
}
688+
689+
#[tokio::test]
690+
#[serial]
691+
async fn test_heartbeats() -> Result<()> {
692+
crate::database::tests::test_heartbeats(db_with_migrations().await?).await?;
693+
Ok(())
694+
}
695+
696+
#[tokio::test]
697+
#[serial]
698+
async fn test_heartbeats_cache() -> Result<()> {
699+
crate::database::tests::test_heartbeats_cache(db_with_migrations().await?).await?;
700+
Ok(())
701+
}
702+
703+
#[tokio::test]
704+
#[serial]
705+
async fn test_subscriptions() -> Result<()> {
706+
crate::database::tests::test_subscriptions(db_with_migrations().await?).await?;
707+
Ok(())
708+
}
709+
710+
#[tokio::test]
711+
#[serial]
712+
async fn test_stats() -> Result<()> {
713+
crate::database::tests::test_stats_and_machines(db_with_migrations().await?).await?;
714+
Ok(())
715+
}
716+
717+
#[tokio::test]
718+
#[serial]
719+
async fn test_current_version_empty() -> Result<()> {
720+
let db = db_with_migrations().await?;
721+
let res = db.current_version().await?;
722+
assert_eq!(res, None);
723+
Ok(())
724+
}
725+
726+
#[tokio::test]
727+
#[serial]
728+
async fn test_current_version() -> Result<()> {
729+
let db = redis_db().await?;
730+
let mut con = db.pool.get().await?;
731+
let members = vec![(1.0, 1),(2.0, 2),(3.0, 3)];
732+
let _:() = con.zadd_multiple(MIGRATION_TABLE_NAME, &members).await?;
733+
let res = db.current_version().await?;
734+
assert_eq!(res, Some(3));
735+
Ok(())
736+
}
737+
738+
#[tokio::test]
739+
#[serial]
740+
async fn test_migrated_versions() -> Result<()> {
741+
let db = redis_db().await?;
742+
let mut con = db.pool.get().await?;
743+
let members = vec![(1.0, 1),(2.0, 2),(3.0, 3)];
744+
let _:() = con.zadd_multiple(MIGRATION_TABLE_NAME, &members).await?;
745+
let res = db.migrated_versions().await?;
746+
assert_eq!(res, BTreeSet::<i64>::from_iter(vec![1,2,3]));
747+
Ok(())
748+
}
749+
750+
struct CreateUsers;
751+
migration!(CreateUsers, 1, "create users table");
752+
753+
#[async_trait]
754+
impl RedisMigration for CreateUsers {
755+
async fn up(&self, conn: &mut Connection) -> Result<()> {
756+
let key = format!("{}", RedisDomain::Users);
757+
let _:() = conn.set(key, "").await?;
758+
Ok(())
759+
}
760+
761+
async fn down(&self, conn: &mut Connection) -> Result<()> {
762+
let key = format!("{}", RedisDomain::Users);
763+
let _:() = conn.del(key).await?;
764+
Ok(())
765+
}
766+
}
767+
768+
#[tokio::test]
769+
#[serial]
770+
async fn test_register() -> Result<()> {
771+
let mut db = redis_db()
772+
.await
773+
.expect("Could not connect to database");
774+
775+
drop_migrations_table(&db).await?;
776+
db.register_migration(Arc::new(CreateUsers));
777+
778+
db.setup_schema().await.expect("Could not setup schema");
779+
780+
let db_arc = Arc::new(db);
781+
782+
let migrator = Migrator::new(db_arc.clone());
783+
784+
migrator.up(None, false).await.unwrap();
785+
786+
assert_eq!(db_arc.current_version().await.unwrap(), Some(1));
787+
788+
migrator.down(None, false).await.unwrap();
789+
790+
assert_eq!(db_arc.current_version().await.unwrap(), None);
791+
Ok(())
792+
}
793+
794+
}

0 commit comments

Comments
 (0)