11use std:: net:: SocketAddr ;
22use std:: time:: Duration ;
33
4- use sqlite_watcher:: server:: spawn_tcp_server;
5- #[ cfg( unix) ]
6- use sqlite_watcher:: server:: spawn_unix_server;
4+ use sqlite_watcher:: queue:: { ChangeOperation , ChangeQueue , NewChange } ;
5+ use sqlite_watcher:: server:: spawn_tcp;
76use sqlite_watcher:: watcher_proto:: watcher_client:: WatcherClient ;
8- use sqlite_watcher:: watcher_proto:: HealthCheckRequest ;
7+ use sqlite_watcher:: watcher_proto:: { AckChangesRequest , HealthCheckRequest , ListChangesRequest } ;
98use tempfile:: tempdir;
109use tokio:: time:: sleep;
1110use tonic:: metadata:: MetadataValue ;
1211
12+ fn seed_queue ( path : & str ) {
13+ let queue = ChangeQueue :: open ( path) . unwrap ( ) ;
14+ for i in 0 ..2 {
15+ let change = NewChange {
16+ table_name : "examples" . into ( ) ,
17+ operation : ChangeOperation :: Insert ,
18+ primary_key : format ! ( "row-{i}" ) ,
19+ payload : None ,
20+ wal_frame : None ,
21+ cursor : None ,
22+ } ;
23+ queue. enqueue ( & change) . unwrap ( ) ;
24+ }
25+ }
26+
1327#[ tokio:: test( flavor = "multi_thread" , worker_threads = 2 ) ]
14- async fn health_check_responds_ok ( ) {
28+ async fn tcp_server_handles_health_and_list ( ) {
1529 let dir = tempdir ( ) . unwrap ( ) ;
1630 let queue_path = dir. path ( ) . join ( "queue.db" ) ;
17- let addr: SocketAddr = "127.0.0.1:55051" . parse ( ) . unwrap ( ) ;
18- let token = "secret-token" . to_string ( ) ;
31+ seed_queue ( queue_path. to_str ( ) . unwrap ( ) ) ;
1932
20- let _handle = spawn_tcp_server ( addr, queue_path, token. clone ( ) ) . unwrap ( ) ;
33+ let addr: SocketAddr = "127.0.0.1:56060" . parse ( ) . unwrap ( ) ;
34+ let token = "secret" . to_string ( ) ;
35+ let _handle = spawn_tcp ( addr, queue_path, token. clone ( ) ) . unwrap ( ) ;
2136 sleep ( Duration :: from_millis ( 200 ) ) . await ;
2237
2338 let channel = tonic:: transport:: Channel :: from_shared ( format ! ( "http://{}" , addr) )
@@ -26,39 +41,68 @@ async fn health_check_responds_ok() {
2641 . await
2742 . unwrap ( ) ;
2843 let mut client = WatcherClient :: new ( channel) ;
29- let mut req = tonic:: Request :: new ( HealthCheckRequest { } ) ;
44+
45+ let mut health_req = tonic:: Request :: new ( HealthCheckRequest { } ) ;
3046 let header = MetadataValue :: try_from ( format ! ( "Bearer {}" , token) ) . unwrap ( ) ;
31- req. metadata_mut ( ) . insert ( "authorization" , header) ;
32- let resp = client. health_check ( req) . await . unwrap ( ) ;
33- assert_eq ! ( resp. into_inner( ) . status, "ok" ) ;
47+ health_req
48+ . metadata_mut ( )
49+ . insert ( "authorization" , header. clone ( ) ) ;
50+ client. health_check ( health_req) . await . unwrap ( ) ;
51+
52+ let mut list_req = tonic:: Request :: new ( ListChangesRequest { limit : 10 } ) ;
53+ list_req. metadata_mut ( ) . insert ( "authorization" , header) ;
54+ let resp = client. list_changes ( list_req) . await . unwrap ( ) ;
55+ assert_eq ! ( resp. into_inner( ) . changes. len( ) , 2 ) ;
3456}
35- #[ cfg( unix) ]
36- #[ tokio:: test( flavor = "multi_thread" , worker_threads = 2 ) ]
37- async fn health_check_over_unix_socket ( ) {
38- use tokio:: net:: UnixStream ;
39- use tonic:: transport:: Endpoint ;
40- use tower:: service_fn;
4157
58+ #[ tokio:: test( flavor = "multi_thread" , worker_threads = 2 ) ]
59+ async fn unauthenticated_requests_fail ( ) {
4260 let dir = tempdir ( ) . unwrap ( ) ;
4361 let queue_path = dir. path ( ) . join ( "queue.db" ) ;
44- let socket_path = dir. path ( ) . join ( "watcher.sock" ) ;
45- let token = "secret-token" . to_string ( ) ;
62+ let addr: SocketAddr = "127.0.0.1:56061" . parse ( ) . unwrap ( ) ;
63+ let token = "secret" . to_string ( ) ;
64+ let _handle = spawn_tcp ( addr, queue_path, token) . unwrap ( ) ;
65+ sleep ( Duration :: from_millis ( 200 ) ) . await ;
66+
67+ let channel = tonic:: transport:: Channel :: from_shared ( format ! ( "http://{}" , addr) )
68+ . unwrap ( )
69+ . connect ( )
70+ . await
71+ . unwrap ( ) ;
72+ let mut client = WatcherClient :: new ( channel) ;
73+
74+ let request = tonic:: Request :: new ( ListChangesRequest { limit : 1 } ) ;
75+ let err = client. list_changes ( request) . await . unwrap_err ( ) ;
76+ assert_eq ! ( err. code( ) , tonic:: Code :: Unauthenticated ) ;
77+ }
4678
47- let _handle = spawn_unix_server ( & socket_path, queue_path, token. clone ( ) ) . unwrap ( ) ;
79+ #[ tokio:: test( flavor = "multi_thread" , worker_threads = 2 ) ]
80+ async fn ack_changes_advances_queue ( ) {
81+ let dir = tempdir ( ) . unwrap ( ) ;
82+ let queue_path = dir. path ( ) . join ( "queue.db" ) ;
83+ seed_queue ( queue_path. to_str ( ) . unwrap ( ) ) ;
84+ let addr: SocketAddr = "127.0.0.1:56062" . parse ( ) . unwrap ( ) ;
85+ let token = "secret" . to_string ( ) ;
86+ let _handle = spawn_tcp ( addr, queue_path, token. clone ( ) ) . unwrap ( ) ;
4887 sleep ( Duration :: from_millis ( 200 ) ) . await ;
4988
50- let endpoint = Endpoint :: try_from ( "http://[::]:50051" ) . unwrap ( ) ;
51- let channel = endpoint
52- . connect_with_connector ( service_fn ( move |_: tonic:: transport:: Uri | {
53- let path = socket_path. clone ( ) ;
54- async move { UnixStream :: connect ( path) . await }
55- } ) )
89+ let channel = tonic:: transport:: Channel :: from_shared ( format ! ( "http://{}" , addr) )
90+ . unwrap ( )
91+ . connect ( )
5692 . await
5793 . unwrap ( ) ;
5894 let mut client = WatcherClient :: new ( channel) ;
59- let mut req = tonic:: Request :: new ( HealthCheckRequest { } ) ;
6095 let header = MetadataValue :: try_from ( format ! ( "Bearer {}" , token) ) . unwrap ( ) ;
61- req. metadata_mut ( ) . insert ( "authorization" , header) ;
62- let resp = client. health_check ( req) . await . unwrap ( ) ;
63- assert_eq ! ( resp. into_inner( ) . status, "ok" ) ;
96+
97+ let mut req = tonic:: Request :: new ( ListChangesRequest { limit : 10 } ) ;
98+ req. metadata_mut ( ) . insert ( "authorization" , header. clone ( ) ) ;
99+ let resp = client. list_changes ( req) . await . unwrap ( ) . into_inner ( ) ;
100+ assert_eq ! ( resp. changes. len( ) , 2 ) ;
101+ let highest = resp. changes . last ( ) . unwrap ( ) . change_id ;
102+
103+ let mut ack_req = tonic:: Request :: new ( AckChangesRequest {
104+ up_to_change_id : highest,
105+ } ) ;
106+ ack_req. metadata_mut ( ) . insert ( "authorization" , header) ;
107+ client. ack_changes ( ack_req) . await . unwrap ( ) ;
64108}
0 commit comments