Skip to content

Commit 3cd2eaf

Browse files
committed
Share DummyFile state between clones in test runtime
Runtime::get_file hands out cloned handles, so reads through fresh handles never advanced the file position. Share pos like the production File impls and make read honor it instead of consuming the buffer.
1 parent 9c64763 commit 3cd2eaf

2 files changed

Lines changed: 53 additions & 7 deletions

File tree

java_runtime/tests/classes/java/io/test_file_input_stream.rs

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,3 +60,42 @@ async fn test_file_input_stream_available() -> Result<()> {
6060

6161
Ok(())
6262
}
63+
64+
#[tokio::test]
65+
async fn test_file_input_stream_sequential_read() -> Result<()> {
66+
let filesystem = [("test.txt".into(), b"hello".to_vec())];
67+
let jvm = test_jvm_filesystem(filesystem.into_iter().collect()).await?;
68+
69+
let file = JavaLangString::from_rust_string(&jvm, "test.txt").await?;
70+
71+
let java_file = jvm.new_class("java/io/File", "(Ljava/lang/String;)V", (file,)).await?;
72+
let fis = jvm.new_class("java/io/FileInputStream", "(Ljava/io/File;)V", (java_file,)).await?;
73+
74+
let mut reads = vec![];
75+
for _ in 0..6 {
76+
reads.push(jvm.invoke_virtual::<_, i32>(&fis, "read", "()I", ()).await?);
77+
}
78+
79+
assert_eq!(reads, vec![104, 101, 108, 108, 111, -1]);
80+
81+
Ok(())
82+
}
83+
84+
#[tokio::test]
85+
async fn test_file_input_stream_skip_past_eof() -> Result<()> {
86+
let filesystem = [("test.txt".into(), b"hello".to_vec())];
87+
let jvm = test_jvm_filesystem(filesystem.into_iter().collect()).await?;
88+
89+
let file = JavaLangString::from_rust_string(&jvm, "test.txt").await?;
90+
91+
let java_file = jvm.new_class("java/io/File", "(Ljava/lang/String;)V", (file,)).await?;
92+
let fis = jvm.new_class("java/io/FileInputStream", "(Ljava/io/File;)V", (java_file,)).await?;
93+
94+
let skipped: i64 = jvm.invoke_virtual(&fis, "skip", "(J)J", (10i64,)).await?;
95+
assert_eq!(skipped, 5);
96+
97+
let read: i32 = jvm.invoke_virtual(&fis, "read", "()I", ()).await?;
98+
assert_eq!(read, -1);
99+
100+
Ok(())
101+
}

test_utils/src/lib.rs

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -158,21 +158,28 @@ impl Runtime for TestRuntime {
158158
#[derive(Clone)]
159159
struct DummyFile {
160160
data: Vec<u8>,
161-
pos: FileSize,
161+
// shared between clones, as Runtime::get_file hands out cloned handles to the same file
162+
pos: Arc<Mutex<FileSize>>,
162163
}
163164

164165
impl DummyFile {
165166
pub fn new(data: Vec<u8>) -> Self {
166-
Self { data, pos: 0 }
167+
Self {
168+
data,
169+
pos: Arc::new(Mutex::new(0)),
170+
}
167171
}
168172
}
169173

170174
#[async_trait::async_trait]
171175
impl File for DummyFile {
172176
async fn read(&mut self, buf: &mut [u8]) -> IOResult<usize> {
173-
let len = min(buf.len(), self.data.len());
174-
buf[..len].copy_from_slice(&self.data[..len]);
175-
self.data = self.data[len..].to_vec();
177+
let mut pos = self.pos.lock().unwrap();
178+
179+
let remaining = &self.data[min(*pos as usize, self.data.len())..];
180+
let len = min(buf.len(), remaining.len());
181+
buf[..len].copy_from_slice(&remaining[..len]);
182+
*pos += len as FileSize;
176183

177184
Ok(len)
178185
}
@@ -182,13 +189,13 @@ impl File for DummyFile {
182189
}
183190

184191
async fn seek(&mut self, pos: FileSize) -> IOResult<()> {
185-
self.pos = pos;
192+
*self.pos.lock().unwrap() = pos;
186193

187194
Ok(())
188195
}
189196

190197
async fn tell(&self) -> IOResult<FileSize> {
191-
Ok(self.pos as _)
198+
Ok(*self.pos.lock().unwrap())
192199
}
193200

194201
async fn set_len(&mut self, _len: FileSize) -> IOResult<()> {

0 commit comments

Comments
 (0)