@@ -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