test(alerting): decentralize @MockBean + add SpringContextSmokeIT (follow-up to #141) #142
@@ -1,10 +1,7 @@
|
||||
package com.cameleer.server.app;
|
||||
|
||||
import com.cameleer.server.app.search.ClickHouseSearchIndex;
|
||||
import com.cameleer.server.core.agent.AgentRegistryService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.boot.test.mock.mockito.MockBean;
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
import org.springframework.test.context.ActiveProfiles;
|
||||
import org.springframework.test.context.DynamicPropertyRegistry;
|
||||
@@ -17,12 +14,6 @@ import org.testcontainers.containers.PostgreSQLContainer;
|
||||
@ActiveProfiles("test")
|
||||
public abstract class AbstractPostgresIT {
|
||||
|
||||
// Mocked infrastructure beans required by the full application context.
|
||||
// ClickHouseSearchIndex is not available in test without explicit ClickHouse wiring,
|
||||
// and AgentRegistryService requires in-memory state that tests manage directly.
|
||||
@MockBean(name = "clickHouseSearchIndex") protected ClickHouseSearchIndex clickHouseSearchIndex;
|
||||
@MockBean protected AgentRegistryService agentRegistryService;
|
||||
|
||||
static final PostgreSQLContainer<?> postgres;
|
||||
static final ClickHouseContainer clickhouse;
|
||||
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
package com.cameleer.server.app;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
/**
|
||||
* Asserts the full production Spring context loads without any @MockBean
|
||||
* replacements. This is the regression test for the #141 crashloop — declared
|
||||
* bean types must match autowire expectations end-to-end.
|
||||
*/
|
||||
class SpringContextSmokeIT extends AbstractPostgresIT {
|
||||
|
||||
@Test
|
||||
void contextLoads() {
|
||||
// no-op: @SpringBootTest refresh is the assertion
|
||||
}
|
||||
}
|
||||
@@ -3,6 +3,7 @@ package com.cameleer.server.app.alerting;
|
||||
import com.cameleer.server.app.AbstractPostgresIT;
|
||||
import com.cameleer.server.app.TestSecurityHelper;
|
||||
import com.cameleer.server.app.search.ClickHouseLogStore;
|
||||
import com.cameleer.server.core.agent.AgentRegistryService;
|
||||
import com.cameleer.server.core.alerting.*;
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
@@ -26,7 +27,7 @@ import static org.mockito.Mockito.when;
|
||||
*/
|
||||
class AlertingEnvIsolationIT extends AbstractPostgresIT {
|
||||
|
||||
// AbstractPostgresIT already declares clickHouseSearchIndex + agentRegistryService mocks.
|
||||
@MockBean AgentRegistryService agentRegistryService;
|
||||
@MockBean(name = "clickHouseLogStore") ClickHouseLogStore clickHouseLogStore;
|
||||
|
||||
@Autowired private TestRestTemplate restTemplate;
|
||||
|
||||
@@ -49,8 +49,6 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
@TestInstance(Lifecycle.PER_CLASS)
|
||||
class AlertingFullLifecycleIT extends AbstractPostgresIT {
|
||||
|
||||
// AbstractPostgresIT already declares clickHouseSearchIndex + agentRegistryService mocks.
|
||||
|
||||
// Replace the alertingClock bean so we can control time in re-notify test
|
||||
@MockBean(name = "alertingClock") Clock alertingClock;
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@ package com.cameleer.server.app.alerting;
|
||||
import com.cameleer.server.app.AbstractPostgresIT;
|
||||
import com.cameleer.server.app.TestSecurityHelper;
|
||||
import com.cameleer.server.app.search.ClickHouseLogStore;
|
||||
import com.cameleer.server.core.agent.AgentRegistryService;
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
@@ -31,7 +32,7 @@ import static org.mockito.Mockito.when;
|
||||
*/
|
||||
class OutboundConnectionAllowedEnvIT extends AbstractPostgresIT {
|
||||
|
||||
// AbstractPostgresIT already declares clickHouseSearchIndex + agentRegistryService mocks.
|
||||
@MockBean AgentRegistryService agentRegistryService;
|
||||
@MockBean(name = "clickHouseLogStore") ClickHouseLogStore clickHouseLogStore;
|
||||
|
||||
@Autowired private TestRestTemplate restTemplate;
|
||||
|
||||
@@ -3,6 +3,7 @@ package com.cameleer.server.app.alerting.eval;
|
||||
import com.cameleer.server.app.AbstractPostgresIT;
|
||||
import com.cameleer.server.app.search.ClickHouseLogStore;
|
||||
import com.cameleer.server.core.agent.AgentInfo;
|
||||
import com.cameleer.server.core.agent.AgentRegistryService;
|
||||
import com.cameleer.server.core.agent.AgentState;
|
||||
import com.cameleer.server.core.alerting.*;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
@@ -23,19 +24,15 @@ import static org.mockito.Mockito.when;
|
||||
* Integration test for {@link AlertEvaluatorJob}.
|
||||
* <p>
|
||||
* Uses real Postgres (Testcontainers) for the full claim→persist pipeline.
|
||||
* {@code ClickHouseSearchIndex} and {@code ClickHouseLogStore} are mocked so
|
||||
* {@code ExchangeMatchEvaluator} and {@code LogPatternEvaluator} wire up even
|
||||
* though those concrete types are not directly registered as Spring beans.
|
||||
* {@code ClickHouseLogStore} is mocked so {@code LogPatternEvaluator} wires up
|
||||
* without requiring real ClickHouse query behaviour.
|
||||
* {@code AgentRegistryService} is mocked so tests can control which agents
|
||||
* are DEAD without depending on in-memory timing.
|
||||
*/
|
||||
class AlertEvaluatorJobIT extends AbstractPostgresIT {
|
||||
|
||||
// Replace the named beans so ExchangeMatchEvaluator / LogPatternEvaluator can wire their
|
||||
// concrete-type constructor args without duplicating the SearchIndex / LogIndex beans.
|
||||
@MockBean(name = "clickHouseLogStore") ClickHouseLogStore clickHouseLogStore;
|
||||
|
||||
// Control agent state per test without timing sensitivity
|
||||
@MockBean AgentRegistryService agentRegistryService;
|
||||
|
||||
@Autowired private AlertEvaluatorJob job;
|
||||
@Autowired private AlertRuleRepository ruleRepo;
|
||||
|
||||
@@ -2,6 +2,7 @@ package com.cameleer.server.app.alerting.notify;
|
||||
|
||||
import com.cameleer.server.app.AbstractPostgresIT;
|
||||
import com.cameleer.server.app.search.ClickHouseLogStore;
|
||||
import com.cameleer.server.core.agent.AgentRegistryService;
|
||||
import com.cameleer.server.core.alerting.*;
|
||||
import com.cameleer.server.core.http.TrustMode;
|
||||
import com.cameleer.server.core.outbound.OutboundAuth;
|
||||
@@ -35,6 +36,7 @@ import static org.mockito.Mockito.*;
|
||||
class NotificationDispatchJobIT extends AbstractPostgresIT {
|
||||
|
||||
@MockBean(name = "clickHouseLogStore") ClickHouseLogStore clickHouseLogStore;
|
||||
@MockBean AgentRegistryService agentRegistryService;
|
||||
|
||||
/** Mock the dispatcher — we control outcomes per test. */
|
||||
@MockBean WebhookDispatcher webhookDispatcher;
|
||||
|
||||
@@ -30,8 +30,6 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
*/
|
||||
class AlertingRetentionJobIT extends AbstractPostgresIT {
|
||||
|
||||
// AbstractPostgresIT already declares clickHouseSearchIndex + agentRegistryService mocks.
|
||||
// Declare only the additional mock needed by this test.
|
||||
@MockBean(name = "clickHouseLogStore") ClickHouseLogStore clickHouseLogStore;
|
||||
|
||||
@Autowired private AlertingRetentionJob job;
|
||||
|
||||
Reference in New Issue
Block a user