task-206: heartbeat 旧字段契约回放(env-gated,真实服务:RUNNING→alive:true、非运行→alive:false、未知任务 alive:false+message、旧/多余字段容忍)+ 已本地真跑
This commit is contained in:
+87
@@ -0,0 +1,87 @@
|
||||
package com.nanri.aiimage.modules.task.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.Statement;
|
||||
import java.time.Duration;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
/**
|
||||
* task-206:heartbeat 旧字段契约回放(真实服务,env-gated)。
|
||||
* CONTRACT_BASE_URL + CONTRACT_DB_* 设则跑、否则跳过(CI 绿)。
|
||||
* 覆盖:RUNNING 任务 heartbeat alive:true(路径/响应字段)、非运行任务 alive:false、未知任务
|
||||
* alive:false+message、缺省/多余(旧)字段容忍。
|
||||
*/
|
||||
class TaskHeartbeatContractReplayTest {
|
||||
|
||||
private static final long TASK_ID = 9000004L;
|
||||
private static final ObjectMapper MAPPER = new ObjectMapper();
|
||||
|
||||
@Test
|
||||
void heartbeatContract() 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, "RUNNING");
|
||||
HttpClient client = HttpClient.newBuilder().connectTimeout(Duration.ofSeconds(10)).build();
|
||||
|
||||
// RUNNING + 旧/额外字段 → alive:true(兼容多余字段)
|
||||
String body = "{\"moduleType\":\"SIMILAR_ASIN\",\"phase\":\"search\",\"current\":1,\"total\":10,"
|
||||
+ "\"collectStage\":\"keyword-search\",\"currentKeyword\":\"ring\",\"searchCurrentPage\":1,"
|
||||
+ "\"searchTotalPages\":4,\"detailProcessedAsins\":1,\"detailTotalAsins\":50,"
|
||||
+ "\"extraLegacyField\":\"ignored\"}";
|
||||
HttpResponse<String> ok = post(client, base + "/api/tasks/" + TASK_ID + "/heartbeat", body);
|
||||
assertEquals(200, ok.statusCode());
|
||||
JsonNode okBody = MAPPER.readTree(ok.body());
|
||||
assertTrue(okBody.path("success").asBoolean(), ok.body());
|
||||
assertTrue(okBody.path("data").path("alive").asBoolean(), "RUNNING 任务应 alive:true: " + ok.body());
|
||||
assertEquals("SIMILAR_ASIN", okBody.path("data").path("moduleType").asText());
|
||||
|
||||
// 非运行 → alive:false
|
||||
seed(dbUrl, dbUser, dbPass, "FINISHED");
|
||||
HttpResponse<String> finished = post(client, base + "/api/tasks/" + TASK_ID + "/heartbeat",
|
||||
"{\"moduleType\":\"SIMILAR_ASIN\",\"phase\":\"search\",\"current\":1,\"total\":1}");
|
||||
JsonNode f = MAPPER.readTree(finished.body());
|
||||
assertFalse(f.path("data").path("alive").asBoolean(), "非运行任务应 alive:false: " + finished.body());
|
||||
|
||||
// 未知任务 → alive:false + message
|
||||
HttpResponse<String> unknown = post(client, base + "/api/tasks/999999999/heartbeat",
|
||||
"{\"moduleType\":\"SIMILAR_ASIN\"}");
|
||||
JsonNode u = MAPPER.readTree(unknown.body());
|
||||
assertFalse(u.path("data").path("alive").asBoolean(), "未知任务应 alive:false");
|
||||
assertTrue(u.path("data").has("message"), "应带 message");
|
||||
}
|
||||
|
||||
private static void seed(String dbUrl, String user, String pass, String status) throws Exception {
|
||||
try (Connection c = DriverManager.getConnection(dbUrl, user, pass);
|
||||
Statement s = c.createStatement()) {
|
||||
s.executeUpdate("INSERT INTO biz_file_task (id,task_no,module_type,task_mode,status,created_at,updated_at,user_id,owner_instance_id) "
|
||||
+ "VALUES (" + TASK_ID + ",'HB-REPLAY-" + TASK_ID + "','SIMILAR_ASIN','workbook','" + status + "',NOW(),NOW(),1,'local-smoke') "
|
||||
+ "ON DUPLICATE KEY UPDATE module_type='SIMILAR_ASIN',status='" + status + "',user_id=1");
|
||||
}
|
||||
}
|
||||
|
||||
private static HttpResponse<String> post(HttpClient client, String url, String body) throws Exception {
|
||||
return client.send(HttpRequest.newBuilder(URI.create(url))
|
||||
.header("Content-Type", "application/json")
|
||||
.POST(HttpRequest.BodyPublishers.ofString(body, StandardCharsets.UTF_8))
|
||||
.timeout(Duration.ofSeconds(15)).build(),
|
||||
HttpResponse.BodyHandlers.ofString(StandardCharsets.UTF_8));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user