feat(ft546): enforce shadow database isolation
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
package com.ruoyi.shadow;
|
||||
|
||||
import com.ruoyi.project.shadowtest.ForbiddenFactoryBean;
|
||||
import com.ruoyi.shadow.startup.ShadowDatabaseGate;
|
||||
import com.ruoyi.shadow.startup.ShadowStartupReport;
|
||||
import com.ruoyi.shadow.web.ShadowStatusController;
|
||||
import com.ruoyi.wcs.application.dispatch.DispatchCoordinator;
|
||||
@@ -11,9 +12,13 @@ import org.springframework.boot.test.context.ConfigDataApplicationContextInitial
|
||||
import org.springframework.boot.test.context.runner.WebApplicationContextRunner;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Primary;
|
||||
import org.springframework.test.web.servlet.MockMvc;
|
||||
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
|
||||
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||
@@ -26,9 +31,10 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
|
||||
class Ft546ShadowApplicationTest {
|
||||
private final WebApplicationContextRunner contextRunner =
|
||||
new WebApplicationContextRunner()
|
||||
.withInitializer(
|
||||
new ConfigDataApplicationContextInitializer())
|
||||
.withUserConfiguration(Ft546ShadowApplication.class);
|
||||
.withInitializer(
|
||||
new ConfigDataApplicationContextInitializer())
|
||||
.withUserConfiguration(Ft546ShadowApplication.class,
|
||||
TestShadowDatabaseGateConfiguration.class);
|
||||
|
||||
@Test
|
||||
void explicitReadOnlyShadowConfigurationStartsTheNarrowContext() {
|
||||
@@ -52,12 +58,17 @@ class Ft546ShadowApplicationTest {
|
||||
.getStartupChecks().get("SHADOW_ENABLED"));
|
||||
assertEquals("PASS", context.getBean(ShadowStartupReport.class)
|
||||
.getStartupChecks().get("SIDE_EFFECT_BEANS_ABSENT"));
|
||||
assertEquals("PENDING", context.getBean(ShadowStartupReport.class)
|
||||
assertEquals("PASS", context.getBean(ShadowStartupReport.class)
|
||||
.getStartupChecks().get("SOURCE_PERMISSIONS_VERIFIED"));
|
||||
assertEquals("PENDING", context.getBean(ShadowStartupReport.class)
|
||||
assertEquals("PASS", context.getBean(ShadowStartupReport.class)
|
||||
.getStartupChecks().get("EVIDENCE_DATABASE_VERIFIED"));
|
||||
assertNotNull(context.getBean(DispatchCoordinator.class));
|
||||
assertNotNull(context.getBean(ShadowStatusController.class));
|
||||
Map<String, String> persisted = context.getBean(
|
||||
RecordingShadowDatabaseGate.class).getPersistedChecks();
|
||||
assertNotNull(persisted);
|
||||
assertEquals(context.getBean(ShadowStartupReport.class)
|
||||
.getStartupChecks(), persisted);
|
||||
assertTrue(context.getBeansOfType(
|
||||
DeviceCommandGateway.class).isEmpty());
|
||||
assertTrue(context.getBeansOfType(
|
||||
@@ -98,18 +109,30 @@ class Ft546ShadowApplicationTest {
|
||||
assertStartupFailure(contextRunner.withPropertyValues(
|
||||
"spring.profiles.active=shadow",
|
||||
"shadow.enabled=true",
|
||||
"shadow.evidence.jdbc-url=jdbc:h2:mem:evidence"),
|
||||
"shadow.evidence.jdbc-url=jdbc:h2:mem:evidence",
|
||||
"shadow.source.username=source",
|
||||
"shadow.evidence.username=evidence"),
|
||||
"SHADOW_SOURCE_JDBC_URL_REQUIRED");
|
||||
assertStartupFailure(contextRunner.withPropertyValues(
|
||||
"spring.profiles.active=shadow",
|
||||
"shadow.enabled=true",
|
||||
"shadow.source.jdbc-url=jdbc:h2:mem:source"),
|
||||
"shadow.source.jdbc-url=jdbc:h2:mem:source",
|
||||
"shadow.source.username=source",
|
||||
"shadow.evidence.username=evidence"),
|
||||
"SHADOW_EVIDENCE_JDBC_URL_REQUIRED");
|
||||
assertStartupFailure(configured(contextRunner).withPropertyValues(
|
||||
"shadow.source.username="),
|
||||
"SHADOW_SOURCE_USERNAME_REQUIRED");
|
||||
assertStartupFailure(configured(contextRunner).withPropertyValues(
|
||||
"shadow.evidence.username="),
|
||||
"SHADOW_EVIDENCE_USERNAME_REQUIRED");
|
||||
assertStartupFailure(contextRunner.withPropertyValues(
|
||||
"spring.profiles.active=shadow",
|
||||
"shadow.enabled=true",
|
||||
"shadow.source.jdbc-url=jdbc:h2:mem:source",
|
||||
"shadow.evidence.jdbc-url=jdbc:h2:mem:evidence",
|
||||
"shadow.source.username=source",
|
||||
"shadow.evidence.username=evidence",
|
||||
"server.address=0.0.0.0"),
|
||||
"SHADOW_STATUS_ADDRESS_MUST_BE_LOOPBACK");
|
||||
}
|
||||
@@ -145,7 +168,9 @@ class Ft546ShadowApplicationTest {
|
||||
"spring.profiles.active=shadow",
|
||||
"shadow.enabled=true",
|
||||
"shadow.source.jdbc-url=jdbc:h2:mem:source",
|
||||
"shadow.evidence.jdbc-url=jdbc:h2:mem:evidence");
|
||||
"shadow.evidence.jdbc-url=jdbc:h2:mem:evidence",
|
||||
"shadow.source.username=source",
|
||||
"shadow.evidence.username=evidence");
|
||||
}
|
||||
|
||||
private static void assertStartupFailure(
|
||||
@@ -197,4 +222,36 @@ class Ft546ShadowApplicationTest {
|
||||
return new ForbiddenFactoryBean();
|
||||
}
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
static class TestShadowDatabaseGateConfiguration {
|
||||
@Bean
|
||||
@Primary
|
||||
RecordingShadowDatabaseGate testShadowDatabaseGate() {
|
||||
return new RecordingShadowDatabaseGate();
|
||||
}
|
||||
}
|
||||
|
||||
static final class RecordingShadowDatabaseGate
|
||||
implements ShadowDatabaseGate {
|
||||
private Map<String, String> persistedChecks;
|
||||
|
||||
@Override
|
||||
public Map<String, String> verify(
|
||||
com.ruoyi.shadow.config.ShadowProperties properties) {
|
||||
Map<String, String> checks =
|
||||
new LinkedHashMap<String, String>();
|
||||
checks.put("SOURCE_PERMISSIONS_VERIFIED", "PASS");
|
||||
checks.put("EVIDENCE_DATABASE_VERIFIED", "PASS");
|
||||
return checks;
|
||||
}
|
||||
|
||||
public void persistChecks(Map<String, String> checks) {
|
||||
persistedChecks = new LinkedHashMap<String, String>(checks);
|
||||
}
|
||||
|
||||
Map<String, String> getPersistedChecks() {
|
||||
return persistedChecks;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user