From 6423987ddfd04b94dfcd65c4d73baa74d6d7cbcc Mon Sep 17 00:00:00 2001 From: lingniu Date: Tue, 23 Jun 2026 16:37:05 +0800 Subject: [PATCH] test: cover split service composition --- .../Gb32960IngestAppCompositionTest.java | 57 +++++++++++++++ .../VehicleAnalyticsAppCompositionTest.java | 72 +++++++++++++++++++ .../VehicleHistoryAppCompositionTest.java | 70 ++++++++++++++++++ 3 files changed, 199 insertions(+) create mode 100644 modules/apps/gb32960-ingest-app/src/test/java/com/lingniu/ingest/gb32960app/Gb32960IngestAppCompositionTest.java create mode 100644 modules/apps/vehicle-analytics-app/src/test/java/com/lingniu/ingest/analyticsapp/VehicleAnalyticsAppCompositionTest.java create mode 100644 modules/apps/vehicle-history-app/src/test/java/com/lingniu/ingest/historyapp/VehicleHistoryAppCompositionTest.java diff --git a/modules/apps/gb32960-ingest-app/src/test/java/com/lingniu/ingest/gb32960app/Gb32960IngestAppCompositionTest.java b/modules/apps/gb32960-ingest-app/src/test/java/com/lingniu/ingest/gb32960app/Gb32960IngestAppCompositionTest.java new file mode 100644 index 00000000..34fee58d --- /dev/null +++ b/modules/apps/gb32960-ingest-app/src/test/java/com/lingniu/ingest/gb32960app/Gb32960IngestAppCompositionTest.java @@ -0,0 +1,57 @@ +package com.lingniu.ingest.gb32960app; + +import com.lingniu.ingest.core.config.IngestCoreAutoConfiguration; +import com.lingniu.ingest.protocol.gb32960.codec.Gb32960MessageDecoder; +import com.lingniu.ingest.protocol.gb32960.config.Gb32960AutoConfiguration; +import com.lingniu.ingest.protocol.gb32960.inbound.Gb32960NettyServer; +import com.lingniu.ingest.session.config.SessionCoreAutoConfiguration; +import com.lingniu.ingest.sink.mq.KafkaEventSink; +import com.lingniu.ingest.sink.mq.SinkMqAutoConfiguration; +import org.junit.jupiter.api.Test; +import org.springframework.boot.autoconfigure.AutoConfigurations; +import org.springframework.boot.test.context.runner.ApplicationContextRunner; +import org.springframework.context.ApplicationContext; +import org.springframework.util.ClassUtils; + +import static org.assertj.core.api.Assertions.assertThat; + +class Gb32960IngestAppCompositionTest { + + private final ApplicationContextRunner contextRunner = new ApplicationContextRunner() + .withConfiguration(AutoConfigurations.of( + IngestCoreAutoConfiguration.class, + SessionCoreAutoConfiguration.class, + SinkMqAutoConfiguration.class, + Gb32960AutoConfiguration.class)) + .withPropertyValues( + "lingniu.ingest.gb32960.enabled=true", + "lingniu.ingest.gb32960.server.enabled=true", + "lingniu.ingest.gb32960.port=0", + "lingniu.ingest.session.store=memory", + "lingniu.ingest.sink.mq.enabled=true", + "lingniu.ingest.sink.mq.type=kafka", + "lingniu.ingest.sink.mq.bootstrap-servers=localhost:9092", + "lingniu.ingest.sink.mq.consumer.enabled=false", + "lingniu.ingest.event-file-store.enabled=false", + "lingniu.ingest.event-history.enabled=false", + "lingniu.ingest.vehicle-state.enabled=false", + "lingniu.ingest.vehicle-stat.enabled=false"); + + @Test + void createsGb32960ListenerWithoutHistoryStorageBoundaries() { + contextRunner.run(context -> { + assertThat(context).hasSingleBean(Gb32960MessageDecoder.class); + assertThat(context).hasSingleBean(Gb32960NettyServer.class); + assertThat(context).hasSingleBean(KafkaEventSink.class); + + assertTypeNotPresent(context, "com.lingniu.ingest.sink.archive.ArchiveStore"); + assertTypeNotPresent(context, "com.lingniu.ingest.eventfilestore.EventFileStore"); + }); + } + + private static void assertTypeNotPresent(ApplicationContext context, String className) { + assertThat(ClassUtils.isPresent(className, context.getClassLoader())) + .as("%s must stay outside the GB32960 ingest runtime", className) + .isFalse(); + } +} diff --git a/modules/apps/vehicle-analytics-app/src/test/java/com/lingniu/ingest/analyticsapp/VehicleAnalyticsAppCompositionTest.java b/modules/apps/vehicle-analytics-app/src/test/java/com/lingniu/ingest/analyticsapp/VehicleAnalyticsAppCompositionTest.java new file mode 100644 index 00000000..9020368d --- /dev/null +++ b/modules/apps/vehicle-analytics-app/src/test/java/com/lingniu/ingest/analyticsapp/VehicleAnalyticsAppCompositionTest.java @@ -0,0 +1,72 @@ +package com.lingniu.ingest.analyticsapp; + +import com.lingniu.ingest.api.consumer.EnvelopeConsumerProcessor; +import com.lingniu.ingest.sink.mq.SinkMqAutoConfiguration; +import com.lingniu.ingest.vehiclestate.VehicleStateEnvelopeIngestor; +import com.lingniu.ingest.vehiclestate.config.VehicleStateAutoConfiguration; +import com.lingniu.ingest.vehiclestat.DailyVehicleStatService; +import com.lingniu.ingest.vehiclestat.FileVehicleStatRepository; +import com.lingniu.ingest.vehiclestat.VehicleStatController; +import com.lingniu.ingest.vehiclestat.VehicleStatEnvelopeIngestor; +import com.lingniu.ingest.vehiclestat.VehicleStatEventProcessor; +import com.lingniu.ingest.vehiclestat.VehicleStatEventSink; +import com.lingniu.ingest.vehiclestat.VehicleStatRepository; +import com.lingniu.ingest.vehiclestat.config.VehicleStatAutoConfiguration; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.io.TempDir; +import org.springframework.boot.autoconfigure.AutoConfigurations; +import org.springframework.boot.test.context.runner.ApplicationContextRunner; +import org.springframework.context.ApplicationContext; +import org.springframework.util.ClassUtils; + +import java.nio.file.Path; + +import static org.assertj.core.api.Assertions.assertThat; + +class VehicleAnalyticsAppCompositionTest { + + @TempDir + Path tempDir; + + @Test + void createsStatsBeansWithoutProtocolListenerOrEventFileStore() { + new ApplicationContextRunner() + .withConfiguration(AutoConfigurations.of( + SinkMqAutoConfiguration.class, + VehicleStateAutoConfiguration.class, + VehicleStatAutoConfiguration.class)) + .withPropertyValues( + "lingniu.ingest.sink.mq.enabled=true", + "lingniu.ingest.sink.mq.type=kafka", + "lingniu.ingest.sink.mq.bootstrap-servers=localhost:9092", + "lingniu.ingest.sink.mq.consumer.enabled=false", + "lingniu.ingest.vehicle-state.enabled=false", + "lingniu.ingest.vehicle-stat.enabled=true", + "lingniu.ingest.vehicle-stat.file-path=" + tempDir.resolve("vehicle-stat"), + "lingniu.ingest.event-file-store.enabled=false", + "lingniu.ingest.event-history.enabled=false", + "lingniu.ingest.gb32960.enabled=false") + .run(context -> { + assertThat(context).hasSingleBean(VehicleStatRepository.class); + assertThat(context).hasSingleBean(FileVehicleStatRepository.class); + assertThat(context).hasSingleBean(DailyVehicleStatService.class); + assertThat(context).hasSingleBean(VehicleStatEventProcessor.class); + assertThat(context).hasSingleBean(VehicleStatEnvelopeIngestor.class); + assertThat(context).hasSingleBean(VehicleStatEventSink.class); + assertThat(context).hasSingleBean(VehicleStatController.class); + assertThat(context).hasBean("vehicleStatEnvelopeConsumerProcessor"); + assertThat(context.getBean("vehicleStatEnvelopeConsumerProcessor")) + .isInstanceOf(EnvelopeConsumerProcessor.class); + + assertThat(context).doesNotHaveBean(VehicleStateEnvelopeIngestor.class); + assertTypeNotPresent(context, "com.lingniu.ingest.protocol.gb32960.inbound.Gb32960NettyServer"); + assertTypeNotPresent(context, "com.lingniu.ingest.eventfilestore.EventFileStore"); + }); + } + + private static void assertTypeNotPresent(ApplicationContext context, String className) { + assertThat(ClassUtils.isPresent(className, context.getClassLoader())) + .as("%s must stay outside the vehicle analytics runtime", className) + .isFalse(); + } +} diff --git a/modules/apps/vehicle-history-app/src/test/java/com/lingniu/ingest/historyapp/VehicleHistoryAppCompositionTest.java b/modules/apps/vehicle-history-app/src/test/java/com/lingniu/ingest/historyapp/VehicleHistoryAppCompositionTest.java new file mode 100644 index 00000000..c505bc6f --- /dev/null +++ b/modules/apps/vehicle-history-app/src/test/java/com/lingniu/ingest/historyapp/VehicleHistoryAppCompositionTest.java @@ -0,0 +1,70 @@ +package com.lingniu.ingest.historyapp; + +import com.lingniu.ingest.eventfilestore.EventFileStore; +import com.lingniu.ingest.eventfilestore.EventFileStoreSink; +import com.lingniu.ingest.eventfilestore.config.EventFileStoreAutoConfiguration; +import com.lingniu.ingest.eventhistory.EventHistoryController; +import com.lingniu.ingest.eventhistory.EventHistoryEnvelopeIngestor; +import com.lingniu.ingest.eventhistory.Gb32960DecodedFrameService; +import com.lingniu.ingest.eventhistory.Gb32960FrameController; +import com.lingniu.ingest.eventhistory.config.EventHistoryAutoConfiguration; +import com.lingniu.ingest.protocol.gb32960.codec.Gb32960MessageDecoder; +import com.lingniu.ingest.protocol.gb32960.config.Gb32960AutoConfiguration; +import com.lingniu.ingest.protocol.gb32960.inbound.Gb32960NettyServer; +import com.lingniu.ingest.sink.archive.ArchiveStore; +import com.lingniu.ingest.sink.archive.RawArchiveEventSink; +import com.lingniu.ingest.sink.archive.config.SinkArchiveAutoConfiguration; +import com.lingniu.ingest.sink.mq.SinkMqAutoConfiguration; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.io.TempDir; +import org.springframework.boot.autoconfigure.AutoConfigurations; +import org.springframework.boot.test.context.runner.ApplicationContextRunner; + +import java.nio.file.Path; + +import static org.assertj.core.api.Assertions.assertThat; + +class VehicleHistoryAppCompositionTest { + + @TempDir + Path tempDir; + + @Test + void createsHistoryStorageAndQueryBeansWithoutGb32960TcpServer() { + new ApplicationContextRunner() + .withConfiguration(AutoConfigurations.of( + SinkArchiveAutoConfiguration.class, + EventFileStoreAutoConfiguration.class, + SinkMqAutoConfiguration.class, + Gb32960AutoConfiguration.class, + EventHistoryAutoConfiguration.class)) + .withPropertyValues( + "lingniu.ingest.sink.archive.enabled=true", + "lingniu.ingest.sink.archive.type=local", + "lingniu.ingest.sink.archive.path=" + tempDir.resolve("archive"), + "lingniu.ingest.event-file-store.enabled=true", + "lingniu.ingest.event-file-store.path=" + tempDir.resolve("event-store"), + "lingniu.ingest.event-history.enabled=true", + "lingniu.ingest.gb32960.enabled=true", + "lingniu.ingest.gb32960.server.enabled=false", + "lingniu.ingest.sink.mq.enabled=true", + "lingniu.ingest.sink.mq.type=kafka", + "lingniu.ingest.sink.mq.bootstrap-servers=localhost:9092", + "lingniu.ingest.sink.mq.consumer.enabled=false", + "lingniu.ingest.vehicle-state.enabled=false", + "lingniu.ingest.vehicle-stat.enabled=false") + .run(context -> { + assertThat(context).hasSingleBean(ArchiveStore.class); + assertThat(context).hasSingleBean(RawArchiveEventSink.class); + assertThat(context).hasSingleBean(EventFileStore.class); + assertThat(context).hasSingleBean(EventFileStoreSink.class); + + assertThat(context).hasSingleBean(EventHistoryEnvelopeIngestor.class); + assertThat(context).hasSingleBean(EventHistoryController.class); + assertThat(context).hasSingleBean(Gb32960MessageDecoder.class); + assertThat(context).hasSingleBean(Gb32960DecodedFrameService.class); + assertThat(context).hasSingleBean(Gb32960FrameController.class); + assertThat(context).doesNotHaveBean(Gb32960NettyServer.class); + }); + } +}