mirror of
https://github.com/xinnan-tech/xiaozhi-esp32-server.git
synced 2026-07-24 16:13:54 +08:00
fix: harden agent snapshot restore flow
This commit is contained in:
+77
@@ -0,0 +1,77 @@
|
||||
package xiaozhi.modules.agent.service.impl;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertSame;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.springframework.beans.factory.SmartInitializingSingleton;
|
||||
import org.springframework.boot.test.system.CapturedOutput;
|
||||
import org.springframework.boot.test.system.OutputCaptureExtension;
|
||||
import org.springframework.scheduling.annotation.Scheduled;
|
||||
|
||||
import xiaozhi.modules.agent.service.AgentSnapshotService;
|
||||
|
||||
@ExtendWith(OutputCaptureExtension.class)
|
||||
class AgentSnapshotRedactionRunnerTest {
|
||||
|
||||
@Test
|
||||
void startupRedactionRunsSynchronouslyAndReportsCompensationWindow(CapturedOutput output) {
|
||||
assertTrue(SmartInitializingSingleton.class.isAssignableFrom(AgentSnapshotRedactionRunner.class));
|
||||
AgentSnapshotService service = mock(AgentSnapshotService.class);
|
||||
AgentSnapshotRedactionRunner runner = new AgentSnapshotRedactionRunner(service);
|
||||
when(service.redactLegacySnapshots()).thenReturn(0L);
|
||||
|
||||
runner.afterSingletonsInstantiated();
|
||||
|
||||
verify(service).redactLegacySnapshots();
|
||||
assertTrue(output.getAll().contains("startup pass completed"));
|
||||
assertTrue(output.getAll().contains("starts after 5000 ms and repeats every 15000 ms"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void startupRedactionFailureIsLoggedAndPropagatedToKeepStartupFailClosed(CapturedOutput output) {
|
||||
AgentSnapshotService service = mock(AgentSnapshotService.class);
|
||||
AgentSnapshotRedactionRunner runner = new AgentSnapshotRedactionRunner(service);
|
||||
IllegalStateException failure = new IllegalStateException("database unavailable");
|
||||
when(service.redactLegacySnapshots()).thenThrow(failure);
|
||||
|
||||
IllegalStateException thrown = assertThrows(IllegalStateException.class,
|
||||
runner::afterSingletonsInstantiated);
|
||||
|
||||
assertSame(failure, thrown);
|
||||
assertTrue(output.getAll().contains("blocking application startup before it can accept traffic"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void rollingDeploymentRedactionReportsTriggerCountAndCredentialRotation(CapturedOutput output) {
|
||||
AgentSnapshotService service = mock(AgentSnapshotService.class);
|
||||
AgentSnapshotRedactionRunner runner = new AgentSnapshotRedactionRunner(service);
|
||||
when(service.redactLegacySnapshots()).thenReturn(3L);
|
||||
|
||||
runner.redactLateRollingDeploymentWrites();
|
||||
|
||||
assertTrue(output.getAll().contains("trigger=rolling-deployment migrated=3"));
|
||||
assertTrue(output.getAll().contains("Rotate credentials"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void rollingDeploymentScheduleKeepsLegacyWriteExposureWindowShort() throws Exception {
|
||||
Method method = AgentSnapshotRedactionRunner.class.getMethod("redactLateRollingDeploymentWrites");
|
||||
Scheduled scheduled = method.getAnnotation(Scheduled.class);
|
||||
|
||||
assertNotNull(scheduled);
|
||||
assertEquals(5_000, scheduled.initialDelay());
|
||||
assertEquals(15_000, scheduled.fixedDelay());
|
||||
assertTrue(scheduled.initialDelay() <= 10_000);
|
||||
assertTrue(scheduled.fixedDelay() <= 30_000);
|
||||
}
|
||||
}
|
||||
+1382
-29
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user