usecrate::{Error, ErrorCode, FileState, OpenMode, Port, Session}; use test::assert_eq;
/// Tests that connecting to the service works. #[test] fn connect() { let session = Session::new(Port::TamperDetectEarlyAccess, true).unwrap();
session.close();
}
/// Tests successfully connecting to a port when not waiting for the port to be /// available. #[test] fn connect_no_wait() { let session = Session::new(Port::TamperDetectEarlyAccess, false).unwrap();
session.close();
}
/// Tests that `Session::new` will return an error instead of blocking when /// trying to connect to a port that doesn't exist if not waiting on the port to /// be available. #[test] fn connect_fail_no_wait() { let result = Session::new(Port::TestPortNonExistent, false);
assert_eq!(Err(Error::Code(ErrorCode::NotFound)), result);
}
/// Tests that reading/writing to a file with the basic file access APIs works. #[test] fn read_write() { letmut session = Session::new(Port::TamperDetectEarlyAccess, true).unwrap();
let file_name = "read_write.txt"; let file_contents = "Hello, world!";
// Write the initial contents of the file.
session.write(file_name, file_contents.as_bytes()).unwrap();
// Read the contents of the file. let data = &mut [0; 32]; let data = session.read(file_name, data).unwrap();
// Verify that the contents are as expected.
assert_eq!(data.len(), file_contents.len(), "Incorrect number of bytes read");
assert_eq!(data, file_contents.as_bytes(), "Incorrect file contents returned");
}
/// Tests that trying to read a full file with a buffer that's too small returns /// an error. #[test] fn read_all_buf_too_small() { letmut session = Session::new(Port::TamperDetectEarlyAccess, true).unwrap();
let file_name = "read_all_buf_too_small.txt"; let file_contents = "Hello, world!";
// Write the initial contents of the file.
session.write(file_name, file_contents.as_bytes()).unwrap();
// Try to read the contents of the file with a buffer that is not large enough // to hold the full file. let data = &mut [0; 5]; let result = session.read(file_name, data);
/// Tests `read_at`, verifying that it can partially read a file at different /// offsets, and that it does not read past the end of the file. #[test] fn read_at() { letmut session = Session::new(Port::TamperDetectEarlyAccess, true).unwrap();
let file_name = "read_at.txt"; let file_contents = b"Hello, world!";
// Write the initial contents of the file.
session.write(file_name, file_contents).unwrap();
// Read 5 bytes of the file starting at the 4th byte. let data = &mut [0; 5]; let result = session.read_at(&mut file, 3, data);
// Verify that the correct chunk of the file was read.
assert_eq!(Ok(&file_contents[3..8]), result);
// Read past the end of the file to verify that the buffer is only partially // filled.
data.fill(0); let result = session.read_at(&mut file, 10, data);
// Verify that the remaining portion of the file is returned.
assert_eq!(Ok(&file_contents[10..]), result);
// Verify that only a prefix of the buffer was overwritten. let expected = &[file_contents[10], file_contents[11], file_contents[12], 0, 0][..];
assert_eq!(expected, data, "Data buffer was not overwritten in expected way");
}
let file_name = "write_at.txt"; let file_contents = "Hello, world!";
// Write the initial contents of the file. letmut file = session.open_file(file_name, OpenMode::Create).unwrap();
session.write_all(&mut file, file_contents.as_bytes()).unwrap();
// Overwrite a portion of the file. let result = session.write_at(&mut file, 7, b"Trusty");
assert_eq!(Ok(()), result);
// Verify that the contents are as expected. let data = &mut [0; 32]; let result = session.read_all(&file, data); let expected = b"Hello, Trusty".as_slice();
assert_eq!(Ok(expected), result, "Incorrect bytes read");
// Use `write_at` in a transaction. letmut transaction = session.begin_transaction();
assert_eq!(Ok(()), transaction.write_at(&mut file, 7, b"C"));
assert_eq!(Ok(()), transaction.commit());
let result = session.read_all(&file, data); let expected = b"Hello, Crusty".as_slice();
assert_eq!(Ok(expected), result);
// Verify that attempting to write past the end of the file succeeds and expands // the file to fit the new data. let result = session.write_at(&mut file, 7, b"too long data");
assert_eq!(Ok(()), result, "Writing past end of file failed");
let result = session.read_all(&file, data); let expected = b"Hello, too long data".as_slice();
assert_eq!(Ok(expected), result);
}
/// Tests that file sizes are reported correctly, and that setting file size /// works both when increasing and decreasing a file's size. #[test] fn get_set_size() { letmut session = Session::new(Port::TamperDetectEarlyAccess, true).unwrap();
let file_name = "get_set_size.txt"; let initial_contents = "Hello, world!"; letmut buf = [0; 32];
// Create the file and set its initial contents. letmut file = session.open_file(file_name, OpenMode::Create).unwrap();
session.write_all(&mut file, initial_contents.as_bytes()).unwrap();
// Verify that the reported size is correct after writing to the file. let size = session.get_size(&file).unwrap();
assert_eq!(initial_contents.len(), size, "File has incorrect size after initial creation");
// Decrease the file's size and verify that the contents are truncated as // expected.
session.set_size(&mut file, 5).unwrap(); let contents = session.read_all(&file, buf.as_mut_slice()).unwrap();
assert_eq!("Hello".as_bytes(), contents, "File has incorrect contents after truncating");
// Increase the file's size and verify that the contents are 0-extended as // expected.
session.set_size(&mut file, 10).unwrap(); let contents = session.read_all(&file, buf.as_mut_slice()).unwrap();
assert_eq!( "Hello\0\0\0\0\0".as_bytes(),
contents, "File has incorrect contents after extending",
);
}
/// Tests that files can be renamed and deleted. #[test] fn rename_delete() { letmut session = Session::new(Port::TamperDetectEarlyAccess, true).unwrap();
let before_name = "before.txt"; let after_name = "after.txt"; let file_contents = "Hello, world!"; letmut buf = [0; 32];
// Verify that neither of the test files exist before the test runs.
session.open_file(before_name, OpenMode::Open).unwrap_err();
session.open_file(after_name, OpenMode::Open).unwrap_err();
// Create the initial file and then rename it.
session.write(before_name, file_contents.as_bytes()).unwrap();
session.rename(before_name, after_name).unwrap();
// Verify that the file no longer exists at the original name, and that the new // file has the same contents as the original file.
session.open_file(before_name, OpenMode::Open).unwrap_err(); let contents = session.read(after_name, buf.as_mut_slice()).unwrap();
assert_eq!(file_contents.as_bytes(), contents, "File has incorrect contents after renaming");
// Delete the file and then verify it no longer exists
session.remove(after_name).unwrap();
session.open_file(after_name, OpenMode::Open).unwrap_err();
}
/// Tests that a file that is open as a handle cannot be renamed. #[test] fn cannot_rename_open_file() { letmut session = Session::new(Port::TamperDetectEarlyAccess, true).unwrap();
// Clear any leftover files from a previous test run.
remove_all(&mut session);
let file_name = "cannot_rename_or_delete_open_file.txt";
// Create the file and open a handle for it. let file = session.open_file(file_name, OpenMode::CreateExclusive).unwrap();
// Verify that renaming the file fails while the handle is open.
assert_eq!(
Err(Error::Code(ErrorCode::NotAllowed)),
session.rename(file_name, "different_file.txt"), "Unexpected result when renaming open file",
);
// Verify that the file can be renamed once the handle is closed.
file.close();
session.rename(file_name, "different_file.txt").unwrap();
}
/// Tests that multiple files can be modified in a single transaction, and that /// file handles opened as part of a transaction can still be used after the /// transaction is committed. #[test] fn multiple_files_in_transaction() { letmut session = Session::new(Port::TamperDetectEarlyAccess, true).unwrap();
let file_a = "file_a.txt"; let file_b = "file_b.txt"; let file_contents = "multiple_files_in_transaction"; letmut buf = [0; 32];
// Clear any leftover files from a previous test run.
remove_all(&mut session);
// Start a transaction, create two files, and then write the contents of those // files before committing the transaction.
// Verify that we can observe the updated file contents. Note that we reuse the // existing file handles to verify that file handles opened in a transaction // remain valid after the transaction is committed.
let actual_contents = session.read_all(&file_a, &mut buf).unwrap();
assert_eq!(
file_contents.as_bytes(),
actual_contents, "Changes from transaction were not written",
);
let actual_contents = session.read_all(&file_b, &mut buf).unwrap();
assert_eq!(
file_contents.as_bytes(),
actual_contents, "Changes from transaction were not written",
);
}
/// Tests that file contents can be read while using a `Transaction`. #[test] fn read_in_transaction() { letmut session = Session::new(Port::TamperDetectEarlyAccess, true).unwrap();
let file_name = "read_in_transaction.txt"; let file_contents = "Hello, world!";
// Write the initial contents of the file. letmut file = session.open_file(file_name, OpenMode::Create).unwrap();
session.write_all(&mut file, file_contents.as_bytes()).unwrap();
// Overwrite a portion of the file in a transaction. letmut transaction = session.begin_transaction(); let result = transaction.write_at(&mut file, 7, b"Trusty");
assert_eq!(Ok(()), result);
// Verify that the contents are as expected. let data = &mut [0; 32]; let result = transaction.read_all(&file, data); let expected = b"Hello, Trusty".as_slice();
assert_eq!(Ok(expected), result, "Incorrect bytes read");
// Change the contents of the file then verify that we can get the updated length. let long_contents = b"Now for a much much longer file";
assert_eq!(Ok(()), transaction.write_all(&mut file, long_contents));
assert_eq!(Ok(long_contents.len()), transaction.get_size(&file));
transaction.discard().unwrap();
}
/// Tests that pending changes in a transaction are not committed if the /// transaction is discarded. #[test] fn discard_transaction() { letmut session = Session::new(Port::TamperDetectEarlyAccess, true).unwrap();
let file_name = "discard_transaction.txt"; let file_contents = "discard_transaction"; letmut buf = [0; 32];
// Clear any leftover files from a previous test run.
remove_all(&mut session);
// Begin to make changes in a transaction, then discard the transaction without // committing the pending changes.
{ letmut transaction = session.begin_transaction();
// Verify that the file was never created or written to.
assert_eq!(
Err(Error::Code(ErrorCode::NotFound)),
session.read(file_name, &mut buf), "Unexpected result when renaming open file",
);
}
/// Tests that pending changes in a transaction are not committed if the /// transaction is discarded. #[test] fn drop_transaction() { letmut session = Session::new(Port::TamperDetectEarlyAccess, true).unwrap();
let file_name = "discard_transaction_on_drop.txt"; let file_contents = "discard_transaction_on_drop"; letmut buf = [0; 32];
// Clear any leftover files from a previous test run.
remove_all(&mut session);
// Begin to make changes in a transaction, then drop it without explicitly // committing or discarding it. This should discard any pending changes.
{ letmut transaction = session.begin_transaction();
// Verify that the file was never created or written to.
assert_eq!(
Err(Error::Code(ErrorCode::NotFound)),
session.read(file_name, &mut buf), "Unexpected result when renaming open file",
);
}
/// Tests directory enumeration in an empty directory. #[test] fn list_empty_dir() { letmut session = Session::new(Port::TamperDetectEarlyAccess, true).unwrap();
// Reset the storage dir so that we can test listing files in an empty dir.
remove_all(&mut session);
// Verify that listing files in an empty dir yields no elements. for entry in session.list_files().unwrap() { let entry = entry.unwrap();
panic!("Unexpected file: {:?}", entry);
}
}
/// Tests that directory enumeration correctly returns errors if the session is /// closed while directory enumeration is still in progress. #[test] fn drop_session_while_listing() { // Open a session, start listing files, and then drop the `Session` object // while keeping the `DirIter` object alive. letmut dir_iter = { letmut session = Session::new(Port::TamperDetectEarlyAccess, true).unwrap();
session.list_files().unwrap()
};
// Verify that attempting to use the iterator after the session is closed // generates an error and then only yields `None`.
assert_eq!(Some(Err(Error::Code(ErrorCode::NotFound))), dir_iter.next());
assert_eq!(None, dir_iter.next());
assert_eq!(None, dir_iter.next());
}
/// Verifies that directory enumeration lists files correctly, and that that /// states of files are reported correctly. #[test] fn list_during_transaction() { letmut session = Session::new(Port::TamperDetectEarlyAccess, true).unwrap();
// Clear any leftover files from a previous test run.
remove_all(&mut session);
let file_a = "file_a.txt"; let file_b = "file_b.txt"; let file_contents = "Hello, world!";
// Create a file and write to it such that it is fully committed.
session.write(file_a, file_contents.as_bytes()).unwrap();
letmut transaction = session.begin_transaction();
// Create a file as part of `transaction` that will be in the "added" state. letmut file = transaction.open_file(file_b, OpenMode::CreateExclusive).unwrap();
transaction.write_all(&mut file, file_contents.as_bytes()).unwrap();
// Verify that listing files while a transaction is active correctly reports all // expected files and in the correct states. letmut dir_iter = transaction.list_files().unwrap();
assert_eq!(Some(Ok((file_a.into(), FileState::Committed))), dir_iter.next());
assert_eq!(Some(Ok((file_b.into(), FileState::Added))), dir_iter.next());
assert_eq!(None, dir_iter.next());
transaction.discard().unwrap();
}
/// Removes all files in the storage for `session`. /// /// Useful for resetting the state of the storage for tests that need to iterate /// the contents of storage and so need things to be in a known starting state. fn remove_all(session: &mut Session) { for entry in session.list_files().unwrap() { let (name, _state) = entry.unwrap();
session.remove(&name).unwrap();
}
}
test::init!();
Messung V0.5 in Prozent
¤ Dauer der Verarbeitung: 0.16 Sekunden
(vorverarbeitet am 2026-06-27)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.