0
0
mirror of https://github.com/tursodatabase/libsql.git synced 2024-12-15 20:20:20 +00:00
2024-07-22 15:53:02 +00:00

156 lines
3.8 KiB
Rust

//! Test hrana related functionalities
#![allow(deprecated)]
use futures::SinkExt as _;
use libsql::Database;
use libsql_server::{
auth::{
user_auth_strategies::{self, jwt::Token},
Auth,
},
config::UserApiConfig,
};
use tempfile::tempdir;
use tokio_stream::StreamExt;
use tokio_tungstenite::{
client_async,
tungstenite::{self, client::IntoClientRequest},
};
use turmoil::net::TcpStream;
use crate::common::{
auth::{encode, key_pair},
net::{init_tracing, SimServer, TestServer, TurmoilConnector},
};
async fn make_standalone_server(auth_strategy: Auth) -> Result<(), Box<dyn std::error::Error>> {
init_tracing();
let tmp = tempdir()?;
let server = TestServer {
path: tmp.path().to_owned().into(),
user_api_config: UserApiConfig {
hrana_ws_acceptor: None,
auth_strategy,
..Default::default()
},
..Default::default()
};
server.start_sim(8080).await?;
Ok(())
}
fn gen_test_jwt_auth() -> (Auth, String) {
let (encoding_key, decoding_key) = key_pair();
let jwt_keys = vec![jsonwebtoken::DecodingKey::from_ed_components(&decoding_key).unwrap()];
let auth = Auth::new(user_auth_strategies::Jwt::new(jwt_keys));
let claims = Token::default();
let token = encode(&claims, &encoding_key);
(auth, token)
}
#[test]
fn http_hrana() {
let (auth, token) = gen_test_jwt_auth();
let mut sim = turmoil::Builder::new().build();
sim.host("primary", move || make_standalone_server(auth.clone()));
sim.client("client", async {
let db =
Database::open_remote_with_connector("http://primary:8080", token, TurmoilConnector)?;
let conn = db.connect()?;
conn.execute("create table t(x text)", ()).await?;
Ok(())
});
sim.run().unwrap();
}
#[test]
fn embedded_replica() {
let tmp_embedded = tempdir().unwrap();
let tmp_embedded_path = tmp_embedded.path().to_owned();
let (auth, token) = gen_test_jwt_auth();
let mut sim = turmoil::Builder::new().build();
sim.host("primary", move || make_standalone_server(auth.clone()));
sim.client("client", async move {
let path = tmp_embedded_path.join("embedded");
let db = Database::open_with_remote_sync_connector(
path.to_str().unwrap(),
"http://primary:8080",
token,
TurmoilConnector,
false,
None,
)
.await?;
let conn = db.connect()?;
conn.execute("create table t(x text)", ()).await?;
Ok(())
});
sim.run().unwrap();
}
#[test]
fn ws_hrana() {
let (auth, token) = gen_test_jwt_auth();
let mut sim = turmoil::Builder::new().build();
sim.host("primary", move || make_standalone_server(auth.clone()));
sim.client("client", async move {
let url = "ws://primary:8080";
let req = url.into_client_request().unwrap();
let conn = TcpStream::connect("primary:8080").await.unwrap();
let (mut ws, _) = client_async(req, conn).await.unwrap();
#[derive(serde::Serialize, Debug)]
#[serde(tag = "type", rename_all = "snake_case")]
pub enum ClientMsg {
Hello { jwt: Option<String> },
}
#[derive(serde::Deserialize, Debug)]
#[serde(tag = "type", rename_all = "snake_case")]
pub enum ServerMsg {
HelloOk {},
}
let msg = ClientMsg::Hello {
jwt: Some(token.to_string()),
};
let msg_data = serde_json::to_string(&msg).unwrap();
ws.send(tungstenite::Message::Text(msg_data)).await.unwrap();
let Some(tungstenite::Message::Text(msg)) = ws.try_next().await.unwrap() else {
panic!("wrong message type");
};
serde_json::from_str::<ServerMsg>(&msg).unwrap();
Ok(())
});
sim.run().unwrap();
}