test and fix #282

Sessions' last use updates weren't getting persisted to the database
because the update statement wasn't passing through the hash.

Also address a TODO of tracing in tests by using the same tracing
setup as in production.
This commit is contained in:
Scott Lamb 2023-07-04 20:42:15 -07:00
parent 028243532a
commit aa60bc991c
8 changed files with 64 additions and 5 deletions

View File

@ -40,6 +40,8 @@ even on minor releases, e.g. `0.7.5` -> `0.7.6`.
* get rid of live view's dreaded `ws close: 1006` error altogether. The live
view WebSocket protocol now conveys errors in a way that allows the
Javscript UI to see them.
* fix [#282](https://github.com/scottlamb/moonfire-nvr/issues/282):
sessions' last use information wasn't getting persisted.
## 0.7.5 (2022-05-09)

4
server/Cargo.lock generated
View File

@ -1081,6 +1081,7 @@ dependencies = [
name = "moonfire-base"
version = "0.0.1"
dependencies = [
"chrono",
"failure",
"futures",
"libc",
@ -1090,6 +1091,9 @@ dependencies = [
"slab",
"time 0.1.45",
"tracing",
"tracing-core",
"tracing-log",
"tracing-subscriber",
]
[[package]]

View File

@ -13,6 +13,7 @@ nightly = []
path = "lib.rs"
[dependencies]
chrono = "0.4.23"
failure = "0.1.1"
futures = "0.3"
libc = "0.2"
@ -22,3 +23,6 @@ serde_json = "1.0"
slab = "0.4"
time = "0.1"
tracing = "0.1.37"
tracing-core = "0.1.30"
tracing-log = "0.1.3"
tracing-subscriber = { version = "0.3.16", features = ["env-filter", "json"] }

View File

@ -7,5 +7,6 @@ mod error;
pub mod shutdown;
pub mod strutil;
pub mod time;
pub mod tracing_setup;
pub use crate::error::{prettify_failure, Error, ErrorKind, ResultExt};

View File

@ -831,18 +831,20 @@ impl State {
":id": &id,
})?;
}
for s in self.sessions.values() {
for (sh, s) in &self.sessions {
if !s.dirty {
continue;
}
let addr = s.last_use.addr_buf();
let addr: Option<&[u8]> = addr.as_ref().map(|a| a.as_ref());
s_stmt.execute(named_params! {
let cnt = s_stmt.execute(named_params! {
":last_use_time_sec": &s.last_use.when_sec,
":last_use_user_agent": &s.last_use.user_agent,
":last_use_peer_addr": &addr,
":use_count": &s.use_count,
":hash": &sh.0[..],
})?;
debug_assert_eq!(cnt, 1);
}
Ok(())
}
@ -1049,6 +1051,53 @@ mod tests {
);
}
/// Tests that flush works, including updating dirty sessions.
#[test]
fn flush() {
testutil::init();
let mut conn = Connection::open_in_memory().unwrap();
db::init(&mut conn).unwrap();
let mut state = State::init(&conn).unwrap();
let req = Request {
when_sec: Some(42),
addr: Some(::std::net::IpAddr::V4(::std::net::Ipv4Addr::new(
127, 0, 0, 1,
))),
user_agent: Some(b"some ua".to_vec()),
};
{
let mut c = UserChange::add_user("slamb".to_owned());
c.set_password("hunter2".to_owned());
state.apply(&conn, c).unwrap();
}
let (sid, _) = state
.login_by_password(
&conn,
req.clone(),
"slamb",
"hunter2".to_owned(),
Some(b"nvr.example.com".to_vec()),
0,
)
.unwrap();
let (s, _u) = state
.authenticate_session(&conn, req.clone(), &sid.hash())
.unwrap();
assert_eq!(s.use_count, 1);
let mut tx = conn.transaction().unwrap();
state.flush(&mut tx).unwrap();
tx.commit().unwrap();
state.post_flush();
// Everything should persist across reload.
drop(state);
let mut state = State::init(&conn).unwrap();
let (s, _u) = state.authenticate_session(&conn, req, &sid.hash()).unwrap();
assert_eq!(s.use_count, 2);
}
#[test]
fn revoke_not_in_cache() {
testutil::init();

View File

@ -38,7 +38,7 @@ pub const TEST_VIDEO_SAMPLE_ENTRY_DATA: &[u8] =
/// * use a fast but insecure password hashing format.
pub fn init() {
INIT.call_once(|| {
// TODO: tracing setup.
base::tracing_setup::install();
env::set_var("TZ", "America/Los_Angeles");
time::tzset();
crate::auth::set_test_config();

View File

@ -17,7 +17,6 @@ mod mp4;
mod slices;
mod stream;
mod streamer;
mod tracing_setup;
mod web;
const DEFAULT_DB_DIR: &str = "/var/lib/moonfire-nvr/db";
@ -71,7 +70,7 @@ fn main() {
std::process::exit(1);
}
tracing_setup::install();
base::tracing_setup::install();
// Get the program name from the OS (e.g. if invoked as `target/debug/nvr`: `nvr`),
// falling back to the crate name if conversion to a path/UTF-8 string fails.