some simple server tests (#1096)
* some simple server tests * fmt * logging in server test * log server errors * fix postgres uri * postgres ports * localhost again? * Rebase fixes --------- Co-authored-by: Ellie Huxtable <ellie@elliehuxtable.com>
This commit is contained in:
parent
c0449955e3
commit
c10ba684e0
6 changed files with 178 additions and 8 deletions
2
.github/workflows/nix.yml
vendored
2
.github/workflows/nix.yml
vendored
|
@ -19,7 +19,7 @@ jobs:
|
|||
- name: Run nix flake check
|
||||
run: nix flake check --print-build-logs
|
||||
|
||||
build:
|
||||
build-test:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
|
|
12
.github/workflows/rust.yml
vendored
12
.github/workflows/rust.yml
vendored
|
@ -44,6 +44,16 @@ jobs:
|
|||
test:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
services:
|
||||
postgres:
|
||||
image: postgres
|
||||
env:
|
||||
POSTGRES_USER: atuin
|
||||
POSTGRES_PASSWORD: pass
|
||||
POSTGRES_DB: atuin
|
||||
ports:
|
||||
- 5432:5432
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
|
@ -62,6 +72,8 @@ jobs:
|
|||
|
||||
- name: Run cargo test
|
||||
run: cargo test --all-features --workspace
|
||||
env:
|
||||
ATUIN_DB_URI: postgres://atuin:pass@localhost:5432/atuin
|
||||
|
||||
- name: Run cargo check (all features)
|
||||
run: cargo check --all-features --workspace
|
||||
|
|
33
Cargo.lock
generated
33
Cargo.lock
generated
|
@ -111,7 +111,9 @@ dependencies = [
|
|||
"serde_json",
|
||||
"tiny-bip39",
|
||||
"tokio",
|
||||
"tracing",
|
||||
"tracing-subscriber",
|
||||
"tracing-tree",
|
||||
"unicode-width",
|
||||
"whoami",
|
||||
]
|
||||
|
@ -2947,6 +2949,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "24eb03ba0eab1fd845050058ce5e616558e8f8d8fca633e6b163fe25c797213a"
|
||||
dependencies = [
|
||||
"once_cell",
|
||||
"valuable",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tracing-log"
|
||||
version = "0.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "78ddad33d2d10b1ed7eb9d1f518a5674713876e97e5bb9b7345a7984fbb4f922"
|
||||
dependencies = [
|
||||
"lazy_static",
|
||||
"log",
|
||||
"tracing-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -2965,6 +2979,19 @@ dependencies = [
|
|||
"tracing-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tracing-tree"
|
||||
version = "0.2.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "92d6b63348fad3ae0439b8bebf8d38fb5bda0b115d7a8a7e6f165f12790c58c3"
|
||||
dependencies = [
|
||||
"is-terminal",
|
||||
"nu-ansi-term",
|
||||
"tracing-core",
|
||||
"tracing-log",
|
||||
"tracing-subscriber",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "try-lock"
|
||||
version = "0.2.3"
|
||||
|
@ -3070,6 +3097,12 @@ dependencies = [
|
|||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "valuable"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d"
|
||||
|
||||
[[package]]
|
||||
name = "vcpkg"
|
||||
version = "0.2.15"
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
#![forbid(unsafe_code)]
|
||||
|
||||
use std::net::{IpAddr, SocketAddr};
|
||||
use std::{
|
||||
future::Future,
|
||||
net::{IpAddr, SocketAddr, TcpListener},
|
||||
};
|
||||
|
||||
use atuin_server_database::Database;
|
||||
use axum::Server;
|
||||
|
@ -16,10 +19,15 @@ use tokio::signal;
|
|||
|
||||
#[cfg(target_family = "unix")]
|
||||
async fn shutdown_signal() {
|
||||
signal::unix::signal(signal::unix::SignalKind::terminate())
|
||||
.expect("failed to register signal handler")
|
||||
.recv()
|
||||
.await;
|
||||
let mut term = signal::unix::signal(signal::unix::SignalKind::terminate())
|
||||
.expect("failed to register signal handler");
|
||||
let mut interrupt = signal::unix::signal(signal::unix::SignalKind::interrupt())
|
||||
.expect("failed to register signal handler");
|
||||
|
||||
tokio::select! {
|
||||
_ = term.recv() => {},
|
||||
_ = interrupt.recv() => {},
|
||||
};
|
||||
eprintln!("Shutting down gracefully...");
|
||||
}
|
||||
|
||||
|
@ -38,16 +46,29 @@ pub async fn launch<Db: Database>(
|
|||
port: u16,
|
||||
) -> Result<()> {
|
||||
let host = host.parse::<IpAddr>()?;
|
||||
launch_with_listener::<Db>(
|
||||
settings,
|
||||
TcpListener::bind(SocketAddr::new(host, port)).context("could not connect to socket")?,
|
||||
shutdown_signal(),
|
||||
)
|
||||
.await
|
||||
}
|
||||
|
||||
pub async fn launch_with_listener<Db: Database>(
|
||||
settings: Settings<Db::Settings>,
|
||||
listener: TcpListener,
|
||||
shutdown: impl Future<Output = ()>,
|
||||
) -> Result<()> {
|
||||
let db = Db::new(&settings.db_settings)
|
||||
.await
|
||||
.wrap_err_with(|| format!("failed to connect to db: {:?}", settings.db_settings))?;
|
||||
|
||||
let r = router::router(db, settings);
|
||||
|
||||
Server::bind(&SocketAddr::new(host, port))
|
||||
Server::from_tcp(listener)
|
||||
.context("could not launch server")?
|
||||
.serve(r.into_make_service())
|
||||
.with_graceful_shutdown(shutdown_signal())
|
||||
.with_graceful_shutdown(shutdown)
|
||||
.await?;
|
||||
|
||||
Ok(())
|
||||
|
|
|
@ -71,9 +71,14 @@ futures-util = "0.3"
|
|||
fuzzy-matcher = "0.3.7"
|
||||
colored = "2.0.4"
|
||||
ratatui = "0.21"
|
||||
tracing = "0.1"
|
||||
|
||||
|
||||
[dependencies.tracing-subscriber]
|
||||
version = "0.3"
|
||||
default-features = false
|
||||
features = ["ansi", "fmt", "registry", "env-filter"]
|
||||
optional = true
|
||||
|
||||
[dev-dependencies]
|
||||
tracing-tree = "0.2"
|
||||
|
|
99
atuin/tests/sync.rs
Normal file
99
atuin/tests/sync.rs
Normal file
|
@ -0,0 +1,99 @@
|
|||
use std::{env, net::TcpListener, time::Duration};
|
||||
|
||||
use atuin_client::api_client;
|
||||
use atuin_common::utils::uuid_v7;
|
||||
use atuin_server::{launch_with_listener, Settings as ServerSettings};
|
||||
use atuin_server_postgres::{Postgres, PostgresSettings};
|
||||
use futures_util::TryFutureExt;
|
||||
use tokio::{sync::oneshot, task::JoinHandle};
|
||||
use tracing::{dispatcher, Dispatch};
|
||||
use tracing_subscriber::{layer::SubscriberExt, EnvFilter};
|
||||
|
||||
async fn start_server(path: &str) -> (String, oneshot::Sender<()>, JoinHandle<()>) {
|
||||
let formatting_layer = tracing_tree::HierarchicalLayer::default()
|
||||
.with_writer(tracing_subscriber::fmt::TestWriter::new())
|
||||
.with_indent_lines(true)
|
||||
.with_ansi(true)
|
||||
.with_targets(true)
|
||||
.with_indent_amount(2);
|
||||
|
||||
let dispatch: Dispatch = tracing_subscriber::registry()
|
||||
.with(formatting_layer)
|
||||
.with(EnvFilter::new("atuin_server=debug,info"))
|
||||
.into();
|
||||
|
||||
let db_uri = env::var("ATUIN_DB_URI")
|
||||
.unwrap_or_else(|_| "postgres://atuin:pass@localhost:5432/atuin".to_owned());
|
||||
|
||||
let server_settings = ServerSettings {
|
||||
host: "127.0.0.1".to_owned(),
|
||||
port: 0,
|
||||
path: path.to_owned(),
|
||||
open_registration: true,
|
||||
max_history_length: 8192,
|
||||
max_record_size: 1024 * 1024 * 1024,
|
||||
page_size: 1100,
|
||||
register_webhook_url: None,
|
||||
register_webhook_username: String::new(),
|
||||
db_settings: PostgresSettings { db_uri },
|
||||
};
|
||||
|
||||
let (shutdown_tx, shutdown_rx) = tokio::sync::oneshot::channel();
|
||||
let listener = TcpListener::bind("127.0.0.1:0").unwrap();
|
||||
let addr = listener.local_addr().unwrap();
|
||||
let server = tokio::spawn(async move {
|
||||
let _tracing_guard = dispatcher::set_default(&dispatch);
|
||||
|
||||
if let Err(e) = launch_with_listener::<Postgres>(
|
||||
server_settings,
|
||||
listener,
|
||||
shutdown_rx.unwrap_or_else(|_| ()),
|
||||
)
|
||||
.await
|
||||
{
|
||||
tracing::error!(error=?e, "server error");
|
||||
panic!("error running server: {e:?}");
|
||||
}
|
||||
});
|
||||
|
||||
// let the server come online
|
||||
tokio::time::sleep(Duration::from_millis(200)).await;
|
||||
|
||||
(format!("http://{addr}{path}"), shutdown_tx, server)
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn registration() {
|
||||
let path = format!("/{}", uuid_v7().as_simple());
|
||||
let (address, shutdown, server) = start_server(&path).await;
|
||||
dbg!(&address);
|
||||
|
||||
let username = uuid_v7().as_simple().to_string();
|
||||
let email = format!("{}@example.com", uuid_v7().as_simple());
|
||||
let password = uuid_v7().as_simple().to_string();
|
||||
|
||||
// registration works
|
||||
let registration_response = api_client::register(&address, &username, &email, &password)
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
let client = api_client::Client::new(&address, ®istration_response.session).unwrap();
|
||||
|
||||
// the session token works
|
||||
let status = client.status().await.unwrap();
|
||||
assert_eq!(status.username, username);
|
||||
|
||||
// login works
|
||||
let login_response = api_client::login(
|
||||
&address,
|
||||
atuin_common::api::LoginRequest { username, password },
|
||||
)
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
// currently we return the same session token
|
||||
assert_eq!(registration_response.session, login_response.session);
|
||||
|
||||
shutdown.send(()).unwrap();
|
||||
server.await.unwrap();
|
||||
}
|
Loading…
Reference in a new issue