You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by sk...@apache.org on 2021/02/24 13:28:33 UTC

[ignite] branch master updated: IGNITE-14175 Correction of the metrics of received keys for rebalancing #8799

This is an automated email from the ASF dual-hosted git repository.

sk0x50 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/ignite.git


The following commit(s) were added to refs/heads/master by this push:
     new eda18a4  IGNITE-14175 Correction of the metrics of received keys for rebalancing #8799
eda18a4 is described below

commit eda18a4a5b92b6738f15073f61e9d810fd0a0266
Author: Kirill Tkalenko <tk...@yandex.ru>
AuthorDate: Wed Feb 24 16:27:51 2021 +0300

    IGNITE-14175 Correction of the metrics of received keys for rebalancing #8799
    
    Signed-off-by: Slava Koptilin <sl...@gmail.com>
---
 .../processors/cache/CacheMetricsImpl.java         |   8 +-
 .../dht/preloader/GridDhtPartitionDemander.java    |  65 ++++++++----
 .../ignite/internal/util/GridMutableLong.java      |  64 ++++++++++++
 .../ignite/internal/util/collection/IntMap.java    |  30 ++++++
 .../cache/CacheGroupsMetricsRebalanceTest.java     |  52 +++++-----
 .../rebalancing/RebalanceMetricsTest.java          | 112 +++++++++++++++++++++
 .../ignite/internal/util/GridMutableLongTest.java  |  61 +++++++++++
 .../internal/util/collection/IntHashMapTest.java   |  27 +++++
 .../ignite/testsuites/IgniteCacheTestSuite5.java   |   2 +
 .../testsuites/IgniteKernalSelfTestSuite.java      |   4 +-
 .../PerformanceStatisticsQueryTest.java            |   4 +-
 11 files changed, 379 insertions(+), 50 deletions(-)

diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheMetricsImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheMetricsImpl.java
index 0b9811f..0b2ee8c 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheMetricsImpl.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheMetricsImpl.java
@@ -1494,11 +1494,13 @@ public class CacheMetricsImpl implements CacheMetrics {
 
     /**
      * Rebalance entry store callback.
+     *
+     * @param keys Key count.
      */
-    public void onRebalanceKeyReceived() {
-        rebalancedKeys.increment();
+    public void onRebalanceKeyReceived(long keys) {
+        rebalancedKeys.add(keys);
 
-        rebalancingKeysRate.increment();
+        rebalancingKeysRate.add(keys);
     }
 
     /**
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtPartitionDemander.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtPartitionDemander.java
index 7c022ab..10b9969 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtPartitionDemander.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtPartitionDemander.java
@@ -69,6 +69,8 @@ import org.apache.ignite.internal.processors.cache.persistence.checkpoint.Checkp
 import org.apache.ignite.internal.processors.metric.MetricRegistry;
 import org.apache.ignite.internal.processors.timeout.GridTimeoutObject;
 import org.apache.ignite.internal.processors.timeout.GridTimeoutObjectAdapter;
+import org.apache.ignite.internal.util.GridMutableLong;
+import org.apache.ignite.internal.util.collection.IntHashMap;
 import org.apache.ignite.internal.util.future.GridCompoundFuture;
 import org.apache.ignite.internal.util.future.GridFinishedFuture;
 import org.apache.ignite.internal.util.future.GridFutureAdapter;
@@ -772,20 +774,27 @@ public class GridDhtPartitionDemander {
     /**
      * Adds mvcc entries with theirs history to partition p.
      *
+     * @param topVer Topology version.
      * @param node Node which sent entry.
      * @param p Partition id.
      * @param infos Entries info for preload.
-     * @param topVer Topology version.
-     * @throws IgniteInterruptedCheckedException If interrupted.
+     * @throws IgniteCheckedException If failed.
      */
-    private void mvccPreloadEntries(AffinityTopologyVersion topVer, ClusterNode node, int p,
-        Iterator<GridCacheEntryInfo> infos) throws IgniteCheckedException {
+    private void mvccPreloadEntries(
+        AffinityTopologyVersion topVer,
+        ClusterNode node,
+        int p,
+        Iterator<GridCacheEntryInfo> infos
+    ) throws IgniteCheckedException {
         if (!infos.hasNext())
             return;
 
+        // Received keys by caches, for statistics.
+        IntHashMap<GridMutableLong> receivedKeys = new IntHashMap<>();
+
         List<GridCacheMvccEntryInfo> entryHist = new ArrayList<>();
 
-        GridCacheContext cctx = grp.sharedGroup() ? null : grp.singleCacheContext();
+        GridCacheContext<?, ?> cctx = grp.sharedGroup() ? null : grp.singleCacheContext();
 
         // Loop through all received entries and try to preload them.
         while (infos.hasNext() || !entryHist.isEmpty()) {
@@ -828,13 +837,13 @@ public class GridDhtPartitionDemander {
 
                             rebalanceFut.onReceivedKeys(p, 1, node);
 
-                            updateGroupMetrics();
+                            receivedKeys.computeIfAbsent(cacheId, cid -> new GridMutableLong()).incrementAndGet();
                         }
 
-                        if (!hasMore)
-                            return;
-
                         entryHist.clear();
+
+                        if (!hasMore)
+                            break;
                     }
 
                     entryHist.add(entry);
@@ -844,6 +853,8 @@ public class GridDhtPartitionDemander {
                 ctx.database().checkpointReadUnlock();
             }
         }
+
+        updateKeyReceivedMetrics(grp, receivedKeys);
     }
 
     /**
@@ -854,14 +865,24 @@ public class GridDhtPartitionDemander {
      * @param infos Entries info for preload.
      * @throws IgniteCheckedException If failed.
      */
-    private void preloadEntries(AffinityTopologyVersion topVer, int p,
-        Iterator<GridCacheEntryInfo> infos) throws IgniteCheckedException {
+    private void preloadEntries(
+        AffinityTopologyVersion topVer,
+        int p,
+        Iterator<GridCacheEntryInfo> infos
+    ) throws IgniteCheckedException {
+        // Received keys by caches, for statistics.
+        IntHashMap<GridMutableLong> receivedKeys = new IntHashMap<>();
 
         grp.offheap().storeEntries(p, infos, new IgnitePredicateX<CacheDataRow>() {
+            /** {@inheritDoc} */
             @Override public boolean applyx(CacheDataRow row) throws IgniteCheckedException {
+                receivedKeys.computeIfAbsent(row.cacheId(), cid -> new GridMutableLong()).incrementAndGet();
+
                 return preloadEntry(row, topVer);
             }
         });
+
+        updateKeyReceivedMetrics(grp, receivedKeys);
     }
 
     /**
@@ -876,9 +897,7 @@ public class GridDhtPartitionDemander {
         assert !grp.mvccEnabled();
         assert ctx.database().checkpointLockIsHeldByThread();
 
-        updateGroupMetrics();
-
-        GridCacheContext cctx = grp.sharedGroup() ? ctx.cacheContext(row.cacheId()) : grp.singleCacheContext();
+        GridCacheContext<?, ?> cctx = grp.sharedGroup() ? ctx.cacheContext(row.cacheId()) : grp.singleCacheContext();
 
         if (cctx == null)
             return false;
@@ -1031,15 +1050,17 @@ public class GridDhtPartitionDemander {
     }
 
     /**
-     * Update rebalancing metrics.
+     * Updating metrics of received keys on rebalance.
+     *
+     * @param grpCtx Cache group context.
+     * @param receivedKeys Statistics of received keys by caches.
      */
-    private void updateGroupMetrics() {
-        // TODO: IGNITE-11330: Update metrics for touched cache only.
-        // Due to historical rebalancing "EstimatedRebalancingKeys" metric is currently calculated for the whole cache
-        // group (by partition counters), so "RebalancedKeys" and "RebalancingKeysRate" is calculated in the same way.
-        for (GridCacheContext cctx0 : grp.caches()) {
-            if (cctx0.statisticsEnabled())
-                cctx0.cache().metrics0().onRebalanceKeyReceived();
+    private void updateKeyReceivedMetrics(CacheGroupContext grpCtx, IntHashMap<GridMutableLong> receivedKeys) {
+        if (!receivedKeys.isEmpty()) {
+            for (GridCacheContext<?, ?> cacheCtx : grpCtx.caches()) {
+                if (cacheCtx.statisticsEnabled() && receivedKeys.containsKey(cacheCtx.cacheId()))
+                    cacheCtx.cache().metrics0().onRebalanceKeyReceived(receivedKeys.get(cacheCtx.cacheId()).get());
+            }
         }
     }
 
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/util/GridMutableLong.java b/modules/core/src/main/java/org/apache/ignite/internal/util/GridMutableLong.java
new file mode 100644
index 0000000..fd8a29f
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/util/GridMutableLong.java
@@ -0,0 +1,64 @@
+/*
+ * 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.ignite.internal.util;
+
+/**
+ * A mutable long for use in collections.
+ */
+public class GridMutableLong {
+    /** Long value. */
+    private long v;
+
+    /**
+     * Constructor.
+     *
+     * @param v Long value.
+     */
+    public GridMutableLong(long v) {
+        this.v = v;
+    }
+
+    /**
+     * Default constructor.
+     */
+    public GridMutableLong() {
+    }
+
+    /**
+     * Increments by one the current value.
+     *
+     * @return Updated value.
+     */
+    public final long incrementAndGet() {
+        return ++v;
+    }
+
+    /**
+     * Gets the current value.
+     *
+     * @return Current value.
+     */
+    public long get() {
+        return v;
+    }
+
+    /** {@inheritDoc} */
+    @Override public String toString() {
+        return Long.toString(v);
+    }
+}
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/util/collection/IntMap.java b/modules/core/src/main/java/org/apache/ignite/internal/util/collection/IntMap.java
index c606003..12d447e 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/util/collection/IntMap.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/util/collection/IntMap.java
@@ -17,6 +17,10 @@
 
 package org.apache.ignite.internal.util.collection;
 
+import java.util.function.IntFunction;
+import org.apache.ignite.internal.util.typedef.internal.A;
+import org.jetbrains.annotations.Nullable;
+
 /**
  * The map for integer keys.
  */
@@ -88,4 +92,30 @@ public interface IntMap<V> {
 
     /** Return array of values. */
     V[] values();
+
+    /**
+     * If the specified key is not already associated with a value (or is mapped
+     * to {@code null}), attempts to compute its value using the given mapping
+     * function and enters it into this map unless {@code null}.
+     *
+     * @param key Key with which the specified value is to be associated.
+     * @param mappingFunction Function to compute a value.
+     * @return Current (existing or computed) value.
+     * @throws NullPointerException If  the mappingFunction is null.
+     */
+    @Nullable default V computeIfAbsent(int key, IntFunction<? extends V> mappingFunction) {
+        A.notNull(mappingFunction, "mappingFunction");
+
+        V v;
+
+        if ((v = get(key)) == null) {
+            V newVal;
+            if ((newVal = mappingFunction.apply(key)) != null) {
+                put(key, newVal);
+                return newVal;
+            }
+        }
+
+        return v;
+    }
 }
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/CacheGroupsMetricsRebalanceTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/CacheGroupsMetricsRebalanceTest.java
index 43a873c..4635830 100644
--- a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/CacheGroupsMetricsRebalanceTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/CacheGroupsMetricsRebalanceTest.java
@@ -48,6 +48,7 @@ import org.apache.ignite.internal.TestRecordingCommunicationSpi;
 import org.apache.ignite.internal.processors.cache.distributed.dht.preloader.GridDhtPartitionSupplyMessage;
 import org.apache.ignite.internal.processors.metric.MetricRegistry;
 import org.apache.ignite.internal.processors.metric.impl.ObjectGauge;
+import org.apache.ignite.internal.util.future.GridFutureAdapter;
 import org.apache.ignite.internal.util.lang.GridAbsPredicate;
 import org.apache.ignite.internal.util.typedef.PA;
 import org.apache.ignite.internal.util.typedef.internal.A;
@@ -175,11 +176,13 @@ public class CacheGroupsMetricsRebalanceTest extends GridCommonAbstractTest {
     }
 
     /**
+     * Checks the correctness of {@link CacheMetrics#getRebalancingKeysRate}.
+     *
      * @throws Exception If failed.
      */
     @Test
     public void testRebalance() throws Exception {
-        Ignite ignite = startGrids(4);
+        Ignite ignite = startGrid(0);
 
         IgniteCache<Object, Object> cache1 = ignite.cache(CACHE1);
         IgniteCache<Object, Object> cache2 = ignite.cache(CACHE2);
@@ -191,45 +194,48 @@ public class CacheGroupsMetricsRebalanceTest extends GridCommonAbstractTest {
                 cache2.put(i, CACHE2 + "-" + i);
         }
 
-        final CountDownLatch l1 = new CountDownLatch(1);
-        final CountDownLatch l2 = new CountDownLatch(1);
+        final CountDownLatch startStopRebalanceLatch = new CountDownLatch(1);
+        final CountDownLatch finishStopRebalanceLatch = new CountDownLatch(1);
+        GridFutureAdapter<Void> stopRebalanceResFut = new GridFutureAdapter<>();
 
-        startGrid(4).events().localListen(new IgnitePredicate<Event>() {
-            @Override public boolean apply(Event evt) {
-                l1.countDown();
+        ignite = startGrid(1, cfg -> {
+            cfg.setLocalEventListeners(Collections.singletonMap(
+                (IgnitePredicate<Event>)evt -> {
+                    startStopRebalanceLatch.countDown();
 
-                try {
-                    assertTrue(l2.await(5, TimeUnit.SECONDS));
-                }
-                catch (InterruptedException e) {
-                    throw new AssertionError();
-                }
+                    try {
+                        assertTrue(finishStopRebalanceLatch.await(getTestTimeout(), TimeUnit.SECONDS));
 
-                return false;
-            }
-        }, EventType.EVT_CACHE_REBALANCE_STOPPED);
+                        stopRebalanceResFut.onDone();
+                    }
+                    catch (Throwable e) {
+                        stopRebalanceResFut.onDone(e);
+                    }
 
-        assertTrue(l1.await(5, TimeUnit.SECONDS));
+                    return false;
+                },
+                new int[] {EventType.EVT_CACHE_REBALANCE_STOPPED}
+            ));
+        });
 
-        ignite = ignite(4);
+        assertTrue(startStopRebalanceLatch.await(getTestTimeout(), TimeUnit.SECONDS));
 
         CacheMetrics metrics1 = ignite.cache(CACHE1).localMetrics();
         CacheMetrics metrics2 = ignite.cache(CACHE2).localMetrics();
 
-        l2.countDown();
+        finishStopRebalanceLatch.countDown();
 
         long rate1 = metrics1.getRebalancingKeysRate();
         long rate2 = metrics2.getRebalancingKeysRate();
 
         assertTrue(rate1 > 0);
         assertTrue(rate2 > 0);
+        assertTrue(rate1 > rate2);
 
-        // rate1 has to be roughly the same as rate2
-        double ratio = ((double)rate2 / rate1);
-
-        log.info("Ratio: " + ratio);
+        assertEquals(metrics1.getRebalancedKeys(), rate1);
+        assertEquals(metrics2.getRebalancedKeys(), rate2);
 
-        assertTrue(ratio > 0.9 && ratio < 1.1);
+        stopRebalanceResFut.get(getTestTimeout());
     }
 
     /**
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/rebalancing/RebalanceMetricsTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/rebalancing/RebalanceMetricsTest.java
new file mode 100644
index 0000000..49343b1
--- /dev/null
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/rebalancing/RebalanceMetricsTest.java
@@ -0,0 +1,112 @@
+/*
+ * 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.ignite.internal.processors.cache.distributed.rebalancing;
+
+import org.apache.ignite.cache.CacheMetrics;
+import org.apache.ignite.cluster.ClusterState;
+import org.apache.ignite.configuration.CacheConfiguration;
+import org.apache.ignite.configuration.IgniteConfiguration;
+import org.apache.ignite.internal.IgniteEx;
+import org.apache.ignite.internal.processors.cache.CacheMetricsImpl;
+import org.apache.ignite.internal.processors.cache.GridCacheContext;
+import org.apache.ignite.internal.util.typedef.internal.CU;
+import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
+import org.jetbrains.annotations.Nullable;
+import org.junit.Test;
+
+/**
+ * Class for testing rebalance metrics.
+ */
+public class RebalanceMetricsTest extends GridCommonAbstractTest {
+    /** Cache configurations. */
+    @Nullable private CacheConfiguration<?, ?>[] cacheConfigs;
+
+    /** {@inheritDoc} */
+    @Override protected void beforeTest() throws Exception {
+        super.beforeTest();
+
+        stopAllGrids();
+    }
+
+    /** {@inheritDoc} */
+    @Override protected void afterTest() throws Exception {
+        super.afterTest();
+
+        stopAllGrids();
+    }
+
+    /** {@inheritDoc} */
+    @Override protected IgniteConfiguration getConfiguration(String igniteInstanceName) throws Exception {
+        return super.getConfiguration(igniteInstanceName).setCacheConfiguration(cacheConfigs);
+    }
+
+    /**
+     * Testing the correctness of metric {@link CacheMetrics#getRebalancedKeys()}.
+     *
+     * @throws Exception If failed.
+     */
+    @Test
+    public void testReceivedKeys() throws Exception {
+        cacheConfigs = new CacheConfiguration[] {
+            new CacheConfiguration<>(DEFAULT_CACHE_NAME + "0")
+                .setGroupName(DEFAULT_CACHE_NAME)
+                .setStatisticsEnabled(true),
+            new CacheConfiguration<>(DEFAULT_CACHE_NAME + "1")
+                .setGroupName(DEFAULT_CACHE_NAME)
+                .setStatisticsEnabled(true),
+            new CacheConfiguration<>(DEFAULT_CACHE_NAME + "2")
+                .setGroupName(DEFAULT_CACHE_NAME)
+                .setStatisticsEnabled(false),
+        };
+
+        IgniteEx n0 = startGrid(0);
+
+        n0.cluster().state(ClusterState.ACTIVE);
+        awaitPartitionMapExchange();
+
+        for (CacheConfiguration<?, ?> cacheCfg : cacheConfigs) {
+            for (int i = 0; i < 100; i++)
+                n0.cache(cacheCfg.getName()).put(i + CU.cacheId(cacheCfg.getName()), new byte[64]);
+        }
+
+        IgniteEx n1 = startGrid(1);
+        awaitPartitionMapExchange();
+
+        for (CacheConfiguration<?, ?> cacheCfg : cacheConfigs) {
+            GridCacheContext<?, ?> cacheCtx0 = n0.context().cache().cache(cacheCfg.getName()).context();
+            GridCacheContext<?, ?> cacheCtx1 = n1.context().cache().cache(cacheCfg.getName()).context();
+
+            assertEquals(cacheCfg.getName(), cacheCfg.isStatisticsEnabled(), cacheCtx0.statisticsEnabled());
+            assertEquals(cacheCfg.getName(), cacheCfg.isStatisticsEnabled(), cacheCtx1.statisticsEnabled());
+
+            CacheMetricsImpl metrics0 = cacheCtx0.cache().metrics0();
+            CacheMetricsImpl metrics1 = cacheCtx1.cache().metrics0();
+
+            assertEquals(cacheCfg.getName(), cacheCfg.isStatisticsEnabled(), metrics0.isStatisticsEnabled());
+            assertEquals(cacheCfg.getName(), cacheCfg.isStatisticsEnabled(), metrics1.isStatisticsEnabled());
+
+            assertEquals(cacheCfg.getName(), 0, metrics0.getRebalancedKeys());
+
+            assertEquals(
+                cacheCfg.getName(),
+                cacheCfg.isStatisticsEnabled() ? metrics1.getKeySize() : 0,
+                metrics1.getRebalancedKeys()
+            );
+        }
+    }
+}
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/util/GridMutableLongTest.java b/modules/core/src/test/java/org/apache/ignite/internal/util/GridMutableLongTest.java
new file mode 100644
index 0000000..92f45d6
--- /dev/null
+++ b/modules/core/src/test/java/org/apache/ignite/internal/util/GridMutableLongTest.java
@@ -0,0 +1,61 @@
+/*
+ * 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.ignite.internal.util;
+
+import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
+import org.junit.Test;
+
+/**
+ * Class for testing {@link GridMutableLong}.
+ */
+public class GridMutableLongTest extends GridCommonAbstractTest {
+    /**
+     * Checking the correctness of object initialization.
+     */
+    @Test
+    public void testInitialization() {
+        assertEquals(0, new GridMutableLong().get());
+        assertEquals(5, new GridMutableLong(5).get());
+        assertEquals(-25, new GridMutableLong(-25).get());
+        assertEquals(Long.MIN_VALUE, new GridMutableLong(Long.MIN_VALUE).get());
+        assertEquals(Long.MAX_VALUE, new GridMutableLong(Long.MAX_VALUE).get());
+    }
+
+    /**
+     * Checking the correctness of the string representation of an object.
+     */
+    @Test
+    public void testToString() {
+        assertEquals(Long.toString(0), new GridMutableLong().toString());
+        assertEquals(Long.toString(5), new GridMutableLong(5).toString());
+        assertEquals(Long.toString(-25), new GridMutableLong(-25).toString());
+    }
+
+    /**
+     * Checking the correctness of the {@link GridMutableLong#incrementAndGet()}.
+     */
+    @Test
+    public void testIncrementAndGet() {
+        for (long l : new long[] {0, 5, -25}) {
+            GridMutableLong mutableLong = new GridMutableLong(l);
+
+            for (int i = 0; i < 5; i++)
+                assertEquals(++l, mutableLong.incrementAndGet());
+        }
+    }
+}
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/util/collection/IntHashMapTest.java b/modules/core/src/test/java/org/apache/ignite/internal/util/collection/IntHashMapTest.java
index da84dfc..704ca2d 100644
--- a/modules/core/src/test/java/org/apache/ignite/internal/util/collection/IntHashMapTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/internal/util/collection/IntHashMapTest.java
@@ -25,6 +25,7 @@ import org.junit.Test;
 
 import static org.apache.ignite.internal.util.collection.IntHashMap.INITIAL_CAPACITY;
 import static org.apache.ignite.internal.util.collection.IntHashMap.MAXIMUM_CAPACITY;
+import static org.apache.ignite.testframework.GridTestUtils.assertThrows;
 import static org.junit.Assert.assertEquals;
 
 /**
@@ -115,6 +116,32 @@ public class IntHashMapTest extends AbstractBaseIntMapTest {
     }
 
     /**
+     * Checking the correctness of {@link IntMap#computeIfAbsent}.
+     */
+    @Test
+    public void testComputeIfAbsent() {
+        IntHashMap<Object> map0 = new IntHashMap<>();
+
+        assertThrows(
+            null,
+            () -> map0.computeIfAbsent(0, null),
+            NullPointerException.class,
+            null
+        );
+
+        Map<Integer, Object> map1 = new HashMap<>();
+
+        assertEquals(map1.computeIfAbsent(0, i -> i + " 0"), map0.computeIfAbsent(0, i -> i + " 0"));
+        assertEquals(map1.computeIfAbsent(0, i -> i + " 1"), map0.computeIfAbsent(0, i -> i + " 1"));
+
+        assertEquals(map1.computeIfAbsent(1, i -> i + " 0"), map0.computeIfAbsent(1, i -> i + " 0"));
+        assertEquals(map1.computeIfAbsent(1, i -> i + " 1"), map0.computeIfAbsent(1, i -> i + " 1"));
+
+        assertEquals("0 0", map0.get(0));
+        assertEquals("1 0", map0.get(1));
+    }
+
+    /**
      * @param initSize Initial size.
      */
     private int realCapacityForInitialSize(int initSize) {
diff --git a/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheTestSuite5.java b/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheTestSuite5.java
index b1f7823..35072ab 100644
--- a/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheTestSuite5.java
+++ b/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheTestSuite5.java
@@ -63,6 +63,7 @@ import org.apache.ignite.internal.processors.cache.distributed.dht.NotMappedPart
 import org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridCacheAtomicPreloadSelfTest;
 import org.apache.ignite.internal.processors.cache.distributed.dht.atomic.IgniteCacheAtomicProtocolTest;
 import org.apache.ignite.internal.processors.cache.distributed.rebalancing.CacheManualRebalancingTest;
+import org.apache.ignite.internal.processors.cache.distributed.rebalancing.RebalanceMetricsTest;
 import org.apache.ignite.internal.processors.cache.distributed.replicated.IgniteCacheSyncRebalanceModeSelfTest;
 import org.apache.ignite.internal.processors.cache.store.IgniteCacheWriteBehindNoUpdateSelfTest;
 import org.apache.ignite.testframework.GridTestUtils;
@@ -121,6 +122,7 @@ public class IgniteCacheTestSuite5 {
 
         GridTestUtils.addTestIfNeeded(suite, CacheRebalancingSelfTest.class, ignoredTests);
         GridTestUtils.addTestIfNeeded(suite, CacheManualRebalancingTest.class, ignoredTests);
+        GridTestUtils.addTestIfNeeded(suite, RebalanceMetricsTest.class, ignoredTests);
 
         // Affinity tests.
         GridTestUtils.addTestIfNeeded(suite, GridCacheAffinityBackupsSelfTest.class, ignoredTests);
diff --git a/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteKernalSelfTestSuite.java b/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteKernalSelfTestSuite.java
index b79d174..70bce85 100644
--- a/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteKernalSelfTestSuite.java
+++ b/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteKernalSelfTestSuite.java
@@ -58,6 +58,7 @@ import org.apache.ignite.internal.processors.cluster.ClusterReadOnlyModeSelfTest
 import org.apache.ignite.internal.processors.cluster.GridAddressResolverSelfTest;
 import org.apache.ignite.internal.processors.cluster.GridUpdateNotifierSelfTest;
 import org.apache.ignite.internal.processors.port.GridPortProcessorSelfTest;
+import org.apache.ignite.internal.util.GridMutableLongTest;
 import org.apache.ignite.internal.util.GridStartupWithUndefinedIgniteHomeSelfTest;
 import org.apache.ignite.internal.util.IgniteUtilsWorkDirectoryTest;
 import org.apache.ignite.spi.communication.GridCacheMessageSelfTest;
@@ -113,7 +114,8 @@ import org.junit.runners.Suite;
     ThreadNameValidationTest.class,
     NodeWithFilterRestartTest.class,
     ClusterActiveStateChangeWithNodeOutOfBaselineTest.class,
-    IgniteNodeValidationFailedEventTest.class
+    IgniteNodeValidationFailedEventTest.class,
+    GridMutableLongTest.class
 })
 public class IgniteKernalSelfTestSuite {
 }
diff --git a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/performancestatistics/PerformanceStatisticsQueryTest.java b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/performancestatistics/PerformanceStatisticsQueryTest.java
index 2cd63db..4aa14fa 100644
--- a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/performancestatistics/PerformanceStatisticsQueryTest.java
+++ b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/performancestatistics/PerformanceStatisticsQueryTest.java
@@ -119,6 +119,7 @@ public class PerformanceStatisticsQueryTest extends AbstractPerformanceStatistic
     @Override protected void beforeTestsStarted() throws Exception {
         super.beforeTestsStarted();
 
+        stopAllGrids();
         cleanPersistenceDir();
 
         srv = startGrids(2);
@@ -164,7 +165,8 @@ public class PerformanceStatisticsQueryTest extends AbstractPerformanceStatistic
     @Override protected void afterTest() throws Exception {
         super.afterTest();
 
-        cache.query(new SqlFieldsQuery("drop table if exists " + SQL_TABLE));
+        if (cache != null)
+            cache.query(new SqlFieldsQuery("drop table if exists " + SQL_TABLE));
     }
 
     /** @throws Exception If failed. */