feat(storage): 新增应用更新目录并切换存储至 S3,新增应用管理日志模块
This commit is contained in:
1 parent
1829238de6
commit
4b746255da
58 files changed
+4906
-10
No files matched your search
@@ -0,0 +1,102 @@
|
||||
package com.youlai.boot.app.update.component;
|
||||
|
||||
import org.junit.jupiter.api.DisplayName;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.io.TempDir;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.SecureRandom;
|
||||
import java.util.Arrays;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
/**
|
||||
* APK 增量差分工具测试。
|
||||
* <p>
|
||||
* 覆盖两点:当前平台能定位到内置的 {@code hdiffz}(且与 classpath 资源逐字节一致,
|
||||
* 防止资源被过滤/损坏);对高度相似的文件生成的补丁明显小于新包。
|
||||
*/
|
||||
@DisplayName("APK 增量差分工具测试")
|
||||
class ApkDeltaUpdaterTest {
|
||||
|
||||
private static final SecureRandom SECURE_RANDOM = new SecureRandom();
|
||||
private static final int SIZE = 4 * 1024 * 1024;
|
||||
private static final int CHANGED_OFFSET = 1024 * 1024;
|
||||
private static final int CHANGED_LENGTH = 256 * 1024;
|
||||
|
||||
@Test
|
||||
@DisplayName("当前平台应定位到可用的内置 hdiffz,且与资源逐字节一致")
|
||||
void shouldPrepareBinaryForCurrentPlatform() throws IOException {
|
||||
ApkDeltaUpdater.Platform platform = ApkDeltaUpdater.currentPlatform();
|
||||
assertNotNull(platform);
|
||||
|
||||
Path hdiffz = ApkDeltaUpdater.binaryDir().resolve(platform.hdiffzName());
|
||||
assertTrue(Files.isRegularFile(hdiffz), "hdiffz 不存在: " + hdiffz);
|
||||
assertTrue(platform.isWindows() || Files.isExecutable(hdiffz), "hdiffz 不可执行: " + hdiffz);
|
||||
assertEquals(sha256OfResource("/hdiffpatch/" + platform.folder() + "/" + platform.hdiffzName()),
|
||||
sha256OfFile(hdiffz), "释放到工作目录的二进制与 classpath 资源不一致");
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("相似文件应生成明显小于新包的补丁")
|
||||
void shouldCreateCompactPatchForSimilarFiles(@TempDir Path dir)
|
||||
throws IOException, InterruptedException {
|
||||
byte[] oldBytes = randomBytes(SIZE);
|
||||
byte[] newBytes = Arrays.copyOf(oldBytes, SIZE);
|
||||
System.arraycopy(randomBytes(CHANGED_LENGTH), 0, newBytes, CHANGED_OFFSET, CHANGED_LENGTH);
|
||||
|
||||
File oldFile = dir.resolve("old.bin").toFile();
|
||||
File newFile = dir.resolve("new.bin").toFile();
|
||||
File patchFile = dir.resolve("delta.patch").toFile();
|
||||
Files.write(oldFile.toPath(), oldBytes);
|
||||
Files.write(newFile.toPath(), newBytes);
|
||||
|
||||
ApkDeltaUpdater.DeltaPlan plan = ApkDeltaUpdater.DeltaPlan.forFiles(oldFile, newFile);
|
||||
assertEquals(ApkDeltaUpdater.SizeTier.SMALL, plan.tier(), "4MB 应落在 SMALL 档");
|
||||
|
||||
ApkDeltaUpdater.createPatch(oldFile, newFile, patchFile, plan);
|
||||
|
||||
long patchSize = patchFile.length();
|
||||
assertTrue(patchSize > 0, "补丁为空");
|
||||
// 仅改动 6.25% 内容,补丁应远小于新包(未改动部分由 hdiffz 以 copy 指令引用)
|
||||
assertTrue(patchSize < newFile.length() / 4,
|
||||
"补丁过大:" + patchSize + " / " + newFile.length());
|
||||
}
|
||||
|
||||
private static byte[] randomBytes(int length) {
|
||||
byte[] bytes = new byte[length];
|
||||
SECURE_RANDOM.nextBytes(bytes);
|
||||
return bytes;
|
||||
}
|
||||
|
||||
private static String sha256OfResource(String resource) throws IOException {
|
||||
try (InputStream in = ApkDeltaUpdater.class.getResourceAsStream(resource)) {
|
||||
assertNotNull(in, "classpath 缺少内置二进制: " + resource);
|
||||
return sha256(in.readAllBytes());
|
||||
}
|
||||
}
|
||||
|
||||
private static String sha256OfFile(Path file) throws IOException {
|
||||
return sha256(Files.readAllBytes(file));
|
||||
}
|
||||
|
||||
private static String sha256(byte[] bytes) {
|
||||
try {
|
||||
MessageDigest digest = MessageDigest.getInstance("SHA-256");
|
||||
StringBuilder text = new StringBuilder();
|
||||
for (byte b : digest.digest(bytes)) {
|
||||
text.append(String.format("%02x", b));
|
||||
}
|
||||
return text.toString();
|
||||
} catch (Exception e) {
|
||||
throw new IllegalStateException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user