Skip to content

Commit

Permalink
update tests and functions
Browse files Browse the repository at this point in the history
  • Loading branch information
rupeshkoushik07 committed Aug 31, 2024
1 parent 504398c commit abe67ec
Show file tree
Hide file tree
Showing 4 changed files with 105 additions and 59 deletions.
22 changes: 7 additions & 15 deletions src/interface/file.rs
Original file line number Diff line number Diff line change
Expand Up @@ -206,26 +206,18 @@ impl EmulatedFile {
bufs: &[IoSlice<'_>],
offset: usize,
) -> std::io::Result<usize> {
let mut total_bytes_written = 0; //to keep track of the total number of bytes written.

let mut total_bytes_written = 0; // To keep track of the total number of bytes written.
if let Some(f) = &self.fobj {
// checks if the file object (fobj) exists.
let mut file = f.lock();
// Seek to the specified offset from the beginning of the file
file.seek(SeekFrom::Start(offset as u64))?;
// moves the file pointer to the desired starting position (offset) from the
// beginning of the file.

// Use write_vectored for efficient writing from multiple buffers
total_bytes_written = file.write_vectored(bufs)?;
//It performs a vectored write operation,which means it
// writes data to the file from multiple buffers
// Use write_vectored_at directly
total_bytes_written = f.lock().write_vectored_at(bufs, offset as u64)?;
}
// Update recorded filesize if we've written past the previous filesize

// Update the recorded file size if we've written past the previous file size
if offset + total_bytes_written > self.filesize {
self.filesize = offset + total_bytes_written;
}

Ok(total_bytes_written)
}

Expand Down
35 changes: 9 additions & 26 deletions src/interface/misc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -131,34 +131,17 @@ pub fn concat_iovec_to_slice(iovec: *const interface::IovecStruct, iovcnt: i32)
}

//This function logs data from a slice to the specified file descriptor.
// It handles logging to standard output (fd 1) and standard error (fd 2).
// For other file descriptors, it uses a low-level approach to write the data.
// It handles logging to standard output

