Skip to content

Commit

Permalink
Add tests for fetching keys with failure
Browse files Browse the repository at this point in the history
  • Loading branch information
sosthene-nitrokey committed Feb 1, 2024
1 parent 37888ad commit bb8a6ac
Showing 1 changed file with 61 additions and 7 deletions.
68 changes: 61 additions & 7 deletions pkcs11/src/backend/session.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use std::{
collections::HashMap,
sync::{atomic::Ordering, Arc, Condvar, Mutex},
sync::{atomic::Ordering, Arc, Condvar, Mutex, MutexGuard},
};

use cryptoki_sys::{
Expand Down Expand Up @@ -527,15 +527,26 @@ impl Session {
}

/// Drop the Condvar to notify on close
struct NotifyAllGuard<'a>(&'a (Mutex<Db>, Condvar));
struct NotifyAllGuard<'a>(Option<&'a (Mutex<Db>, Condvar)>);
impl<'a> Drop for NotifyAllGuard<'a> {
fn drop(&mut self) {
self.0 .0.lock().unwrap().set_is_being_fetched(false);
self.0 .1.notify_all();
if let Some(cv) = self.0 {
cv.0.lock().unwrap().set_is_being_fetched(false);
cv.1.notify_all();
}
}
}

NotifyAllGuard(&self.db);
impl<'a> NotifyAllGuard<'a> {
fn success(&mut self, mut lock: MutexGuard<'a, Db>) {
let cv = self.0.take().unwrap();
lock.set_is_being_fetched(false);
lock.set_fetched_all_keys(true);
cv.1.notify_all();
}
}

let mut guard = NotifyAllGuard(Some(&self.db));

if !self
.login_ctx
Expand Down Expand Up @@ -573,7 +584,7 @@ impl Session {
.flatten()
.map(|o| db.add_object(o))
.collect();
db.set_fetched_all_keys(true);
guard.success(db);

Ok(handles)
}
Expand Down Expand Up @@ -692,7 +703,7 @@ mod test {

let db = Arc::new((Mutex::new(Db::new()), Condvar::new()));
let mut sessions = Vec::new();
for _ in 0..20 {
for _ in 0..10 {
let session = Session {
db: db.clone(),
decrypt_ctx: None,
Expand Down Expand Up @@ -724,4 +735,47 @@ mod test {
}
})
}

#[test]
fn parrallel_fetch_all_keys_fail() {
THREADS_ALLOWED.store(false, Ordering::Relaxed);
init_for_tests();
let slot = get_slot(0).unwrap();

let db = Arc::new((Mutex::new(Db::new()), Condvar::new()));
let mut sessions = Vec::new();
for _ in 0..3 {
let session = Session {
db: db.clone(),
decrypt_ctx: None,
encrypt_ctx: None,
sign_ctx: None,
device_error: 0,
enum_ctx: None,
flags: 0,
login_ctx: LoginCtx::new(
None,
None,
vec![slot.instances[0].clone()],
Some(RetryConfig {
count: 2,
delay_seconds: 0,
}),
),
slot_id: 0,
};
sessions.push(session);
}

thread::scope(|s| {
for session in &mut sessions {
s.spawn(|| {
assert!(matches!(
session.fetch_all_keys(),
Err(Error::NotLoggedIn(UserMode::OperatorOrAdministrator))
))
});
}
})
}
}

0 comments on commit bb8a6ac

Please sign in to comment.