| /* |
| * 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.geode.internal.statistics; |
| |
| import static org.assertj.core.api.Assertions.assertThat; |
| import static org.assertj.core.api.Assertions.catchThrowable; |
| import static org.mockito.Mockito.anyInt; |
| import static org.mockito.Mockito.anyString; |
| import static org.mockito.Mockito.isA; |
| import static org.mockito.Mockito.isNull; |
| import static org.mockito.Mockito.mock; |
| import static org.mockito.Mockito.verify; |
| import static org.mockito.Mockito.when; |
| |
| import java.util.HashMap; |
| import java.util.Map; |
| import java.util.function.DoubleSupplier; |
| import java.util.function.IntSupplier; |
| import java.util.function.LongSupplier; |
| |
| import org.junit.Before; |
| import org.junit.Test; |
| |
| import org.apache.geode.StatisticsType; |
| import org.apache.geode.internal.statistics.StatisticsImpl.StatisticsLogger; |
| |
| /** |
| * Unit tests for {@link StatisticsImpl}. |
| */ |
| public class StatisticsImplTest { |
| |
| // arbitrary values for constructing a StatisticsImpl |
| private static final String ANY_TEXT_ID = null; |
| private static final long ANY_NUMERIC_ID = 0; |
| private static final long ANY_UNIQUE_ID = 0; |
| private static final int ANY_OS_STAT_FLAGS = 0; |
| |
| private StatisticsManager statisticsManager; |
| private StatisticsTypeImpl statisticsType; |
| |
| private StatisticsImpl statistics; |
| |
| @Before |
| public void createStats() { |
| statisticsManager = mock(StatisticsManager.class); |
| |
| statisticsType = mock(StatisticsTypeImpl.class); |
| when(statisticsType.isValidLongId(anyInt())).thenReturn(true); |
| when(statisticsType.isValidDoubleId(anyInt())).thenReturn(true); |
| |
| statistics = new SimpleStatistics(statisticsType, ANY_TEXT_ID, ANY_NUMERIC_ID, ANY_UNIQUE_ID, |
| ANY_OS_STAT_FLAGS, statisticsManager); |
| } |
| |
| @Test |
| public void invokeIntSuppliersShouldUpdateStats() { |
| IntSupplier intSupplier = mock(IntSupplier.class); |
| when(intSupplier.getAsInt()).thenReturn(23); |
| statistics.setIntSupplier(4, intSupplier); |
| assertThat(statistics.updateSuppliedValues()).isEqualTo(0); |
| |
| verify(intSupplier).getAsInt(); |
| assertThat(statistics.getInt(4)).isEqualTo(23); |
| } |
| |
| @Test |
| public void invokeLongSuppliersShouldUpdateStats() { |
| LongSupplier longSupplier = mock(LongSupplier.class); |
| when(longSupplier.getAsLong()).thenReturn(23L); |
| statistics.setLongSupplier(4, longSupplier); |
| assertThat(statistics.updateSuppliedValues()).isEqualTo(0); |
| |
| verify(longSupplier).getAsLong(); |
| assertThat(statistics.getLong(4)).isEqualTo(23L); |
| } |
| |
| @Test |
| public void invokeDoubleSuppliersShouldUpdateStats() { |
| DoubleSupplier doubleSupplier = mock(DoubleSupplier.class); |
| when(doubleSupplier.getAsDouble()).thenReturn(23.3); |
| statistics.setDoubleSupplier(4, doubleSupplier); |
| assertThat(statistics.updateSuppliedValues()).isEqualTo(0); |
| |
| verify(doubleSupplier).getAsDouble(); |
| assertThat(statistics.getDouble(4)).isEqualTo(23.3); |
| } |
| |
| @Test |
| public void getSupplierCountShouldReturnCorrectCount() { |
| IntSupplier intSupplier = mock(IntSupplier.class); |
| statistics.setIntSupplier(4, intSupplier); |
| assertThat(statistics.getSupplierCount()).isEqualTo(1); |
| } |
| |
| @Test |
| public void invokeSuppliersShouldCatchSupplierErrorsAndReturnCount() { |
| IntSupplier throwingSupplier = mock(IntSupplier.class); |
| when(throwingSupplier.getAsInt()).thenThrow(NullPointerException.class); |
| statistics.setIntSupplier(4, throwingSupplier); |
| assertThat(statistics.updateSuppliedValues()).isEqualTo(1); |
| |
| verify(throwingSupplier).getAsInt(); |
| } |
| |
| @Test |
| public void invokeSuppliersShouldLogErrorOnlyOnce() { |
| StatisticsLogger statisticsLogger = mock(StatisticsLogger.class); |
| statistics = new SimpleStatistics(statisticsType, ANY_TEXT_ID, ANY_NUMERIC_ID, ANY_UNIQUE_ID, |
| ANY_OS_STAT_FLAGS, statisticsManager, statisticsLogger); |
| |
| IntSupplier throwingSupplier = mock(IntSupplier.class); |
| when(throwingSupplier.getAsInt()).thenThrow(NullPointerException.class); |
| statistics.setIntSupplier(4, throwingSupplier); |
| assertThat(statistics.updateSuppliedValues()).isEqualTo(1); |
| |
| // String message, Object p0, Object p1, Object p2 |
| verify(statisticsLogger).logWarning(anyString(), isNull(), anyInt(), |
| isA(NullPointerException.class)); |
| |
| assertThat(statistics.updateSuppliedValues()).isEqualTo(1); |
| |
| // Make sure the logger isn't invoked again |
| verify(statisticsLogger).logWarning(anyString(), isNull(), anyInt(), |
| isA(NullPointerException.class)); |
| } |
| |
| @Test |
| public void badSupplierParamShouldThrowError() { |
| IntSupplier intSupplier = mock(IntSupplier.class); |
| when(intSupplier.getAsInt()).thenReturn(23); |
| when(statisticsType.isValidLongId(anyInt())).thenReturn(false); |
| |
| Throwable thrown = catchThrowable(() -> statistics.setIntSupplier(23, intSupplier)); |
| |
| assertThat(thrown).isInstanceOf(IllegalArgumentException.class); |
| } |
| |
| @Test |
| public void nonEmptyTextId_usesGivenTextId() { |
| String nonEmptyTextId = "non-empty-text-id"; |
| |
| statistics = new SimpleStatistics(statisticsType, nonEmptyTextId, ANY_NUMERIC_ID, ANY_UNIQUE_ID, |
| ANY_OS_STAT_FLAGS, statisticsManager); |
| |
| assertThat(statistics.getTextId()).isEqualTo(nonEmptyTextId); |
| } |
| |
| @Test |
| public void nullTextId_usesNameFromStatisticsManager() { |
| String nameFromStatisticsManager = "statistics-manager-name"; |
| when(statisticsManager.getName()).thenReturn(nameFromStatisticsManager); |
| String nullTextId = null; |
| |
| statistics = new SimpleStatistics(statisticsType, nullTextId, ANY_NUMERIC_ID, ANY_UNIQUE_ID, |
| ANY_OS_STAT_FLAGS, statisticsManager); |
| |
| assertThat(statistics.getTextId()).isEqualTo(nameFromStatisticsManager); |
| } |
| |
| @Test |
| public void emptyTextId_usesNameFromStatisticsManager() { |
| String nameFromStatisticsManager = "statistics-manager-name"; |
| when(statisticsManager.getName()).thenReturn(nameFromStatisticsManager); |
| String emptyTextId = ""; |
| |
| statistics = new SimpleStatistics(statisticsType, emptyTextId, ANY_NUMERIC_ID, ANY_UNIQUE_ID, |
| ANY_OS_STAT_FLAGS, statisticsManager); |
| |
| assertThat(statistics.getTextId()).isEqualTo(nameFromStatisticsManager); |
| } |
| |
| @Test |
| public void positiveNumericId_usesGivenNumericId() { |
| int positiveNumericId = 21; |
| |
| statistics = new SimpleStatistics(statisticsType, ANY_TEXT_ID, positiveNumericId, ANY_UNIQUE_ID, |
| ANY_OS_STAT_FLAGS, statisticsManager); |
| |
| assertThat(statistics.getNumericId()).isEqualTo(positiveNumericId); |
| } |
| |
| @Test |
| public void negativeNumericId_usesGivenNumericId() { |
| int negativeNumericId = -21; |
| |
| statistics = new SimpleStatistics(statisticsType, ANY_TEXT_ID, negativeNumericId, ANY_UNIQUE_ID, |
| ANY_OS_STAT_FLAGS, statisticsManager); |
| |
| assertThat(statistics.getNumericId()).isEqualTo(negativeNumericId); |
| } |
| |
| @Test |
| public void zeroNumericId_usesPidFromStatisticsManager() { |
| int pidFromStatisticsManager = 42; |
| when(statisticsManager.getPid()).thenReturn(pidFromStatisticsManager); |
| int zeroNumericId = 0; |
| |
| statistics = new SimpleStatistics(statisticsType, ANY_TEXT_ID, zeroNumericId, ANY_UNIQUE_ID, |
| ANY_OS_STAT_FLAGS, statisticsManager); |
| |
| assertThat(statistics.getNumericId()).isEqualTo(pidFromStatisticsManager); |
| } |
| |
| private static class SimpleStatistics extends StatisticsImpl { |
| |
| private final Map<Number, Number> values = new HashMap<>(); |
| |
| SimpleStatistics(StatisticsType type, String textId, long numericId, long uniqueId, |
| int osStatFlags, StatisticsManager statisticsManager) { |
| super(type, textId, numericId, uniqueId, osStatFlags, statisticsManager); |
| } |
| |
| SimpleStatistics(StatisticsType type, String textId, long numericId, long uniqueId, |
| int osStatFlags, StatisticsManager statisticsManager, StatisticsLogger statisticsLogger) { |
| super(type, textId, numericId, uniqueId, osStatFlags, statisticsManager, statisticsLogger); |
| } |
| |
| @Override |
| public boolean isAtomic() { |
| return false; |
| } |
| |
| @Override |
| protected void _setLong(int offset, long value) { |
| values.put(offset, value); |
| } |
| |
| @Override |
| protected void _setDouble(int offset, double value) { |
| values.put(offset, value); |
| } |
| |
| @Override |
| protected long _getLong(int offset) { |
| return (long) values.get(offset); |
| } |
| |
| @Override |
| protected double _getDouble(int offset) { |
| return (double) values.get(offset); |
| } |
| |
| @Override |
| protected void _incLong(int offset, long delta) { |
| values.put(offset, (long) values.get(delta) + 1); |
| } |
| |
| @Override |
| protected void _incDouble(int offset, double delta) { |
| values.put(offset, (double) values.get(delta) + 1); |
| } |
| } |
| } |