task-149: 临时文件时间元数据补缺(TempFileMetadata 创建/修改/访问时间与大小读取,mtime 回退不改变清理语义,IO 错误容忍)+ 8 条测试

This commit is contained in:
2026-09-02 06:08:50 +08:00
parent 383ec544e1
commit dd569edc66
3 changed files with 168 additions and 1 deletions
@@ -0,0 +1,109 @@
package com.nanri.aiimage.modules.file.service;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.io.TempDir;
import java.io.File;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.time.Instant;
import java.time.temporal.ChronoUnit;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertTrue;
/**
* task-149:临时文件创建/访问时间记录契约(plan 09)。
* 创建时间/大小显式读取;最后访问时间以 mtime 回退(与清理语义一致);
* 缺记录/IO 错误容忍,不改变文件语义。
*/
class TempFileMetadataTest {
@TempDir
Path tempDir;
private File writeTempFile(String name, String content) throws Exception {
Path path = tempDir.resolve(name);
Files.writeString(path, content, StandardCharsets.UTF_8);
return path.toFile();
}
@Test
void creationTimeRecorded() throws Exception {
File file = writeTempFile("a.tmp", "hello");
Instant creation = TempFileMetadata.creationTime(file);
assertNotNull(creation);
assertFalse(creation.isAfter(Instant.now().plus(1, ChronoUnit.MINUTES)),
"创建时间不得晚于当前时间");
}
@Test
void sizeRecorded() throws Exception {
File file = writeTempFile("b.tmp", "0123456789");
assertEquals(10L, TempFileMetadata.size(file), "大小按字节记录");
}
@Test
void accessTimeReadable() throws Exception {
File file = writeTempFile("c.tmp", "x");
Instant access = TempFileMetadata.lastAccessTime(file);
assertNotNull(access);
assertFalse(access.isAfter(Instant.now().plus(1, ChronoUnit.MINUTES)));
}
@Test
void accessTimeFallsBackToMtime() throws Exception {
File file = writeTempFile("d.tmp", "y");
assertEquals(TempFileMetadata.lastModified(file), TempFileMetadata.lastAccessTime(file),
"无独立访问记录时以 mtime 回退(清理语义不变)");
}
@Test
void modifiedTimeUpdatesOnWrite() throws Exception {
File file = writeTempFile("e.tmp", "v1");
Instant before = TempFileMetadata.lastModified(file);
Thread.sleep(20);
Files.writeString(file.toPath(), "v2-longer-content", StandardCharsets.UTF_8);
Instant after = TempFileMetadata.lastModified(file);
assertFalse(after.isBefore(before), "写入后 mtime 必须更新");
}
@Test
void missingFileIsGraceful() {
File missing = tempDir.resolve("nope.tmp").toFile();
assertEquals(0L, TempFileMetadata.size(missing), "缺失文件大小为 0");
assertNotNull(TempFileMetadata.creationTime(missing), "缺失文件不回退抛错");
assertNotNull(TempFileMetadata.lastAccessTime(missing));
}
@Test
void nullFileIsGraceful() {
assertEquals(0L, TempFileMetadata.size(null));
assertEquals(Instant.EPOCH, TempFileMetadata.lastModified(null), "null 文件回退 EPOCH");
assertEquals(Instant.EPOCH, TempFileMetadata.lastAccessTime(null));
}
@Test
void timeOrderingConsistent() throws Exception {
File file = writeTempFile("f.tmp", "z");
Instant creation = TempFileMetadata.creationTime(file);
Instant modified = TempFileMetadata.lastModified(file);
Instant now = Instant.now().plus(1, ChronoUnit.MINUTES);
assertTrue(!creation.isAfter(modified.plus(1, ChronoUnit.SECONDS)),
"创建时间 <= 修改时间(容忍文件系统时钟精度)");
assertTrue(!modified.isAfter(now), "修改时间 <= 当前时间");
}
}