package com.eactive.eai.manage.inflow; import static org.junit.jupiter.api.Assertions.*; import static org.mockito.Mockito.*; import java.util.List; import org.junit.jupiter.api.Test; import com.eactive.eai.common.inflow.InflowGroupVO; import com.eactive.eai.common.inflow.dual.DualInflowControlManager; /** * InflowGroupMetricService 단위 테스트. * *

getManager()를 protected로 오버라이드하는 내부 테스트 서브클래스를 사용하여 * mockito-inline(static mock) 없이 DualInflowControlManager 의존성을 주입한다. */ class InflowGroupMetricServiceTest { // ------------------------------------------------------------------------- // 테스트용 서브클래스 — getManager()를 오버라이드하여 mock 주입 // ------------------------------------------------------------------------- private static InflowGroupMetricService serviceWith(DualInflowControlManager manager) { return new InflowGroupMetricService() { @Override protected DualInflowControlManager getManager() { return manager; } }; } // ------------------------------------------------------------------------- // Helpers // ------------------------------------------------------------------------- private InflowGroupVO makeGroupVO(String groupId, String groupName) { InflowGroupVO vo = new InflowGroupVO(); vo.setGroupId(groupId); vo.setGroupName(groupName); vo.setActivate(true); return vo; } private DualInflowControlManager.TargetMetrics makeMetrics(long allowed, long rejPs, long rejTh) { DualInflowControlManager.TargetMetrics m = new DualInflowControlManager.TargetMetrics(); m.allowed.set(allowed); m.rejectedPerSecond.set(rejPs); m.rejectedThreshold.set(rejTh); return m; } // ========================================================================= // getGroupMetric // ========================================================================= @Test void getGroupMetric_managerIsNull_returnsNull() { assertNull(serviceWith(null).getGroupMetric("G1")); } @Test void getGroupMetric_groupNotFound_returnsNull() { DualInflowControlManager manager = mock(DualInflowControlManager.class); when(manager.getGroupInflowThreshold("G1")).thenReturn(null); assertNull(serviceWith(manager).getGroupMetric("G1")); } @Test void getGroupMetric_noMetricsYet_returnsZeroCounters() { DualInflowControlManager manager = mock(DualInflowControlManager.class); when(manager.getGroupInflowThreshold("G1")).thenReturn(makeGroupVO("G1", "결제그룹")); when(manager.getGroupMetrics("G1")).thenReturn(null); GroupMetricDTO dto = serviceWith(manager).getGroupMetric("G1"); assertNotNull(dto); assertEquals("G1", dto.getGroupId()); assertEquals("결제그룹", dto.getGroupName()); assertTrue(dto.isActivate()); assertEquals(0, dto.getAllowed()); assertEquals(0, dto.getRejectedPerSecond()); assertEquals(0, dto.getRejectedThreshold()); assertEquals(0, dto.getTotalRequests()); assertEquals(0.0, dto.getRejectRatio()); assertEquals(0, dto.getLastResetTime()); } @Test void getGroupMetric_withMetrics_returnsCorrectValues() { DualInflowControlManager manager = mock(DualInflowControlManager.class); when(manager.getGroupInflowThreshold("G1")).thenReturn(makeGroupVO("G1", "결제그룹")); when(manager.getGroupMetrics("G1")).thenReturn(makeMetrics(900, 60, 40)); GroupMetricDTO dto = serviceWith(manager).getGroupMetric("G1"); assertEquals(900, dto.getAllowed()); assertEquals(60, dto.getRejectedPerSecond()); assertEquals(40, dto.getRejectedThreshold()); assertEquals(1000, dto.getTotalRequests()); } @Test void getGroupMetric_rejectRatioCalculation() { DualInflowControlManager manager = mock(DualInflowControlManager.class); when(manager.getGroupInflowThreshold("G1")).thenReturn(makeGroupVO("G1", "G1")); // allowed=90, rejPs=5, rejTh=5 → reject=10/100 = 10.00% when(manager.getGroupMetrics("G1")).thenReturn(makeMetrics(90, 5, 5)); GroupMetricDTO dto = serviceWith(manager).getGroupMetric("G1"); assertEquals(10.0, dto.getRejectRatio(), 0.01); } @Test void getGroupMetric_zeroTotal_rejectRatioIsZero() { DualInflowControlManager manager = mock(DualInflowControlManager.class); when(manager.getGroupInflowThreshold("G1")).thenReturn(makeGroupVO("G1", "G1")); when(manager.getGroupMetrics("G1")).thenReturn(makeMetrics(0, 0, 0)); GroupMetricDTO dto = serviceWith(manager).getGroupMetric("G1"); assertEquals(0.0, dto.getRejectRatio(), 0.0001); } @Test void getGroupMetric_lastResetTimeIsPropagated() { DualInflowControlManager.TargetMetrics m = makeMetrics(10, 0, 0); m.lastResetTime = 1234567890L; DualInflowControlManager manager = mock(DualInflowControlManager.class); when(manager.getGroupInflowThreshold("G1")).thenReturn(makeGroupVO("G1", "G1")); when(manager.getGroupMetrics("G1")).thenReturn(m); GroupMetricDTO dto = serviceWith(manager).getGroupMetric("G1"); assertEquals(1234567890L, dto.getLastResetTime()); } // ========================================================================= // getAllGroupMetrics // ========================================================================= @Test void getAllGroupMetrics_managerIsNull_returnsEmptyList() { List result = serviceWith(null).getAllGroupMetrics(); assertNotNull(result); assertTrue(result.isEmpty()); } @Test void getAllGroupMetrics_noGroups_returnsEmptyList() { DualInflowControlManager manager = mock(DualInflowControlManager.class); when(manager.getGroupAllKeys()).thenReturn(new String[]{}); assertTrue(serviceWith(manager).getAllGroupMetrics().isEmpty()); } @Test void getAllGroupMetrics_twoGroups_returnsBoth() { DualInflowControlManager manager = mock(DualInflowControlManager.class); when(manager.getGroupAllKeys()).thenReturn(new String[]{"G1", "G2"}); when(manager.getGroupInflowThreshold("G1")).thenReturn(makeGroupVO("G1", "그룹1")); when(manager.getGroupInflowThreshold("G2")).thenReturn(makeGroupVO("G2", "그룹2")); when(manager.getGroupMetrics("G1")).thenReturn(makeMetrics(10, 0, 0)); when(manager.getGroupMetrics("G2")).thenReturn(makeMetrics(20, 5, 0)); List result = serviceWith(manager).getAllGroupMetrics(); assertEquals(2, result.size()); assertEquals("G1", result.get(0).getGroupId()); assertEquals("G2", result.get(1).getGroupId()); } @Test void getAllGroupMetrics_groupNotFoundIsSkipped() { DualInflowControlManager manager = mock(DualInflowControlManager.class); when(manager.getGroupAllKeys()).thenReturn(new String[]{"G1", "GHOST"}); when(manager.getGroupInflowThreshold("G1")).thenReturn(makeGroupVO("G1", "그룹1")); when(manager.getGroupInflowThreshold("GHOST")).thenReturn(null); when(manager.getGroupMetrics("G1")).thenReturn(makeMetrics(5, 0, 0)); List result = serviceWith(manager).getAllGroupMetrics(); assertEquals(1, result.size()); assertEquals("G1", result.get(0).getGroupId()); } // ========================================================================= // resetGroupMetric // ========================================================================= @Test void resetGroupMetric_managerIsNull_returnsFalse() { assertFalse(serviceWith(null).resetGroupMetric("G1")); } @Test void resetGroupMetric_groupNotFound_returnsFalse() { DualInflowControlManager manager = mock(DualInflowControlManager.class); when(manager.getGroupInflowThreshold("G1")).thenReturn(null); assertFalse(serviceWith(manager).resetGroupMetric("G1")); verify(manager, never()).resetGroupMetrics(any()); } @Test void resetGroupMetric_success_returnsTrueAndCallsManager() { DualInflowControlManager manager = mock(DualInflowControlManager.class); when(manager.getGroupInflowThreshold("G1")).thenReturn(makeGroupVO("G1", "그룹1")); assertTrue(serviceWith(manager).resetGroupMetric("G1")); verify(manager).resetGroupMetrics("G1"); } // ========================================================================= // resetAllGroupMetrics // ========================================================================= @Test void resetAllGroupMetrics_managerIsNull_noException() { assertDoesNotThrow(() -> serviceWith(null).resetAllGroupMetrics()); } @Test void resetAllGroupMetrics_callsManagerReset() { DualInflowControlManager manager = mock(DualInflowControlManager.class); serviceWith(manager).resetAllGroupMetrics(); verify(manager).resetAllGroupMetrics(); } }