Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix inconsistent stronghold storage test #320

Merged
merged 1 commit into from
Jul 19, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ Cargo.lock
.idea/
.vscode/

# Ignore temporary test files
test-storage/

# remove book
book

Expand Down
51 changes: 30 additions & 21 deletions identity-account/src/stronghold/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@ use crate::stronghold::Store;
use crate::utils::derive_encryption_key;
use crate::utils::EncryptionKey;

const ROOT: &str = "./test-storage";
const SIZE: usize = 10;
const TEST_DIR: &str = "./test-storage";
const RANDOM_FILENAME_SIZE: usize = 10;

fn location(name: &str) -> Location {
Location::generic(name, name)
Expand All @@ -38,7 +38,7 @@ fn rand_string(chars: usize) -> String {
}

fn generate_filename() -> PathBuf {
AsRef::<Path>::as_ref(ROOT).join(format!("{}.stronghold", rand_string(SIZE)))
AsRef::<Path>::as_ref(TEST_DIR).join(format!("{}.stronghold", rand_string(RANDOM_FILENAME_SIZE)))
}

async fn open_snapshot(path: &Path, password: EncryptionKey) -> Snapshot {
Expand All @@ -59,7 +59,7 @@ rusty_fork_test! {
#[test]
fn test_password_expiration() {
block_on(async {
let interval: Duration = Duration::from_millis(25);
let interval: Duration = Duration::from_millis(100);

Snapshot::set_password_clear(interval).unwrap();

Expand All @@ -68,6 +68,7 @@ rusty_fork_test! {

snapshot.load(Default::default()).await.unwrap();

// Wait for password to be cleared
thread::sleep(interval * 3);

let store: Store<'_> = snapshot.store("", &[]);
Expand All @@ -89,53 +90,61 @@ rusty_fork_test! {
#[test]
fn test_password_persistence() {
block_on(async {
let interval: Duration = Duration::from_millis(25);
let interval: Duration = Duration::from_millis(300);

Snapshot::set_password_clear(interval).unwrap();

let filename: PathBuf = generate_filename();
let snapshot: Snapshot = Snapshot::new(&filename);

snapshot.load(Default::default()).await.unwrap();
let mut instant: Instant = Instant::now();

let store: Store<'_> = snapshot.store("", &[]);

for index in 1..6 {
let instant: Instant = Instant::now();
for index in 1..=5u8 {
let location: Location = location(&format!("persists{}", index));

store.set(location, "STRONGHOLD".to_string(), None).await.unwrap();

let set_result = store.set(location, format!("STRONGHOLD{}", index), None).await;
let status: SnapshotStatus = snapshot.status().unwrap();

assert!(
matches!(status, SnapshotStatus::Unlocked(_)),
"unexpected snapshot status",
);

if let Some(timeout) = interval.checked_sub(instant.elapsed()) {
// Prior to the expiration time, the password should not be cleared yet
assert!(
set_result.is_ok(),
"set failed"
);
assert!(
matches!(status, SnapshotStatus::Unlocked(_)),
"unexpected snapshot status",
);

thread::sleep(timeout / 2);
} else {
// if elapsed > interval, set the password again.
// this might happen if the test is stopped by another thread
// If elapsed > interval, set the password again.
// This might happen if the test is stopped by another thread.
snapshot.set_password(Default::default()).unwrap();
instant = Instant::now();
}
}

let result: Vec<u8> = store.get(location("persists1")).await.unwrap();
let mut result: Result<Vec<u8>, Error> = store.get(location("persists1")).await;

assert_eq!(result, b"STRONGHOLD");
// Test may have taken too long / been interrupted and cleared the password already, retry
if matches!(result, Err(Error::StrongholdPasswordNotSet)) && interval.checked_sub(instant.elapsed()).is_none() {
snapshot.set_password(Default::default()).unwrap();
result = store.get(location("persists1")).await;
}
assert_eq!(result.unwrap(), b"STRONGHOLD1");

// Wait for password to be cleared
thread::sleep(interval * 2);

let error: Error = store.get(location("persists1")).await.unwrap_err();

assert!(
matches!(error, Error::StrongholdPasswordNotSet),
"unexpected error: {:?}",
error
);

assert!(
matches!(snapshot.status().unwrap(), SnapshotStatus::Locked),
"unexpected snapshot status",
Expand Down