mirror of
https://github.com/tursodatabase/libsql.git
synced 2024-12-15 20:20:20 +00:00
156 lines
3.8 KiB
Rust
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();
|
|
}
|