feat(self-operated): expose private runtime configuration snapshots
This commit is contained in:
+57
@@ -4,6 +4,63 @@ import org.junit.jupiter.api.Test;
|
||||
import static org.mockito.Mockito.*;
|
||||
import static org.assertj.core.api.Assertions.*;
|
||||
class SelfopEgressControllerTest {
|
||||
@Test void runtimeRequiresInternalTokenBeforeReadingConfiguration(){
|
||||
var service=mock(SelfopEgressService.class);var c=new SelfopEgressController(new InternalServiceTokenGuard("synthetic"),service);
|
||||
for(String token:new String[]{null,"","wrong"})assertThatThrownBy(()->c.runtime(token))
|
||||
.isInstanceOf(org.springframework.web.server.ResponseStatusException.class)
|
||||
.satisfies(e->assertThat(((org.springframework.web.server.ResponseStatusException)e).getStatusCode().value()).isEqualTo(401));
|
||||
verifyNoInteractions(service);
|
||||
var missing=new SelfopEgressController(new InternalServiceTokenGuard(""),service);
|
||||
assertThatThrownBy(()->missing.runtime("synthetic")).isInstanceOf(org.springframework.web.server.ResponseStatusException.class)
|
||||
.satisfies(e->assertThat(((org.springframework.web.server.ResponseStatusException)e).getStatusCode().value()).isEqualTo(503));
|
||||
verifyNoInteractions(service);c.runtime("synthetic");verify(service).runtime();
|
||||
}
|
||||
@Test void runtimeUsesExecutionConfigurationAndSerializesOnlyWhitelistedFields() throws Exception {
|
||||
var storage=mock(SelfopEgressMapper.class);var config=new com.baiyue.lastleg.selfoperated.analytics.model.SelfopAnalyticsProperties();
|
||||
config.setCollectionMode("BUSINESS");config.setEnvironment("test");config.setContinuousBusinessCollectionEnabled(true);
|
||||
config.setSourceAccount("synthetic-private-account");config.setExclusiveGrantId("synthetic-private-grant");
|
||||
config.setInternalServiceToken("synthetic-private-token");config.setIntegrationBaseUrl("http://synthetic-private-host");
|
||||
config.setBusinessMinRequestIntervalMs(1200);config.setEgressLeaseSeconds(999);
|
||||
config.setExclusiveHandoffVerified(true);config.setPriorEgressClosed(true);config.setInflightDrained(true);config.setTransferredBudgetVerified(true);
|
||||
var now=java.time.Instant.parse("2026-10-13T00:00:00Z");
|
||||
var service=new SelfopEgressService(storage,config,java.time.Clock.fixed(now,java.time.ZoneOffset.UTC));
|
||||
var controller=new SelfopEgressController(new InternalServiceTokenGuard("synthetic"),service);
|
||||
var response=controller.runtime("synthetic");var runtime=response.data();
|
||||
assertThat(runtime.schemaVersion()).isEqualTo(1);assertThat(runtime.service()).isEqualTo("lastleg");assertThat(runtime.observedAt()).isEqualTo(now);
|
||||
assertThat(runtime.mode()).isEqualTo("BUSINESS");assertThat(runtime.environment()).isEqualTo("test");assertThat(runtime.continuousEnabled()).isTrue();
|
||||
assertThat(runtime.intervalMs()).isEqualTo(1200);assertThat(runtime.permitMaxSeconds()).isEqualTo(30);assertThat(runtime.pendingMaxSeconds()).isEqualTo(120);
|
||||
assertThat(runtime.executionEnabled()).isTrue();assertThat(runtime.grantPresent()).isTrue();
|
||||
assertThat(runtime.exclusiveHandoffVerified()&&runtime.priorEgressClosed()&&runtime.inflightDrained()&&runtime.transferredBudgetVerified()).isTrue();
|
||||
var mapper=new com.fasterxml.jackson.databind.ObjectMapper().findAndRegisterModules().disable(com.fasterxml.jackson.databind.SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
|
||||
String serialized=mapper.writeValueAsString(response);var data=mapper.readTree(serialized).path("data");
|
||||
var names=new java.util.HashSet<String>();data.fieldNames().forEachRemaining(names::add);
|
||||
assertThat(names).containsExactlyInAnyOrder("schemaVersion","service","observedAt","mode","environment","continuousEnabled",
|
||||
"sourceAccountFingerprint","grantPresent","grantFingerprint","intervalMs","permitMaxSeconds","executionEnabled","pendingMaxSeconds",
|
||||
"exclusiveHandoffVerified","priorEgressClosed","inflightDrained","transferredBudgetVerified");
|
||||
assertThat(serialized).doesNotContain("synthetic-private-account","synthetic-private-grant","synthetic-private-token","synthetic-private-host");
|
||||
config.setCollectionMode("VALIDATION");config.setContinuousBusinessCollectionEnabled(false);config.setBusinessMinRequestIntervalMs(5000);config.setEgressLeaseSeconds(0);
|
||||
var changed=controller.runtime("synthetic").data();assertThat(changed.mode()).isEqualTo("VALIDATION");assertThat(changed.continuousEnabled()).isFalse();
|
||||
assertThat(changed.intervalMs()).isEqualTo(5000);assertThat(changed.pendingMaxSeconds()).isEqualTo(1);
|
||||
assertThat(runtime.mode()).isEqualTo("BUSINESS");verifyNoInteractions(storage);
|
||||
}
|
||||
@Test void runtimeFingerprintsUseRawUtf8WithSeparateDomainsAndExplicitNulls() throws Exception {
|
||||
var storage=mock(SelfopEgressMapper.class);var config=new com.baiyue.lastleg.selfoperated.analytics.model.SelfopAnalyticsProperties();
|
||||
var service=new SelfopEgressService(storage,config);
|
||||
String value=" fixture-账户 ";config.setSourceAccount(value);config.setExclusiveGrantId(value);
|
||||
var digest=java.security.MessageDigest.getInstance("SHA-256");var hex=java.util.HexFormat.of();
|
||||
var runtime=service.runtime();
|
||||
assertThat(runtime.sourceAccountFingerprint()).isEqualTo(hex.formatHex(digest.digest(("selfop-runtime:v1:source-account\n"+value).getBytes(java.nio.charset.StandardCharsets.UTF_8))));
|
||||
assertThat(runtime.grantFingerprint()).isEqualTo(hex.formatHex(digest.digest(("selfop-runtime:v1:grant\n"+value).getBytes(java.nio.charset.StandardCharsets.UTF_8))));
|
||||
assertThat(runtime.sourceAccountFingerprint()).isNotEqualTo(runtime.grantFingerprint());
|
||||
config.setExclusiveGrantId(value.trim());assertThat(service.runtime().grantFingerprint()).isNotEqualTo(runtime.grantFingerprint());
|
||||
var mapper=new com.fasterxml.jackson.databind.ObjectMapper().findAndRegisterModules();
|
||||
for(String empty:new String[]{null,""," \t"}){
|
||||
config.setSourceAccount(empty);config.setExclusiveGrantId(empty);var absent=service.runtime();
|
||||
assertThat(absent.grantPresent()).isFalse();assertThat(absent.grantFingerprint()).isNull();assertThat(absent.sourceAccountFingerprint()).isNull();
|
||||
var node=mapper.valueToTree(absent);assertThat(node.has("grantFingerprint")).isTrue();assertThat(node.path("grantFingerprint").isNull()).isTrue();
|
||||
}
|
||||
verifyNoInteractions(storage);
|
||||
}
|
||||
@Test void invalidInternalTokenCannotReachAuthority(){
|
||||
var service=mock(SelfopEgressService.class);var c=new SelfopEgressController(new InternalServiceTokenGuard("synthetic"),service);
|
||||
assertThatThrownBy(()->c.authorize("other",null)).isInstanceOf(org.springframework.web.server.ResponseStatusException.class).satisfies(e->assertThat(((org.springframework.web.server.ResponseStatusException)e).getStatusCode().value()).isEqualTo(401));
|
||||
|
||||
Reference in New Issue
Block a user