This is an automated email from the ASF dual-hosted git repository. onichols pushed a commit to branch support/1.14 in repository https://gitbox.apache.org/repos/asf/geode.git
commit 453e298cbeaf847b5cb7dd6136858be212f9237f Author: Ray Ingles <ring...@pivotal.io> AuthorDate: Tue Feb 16 09:47:52 2021 -0500 GEODE-8933: update INFO to return maxmemory field (#6019) * Also fix fragmentation ratio Co-authored-by: Ray Ingles <ring...@vmware.com> (cherry-picked from ab5ef9d46b24bd686d91c920bdbd3dc0a5026e26) --- .../MemoryStatsNativeRedisAcceptanceTest.java | 37 +++++++ .../server/AbstractInfoIntegrationTest.java | 1 + .../AbstractRedisMemoryStatsIntegrationTest.java | 120 +++++++++++++++++++++ .../server/MemoryStatsIntegrationTest.java | 30 ++++++ .../internal/executor/server/InfoExecutor.java | 5 +- 5 files changed, 192 insertions(+), 1 deletion(-) diff --git a/geode-redis/src/acceptanceTest/java/org/apache/geode/redis/internal/executor/server/MemoryStatsNativeRedisAcceptanceTest.java b/geode-redis/src/acceptanceTest/java/org/apache/geode/redis/internal/executor/server/MemoryStatsNativeRedisAcceptanceTest.java new file mode 100644 index 0000000..4f2d34a --- /dev/null +++ b/geode-redis/src/acceptanceTest/java/org/apache/geode/redis/internal/executor/server/MemoryStatsNativeRedisAcceptanceTest.java @@ -0,0 +1,37 @@ +/* + * 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.redis.internal.executor.server; + +import org.junit.ClassRule; +import redis.clients.jedis.Jedis; + +import org.apache.geode.NativeRedisTestRule; + +public class MemoryStatsNativeRedisAcceptanceTest extends AbstractRedisMemoryStatsIntegrationTest { + @ClassRule + public static NativeRedisTestRule redis = new NativeRedisTestRule(); + + @Override + public int getPort() { + return redis.getPort(); + } + + @Override + public void configureMemoryAndEvictionPolicy(Jedis jedis) { + jedis.configSet("maxmemory", "2000000"); + jedis.configSet("maxmemory-policy", "allkeys-lru"); + } +} diff --git a/geode-redis/src/integrationTest/java/org/apache/geode/redis/internal/executor/server/AbstractInfoIntegrationTest.java b/geode-redis/src/integrationTest/java/org/apache/geode/redis/internal/executor/server/AbstractInfoIntegrationTest.java index 83e3e3c..84b3043 100644 --- a/geode-redis/src/integrationTest/java/org/apache/geode/redis/internal/executor/server/AbstractInfoIntegrationTest.java +++ b/geode-redis/src/integrationTest/java/org/apache/geode/redis/internal/executor/server/AbstractInfoIntegrationTest.java @@ -80,6 +80,7 @@ public abstract class AbstractInfoIntegrationTest implements RedisPortSupplier { final List<String> MEMORY_PROPERTIES = Arrays.asList( "# Memory", + "maxmemory:", "used_memory:", "mem_fragmentation_ratio:"); diff --git a/geode-redis/src/integrationTest/java/org/apache/geode/redis/internal/executor/server/AbstractRedisMemoryStatsIntegrationTest.java b/geode-redis/src/integrationTest/java/org/apache/geode/redis/internal/executor/server/AbstractRedisMemoryStatsIntegrationTest.java new file mode 100644 index 0000000..85de4fe --- /dev/null +++ b/geode-redis/src/integrationTest/java/org/apache/geode/redis/internal/executor/server/AbstractRedisMemoryStatsIntegrationTest.java @@ -0,0 +1,120 @@ +/* + * 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.redis.internal.executor.server; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.util.HashMap; +import java.util.Map; + +import org.junit.After; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; +import redis.clients.jedis.Jedis; + +import org.apache.geode.internal.statistics.EnabledStatisticsClock; +import org.apache.geode.internal.statistics.StatisticsClock; +import org.apache.geode.test.awaitility.GeodeAwaitility; +import org.apache.geode.test.dunit.rules.RedisPortSupplier; + +public abstract class AbstractRedisMemoryStatsIntegrationTest implements RedisPortSupplier { + + private static final int TIMEOUT = (int) GeodeAwaitility.getTimeout().toMillis(); + private static final String EXISTING_HASH_KEY = "Existing_Hash"; + private static final String EXISTING_STRING_KEY = "Existing_String"; + private static final String EXISTING_SET_KEY_1 = "Existing_Set_1"; + private static final String EXISTING_SET_KEY_2 = "Existing_Set_2"; + + private Jedis jedis; + private static long START_TIME; + private static StatisticsClock statisticsClock; + + private long preTestConnectionsReceived = 0; + private long preTestConnectedClients = 0; + + private static final String MAX_MEMORY = "maxmemory"; + private static final String USED_MEMORY = "used_memory"; + private static final String MEM_FRAGMENTATION_RATIO = "mem_fragmentation_ratio"; + + public void configureMemoryAndEvictionPolicy(Jedis jedis) {} + + // ------------------- Setup -------------------------- // + @BeforeClass + public static void beforeClass() { + statisticsClock = new EnabledStatisticsClock(); + START_TIME = statisticsClock.getTime(); + } + + @Before + public void before() { + jedis = new Jedis("localhost", getPort(), TIMEOUT); + configureMemoryAndEvictionPolicy(jedis); + } + + @After + public void after() { + jedis.flushAll(); + jedis.close(); + } + + // ------------------- Memory Section -------------------------- // + + @Test + public void maxMemory_shouldBeASensibleValue() { + long maxMemory = Long.valueOf(getInfo(jedis).get(MAX_MEMORY)); + assertThat(maxMemory).isGreaterThan(0L); + } + + @Test + public void memoryFragmentationRatio_shouldBeGreaterThanZero() { + double memoryFragmentationRatio = Double.valueOf(getInfo(jedis).get(MEM_FRAGMENTATION_RATIO)); + assertThat(memoryFragmentationRatio).isGreaterThan(0.0); + } + + @Test + public void usedMemory_shouldReflectActualMemoryUsage() { + long initialUsedMemory = Long.valueOf(getInfo(jedis).get(USED_MEMORY)); + + jedis.set(EXISTING_STRING_KEY, "A_Value"); + jedis.hset(EXISTING_HASH_KEY, "Field1", "Value1"); + jedis.sadd(EXISTING_SET_KEY_1, "m1", "m2", "m3"); + jedis.sadd(EXISTING_SET_KEY_2, "m4", "m5", "m6"); + + long finalUsedMemory = Long.valueOf(getInfo(jedis).get(USED_MEMORY)); + assertThat(finalUsedMemory).isGreaterThan(initialUsedMemory); + } + + // ------------------- Helper Methods ----------------------------- // + + /** + * Convert the values returned by the INFO command into a basic param:value map. + */ + static synchronized Map<String, String> getInfo(Jedis jedis) { + Map<String, String> results = new HashMap<>(); + String rawInfo = jedis.info(); + + for (String line : rawInfo.split("\r\n")) { + int colonIndex = line.indexOf(":"); + if (colonIndex > 0) { + String key = line.substring(0, colonIndex); + String value = line.substring(colonIndex + 1); + results.put(key, value); + } + } + + return results; + } +} diff --git a/geode-redis/src/integrationTest/java/org/apache/geode/redis/internal/executor/server/MemoryStatsIntegrationTest.java b/geode-redis/src/integrationTest/java/org/apache/geode/redis/internal/executor/server/MemoryStatsIntegrationTest.java new file mode 100644 index 0000000..ecdacb9 --- /dev/null +++ b/geode-redis/src/integrationTest/java/org/apache/geode/redis/internal/executor/server/MemoryStatsIntegrationTest.java @@ -0,0 +1,30 @@ +/* + * 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.redis.internal.executor.server; + +import org.junit.ClassRule; + +import org.apache.geode.redis.GeodeRedisServerRule; + +public class MemoryStatsIntegrationTest extends AbstractRedisMemoryStatsIntegrationTest { + @ClassRule + public static GeodeRedisServerRule server = new GeodeRedisServerRule(); + + @Override + public int getPort() { + return server.getPort(); + } +} diff --git a/geode-redis/src/main/java/org/apache/geode/redis/internal/executor/server/InfoExecutor.java b/geode-redis/src/main/java/org/apache/geode/redis/internal/executor/server/InfoExecutor.java index ebe13da..d7b3174 100644 --- a/geode-redis/src/main/java/org/apache/geode/redis/internal/executor/server/InfoExecutor.java +++ b/geode-redis/src/main/java/org/apache/geode/redis/internal/executor/server/InfoExecutor.java @@ -28,6 +28,8 @@ import org.apache.geode.redis.internal.statistics.RedisStats; public class InfoExecutor extends AbstractExecutor { + private static final Long ONE_MEGABYTE = 1024 * 1024L; + private DecimalFormat decimalFormat = new DecimalFormat("0.00"); @Override @@ -139,8 +141,9 @@ public class InfoExecutor extends AbstractExecutor { long usedMemory = pr.getDataStore().currentAllocatedMemory(); final String MEMORY_STRING = "# Memory\r\n" + + "maxmemory:" + pr.getLocalMaxMemory() * ONE_MEGABYTE + "\r\n" + "used_memory:" + usedMemory + "\r\n" + - "mem_fragmentation_ratio:0\r\n"; + "mem_fragmentation_ratio:1.00\r\n"; return MEMORY_STRING; }