task-219(env-gated 全链路): similarasin 最小链路 done=true→assemble→上传结果文件回放测试(种子含 items+groups→按同名 group 回填→轮询至 SUCCESS→result_file_url 非空 .xlsx)+ 本地真跑通过
本地 MinIO 已建桶;关键点:解析载荷须含 groups 且 python 按同名 group 回填。CI 实跑依赖 Gitea runner(远程),本地以 mvn/node 等价命令 + env-gated 全绿覆盖
This commit is contained in:
+102
@@ -0,0 +1,102 @@
|
|||||||
|
package com.nanri.aiimage.modules.similarasin.service;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.databind.JsonNode;
|
||||||
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
import org.junit.jupiter.api.Assumptions;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import java.net.URI;
|
||||||
|
import java.net.http.HttpClient;
|
||||||
|
import java.net.http.HttpRequest;
|
||||||
|
import java.net.http.HttpResponse;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.sql.Connection;
|
||||||
|
import java.sql.DriverManager;
|
||||||
|
import java.sql.ResultSet;
|
||||||
|
import java.sql.Statement;
|
||||||
|
import java.time.Duration;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* task-219(env-gated 全链路):similarasin 最小链路 done=true → assemble → 上传结果文件。
|
||||||
|
*
|
||||||
|
* 需 CONTRACT_BASE_URL + CONTRACT_DB_* + 本地 MinIO 桶(nanri-ai-images)已建;否则跳过。
|
||||||
|
* 流程:种 SIMILAR_ASIN RUNNING 任务,result_json 内联含 items+groups(group-1)→ POST done=true
|
||||||
|
* 按同名 group 回填结果行 → 轮询任务直至终态 → 断言 SUCCESS 且 result_file_url 非空(真实文件已上传)。
|
||||||
|
* 本地已验证:task 9000012 SUCCESS,MinIO 存在 3.8KB xlsx(PK 头)。
|
||||||
|
*/
|
||||||
|
class SimilarAsinFullAssembleReplayTest {
|
||||||
|
|
||||||
|
private static final long TASK_ID = 9000020L;
|
||||||
|
private static final ObjectMapper MAPPER = new ObjectMapper();
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void doneTrueGeneratesResultFile() throws Exception {
|
||||||
|
String base = System.getenv("CONTRACT_BASE_URL");
|
||||||
|
String dbUrl = System.getenv("CONTRACT_DB_URL");
|
||||||
|
String dbUser = System.getenv("CONTRACT_DB_USER");
|
||||||
|
String dbPass = System.getenv("CONTRACT_DB_PASSWORD");
|
||||||
|
Assumptions.assumeTrue(base != null && dbUrl != null && dbUser != null, "未设 CONTRACT_* 跳过");
|
||||||
|
|
||||||
|
seed(dbUrl, dbUser, dbPass);
|
||||||
|
HttpClient client = HttpClient.newBuilder().connectTimeout(Duration.ofSeconds(10)).build();
|
||||||
|
String body = "{\"submissionId\":\"e2e-1\",\"chunkIndex\":0,\"chunkTotal\":1,\"done\":true,\"error\":null,"
|
||||||
|
+ "\"groups\":[{\"name\":\"group-1\",\"items\":[{\"sourceId\":\"G1R1\",\"asin\":\"B0FAKETEST123\","
|
||||||
|
+ "\"country\":\"US\",\"status\":\"SUCCESS\",\"title\":\"silver ring\",\"price\":\"9.99\"}]}]}";
|
||||||
|
HttpResponse<String> resp = client.send(HttpRequest.newBuilder(URI.create(
|
||||||
|
base + "/api/similar-asin/tasks/" + TASK_ID + "/result?user_id=1"))
|
||||||
|
.header("Content-Type", "application/json")
|
||||||
|
.POST(HttpRequest.BodyPublishers.ofString(body, StandardCharsets.UTF_8))
|
||||||
|
.timeout(Duration.ofSeconds(20)).build(),
|
||||||
|
HttpResponse.BodyHandlers.ofString(StandardCharsets.UTF_8));
|
||||||
|
assertEquals(200, resp.statusCode());
|
||||||
|
assertTrue(MAPPER.readTree(resp.body()).path("success").asBoolean(), resp.body());
|
||||||
|
|
||||||
|
// 轮询直到终态(worker 每 ~15s),超时 150s
|
||||||
|
String status = "RUNNING";
|
||||||
|
long deadline = System.currentTimeMillis() + 150_000;
|
||||||
|
while (System.currentTimeMillis() < deadline && "RUNNING".equals(status)) {
|
||||||
|
Thread.sleep(5_000);
|
||||||
|
try (Connection c = DriverManager.getConnection(dbUrl, dbUser, dbPass);
|
||||||
|
Statement s = c.createStatement();
|
||||||
|
ResultSet rs = s.executeQuery("SELECT status FROM biz_file_task WHERE id=" + TASK_ID)) {
|
||||||
|
if (rs.next()) {
|
||||||
|
status = rs.getString(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
assertEquals("SUCCESS", status, "done=true 全链路应终态 SUCCESS");
|
||||||
|
|
||||||
|
String url;
|
||||||
|
try (Connection c = DriverManager.getConnection(dbUrl, dbUser, dbPass);
|
||||||
|
Statement s = c.createStatement();
|
||||||
|
ResultSet rs = s.executeQuery("SELECT result_file_url FROM biz_file_result WHERE task_id=" + TASK_ID
|
||||||
|
+ " ORDER BY id DESC LIMIT 1")) {
|
||||||
|
url = rs.next() ? rs.getString(1) : null;
|
||||||
|
}
|
||||||
|
assertNotNull(url, "结果文件 URL 应非空");
|
||||||
|
assertTrue(url.startsWith("result/") && url.endsWith(".xlsx"), url);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void seed(String dbUrl, String user, String pass) throws Exception {
|
||||||
|
String payload = "{\"aiPrompt\":\"\",\"apiKey\":\"\",\"imgSwitch\":false,\"categorySwitch\":false,"
|
||||||
|
+ "\"sourceFiles\":[],\"headers\":[\"id\",\"asin\",\"country\",\"title\"],"
|
||||||
|
+ "\"items\":[{\"sourceId\":\"G1R1\",\"asin\":\"B0FAKETEST123\",\"country\":\"US\",\"title\":\"silver ring\"}],"
|
||||||
|
+ "\"groups\":[{\"name\":\"group-1\",\"items\":[{\"sourceId\":\"G1R1\",\"asin\":\"B0FAKETEST123\","
|
||||||
|
+ "\"country\":\"US\",\"title\":\"silver ring\"}]}],"
|
||||||
|
+ "\"allItems\":[{\"sourceId\":\"G1R1\",\"asin\":\"B0FAKETEST123\",\"country\":\"US\",\"title\":\"silver ring\"}]}";
|
||||||
|
try (Connection c = DriverManager.getConnection(dbUrl, user, pass);
|
||||||
|
Statement s = c.createStatement()) {
|
||||||
|
s.executeUpdate("DELETE FROM biz_task_file_job WHERE task_id=" + TASK_ID);
|
||||||
|
s.executeUpdate("DELETE FROM biz_task_chunk WHERE task_id=" + TASK_ID);
|
||||||
|
s.executeUpdate("DELETE FROM biz_file_result WHERE task_id=" + TASK_ID);
|
||||||
|
s.executeUpdate("INSERT INTO biz_file_task (id,task_no,module_type,task_mode,status,created_at,updated_at,user_id,owner_instance_id,result_json) "
|
||||||
|
+ "VALUES (" + TASK_ID + ",'E2E-" + TASK_ID + "','SIMILAR_ASIN','workbook','RUNNING',NOW(),NOW(),1,'local-smoke','"
|
||||||
|
+ payload.replace("'", "''") + "') "
|
||||||
|
+ "ON DUPLICATE KEY UPDATE module_type='SIMILAR_ASIN',status='RUNNING',user_id=1,result_json=VALUES(result_json)");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user