You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cassandra.apache.org by bl...@apache.org on 2020/06/09 09:17:18 UTC
[cassandra] branch trunk updated: Add BufferPoolMetricsTest
This is an automated email from the ASF dual-hosted git repository.
blerer pushed a commit to branch trunk
in repository https://gitbox.apache.org/repos/asf/cassandra.git
The following commit(s) were added to refs/heads/trunk by this push:
new bc600f1 Add BufferPoolMetricsTest
bc600f1 is described below
commit bc600f1bd5b188030305b964e5aef1b0ea70f634
Author: Stephen Mallette <sp...@genoprime.com>
AuthorDate: Wed Apr 29 11:51:03 2020 -0400
Add BufferPoolMetricsTest
patch by Stephen Mallette; reviewed by David Capwell and by Benjamin Lerer
for CASSANDRA-15773
---
.../apache/cassandra/metrics/BatchMetricsTest.java | 1 -
.../cassandra/metrics/BufferPoolMetricsTest.java | 192 +++++++++++++++++++++
.../cassandra/utils/memory/BufferPoolTest.java | 9 +
3 files changed, 201 insertions(+), 1 deletion(-)
diff --git a/test/unit/org/apache/cassandra/metrics/BatchMetricsTest.java b/test/unit/org/apache/cassandra/metrics/BatchMetricsTest.java
index 900ac75..c3bf794 100644
--- a/test/unit/org/apache/cassandra/metrics/BatchMetricsTest.java
+++ b/test/unit/org/apache/cassandra/metrics/BatchMetricsTest.java
@@ -40,7 +40,6 @@ import org.apache.cassandra.metrics.DecayingEstimatedHistogramReservoir.Estimate
import static org.apache.cassandra.cql3.statements.BatchStatement.metrics;
import static org.apache.cassandra.metrics.DecayingEstimatedHistogramReservoir.*;
import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
import static org.quicktheories.QuickTheory.qt;
import static org.quicktheories.generators.Generate.intArrays;
import static org.quicktheories.generators.SourceDSL.integers;
diff --git a/test/unit/org/apache/cassandra/metrics/BufferPoolMetricsTest.java b/test/unit/org/apache/cassandra/metrics/BufferPoolMetricsTest.java
new file mode 100644
index 0000000..fade96c
--- /dev/null
+++ b/test/unit/org/apache/cassandra/metrics/BufferPoolMetricsTest.java
@@ -0,0 +1,192 @@
+/*
+ * 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.cassandra.metrics;
+
+import java.util.Random;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import org.apache.cassandra.OrderedJUnit4ClassRunner;
+import org.apache.cassandra.config.DatabaseDescriptor;
+import org.apache.cassandra.exceptions.ConfigurationException;
+import org.apache.cassandra.io.compress.BufferType;
+import org.apache.cassandra.utils.memory.BufferPool;
+import org.apache.cassandra.utils.memory.BufferPoolTest;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
+import static org.junit.Assert.assertEquals;
+
+@RunWith(OrderedJUnit4ClassRunner.class)
+public class BufferPoolMetricsTest
+{
+ private static final BufferPoolMetrics metrics = new BufferPoolMetrics();
+
+ @BeforeClass()
+ public static void setup() throws ConfigurationException
+ {
+ DatabaseDescriptor.daemonInitialization();
+ }
+
+ @Before
+ public void setUp()
+ {
+ BufferPool.MEMORY_USAGE_THRESHOLD = 16 * 1024L * 1024L;
+ }
+
+ @After
+ public void cleanUp()
+ {
+ BufferPoolTest.resetBufferPool();
+ metrics.misses.mark(metrics.misses.getCount() * -1);
+ }
+
+ @Test
+ public void testMetricsSize()
+ {
+ // basically want to test changes in the metric being reported as the buffer pool grows - starts at zero
+ assertThat(metrics.size.getValue()).isEqualTo(BufferPool.sizeInBytes())
+ .isEqualTo(0);
+
+ // the idea is to test changes in the sizeOfBufferPool metric which starts at zero. it will bump up
+ // after the first request for a ByteBuffer and the idea from there will be to keep requesting them
+ // until it bumps a second time at which point there should be some confidence that thie metric is
+ // behaving as expected. these assertions should occur well within the value of the MEMORY_USAGE_THRESHOLD
+ // given the maxBufferSize (just covering the case of the weirdest random seed in the multiverse i guess - a
+ // while loop might have sufficed as well but a definitive termination seemed nicer)
+ final long seed = System.currentTimeMillis();
+ final Random rand = new Random(seed);
+ final String assertionMessage = String.format("Failed with seed of %s", seed);
+ final long maxIterations = BufferPool.MEMORY_USAGE_THRESHOLD;
+ final int maxBufferSize = BufferPool.NORMAL_CHUNK_SIZE - 1;
+ int nextSizeToRequest;
+ long totalBytesRequestedFromPool = 0;
+ long initialSizeInBytesAfterZero = 0;
+ boolean exitedBeforeMax = false;
+ for (int ix = 0; ix < maxIterations; ix++)
+ {
+ nextSizeToRequest = rand.nextInt(maxBufferSize) + 1;
+ totalBytesRequestedFromPool = totalBytesRequestedFromPool + nextSizeToRequest;
+ BufferPool.get(nextSizeToRequest, BufferType.OFF_HEAP);
+
+ assertThat(metrics.size.getValue()).as(assertionMessage)
+ .isEqualTo(BufferPool.sizeInBytes())
+ .isGreaterThanOrEqualTo(totalBytesRequestedFromPool);
+
+ if (initialSizeInBytesAfterZero == 0)
+ {
+ initialSizeInBytesAfterZero = BufferPool.sizeInBytes();
+ }
+ else
+ {
+ // when the total bytes requested from the pool exceeds the initial size we should have
+ // asserted a bump in the sizeInBytes which means that we've asserted the metric increasing
+ // as a result of that bump - can stop trying to grow the pool further
+ if (totalBytesRequestedFromPool > initialSizeInBytesAfterZero)
+ {
+ exitedBeforeMax = true;
+ break;
+ }
+ }
+ }
+
+ assertThat(exitedBeforeMax).as(assertionMessage).isTrue();
+ assertEquals(0, metrics.misses.getCount());
+ }
+
+ @Test
+ public void testMetricsMisses()
+ {
+ assertEquals(0, metrics.misses.getCount());
+
+ final int tinyBufferSizeThatHits = BufferPool.NORMAL_CHUNK_SIZE - 1;
+ final int bigBufferSizeThatMisses = BufferPool.NORMAL_CHUNK_SIZE + 1;
+
+ int iterations = 16;
+ for (int ix = 0; ix < iterations; ix++)
+ {
+ BufferPool.get(tinyBufferSizeThatHits, BufferType.OFF_HEAP);
+ assertEquals(0, metrics.misses.getCount());
+ }
+
+ for (int ix = 0; ix < iterations; ix++)
+ {
+ BufferPool.get(bigBufferSizeThatMisses + ix, BufferType.OFF_HEAP);
+ assertEquals(ix + 1, metrics.misses.getCount());
+ }
+ }
+
+ @Test
+ public void testZeroSizeRequestsDontChangeMetrics()
+ {
+ assertEquals(0, metrics.misses.getCount());
+ assertThat(metrics.size.getValue()).isEqualTo(BufferPool.sizeInBytes())
+ .isEqualTo(0);
+
+ BufferPool.get(0, BufferType.OFF_HEAP);
+
+ assertEquals(0, metrics.misses.getCount());
+ assertThat(metrics.size.getValue()).isEqualTo(BufferPool.sizeInBytes())
+ .isEqualTo(0);
+
+ BufferPool.get(65536, BufferType.OFF_HEAP);
+ BufferPool.get(0, BufferType.OFF_HEAP);
+ BufferPool.get(0, BufferType.OFF_HEAP);
+ BufferPool.get(0, BufferType.OFF_HEAP);
+ BufferPool.get(0, BufferType.OFF_HEAP);
+
+ assertEquals(0, metrics.misses.getCount());
+ assertThat(metrics.size.getValue()).isEqualTo(BufferPool.sizeInBytes())
+ .isGreaterThanOrEqualTo(65536);
+ }
+
+ @Test
+ public void testFailedRequestsDontChangeMetrics()
+ {
+ assertEquals(0, metrics.misses.getCount());
+ assertThat(metrics.size.getValue()).isEqualTo(BufferPool.sizeInBytes())
+ .isEqualTo(0);
+
+ tryRequestNegativeBufferSize();
+
+ assertEquals(0, metrics.misses.getCount());
+ assertThat(metrics.size.getValue()).isEqualTo(BufferPool.sizeInBytes())
+ .isEqualTo(0);
+
+ BufferPool.get(65536, BufferType.OFF_HEAP);
+ tryRequestNegativeBufferSize();
+ tryRequestNegativeBufferSize();
+ tryRequestNegativeBufferSize();
+ tryRequestNegativeBufferSize();
+
+ assertEquals(0, metrics.misses.getCount());
+ assertThat(metrics.size.getValue()).isEqualTo(BufferPool.sizeInBytes())
+ .isGreaterThanOrEqualTo(65536);
+ }
+
+ private void tryRequestNegativeBufferSize()
+ {
+ assertThatExceptionOfType(IllegalArgumentException.class).isThrownBy(
+ () -> BufferPool.get(-1, BufferType.OFF_HEAP));
+ }
+}
diff --git a/test/unit/org/apache/cassandra/utils/memory/BufferPoolTest.java b/test/unit/org/apache/cassandra/utils/memory/BufferPoolTest.java
index 85ca2d0..5df94ec 100644
--- a/test/unit/org/apache/cassandra/utils/memory/BufferPoolTest.java
+++ b/test/unit/org/apache/cassandra/utils/memory/BufferPoolTest.java
@@ -52,6 +52,15 @@ public class BufferPoolTest
@After
public void cleanUp()
{
+ resetBufferPool();
+ }
+
+ /**
+ * Exposes a utility method on this test that other tests might use to access the protected
+ * {@link BufferPool#unsafeReset()} method.
+ */
+ public static void resetBufferPool()
+ {
BufferPool.unsafeReset();
}
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@cassandra.apache.org
For additional commands, e-mail: commits-help@cassandra.apache.org