From 586dad660ec0bf8320dead1744724cef8cefac9d Mon Sep 17 00:00:00 2001 From: flycash Date: Mon, 22 Apr 2019 23:51:49 +0800 Subject: [PATCH] add unit tests for alarm-plugin module --- .../provider/grpc/GRPCExporterTest.java | 2 +- ...catior.java => MockIntValueIndicator.java} | 2 +- .../server/core/alarm/provider/AlarmCore.java | 22 +- .../provider/AlarmModuleProviderTest.java | 86 ++++++ .../alarm/provider/NotifyHandlerTest.java | 253 ++++++++++++++++++ .../core/alarm/provider/ThresholdTest.java | 49 ++++ 6 files changed, 400 insertions(+), 14 deletions(-) rename oap-server/exporter/src/test/java/org/apache/skywalking/oap/server/exporter/provider/grpc/{MockIntValueIndicatior.java => MockIntValueIndicator.java} (92%) create mode 100644 oap-server/server-alarm-plugin/src/test/java/org/apache/skywalking/oap/server/core/alarm/provider/AlarmModuleProviderTest.java create mode 100644 oap-server/server-alarm-plugin/src/test/java/org/apache/skywalking/oap/server/core/alarm/provider/NotifyHandlerTest.java create mode 100644 oap-server/server-alarm-plugin/src/test/java/org/apache/skywalking/oap/server/core/alarm/provider/ThresholdTest.java diff --git a/oap-server/exporter/src/test/java/org/apache/skywalking/oap/server/exporter/provider/grpc/GRPCExporterTest.java b/oap-server/exporter/src/test/java/org/apache/skywalking/oap/server/exporter/provider/grpc/GRPCExporterTest.java index 815875629cd3..f4fcca2288e3 100644 --- a/oap-server/exporter/src/test/java/org/apache/skywalking/oap/server/exporter/provider/grpc/GRPCExporterTest.java +++ b/oap-server/exporter/src/test/java/org/apache/skywalking/oap/server/exporter/provider/grpc/GRPCExporterTest.java @@ -95,7 +95,7 @@ public void onExit() { private List dataList() { List dataList = new LinkedList<>(); dataList.add(exporter.new ExportData(metaInfo, new MockIndicator())); - dataList.add(exporter.new ExportData(metaInfo, new MockIntValueIndicatior())); + dataList.add(exporter.new ExportData(metaInfo, new MockIntValueIndicator())); dataList.add(exporter.new ExportData(metaInfo, new MockLongValueIndicator())); dataList.add(exporter.new ExportData(metaInfo, new MockDoubleValueIndicator())); return dataList; diff --git a/oap-server/exporter/src/test/java/org/apache/skywalking/oap/server/exporter/provider/grpc/MockIntValueIndicatior.java b/oap-server/exporter/src/test/java/org/apache/skywalking/oap/server/exporter/provider/grpc/MockIntValueIndicator.java similarity index 92% rename from oap-server/exporter/src/test/java/org/apache/skywalking/oap/server/exporter/provider/grpc/MockIntValueIndicatior.java rename to oap-server/exporter/src/test/java/org/apache/skywalking/oap/server/exporter/provider/grpc/MockIntValueIndicator.java index cd3b9277e92f..509727f64335 100644 --- a/oap-server/exporter/src/test/java/org/apache/skywalking/oap/server/exporter/provider/grpc/MockIntValueIndicatior.java +++ b/oap-server/exporter/src/test/java/org/apache/skywalking/oap/server/exporter/provider/grpc/MockIntValueIndicator.java @@ -23,7 +23,7 @@ /** * Created by dengming, 2019.04.20 */ -public class MockIntValueIndicatior extends MockIndicator implements IntValueHolder { +public class MockIntValueIndicator extends MockIndicator implements IntValueHolder { @Override public int getValue() { return 12; diff --git a/oap-server/server-alarm-plugin/src/main/java/org/apache/skywalking/oap/server/core/alarm/provider/AlarmCore.java b/oap-server/server-alarm-plugin/src/main/java/org/apache/skywalking/oap/server/core/alarm/provider/AlarmCore.java index a0a735ca5bea..1b83b07125a6 100644 --- a/oap-server/server-alarm-plugin/src/main/java/org/apache/skywalking/oap/server/core/alarm/provider/AlarmCore.java +++ b/oap-server/server-alarm-plugin/src/main/java/org/apache/skywalking/oap/server/core/alarm/provider/AlarmCore.java @@ -18,12 +18,6 @@ package org.apache.skywalking.oap.server.core.alarm.provider; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.concurrent.Executors; -import java.util.concurrent.TimeUnit; import org.apache.skywalking.oap.server.core.alarm.AlarmCallback; import org.apache.skywalking.oap.server.core.alarm.AlarmMessage; import org.joda.time.LocalDateTime; @@ -31,6 +25,13 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.Executors; +import java.util.concurrent.TimeUnit; + /** * Alarm core includes metric values in certain time windows based on alarm settings. By using its internal timer * trigger and the alarm rules to decides whether send the alarm to database and webhook(s) @@ -50,11 +51,8 @@ public class AlarmCore { String indicatorName = rule.getIndicatorName(); - List runningRules = runningContext.get(indicatorName); - if (runningRules == null) { - runningRules = new ArrayList<>(); - runningContext.put(indicatorName, runningRules); - } + List runningRules = runningContext.computeIfAbsent(indicatorName, key -> new ArrayList<>()); + runningRules.add(runningRule); }); } @@ -71,7 +69,7 @@ public void start(List allCallbacks) { List alarmMessageList = new ArrayList<>(30); LocalDateTime checkTime = LocalDateTime.now(); int minutes = Minutes.minutesBetween(lastExecuteTime, checkTime).getMinutes(); - boolean[] hasExecute = new boolean[] {false}; + boolean[] hasExecute = new boolean[]{false}; runningContext.values().forEach(ruleList -> ruleList.forEach(runningRule -> { if (minutes > 0) { runningRule.moveTo(checkTime); diff --git a/oap-server/server-alarm-plugin/src/test/java/org/apache/skywalking/oap/server/core/alarm/provider/AlarmModuleProviderTest.java b/oap-server/server-alarm-plugin/src/test/java/org/apache/skywalking/oap/server/core/alarm/provider/AlarmModuleProviderTest.java new file mode 100644 index 000000000000..31bb8d53af10 --- /dev/null +++ b/oap-server/server-alarm-plugin/src/test/java/org/apache/skywalking/oap/server/core/alarm/provider/AlarmModuleProviderTest.java @@ -0,0 +1,86 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +package org.apache.skywalking.oap.server.core.alarm.provider; + +import org.apache.skywalking.oap.server.core.CoreModule; +import org.apache.skywalking.oap.server.core.alarm.AlarmModule; +import org.apache.skywalking.oap.server.library.module.ModuleProvider; +import org.junit.Before; +import org.junit.Test; +import org.powermock.reflect.Whitebox; + +import java.util.Iterator; +import java.util.ServiceLoader; + +import static org.junit.Assert.*; +import static org.mockito.Mockito.doNothing; +import static org.mockito.Mockito.mock; + +/** + * Created by dengming, 2019.04.22 + */ +public class AlarmModuleProviderTest { + + private AlarmModuleProvider moduleProvider; + + @Before + public void setUp() throws Exception { + ServiceLoader serviceLoader = ServiceLoader.load(ModuleProvider.class); + Iterator providerIterator = serviceLoader.iterator(); + + assertTrue(providerIterator.hasNext()); + + moduleProvider = (AlarmModuleProvider) providerIterator.next(); + + moduleProvider.createConfigBeanIfAbsent(); + + moduleProvider.prepare(); + } + + @Test + public void name() { + assertEquals("default", moduleProvider.name()); + } + + @Test + public void module() { + assertEquals(AlarmModule.class, moduleProvider.module()); + } + + @Test + public void start() throws Exception { + moduleProvider.start(); + } + + @Test + public void notifyAfterCompleted() throws Exception { + + NotifyHandler handler = mock(NotifyHandler.class); + + doNothing().when(handler).initCache(null); + + Whitebox.setInternalState(moduleProvider, "notifyHandler", handler); + moduleProvider.notifyAfterCompleted(); + } + + @Test + public void requiredModules() { + String[] modules = moduleProvider.requiredModules(); + assertArrayEquals(new String[]{CoreModule.NAME}, modules); + } +} \ No newline at end of file diff --git a/oap-server/server-alarm-plugin/src/test/java/org/apache/skywalking/oap/server/core/alarm/provider/NotifyHandlerTest.java b/oap-server/server-alarm-plugin/src/test/java/org/apache/skywalking/oap/server/core/alarm/provider/NotifyHandlerTest.java new file mode 100644 index 000000000000..2f578461b043 --- /dev/null +++ b/oap-server/server-alarm-plugin/src/test/java/org/apache/skywalking/oap/server/core/alarm/provider/NotifyHandlerTest.java @@ -0,0 +1,253 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.apache.skywalking.oap.server.core.alarm.provider; + +import com.google.common.collect.Lists; +import org.apache.skywalking.oap.server.core.CoreModule; +import org.apache.skywalking.oap.server.core.alarm.*; +import org.apache.skywalking.oap.server.core.analysis.indicator.Indicator; +import org.apache.skywalking.oap.server.core.analysis.indicator.IndicatorMetaInfo; +import org.apache.skywalking.oap.server.core.analysis.indicator.WithMetadata; +import org.apache.skywalking.oap.server.core.cache.EndpointInventoryCache; +import org.apache.skywalking.oap.server.core.cache.ServiceInstanceInventoryCache; +import org.apache.skywalking.oap.server.core.cache.ServiceInventoryCache; +import org.apache.skywalking.oap.server.core.register.EndpointInventory; +import org.apache.skywalking.oap.server.core.register.ServiceInstanceInventory; +import org.apache.skywalking.oap.server.core.register.ServiceInventory; +import org.apache.skywalking.oap.server.core.source.DefaultScopeDefine; +import org.apache.skywalking.oap.server.library.module.ModuleManager; +import org.apache.skywalking.oap.server.library.module.ModuleProviderHolder; +import org.apache.skywalking.oap.server.library.module.ModuleServiceHolder; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.ArgumentCaptor; +import org.powermock.api.mockito.PowerMockito; +import org.powermock.core.classloader.annotations.PowerMockIgnore; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; +import org.powermock.reflect.Whitebox; + +import static junit.framework.TestCase.*; +import static org.mockito.Mockito.*; + +/** + * Created by dengming, 2019.04.22 + */ +@RunWith(PowerMockRunner.class) +@PowerMockIgnore("javax.management.*") +@PrepareForTest(DefaultScopeDefine.class) +public class NotifyHandlerTest { + + private NotifyHandler notifyHandler; + + private ModuleManager moduleManager; + + private ModuleProviderHolder moduleProviderHolder; + + private ModuleServiceHolder moduleServiceHolder; + + private ServiceInventoryCache serviceInventoryCache; + + private ServiceInstanceInventoryCache serviceInstanceInventoryCache; + + private EndpointInventoryCache endpointInventoryCache; + + private MockIndicator indicator; + + private IndicatorMetaInfo metadata; + + private int mockId = 1; + + private RunningRule rule; + + + @Test + public void testNotifyWithEndpointCatalog() { + prepareNotify(); + + String indicatorName = "endpoint-indicator"; + when(metadata.getIndicatorName()).thenReturn(indicatorName); + + when(DefaultScopeDefine.inEndpointCatalog(0)).thenReturn(true); + + String endpointInventoryName = "endpoint-inventory-name"; + EndpointInventory endpointInventory = mock(EndpointInventory.class); + when(endpointInventory.getName()).thenReturn(endpointInventoryName); + + String serviceInventoryName = "service-inventory-name"; + ServiceInventory serviceInventory = mock(ServiceInventory.class); + when(serviceInventory.getName()).thenReturn(serviceInventoryName); + + when(serviceInventoryCache.get(anyInt())).thenReturn(serviceInventory); + + when(endpointInventoryCache.get(anyInt())).thenReturn(endpointInventory); + + ArgumentCaptor metaCaptor = ArgumentCaptor.forClass(MetaInAlarm.class); + + notifyHandler.notify(indicator); + verify(rule).in(metaCaptor.capture(), any()); + + MetaInAlarm metaInAlarm = metaCaptor.getValue(); + + assertTrue(metaInAlarm instanceof EndpointMetaInAlarm); + assertEquals(mockId, metaInAlarm.getId0()); + assertEquals(indicatorName, metaInAlarm.getIndicatorName()); + assertEquals(endpointInventoryName + " in " + serviceInventoryName, metaInAlarm.getName()); + assertEquals(DefaultScopeDefine.ENDPOINT, metaInAlarm.getScopeId()); + + } + + @Test + public void testNotifyWithServiceInstanceCatalog() { + + prepareNotify(); + + String indicatorName = "service-instance-indicator"; + when(metadata.getIndicatorName()).thenReturn(indicatorName); + + when(DefaultScopeDefine.inServiceInstanceCatalog(0)).thenReturn(true); + + ServiceInstanceInventory instanceInventory = mock(ServiceInstanceInventory.class); + String instanceInventoryName = "instance-inventory-name"; + when(instanceInventory.getName()).thenReturn(instanceInventoryName); + + when(serviceInstanceInventoryCache.get(anyInt())).thenReturn(instanceInventory); + + ArgumentCaptor metaCaptor = ArgumentCaptor.forClass(MetaInAlarm.class); + + notifyHandler.notify(indicator); + verify(rule).in(metaCaptor.capture(), any()); + + MetaInAlarm metaInAlarm = metaCaptor.getValue(); + + assertTrue(metaInAlarm instanceof ServiceInstanceMetaInAlarm); + assertEquals(indicatorName, metaInAlarm.getIndicatorName()); + assertEquals(mockId, metaInAlarm.getId0()); + assertEquals(instanceInventoryName, metaInAlarm.getName()); + assertEquals(DefaultScopeDefine.SERVICE_INSTANCE, metaInAlarm.getScopeId()); + } + + @Test + public void testNotifyWithServiceCatalog() { + prepareNotify(); + + String indicatorName = "service-indicator"; + when(metadata.getIndicatorName()).thenReturn(indicatorName); + when(DefaultScopeDefine.inServiceCatalog(0)).thenReturn(true); + + ServiceInventory serviceInventory = mock(ServiceInventory.class); + String serviceInventoryName = "service-inventory"; + when(serviceInventory.getName()).thenReturn(serviceInventoryName); + + when(serviceInventoryCache.get(anyInt())).thenReturn(serviceInventory); + + ArgumentCaptor metaCaptor = ArgumentCaptor.forClass(MetaInAlarm.class); + + notifyHandler.notify(indicator); + verify(rule).in(metaCaptor.capture(), any()); + + MetaInAlarm metaInAlarm = metaCaptor.getValue(); + + assertTrue(metaInAlarm instanceof ServiceMetaInAlarm); + assertEquals(indicatorName, metaInAlarm.getIndicatorName()); + assertEquals(mockId, metaInAlarm.getId0()); + assertEquals(serviceInventoryName, metaInAlarm.getName()); + assertEquals(DefaultScopeDefine.SERVICE, metaInAlarm.getScopeId()); + } + + private void prepareNotify() { + notifyHandler.initCache(moduleManager); + + metadata = mock(IndicatorMetaInfo.class); + when(metadata.getScope()).thenReturn(DefaultScopeDefine.ALL); + when(metadata.getId()).thenReturn(String.valueOf(mockId)); + + indicator = mock(MockIndicator.class); + when(indicator.getMeta()).thenReturn(metadata); + + PowerMockito.mockStatic(DefaultScopeDefine.class); + } + + @Test + public void dontNotify() { + + IndicatorMetaInfo metadata = mock(IndicatorMetaInfo.class); + when(metadata.getScope()).thenReturn(DefaultScopeDefine.ALL); + + MockIndicator indicator = mock(MockIndicator.class); + when(indicator.getMeta()).thenReturn(metadata); + + notifyHandler.notify(indicator); + } + + @Test + public void initCache() { + + notifyHandler.initCache(moduleManager); + } + + + @Before + public void setUp() throws Exception { + + Rules rules = new Rules(); + + notifyHandler = new NotifyHandler(rules); + + notifyHandler.init(alarmMessageList -> { + for (AlarmMessage message : alarmMessageList) { + assertNotNull(message); + } + }); + + + moduleManager = mock(ModuleManager.class); + + moduleProviderHolder = mock(ModuleProviderHolder.class); + + + moduleServiceHolder = mock(ModuleServiceHolder.class); + + when(moduleManager.find(CoreModule.NAME)).thenReturn(moduleProviderHolder); + when(moduleProviderHolder.provider()).thenReturn(moduleServiceHolder); + + serviceInventoryCache = mock(ServiceInventoryCache.class); + serviceInstanceInventoryCache = mock(ServiceInstanceInventoryCache.class); + endpointInventoryCache = mock(EndpointInventoryCache.class); + + when(moduleServiceHolder.getService(ServiceInventoryCache.class)).thenReturn(serviceInventoryCache); + when(moduleServiceHolder.getService(ServiceInstanceInventoryCache.class)).thenReturn(serviceInstanceInventoryCache); + when(moduleServiceHolder.getService(EndpointInventoryCache.class)).thenReturn(endpointInventoryCache); + + AlarmCore core = mock(AlarmCore.class); + + rule = mock(RunningRule.class); + + doNothing().when(rule).in(any(MetaInAlarm.class), any(Indicator.class)); + + when(core.findRunningRule(anyString())).thenReturn(Lists.newArrayList(rule)); + + Whitebox.setInternalState(notifyHandler, "core", core); + } + + private abstract class MockIndicator extends Indicator implements WithMetadata { + + } +} \ No newline at end of file diff --git a/oap-server/server-alarm-plugin/src/test/java/org/apache/skywalking/oap/server/core/alarm/provider/ThresholdTest.java b/oap-server/server-alarm-plugin/src/test/java/org/apache/skywalking/oap/server/core/alarm/provider/ThresholdTest.java new file mode 100644 index 000000000000..85f2bcd88345 --- /dev/null +++ b/oap-server/server-alarm-plugin/src/test/java/org/apache/skywalking/oap/server/core/alarm/provider/ThresholdTest.java @@ -0,0 +1,49 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.apache.skywalking.oap.server.core.alarm.provider; + +import org.junit.Test; + +import static org.junit.Assert.assertEquals; + +/** + * Created by dengming, 2019.04.27 + */ +public class ThresholdTest { + + @Test + public void setType() { + Threshold threshold = new Threshold("my-rule", "75"); + threshold.setType(IndicatorValueType.DOUBLE); + assertEquals(0, Double.compare(75, threshold.getDoubleThreadhold())); + + threshold.setType(IndicatorValueType.INT); + assertEquals(75, threshold.getIntThreshold()); + + threshold.setType(IndicatorValueType.LONG); + assertEquals(75L, threshold.getLongThreshold()); + } + + @Test + public void setTypeWithWrong() { + Threshold threshold = new Threshold("my-rule", "wrong"); + threshold.setType(IndicatorValueType.INT); + assertEquals(0, threshold.getIntThreshold()); + } +} \ No newline at end of file