pub fn log_from_slice(fd: i32, data: &[u8]) -> Result<i32, String> {
match from_utf8(data) {

pub fn log_from_slice(_fd: i32, data: &[u8]) -> Result<i32, String> {
match std::str::from_utf8(data) {
Ok(s) => {
match fd {
1 => {
// File descriptor 1 is standard output
io::stdout()
.write_all(s.as_bytes())
.map_err(|_| "Failed to write to stdout".to_string())?;
}
2 => {
// File descriptor 2 is standard error
io::stderr()
.write_all(s.as_bytes())
.map_err(|_| "Failed to write to stderr".to_string())?;
}
_ => {
// For other file descriptors, we need to use a low-level approach
let result =
unsafe { libc::write(fd, s.as_ptr() as *const libc::c_void, s.len()) };
if result < 0 {
return Err("Failed to write to file descriptor".to_string());
}
}
}
// Log everything to stdout, regardless of the file descriptor provided
io::stdout()
.write_all(s.as_bytes())
.map_err(|_| "Failed to write to stdout".to_string())?;

Ok(data.len() as i32)
}
Err(_) => Err("Failed to convert data to string".to_string()),
Expand Down
1 change: 1 addition & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#![feature(vec_into_raw_parts)]
#![feature(thread_local)]
#![allow(unused_imports)]
#![feature(unix_file_vectored_at)]

//! # RustPOSIX
//! Welcome to the RustPOSIX microvisor.
Expand Down
106 changes: 88 additions & 18 deletions src/tests/fs_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4739,39 +4739,109 @@ pub mod fs_tests {

#[test]
fn ut_lind_fs_writev_pipe() {
//acquiring a lock on TESTMUTEX prevents other tests from running concurrently,
// Acquiring a lock on TESTMUTEX prevents other tests from running concurrently,
// and also performs clean env setup
let _thelock = setup::lock_and_init();
let cage = interface::cagetable_getref(1);

// Create a pipe
let mut pipe_fds = PipeArray::default();
assert_eq!(cage.pipe_syscall(&mut pipe_fds), 0);
let read_fd = pipe_fds.readfd;
let write_fd = pipe_fds.writefd;

// Prepare multiple data segments to be written using an iovec structure
let data1 = b"Hello, ";
let data2 = b"pipe!";
let data3 = b" Testing writev.";

let iovec = [
interface::IovecStruct {
iov_base: data1.as_ptr() as *mut libc::c_void,
iov_len: data1.len(),
},
interface::IovecStruct {
iov_base: data2.as_ptr() as *mut libc::c_void,
iov_len: data2.len(),
},
interface::IovecStruct {
iov_base: data3.as_ptr() as *mut libc::c_void,
iov_len: data3.len(),
},
];

// Write the data to the pipe using writev_syscall
let bytes_written = cage.writev_syscall(write_fd, iovec.as_ptr(), iovec.len() as i32);
assert_eq!(
bytes_written,
(data1.len() + data2.len() + data3.len()) as i32
);

// Read the data from the pipe
let mut buffer = vec![0u8; data1.len() + data2.len() + data3.len()];
let bytes_read = cage.read_syscall(read_fd, buffer.as_mut_ptr(), buffer.len());
assert_eq!(bytes_read, buffer.len() as i32);

// Verify that the data read is the same as the data written
let expected_data = [data1.as_ref(), data2.as_ref(), data3.as_ref()].concat();
assert_eq!(buffer, expected_data);

// Close both pipe file descriptors
assert_eq!(cage.close_syscall(read_fd), 0);
assert_eq!(cage.close_syscall(write_fd), 0);

assert_eq!(cage.exit_syscall(EXIT_SUCCESS), EXIT_SUCCESS);
lindrustfinalize();
}

// Prepare the data to be written using an iovec structure
#[test]
fn ut_lind_fs_writev_file() {
// Acquiring a lock on TESTMUTEX prevents other tests from running concurrently,
// and also performs clean environment setup.
let _thelock = setup::lock_and_init();
let cage = interface::cagetable_getref(1);

let data = b"Hello, pipe!";
let iovec = interface::IovecStruct {
iov_base: data.as_ptr() as *mut libc::c_void,
iov_len: data.len(),
};
// Define the file path
let file_path = "/tmp/test_writev_file";

// Write the data to the pipe using writev_syscall
let bytes_written = cage.writev_syscall(write_fd, &iovec, 1);
assert_eq!(bytes_written, data.len() as i32);
// Open or create a file for writing
let fd = cage.open_syscall(file_path, O_CREAT | O_RDWR, S_IRWXA);
assert!(fd >= 0, "Failed to open file");

// Read the data from the pipe
let mut buffer = vec![0u8; data.len()];
let bytes_read = cage.read_syscall(read_fd, buffer.as_mut_ptr(), buffer.len());
assert_eq!(bytes_read, data.len() as i32);
// Prepare the data to be written using an iovec structure
let data1 = b"Hello, ";
let data2 = b"world!";
let expected_data = [data1.as_slice(), data2.as_slice()].concat(); // Concatenate slices for comparison
let iovecs = [
interface::IovecStruct {
iov_base: data1.as_ptr() as *mut libc::c_void,
iov_len: data1.len(),
},
interface::IovecStruct {
iov_base: data2.as_ptr() as *mut libc::c_void,
iov_len: data2.len(),
},
];

// Write the data to the file using writev_syscall
let total_len = expected_data.len() as i32;
let bytes_written = cage.writev_syscall(fd, iovecs.as_ptr(), iovecs.len() as i32);
assert_eq!(bytes_written, total_len);

// Read the data back from the file
let mut buffer = vec![0u8; total_len as usize];
cage.lseek_syscall(fd, 0, libc::SEEK_SET); // Seek to the beginning of the file
let bytes_read = cage.read_syscall(fd, buffer.as_mut_ptr(), buffer.len());
assert_eq!(bytes_read, total_len);

// Verify that the data read is the same as the data written
assert_eq!(buffer, data);
assert_eq!(buffer, expected_data);

assert_eq!(cage.close_syscall(read_fd), 0);
assert_eq!(cage.close_syscall(write_fd), 0);
// Close the file
assert_eq!(cage.close_syscall(fd), 0);

// Clean up the file
assert_eq!(cage.unlink_syscall(file_path), 0);

assert_eq!(cage.exit_syscall(EXIT_SUCCESS), EXIT_SUCCESS);
lindrustfinalize();
Expand Down

0 comments on commit abe67ec

Please sign in to comment.