diff --git a/docs/_docs/monitoring-metrics/system-views.adoc b/docs/_docs/monitoring-metrics/system-views.adoc index d7426347a0f6b..61a519e02c9b0 100644 --- a/docs/_docs/monitoring-metrics/system-views.adoc +++ b/docs/_docs/monitoring-metrics/system-views.adoc @@ -275,6 +275,7 @@ Each row in this view represents a transaction object on the node where the view |ORIGINATING_NODE_ID | UUID | ID of the node that initiated the current transaction object. For a transaction object mapped to a primary partition, this is the transaction initiator node; for a transaction object mapped to a backup partition, this is the node that owns the primary partition |STATE | string | Current transaction state |XID | UUID | Unique transaction identifier +|ORIGINATING_XID | UUID | Ttransaction ID on originating node |LABEL | string | Transaction label |START_TIME | long | Start time of the transaction on this node |ISOLATION | string | Transaction isolation level @@ -299,6 +300,39 @@ Each row in this view represents a transaction object on the node where the view |TOP_VER | string | Topology version assigned to the transaction. If not assigned explicitly, it is a topology version of the latest partition exchange. |=== +== CACHE_EXPLICIT_LOCKS + +This view exposes information about explicit locks acquired on the current node. +Explicit locks are acquired using the `Cache.lock(key)` API. + +[{table_opts}] +|=== +|NAME | TYPE | DESCRIPTION +|CACHE_ID | int | Cache ID +|KEY | string | Locked key +|THREAD_ID | long | ID of the thread that acquired the lock +|XID | UUID | Lock ID (unique identifier) +|=== + +== CACHE_KEY_LOCKS + +This view exposes information about all locks (both explicit and transactional) requested for keys hosted on the current node. +This includes locks from remote nodes trying to access primary keys on this node. + +[{table_opts}] +|=== +|NAME | TYPE | DESCRIPTION +|CACHE_ID | int | Cache ID +|KEY | string | Locked key +|NODE_ID | UUID | ID of the node where the lock is hosted +|ORIGINATING_NODE_ID | UUID | ID of the node that initiated the lock request +|IS_OWNER | boolean | `True` if the lock is currently owned +|IS_TX | boolean | `True` if the lock is part of a transaction +|FLAGS | string | All flags for the lock +|XID | UUID | Current transaction ID (or explicit lock ID) +|ORIGINATING_XID | UUID | Originating transaction ID (or explicit lock ID) +|=== + == NODES diff --git a/modules/binary/api/src/main/java/org/apache/ignite/internal/binary/BinaryUtils.java b/modules/binary/api/src/main/java/org/apache/ignite/internal/binary/BinaryUtils.java index fcbd74fe0c550..14a97520c8175 100644 --- a/modules/binary/api/src/main/java/org/apache/ignite/internal/binary/BinaryUtils.java +++ b/modules/binary/api/src/main/java/org/apache/ignite/internal/binary/BinaryUtils.java @@ -3291,7 +3291,7 @@ public void clearAllListener() { * @param ver Cache version. * @return Version represented as {@code IgniteUuid}. */ - public static IgniteUuid asIgniteUuid(GridCacheVersion ver) { - return new IgniteUuid(new UUID(ver.topologyVersion(), ver.nodeOrderAndDrIdRaw()), ver.order()); + public static @Nullable IgniteUuid asIgniteUuid(@Nullable GridCacheVersion ver) { + return ver == null ? null : new IgniteUuid(new UUID(ver.topologyVersion(), ver.nodeOrderAndDrIdRaw()), ver.order()); } } diff --git a/modules/control-utility/src/test/java/org/apache/ignite/util/SystemViewCommandTest.java b/modules/control-utility/src/test/java/org/apache/ignite/util/SystemViewCommandTest.java index 288484d8a1483..d927b361a758e 100644 --- a/modules/control-utility/src/test/java/org/apache/ignite/util/SystemViewCommandTest.java +++ b/modules/control-utility/src/test/java/org/apache/ignite/util/SystemViewCommandTest.java @@ -61,9 +61,9 @@ import org.apache.ignite.internal.binary.mutabletest.GridBinaryTestClasses.TestObjectEnum; import org.apache.ignite.internal.management.SystemViewCommand; import org.apache.ignite.internal.management.SystemViewTask; -import org.apache.ignite.internal.metric.SystemViewSelfTest.TestPredicate; -import org.apache.ignite.internal.metric.SystemViewSelfTest.TestRunnable; -import org.apache.ignite.internal.metric.SystemViewSelfTest.TestTransformer; +import org.apache.ignite.internal.metric.SystemViewExecutorsTest.TestRunnable; +import org.apache.ignite.internal.metric.SystemViewQueriesTest.TestPredicate; +import org.apache.ignite.internal.metric.SystemViewQueriesTest.TestTransformer; import org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion; import org.apache.ignite.internal.processors.cache.distributed.dht.topology.GridDhtPartitionState; import org.apache.ignite.internal.processors.cache.metric.SqlViewExporterSpiTest.TestAffinityFunction; @@ -93,8 +93,8 @@ import static org.apache.ignite.internal.management.SystemViewCommand.COLUMN_SEPARATOR; import static org.apache.ignite.internal.managers.discovery.GridDiscoveryManager.NODES_SYS_VIEW; import static org.apache.ignite.internal.managers.systemview.ScanQuerySystemView.SCAN_QRY_SYS_VIEW; -import static org.apache.ignite.internal.metric.SystemViewSelfTest.TEST_PREDICATE; -import static org.apache.ignite.internal.metric.SystemViewSelfTest.TEST_TRANSFORMER; +import static org.apache.ignite.internal.metric.SystemViewQueriesTest.TEST_PREDICATE; +import static org.apache.ignite.internal.metric.SystemViewQueriesTest.TEST_TRANSFORMER; import static org.apache.ignite.internal.processors.cache.ClusterCachesInfo.CACHES_VIEW; import static org.apache.ignite.internal.processors.cache.ClusterCachesInfo.CACHE_GRPS_VIEW; import static org.apache.ignite.internal.processors.cache.GridCacheProcessor.CACHE_GRP_PAGE_LIST_VIEW; diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheExplicitLockSpan.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheExplicitLockSpan.java index e0c6d9b42406a..53c8ad6f5774d 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheExplicitLockSpan.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheExplicitLockSpan.java @@ -17,6 +17,8 @@ package org.apache.ignite.internal.processors.cache; +import java.util.ArrayList; +import java.util.Collection; import java.util.Deque; import java.util.HashMap; import java.util.Iterator; @@ -216,6 +218,20 @@ public boolean isEmpty() { } } + /** + * @return Lock candidates. + */ + public Collection candidates() { + lock(); + + try { + return new ArrayList<>(F.flatCollections(cands.values())); + } + finally { + unlock(); + } + } + /** * Marks all candidates added for given key as owned. * diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheMvccCandidate.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheMvccCandidate.java index d0e624f94bb0d..4a6e96e4b8287 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheMvccCandidate.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheMvccCandidate.java @@ -607,6 +607,22 @@ public IgniteTxKey key() { return parent0.txKey(); } + /** */ + public String enabledFlags() { + SB sb = new SB(); + + for (Mask m : Mask.MASKS) { + if (m.bit(flags) != 0) { + if (sb.length() != 0) + sb.a(" | "); + + sb.a(m.name()); + } + } + + return sb.toString(); + } + /** {@inheritDoc} */ @Override public GridCacheMvccCandidate candidate(int idx) { assert idx == 0 : idx; diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheMvccManager.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheMvccManager.java index 9ca503678031b..2123441110e76 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheMvccManager.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheMvccManager.java @@ -20,6 +20,7 @@ import java.util.ArrayDeque; import java.util.ArrayList; import java.util.Collection; +import java.util.Collections; import java.util.Deque; import java.util.HashMap; import java.util.HashSet; @@ -49,6 +50,8 @@ import org.apache.ignite.internal.processors.cache.transactions.IgniteInternalTx; import org.apache.ignite.internal.processors.cache.transactions.IgniteTxKey; import org.apache.ignite.internal.processors.cache.version.GridCacheVersion; +import org.apache.ignite.internal.systemview.CacheExplicitLockViewWalker; +import org.apache.ignite.internal.systemview.CacheKeyLockViewWalker; import org.apache.ignite.internal.util.GridBoundedConcurrentLinkedHashSet; import org.apache.ignite.internal.util.GridConcurrentFactory; import org.apache.ignite.internal.util.GridConcurrentHashSet; @@ -67,6 +70,8 @@ import org.apache.ignite.lang.IgniteFuture; import org.apache.ignite.lang.IgnitePredicate; import org.apache.ignite.lang.IgniteUuid; +import org.apache.ignite.spi.systemview.view.CacheExplicitLockView; +import org.apache.ignite.spi.systemview.view.CacheKeyLockView; import org.apache.ignite.util.deque.FastSizeDeque; import org.jetbrains.annotations.Nullable; @@ -94,6 +99,18 @@ public class GridCacheMvccManager extends GridCacheSharedManagerAdapter { private static final int MAX_NESTED_LSNR_CALLS = getInteger(IGNITE_MAX_NESTED_LISTENER_CALLS, DFLT_MAX_NESTED_LISTENER_CALLS); + /** System view name for cache explicit locks. */ + public static final String CACHE_EXPLICIT_LOCKS_VIEW = "cacheExplicitLocks"; + + /** System view description for cache explicit locks. */ + public static final String CACHE_EXPLICIT_LOCKS_VIEW_DESC = "Explicit locks on cache keys"; + + /** System view name for cache locks. */ + public static final String CACHE_KEY_LOCKS_VIEW = "cacheKeyLocks"; + + /** System view description for cache keys locks. */ + public static final String CACHE_KEY_LOCKS_VIEW_DESC = "Held and queued locks on cache keys"; + /** Pending locks per thread. */ private final ThreadLocal> pending = new ThreadLocal<>(); @@ -282,6 +299,34 @@ else if (log.isDebugEnabled()) pendingExplicit = GridConcurrentFactory.newMap(); cctx.gridEvents().addLocalEventListener(discoLsnr, EVT_NODE_FAILED, EVT_NODE_LEFT); + + cctx.kernalContext().systemView().registerInnerCollectionView( + CACHE_EXPLICIT_LOCKS_VIEW, + CACHE_EXPLICIT_LOCKS_VIEW_DESC, + new CacheExplicitLockViewWalker(), + pendingExplicit.values(), + GridCacheExplicitLockSpan::candidates, + (threadId, lock) -> new CacheExplicitLockView(lock) + ); + + cctx.kernalContext().systemView().registerInnerCollectionView( + CACHE_KEY_LOCKS_VIEW, + CACHE_KEY_LOCKS_VIEW_DESC, + new CacheKeyLockViewWalker(), + locked.values(), + entry -> { + entry.lockEntry(); + try { + GridCacheMvcc mvcc = entry.mvccExtras(); + return mvcc != null ? mvcc.localCandidates() : Collections.emptyList(); + } + finally { + entry.unlockEntry(); + } + }, + (entry, cand) -> new CacheKeyLockView(cand) + ); + } /** {@inheritDoc} */ diff --git a/modules/core/src/main/java/org/apache/ignite/spi/systemview/view/CacheExplicitLockView.java b/modules/core/src/main/java/org/apache/ignite/spi/systemview/view/CacheExplicitLockView.java new file mode 100644 index 0000000000000..ff1ff8bee6d20 --- /dev/null +++ b/modules/core/src/main/java/org/apache/ignite/spi/systemview/view/CacheExplicitLockView.java @@ -0,0 +1,76 @@ +/* + * 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.spi.systemview.view; + +import org.apache.ignite.internal.binary.BinaryUtils; +import org.apache.ignite.internal.processors.cache.GridCacheMvccCandidate; +import org.apache.ignite.internal.systemview.Order; +import org.apache.ignite.internal.systemview.SystemViewDescriptor; +import org.apache.ignite.internal.util.tostring.GridToStringExclude; +import org.apache.ignite.internal.util.typedef.internal.S; +import org.apache.ignite.lang.IgniteUuid; + +/** + * Cache explicit lock representation for a {@link SystemView}. + * Shows locks acquired on current node (not hosted by current node). + */ +@SystemViewDescriptor +public class CacheExplicitLockView { + /** */ + @GridToStringExclude + private final GridCacheMvccCandidate cand; + + /** + * @param cand Lock candidate + */ + public CacheExplicitLockView(GridCacheMvccCandidate cand) { + this.cand = cand; + } + + /** + * @return Cache ID. + */ + @Order + public int cacheId() { + return cand.key().cacheId(); + } + + /** + * @return Key. + */ + @Order(1) + public String key() { + return cand.key().key().toString(); + } + + /** + * @return Thread ID. + */ + @Order(2) + public long threadId() { + return cand.threadId(); + } + + /** + * @return Version. + */ + @Order(3) + public IgniteUuid xid() { + return BinaryUtils.asIgniteUuid(cand.version()); + } +} diff --git a/modules/core/src/main/java/org/apache/ignite/spi/systemview/view/CacheKeyLockView.java b/modules/core/src/main/java/org/apache/ignite/spi/systemview/view/CacheKeyLockView.java new file mode 100644 index 0000000000000..ab4e1287f63da --- /dev/null +++ b/modules/core/src/main/java/org/apache/ignite/spi/systemview/view/CacheKeyLockView.java @@ -0,0 +1,119 @@ +/* + * 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.spi.systemview.view; + +import java.util.UUID; +import org.apache.ignite.internal.binary.BinaryUtils; +import org.apache.ignite.internal.processors.cache.GridCacheMvccCandidate; +import org.apache.ignite.internal.systemview.Order; +import org.apache.ignite.internal.systemview.SystemViewDescriptor; +import org.apache.ignite.internal.util.tostring.GridToStringExclude; +import org.apache.ignite.internal.util.typedef.internal.S; +import org.apache.ignite.lang.IgniteUuid; + +/** + * Cache key lock representation for a {@link SystemView}. + * Shows held cache key locks and queued cache key locks hosted on current node, + * including explicit locks and transactional locks. + */ +@SystemViewDescriptor +public class CacheKeyLockView { + /** Lock candidate. */ + @GridToStringExclude + private final GridCacheMvccCandidate cand; + + /** + * @param cand Lock candidate + */ + public CacheKeyLockView(GridCacheMvccCandidate cand) { + this.cand = cand; + } + + /** + * @return Cache ID. + */ + @Order + public int cacheId() { + return cand.key().cacheId(); + } + + /** + * @return Key. + */ + @Order(1) + public String key() { + return cand.key().key().toString(); + } + + /** + * @return Node ID. + */ + @Order(2) + public UUID nodeId() { + return cand.nodeId(); + } + + /** + * @return Originating node ID. + */ + @Order(3) + public UUID originatingNodeId() { + return cand.otherNodeId(); + } + + + /** + * @return "OWNER" flag. + */ + @Order(4) + public boolean isOwner() { + return cand.owner(); + } + + /** + * @return "TX" flag. + */ + @Order(5) + public boolean isTx() { + return cand.tx(); + } + + /** + * @return All enabled flags. + */ + @Order(6) + public String flags() { + return cand.enabledFlags(); + } + + /** + * @return Transaction ID. + */ + @Order(7) + public IgniteUuid xid() { + return BinaryUtils.asIgniteUuid(cand.version()); + } + + /** + * @return Originating transaction ID. + */ + @Order(8) + public IgniteUuid originatingXid() { + return BinaryUtils.asIgniteUuid(cand.otherVersion()); + } +} diff --git a/modules/core/src/main/java/org/apache/ignite/spi/systemview/view/TransactionView.java b/modules/core/src/main/java/org/apache/ignite/spi/systemview/view/TransactionView.java index bc09a478c99b7..cd49ddd0aafab 100644 --- a/modules/core/src/main/java/org/apache/ignite/spi/systemview/view/TransactionView.java +++ b/modules/core/src/main/java/org/apache/ignite/spi/systemview/view/TransactionView.java @@ -20,6 +20,7 @@ import java.util.Collection; import java.util.Objects; import java.util.UUID; +import org.apache.ignite.internal.binary.BinaryUtils; import org.apache.ignite.internal.processors.cache.transactions.IgniteInternalTx; import org.apache.ignite.internal.processors.cache.transactions.IgniteTxEntry; import org.apache.ignite.internal.processors.cache.transactions.IgniteTxState; @@ -125,6 +126,14 @@ public IgniteUuid xid() { return tx.xid(); } + /** + * @return Near transaction ID. + * @see IgniteInternalTx#nearXidVersion() () + */ + public IgniteUuid originatingXid() { + return BinaryUtils.asIgniteUuid(tx.nearXidVersion()); + } + /** * @return {@code True} if transaction is started for system cache. * @see IgniteInternalTx#system() @@ -284,6 +293,5 @@ public String cacheIds() { catch (Throwable e) { return null; } - - } + } } diff --git a/modules/core/src/test/java/org/apache/ignite/internal/metric/JmxExporterSpiTest.java b/modules/core/src/test/java/org/apache/ignite/internal/metric/JmxExporterSpiTest.java index 67d90fe45a95b..36b457963d5dc 100644 --- a/modules/core/src/test/java/org/apache/ignite/internal/metric/JmxExporterSpiTest.java +++ b/modules/core/src/test/java/org/apache/ignite/internal/metric/JmxExporterSpiTest.java @@ -64,8 +64,8 @@ import org.apache.ignite.internal.binary.mutabletest.GridBinaryTestClasses.TestObjectAllTypes; import org.apache.ignite.internal.binary.mutabletest.GridBinaryTestClasses.TestObjectEnum; import org.apache.ignite.internal.client.thin.ProtocolVersion; -import org.apache.ignite.internal.metric.SystemViewSelfTest.TestPredicate; -import org.apache.ignite.internal.metric.SystemViewSelfTest.TestTransformer; +import org.apache.ignite.internal.metric.SystemViewQueriesTest.TestPredicate; +import org.apache.ignite.internal.metric.SystemViewQueriesTest.TestTransformer; import org.apache.ignite.internal.processors.cache.persistence.IgniteCacheDatabaseSharedManager; import org.apache.ignite.internal.processors.metastorage.DistributedMetaStorage; import org.apache.ignite.internal.processors.metric.GridMetricManager; @@ -91,8 +91,8 @@ import static org.apache.ignite.internal.managers.systemview.ScanQuerySystemView.SCAN_QRY_SYS_VIEW; import static org.apache.ignite.internal.managers.systemview.SystemViewMBean.FILTER_OPERATION; import static org.apache.ignite.internal.managers.systemview.SystemViewMBean.VIEWS; -import static org.apache.ignite.internal.metric.SystemViewSelfTest.TEST_PREDICATE; -import static org.apache.ignite.internal.metric.SystemViewSelfTest.TEST_TRANSFORMER; +import static org.apache.ignite.internal.metric.SystemViewQueriesTest.TEST_PREDICATE; +import static org.apache.ignite.internal.metric.SystemViewQueriesTest.TEST_TRANSFORMER; import static org.apache.ignite.internal.processors.cache.CacheMetricsImpl.CACHE_METRICS; import static org.apache.ignite.internal.processors.cache.ClusterCachesInfo.CACHES_VIEW; import static org.apache.ignite.internal.processors.cache.ClusterCachesInfo.CACHE_GRPS_VIEW; diff --git a/modules/core/src/test/java/org/apache/ignite/internal/metric/SystemViewAbstractTest.java b/modules/core/src/test/java/org/apache/ignite/internal/metric/SystemViewAbstractTest.java new file mode 100644 index 0000000000000..8a6c2ae2d2e79 --- /dev/null +++ b/modules/core/src/test/java/org/apache/ignite/internal/metric/SystemViewAbstractTest.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.ignite.internal.metric; + +import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest; + +/** Abstract base class for system view tests. */ +public abstract class SystemViewAbstractTest extends GridCommonAbstractTest { + /** {@inheritDoc} */ + @Override protected void beforeTestsStarted() throws Exception { + super.beforeTestsStarted(); + + cleanPersistenceDir(); + } + + /** {@inheritDoc} */ + @Override protected void afterTestsStopped() throws Exception { + super.afterTestsStopped(); + + cleanPersistenceDir(); + } +} diff --git a/modules/core/src/test/java/org/apache/ignite/internal/metric/SystemViewBinaryMetaTest.java b/modules/core/src/test/java/org/apache/ignite/internal/metric/SystemViewBinaryMetaTest.java new file mode 100644 index 0000000000000..7954ae064ba75 --- /dev/null +++ b/modules/core/src/test/java/org/apache/ignite/internal/metric/SystemViewBinaryMetaTest.java @@ -0,0 +1,68 @@ +/* + * 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.metric; + +import java.lang.reflect.Field; +import org.apache.ignite.IgniteCache; +import org.apache.ignite.internal.IgniteEx; +import org.apache.ignite.internal.binary.mutabletest.GridBinaryTestClasses.TestObjectAllTypes; +import org.apache.ignite.internal.binary.mutabletest.GridBinaryTestClasses.TestObjectEnum; +import org.apache.ignite.spi.systemview.view.BinaryMetadataView; +import org.apache.ignite.spi.systemview.view.SystemView; +import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest; +import org.junit.Test; + +import static org.apache.ignite.internal.processors.cache.binary.CacheObjectBinaryProcessorImpl.BINARY_METADATA_VIEW; + +/** Tests for {@link SystemView} for binary meta. */ +public class SystemViewBinaryMetaTest extends GridCommonAbstractTest { + /** */ + @Test + public void testBinaryMeta() throws Exception { + try (IgniteEx g = startGrid(0)) { + IgniteCache c1 = g.createCache("test-cache"); + IgniteCache c2 = g.createCache("test-enum-cache"); + + c1.put(1, new TestObjectAllTypes()); + c2.put(1, TestObjectEnum.A); + + SystemView view = g.context().systemView().view(BINARY_METADATA_VIEW); + + assertNotNull(view); + assertEquals(2, view.size()); + + for (BinaryMetadataView meta : view) { + if (TestObjectEnum.class.getName().contains(meta.typeName())) { + assertTrue(meta.isEnum()); + + assertEquals(0, meta.fieldsCount()); + } + else { + assertFalse(meta.isEnum()); + + Field[] fields = TestObjectAllTypes.class.getDeclaredFields(); + + assertEquals(fields.length, meta.fieldsCount()); + + for (Field field : fields) + assertTrue(meta.fields().contains(field.getName())); + } + } + } + } +} diff --git a/modules/core/src/test/java/org/apache/ignite/internal/metric/SystemViewCacheTest.java b/modules/core/src/test/java/org/apache/ignite/internal/metric/SystemViewCacheTest.java new file mode 100644 index 0000000000000..94028e0996b46 --- /dev/null +++ b/modules/core/src/test/java/org/apache/ignite/internal/metric/SystemViewCacheTest.java @@ -0,0 +1,221 @@ +/* + * 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.metric; + +import java.util.Arrays; +import java.util.HashSet; +import java.util.Set; +import java.util.concurrent.TimeUnit; +import javax.cache.expiry.CreatedExpiryPolicy; +import javax.cache.expiry.Duration; +import javax.cache.expiry.EternalExpiryPolicy; +import javax.cache.expiry.ModifiedExpiryPolicy; +import org.apache.ignite.IgniteCache; +import org.apache.ignite.cluster.ClusterState; +import org.apache.ignite.configuration.CacheConfiguration; +import org.apache.ignite.configuration.DataRegionConfiguration; +import org.apache.ignite.configuration.DataStorageConfiguration; +import org.apache.ignite.internal.IgniteEx; +import org.apache.ignite.internal.util.typedef.F; +import org.apache.ignite.lang.IgnitePredicate; +import org.apache.ignite.spi.systemview.view.CacheGroupIoView; +import org.apache.ignite.spi.systemview.view.CacheGroupView; +import org.apache.ignite.spi.systemview.view.CacheView; +import org.apache.ignite.spi.systemview.view.SystemView; +import org.junit.Test; + +import static org.apache.ignite.internal.processors.cache.ClusterCachesInfo.CACHES_VIEW; +import static org.apache.ignite.internal.processors.cache.ClusterCachesInfo.CACHE_GRPS_VIEW; +import static org.apache.ignite.internal.processors.cache.GridCacheProcessor.CACHE_GRP_IO_VIEW; +import static org.apache.ignite.testframework.GridTestUtils.waitForCondition; + +/** Tests for {@link SystemView} for caches. */ +public class SystemViewCacheTest extends SystemViewAbstractTest { + /** Tests work of {@link SystemView} for caches. */ + @Test + public void testCachesView() throws Exception { + try (IgniteEx g = startGrid()) { + Set cacheNames = new HashSet<>(Arrays.asList("cache-1", "cache-2")); + + for (String name : cacheNames) + g.createCache(name); + + SystemView caches = g.context().systemView().view(CACHES_VIEW); + + assertEquals(g.context().cache().cacheDescriptors().size(), F.size(caches.iterator())); + + for (CacheView row : caches) + cacheNames.remove(row.cacheName()); + + assertTrue(cacheNames.toString(), cacheNames.isEmpty()); + } + } + + /** Tests work of {@link SystemView} for cache groups. */ + @Test + public void testCacheGroupsView() throws Exception { + try (IgniteEx g = startGrid()) { + Set grpNames = new HashSet<>(Arrays.asList("grp-1", "grp-2")); + + for (String grpName : grpNames) + g.createCache(new CacheConfiguration<>("cache-" + grpName).setGroupName(grpName)); + + SystemView grps = g.context().systemView().view(CACHE_GRPS_VIEW); + + assertEquals(g.context().cache().cacheGroupDescriptors().size(), F.size(grps.iterator())); + + for (CacheGroupView row : grps) + grpNames.remove(row.cacheGroupName()); + + assertTrue(grpNames.toString(), grpNames.isEmpty()); + } + } + + /** Tests work of {@link SystemView} for cache expiry policy info with in-memory configuration. */ + @Test + public void testCacheViewExpiryPolicyWithInMemory() throws Exception { + testCacheViewExpiryPolicy(false); + } + + /** Tests work of {@link SystemView} for cache expiry policy info with persist configuration. */ + @Test + public void testCacheViewExpiryPolicyWithPersist() throws Exception { + testCacheViewExpiryPolicy(true); + } + + /** Tests work of {@link SystemView} for cache groups expiry policy info. */ + private void testCacheViewExpiryPolicy(boolean withPersistence) throws Exception { + try (IgniteEx g = !withPersistence ? startGrid() : startGrid(getConfiguration().setDataStorageConfiguration( + new DataStorageConfiguration().setDefaultDataRegionConfiguration( + new DataRegionConfiguration().setPersistenceEnabled(true) + )))) { + + if (withPersistence) + g.cluster().state(ClusterState.ACTIVE); + + String eternalCacheName = "eternalCache"; + String createdCacheName = "createdCache"; + String eagerTtlCacheName = "eagerTtlCache"; + String withoutGrpCacheName = "withoutGrpCache"; + String dfltCacheName = "defaultCache"; + + CacheConfiguration eternalCache = new CacheConfiguration(eternalCacheName) + .setGroupName("group1") + .setExpiryPolicyFactory(EternalExpiryPolicy.factoryOf()); + + CacheConfiguration createdCache = new CacheConfiguration(createdCacheName) + .setGroupName("group2") + .setExpiryPolicyFactory(CreatedExpiryPolicy.factoryOf(new Duration(TimeUnit.MILLISECONDS, 500L))); + + CacheConfiguration eagerTtlCache = new CacheConfiguration(eagerTtlCacheName) + .setGroupName("group2") + .setEagerTtl(false) + .setExpiryPolicyFactory(CreatedExpiryPolicy.factoryOf(new Duration(TimeUnit.MILLISECONDS, 500L))); + + CacheConfiguration withoutGrpCache = new CacheConfiguration(withoutGrpCacheName) + .setExpiryPolicyFactory(CreatedExpiryPolicy.factoryOf(new Duration(TimeUnit.MILLISECONDS, 500L))); + + CacheConfiguration dfltCache = new CacheConfiguration(dfltCacheName) + .setGroupName("group3"); + + g.createCache(eternalCache); + g.createCache(createdCache); + g.createCache(eagerTtlCache); + g.createCache(withoutGrpCache); + g.createCache(dfltCache); + + SystemView caches = g.context().systemView().view(CACHES_VIEW); + + for (CacheView row : caches) { + switch (row.cacheName()) { + case "defaultCache": + case "eternalCache": + assertEquals("No", row.hasExpiringEntries()); + + g.cache(row.cacheName()).put(0, 0); + + assertEquals("No", row.hasExpiringEntries()); + + g.cache(row.cacheName()) + .withExpiryPolicy(new CreatedExpiryPolicy(new Duration(TimeUnit.MILLISECONDS, 200L))) + .put(1, 1); + + assertEquals("Yes", row.hasExpiringEntries()); + assertTrue(waitForCondition(() -> "No".equals(row.hasExpiringEntries()), getTestTimeout())); + + break; + + case "withoutGrpCache": + case "createdCache": + assertEquals("No", row.hasExpiringEntries()); + + g.cache(row.cacheName()).put(0, 0); + + assertEquals("Yes", row.hasExpiringEntries()); + assertTrue(waitForCondition(() -> "No".equals(row.hasExpiringEntries()), getTestTimeout())); + + g.cache(row.cacheName()) + .withExpiryPolicy(new ModifiedExpiryPolicy(new Duration(TimeUnit.MILLISECONDS, 200L))) + .put(1, 1); + + assertEquals("Yes", row.hasExpiringEntries()); + assertTrue(waitForCondition(() -> "No".equals(row.hasExpiringEntries()), getTestTimeout())); + + if (row.cacheName().equals(createdCacheName)) { + g.cache(eagerTtlCacheName).put(2, 2); + assertEquals("No", row.hasExpiringEntries()); + } + + break; + + case "eagerTtlCache": + assertEquals("Unknown", row.hasExpiringEntries()); + + break; + } + } + } + } + + /** Tests work of {@link SystemView} for cache group I/O operations. */ + @Test + public void testCacheGroupIo() throws Exception { + cleanPersistenceDir(); + + try (IgniteEx ignite = startGrid(getConfiguration().setDataStorageConfiguration( + new DataStorageConfiguration().setDefaultDataRegionConfiguration( + new DataRegionConfiguration().setPersistenceEnabled(true)))) + ) { + ignite.cluster().state(ClusterState.ACTIVE); + + IgniteCache cache = ignite.createCache("cache"); + + cache.put(0, 0); + cache.get(0); + + SystemView view = ignite.context().systemView().view(CACHE_GRP_IO_VIEW); + + CacheGroupIoView row = F.find(view, null, + (IgnitePredicate)r -> "cache".equals(r.cacheGroupName())); + + assertNotNull(row); + assertTrue(row.logicalReads() > 0); + assertTrue(row.insertedBytes() > 0); + } + } +} diff --git a/modules/core/src/test/java/org/apache/ignite/internal/metric/SystemViewClientTest.java b/modules/core/src/test/java/org/apache/ignite/internal/metric/SystemViewClientTest.java new file mode 100644 index 0000000000000..f1448d74f770e --- /dev/null +++ b/modules/core/src/test/java/org/apache/ignite/internal/metric/SystemViewClientTest.java @@ -0,0 +1,138 @@ +/* + * 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.metric; + +import java.sql.Connection; +import java.util.Iterator; +import java.util.Properties; +import org.apache.ignite.IgniteJdbcThinDriver; +import org.apache.ignite.Ignition; +import org.apache.ignite.client.Config; +import org.apache.ignite.client.IgniteClient; +import org.apache.ignite.configuration.ClientConfiguration; +import org.apache.ignite.internal.IgniteEx; +import org.apache.ignite.internal.client.thin.ProtocolVersion; +import org.apache.ignite.internal.processors.odbc.jdbc.JdbcConnectionContext; +import org.apache.ignite.internal.systemview.ClientConnectionAttributeViewWalker; +import org.apache.ignite.internal.util.typedef.F; +import org.apache.ignite.spi.systemview.view.ClientConnectionAttributeView; +import org.apache.ignite.spi.systemview.view.ClientConnectionView; +import org.apache.ignite.spi.systemview.view.FiltrableSystemView; +import org.apache.ignite.spi.systemview.view.SystemView; +import org.apache.ignite.testframework.GridTestUtils; +import org.junit.Test; + +import static org.apache.ignite.internal.processors.odbc.ClientListenerProcessor.CLI_CONN_ATTR_VIEW; +import static org.apache.ignite.internal.processors.odbc.ClientListenerProcessor.CLI_CONN_VIEW; +import static org.apache.ignite.internal.util.lang.GridFunc.identity; + +/** Tests for {@link SystemView} for clients. */ +public class SystemViewClientTest extends SystemViewAbstractTest { + /** */ + @Test + public void testClientsConnections() throws Exception { + try (IgniteEx g0 = startGrid(0)) { + String host = g0.configuration().getClientConnectorConfiguration().getHost(); + + if (host == null) + host = g0.configuration().getLocalHost(); + + int port = g0.configuration().getClientConnectorConfiguration().getPort(); + + SystemView conns = g0.context().systemView().view(CLI_CONN_VIEW); + + try (IgniteClient cli = Ignition.startClient(new ClientConfiguration().setAddresses(host + ":" + port))) { + assertEquals(1, conns.size()); + + ClientConnectionView cliConn = conns.iterator().next(); + + assertEquals("THIN", cliConn.type()); + assertEquals(cliConn.localAddress().getHostName(), cliConn.remoteAddress().getHostName()); + assertEquals(g0.configuration().getClientConnectorConfiguration().getPort(), + cliConn.localAddress().getPort()); + assertEquals(cliConn.version(), ProtocolVersion.LATEST_VER.toString()); + + try (Connection conn = + new IgniteJdbcThinDriver().connect("jdbc:ignite:thin://" + host, new Properties())) { + assertEquals(2, conns.size()); + assertEquals(1, F.size(jdbcConnectionsIterator(conns))); + + ClientConnectionView jdbcConn = jdbcConnectionsIterator(conns).next(); + + assertEquals("JDBC", jdbcConn.type()); + assertEquals(jdbcConn.localAddress().getHostName(), jdbcConn.remoteAddress().getHostName()); + assertEquals(g0.configuration().getClientConnectorConfiguration().getPort(), + jdbcConn.localAddress().getPort()); + assertEquals(jdbcConn.version(), JdbcConnectionContext.CURRENT_VER.asString()); + } + } + + boolean res = GridTestUtils.waitForCondition(() -> conns.size() == 0, 5_000); + + assertTrue(res); + } + } + + /** */ + @Test + public void testClientConnectionAttributes() throws Exception { + try (IgniteEx g0 = startGrid(0)) { + SystemView view = g0.context().systemView().view(CLI_CONN_ATTR_VIEW); + + try ( + IgniteClient cl1 = Ignition.startClient(new ClientConfiguration().setAddresses(Config.SERVER) + .setUserAttributes(F.asMap("attr1", "val1", "attr2", "val2"))); + IgniteClient cl2 = Ignition.startClient(new ClientConfiguration().setAddresses(Config.SERVER) + .setUserAttributes(F.asMap("attr1", "val2"))); + IgniteClient cl3 = Ignition.startClient(new ClientConfiguration().setAddresses(Config.SERVER)) + ) { + assertEquals(3, F.size(view.iterator())); + + assertEquals(1, F.size(view.iterator(), row -> + "attr1".equals(row.name()) && "val1".equals(row.value()))); + + // Test filtering. + assertTrue(view instanceof FiltrableSystemView); + + Iterator iter = ((FiltrableSystemView)view) + .iterator(F.asMap(ClientConnectionAttributeViewWalker.NAME_FILTER, "attr1")); + + assertEquals(2, F.size(iter)); + + iter = ((FiltrableSystemView)view).iterator( + F.asMap(ClientConnectionAttributeViewWalker.NAME_FILTER, "attr2")); + + assertTrue(iter.hasNext()); + + long connId = iter.next().connectionId(); + + assertFalse(iter.hasNext()); + + iter = ((FiltrableSystemView)view).iterator( + F.asMap(ClientConnectionAttributeViewWalker.CONNECTION_ID_FILTER, connId)); + + assertEquals(2, F.size(iter)); + } + } + } + + /** */ + private Iterator jdbcConnectionsIterator(SystemView conns) { + return F.iterator(conns.iterator(), identity(), true, v -> "JDBC".equals(v.type())); + } +} diff --git a/modules/core/src/test/java/org/apache/ignite/internal/metric/SystemViewComputeTaskTest.java b/modules/core/src/test/java/org/apache/ignite/internal/metric/SystemViewComputeTaskTest.java new file mode 100644 index 0000000000000..e7f388d5f9104 --- /dev/null +++ b/modules/core/src/test/java/org/apache/ignite/internal/metric/SystemViewComputeTaskTest.java @@ -0,0 +1,349 @@ +/* + * 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.metric; + +import java.util.List; +import java.util.Map; +import java.util.concurrent.BrokenBarrierException; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.CyclicBarrier; +import java.util.concurrent.TimeUnit; +import java.util.function.Function; +import java.util.stream.Collectors; +import org.apache.ignite.IgniteCache; +import org.apache.ignite.IgniteCompute; +import org.apache.ignite.IgniteException; +import org.apache.ignite.cluster.ClusterNode; +import org.apache.ignite.compute.ComputeJob; +import org.apache.ignite.compute.ComputeJobResult; +import org.apache.ignite.compute.ComputeJobResultPolicy; +import org.apache.ignite.compute.ComputeTask; +import org.apache.ignite.internal.IgniteEx; +import org.apache.ignite.internal.IgniteInternalFuture; +import org.apache.ignite.internal.processors.task.GridInternal; +import org.apache.ignite.lang.IgniteCallable; +import org.apache.ignite.lang.IgniteClosure; +import org.apache.ignite.lang.IgniteRunnable; +import org.apache.ignite.lang.IgniteUuid; +import org.apache.ignite.spi.systemview.view.ComputeJobView; +import org.apache.ignite.spi.systemview.view.ComputeTaskView; +import org.apache.ignite.spi.systemview.view.SystemView; +import org.apache.ignite.testframework.GridTestUtils; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.junit.Test; + +import static org.apache.ignite.internal.processors.job.GridJobProcessor.JOBS_VIEW; +import static org.apache.ignite.internal.processors.task.GridTaskProcessor.TASKS_VIEW; +import static org.apache.ignite.testframework.GridTestUtils.runAsync; + +/** Tests for {@link SystemView} for compute tasks. */ +public class SystemViewComputeTaskTest extends SystemViewAbstractTest { + /** */ + private static CountDownLatch jobStartedLatch; + + /** */ + private static CountDownLatch releaseJobLatch; + + /** Tests work of {@link SystemView} for compute grid {@link IgniteCompute#broadcastAsync(IgniteRunnable)} call. */ + @Test + public void testComputeBroadcast() throws Exception { + CyclicBarrier barrier = new CyclicBarrier(6); + + try (IgniteEx g1 = startGrid(0)) { + SystemView tasks = g1.context().systemView().view(TASKS_VIEW); + + for (int i = 0; i < 5; i++) { + g1.compute().broadcastAsync(() -> { + try { + barrier.await(); + barrier.await(); + } + catch (InterruptedException | BrokenBarrierException e) { + throw new RuntimeException(e); + } + }); + } + + barrier.await(); + + assertEquals(5, tasks.size()); + + ComputeTaskView t = tasks.iterator().next(); + + assertFalse(t.internal()); + assertNull(t.affinityCacheName()); + assertEquals(-1, t.affinityPartitionId()); + assertTrue(t.taskClassName().startsWith(getClass().getName())); + assertTrue(t.taskName().startsWith(getClass().getName())); + assertEquals(g1.localNode().id(), t.taskNodeId()); + assertEquals("0", t.userVersion()); + + barrier.await(); + } + } + + /** Tests work of {@link SystemView} for compute grid {@link IgniteCompute#runAsync(IgniteRunnable)} call. */ + @Test + public void testComputeRunnable() throws Exception { + CyclicBarrier barrier = new CyclicBarrier(2); + + try (IgniteEx g1 = startGrid(0)) { + SystemView tasks = g1.context().systemView().view(TASKS_VIEW); + + g1.compute().runAsync(() -> { + try { + barrier.await(); + barrier.await(); + } + catch (InterruptedException | BrokenBarrierException e) { + throw new RuntimeException(e); + } + }); + + barrier.await(); + + assertEquals(1, tasks.size()); + + ComputeTaskView t = tasks.iterator().next(); + + assertFalse(t.internal()); + assertNull(t.affinityCacheName()); + assertEquals(-1, t.affinityPartitionId()); + assertTrue(t.taskClassName().startsWith(getClass().getName())); + assertTrue(t.taskName().startsWith(getClass().getName())); + assertEquals(g1.localNode().id(), t.taskNodeId()); + assertEquals("0", t.userVersion()); + + barrier.await(); + } + } + + /** Tests work of {@link SystemView} for compute grid {@link IgniteCompute#apply(IgniteClosure, Object)} call. */ + @Test + public void testComputeApply() throws Exception { + CyclicBarrier barrier = new CyclicBarrier(2); + + try (IgniteEx g1 = startGrid(0)) { + SystemView tasks = g1.context().systemView().view(TASKS_VIEW); + + GridTestUtils.runAsync(() -> { + g1.compute().apply(x -> { + try { + barrier.await(); + barrier.await(); + } + catch (InterruptedException | BrokenBarrierException e) { + throw new RuntimeException(e); + } + + return 0; + }, 1); + }); + + barrier.await(); + + assertEquals(1, tasks.size()); + + ComputeTaskView t = tasks.iterator().next(); + + assertFalse(t.internal()); + assertNull(t.affinityCacheName()); + assertEquals(-1, t.affinityPartitionId()); + assertTrue(t.taskClassName().startsWith(getClass().getName())); + assertTrue(t.taskName().startsWith(getClass().getName())); + assertEquals(g1.localNode().id(), t.taskNodeId()); + assertEquals("0", t.userVersion()); + + barrier.await(); + } + } + + /** + * Tests work of {@link SystemView} for compute grid + * {@link IgniteCompute#affinityCallAsync(String, Object, IgniteCallable)} call. + */ + @Test + public void testComputeAffinityCall() throws Exception { + CyclicBarrier barrier = new CyclicBarrier(2); + + try (IgniteEx g1 = startGrid(0)) { + SystemView tasks = g1.context().systemView().view(TASKS_VIEW); + + IgniteCache cache = g1.createCache("test-cache"); + + cache.put(1, 1); + + g1.compute().affinityCallAsync("test-cache", 1, () -> { + try { + barrier.await(); + barrier.await(); + } + catch (InterruptedException e) { + throw new RuntimeException(e); + } + + return 0; + }); + + barrier.await(); + + assertEquals(1, tasks.size()); + + ComputeTaskView t = tasks.iterator().next(); + + assertFalse(t.internal()); + assertEquals("test-cache", t.affinityCacheName()); + assertEquals(1, t.affinityPartitionId()); + assertTrue(t.taskClassName().startsWith(getClass().getName())); + assertTrue(t.taskName().startsWith(getClass().getName())); + assertEquals(g1.localNode().id(), t.taskNodeId()); + assertEquals("0", t.userVersion()); + + barrier.await(); + } + } + + /** */ + @Test + public void testComputeTask() throws Exception { + doTestComputeTask(false); + } + + /** */ + @Test + public void testInternalComputeTask() throws Exception { + doTestComputeTask(true); + } + + /** */ + private void doTestComputeTask(boolean internal) throws Exception { + int gridCnt = 3; + + IgniteEx g1 = startGrids(gridCnt); + + try { + IgniteCache cache = g1.createCache("test-cache"); + + cache.put(1, 1); + + for (int i = 0; i < gridCnt; i++) { + IgniteEx grid = grid(i); + + SystemView tasks = grid.context().systemView().view(TASKS_VIEW); + + jobStartedLatch = new CountDownLatch(3); + releaseJobLatch = new CountDownLatch(1); + + IgniteInternalFuture fut + = runAsync(() -> grid.compute().execute(internal ? new InternalTask() : new UserTask(), 1)); + + assertTrue(jobStartedLatch.await(30_000, TimeUnit.MILLISECONDS)); + + try { + assertEquals(1, tasks.size()); + + ComputeTaskView t = tasks.iterator().next(); + + assertEquals("Expecting to see " + (internal ? "internal" : "user") + " task", internal, t.internal()); + assertNull(t.affinityCacheName()); + assertEquals(-1, t.affinityPartitionId()); + assertTrue(t.taskClassName().startsWith(getClass().getName())); + assertTrue(t.taskName().startsWith(getClass().getName())); + assertEquals(grid.localNode().id(), t.taskNodeId()); + assertEquals("0", t.userVersion()); + + checkJobs(gridCnt, internal, t.sessionId()); + } + finally { + releaseJobLatch.countDown(); + } + + fut.get(getTestTimeout(), TimeUnit.MILLISECONDS); + } + } + finally { + stopAllGrids(); + } + } + + /** */ + private void checkJobs(int gridCnt, boolean internal, IgniteUuid sesId) { + for (int i = 0; i < gridCnt; i++) { + SystemView jobs = grid(i).context().systemView().view(JOBS_VIEW); + + assertTrue("Expecting to see " + (internal ? "internal" : "user") + " job", jobs.size() > 0); + + ComputeJobView job = jobs.iterator().next(); + + assertEquals(sesId, job.sessionId()); + assertEquals("Expecting to see " + (internal ? "internal" : "user") + " job", internal, job.isInternal()); + } + + releaseJobLatch.countDown(); + } + + /** */ + private static class UserTask implements ComputeTask { + /** {@inheritDoc} */ + @Override public @NotNull Map map( + List subgrid, + @Nullable Object arg + ) throws IgniteException { + return subgrid.stream().collect(Collectors.toMap(k -> new UserJob(), Function.identity())); + } + + /** {@inheritDoc} */ + @Override public ComputeJobResultPolicy result(ComputeJobResult res, List rcvd) throws IgniteException { + return ComputeJobResultPolicy.WAIT; + } + + /** {@inheritDoc} */ + @Nullable @Override public Object reduce(List results) throws IgniteException { + return 1; + } + + /** */ + private static class UserJob implements ComputeJob { + /** {@inheritDoc} */ + @Override public void cancel() { + // No-op. + } + + /** {@inheritDoc} */ + @Override public Object execute() throws IgniteException { + jobStartedLatch.countDown(); + + try { + assertTrue(releaseJobLatch.await(30_000, TimeUnit.MILLISECONDS)); + } + catch (InterruptedException e) { + throw new RuntimeException(e); + } + + return 1; + } + } + } + + /** */ + @GridInternal + public static class InternalTask extends UserTask { + // No-op. + } +} diff --git a/modules/core/src/test/java/org/apache/ignite/internal/metric/SystemViewConfigurationTest.java b/modules/core/src/test/java/org/apache/ignite/internal/metric/SystemViewConfigurationTest.java new file mode 100644 index 0000000000000..35574e996aa46 --- /dev/null +++ b/modules/core/src/test/java/org/apache/ignite/internal/metric/SystemViewConfigurationTest.java @@ -0,0 +1,82 @@ +/* + * 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.metric; + +import java.util.HashMap; +import java.util.Map; +import org.apache.ignite.cache.CacheAtomicityMode; +import org.apache.ignite.configuration.DataRegionConfiguration; +import org.apache.ignite.configuration.DataStorageConfiguration; +import org.apache.ignite.configuration.IgniteConfiguration; +import org.apache.ignite.internal.IgniteEx; +import org.apache.ignite.spi.systemview.view.ConfigurationView; +import org.apache.ignite.spi.systemview.view.SystemView; +import org.junit.Test; + +import static org.apache.ignite.events.EventType.EVT_CONSISTENCY_VIOLATION; +import static org.apache.ignite.internal.IgniteKernal.CFG_VIEW; +import static org.apache.ignite.internal.util.IgniteUtils.MB; + +/** Tests for {@link SystemView} for configuration. */ +public class SystemViewConfigurationTest extends SystemViewAbstractTest { + /** */ + @Test + public void testConfigurationView() throws Exception { + long expMaxSize = 10 * MB; + + String expName = "my-instance"; + + String expDrName = "my-dr"; + + IgniteConfiguration icfg = getConfiguration(expName) + .setIncludeEventTypes(EVT_CONSISTENCY_VIOLATION) + .setDataStorageConfiguration(new DataStorageConfiguration() + .setDefaultDataRegionConfiguration( + new DataRegionConfiguration() + .setLazyMemoryAllocation(false)) + .setDataRegionConfigurations( + new DataRegionConfiguration() + .setName(expDrName) + .setMaxSize(expMaxSize))); + + try (IgniteEx ignite = startGrid(icfg)) { + Map viewContent = new HashMap<>(); + + ignite.context().systemView().view(CFG_VIEW) + .forEach(view -> viewContent.put(view.name(), view.value())); + + assertEquals(expName, viewContent.get("IgniteInstanceName")); + assertEquals( + "false", + viewContent.get("DataStorageConfiguration.DefaultDataRegionConfiguration.LazyMemoryAllocation") + ); + assertEquals(expDrName, viewContent.get("DataStorageConfiguration.DataRegionConfigurations[0].Name")); + assertEquals( + Long.toString(expMaxSize), + viewContent.get("DataStorageConfiguration.DataRegionConfigurations[0].MaxSize") + ); + assertEquals( + CacheAtomicityMode.TRANSACTIONAL.name(), + viewContent.get("CacheConfiguration[0].AtomicityMode") + ); + assertTrue(viewContent.containsKey("AddressResolver")); + assertNull(viewContent.get("AddressResolver")); + assertEquals("[" + EVT_CONSISTENCY_VIOLATION + ']', viewContent.get("IncludeEventTypes")); + } + } +} diff --git a/modules/core/src/test/java/org/apache/ignite/internal/metric/SystemViewDSTest.java b/modules/core/src/test/java/org/apache/ignite/internal/metric/SystemViewDSTest.java new file mode 100644 index 0000000000000..05abbf428576b --- /dev/null +++ b/modules/core/src/test/java/org/apache/ignite/internal/metric/SystemViewDSTest.java @@ -0,0 +1,704 @@ +/* + * 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.metric; + +import org.apache.ignite.IgniteAtomicLong; +import org.apache.ignite.IgniteAtomicReference; +import org.apache.ignite.IgniteAtomicSequence; +import org.apache.ignite.IgniteAtomicStamped; +import org.apache.ignite.IgniteCountDownLatch; +import org.apache.ignite.IgniteLock; +import org.apache.ignite.IgniteQueue; +import org.apache.ignite.IgniteSemaphore; +import org.apache.ignite.IgniteSet; +import org.apache.ignite.configuration.AtomicConfiguration; +import org.apache.ignite.configuration.CollectionConfiguration; +import org.apache.ignite.internal.IgniteEx; +import org.apache.ignite.internal.IgniteInternalFuture; +import org.apache.ignite.internal.util.typedef.internal.CU; +import org.apache.ignite.spi.systemview.view.SystemView; +import org.apache.ignite.spi.systemview.view.datastructures.AtomicLongView; +import org.apache.ignite.spi.systemview.view.datastructures.AtomicReferenceView; +import org.apache.ignite.spi.systemview.view.datastructures.AtomicSequenceView; +import org.apache.ignite.spi.systemview.view.datastructures.AtomicStampedView; +import org.apache.ignite.spi.systemview.view.datastructures.CountDownLatchView; +import org.apache.ignite.spi.systemview.view.datastructures.QueueView; +import org.apache.ignite.spi.systemview.view.datastructures.ReentrantLockView; +import org.apache.ignite.spi.systemview.view.datastructures.SemaphoreView; +import org.apache.ignite.spi.systemview.view.datastructures.SetView; +import org.junit.Test; + +import static org.apache.ignite.configuration.AtomicConfiguration.DFLT_ATOMIC_SEQUENCE_RESERVE_SIZE; +import static org.apache.ignite.internal.processors.datastructures.DataStructuresProcessor.DEFAULT_DS_GROUP_NAME; +import static org.apache.ignite.internal.processors.datastructures.DataStructuresProcessor.DEFAULT_VOLATILE_DS_GROUP_NAME; +import static org.apache.ignite.internal.processors.datastructures.DataStructuresProcessor.LATCHES_VIEW; +import static org.apache.ignite.internal.processors.datastructures.DataStructuresProcessor.LOCKS_VIEW; +import static org.apache.ignite.internal.processors.datastructures.DataStructuresProcessor.LONGS_VIEW; +import static org.apache.ignite.internal.processors.datastructures.DataStructuresProcessor.QUEUES_VIEW; +import static org.apache.ignite.internal.processors.datastructures.DataStructuresProcessor.REFERENCES_VIEW; +import static org.apache.ignite.internal.processors.datastructures.DataStructuresProcessor.SEMAPHORES_VIEW; +import static org.apache.ignite.internal.processors.datastructures.DataStructuresProcessor.SEQUENCES_VIEW; +import static org.apache.ignite.internal.processors.datastructures.DataStructuresProcessor.SETS_VIEW; +import static org.apache.ignite.internal.processors.datastructures.DataStructuresProcessor.STAMPED_VIEW; +import static org.apache.ignite.internal.processors.datastructures.DataStructuresProcessor.VOLATILE_DATA_REGION_NAME; +import static org.apache.ignite.testframework.GridTestUtils.runAsync; +import static org.apache.ignite.testframework.GridTestUtils.waitForCondition; + +/** Tests for {@link SystemView} for data structures. */ +public class SystemViewDSTest extends SystemViewAbstractTest { + /** */ + @Test + public void testAtomicSequence() throws Exception { + try (IgniteEx g0 = startGrid(0); + IgniteEx g1 = startGrid(1)) { + IgniteAtomicSequence s1 = g0.atomicSequence("seq-1", 42, true); + IgniteAtomicSequence s2 = g0.atomicSequence("seq-2", + new AtomicConfiguration().setBackups(1).setGroupName("my-group"), 43, true); + + s1.batchSize(42); + + SystemView seqs0 = g0.context().systemView().view(SEQUENCES_VIEW); + SystemView seqs1 = g1.context().systemView().view(SEQUENCES_VIEW); + + assertEquals(2, seqs0.size()); + assertEquals(0, seqs1.size()); + + for (AtomicSequenceView s : seqs0) { + if ("seq-1".equals(s.name())) { + assertEquals(42, s.value()); + assertEquals(42, s.batchSize()); + assertEquals(DEFAULT_DS_GROUP_NAME, s.groupName()); + assertEquals(CU.cacheId(DEFAULT_DS_GROUP_NAME), s.groupId()); + + long val = s1.addAndGet(42); + + assertEquals(val, s.value()); + assertFalse(s.removed()); + } + else { + assertEquals("seq-2", s.name()); + assertEquals(DFLT_ATOMIC_SEQUENCE_RESERVE_SIZE, s.batchSize()); + assertEquals(43, s.value()); + assertEquals("my-group", s.groupName()); + assertEquals(CU.cacheId("my-group"), s.groupId()); + assertFalse(s.removed()); + + s2.close(); + + assertTrue(waitForCondition(s::removed, getTestTimeout())); + } + } + + g1.atomicSequence("seq-1", 42, true); + + assertEquals(1, seqs1.size()); + + AtomicSequenceView s = seqs1.iterator().next(); + + assertEquals(DFLT_ATOMIC_SEQUENCE_RESERVE_SIZE + 42, s.value()); + assertEquals(DFLT_ATOMIC_SEQUENCE_RESERVE_SIZE, s.batchSize()); + assertEquals(DEFAULT_DS_GROUP_NAME, s.groupName()); + assertEquals(CU.cacheId(DEFAULT_DS_GROUP_NAME), s.groupId()); + assertFalse(s.removed()); + + s1.close(); + + assertTrue(waitForCondition(s::removed, getTestTimeout())); + + assertEquals(0, seqs0.size()); + assertEquals(0, seqs1.size()); + } + } + + /** */ + @Test + public void testAtomicLongs() throws Exception { + try (IgniteEx g0 = startGrid(0); + IgniteEx g1 = startGrid(1)) { + IgniteAtomicLong l1 = g0.atomicLong("long-1", 42, true); + IgniteAtomicLong l2 = g0.atomicLong("long-2", + new AtomicConfiguration().setBackups(1).setGroupName("my-group"), 43, true); + + SystemView longs0 = g0.context().systemView().view(LONGS_VIEW); + SystemView longs1 = g1.context().systemView().view(LONGS_VIEW); + + assertEquals(2, longs0.size()); + assertEquals(0, longs1.size()); + + for (AtomicLongView l : longs0) { + if ("long-1".equals(l.name())) { + assertEquals(42, l.value()); + assertEquals(DEFAULT_DS_GROUP_NAME, l.groupName()); + assertEquals(CU.cacheId(DEFAULT_DS_GROUP_NAME), l.groupId()); + + long val = l1.addAndGet(42); + + assertEquals(val, l.value()); + assertFalse(l.removed()); + } + else { + assertEquals("long-2", l.name()); + assertEquals(43, l.value()); + assertEquals("my-group", l.groupName()); + assertEquals(CU.cacheId("my-group"), l.groupId()); + assertFalse(l.removed()); + + l2.close(); + + assertTrue(waitForCondition(l::removed, getTestTimeout())); + } + } + + g1.atomicLong("long-1", 42, true); + + assertEquals(1, longs1.size()); + + AtomicLongView l = longs1.iterator().next(); + + assertEquals(84, l.value()); + assertEquals(DEFAULT_DS_GROUP_NAME, l.groupName()); + assertEquals(CU.cacheId(DEFAULT_DS_GROUP_NAME), l.groupId()); + assertFalse(l.removed()); + + l1.close(); + + assertTrue(waitForCondition(l::removed, getTestTimeout())); + + assertEquals(0, longs0.size()); + assertEquals(0, longs1.size()); + } + } + + /** */ + @Test + public void testAtomicReference() throws Exception { + try (IgniteEx g0 = startGrid(0); + IgniteEx g1 = startGrid(1)) { + IgniteAtomicReference l1 = g0.atomicReference("ref-1", "str1", true); + IgniteAtomicReference l2 = g0.atomicReference("ref-2", + new AtomicConfiguration().setBackups(1).setGroupName("my-group"), 43, true); + + SystemView refs0 = g0.context().systemView().view(REFERENCES_VIEW); + SystemView refs1 = g1.context().systemView().view(REFERENCES_VIEW); + + assertEquals(2, refs0.size()); + assertEquals(0, refs1.size()); + + for (AtomicReferenceView r : refs0) { + if ("ref-1".equals(r.name())) { + assertEquals("str1", r.value()); + assertEquals(DEFAULT_DS_GROUP_NAME, r.groupName()); + assertEquals(CU.cacheId(DEFAULT_DS_GROUP_NAME), r.groupId()); + + l1.set("str2"); + + assertEquals("str2", r.value()); + assertFalse(r.removed()); + } + else { + assertEquals("ref-2", r.name()); + assertEquals("43", r.value()); + assertEquals("my-group", r.groupName()); + assertEquals(CU.cacheId("my-group"), r.groupId()); + assertFalse(r.removed()); + + l2.close(); + + assertTrue(waitForCondition(r::removed, getTestTimeout())); + } + } + + g1.atomicReference("ref-1", "str3", true); + + assertEquals(1, refs1.size()); + + AtomicReferenceView l = refs1.iterator().next(); + + assertEquals("str2", l.value()); + assertEquals(DEFAULT_DS_GROUP_NAME, l.groupName()); + assertEquals(CU.cacheId(DEFAULT_DS_GROUP_NAME), l.groupId()); + assertFalse(l.removed()); + + l1.close(); + + assertTrue(waitForCondition(l::removed, getTestTimeout())); + + assertEquals(0, refs0.size()); + assertEquals(0, refs1.size()); + } + } + + /** */ + @Test + public void testAtomicStamped() throws Exception { + try (IgniteEx g0 = startGrid(0); + IgniteEx g1 = startGrid(1)) { + IgniteAtomicStamped s1 = g0.atomicStamped("s-1", "str0", 1, true); + IgniteAtomicStamped s2 = g0.atomicStamped("s-2", + new AtomicConfiguration().setBackups(1).setGroupName("my-group"), "str1", 43, true); + + SystemView stamps0 = g0.context().systemView().view(STAMPED_VIEW); + SystemView stamps1 = g1.context().systemView().view(STAMPED_VIEW); + + assertEquals(2, stamps0.size()); + assertEquals(0, stamps1.size()); + + for (AtomicStampedView s : stamps0) { + if ("s-1".equals(s.name())) { + assertEquals("str0", s.value()); + assertEquals("1", s.stamp()); + assertEquals(DEFAULT_DS_GROUP_NAME, s.groupName()); + assertEquals(CU.cacheId(DEFAULT_DS_GROUP_NAME), s.groupId()); + + s1.set("str2", 2); + + assertEquals("str2", s.value()); + assertEquals("2", s.stamp()); + assertFalse(s.removed()); + } + else { + assertEquals("s-2", s.name()); + assertEquals("str1", s.value()); + assertEquals("43", s.stamp()); + assertEquals("my-group", s.groupName()); + assertEquals(CU.cacheId("my-group"), s.groupId()); + assertFalse(s.removed()); + + s2.close(); + + assertTrue(waitForCondition(s::removed, getTestTimeout())); + } + } + + g1.atomicStamped("s-1", "str3", 3, true); + + assertEquals(1, stamps1.size()); + + AtomicStampedView l = stamps1.iterator().next(); + + assertEquals("str2", l.value()); + assertEquals("2", l.stamp()); + assertEquals(DEFAULT_DS_GROUP_NAME, l.groupName()); + assertEquals(CU.cacheId(DEFAULT_DS_GROUP_NAME), l.groupId()); + assertFalse(l.removed()); + + s1.close(); + + assertTrue(l.removed()); + + assertEquals(0, stamps0.size()); + assertEquals(0, stamps1.size()); + } + } + + /** */ + @Test + public void testCountDownLatch() throws Exception { + try (IgniteEx g0 = startGrid(0); + IgniteEx g1 = startGrid(1)) { + IgniteCountDownLatch l1 = g0.countDownLatch("c1", 3, false, true); + IgniteCountDownLatch l2 = g0.countDownLatch("c2", 1, true, true); + + SystemView latches0 = g0.context().systemView().view(LATCHES_VIEW); + SystemView latches1 = g1.context().systemView().view(LATCHES_VIEW); + + assertEquals(2, latches0.size()); + assertEquals(0, latches1.size()); + + String grpName = DEFAULT_VOLATILE_DS_GROUP_NAME + "@" + VOLATILE_DATA_REGION_NAME; + + for (CountDownLatchView l : latches0) { + if ("c1".equals(l.name())) { + assertEquals(3, l.count()); + assertEquals(3, l.initialCount()); + assertFalse(l.autoDelete()); + + l1.countDown(); + + assertEquals(2, l.count()); + assertEquals(3, l.initialCount()); + assertFalse(l.removed()); + } + else { + assertEquals("c2", l.name()); + assertEquals(1, l.count()); + assertEquals(1, l.initialCount()); + assertTrue(l.autoDelete()); + assertFalse(l.removed()); + + l2.countDown(); + l2.close(); + + assertTrue(waitForCondition(l::removed, getTestTimeout())); + } + + assertEquals(grpName, l.groupName()); + assertEquals(CU.cacheId(grpName), l.groupId()); + } + + IgniteCountDownLatch l3 = g1.countDownLatch("c1", 10, true, true); + + assertEquals(1, latches1.size()); + + CountDownLatchView l = latches1.iterator().next(); + + assertEquals(2, l.count()); + assertEquals(3, l.initialCount()); + assertEquals(grpName, l.groupName()); + assertEquals(CU.cacheId(grpName), l.groupId()); + assertFalse(l.removed()); + assertFalse(l.autoDelete()); + + l3.countDown(); + l3.countDown(); + l3.close(); + + assertTrue(waitForCondition(l::removed, getTestTimeout())); + + assertEquals(0, latches0.size()); + assertEquals(0, latches1.size()); + } + } + + /** */ + @Test + public void testSemaphores() throws Exception { + try (IgniteEx g0 = startGrid(0); + IgniteEx g1 = startGrid(1)) { + IgniteSemaphore s1 = g0.semaphore("s1", 3, false, true); + IgniteSemaphore s2 = g0.semaphore("s2", 1, true, true); + + SystemView semaphores0 = g0.context().systemView().view(SEMAPHORES_VIEW); + SystemView semaphores1 = g1.context().systemView().view(SEMAPHORES_VIEW); + + assertEquals(2, semaphores0.size()); + assertEquals(0, semaphores1.size()); + + String grpName = DEFAULT_VOLATILE_DS_GROUP_NAME + "@" + VOLATILE_DATA_REGION_NAME; + + IgniteInternalFuture acquirePermitFut = null; + + for (SemaphoreView s : semaphores0) { + if ("s1".equals(s.name())) { + assertEquals(3, s.availablePermits()); + assertFalse(s.hasQueuedThreads()); + assertEquals(0, s.queueLength()); + assertFalse(s.failoverSafe()); + assertFalse(s.broken()); + assertFalse(s.removed()); + + acquirePermitFut = runAsync(() -> { + s1.acquire(2); + + try { + Thread.sleep(getTestTimeout()); + } + catch (InterruptedException e) { + throw new RuntimeException(e); + } + finally { + s1.release(2); + } + }); + + assertTrue(waitForCondition(() -> s.availablePermits() == 1, getTestTimeout())); + assertTrue(s.hasQueuedThreads()); + assertEquals(1, s.queueLength()); + } + else { + assertEquals(1, s.availablePermits()); + assertFalse(s.hasQueuedThreads()); + assertEquals(0, s.queueLength()); + assertTrue(s.failoverSafe()); + assertFalse(s.broken()); + assertFalse(s.removed()); + + s2.close(); + + assertTrue(waitForCondition(s::removed, getTestTimeout())); + } + + assertEquals(grpName, s.groupName()); + assertEquals(CU.cacheId(grpName), s.groupId()); + } + + IgniteSemaphore l3 = g1.semaphore("s1", 10, true, true); + + assertEquals(1, semaphores1.size()); + + SemaphoreView s = semaphores1.iterator().next(); + + assertEquals(1, s.availablePermits()); + assertTrue(s.hasQueuedThreads()); + assertEquals(1, s.queueLength()); + assertFalse(s.failoverSafe()); + assertFalse(s.broken()); + assertFalse(s.removed()); + + acquirePermitFut.cancel(); + assertTrue(waitForCondition(() -> s.availablePermits() == 3, getTestTimeout())); + + l3.close(); + + assertTrue(waitForCondition(s::removed, getTestTimeout())); + + assertEquals(0, semaphores0.size()); + assertEquals(0, semaphores1.size()); + } + } + + /** */ + @Test + public void testLocks() throws Exception { + try (IgniteEx g0 = startGrid(0); + IgniteEx g1 = startGrid(1)) { + IgniteLock l1 = g0.reentrantLock("l1", false, true, true); + IgniteLock l2 = g0.reentrantLock("l2", true, false, true); + + SystemView locks0 = g0.context().systemView().view(LOCKS_VIEW); + SystemView locks1 = g1.context().systemView().view(LOCKS_VIEW); + + assertEquals(2, locks0.size()); + assertEquals(0, locks1.size()); + + String grpName = DEFAULT_VOLATILE_DS_GROUP_NAME + "@" + VOLATILE_DATA_REGION_NAME; + + IgniteInternalFuture lockFut = null; + + Runnable lockNSleep = () -> { + l1.lock(); + + try { + Thread.sleep(getTestTimeout()); + } + catch (InterruptedException e) { + throw new RuntimeException(e); + } + finally { + l1.unlock(); + } + }; + + for (ReentrantLockView l : locks0) { + if ("l1".equals(l.name())) { + assertFalse(l.locked()); + assertFalse(l.hasQueuedThreads()); + assertFalse(l.failoverSafe()); + assertTrue(l.fair()); + assertFalse(l.broken()); + assertFalse(l.removed()); + + lockFut = runAsync(lockNSleep); + + assertTrue(waitForCondition(l::locked, getTestTimeout())); + } + else { + assertFalse(l.hasQueuedThreads()); + assertTrue(l.failoverSafe()); + assertFalse(l.fair()); + assertFalse(l.broken()); + assertFalse(l.removed()); + + l2.close(); + + assertTrue(waitForCondition(l::removed, getTestTimeout())); + } + + assertEquals(grpName, l.groupName()); + assertEquals(CU.cacheId(grpName), l.groupId()); + } + + IgniteLock l3 = g1.reentrantLock("l1", true, false, true); + + assertEquals(1, locks1.size()); + + ReentrantLockView s = locks1.iterator().next(); + + assertTrue(s.locked()); + assertFalse(s.hasQueuedThreads()); + assertFalse(s.failoverSafe()); + assertTrue(s.fair()); + assertFalse(s.broken()); + assertFalse(s.removed()); + + lockFut.cancel(); + + assertTrue(waitForCondition(() -> !s.locked(), getTestTimeout())); + assertFalse(s.hasQueuedThreads()); + + l3.close(); + + assertTrue(waitForCondition(s::removed, getTestTimeout())); + + assertEquals(0, locks0.size()); + assertEquals(0, locks1.size()); + } + } + + /** */ + @Test + public void testQueue() throws Exception { + try (IgniteEx g0 = startGrid(0); + IgniteEx g1 = startGrid(1)) { + + IgniteQueue q0 = g0.queue("queue-1", 42, new CollectionConfiguration() + .setCollocated(true) + .setBackups(1) + .setGroupName("my-group")); + IgniteQueue q1 = g0.queue("queue-2", 0, new CollectionConfiguration()); + + SystemView queues0 = g0.context().systemView().view(QUEUES_VIEW); + SystemView queues1 = g1.context().systemView().view(QUEUES_VIEW); + + assertEquals(2, queues0.size()); + assertEquals(0, queues1.size()); + + for (QueueView q : queues0) { + if ("queue-1".equals(q.name())) { + assertNotNull(q.id()); + assertEquals("queue-1", q.name()); + assertEquals(42, q.capacity()); + assertTrue(q.bounded()); + assertTrue(q.collocated()); + assertEquals("my-group", q.groupName()); + assertEquals(CU.cacheId("my-group"), q.groupId()); + assertFalse(q.removed()); + assertEquals(0, q.size()); + + q0.add("first"); + + assertEquals(1, q.size()); + } + else { + assertNotNull(q.id()); + assertEquals("queue-2", q.name()); + assertEquals(Integer.MAX_VALUE, q.capacity()); + assertFalse(q.bounded()); + assertFalse(q.collocated()); + assertEquals(DEFAULT_DS_GROUP_NAME, q.groupName()); + assertEquals(CU.cacheId(DEFAULT_DS_GROUP_NAME), q.groupId()); + assertFalse(q.removed()); + assertEquals(0, q.size()); + + q1.close(); + + assertTrue(waitForCondition(q::removed, getTestTimeout())); + } + } + + IgniteQueue q2 = g1.queue("queue-1", 42, new CollectionConfiguration() + .setCollocated(true) + .setBackups(1) + .setGroupName("my-group")); + + assertEquals(1, queues1.size()); + + QueueView q = queues1.iterator().next(); + + assertNotNull(q.id()); + assertEquals("queue-1", q.name()); + assertEquals(42, q.capacity()); + assertTrue(q.bounded()); + assertTrue(q.collocated()); + assertEquals("my-group", q.groupName()); + assertEquals(CU.cacheId("my-group"), q.groupId()); + assertFalse(q.removed()); + assertEquals(1, q.size()); + + q2.close(); + + assertTrue(waitForCondition(q::removed, getTestTimeout())); + + assertEquals(0, queues0.size()); + assertEquals(0, queues1.size()); + } + } + + /** */ + @Test + public void testSet() throws Exception { + try (IgniteEx g0 = startGrid(0); + IgniteEx g1 = startGrid(1)) { + + IgniteSet s0 = g0.set("set-1", new CollectionConfiguration() + .setCollocated(true) + .setBackups(1) + .setGroupName("my-group")); + IgniteSet s1 = g0.set("set-2", new CollectionConfiguration()); + + SystemView sets0 = g0.context().systemView().view(SETS_VIEW); + SystemView sets1 = g1.context().systemView().view(SETS_VIEW); + + assertEquals(2, sets0.size()); + assertEquals(0, sets1.size()); + + for (SetView q : sets0) { + if ("set-1".equals(q.name())) { + assertNotNull(q.id()); + assertEquals("set-1", q.name()); + assertTrue(q.collocated()); + assertEquals("my-group", q.groupName()); + assertEquals(CU.cacheId("my-group"), q.groupId()); + assertFalse(q.removed()); + assertEquals(0, q.size()); + + s0.add("first"); + + assertEquals(1, q.size()); + } + else { + assertNotNull(q.id()); + assertEquals("set-2", q.name()); + assertFalse(q.collocated()); + assertEquals(DEFAULT_DS_GROUP_NAME, q.groupName()); + assertEquals(CU.cacheId(DEFAULT_DS_GROUP_NAME), q.groupId()); + assertFalse(q.removed()); + assertEquals(0, q.size()); + + s1.close(); + + assertTrue(waitForCondition(q::removed, getTestTimeout())); + } + } + + IgniteSet s2 = g1.set("set-1", new CollectionConfiguration() + .setCollocated(true) + .setBackups(1) + .setGroupName("my-group")); + + assertEquals(1, sets1.size()); + + SetView s = sets1.iterator().next(); + + assertNotNull(s.id()); + assertEquals("set-1", s.name()); + assertTrue(s.collocated()); + assertEquals("my-group", s.groupName()); + assertEquals(CU.cacheId("my-group"), s.groupId()); + assertFalse(s.removed()); + assertEquals(1, s.size()); + + s2.close(); + + assertTrue(waitForCondition(s::removed, getTestTimeout())); + + assertEquals(0, sets0.size()); + assertEquals(0, sets1.size()); + } + } +} diff --git a/modules/core/src/test/java/org/apache/ignite/internal/metric/SystemViewExecutorsTest.java b/modules/core/src/test/java/org/apache/ignite/internal/metric/SystemViewExecutorsTest.java new file mode 100644 index 0000000000000..b6b154b5d1510 --- /dev/null +++ b/modules/core/src/test/java/org/apache/ignite/internal/metric/SystemViewExecutorsTest.java @@ -0,0 +1,124 @@ +/* + * 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.metric; + +import java.util.Iterator; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; +import org.apache.ignite.IgniteException; +import org.apache.ignite.internal.IgniteEx; +import org.apache.ignite.internal.thread.pool.IgniteStripedExecutor; +import org.apache.ignite.spi.systemview.view.StripedExecutorTaskView; +import org.apache.ignite.spi.systemview.view.SystemView; +import org.junit.Test; + +import static org.apache.ignite.internal.processors.pool.PoolProcessor.STREAM_POOL_QUEUE_VIEW; +import static org.apache.ignite.internal.processors.pool.PoolProcessor.SYS_POOL_QUEUE_VIEW; +import static org.apache.ignite.testframework.GridTestUtils.waitForCondition; + +/** Tests for {@link SystemView} for executors. */ +public class SystemViewExecutorsTest extends SystemViewAbstractTest { + /** */ + @Test + public void testStripedExecutors() throws Exception { + try (IgniteEx g = startGrid(0)) { + checkStripeExecutorView(g.context().pools().getStripedExecutorService(), + g.context().systemView().view(SYS_POOL_QUEUE_VIEW), + "sys"); + + checkStripeExecutorView(g.context().pools().getDataStreamerExecutorService(), + g.context().systemView().view(STREAM_POOL_QUEUE_VIEW), + "data-streamer"); + } + } + + /** + * Checks striped executor system view. + * + * @param execSvc Striped executor. + * @param view System view. + * @param poolName Executor name. + */ + private void checkStripeExecutorView(IgniteStripedExecutor execSvc, SystemView view, + String poolName) throws Exception { + CountDownLatch latch = new CountDownLatch(1); + + execSvc.execute(0, new TestRunnable(latch, 0)); + execSvc.execute(0, new TestRunnable(latch, 1)); + execSvc.execute(1, new TestRunnable(latch, 2)); + execSvc.execute(1, new TestRunnable(latch, 3)); + + try { + boolean res = waitForCondition(() -> view.size() == 2, 5_000); + + assertTrue(res); + + Iterator iter = view.iterator(); + + assertTrue(iter.hasNext()); + + StripedExecutorTaskView row0 = iter.next(); + + assertEquals(0, row0.stripeIndex()); + assertEquals(TestRunnable.class.getSimpleName() + '1', row0.description()); + assertEquals(poolName + "-stripe-0", row0.threadName()); + assertEquals(TestRunnable.class.getName(), row0.taskName()); + + assertTrue(iter.hasNext()); + + StripedExecutorTaskView row1 = iter.next(); + + assertEquals(1, row1.stripeIndex()); + assertEquals(TestRunnable.class.getSimpleName() + '3', row1.description()); + assertEquals(poolName + "-stripe-1", row1.threadName()); + assertEquals(TestRunnable.class.getName(), row1.taskName()); + } + finally { + latch.countDown(); + } + } + /** Test runnable. */ + public static class TestRunnable implements Runnable { + /** */ + private final CountDownLatch latch; + + /** */ + private final int idx; + + /** */ + public TestRunnable(CountDownLatch latch, int idx) { + this.latch = latch; + this.idx = idx; + } + + /** {@inheritDoc} */ + @Override public void run() { + try { + latch.await(5, TimeUnit.SECONDS); + } + catch (InterruptedException e) { + throw new IgniteException(e); + } + } + + /** {@inheritDoc} */ + @Override public String toString() { + return getClass().getSimpleName() + idx; + } + } +} diff --git a/modules/core/src/test/java/org/apache/ignite/internal/metric/SystemViewLocksTest.java b/modules/core/src/test/java/org/apache/ignite/internal/metric/SystemViewLocksTest.java new file mode 100644 index 0000000000000..8830dbb36c21d --- /dev/null +++ b/modules/core/src/test/java/org/apache/ignite/internal/metric/SystemViewLocksTest.java @@ -0,0 +1,387 @@ +/* + * 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.metric; + +import java.util.List; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.locks.Lock; +import org.apache.ignite.configuration.CacheConfiguration; +import org.apache.ignite.internal.IgniteEx; +import org.apache.ignite.internal.IgniteInternalFuture; +import org.apache.ignite.internal.util.typedef.F; +import org.apache.ignite.internal.util.typedef.internal.U; +import org.apache.ignite.spi.systemview.view.CacheExplicitLockView; +import org.apache.ignite.spi.systemview.view.CacheKeyLockView; +import org.apache.ignite.spi.systemview.view.SystemView; +import org.apache.ignite.spi.systemview.view.TransactionView; +import org.apache.ignite.testframework.GridTestUtils; +import org.apache.ignite.transactions.Transaction; +import org.junit.Test; + +import static org.apache.ignite.cache.CacheAtomicityMode.TRANSACTIONAL; +import static org.apache.ignite.cache.CacheMode.PARTITIONED; +import static org.apache.ignite.internal.processors.cache.GridCacheMvccManager.CACHE_EXPLICIT_LOCKS_VIEW; +import static org.apache.ignite.internal.processors.cache.GridCacheMvccManager.CACHE_KEY_LOCKS_VIEW; +import static org.apache.ignite.internal.processors.cache.transactions.IgniteTxManager.TXS_MON_LIST; +import static org.apache.ignite.testframework.GridTestUtils.waitForCondition; +import static org.apache.ignite.transactions.TransactionConcurrency.PESSIMISTIC; +import static org.apache.ignite.transactions.TransactionIsolation.REPEATABLE_READ; + +/** Tests for {@link SystemView} for locks. */ +public class SystemViewLocksTest extends SystemViewAbstractTest { + /** {@inheritDoc} */ + @Override protected void beforeTest() throws Exception { + super.beforeTest(); + + IgniteEx ignite = startGrids(3); + + ignite.getOrCreateCache( + new CacheConfiguration(DEFAULT_CACHE_NAME) + .setAtomicityMode(TRANSACTIONAL) + .setCacheMode(PARTITIONED) + .setBackups(1) + ); + } + + /** {@inheritDoc} */ + @Override protected void afterTest() throws Exception { + stopAllGrids(); + + super.afterTest(); + } + + /** */ + @Test + public void testExplicitLocks() throws Exception { + IgniteEx ignite0 = grid(0); + IgniteEx ignite1 = grid(1); + IgniteEx ignite2 = grid(2); + + CountDownLatch finishLatch = new CountDownLatch(1); + + try { + Integer key0 = primaryKey(ignite0.cache(DEFAULT_CACHE_NAME)); + Integer key1 = primaryKey(ignite1.cache(DEFAULT_CACHE_NAME)); + Integer key2 = primaryKey(ignite2.cache(DEFAULT_CACHE_NAME)); + + CountDownLatch firstNodeLatch = new CountDownLatch(1); + + // Block key0 and key1 from node0. + Runnable task0 = explicitLockTask(ignite0, () -> { + firstNodeLatch.countDown(); + U.awaitQuiet(finishLatch); + }, key0, key1); + + // Block key2 and wait for key0 from node1. + Runnable task1 = explicitLockTask(ignite1, () -> {}, key2, key0); + + // Wait for key0 from node2. + Runnable task2a = explicitLockTask(ignite2, () -> {}, key0); + + // Wait for key1 from node2. + Runnable task2b = explicitLockTask(ignite2, () -> {}, key1); + + IgniteInternalFuture fut0 = GridTestUtils.runAsync(task0); + firstNodeLatch.await(); + IgniteInternalFuture fut1 = GridTestUtils.runAsync(task1); + IgniteInternalFuture fut2a = GridTestUtils.runAsync(task2a); + IgniteInternalFuture fut2b = GridTestUtils.runAsync(task2b); + + List explicitLocks0 = viewContent(ignite0, CACHE_EXPLICIT_LOCKS_VIEW, 2); + List explicitLocks1 = viewContent(ignite1, CACHE_EXPLICIT_LOCKS_VIEW, 2); + List explicitLocks2 = viewContent(ignite2, CACHE_EXPLICIT_LOCKS_VIEW, 2); + + List keyLocks0 = viewContent(ignite0, CACHE_KEY_LOCKS_VIEW, 3); + List keyLocks1 = viewContent(ignite1, CACHE_KEY_LOCKS_VIEW, 2); + List keyLocks2 = viewContent(ignite2, CACHE_KEY_LOCKS_VIEW, 1); + + // Check threads. + assertEquals(explicitLocks0.get(0).threadId(), explicitLocks0.get(1).threadId()); + assertEquals(explicitLocks1.get(0).threadId(), explicitLocks1.get(1).threadId()); + assertNotSame(explicitLocks2.get(0).threadId(), explicitLocks2.get(1).threadId()); + + // Check lock owners. + CacheKeyLockView owner0 = F.find(keyLocks0, null, CacheKeyLockView::isOwner); + CacheKeyLockView owner1 = F.find(keyLocks1, null, CacheKeyLockView::isOwner); + CacheKeyLockView owner2 = F.find(keyLocks2, null, CacheKeyLockView::isOwner); + + assertNotNull(owner0); + assertNotNull(owner1); + assertNotNull(owner2); + + assertEquals(owner0.originatingNodeId(), ignite0.localNode().id()); + assertEquals(1, F.size(explicitLocks0, l -> l.xid().equals(owner0.originatingXid()))); + + assertEquals(owner1.originatingNodeId(), ignite0.localNode().id()); + assertEquals(1, F.size(explicitLocks0, l -> l.xid().equals(owner1.originatingXid()))); + + assertEquals(owner2.originatingNodeId(), ignite1.localNode().id()); + assertEquals(1, F.size(explicitLocks1, l -> l.xid().equals(owner2.originatingXid()))); + + // Check waiting locks. + assertEquals(1, F.size(keyLocks0, + l -> !l.isOwner() && l.originatingNodeId().equals(ignite1.localNode().id()))); + assertEquals(1, F.size(keyLocks0, + l -> !l.isOwner() && l.originatingNodeId().equals(ignite2.localNode().id()))); + assertEquals(1, F.size(keyLocks1, + l -> !l.isOwner() && l.originatingNodeId().equals(ignite2.localNode().id()))); + + finishLatch.countDown(); + + fut0.get(); + fut1.get(); + fut2a.get(); + fut2b.get(); + } + finally { + finishLatch.countDown(); + } + } + + /** */ + @Test + public void testTxLocks() throws Exception { + IgniteEx ignite0 = grid(0); + IgniteEx ignite1 = grid(1); + IgniteEx ignite2 = grid(2); + + CountDownLatch finishLatch = new CountDownLatch(1); + + try { + Integer key0 = primaryKey(ignite0.cache(DEFAULT_CACHE_NAME)); + Integer key1 = primaryKey(ignite1.cache(DEFAULT_CACHE_NAME)); + Integer key2 = primaryKey(ignite2.cache(DEFAULT_CACHE_NAME)); + + CountDownLatch firstNodeLatch = new CountDownLatch(1); + + // Block key0 and key1 from node0. + Runnable task0 = txLockTask(ignite0, () -> { + firstNodeLatch.countDown(); + U.awaitQuiet(finishLatch); + }, key0, key1); + + // Block key2 and wait for key0 from node1. + Runnable task1 = txLockTask(ignite1, () -> {}, key2, key0); + + // Wait for key0 from node2. + Runnable task2a = txLockTask(ignite2, () -> {}, key0); + + // Wait for key1 from node2. + Runnable task2b = txLockTask(ignite2, () -> {}, key1); + + IgniteInternalFuture fut0 = GridTestUtils.runAsync(task0); + firstNodeLatch.await(); + IgniteInternalFuture fut1 = GridTestUtils.runAsync(task1); + IgniteInternalFuture fut2a = GridTestUtils.runAsync(task2a); + IgniteInternalFuture fut2b = GridTestUtils.runAsync(task2b); + + List txs0 = viewContent(ignite0, TXS_MON_LIST, 3); // 1 near + 2 dht. + List txs1 = viewContent(ignite1, TXS_MON_LIST, 3); // 1 near + 2 dht + List txs2 = viewContent(ignite2, TXS_MON_LIST, 3); // 2 near + 1 dht + + List keyLocks0 = viewContent(ignite0, CACHE_KEY_LOCKS_VIEW, 3); + List keyLocks1 = viewContent(ignite1, CACHE_KEY_LOCKS_VIEW, 2); + List keyLocks2 = viewContent(ignite2, CACHE_KEY_LOCKS_VIEW, 1); + + // Check lock owners. + CacheKeyLockView owner0 = F.find(keyLocks0, null, CacheKeyLockView::isOwner); + CacheKeyLockView owner1 = F.find(keyLocks1, null, CacheKeyLockView::isOwner); + CacheKeyLockView owner2 = F.find(keyLocks2, null, CacheKeyLockView::isOwner); + + assertNotNull(owner0); + assertNotNull(owner1); + assertNotNull(owner2); + + assertEquals(owner0.originatingNodeId(), ignite0.localNode().id()); + assertEquals(1, F.size(txs0, l -> l.xid().equals(owner0.originatingXid()) && l.xid().equals(owner0.xid()))); + + assertEquals(owner1.originatingNodeId(), ignite0.localNode().id()); + assertEquals(1, F.size(txs0, l -> l.xid().equals(owner1.originatingXid()))); // Near. + assertEquals(1, F.size(txs1, l -> l.xid().equals(owner1.xid()))); // Dht. + + assertEquals(owner2.originatingNodeId(), ignite1.localNode().id()); + assertEquals(1, F.size(txs1, l -> l.xid().equals(owner2.originatingXid()))); // Near. + assertEquals(1, F.size(txs2, l -> l.xid().equals(owner2.xid()))); // Dht. + + // Check waiting locks. + CacheKeyLockView waiting1on0 = F.find(keyLocks0, null, + l -> !l.isOwner() && l.originatingNodeId().equals(ignite1.localNode().id())); + CacheKeyLockView waiting2on0 = F.find(keyLocks0, null, + l -> !l.isOwner() && l.originatingNodeId().equals(ignite2.localNode().id())); + CacheKeyLockView waiting2on1 = F.find(keyLocks1, null, + l -> !l.isOwner() && l.originatingNodeId().equals(ignite2.localNode().id())); + + assertNotNull(waiting1on0); + assertNotNull(waiting2on0); + assertNotNull(waiting2on1); + + assertEquals(1, F.size(txs1, l -> l.xid().equals(waiting1on0.originatingXid()))); // Near. + assertEquals(1, F.size(txs0, l -> l.xid().equals(waiting1on0.xid()))); // Dht. + + assertEquals(1, F.size(txs2, l -> l.xid().equals(waiting2on0.originatingXid()))); // Near. + assertEquals(1, F.size(txs0, l -> l.xid().equals(waiting2on0.xid()))); // Dht. + + assertEquals(1, F.size(txs2, l -> l.xid().equals(waiting2on1.originatingXid()))); // Near. + assertEquals(1, F.size(txs1, l -> l.xid().equals(waiting2on1.xid()))); // Dht. + + finishLatch.countDown(); + + fut0.get(); + fut1.get(); + fut2a.get(); + fut2b.get(); + } + finally { + finishLatch.countDown(); + } + } + + /** */ + @Test + public void testMixedExplicitTxLocks() throws Exception { + IgniteEx ignite0 = grid(0); + IgniteEx ignite1 = grid(1); + IgniteEx ignite2 = grid(2); + + CountDownLatch finishLatch = new CountDownLatch(1); + + try { + Integer key1 = primaryKey(ignite1.cache(DEFAULT_CACHE_NAME)); + Integer key2 = primaryKey(ignite2.cache(DEFAULT_CACHE_NAME)); + + CountDownLatch firstNodeLatch = new CountDownLatch(1); + CountDownLatch secondNodeLatch = new CountDownLatch(1); + + // Block key1 from node0. + Runnable task0 = explicitLockTask(ignite0, () -> { + firstNodeLatch.countDown(); + U.awaitQuiet(finishLatch); + }, key1); + + // Block key2 from node1. + Runnable task1 = txLockTask(ignite1, () -> { + secondNodeLatch.countDown(); + U.awaitQuiet(finishLatch); + }, key2); + + // Wait for key2 from node2. + Runnable task2a = explicitLockTask(ignite2, () -> {}, key2); + + // Wait for key1 from node2. + Runnable task2b = txLockTask(ignite2, () -> {}, key1); + + IgniteInternalFuture fut0 = GridTestUtils.runAsync(task0); + firstNodeLatch.await(); + IgniteInternalFuture fut1 = GridTestUtils.runAsync(task1); + secondNodeLatch.await(); + IgniteInternalFuture fut2a = GridTestUtils.runAsync(task2a); + IgniteInternalFuture fut2b = GridTestUtils.runAsync(task2b); + + List explicitLocks0 = viewContent(ignite0, CACHE_EXPLICIT_LOCKS_VIEW, 1); + List explicitLocks2 = viewContent(ignite2, CACHE_EXPLICIT_LOCKS_VIEW, 1); + List txs1 = viewContent(ignite1, TXS_MON_LIST, 2); // 1 near + 1 dht + List txs2 = viewContent(ignite2, TXS_MON_LIST, 2); // 1 near + 1 dht + + List keyLocks1 = viewContent(ignite1, CACHE_KEY_LOCKS_VIEW, 2); + List keyLocks2 = viewContent(ignite2, CACHE_KEY_LOCKS_VIEW, 2); + + // Check lock owners. + CacheKeyLockView owner1 = F.find(keyLocks1, null, CacheKeyLockView::isOwner); + CacheKeyLockView owner2 = F.find(keyLocks2, null, CacheKeyLockView::isOwner); + + assertNotNull(owner1); + assertNotNull(owner2); + + assertEquals(owner1.originatingNodeId(), ignite0.localNode().id()); + assertEquals(1, F.size(explicitLocks0, l -> l.xid().equals(owner1.originatingXid()))); + + assertEquals(owner2.originatingNodeId(), ignite1.localNode().id()); + assertEquals(1, F.size(txs1, l -> l.xid().equals(owner2.originatingXid()))); // Near. + assertEquals(1, F.size(txs2, l -> l.xid().equals(owner2.xid()))); // Dht. + + // Check waiting locks. + CacheKeyLockView waiting2on1 = F.find(keyLocks1, null, + l -> !l.isOwner() && l.originatingNodeId().equals(ignite2.localNode().id())); + CacheKeyLockView waiting2on2 = F.find(keyLocks2, null, + l -> !l.isOwner() && l.originatingNodeId().equals(ignite2.localNode().id())); + + assertNotNull(waiting2on1); + assertNotNull(waiting2on2); + + assertEquals(1, F.size(txs2, l -> l.xid().equals(waiting2on1.originatingXid()))); // Near. + assertEquals(1, F.size(txs1, l -> l.xid().equals(waiting2on1.xid()))); // Dht. + + assertEquals(1, F.size(explicitLocks2, l -> l.xid().equals(waiting2on2.originatingXid()))); + + finishLatch.countDown(); + + fut0.get(); + fut1.get(); + fut2a.get(); + fut2b.get(); + } + finally { + finishLatch.countDown(); + } + } + + /** */ + private static Runnable explicitLockTask(IgniteEx ignite, Runnable body, int... keysToLock) { + return () -> { + Lock[] locks = new Lock[keysToLock.length]; + + for (int i = 0; i < keysToLock.length; i++) { + locks[i] = ignite.cache(DEFAULT_CACHE_NAME).lock(keysToLock[i]); + locks[i].lock(); + } + + try { + body.run(); + } + finally { + for (int i = keysToLock.length - 1; i >= 0; i--) + locks[i].unlock(); + } + }; + } + + /** */ + private static Runnable txLockTask(IgniteEx ignite, Runnable body, int... keysToLock) { + return () -> { + try (Transaction tx = ignite.transactions().txStart(PESSIMISTIC, REPEATABLE_READ)) { + for (int i = 0; i < keysToLock.length; i++) + ignite.cache(DEFAULT_CACHE_NAME).put(keysToLock[i], 0); + + body.run(); + + tx.commit(); + } + }; + } + + /** */ + private static List viewContent(IgniteEx ignite, String viewName, int expSize) throws Exception { + SystemView view = ignite.context().systemView().view(viewName); + + assertTrue("Failed to wait for view size [ignite=" + ignite.name() + ", viewName=" + viewName + + ", expSize=" + expSize + ", actSize=" + F.size(view.iterator()), + waitForCondition(() -> F.size(view.iterator()) == expSize, 1_000L)); + + return U.arrayList(view.iterator(), expSize); + } +} diff --git a/modules/core/src/test/java/org/apache/ignite/internal/metric/SystemViewMetastorageTest.java b/modules/core/src/test/java/org/apache/ignite/internal/metric/SystemViewMetastorageTest.java new file mode 100644 index 0000000000000..16a3174868c7c --- /dev/null +++ b/modules/core/src/test/java/org/apache/ignite/internal/metric/SystemViewMetastorageTest.java @@ -0,0 +1,148 @@ +/* + * 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.metric; + +import java.util.Iterator; +import org.apache.ignite.cluster.ClusterState; +import org.apache.ignite.configuration.DataRegionConfiguration; +import org.apache.ignite.configuration.DataStorageConfiguration; +import org.apache.ignite.internal.IgniteEx; +import org.apache.ignite.internal.processors.cache.persistence.IgniteCacheDatabaseSharedManager; +import org.apache.ignite.internal.processors.metastorage.DistributedMetaStorage; +import org.apache.ignite.internal.systemview.MetastorageViewWalker; +import org.apache.ignite.internal.util.typedef.F; +import org.apache.ignite.lang.IgnitePredicate; +import org.apache.ignite.spi.systemview.view.FiltrableSystemView; +import org.apache.ignite.spi.systemview.view.MetastorageView; +import org.apache.ignite.spi.systemview.view.SystemView; +import org.junit.Test; + +import static org.apache.ignite.internal.processors.cache.persistence.DataStorageMetricsImpl.DATASTORAGE_METRIC_PREFIX; +import static org.apache.ignite.internal.processors.cache.persistence.GridCacheDatabaseSharedManager.METASTORE_VIEW; +import static org.apache.ignite.internal.processors.metastorage.persistence.DistributedMetaStorageImpl.DISTRIBUTED_METASTORE_VIEW; +import static org.apache.ignite.internal.processors.metric.impl.MetricUtils.metricName; + +/** Tests for {@link SystemView} for metastorage. */ +public class SystemViewMetastorageTest extends SystemViewAbstractTest { + /** */ + @Test + public void testMetastorage() throws Exception { + cleanPersistenceDir(); + + try (IgniteEx ignite = startGrid(getConfiguration().setDataStorageConfiguration( + new DataStorageConfiguration().setDefaultDataRegionConfiguration( + new DataRegionConfiguration().setPersistenceEnabled(true) + )))) { + ignite.cluster().state(ClusterState.ACTIVE); + + IgniteCacheDatabaseSharedManager db = ignite.context().cache().context().database(); + + SystemView metaStoreView = ignite.context().systemView().view(METASTORE_VIEW); + + assertNotNull(metaStoreView); + + String name = "test-key"; + String val = "test-value"; + String unmarshalledName = "unmarshalled-key"; + String unmarshalledVal = "[Raw data. 0 bytes]"; + + db.checkpointReadLock(); + + try { + db.metaStorage().write(name, val); + db.metaStorage().writeRaw(unmarshalledName, new byte[0]); + } + finally { + db.checkpointReadUnlock(); + } + + assertNotNull(F.find(metaStoreView, null, + (IgnitePredicate)view -> + name.equals(view.name()) && val.equals(view.value()))); + + assertNotNull(F.find(metaStoreView, null, + (IgnitePredicate)view -> + unmarshalledName.equals(view.name()) && unmarshalledVal.equals(view.value()))); + + // Test filtering. + assertTrue(metaStoreView instanceof FiltrableSystemView); + + Iterator iter = ((FiltrableSystemView)metaStoreView) + .iterator(F.asMap(MetastorageViewWalker.NAME_FILTER, name)); + + assertTrue(iter.hasNext()); + + MetastorageView row = iter.next(); + + assertTrue(name.equals(row.name()) && val.equals(row.value())); + assertFalse(iter.hasNext()); + } + } + + /** */ + @Test + public void testDistributedMetastorage() throws Exception { + cleanPersistenceDir(); + + try (IgniteEx ignite = startGrid(getConfiguration().setDataStorageConfiguration( + new DataStorageConfiguration().setDefaultDataRegionConfiguration( + new DataRegionConfiguration().setPersistenceEnabled(true) + )))) { + ignite.cluster().state(ClusterState.ACTIVE); + + String histogramName = "CheckpointBeforeLockHistogram"; + + ignite.context().metric().configureHistogram(metricName(DATASTORAGE_METRIC_PREFIX, histogramName), new long[] { 1, 2, 3}); + + DistributedMetaStorage dms = ignite.context().distributedMetastorage(); + + String name = "test-distributed-key"; + String val = "test-distributed-value"; + + dms.write(name, val); + + SystemView dmsView = ignite.context().systemView().view(DISTRIBUTED_METASTORE_VIEW); + + assertNotNull(F.find( + dmsView, + null, + (IgnitePredicate)view -> name.equals(view.name()) && val.equals(view.value())) + ); + + assertNotNull(F.find( + dmsView, + null, + (IgnitePredicate) + view -> view.name().endsWith(histogramName) && "[1, 2, 3]".equals(view.value())) + ); + + // Test filtering. + assertTrue(dmsView instanceof FiltrableSystemView); + + Iterator iter = ((FiltrableSystemView)dmsView) + .iterator(F.asMap(MetastorageViewWalker.NAME_FILTER, name)); + + assertTrue(iter.hasNext()); + + MetastorageView row = iter.next(); + + assertTrue(name.equals(row.name()) && val.equals(row.value())); + assertFalse(iter.hasNext()); + } + } +} diff --git a/modules/core/src/test/java/org/apache/ignite/internal/metric/SystemViewNodesTest.java b/modules/core/src/test/java/org/apache/ignite/internal/metric/SystemViewNodesTest.java new file mode 100644 index 0000000000000..f6036418a84fa --- /dev/null +++ b/modules/core/src/test/java/org/apache/ignite/internal/metric/SystemViewNodesTest.java @@ -0,0 +1,235 @@ +/* + * 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.metric; + +import java.util.Iterator; +import org.apache.ignite.cluster.ClusterNode; +import org.apache.ignite.cluster.ClusterState; +import org.apache.ignite.configuration.DataRegionConfiguration; +import org.apache.ignite.configuration.DataStorageConfiguration; +import org.apache.ignite.internal.IgniteEx; +import org.apache.ignite.internal.systemview.BaselineNodeAttributeViewWalker; +import org.apache.ignite.internal.systemview.NodeAttributeViewWalker; +import org.apache.ignite.internal.util.typedef.F; +import org.apache.ignite.internal.util.typedef.internal.U; +import org.apache.ignite.spi.systemview.view.BaselineNodeAttributeView; +import org.apache.ignite.spi.systemview.view.BaselineNodeView; +import org.apache.ignite.spi.systemview.view.ClusterNodeView; +import org.apache.ignite.spi.systemview.view.FiltrableSystemView; +import org.apache.ignite.spi.systemview.view.NodeAttributeView; +import org.apache.ignite.spi.systemview.view.NodeMetricsView; +import org.apache.ignite.spi.systemview.view.SystemView; +import org.apache.ignite.testframework.junits.WithSystemProperty; +import org.junit.Test; + +import static org.apache.ignite.IgniteSystemProperties.IGNITE_DATA_CENTER_ID; +import static org.apache.ignite.internal.managers.discovery.GridDiscoveryManager.NODES_SYS_VIEW; +import static org.apache.ignite.internal.managers.discovery.GridDiscoveryManager.NODE_ATTRIBUTES_SYS_VIEW; +import static org.apache.ignite.internal.managers.discovery.GridDiscoveryManager.NODE_METRICS_SYS_VIEW; +import static org.apache.ignite.internal.processors.cluster.GridClusterStateProcessor.BASELINE_NODES_SYS_VIEW; +import static org.apache.ignite.internal.processors.cluster.GridClusterStateProcessor.BASELINE_NODE_ATTRIBUTES_SYS_VIEW; +import static org.apache.ignite.internal.util.IgniteUtils.toStringSafe; + +/** Tests for {@link SystemView} for nodes. */ +public class SystemViewNodesTest extends SystemViewAbstractTest { + /** */ + @Test + @WithSystemProperty(key = IGNITE_DATA_CENTER_ID, value = "DC0") + public void testNodes() throws Exception { + try (IgniteEx g1 = startGrid(0)) { + SystemView views = g1.context().systemView().view(NODES_SYS_VIEW); + + assertEquals(1, views.size()); + + try (IgniteEx g2 = startGrid(1)) { + awaitPartitionMapExchange(); + + checkViewsState(views, g1.localNode(), g2.localNode()); + checkViewsState(g2.context().systemView().view(NODES_SYS_VIEW), g2.localNode(), g1.localNode()); + } + + assertEquals(1, views.size()); + } + } + + /** */ + @Test + public void testNodeAttributes() throws Exception { + try ( + IgniteEx ignite0 = startGrid(getConfiguration(getTestIgniteInstanceName(0)) + .setUserAttributes(F.asMap("name", "val0"))); + IgniteEx ignite1 = startGrid(getConfiguration(getTestIgniteInstanceName(1)) + .setUserAttributes(F.asMap("name", "val1"))) + ) { + awaitPartitionMapExchange(); + + SystemView view = ignite0.context().systemView().view(NODE_ATTRIBUTES_SYS_VIEW); + + assertEquals(ignite0.cluster().localNode().attributes().size() + + ignite1.cluster().localNode().attributes().size(), view.size()); + + assertEquals(1, F.size(view.iterator(), row -> "name".equals(row.name()) && "val0".equals(row.value()))); + assertEquals(1, F.size(view.iterator(), row -> "name".equals(row.name()) && "val1".equals(row.value()))); + + // Test filtering. + assertTrue(view instanceof FiltrableSystemView); + + Iterator iter = ((FiltrableSystemView)view) + .iterator(F.asMap(NodeAttributeViewWalker.NODE_ID_FILTER, ignite0.cluster().localNode().id())); + + assertEquals(1, F.size(iter, row -> "name".equals(row.name()) && "val0".equals(row.value()))); + + iter = ((FiltrableSystemView)view).iterator( + F.asMap(NodeAttributeViewWalker.NODE_ID_FILTER, ignite1.cluster().localNode().id().toString())); + + assertEquals(1, F.size(iter, row -> "name".equals(row.name()) && "val1".equals(row.value()))); + + iter = ((FiltrableSystemView)view).iterator( + F.asMap(NodeAttributeViewWalker.NODE_ID_FILTER, "malformed-id")); + + assertEquals(0, F.size(iter)); + + iter = ((FiltrableSystemView)view).iterator( + F.asMap(NodeAttributeViewWalker.NAME_FILTER, "name")); + + assertEquals(2, F.size(iter)); + + iter = ((FiltrableSystemView)view) + .iterator(F.asMap(NodeAttributeViewWalker.NODE_ID_FILTER, ignite0.cluster().localNode().id(), + NodeAttributeViewWalker.NAME_FILTER, "name")); + + assertEquals(1, F.size(iter)); + } + } + + /** */ + @Test + public void testNodeMetrics() throws Exception { + long ts = U.currentTimeMillis(); + + try (IgniteEx ignite0 = startGrid(0); IgniteEx ignite1 = startGrid(1)) { + awaitPartitionMapExchange(); + + SystemView view = ignite0.context().systemView().view(NODE_METRICS_SYS_VIEW); + + assertEquals(2, view.size()); + assertEquals(1, F.size(view.iterator(), row -> row.nodeId().equals(ignite0.cluster().localNode().id()))); + assertEquals(1, F.size(view.iterator(), row -> row.nodeId().equals(ignite1.cluster().localNode().id()))); + assertEquals(2, F.size(view.iterator(), row -> row.lastUpdateTime().getTime() >= ts)); + } + } + + /** */ + @Test + public void testBaselineNodes() throws Exception { + cleanPersistenceDir(); + + try ( + IgniteEx ignite0 = startGrid(getConfiguration(getTestIgniteInstanceName(0)) + .setDataStorageConfiguration(new DataStorageConfiguration().setDefaultDataRegionConfiguration( + new DataRegionConfiguration().setPersistenceEnabled(true))) + .setConsistentId("consId0")); + IgniteEx ignite1 = startGrid(getConfiguration(getTestIgniteInstanceName(1)) + .setDataStorageConfiguration(new DataStorageConfiguration().setDefaultDataRegionConfiguration( + new DataRegionConfiguration().setPersistenceEnabled(true))) + .setConsistentId("consId1")); + ) { + ignite0.cluster().state(ClusterState.ACTIVE); + + ignite1.close(); + + awaitPartitionMapExchange(); + + SystemView view = ignite0.context().systemView().view(BASELINE_NODES_SYS_VIEW); + + assertEquals(2, view.size()); + assertEquals(1, F.size(view.iterator(), row -> "consId0".equals(row.consistentId()) && row.online())); + assertEquals(1, F.size(view.iterator(), row -> "consId1".equals(row.consistentId()) && !row.online())); + } + } + + /** */ + @Test + public void testBaselineNodeAttributes() throws Exception { + cleanPersistenceDir(); + + try (IgniteEx ignite = startGrid(getConfiguration() + .setDataStorageConfiguration( + new DataStorageConfiguration().setDefaultDataRegionConfiguration( + new DataRegionConfiguration().setName("pds").setPersistenceEnabled(true) + )) + .setUserAttributes(F.asMap("name", "val")) + .setConsistentId("consId")) + ) { + ignite.cluster().state(ClusterState.ACTIVE); + + SystemView view = ignite.context().systemView() + .view(BASELINE_NODE_ATTRIBUTES_SYS_VIEW); + + assertEquals(ignite.cluster().localNode().attributes().size(), view.size()); + + assertEquals(1, F.size(view.iterator(), row -> "consId".equals(row.nodeConsistentId()) && + "name".equals(row.name()) && "val".equals(row.value()))); + + // Test filtering. + assertTrue(view instanceof FiltrableSystemView); + + Iterator iter = ((FiltrableSystemView)view) + .iterator(F.asMap(BaselineNodeAttributeViewWalker.NODE_CONSISTENT_ID_FILTER, "consId", + BaselineNodeAttributeViewWalker.NAME_FILTER, "name")); + + assertEquals(1, F.size(iter)); + + iter = ((FiltrableSystemView)view).iterator( + F.asMap(BaselineNodeAttributeViewWalker.NODE_CONSISTENT_ID_FILTER, "consId")); + + assertEquals(1, F.size(iter, row -> "name".equals(row.name()))); + + iter = ((FiltrableSystemView)view).iterator( + F.asMap(BaselineNodeAttributeViewWalker.NAME_FILTER, "name")); + + assertEquals(1, F.size(iter)); + } + } + + /** */ + private void checkViewsState(SystemView views, ClusterNode loc, ClusterNode rmt) { + assertEquals(2, views.size()); + + for (ClusterNodeView nodeView : views) { + if (nodeView.nodeId().equals(loc.id())) + checkNodeView(nodeView, loc, true); + else + checkNodeView(nodeView, rmt, false); + } + } + + /** */ + private void checkNodeView(ClusterNodeView view, ClusterNode node, boolean isLoc) { + assertEquals(node.id(), view.nodeId()); + assertEquals(node.consistentId().toString(), view.consistentId()); + assertEquals(toStringSafe(node.addresses()), view.addresses()); + assertEquals(toStringSafe(node.hostNames()), view.hostnames()); + assertEquals(node.order(), view.nodeOrder()); + assertEquals(node.version().toString(), view.version()); + assertEquals(isLoc, view.isLocal()); + assertEquals(node.isClient(), view.isClient()); + assertEquals(node.dataCenterId(), view.dataCenterId()); + assertEquals("DC0", view.dataCenterId()); + } +} diff --git a/modules/core/src/test/java/org/apache/ignite/internal/metric/SystemViewPageListsTest.java b/modules/core/src/test/java/org/apache/ignite/internal/metric/SystemViewPageListsTest.java new file mode 100644 index 0000000000000..e2182ce77d8bb --- /dev/null +++ b/modules/core/src/test/java/org/apache/ignite/internal/metric/SystemViewPageListsTest.java @@ -0,0 +1,156 @@ +/* + * 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.metric; + +import java.util.Iterator; +import java.util.Map; +import org.apache.ignite.IgniteCache; +import org.apache.ignite.cache.affinity.rendezvous.RendezvousAffinityFunction; +import org.apache.ignite.cluster.ClusterState; +import org.apache.ignite.configuration.CacheConfiguration; +import org.apache.ignite.configuration.DataRegionConfiguration; +import org.apache.ignite.configuration.DataStorageConfiguration; +import org.apache.ignite.internal.IgniteEx; +import org.apache.ignite.internal.processors.cache.persistence.GridCacheDatabaseSharedManager; +import org.apache.ignite.internal.processors.cache.persistence.freelist.PagesList; +import org.apache.ignite.internal.systemview.CachePagesListViewWalker; +import org.apache.ignite.internal.util.typedef.F; +import org.apache.ignite.spi.systemview.view.CachePagesListView; +import org.apache.ignite.spi.systemview.view.FiltrableSystemView; +import org.apache.ignite.spi.systemview.view.PagesListView; +import org.apache.ignite.spi.systemview.view.SystemView; +import org.junit.Test; + +import static org.apache.ignite.internal.processors.cache.GridCacheProcessor.CACHE_GRP_PAGE_LIST_VIEW; +import static org.apache.ignite.internal.processors.cache.GridCacheUtils.cacheId; +import static org.apache.ignite.internal.processors.cache.persistence.IgniteCacheDatabaseSharedManager.DATA_REGION_PAGE_LIST_VIEW; + +/** Tests for {@link SystemView} for page lists. */ +public class SystemViewPageListsTest extends SystemViewAbstractTest { + /** */ + @Test + public void testPagesList() throws Exception { + cleanPersistenceDir(); + + try (IgniteEx ignite = startGrid(getConfiguration() + .setDataStorageConfiguration( + new DataStorageConfiguration().setDataRegionConfigurations( + new DataRegionConfiguration().setName("dr0").setMaxSize(100L * 1024 * 1024), + new DataRegionConfiguration().setName("dr1").setMaxSize(100L * 1024 * 1024) + .setPersistenceEnabled(true) + )))) { + ignite.cluster().state(ClusterState.ACTIVE); + + GridCacheDatabaseSharedManager dbMgr = (GridCacheDatabaseSharedManager)ignite.context().cache().context() + .database(); + + int pageSize = dbMgr.pageSize(); + + dbMgr.enableCheckpoints(false).get(); + + for (int i = 0; i < 2; i++) { + IgniteCache cache = ignite.getOrCreateCache(new CacheConfiguration<>("cache" + i) + .setDataRegionName("dr" + i).setAffinity(new RendezvousAffinityFunction().setPartitions(2))); + + int key = 0; + + // Fill up different free-list buckets. + for (int j = 0; j < pageSize / 2; j++) + cache.put(key++, new byte[j + 1]); + + // Put some pages to one bucket to overflow pages cache. + for (int j = 0; j < 1000; j++) + cache.put(key++, new byte[pageSize / 2]); + } + + long dr0flPages = 0; + int dr0flStripes = 0; + + SystemView dataRegionPageLists = ignite.context().systemView().view(DATA_REGION_PAGE_LIST_VIEW); + + for (PagesListView pagesListView : dataRegionPageLists) { + if (pagesListView.name().startsWith("dr0")) { + dr0flPages += pagesListView.bucketSize(); + dr0flStripes += pagesListView.stripesCount(); + } + } + + assertTrue(dr0flPages > 0); + assertTrue(dr0flStripes > 0); + + int bucketsCnt = ((PagesList)ignite.context().cache().context().database().freeList("dr0")).bucketsCount(); + int[] bucketPagesSize = new int[bucketsCnt]; + + for (PagesListView pagesListView : dataRegionPageLists) { + int bucket = pagesListView.bucketNumber(); + + if (bucketPagesSize[bucket] == 0) { + assertTrue(bucket == 0 || pagesListView.pageFreeSpace() != 0); + bucketPagesSize[bucket] = pagesListView.pageFreeSpace(); + } + else + assertEquals(bucketPagesSize[bucket], pagesListView.pageFreeSpace()); + } + + int prev = 0; + + for (int size : bucketPagesSize) { + if (size > 0) { + assertTrue(size > prev); + prev = size; + } + } + + SystemView cacheGrpPageLists = ignite.context().systemView().view(CACHE_GRP_PAGE_LIST_VIEW); + + long dr1flPages = 0; + int dr1flStripes = 0; + int dr1flCached = 0; + + for (CachePagesListView pagesListView : cacheGrpPageLists) { + if (pagesListView.cacheGroupId() == cacheId("cache1")) { + dr1flPages += pagesListView.bucketSize(); + dr1flStripes += pagesListView.stripesCount(); + dr1flCached += pagesListView.cachedPagesCount(); + } + } + + assertTrue(dr1flPages > 0); + assertTrue(dr1flStripes > 0); + assertTrue(dr1flCached > 0); + + // Test filtering. + assertTrue(cacheGrpPageLists instanceof FiltrableSystemView); + + Iterator iter = ((FiltrableSystemView)cacheGrpPageLists).iterator(Map.of( + CachePagesListViewWalker.CACHE_GROUP_ID_FILTER, cacheId("cache1"), + CachePagesListViewWalker.PARTITION_ID_FILTER, 0, + CachePagesListViewWalker.BUCKET_NUMBER_FILTER, 0 + )); + + assertEquals(1, F.size(iter)); + + iter = ((FiltrableSystemView)cacheGrpPageLists).iterator(Map.of( + CachePagesListViewWalker.CACHE_GROUP_ID_FILTER, cacheId("cache1"), + CachePagesListViewWalker.BUCKET_NUMBER_FILTER, 0 + )); + + assertEquals(2, F.size(iter)); + } + } +} diff --git a/modules/core/src/test/java/org/apache/ignite/internal/metric/SystemViewPageTimestampsTest.java b/modules/core/src/test/java/org/apache/ignite/internal/metric/SystemViewPageTimestampsTest.java new file mode 100644 index 0000000000000..86f28a7b1f490 --- /dev/null +++ b/modules/core/src/test/java/org/apache/ignite/internal/metric/SystemViewPageTimestampsTest.java @@ -0,0 +1,228 @@ +/* + * 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.metric; + +import java.util.concurrent.atomic.AtomicLong; +import org.apache.ignite.IgniteCache; +import org.apache.ignite.IgniteDataStreamer; +import org.apache.ignite.cache.affinity.rendezvous.RendezvousAffinityFunction; +import org.apache.ignite.cluster.ClusterState; +import org.apache.ignite.configuration.CacheConfiguration; +import org.apache.ignite.configuration.DataRegionConfiguration; +import org.apache.ignite.configuration.DataStorageConfiguration; +import org.apache.ignite.internal.IgniteEx; +import org.apache.ignite.internal.processors.metric.impl.PeriodicHistogramMetricImpl; +import org.apache.ignite.internal.util.GridTestClockTimer; +import org.apache.ignite.internal.util.typedef.F; +import org.apache.ignite.spi.systemview.view.PagesTimestampHistogramView; +import org.apache.ignite.spi.systemview.view.SystemView; +import org.apache.ignite.testframework.GridTestUtils; +import org.junit.Test; + +import static org.apache.ignite.internal.processors.cache.persistence.IgniteCacheDatabaseSharedManager.PAGE_TS_HISTOGRAM_VIEW; + +/** Tests for {@link SystemView} for page timestamps. */ +public class SystemViewPageTimestampsTest extends SystemViewAbstractTest { + /** */ + @Test + public void testPagesTimestampHistogram() throws Exception { + int keysCnt = 50_000; + + AtomicLong curTime = new AtomicLong(System.currentTimeMillis()); + + GridTestClockTimer.timeSupplier(curTime::get); + GridTestClockTimer.update(); + + String regionName = "default"; + + DataStorageConfiguration dsCfg = new DataStorageConfiguration().setDefaultDataRegionConfiguration( + new DataRegionConfiguration() + .setMaxSize(50L * 1024 * 1024) + .setPersistenceEnabled(true) + .setName(regionName) + .setMetricsEnabled(true) + ); + + cleanPersistenceDir(); + + try (IgniteEx ignite = startGrid(getConfiguration().setDataStorageConfiguration(dsCfg))) { + ignite.cluster().state(ClusterState.ACTIVE); + + CacheConfiguration ccfg1 = new CacheConfiguration<>("test-pages-ts1") + .setAffinity(new RendezvousAffinityFunction(false, 10)); + + CacheConfiguration ccfg2 = new CacheConfiguration<>("test-pages-ts2") + .setAffinity(new RendezvousAffinityFunction(false, 10)); + + IgniteCache cache1 = ignite.createCache(ccfg1); + + long ts1 = curTime.get(); + + for (int i = 0; i < 1000; i++) + cache1.put(i, i); + + long ts2 = curTime.addAndGet(PeriodicHistogramMetricImpl.DFLT_BUCKETS_INTERVAL); + GridTestClockTimer.update(); + + for (int i = 1000; i < 2000; i++) + cache1.put(i, i); + + SystemView pagesTsHistogram = + ignite.context().systemView().view(PAGE_TS_HISTOGRAM_VIEW); + + assertNotNull(pagesTsHistogram); + + long totalCnt = 0; + + for (PagesTimestampHistogramView view : pagesTsHistogram) { + if (regionName.equals(view.dataRegionName())) { + if ((ts1 >= view.intervalStart().getTime() && ts1 <= view.intervalEnd().getTime()) || + (ts2 >= view.intervalStart().getTime() && ts2 <= view.intervalEnd().getTime())) { + assertTrue("Unexpected pages count: " + view.pagesCount(), view.pagesCount() > 0); + + totalCnt += view.pagesCount(); + } + else + assertEquals(0, view.pagesCount()); + } + } + + assertTrue(totalCnt > 0); + assertEquals(ignite.dataRegionMetrics(regionName).getPhysicalMemoryPages(), totalCnt); + + assertEquals(2, F.size(F.iterator(pagesTsHistogram, v -> v, true, v -> v.pagesCount() > 0))); + + // Check histogram after replacement. + long ts3 = curTime.addAndGet(PeriodicHistogramMetricImpl.DFLT_BUCKETS_INTERVAL); + GridTestClockTimer.update(); + + ignite.createCache(ccfg2); + + try (IgniteDataStreamer streamer = ignite.dataStreamer("test-pages-ts2")) { + for (int i = 0; i < keysCnt; i++) + streamer.addData(i, new byte[1000]); + } + + assertEquals(ignite.dataRegionMetrics(regionName).getPhysicalMemoryPages(), + F.sumInt(F.iterator(pagesTsHistogram, v -> (int)v.pagesCount(), true))); + + assertFalse(F.isEmpty(F.iterator(pagesTsHistogram, v -> v, true, v -> v.pagesCount() > 0 && + v.intervalStart().getTime() <= ts3 && ts3 <= v.intervalEnd().getTime()))); + + // Check histogram after cache destroy and remove of outdated pages. + long ts4 = curTime.addAndGet(PeriodicHistogramMetricImpl.DFLT_BUCKETS_INTERVAL); + GridTestClockTimer.update(); + + ignite.destroyCache("test-pages-ts2"); + + IgniteCache cache2 = ignite.createCache(ccfg2); + + for (int i = 0; i < keysCnt; i++) { + cache1.put(i, i); + cache2.put(i, new byte[1000]); + } + + assertEquals(ignite.dataRegionMetrics(regionName).getPhysicalMemoryPages(), + F.sumInt(F.iterator(pagesTsHistogram, v -> (int)v.pagesCount(), true))); + + assertFalse(F.isEmpty(F.iterator(pagesTsHistogram, v -> v, true, v -> v.pagesCount() > 0 && + v.intervalStart().getTime() <= ts4 && ts4 <= v.intervalEnd().getTime()))); + } + finally { + GridTestClockTimer.timeSupplier(GridTestClockTimer.DFLT_TIME_SUPPLIER); + } + } + + /** */ + @Test + public void testPagesTimestampHistogramAfterPartitionEviction() throws Exception { + int keysCnt = 50_000; + + String regionName = "default"; + + DataStorageConfiguration dsCfg = new DataStorageConfiguration().setDefaultDataRegionConfiguration( + new DataRegionConfiguration() + .setMaxSize(50L * 1024 * 1024) + .setPersistenceEnabled(true) + .setName(regionName) + .setMetricsEnabled(true) + ); + + cleanPersistenceDir(); + + try (IgniteEx ignite = startGrid(getConfiguration().setDataStorageConfiguration(dsCfg))) { + ignite.cluster().state(ClusterState.ACTIVE); + + IgniteCache cache = ignite.createCache(new CacheConfiguration<>("test-pages-ts") + .setBackups(1).setAffinity(new RendezvousAffinityFunction(false, 10))); + + try (IgniteDataStreamer streamer = ignite.dataStreamer("test-pages-ts")) { + for (int i = 0; i < keysCnt; i++) + streamer.addData(i, new byte[1000]); + } + + startGrid(getConfiguration(getTestIgniteInstanceName(1)).setDataStorageConfiguration(dsCfg)); + startGrid(getConfiguration(getTestIgniteInstanceName(2)).setDataStorageConfiguration(dsCfg)); + + resetBaselineTopology(); + + awaitPartitionMapExchange(true, true, null); + + // Force checkpoint to invalidate evicted partitions. + forceCheckpoint(ignite); + + // Check histogram after partition eviction. + SystemView pagesTsHistogram = + ignite.context().systemView().view(PAGE_TS_HISTOGRAM_VIEW); + + assertEquals(ignite.dataRegionMetrics(regionName).getPhysicalMemoryPages(), + F.sumInt(F.iterator(pagesTsHistogram, v -> (int)v.pagesCount(), true))); + + stopGrid(2); + + resetBaselineTopology(); + + // Wait until rebalance complete. + assertTrue(GridTestUtils.waitForCondition(() -> ignite.context().discovery().topologyVersionEx() + .minorTopologyVersion() >= 2, 5_000L)); + + // Check histogram after rebalance. + assertEquals(ignite.dataRegionMetrics(regionName).getPhysicalMemoryPages(), + F.sumInt(F.iterator(pagesTsHistogram, v -> (int)v.pagesCount(), true))); + + stopGrid(1); + + resetBaselineTopology(); + + // Allocate some pages after eviction. + for (int i = 0; i < 10_000; i++) + cache.put(i + keysCnt, new byte[1024]); + + // Acquire some outdated pages. + for (int i = 0; i < keysCnt + 10_000; i++) + assertNotNull(cache.get(i)); + + // Check histogram after replacement of outdated pages. + assertEquals(ignite.dataRegionMetrics(regionName).getPhysicalMemoryPages(), + F.sumInt(F.iterator(pagesTsHistogram, v -> (int)v.pagesCount(), true))); + } + finally { + stopAllGrids(); + } + } +} diff --git a/modules/core/src/test/java/org/apache/ignite/internal/metric/SystemViewPluginTest.java b/modules/core/src/test/java/org/apache/ignite/internal/metric/SystemViewPluginTest.java new file mode 100644 index 0000000000000..7732c5f228834 --- /dev/null +++ b/modules/core/src/test/java/org/apache/ignite/internal/metric/SystemViewPluginTest.java @@ -0,0 +1,76 @@ +/* + * 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.metric; + +import java.util.stream.StreamSupport; +import org.apache.ignite.internal.IgniteEx; +import org.apache.ignite.plugin.AbstractTestPluginProvider; +import org.apache.ignite.plugin.IgnitePlugin; +import org.apache.ignite.spi.systemview.view.PluginView; +import org.apache.ignite.spi.systemview.view.SystemView; +import org.junit.Test; + +import static org.apache.ignite.internal.processors.plugin.IgnitePluginProcessor.PLUGINS_SYS_VIEW; + +/** Tests for {@link SystemView} for plugins. */ +public class SystemViewPluginTest extends SystemViewAbstractTest { + /** */ + @Test + public void testPluginView() throws Exception { + try (IgniteEx n = startGrid(getConfiguration().setPluginProviders(new TestPluginProvider()))) { + SystemView view = n.context().systemView().view(PLUGINS_SYS_VIEW); + + PluginView testPluginView = StreamSupport.stream(view.spliterator(), false) + .filter(v -> "FOR_SYS_VIEW_PLUGIN_NAME".equals(v.name())) + .findFirst() + .orElseThrow(() -> new AssertionError("Plugin not found")); + + assertEquals("FOR_SYS_VIEW_PLUGIN_NAME", testPluginView.name()); + assertEquals("FOR_SYS_VIEW_PLUGIN_INFO", testPluginView.info()); + assertEquals("42", testPluginView.version()); + assertEquals(TestPluginProvider.TestPlugin.class.getName(), testPluginView.className()); + } + } + + /** */ + private static class TestPluginProvider extends AbstractTestPluginProvider { + /** {@inheritDoc} */ + @Override public String name() { + return "FOR_SYS_VIEW_PLUGIN_NAME"; + } + + /** {@inheritDoc} */ + @Override public String version() { + return "42"; + } + + /** {@inheritDoc} */ + @Override public String info() { + return "FOR_SYS_VIEW_PLUGIN_INFO"; + } + + /** {@inheritDoc} */ + @Override public T plugin() { + return (T)new TestPlugin(); + } + + /** */ + private static class TestPlugin implements IgnitePlugin { + } + } +} diff --git a/modules/core/src/test/java/org/apache/ignite/internal/metric/SystemViewQueriesTest.java b/modules/core/src/test/java/org/apache/ignite/internal/metric/SystemViewQueriesTest.java new file mode 100644 index 0000000000000..b444e8bb5780b --- /dev/null +++ b/modules/core/src/test/java/org/apache/ignite/internal/metric/SystemViewQueriesTest.java @@ -0,0 +1,312 @@ +/* + * 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.metric; + +import java.util.List; +import java.util.function.Consumer; +import javax.cache.Cache; +import org.apache.ignite.IgniteCache; +import org.apache.ignite.cache.query.ContinuousQuery; +import org.apache.ignite.cache.query.QueryCursor; +import org.apache.ignite.cache.query.ScanQuery; +import org.apache.ignite.configuration.CacheConfiguration; +import org.apache.ignite.internal.IgniteEx; +import org.apache.ignite.lang.IgniteBiPredicate; +import org.apache.ignite.lang.IgniteClosure; +import org.apache.ignite.spi.systemview.view.ContinuousQueryView; +import org.apache.ignite.spi.systemview.view.ScanQueryView; +import org.apache.ignite.spi.systemview.view.SystemView; +import org.junit.Test; + +import static org.apache.ignite.internal.managers.systemview.ScanQuerySystemView.SCAN_QRY_SYS_VIEW; +import static org.apache.ignite.internal.processors.cache.GridCacheUtils.cacheGroupId; +import static org.apache.ignite.internal.processors.cache.GridCacheUtils.cacheId; +import static org.apache.ignite.internal.processors.continuous.GridContinuousProcessor.CQ_SYS_VIEW; +import static org.apache.ignite.internal.util.IgniteUtils.toStringSafe; +import static org.apache.ignite.testframework.GridTestUtils.waitForCondition; + +/** Tests for {@link SystemView} for queries. */ +public class SystemViewQueriesTest extends SystemViewAbstractTest { + /** */ + public static final String TEST_PREDICATE = "TestPredicate"; + + /** */ + public static final String TEST_TRANSFORMER = "TestTransformer"; + + /** Tests work of {@link SystemView} for continuous queries. */ + @Test + public void testContinuousQuery() throws Exception { + try (IgniteEx originNode = startGrid(0); IgniteEx remoteNode = startGrid(1)) { + IgniteCache cache = originNode.createCache("cache-1"); + + SystemView origQrys = originNode.context().systemView().view(CQ_SYS_VIEW); + SystemView remoteQrys = remoteNode.context().systemView().view(CQ_SYS_VIEW); + + assertEquals(0, origQrys.size()); + assertEquals(0, remoteQrys.size()); + + try (QueryCursor qry = cache.query(new ContinuousQuery<>() + .setInitialQuery(new ScanQuery<>()) + .setPageSize(100) + .setTimeInterval(1000) + .setLocalListener(evts -> { + // No-op. + }) + .setRemoteFilterFactory(() -> evt -> true) + )) { + for (int i = 0; i < 100; i++) + cache.put(i, i); + + checkContinuousQueryView(originNode, origQrys, true); + checkContinuousQueryView(originNode, remoteQrys, false); + } + + assertEquals(0, origQrys.size()); + assertTrue(waitForCondition(() -> remoteQrys.size() == 0, getTestTimeout())); + } + } + + /** */ + private void checkContinuousQueryView(IgniteEx g, SystemView qrys, boolean loc) { + assertEquals(1, qrys.size()); + + for (ContinuousQueryView cq : qrys) { + assertEquals("cache-1", cq.cacheName()); + assertEquals(100, cq.bufferSize()); + assertEquals(1000, cq.interval()); + assertEquals(g.localNode().id(), cq.nodeId()); + + if (loc) + assertTrue(cq.localListener().startsWith(getClass().getName())); + else + assertNull(cq.localListener()); + + assertTrue(cq.remoteFilter().startsWith(getClass().getName())); + assertNull(cq.localTransformedListener()); + assertNull(cq.remoteTransformer()); + } + } + + /** Tests work of {@link SystemView} for local scan queries. */ + @Test + public void testLocalScanQuery() throws Exception { + try (IgniteEx g0 = startGrid(0)) { + IgniteCache cache1 = g0.createCache( + new CacheConfiguration("cache1") + .setGroupName("group1")); + + int part = g0.affinity("cache1").primaryPartitions(g0.localNode())[0]; + + List partKeys = partitionKeys(cache1, part, 11, 0); + + for (Integer key : partKeys) + cache1.put(key, key); + + SystemView qrySysView0 = g0.context().systemView().view(SCAN_QRY_SYS_VIEW); + + assertNotNull(qrySysView0); + + assertEquals(0, qrySysView0.size()); + + QueryCursor qryRes1 = cache1.query( + new ScanQuery() + .setFilter(new TestPredicate()) + .setLocal(true) + .setPartition(part) + .setPageSize(10), + new TestTransformer()); + + assertTrue(qryRes1.iterator().hasNext()); + + boolean res = waitForCondition(() -> qrySysView0.size() > 0, 5_000); + + assertTrue(res); + + ScanQueryView view = qrySysView0.iterator().next(); + + assertEquals(g0.localNode().id(), view.originNodeId()); + assertEquals(0, view.queryId()); + assertEquals("cache1", view.cacheName()); + assertEquals(cacheId("cache1"), view.cacheId()); + assertEquals(cacheGroupId("cache1", "group1"), view.cacheGroupId()); + assertEquals("group1", view.cacheGroupName()); + assertTrue(view.startTime() <= System.currentTimeMillis()); + assertTrue(view.duration() >= 0); + assertFalse(view.canceled()); + assertEquals(TEST_PREDICATE, view.filter()); + assertTrue(view.local()); + assertEquals(part, view.partition()); + assertEquals(toStringSafe(g0.context().discovery().topologyVersionEx()), view.topology()); + assertEquals(TEST_TRANSFORMER, view.transformer()); + assertFalse(view.keepBinary()); + assertNull(view.subjectId()); + assertNull(view.taskName()); + + qryRes1.close(); + + res = waitForCondition(() -> qrySysView0.size() == 0, 5_000); + + assertTrue(res); + } + } + + /** Tests work of {@link SystemView} for scan queries. */ + @Test + public void testScanQuery() throws Exception { + try (IgniteEx g0 = startGrid(0); + IgniteEx g1 = startGrid(1); + IgniteEx client1 = startClientGrid("client-1"); + IgniteEx client2 = startClientGrid("client-2")) { + + IgniteCache cache1 = client1.createCache( + new CacheConfiguration("cache1") + .setGroupName("group1")); + + IgniteCache cache2 = client2.createCache("cache2"); + + for (int i = 0; i < 100; i++) { + cache1.put(i, i); + cache2.put(i, i); + } + + SystemView qrySysView0 = g0.context().systemView().view(SCAN_QRY_SYS_VIEW); + SystemView qrySysView1 = g1.context().systemView().view(SCAN_QRY_SYS_VIEW); + + assertNotNull(qrySysView0); + assertNotNull(qrySysView1); + + assertEquals(0, qrySysView0.size()); + assertEquals(0, qrySysView1.size()); + + QueryCursor qryRes1 = cache1.query( + new ScanQuery() + .setFilter(new TestPredicate()) + .setPageSize(10), + new TestTransformer()); + + QueryCursor qryRes2 = cache2.withKeepBinary().query(new ScanQuery<>() + .setPageSize(20)); + + assertTrue(qryRes1.iterator().hasNext()); + assertTrue(qryRes2.iterator().hasNext()); + + checkScanQueryView(client1, client2, qrySysView0); + checkScanQueryView(client1, client2, qrySysView1); + + qryRes1.close(); + qryRes2.close(); + + boolean res = waitForCondition( + () -> qrySysView0.size() + qrySysView1.size() == 0, 5_000); + + assertTrue(res); + } + } + + /** */ + private void checkScanQueryView(IgniteEx client1, IgniteEx client2, SystemView qrySysView) + throws Exception { + boolean res = waitForCondition(() -> qrySysView.size() > 1, 5_000); + + assertTrue(res); + + Consumer cache1checker = view -> { + assertEquals(client1.localNode().id(), view.originNodeId()); + assertTrue(view.queryId() != 0); + assertEquals("cache1", view.cacheName()); + assertEquals(cacheId("cache1"), view.cacheId()); + assertEquals(cacheGroupId("cache1", "group1"), view.cacheGroupId()); + assertEquals("group1", view.cacheGroupName()); + assertTrue(view.startTime() <= System.currentTimeMillis()); + assertTrue(view.duration() >= 0); + assertFalse(view.canceled()); + assertEquals(TEST_PREDICATE, view.filter()); + assertFalse(view.local()); + assertEquals(-1, view.partition()); + assertEquals(toStringSafe(client1.context().discovery().topologyVersionEx()), view.topology()); + assertEquals(TEST_TRANSFORMER, view.transformer()); + assertFalse(view.keepBinary()); + assertNull(view.subjectId()); + assertNull(view.taskName()); + assertEquals(10, view.pageSize()); + }; + + Consumer cache2checker = view -> { + assertEquals(client2.localNode().id(), view.originNodeId()); + assertTrue(view.queryId() != 0); + assertEquals("cache2", view.cacheName()); + assertEquals(cacheId("cache2"), view.cacheId()); + assertEquals(cacheGroupId("cache2", null), view.cacheGroupId()); + assertEquals("cache2", view.cacheGroupName()); + assertTrue(view.startTime() <= System.currentTimeMillis()); + assertTrue(view.duration() >= 0); + assertFalse(view.canceled()); + assertNull(view.filter()); + assertFalse(view.local()); + assertEquals(-1, view.partition()); + assertEquals(toStringSafe(client2.context().discovery().topologyVersionEx()), view.topology()); + assertNull(view.transformer()); + assertTrue(view.keepBinary()); + assertNull(view.subjectId()); + assertNull(view.taskName()); + assertEquals(20, view.pageSize()); + }; + + boolean found1 = false; + boolean found2 = false; + + for (ScanQueryView view : qrySysView) { + if ("cache2".equals(view.cacheName())) { + cache2checker.accept(view); + found1 = true; + } + else { + cache1checker.accept(view); + found2 = true; + } + } + + assertTrue(found1 && found2); + } + + /** Test predicate. */ + public static class TestPredicate implements IgniteBiPredicate { + /** {@inheritDoc} */ + @Override public boolean apply(Integer integer, Integer integer2) { + return true; + } + + /** {@inheritDoc} */ + @Override public String toString() { + return TEST_PREDICATE; + } + } + + /** Test transformer. */ + public static class TestTransformer implements IgniteClosure, Integer> { + /** {@inheritDoc} */ + @Override public Integer apply(Cache.Entry entry) { + return entry.getKey(); + } + + /** {@inheritDoc} */ + @Override public String toString() { + return TEST_TRANSFORMER; + } + } +} diff --git a/modules/core/src/test/java/org/apache/ignite/internal/metric/SystemViewSelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/metric/SystemViewSelfTest.java deleted file mode 100644 index c8d08036d4a8e..0000000000000 --- a/modules/core/src/test/java/org/apache/ignite/internal/metric/SystemViewSelfTest.java +++ /dev/null @@ -1,2754 +0,0 @@ -/* - * 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.metric; - -import java.lang.reflect.Field; -import java.sql.Connection; -import java.util.Arrays; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Properties; -import java.util.Set; -import java.util.concurrent.BrokenBarrierException; -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.CyclicBarrier; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicInteger; -import java.util.concurrent.atomic.AtomicLong; -import java.util.function.Consumer; -import java.util.function.Function; -import java.util.stream.Collectors; -import java.util.stream.StreamSupport; -import javax.cache.Cache; -import javax.cache.expiry.CreatedExpiryPolicy; -import javax.cache.expiry.Duration; -import javax.cache.expiry.EternalExpiryPolicy; -import javax.cache.expiry.ModifiedExpiryPolicy; -import com.google.common.collect.Lists; -import org.apache.ignite.IgniteAtomicLong; -import org.apache.ignite.IgniteAtomicReference; -import org.apache.ignite.IgniteAtomicSequence; -import org.apache.ignite.IgniteAtomicStamped; -import org.apache.ignite.IgniteCache; -import org.apache.ignite.IgniteCompute; -import org.apache.ignite.IgniteCountDownLatch; -import org.apache.ignite.IgniteDataStreamer; -import org.apache.ignite.IgniteException; -import org.apache.ignite.IgniteJdbcThinDriver; -import org.apache.ignite.IgniteLock; -import org.apache.ignite.IgniteQueue; -import org.apache.ignite.IgniteSemaphore; -import org.apache.ignite.IgniteSet; -import org.apache.ignite.Ignition; -import org.apache.ignite.cache.CacheAtomicityMode; -import org.apache.ignite.cache.affinity.rendezvous.RendezvousAffinityFunction; -import org.apache.ignite.cache.query.ContinuousQuery; -import org.apache.ignite.cache.query.QueryCursor; -import org.apache.ignite.cache.query.ScanQuery; -import org.apache.ignite.client.Config; -import org.apache.ignite.client.IgniteClient; -import org.apache.ignite.cluster.ClusterNode; -import org.apache.ignite.cluster.ClusterState; -import org.apache.ignite.compute.ComputeJob; -import org.apache.ignite.compute.ComputeJobResult; -import org.apache.ignite.compute.ComputeJobResultPolicy; -import org.apache.ignite.compute.ComputeTask; -import org.apache.ignite.configuration.AtomicConfiguration; -import org.apache.ignite.configuration.CacheConfiguration; -import org.apache.ignite.configuration.ClientConfiguration; -import org.apache.ignite.configuration.CollectionConfiguration; -import org.apache.ignite.configuration.DataRegionConfiguration; -import org.apache.ignite.configuration.DataStorageConfiguration; -import org.apache.ignite.configuration.IgniteConfiguration; -import org.apache.ignite.internal.IgniteEx; -import org.apache.ignite.internal.IgniteInternalFuture; -import org.apache.ignite.internal.binary.mutabletest.GridBinaryTestClasses.TestObjectAllTypes; -import org.apache.ignite.internal.binary.mutabletest.GridBinaryTestClasses.TestObjectEnum; -import org.apache.ignite.internal.client.thin.ProtocolVersion; -import org.apache.ignite.internal.processors.cache.persistence.GridCacheDatabaseSharedManager; -import org.apache.ignite.internal.processors.cache.persistence.IgniteCacheDatabaseSharedManager; -import org.apache.ignite.internal.processors.cache.persistence.freelist.PagesList; -import org.apache.ignite.internal.processors.metastorage.DistributedMetaStorage; -import org.apache.ignite.internal.processors.metric.impl.PeriodicHistogramMetricImpl; -import org.apache.ignite.internal.processors.odbc.jdbc.JdbcConnectionContext; -import org.apache.ignite.internal.processors.service.DummyService; -import org.apache.ignite.internal.processors.task.GridInternal; -import org.apache.ignite.internal.systemview.BaselineNodeAttributeViewWalker; -import org.apache.ignite.internal.systemview.CachePagesListViewWalker; -import org.apache.ignite.internal.systemview.ClientConnectionAttributeViewWalker; -import org.apache.ignite.internal.systemview.MetastorageViewWalker; -import org.apache.ignite.internal.systemview.NodeAttributeViewWalker; -import org.apache.ignite.internal.thread.pool.IgniteStripedExecutor; -import org.apache.ignite.internal.util.GridTestClockTimer; -import org.apache.ignite.internal.util.typedef.F; -import org.apache.ignite.internal.util.typedef.T2; -import org.apache.ignite.internal.util.typedef.internal.CU; -import org.apache.ignite.internal.util.typedef.internal.U; -import org.apache.ignite.lang.IgniteBiPredicate; -import org.apache.ignite.lang.IgniteCallable; -import org.apache.ignite.lang.IgniteClosure; -import org.apache.ignite.lang.IgnitePredicate; -import org.apache.ignite.lang.IgniteRunnable; -import org.apache.ignite.lang.IgniteUuid; -import org.apache.ignite.plugin.AbstractTestPluginProvider; -import org.apache.ignite.plugin.IgnitePlugin; -import org.apache.ignite.services.ServiceConfiguration; -import org.apache.ignite.spi.systemview.view.BaselineNodeAttributeView; -import org.apache.ignite.spi.systemview.view.BaselineNodeView; -import org.apache.ignite.spi.systemview.view.BinaryMetadataView; -import org.apache.ignite.spi.systemview.view.CacheGroupIoView; -import org.apache.ignite.spi.systemview.view.CacheGroupView; -import org.apache.ignite.spi.systemview.view.CachePagesListView; -import org.apache.ignite.spi.systemview.view.CacheView; -import org.apache.ignite.spi.systemview.view.ClientConnectionAttributeView; -import org.apache.ignite.spi.systemview.view.ClientConnectionView; -import org.apache.ignite.spi.systemview.view.ClusterNodeView; -import org.apache.ignite.spi.systemview.view.ComputeJobView; -import org.apache.ignite.spi.systemview.view.ComputeTaskView; -import org.apache.ignite.spi.systemview.view.ConfigurationView; -import org.apache.ignite.spi.systemview.view.ContinuousQueryView; -import org.apache.ignite.spi.systemview.view.FiltrableSystemView; -import org.apache.ignite.spi.systemview.view.MetastorageView; -import org.apache.ignite.spi.systemview.view.NodeAttributeView; -import org.apache.ignite.spi.systemview.view.NodeMetricsView; -import org.apache.ignite.spi.systemview.view.PagesListView; -import org.apache.ignite.spi.systemview.view.PagesTimestampHistogramView; -import org.apache.ignite.spi.systemview.view.PluginView; -import org.apache.ignite.spi.systemview.view.ScanQueryView; -import org.apache.ignite.spi.systemview.view.ServiceView; -import org.apache.ignite.spi.systemview.view.SnapshotView; -import org.apache.ignite.spi.systemview.view.StripedExecutorTaskView; -import org.apache.ignite.spi.systemview.view.SystemView; -import org.apache.ignite.spi.systemview.view.TransactionView; -import org.apache.ignite.spi.systemview.view.datastructures.AtomicLongView; -import org.apache.ignite.spi.systemview.view.datastructures.AtomicReferenceView; -import org.apache.ignite.spi.systemview.view.datastructures.AtomicSequenceView; -import org.apache.ignite.spi.systemview.view.datastructures.AtomicStampedView; -import org.apache.ignite.spi.systemview.view.datastructures.CountDownLatchView; -import org.apache.ignite.spi.systemview.view.datastructures.QueueView; -import org.apache.ignite.spi.systemview.view.datastructures.ReentrantLockView; -import org.apache.ignite.spi.systemview.view.datastructures.SemaphoreView; -import org.apache.ignite.spi.systemview.view.datastructures.SetView; -import org.apache.ignite.testframework.GridTestUtils; -import org.apache.ignite.testframework.junits.WithSystemProperty; -import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest; -import org.apache.ignite.transactions.Transaction; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; -import org.junit.Test; - -import static org.apache.ignite.IgniteSystemProperties.IGNITE_DATA_CENTER_ID; -import static org.apache.ignite.configuration.AtomicConfiguration.DFLT_ATOMIC_SEQUENCE_RESERVE_SIZE; -import static org.apache.ignite.events.EventType.EVT_CONSISTENCY_VIOLATION; -import static org.apache.ignite.internal.IgniteKernal.CFG_VIEW; -import static org.apache.ignite.internal.managers.discovery.GridDiscoveryManager.NODES_SYS_VIEW; -import static org.apache.ignite.internal.managers.discovery.GridDiscoveryManager.NODE_ATTRIBUTES_SYS_VIEW; -import static org.apache.ignite.internal.managers.discovery.GridDiscoveryManager.NODE_METRICS_SYS_VIEW; -import static org.apache.ignite.internal.managers.systemview.ScanQuerySystemView.SCAN_QRY_SYS_VIEW; -import static org.apache.ignite.internal.processors.cache.ClusterCachesInfo.CACHES_VIEW; -import static org.apache.ignite.internal.processors.cache.ClusterCachesInfo.CACHE_GRPS_VIEW; -import static org.apache.ignite.internal.processors.cache.GridCacheProcessor.CACHE_GRP_IO_VIEW; -import static org.apache.ignite.internal.processors.cache.GridCacheProcessor.CACHE_GRP_PAGE_LIST_VIEW; -import static org.apache.ignite.internal.processors.cache.GridCacheUtils.cacheGroupId; -import static org.apache.ignite.internal.processors.cache.GridCacheUtils.cacheId; -import static org.apache.ignite.internal.processors.cache.binary.CacheObjectBinaryProcessorImpl.BINARY_METADATA_VIEW; -import static org.apache.ignite.internal.processors.cache.persistence.DataStorageMetricsImpl.DATASTORAGE_METRIC_PREFIX; -import static org.apache.ignite.internal.processors.cache.persistence.GridCacheDatabaseSharedManager.METASTORE_VIEW; -import static org.apache.ignite.internal.processors.cache.persistence.IgniteCacheDatabaseSharedManager.DATA_REGION_PAGE_LIST_VIEW; -import static org.apache.ignite.internal.processors.cache.persistence.IgniteCacheDatabaseSharedManager.PAGE_TS_HISTOGRAM_VIEW; -import static org.apache.ignite.internal.processors.cache.persistence.metastorage.MetaStorage.METASTORAGE_CACHE_NAME; -import static org.apache.ignite.internal.processors.cache.transactions.IgniteTxManager.TXS_MON_LIST; -import static org.apache.ignite.internal.processors.cluster.GridClusterStateProcessor.BASELINE_NODES_SYS_VIEW; -import static org.apache.ignite.internal.processors.cluster.GridClusterStateProcessor.BASELINE_NODE_ATTRIBUTES_SYS_VIEW; -import static org.apache.ignite.internal.processors.continuous.GridContinuousProcessor.CQ_SYS_VIEW; -import static org.apache.ignite.internal.processors.datastructures.DataStructuresProcessor.DEFAULT_DS_GROUP_NAME; -import static org.apache.ignite.internal.processors.datastructures.DataStructuresProcessor.DEFAULT_VOLATILE_DS_GROUP_NAME; -import static org.apache.ignite.internal.processors.datastructures.DataStructuresProcessor.LATCHES_VIEW; -import static org.apache.ignite.internal.processors.datastructures.DataStructuresProcessor.LOCKS_VIEW; -import static org.apache.ignite.internal.processors.datastructures.DataStructuresProcessor.LONGS_VIEW; -import static org.apache.ignite.internal.processors.datastructures.DataStructuresProcessor.QUEUES_VIEW; -import static org.apache.ignite.internal.processors.datastructures.DataStructuresProcessor.REFERENCES_VIEW; -import static org.apache.ignite.internal.processors.datastructures.DataStructuresProcessor.SEMAPHORES_VIEW; -import static org.apache.ignite.internal.processors.datastructures.DataStructuresProcessor.SEQUENCES_VIEW; -import static org.apache.ignite.internal.processors.datastructures.DataStructuresProcessor.SETS_VIEW; -import static org.apache.ignite.internal.processors.datastructures.DataStructuresProcessor.STAMPED_VIEW; -import static org.apache.ignite.internal.processors.datastructures.DataStructuresProcessor.VOLATILE_DATA_REGION_NAME; -import static org.apache.ignite.internal.processors.job.GridJobProcessor.JOBS_VIEW; -import static org.apache.ignite.internal.processors.metastorage.persistence.DistributedMetaStorageImpl.DISTRIBUTED_METASTORE_VIEW; -import static org.apache.ignite.internal.processors.metric.impl.MetricUtils.metricName; -import static org.apache.ignite.internal.processors.odbc.ClientListenerProcessor.CLI_CONN_ATTR_VIEW; -import static org.apache.ignite.internal.processors.odbc.ClientListenerProcessor.CLI_CONN_VIEW; -import static org.apache.ignite.internal.processors.plugin.IgnitePluginProcessor.PLUGINS_SYS_VIEW; -import static org.apache.ignite.internal.processors.pool.PoolProcessor.STREAM_POOL_QUEUE_VIEW; -import static org.apache.ignite.internal.processors.pool.PoolProcessor.SYS_POOL_QUEUE_VIEW; -import static org.apache.ignite.internal.processors.service.IgniteServiceProcessor.SVCS_VIEW; -import static org.apache.ignite.internal.processors.task.GridTaskProcessor.TASKS_VIEW; -import static org.apache.ignite.internal.util.IgniteUtils.MB; -import static org.apache.ignite.internal.util.IgniteUtils.toStringSafe; -import static org.apache.ignite.internal.util.lang.GridFunc.alwaysTrue; -import static org.apache.ignite.internal.util.lang.GridFunc.identity; -import static org.apache.ignite.spi.systemview.view.SnapshotView.SNAPSHOT_SYS_VIEW; -import static org.apache.ignite.testframework.GridTestUtils.runAsync; -import static org.apache.ignite.testframework.GridTestUtils.waitForCondition; -import static org.apache.ignite.transactions.TransactionConcurrency.OPTIMISTIC; -import static org.apache.ignite.transactions.TransactionConcurrency.PESSIMISTIC; -import static org.apache.ignite.transactions.TransactionIsolation.REPEATABLE_READ; -import static org.apache.ignite.transactions.TransactionIsolation.SERIALIZABLE; -import static org.apache.ignite.transactions.TransactionState.ACTIVE; - -/** Tests for {@link SystemView}. */ -public class SystemViewSelfTest extends GridCommonAbstractTest { - /** */ - public static final String TEST_PREDICATE = "TestPredicate"; - - /** */ - public static final String TEST_TRANSFORMER = "TestTransformer"; - - /** */ - private static CountDownLatch jobStartedLatch; - - /** */ - private static CountDownLatch releaseJobLatch; - - /** {@inheritDoc} */ - @Override protected void beforeTestsStarted() throws Exception { - super.beforeTestsStarted(); - - cleanPersistenceDir(); - } - - /** {@inheritDoc} */ - @Override protected void afterTestsStopped() throws Exception { - super.afterTestsStopped(); - - cleanPersistenceDir(); - } - - /** Tests work of {@link SystemView} for caches. */ - @Test - public void testCachesView() throws Exception { - try (IgniteEx g = startGrid()) { - Set cacheNames = new HashSet<>(Arrays.asList("cache-1", "cache-2")); - - for (String name : cacheNames) - g.createCache(name); - - SystemView caches = g.context().systemView().view(CACHES_VIEW); - - assertEquals(g.context().cache().cacheDescriptors().size(), F.size(caches.iterator())); - - for (CacheView row : caches) - cacheNames.remove(row.cacheName()); - - assertTrue(cacheNames.toString(), cacheNames.isEmpty()); - } - } - - /** Tests work of {@link SystemView} for cache groups. */ - @Test - public void testCacheGroupsView() throws Exception { - try (IgniteEx g = startGrid()) { - Set grpNames = new HashSet<>(Arrays.asList("grp-1", "grp-2")); - - for (String grpName : grpNames) - g.createCache(new CacheConfiguration<>("cache-" + grpName).setGroupName(grpName)); - - SystemView grps = g.context().systemView().view(CACHE_GRPS_VIEW); - - assertEquals(g.context().cache().cacheGroupDescriptors().size(), F.size(grps.iterator())); - - for (CacheGroupView row : grps) - grpNames.remove(row.cacheGroupName()); - - assertTrue(grpNames.toString(), grpNames.isEmpty()); - } - } - - /** Tests work of {@link SystemView} for cache expiry policy info with in-memory configuration. */ - @Test - public void testCacheViewExpiryPolicyWithInMemory() throws Exception { - testCacheViewExpiryPolicy(false); - } - - /** Tests work of {@link SystemView} for cache expiry policy info with persist configuration. */ - @Test - public void testCacheViewExpiryPolicyWithPersist() throws Exception { - testCacheViewExpiryPolicy(true); - } - - /** Tests work of {@link SystemView} for cache groups expiry policy info. */ - private void testCacheViewExpiryPolicy(boolean withPersistence) throws Exception { - try (IgniteEx g = !withPersistence ? startGrid() : startGrid(getConfiguration().setDataStorageConfiguration( - new DataStorageConfiguration().setDefaultDataRegionConfiguration( - new DataRegionConfiguration().setPersistenceEnabled(true) - )))) { - - if (withPersistence) - g.cluster().state(ClusterState.ACTIVE); - - String eternalCacheName = "eternalCache"; - String createdCacheName = "createdCache"; - String eagerTtlCacheName = "eagerTtlCache"; - String withoutGrpCacheName = "withoutGrpCache"; - String dfltCacheName = "defaultCache"; - - CacheConfiguration eternalCache = new CacheConfiguration(eternalCacheName) - .setGroupName("group1") - .setExpiryPolicyFactory(EternalExpiryPolicy.factoryOf()); - - CacheConfiguration createdCache = new CacheConfiguration(createdCacheName) - .setGroupName("group2") - .setExpiryPolicyFactory(CreatedExpiryPolicy.factoryOf(new Duration(TimeUnit.MILLISECONDS, 500L))); - - CacheConfiguration eagerTtlCache = new CacheConfiguration(eagerTtlCacheName) - .setGroupName("group2") - .setEagerTtl(false) - .setExpiryPolicyFactory(CreatedExpiryPolicy.factoryOf(new Duration(TimeUnit.MILLISECONDS, 500L))); - - CacheConfiguration withoutGrpCache = new CacheConfiguration(withoutGrpCacheName) - .setExpiryPolicyFactory(CreatedExpiryPolicy.factoryOf(new Duration(TimeUnit.MILLISECONDS, 500L))); - - CacheConfiguration dfltCache = new CacheConfiguration(dfltCacheName) - .setGroupName("group3"); - - g.createCache(eternalCache); - g.createCache(createdCache); - g.createCache(eagerTtlCache); - g.createCache(withoutGrpCache); - g.createCache(dfltCache); - - SystemView caches = g.context().systemView().view(CACHES_VIEW); - - for (CacheView row : caches) { - switch (row.cacheName()) { - case "defaultCache": - case "eternalCache": - assertEquals("No", row.hasExpiringEntries()); - - g.cache(row.cacheName()).put(0, 0); - - assertEquals("No", row.hasExpiringEntries()); - - g.cache(row.cacheName()) - .withExpiryPolicy(new CreatedExpiryPolicy(new Duration(TimeUnit.MILLISECONDS, 200L))) - .put(1, 1); - - assertEquals("Yes", row.hasExpiringEntries()); - assertTrue(waitForCondition(() -> "No".equals(row.hasExpiringEntries()), getTestTimeout())); - - break; - - case "withoutGrpCache": - case "createdCache": - assertEquals("No", row.hasExpiringEntries()); - - g.cache(row.cacheName()).put(0, 0); - - assertEquals("Yes", row.hasExpiringEntries()); - assertTrue(waitForCondition(() -> "No".equals(row.hasExpiringEntries()), getTestTimeout())); - - g.cache(row.cacheName()) - .withExpiryPolicy(new ModifiedExpiryPolicy(new Duration(TimeUnit.MILLISECONDS, 200L))) - .put(1, 1); - - assertEquals("Yes", row.hasExpiringEntries()); - assertTrue(waitForCondition(() -> "No".equals(row.hasExpiringEntries()), getTestTimeout())); - - if (row.cacheName().equals(createdCacheName)) { - g.cache(eagerTtlCacheName).put(2, 2); - assertEquals("No", row.hasExpiringEntries()); - } - - break; - - case "eagerTtlCache": - assertEquals("Unknown", row.hasExpiringEntries()); - - break; - } - } - } - } - - /** Tests work of {@link SystemView} for services. */ - @Test - public void testServices() throws Exception { - try (IgniteEx g = startGrid()) { - { - ServiceConfiguration srvcCfg = new ServiceConfiguration(); - - srvcCfg.setName("service"); - srvcCfg.setMaxPerNodeCount(1); - srvcCfg.setService(new DummyService()); - srvcCfg.setNodeFilter(new TestNodeFilter()); - - g.services().deploy(srvcCfg); - - SystemView srvs = g.context().systemView().view(SVCS_VIEW); - - assertEquals(g.context().service().serviceDescriptors().size(), F.size(srvs.iterator())); - - ServiceView sview = srvs.iterator().next(); - - assertEquals(srvcCfg.getName(), sview.name()); - assertNotNull(sview.serviceId()); - assertEquals(DummyService.class, sview.serviceClass()); - assertEquals(srvcCfg.getMaxPerNodeCount(), sview.maxPerNodeCount()); - assertNull(sview.cacheName()); - assertNull(sview.affinityKey()); - assertEquals(TestNodeFilter.class, sview.nodeFilter()); - assertFalse(sview.staticallyConfigured()); - assertEquals(g.localNode().id(), sview.originNodeId()); - assertEquals(F.asMap(g.localNode().id(), 1), sview.topologySnapshot()); - } - - { - g.createCache("test-cache"); - - ServiceConfiguration srvcCfg = new ServiceConfiguration(); - - srvcCfg.setName("service-2"); - srvcCfg.setMaxPerNodeCount(2); - srvcCfg.setService(new DummyService()); - srvcCfg.setNodeFilter(new TestNodeFilter()); - srvcCfg.setCacheName("test-cache"); - srvcCfg.setAffinityKey(1L); - - g.services().deploy(srvcCfg); - - final ServiceView[] sview = {null}; - - g.context().systemView().view(SVCS_VIEW).forEach(sv -> { - if (sv.name().equals(srvcCfg.getName())) - sview[0] = sv; - }); - - assertEquals(srvcCfg.getName(), sview[0].name()); - assertNotNull(sview[0].serviceId()); - assertEquals(DummyService.class, sview[0].serviceClass()); - assertEquals(srvcCfg.getMaxPerNodeCount(), sview[0].maxPerNodeCount()); - assertEquals("test-cache", sview[0].cacheName()); - assertEquals("1", sview[0].affinityKey()); - assertEquals(TestNodeFilter.class, sview[0].nodeFilter()); - assertFalse(sview[0].staticallyConfigured()); - assertEquals(g.localNode().id(), sview[0].originNodeId()); - assertEquals(F.asMap(g.localNode().id(), 2), sview[0].topologySnapshot()); - } - } - } - - /** Tests work of {@link SystemView} for compute grid {@link IgniteCompute#broadcastAsync(IgniteRunnable)} call. */ - @Test - public void testComputeBroadcast() throws Exception { - CyclicBarrier barrier = new CyclicBarrier(6); - - try (IgniteEx g1 = startGrid(0)) { - SystemView tasks = g1.context().systemView().view(TASKS_VIEW); - - for (int i = 0; i < 5; i++) { - g1.compute().broadcastAsync(() -> { - try { - barrier.await(); - barrier.await(); - } - catch (InterruptedException | BrokenBarrierException e) { - throw new RuntimeException(e); - } - }); - } - - barrier.await(); - - assertEquals(5, tasks.size()); - - ComputeTaskView t = tasks.iterator().next(); - - assertFalse(t.internal()); - assertNull(t.affinityCacheName()); - assertEquals(-1, t.affinityPartitionId()); - assertTrue(t.taskClassName().startsWith(getClass().getName())); - assertTrue(t.taskName().startsWith(getClass().getName())); - assertEquals(g1.localNode().id(), t.taskNodeId()); - assertEquals("0", t.userVersion()); - - barrier.await(); - } - } - - /** Tests work of {@link SystemView} for compute grid {@link IgniteCompute#runAsync(IgniteRunnable)} call. */ - @Test - public void testComputeRunnable() throws Exception { - CyclicBarrier barrier = new CyclicBarrier(2); - - try (IgniteEx g1 = startGrid(0)) { - SystemView tasks = g1.context().systemView().view(TASKS_VIEW); - - g1.compute().runAsync(() -> { - try { - barrier.await(); - barrier.await(); - } - catch (InterruptedException | BrokenBarrierException e) { - throw new RuntimeException(e); - } - }); - - barrier.await(); - - assertEquals(1, tasks.size()); - - ComputeTaskView t = tasks.iterator().next(); - - assertFalse(t.internal()); - assertNull(t.affinityCacheName()); - assertEquals(-1, t.affinityPartitionId()); - assertTrue(t.taskClassName().startsWith(getClass().getName())); - assertTrue(t.taskName().startsWith(getClass().getName())); - assertEquals(g1.localNode().id(), t.taskNodeId()); - assertEquals("0", t.userVersion()); - - barrier.await(); - } - } - - /** Tests work of {@link SystemView} for compute grid {@link IgniteCompute#apply(IgniteClosure, Object)} call. */ - @Test - public void testComputeApply() throws Exception { - CyclicBarrier barrier = new CyclicBarrier(2); - - try (IgniteEx g1 = startGrid(0)) { - SystemView tasks = g1.context().systemView().view(TASKS_VIEW); - - GridTestUtils.runAsync(() -> { - g1.compute().apply(x -> { - try { - barrier.await(); - barrier.await(); - } - catch (InterruptedException | BrokenBarrierException e) { - throw new RuntimeException(e); - } - - return 0; - }, 1); - }); - - barrier.await(); - - assertEquals(1, tasks.size()); - - ComputeTaskView t = tasks.iterator().next(); - - assertFalse(t.internal()); - assertNull(t.affinityCacheName()); - assertEquals(-1, t.affinityPartitionId()); - assertTrue(t.taskClassName().startsWith(getClass().getName())); - assertTrue(t.taskName().startsWith(getClass().getName())); - assertEquals(g1.localNode().id(), t.taskNodeId()); - assertEquals("0", t.userVersion()); - - barrier.await(); - } - } - - /** - * Tests work of {@link SystemView} for compute grid - * {@link IgniteCompute#affinityCallAsync(String, Object, IgniteCallable)} call. - */ - @Test - public void testComputeAffinityCall() throws Exception { - CyclicBarrier barrier = new CyclicBarrier(2); - - try (IgniteEx g1 = startGrid(0)) { - SystemView tasks = g1.context().systemView().view(TASKS_VIEW); - - IgniteCache cache = g1.createCache("test-cache"); - - cache.put(1, 1); - - g1.compute().affinityCallAsync("test-cache", 1, () -> { - try { - barrier.await(); - barrier.await(); - } - catch (InterruptedException e) { - throw new RuntimeException(e); - } - - return 0; - }); - - barrier.await(); - - assertEquals(1, tasks.size()); - - ComputeTaskView t = tasks.iterator().next(); - - assertFalse(t.internal()); - assertEquals("test-cache", t.affinityCacheName()); - assertEquals(1, t.affinityPartitionId()); - assertTrue(t.taskClassName().startsWith(getClass().getName())); - assertTrue(t.taskName().startsWith(getClass().getName())); - assertEquals(g1.localNode().id(), t.taskNodeId()); - assertEquals("0", t.userVersion()); - - barrier.await(); - } - } - - /** */ - @Test - public void testComputeTask() throws Exception { - doTestComputeTask(false); - } - - /** */ - @Test - public void testInternalComputeTask() throws Exception { - doTestComputeTask(true); - } - - /** */ - private void doTestComputeTask(boolean internal) throws Exception { - int gridCnt = 3; - - IgniteEx g1 = startGrids(gridCnt); - - try { - IgniteCache cache = g1.createCache("test-cache"); - - cache.put(1, 1); - - for (int i = 0; i < gridCnt; i++) { - IgniteEx grid = grid(i); - - SystemView tasks = grid.context().systemView().view(TASKS_VIEW); - - jobStartedLatch = new CountDownLatch(3); - releaseJobLatch = new CountDownLatch(1); - - IgniteInternalFuture fut - = runAsync(() -> grid.compute().execute(internal ? new InternalTask() : new UserTask(), 1)); - - assertTrue(jobStartedLatch.await(30_000, TimeUnit.MILLISECONDS)); - - try { - assertEquals(1, tasks.size()); - - ComputeTaskView t = tasks.iterator().next(); - - assertEquals("Expecting to see " + (internal ? "internal" : "user") + " task", internal, t.internal()); - assertNull(t.affinityCacheName()); - assertEquals(-1, t.affinityPartitionId()); - assertTrue(t.taskClassName().startsWith(getClass().getName())); - assertTrue(t.taskName().startsWith(getClass().getName())); - assertEquals(grid.localNode().id(), t.taskNodeId()); - assertEquals("0", t.userVersion()); - - checkJobs(gridCnt, internal, t.sessionId()); - } - finally { - releaseJobLatch.countDown(); - } - - fut.get(getTestTimeout(), TimeUnit.MILLISECONDS); - } - } - finally { - stopAllGrids(); - } - } - - /** */ - private void checkJobs(int gridCnt, boolean internal, IgniteUuid sesId) { - for (int i = 0; i < gridCnt; i++) { - SystemView jobs = grid(i).context().systemView().view(JOBS_VIEW); - - assertTrue("Expecting to see " + (internal ? "internal" : "user") + " job", jobs.size() > 0); - - ComputeJobView job = jobs.iterator().next(); - - assertEquals(sesId, job.sessionId()); - assertEquals("Expecting to see " + (internal ? "internal" : "user") + " job", internal, job.isInternal()); - } - - releaseJobLatch.countDown(); - } - - /** */ - @Test - public void testClientsConnections() throws Exception { - try (IgniteEx g0 = startGrid(0)) { - String host = g0.configuration().getClientConnectorConfiguration().getHost(); - - if (host == null) - host = g0.configuration().getLocalHost(); - - int port = g0.configuration().getClientConnectorConfiguration().getPort(); - - SystemView conns = g0.context().systemView().view(CLI_CONN_VIEW); - - try (IgniteClient cli = Ignition.startClient(new ClientConfiguration().setAddresses(host + ":" + port))) { - assertEquals(1, conns.size()); - - ClientConnectionView cliConn = conns.iterator().next(); - - assertEquals("THIN", cliConn.type()); - assertEquals(cliConn.localAddress().getHostName(), cliConn.remoteAddress().getHostName()); - assertEquals(g0.configuration().getClientConnectorConfiguration().getPort(), - cliConn.localAddress().getPort()); - assertEquals(cliConn.version(), ProtocolVersion.LATEST_VER.toString()); - - try (Connection conn = - new IgniteJdbcThinDriver().connect("jdbc:ignite:thin://" + host, new Properties())) { - assertEquals(2, conns.size()); - assertEquals(1, F.size(jdbcConnectionsIterator(conns))); - - ClientConnectionView jdbcConn = jdbcConnectionsIterator(conns).next(); - - assertEquals("JDBC", jdbcConn.type()); - assertEquals(jdbcConn.localAddress().getHostName(), jdbcConn.remoteAddress().getHostName()); - assertEquals(g0.configuration().getClientConnectorConfiguration().getPort(), - jdbcConn.localAddress().getPort()); - assertEquals(jdbcConn.version(), JdbcConnectionContext.CURRENT_VER.asString()); - } - } - - boolean res = GridTestUtils.waitForCondition(() -> conns.size() == 0, 5_000); - - assertTrue(res); - } - } - - /** */ - @Test - public void testClientConnectionAttributes() throws Exception { - try (IgniteEx g0 = startGrid(0)) { - SystemView view = g0.context().systemView().view(CLI_CONN_ATTR_VIEW); - - try ( - IgniteClient cl1 = Ignition.startClient(new ClientConfiguration().setAddresses(Config.SERVER) - .setUserAttributes(F.asMap("attr1", "val1", "attr2", "val2"))); - IgniteClient cl2 = Ignition.startClient(new ClientConfiguration().setAddresses(Config.SERVER) - .setUserAttributes(F.asMap("attr1", "val2"))); - IgniteClient cl3 = Ignition.startClient(new ClientConfiguration().setAddresses(Config.SERVER)) - ) { - assertEquals(3, F.size(view.iterator())); - - assertEquals(1, F.size(view.iterator(), row -> - "attr1".equals(row.name()) && "val1".equals(row.value()))); - - // Test filtering. - assertTrue(view instanceof FiltrableSystemView); - - Iterator iter = ((FiltrableSystemView)view) - .iterator(F.asMap(ClientConnectionAttributeViewWalker.NAME_FILTER, "attr1")); - - assertEquals(2, F.size(iter)); - - iter = ((FiltrableSystemView)view).iterator( - F.asMap(ClientConnectionAttributeViewWalker.NAME_FILTER, "attr2")); - - assertTrue(iter.hasNext()); - - long connId = iter.next().connectionId(); - - assertFalse(iter.hasNext()); - - iter = ((FiltrableSystemView)view).iterator( - F.asMap(ClientConnectionAttributeViewWalker.CONNECTION_ID_FILTER, connId)); - - assertEquals(2, F.size(iter)); - } - } - } - - /** */ - @Test - public void testContinuousQuery() throws Exception { - try (IgniteEx originNode = startGrid(0); IgniteEx remoteNode = startGrid(1)) { - IgniteCache cache = originNode.createCache("cache-1"); - - SystemView origQrys = originNode.context().systemView().view(CQ_SYS_VIEW); - SystemView remoteQrys = remoteNode.context().systemView().view(CQ_SYS_VIEW); - - assertEquals(0, origQrys.size()); - assertEquals(0, remoteQrys.size()); - - try (QueryCursor qry = cache.query(new ContinuousQuery<>() - .setInitialQuery(new ScanQuery<>()) - .setPageSize(100) - .setTimeInterval(1000) - .setLocalListener(evts -> { - // No-op. - }) - .setRemoteFilterFactory(() -> evt -> true) - )) { - for (int i = 0; i < 100; i++) - cache.put(i, i); - - checkContinuousQueryView(originNode, origQrys, true); - checkContinuousQueryView(originNode, remoteQrys, false); - } - - assertEquals(0, origQrys.size()); - assertTrue(waitForCondition(() -> remoteQrys.size() == 0, getTestTimeout())); - } - } - - /** */ - private void checkContinuousQueryView(IgniteEx g, SystemView qrys, boolean loc) { - assertEquals(1, qrys.size()); - - for (ContinuousQueryView cq : qrys) { - assertEquals("cache-1", cq.cacheName()); - assertEquals(100, cq.bufferSize()); - assertEquals(1000, cq.interval()); - assertEquals(g.localNode().id(), cq.nodeId()); - - if (loc) - assertTrue(cq.localListener().startsWith(getClass().getName())); - else - assertNull(cq.localListener()); - - assertTrue(cq.remoteFilter().startsWith(getClass().getName())); - assertNull(cq.localTransformedListener()); - assertNull(cq.remoteTransformer()); - } - } - - /** */ - @Test - @WithSystemProperty(key = IGNITE_DATA_CENTER_ID, value = "DC0") - public void testNodes() throws Exception { - try (IgniteEx g1 = startGrid(0)) { - SystemView views = g1.context().systemView().view(NODES_SYS_VIEW); - - assertEquals(1, views.size()); - - try (IgniteEx g2 = startGrid(1)) { - awaitPartitionMapExchange(); - - checkViewsState(views, g1.localNode(), g2.localNode()); - checkViewsState(g2.context().systemView().view(NODES_SYS_VIEW), g2.localNode(), g1.localNode()); - } - - assertEquals(1, views.size()); - } - } - - /** */ - @Test - public void testNodeAttributes() throws Exception { - try ( - IgniteEx ignite0 = startGrid(getConfiguration(getTestIgniteInstanceName(0)) - .setUserAttributes(F.asMap("name", "val0"))); - IgniteEx ignite1 = startGrid(getConfiguration(getTestIgniteInstanceName(1)) - .setUserAttributes(F.asMap("name", "val1"))) - ) { - awaitPartitionMapExchange(); - - SystemView view = ignite0.context().systemView().view(NODE_ATTRIBUTES_SYS_VIEW); - - assertEquals(ignite0.cluster().localNode().attributes().size() + - ignite1.cluster().localNode().attributes().size(), view.size()); - - assertEquals(1, F.size(view.iterator(), row -> "name".equals(row.name()) && "val0".equals(row.value()))); - assertEquals(1, F.size(view.iterator(), row -> "name".equals(row.name()) && "val1".equals(row.value()))); - - // Test filtering. - assertTrue(view instanceof FiltrableSystemView); - - Iterator iter = ((FiltrableSystemView)view) - .iterator(F.asMap(NodeAttributeViewWalker.NODE_ID_FILTER, ignite0.cluster().localNode().id())); - - assertEquals(1, F.size(iter, row -> "name".equals(row.name()) && "val0".equals(row.value()))); - - iter = ((FiltrableSystemView)view).iterator( - F.asMap(NodeAttributeViewWalker.NODE_ID_FILTER, ignite1.cluster().localNode().id().toString())); - - assertEquals(1, F.size(iter, row -> "name".equals(row.name()) && "val1".equals(row.value()))); - - iter = ((FiltrableSystemView)view).iterator( - F.asMap(NodeAttributeViewWalker.NODE_ID_FILTER, "malformed-id")); - - assertEquals(0, F.size(iter)); - - iter = ((FiltrableSystemView)view).iterator( - F.asMap(NodeAttributeViewWalker.NAME_FILTER, "name")); - - assertEquals(2, F.size(iter)); - - iter = ((FiltrableSystemView)view) - .iterator(F.asMap(NodeAttributeViewWalker.NODE_ID_FILTER, ignite0.cluster().localNode().id(), - NodeAttributeViewWalker.NAME_FILTER, "name")); - - assertEquals(1, F.size(iter)); - } - } - - /** */ - @Test - public void testNodeMetrics() throws Exception { - long ts = U.currentTimeMillis(); - - try (IgniteEx ignite0 = startGrid(0); IgniteEx ignite1 = startGrid(1)) { - awaitPartitionMapExchange(); - - SystemView view = ignite0.context().systemView().view(NODE_METRICS_SYS_VIEW); - - assertEquals(2, view.size()); - assertEquals(1, F.size(view.iterator(), row -> row.nodeId().equals(ignite0.cluster().localNode().id()))); - assertEquals(1, F.size(view.iterator(), row -> row.nodeId().equals(ignite1.cluster().localNode().id()))); - assertEquals(2, F.size(view.iterator(), row -> row.lastUpdateTime().getTime() >= ts)); - } - } - - /** */ - @Test - public void testCacheGroupIo() throws Exception { - cleanPersistenceDir(); - - try (IgniteEx ignite = startGrid(getConfiguration().setDataStorageConfiguration( - new DataStorageConfiguration().setDefaultDataRegionConfiguration( - new DataRegionConfiguration().setPersistenceEnabled(true)))) - ) { - ignite.cluster().state(ClusterState.ACTIVE); - - IgniteCache cache = ignite.createCache("cache"); - - cache.put(0, 0); - cache.get(0); - - SystemView view = ignite.context().systemView().view(CACHE_GRP_IO_VIEW); - - CacheGroupIoView row = F.find(view, null, - (IgnitePredicate)r -> "cache".equals(r.cacheGroupName())); - - assertNotNull(row); - assertTrue(row.logicalReads() > 0); - assertTrue(row.insertedBytes() > 0); - } - } - - /** */ - private void checkViewsState(SystemView views, ClusterNode loc, ClusterNode rmt) { - assertEquals(2, views.size()); - - for (ClusterNodeView nodeView : views) { - if (nodeView.nodeId().equals(loc.id())) - checkNodeView(nodeView, loc, true); - else - checkNodeView(nodeView, rmt, false); - } - } - - /** */ - private void checkNodeView(ClusterNodeView view, ClusterNode node, boolean isLoc) { - assertEquals(node.id(), view.nodeId()); - assertEquals(node.consistentId().toString(), view.consistentId()); - assertEquals(toStringSafe(node.addresses()), view.addresses()); - assertEquals(toStringSafe(node.hostNames()), view.hostnames()); - assertEquals(node.order(), view.nodeOrder()); - assertEquals(node.version().toString(), view.version()); - assertEquals(isLoc, view.isLocal()); - assertEquals(node.isClient(), view.isClient()); - assertEquals(node.dataCenterId(), view.dataCenterId()); - assertEquals("DC0", view.dataCenterId()); - } - - /** */ - private Iterator jdbcConnectionsIterator(SystemView conns) { - return F.iterator(conns.iterator(), identity(), true, v -> "JDBC".equals(v.type())); - } - - /** */ - @Test - public void testTransactions() throws Exception { - try (IgniteEx g = startGrid(0)) { - IgniteCache cache1 = g.createCache(new CacheConfiguration("c1") - .setAtomicityMode(CacheAtomicityMode.TRANSACTIONAL)); - - IgniteCache cache2 = g.createCache(new CacheConfiguration("c2") - .setAtomicityMode(CacheAtomicityMode.TRANSACTIONAL)); - - SystemView txs = g.context().systemView().view(TXS_MON_LIST); - - assertEquals(0, F.size(txs.iterator(), alwaysTrue())); - - CountDownLatch latch = new CountDownLatch(1); - - try { - AtomicInteger cntr = new AtomicInteger(); - - GridTestUtils.runMultiThreadedAsync(() -> { - try (Transaction tx = g.transactions().withLabel("test").txStart(PESSIMISTIC, REPEATABLE_READ)) { - cache1.put(cntr.incrementAndGet(), cntr.incrementAndGet()); - cache1.put(cntr.incrementAndGet(), cntr.incrementAndGet()); - - latch.await(); - } - catch (InterruptedException e) { - throw new RuntimeException(e); - } - }, 5, "xxx"); - - boolean res = waitForCondition(() -> txs.size() == 5, 10_000L); - - assertTrue(res); - - TransactionView txv = txs.iterator().next(); - - assertEquals(g.localNode().id(), txv.localNodeId()); - assertEquals(txv.isolation(), REPEATABLE_READ); - assertEquals(txv.concurrency(), PESSIMISTIC); - assertEquals(txv.state(), ACTIVE); - assertNotNull(txv.xid()); - assertFalse(txv.system()); - assertFalse(txv.implicit()); - assertFalse(txv.implicitSingle()); - assertTrue(txv.near()); - assertFalse(txv.dht()); - assertTrue(txv.colocated()); - assertTrue(txv.local()); - assertEquals("test", txv.label()); - assertFalse(txv.onePhaseCommit()); - assertFalse(txv.internal()); - assertEquals(0, txv.timeout()); - assertTrue(txv.startTime() <= System.currentTimeMillis()); - assertEquals(String.valueOf(cacheId(cache1.getName())), txv.cacheIds()); - - GridTestUtils.runMultiThreadedAsync(() -> { - try (Transaction tx = g.transactions().txStart(OPTIMISTIC, SERIALIZABLE)) { - cache1.put(cntr.incrementAndGet(), cntr.incrementAndGet()); - cache1.put(cntr.incrementAndGet(), cntr.incrementAndGet()); - cache2.put(cntr.incrementAndGet(), cntr.incrementAndGet()); - - latch.await(); - } - catch (InterruptedException e) { - throw new RuntimeException(e); - } - }, 5, "xxx"); - - res = waitForCondition(() -> txs.size() == 10, 10_000L); - - assertTrue(res); - - for (TransactionView tx : txs) { - if (PESSIMISTIC == tx.concurrency()) - continue; - - assertEquals(g.localNode().id(), tx.localNodeId()); - assertEquals(tx.isolation(), SERIALIZABLE); - assertEquals(tx.concurrency(), OPTIMISTIC); - assertEquals(tx.state(), ACTIVE); - assertNotNull(tx.xid()); - assertFalse(tx.system()); - assertFalse(tx.implicit()); - assertFalse(tx.implicitSingle()); - assertTrue(tx.near()); - assertFalse(tx.dht()); - assertTrue(tx.colocated()); - assertTrue(tx.local()); - assertNull(tx.label()); - assertFalse(tx.onePhaseCommit()); - assertFalse(tx.internal()); - assertEquals(0, tx.timeout()); - assertTrue(tx.startTime() <= System.currentTimeMillis()); - - String s1 = cacheId(cache1.getName()) + "," + cacheId(cache2.getName()); - String s2 = cacheId(cache2.getName()) + "," + cacheId(cache1.getName()); - - assertTrue(s1.equals(tx.cacheIds()) || s2.equals(tx.cacheIds())); - } - } - finally { - latch.countDown(); - } - - boolean res = waitForCondition(() -> txs.size() == 0, 10_000L); - - assertTrue(res); - } - } - - /** */ - @Test - public void testLocalScanQuery() throws Exception { - try (IgniteEx g0 = startGrid(0)) { - IgniteCache cache1 = g0.createCache( - new CacheConfiguration("cache1") - .setGroupName("group1")); - - int part = g0.affinity("cache1").primaryPartitions(g0.localNode())[0]; - - List partKeys = partitionKeys(cache1, part, 11, 0); - - for (Integer key : partKeys) - cache1.put(key, key); - - SystemView qrySysView0 = g0.context().systemView().view(SCAN_QRY_SYS_VIEW); - - assertNotNull(qrySysView0); - - assertEquals(0, qrySysView0.size()); - - QueryCursor qryRes1 = cache1.query( - new ScanQuery() - .setFilter(new TestPredicate()) - .setLocal(true) - .setPartition(part) - .setPageSize(10), - new TestTransformer()); - - assertTrue(qryRes1.iterator().hasNext()); - - boolean res = waitForCondition(() -> qrySysView0.size() > 0, 5_000); - - assertTrue(res); - - ScanQueryView view = qrySysView0.iterator().next(); - - assertEquals(g0.localNode().id(), view.originNodeId()); - assertEquals(0, view.queryId()); - assertEquals("cache1", view.cacheName()); - assertEquals(cacheId("cache1"), view.cacheId()); - assertEquals(cacheGroupId("cache1", "group1"), view.cacheGroupId()); - assertEquals("group1", view.cacheGroupName()); - assertTrue(view.startTime() <= System.currentTimeMillis()); - assertTrue(view.duration() >= 0); - assertFalse(view.canceled()); - assertEquals(TEST_PREDICATE, view.filter()); - assertTrue(view.local()); - assertEquals(part, view.partition()); - assertEquals(toStringSafe(g0.context().discovery().topologyVersionEx()), view.topology()); - assertEquals(TEST_TRANSFORMER, view.transformer()); - assertFalse(view.keepBinary()); - assertNull(view.subjectId()); - assertNull(view.taskName()); - - qryRes1.close(); - - res = waitForCondition(() -> qrySysView0.size() == 0, 5_000); - - assertTrue(res); - } - } - - /** */ - @Test - public void testScanQuery() throws Exception { - try (IgniteEx g0 = startGrid(0); - IgniteEx g1 = startGrid(1); - IgniteEx client1 = startClientGrid("client-1"); - IgniteEx client2 = startClientGrid("client-2")) { - - IgniteCache cache1 = client1.createCache( - new CacheConfiguration("cache1") - .setGroupName("group1")); - - IgniteCache cache2 = client2.createCache("cache2"); - - for (int i = 0; i < 100; i++) { - cache1.put(i, i); - cache2.put(i, i); - } - - SystemView qrySysView0 = g0.context().systemView().view(SCAN_QRY_SYS_VIEW); - SystemView qrySysView1 = g1.context().systemView().view(SCAN_QRY_SYS_VIEW); - - assertNotNull(qrySysView0); - assertNotNull(qrySysView1); - - assertEquals(0, qrySysView0.size()); - assertEquals(0, qrySysView1.size()); - - QueryCursor qryRes1 = cache1.query( - new ScanQuery() - .setFilter(new TestPredicate()) - .setPageSize(10), - new TestTransformer()); - - QueryCursor qryRes2 = cache2.withKeepBinary().query(new ScanQuery<>() - .setPageSize(20)); - - assertTrue(qryRes1.iterator().hasNext()); - assertTrue(qryRes2.iterator().hasNext()); - - checkScanQueryView(client1, client2, qrySysView0); - checkScanQueryView(client1, client2, qrySysView1); - - qryRes1.close(); - qryRes2.close(); - - boolean res = waitForCondition( - () -> qrySysView0.size() + qrySysView1.size() == 0, 5_000); - - assertTrue(res); - } - } - - /** */ - private void checkScanQueryView(IgniteEx client1, IgniteEx client2, SystemView qrySysView) - throws Exception { - boolean res = waitForCondition(() -> qrySysView.size() > 1, 5_000); - - assertTrue(res); - - Consumer cache1checker = view -> { - assertEquals(client1.localNode().id(), view.originNodeId()); - assertTrue(view.queryId() != 0); - assertEquals("cache1", view.cacheName()); - assertEquals(cacheId("cache1"), view.cacheId()); - assertEquals(cacheGroupId("cache1", "group1"), view.cacheGroupId()); - assertEquals("group1", view.cacheGroupName()); - assertTrue(view.startTime() <= System.currentTimeMillis()); - assertTrue(view.duration() >= 0); - assertFalse(view.canceled()); - assertEquals(TEST_PREDICATE, view.filter()); - assertFalse(view.local()); - assertEquals(-1, view.partition()); - assertEquals(toStringSafe(client1.context().discovery().topologyVersionEx()), view.topology()); - assertEquals(TEST_TRANSFORMER, view.transformer()); - assertFalse(view.keepBinary()); - assertNull(view.subjectId()); - assertNull(view.taskName()); - assertEquals(10, view.pageSize()); - }; - - Consumer cache2checker = view -> { - assertEquals(client2.localNode().id(), view.originNodeId()); - assertTrue(view.queryId() != 0); - assertEquals("cache2", view.cacheName()); - assertEquals(cacheId("cache2"), view.cacheId()); - assertEquals(cacheGroupId("cache2", null), view.cacheGroupId()); - assertEquals("cache2", view.cacheGroupName()); - assertTrue(view.startTime() <= System.currentTimeMillis()); - assertTrue(view.duration() >= 0); - assertFalse(view.canceled()); - assertNull(view.filter()); - assertFalse(view.local()); - assertEquals(-1, view.partition()); - assertEquals(toStringSafe(client2.context().discovery().topologyVersionEx()), view.topology()); - assertNull(view.transformer()); - assertTrue(view.keepBinary()); - assertNull(view.subjectId()); - assertNull(view.taskName()); - assertEquals(20, view.pageSize()); - }; - - boolean found1 = false; - boolean found2 = false; - - for (ScanQueryView view : qrySysView) { - if ("cache2".equals(view.cacheName())) { - cache2checker.accept(view); - found1 = true; - } - else { - cache1checker.accept(view); - found2 = true; - } - } - - assertTrue(found1 && found2); - } - - /** */ - @Test - public void testAtomicSequence() throws Exception { - try (IgniteEx g0 = startGrid(0); - IgniteEx g1 = startGrid(1)) { - IgniteAtomicSequence s1 = g0.atomicSequence("seq-1", 42, true); - IgniteAtomicSequence s2 = g0.atomicSequence("seq-2", - new AtomicConfiguration().setBackups(1).setGroupName("my-group"), 43, true); - - s1.batchSize(42); - - SystemView seqs0 = g0.context().systemView().view(SEQUENCES_VIEW); - SystemView seqs1 = g1.context().systemView().view(SEQUENCES_VIEW); - - assertEquals(2, seqs0.size()); - assertEquals(0, seqs1.size()); - - for (AtomicSequenceView s : seqs0) { - if ("seq-1".equals(s.name())) { - assertEquals(42, s.value()); - assertEquals(42, s.batchSize()); - assertEquals(DEFAULT_DS_GROUP_NAME, s.groupName()); - assertEquals(CU.cacheId(DEFAULT_DS_GROUP_NAME), s.groupId()); - - long val = s1.addAndGet(42); - - assertEquals(val, s.value()); - assertFalse(s.removed()); - } - else { - assertEquals("seq-2", s.name()); - assertEquals(DFLT_ATOMIC_SEQUENCE_RESERVE_SIZE, s.batchSize()); - assertEquals(43, s.value()); - assertEquals("my-group", s.groupName()); - assertEquals(CU.cacheId("my-group"), s.groupId()); - assertFalse(s.removed()); - - s2.close(); - - assertTrue(waitForCondition(s::removed, getTestTimeout())); - } - } - - g1.atomicSequence("seq-1", 42, true); - - assertEquals(1, seqs1.size()); - - AtomicSequenceView s = seqs1.iterator().next(); - - assertEquals(DFLT_ATOMIC_SEQUENCE_RESERVE_SIZE + 42, s.value()); - assertEquals(DFLT_ATOMIC_SEQUENCE_RESERVE_SIZE, s.batchSize()); - assertEquals(DEFAULT_DS_GROUP_NAME, s.groupName()); - assertEquals(CU.cacheId(DEFAULT_DS_GROUP_NAME), s.groupId()); - assertFalse(s.removed()); - - s1.close(); - - assertTrue(waitForCondition(s::removed, getTestTimeout())); - - assertEquals(0, seqs0.size()); - assertEquals(0, seqs1.size()); - } - } - - /** */ - @Test - public void testAtomicLongs() throws Exception { - try (IgniteEx g0 = startGrid(0); - IgniteEx g1 = startGrid(1)) { - IgniteAtomicLong l1 = g0.atomicLong("long-1", 42, true); - IgniteAtomicLong l2 = g0.atomicLong("long-2", - new AtomicConfiguration().setBackups(1).setGroupName("my-group"), 43, true); - - SystemView longs0 = g0.context().systemView().view(LONGS_VIEW); - SystemView longs1 = g1.context().systemView().view(LONGS_VIEW); - - assertEquals(2, longs0.size()); - assertEquals(0, longs1.size()); - - for (AtomicLongView l : longs0) { - if ("long-1".equals(l.name())) { - assertEquals(42, l.value()); - assertEquals(DEFAULT_DS_GROUP_NAME, l.groupName()); - assertEquals(CU.cacheId(DEFAULT_DS_GROUP_NAME), l.groupId()); - - long val = l1.addAndGet(42); - - assertEquals(val, l.value()); - assertFalse(l.removed()); - } - else { - assertEquals("long-2", l.name()); - assertEquals(43, l.value()); - assertEquals("my-group", l.groupName()); - assertEquals(CU.cacheId("my-group"), l.groupId()); - assertFalse(l.removed()); - - l2.close(); - - assertTrue(waitForCondition(l::removed, getTestTimeout())); - } - } - - g1.atomicLong("long-1", 42, true); - - assertEquals(1, longs1.size()); - - AtomicLongView l = longs1.iterator().next(); - - assertEquals(84, l.value()); - assertEquals(DEFAULT_DS_GROUP_NAME, l.groupName()); - assertEquals(CU.cacheId(DEFAULT_DS_GROUP_NAME), l.groupId()); - assertFalse(l.removed()); - - l1.close(); - - assertTrue(waitForCondition(l::removed, getTestTimeout())); - - assertEquals(0, longs0.size()); - assertEquals(0, longs1.size()); - } - } - - /** */ - @Test - public void testAtomicReference() throws Exception { - try (IgniteEx g0 = startGrid(0); - IgniteEx g1 = startGrid(1)) { - IgniteAtomicReference l1 = g0.atomicReference("ref-1", "str1", true); - IgniteAtomicReference l2 = g0.atomicReference("ref-2", - new AtomicConfiguration().setBackups(1).setGroupName("my-group"), 43, true); - - SystemView refs0 = g0.context().systemView().view(REFERENCES_VIEW); - SystemView refs1 = g1.context().systemView().view(REFERENCES_VIEW); - - assertEquals(2, refs0.size()); - assertEquals(0, refs1.size()); - - for (AtomicReferenceView r : refs0) { - if ("ref-1".equals(r.name())) { - assertEquals("str1", r.value()); - assertEquals(DEFAULT_DS_GROUP_NAME, r.groupName()); - assertEquals(CU.cacheId(DEFAULT_DS_GROUP_NAME), r.groupId()); - - l1.set("str2"); - - assertEquals("str2", r.value()); - assertFalse(r.removed()); - } - else { - assertEquals("ref-2", r.name()); - assertEquals("43", r.value()); - assertEquals("my-group", r.groupName()); - assertEquals(CU.cacheId("my-group"), r.groupId()); - assertFalse(r.removed()); - - l2.close(); - - assertTrue(waitForCondition(r::removed, getTestTimeout())); - } - } - - g1.atomicReference("ref-1", "str3", true); - - assertEquals(1, refs1.size()); - - AtomicReferenceView l = refs1.iterator().next(); - - assertEquals("str2", l.value()); - assertEquals(DEFAULT_DS_GROUP_NAME, l.groupName()); - assertEquals(CU.cacheId(DEFAULT_DS_GROUP_NAME), l.groupId()); - assertFalse(l.removed()); - - l1.close(); - - assertTrue(waitForCondition(l::removed, getTestTimeout())); - - assertEquals(0, refs0.size()); - assertEquals(0, refs1.size()); - } - } - - /** */ - @Test - public void testAtomicStamped() throws Exception { - try (IgniteEx g0 = startGrid(0); - IgniteEx g1 = startGrid(1)) { - IgniteAtomicStamped s1 = g0.atomicStamped("s-1", "str0", 1, true); - IgniteAtomicStamped s2 = g0.atomicStamped("s-2", - new AtomicConfiguration().setBackups(1).setGroupName("my-group"), "str1", 43, true); - - SystemView stamps0 = g0.context().systemView().view(STAMPED_VIEW); - SystemView stamps1 = g1.context().systemView().view(STAMPED_VIEW); - - assertEquals(2, stamps0.size()); - assertEquals(0, stamps1.size()); - - for (AtomicStampedView s : stamps0) { - if ("s-1".equals(s.name())) { - assertEquals("str0", s.value()); - assertEquals("1", s.stamp()); - assertEquals(DEFAULT_DS_GROUP_NAME, s.groupName()); - assertEquals(CU.cacheId(DEFAULT_DS_GROUP_NAME), s.groupId()); - - s1.set("str2", 2); - - assertEquals("str2", s.value()); - assertEquals("2", s.stamp()); - assertFalse(s.removed()); - } - else { - assertEquals("s-2", s.name()); - assertEquals("str1", s.value()); - assertEquals("43", s.stamp()); - assertEquals("my-group", s.groupName()); - assertEquals(CU.cacheId("my-group"), s.groupId()); - assertFalse(s.removed()); - - s2.close(); - - assertTrue(waitForCondition(s::removed, getTestTimeout())); - } - } - - g1.atomicStamped("s-1", "str3", 3, true); - - assertEquals(1, stamps1.size()); - - AtomicStampedView l = stamps1.iterator().next(); - - assertEquals("str2", l.value()); - assertEquals("2", l.stamp()); - assertEquals(DEFAULT_DS_GROUP_NAME, l.groupName()); - assertEquals(CU.cacheId(DEFAULT_DS_GROUP_NAME), l.groupId()); - assertFalse(l.removed()); - - s1.close(); - - assertTrue(l.removed()); - - assertEquals(0, stamps0.size()); - assertEquals(0, stamps1.size()); - } - } - - /** */ - @Test - public void testCountDownLatch() throws Exception { - try (IgniteEx g0 = startGrid(0); - IgniteEx g1 = startGrid(1)) { - IgniteCountDownLatch l1 = g0.countDownLatch("c1", 3, false, true); - IgniteCountDownLatch l2 = g0.countDownLatch("c2", 1, true, true); - - SystemView latches0 = g0.context().systemView().view(LATCHES_VIEW); - SystemView latches1 = g1.context().systemView().view(LATCHES_VIEW); - - assertEquals(2, latches0.size()); - assertEquals(0, latches1.size()); - - String grpName = DEFAULT_VOLATILE_DS_GROUP_NAME + "@" + VOLATILE_DATA_REGION_NAME; - - for (CountDownLatchView l : latches0) { - if ("c1".equals(l.name())) { - assertEquals(3, l.count()); - assertEquals(3, l.initialCount()); - assertFalse(l.autoDelete()); - - l1.countDown(); - - assertEquals(2, l.count()); - assertEquals(3, l.initialCount()); - assertFalse(l.removed()); - } - else { - assertEquals("c2", l.name()); - assertEquals(1, l.count()); - assertEquals(1, l.initialCount()); - assertTrue(l.autoDelete()); - assertFalse(l.removed()); - - l2.countDown(); - l2.close(); - - assertTrue(waitForCondition(l::removed, getTestTimeout())); - } - - assertEquals(grpName, l.groupName()); - assertEquals(CU.cacheId(grpName), l.groupId()); - } - - IgniteCountDownLatch l3 = g1.countDownLatch("c1", 10, true, true); - - assertEquals(1, latches1.size()); - - CountDownLatchView l = latches1.iterator().next(); - - assertEquals(2, l.count()); - assertEquals(3, l.initialCount()); - assertEquals(grpName, l.groupName()); - assertEquals(CU.cacheId(grpName), l.groupId()); - assertFalse(l.removed()); - assertFalse(l.autoDelete()); - - l3.countDown(); - l3.countDown(); - l3.close(); - - assertTrue(waitForCondition(l::removed, getTestTimeout())); - - assertEquals(0, latches0.size()); - assertEquals(0, latches1.size()); - } - } - - /** */ - @Test - public void testSemaphores() throws Exception { - try (IgniteEx g0 = startGrid(0); - IgniteEx g1 = startGrid(1)) { - IgniteSemaphore s1 = g0.semaphore("s1", 3, false, true); - IgniteSemaphore s2 = g0.semaphore("s2", 1, true, true); - - SystemView semaphores0 = g0.context().systemView().view(SEMAPHORES_VIEW); - SystemView semaphores1 = g1.context().systemView().view(SEMAPHORES_VIEW); - - assertEquals(2, semaphores0.size()); - assertEquals(0, semaphores1.size()); - - String grpName = DEFAULT_VOLATILE_DS_GROUP_NAME + "@" + VOLATILE_DATA_REGION_NAME; - - IgniteInternalFuture acquirePermitFut = null; - - for (SemaphoreView s : semaphores0) { - if ("s1".equals(s.name())) { - assertEquals(3, s.availablePermits()); - assertFalse(s.hasQueuedThreads()); - assertEquals(0, s.queueLength()); - assertFalse(s.failoverSafe()); - assertFalse(s.broken()); - assertFalse(s.removed()); - - acquirePermitFut = runAsync(() -> { - s1.acquire(2); - - try { - Thread.sleep(getTestTimeout()); - } - catch (InterruptedException e) { - throw new RuntimeException(e); - } - finally { - s1.release(2); - } - }); - - assertTrue(waitForCondition(() -> s.availablePermits() == 1, getTestTimeout())); - assertTrue(s.hasQueuedThreads()); - assertEquals(1, s.queueLength()); - } - else { - assertEquals(1, s.availablePermits()); - assertFalse(s.hasQueuedThreads()); - assertEquals(0, s.queueLength()); - assertTrue(s.failoverSafe()); - assertFalse(s.broken()); - assertFalse(s.removed()); - - s2.close(); - - assertTrue(waitForCondition(s::removed, getTestTimeout())); - } - - assertEquals(grpName, s.groupName()); - assertEquals(CU.cacheId(grpName), s.groupId()); - } - - IgniteSemaphore l3 = g1.semaphore("s1", 10, true, true); - - assertEquals(1, semaphores1.size()); - - SemaphoreView s = semaphores1.iterator().next(); - - assertEquals(1, s.availablePermits()); - assertTrue(s.hasQueuedThreads()); - assertEquals(1, s.queueLength()); - assertFalse(s.failoverSafe()); - assertFalse(s.broken()); - assertFalse(s.removed()); - - acquirePermitFut.cancel(); - assertTrue(waitForCondition(() -> s.availablePermits() == 3, getTestTimeout())); - - l3.close(); - - assertTrue(waitForCondition(s::removed, getTestTimeout())); - - assertEquals(0, semaphores0.size()); - assertEquals(0, semaphores1.size()); - } - } - - /** */ - @Test - public void testLocks() throws Exception { - try (IgniteEx g0 = startGrid(0); - IgniteEx g1 = startGrid(1)) { - IgniteLock l1 = g0.reentrantLock("l1", false, true, true); - IgniteLock l2 = g0.reentrantLock("l2", true, false, true); - - SystemView locks0 = g0.context().systemView().view(LOCKS_VIEW); - SystemView locks1 = g1.context().systemView().view(LOCKS_VIEW); - - assertEquals(2, locks0.size()); - assertEquals(0, locks1.size()); - - String grpName = DEFAULT_VOLATILE_DS_GROUP_NAME + "@" + VOLATILE_DATA_REGION_NAME; - - IgniteInternalFuture lockFut = null; - - Runnable lockNSleep = () -> { - l1.lock(); - - try { - Thread.sleep(getTestTimeout()); - } - catch (InterruptedException e) { - throw new RuntimeException(e); - } - finally { - l1.unlock(); - } - }; - - for (ReentrantLockView l : locks0) { - if ("l1".equals(l.name())) { - assertFalse(l.locked()); - assertFalse(l.hasQueuedThreads()); - assertFalse(l.failoverSafe()); - assertTrue(l.fair()); - assertFalse(l.broken()); - assertFalse(l.removed()); - - lockFut = runAsync(lockNSleep); - - assertTrue(waitForCondition(l::locked, getTestTimeout())); - } - else { - assertFalse(l.hasQueuedThreads()); - assertTrue(l.failoverSafe()); - assertFalse(l.fair()); - assertFalse(l.broken()); - assertFalse(l.removed()); - - l2.close(); - - assertTrue(waitForCondition(l::removed, getTestTimeout())); - } - - assertEquals(grpName, l.groupName()); - assertEquals(CU.cacheId(grpName), l.groupId()); - } - - IgniteLock l3 = g1.reentrantLock("l1", true, false, true); - - assertEquals(1, locks1.size()); - - ReentrantLockView s = locks1.iterator().next(); - - assertTrue(s.locked()); - assertFalse(s.hasQueuedThreads()); - assertFalse(s.failoverSafe()); - assertTrue(s.fair()); - assertFalse(s.broken()); - assertFalse(s.removed()); - - lockFut.cancel(); - - assertTrue(waitForCondition(() -> !s.locked(), getTestTimeout())); - assertFalse(s.hasQueuedThreads()); - - l3.close(); - - assertTrue(waitForCondition(s::removed, getTestTimeout())); - - assertEquals(0, locks0.size()); - assertEquals(0, locks1.size()); - } - } - - /** */ - @Test - public void testQueue() throws Exception { - try (IgniteEx g0 = startGrid(0); - IgniteEx g1 = startGrid(1)) { - - IgniteQueue q0 = g0.queue("queue-1", 42, new CollectionConfiguration() - .setCollocated(true) - .setBackups(1) - .setGroupName("my-group")); - IgniteQueue q1 = g0.queue("queue-2", 0, new CollectionConfiguration()); - - SystemView queues0 = g0.context().systemView().view(QUEUES_VIEW); - SystemView queues1 = g1.context().systemView().view(QUEUES_VIEW); - - assertEquals(2, queues0.size()); - assertEquals(0, queues1.size()); - - for (QueueView q : queues0) { - if ("queue-1".equals(q.name())) { - assertNotNull(q.id()); - assertEquals("queue-1", q.name()); - assertEquals(42, q.capacity()); - assertTrue(q.bounded()); - assertTrue(q.collocated()); - assertEquals("my-group", q.groupName()); - assertEquals(CU.cacheId("my-group"), q.groupId()); - assertFalse(q.removed()); - assertEquals(0, q.size()); - - q0.add("first"); - - assertEquals(1, q.size()); - } - else { - assertNotNull(q.id()); - assertEquals("queue-2", q.name()); - assertEquals(Integer.MAX_VALUE, q.capacity()); - assertFalse(q.bounded()); - assertFalse(q.collocated()); - assertEquals(DEFAULT_DS_GROUP_NAME, q.groupName()); - assertEquals(CU.cacheId(DEFAULT_DS_GROUP_NAME), q.groupId()); - assertFalse(q.removed()); - assertEquals(0, q.size()); - - q1.close(); - - assertTrue(waitForCondition(q::removed, getTestTimeout())); - } - } - - IgniteQueue q2 = g1.queue("queue-1", 42, new CollectionConfiguration() - .setCollocated(true) - .setBackups(1) - .setGroupName("my-group")); - - assertEquals(1, queues1.size()); - - QueueView q = queues1.iterator().next(); - - assertNotNull(q.id()); - assertEquals("queue-1", q.name()); - assertEquals(42, q.capacity()); - assertTrue(q.bounded()); - assertTrue(q.collocated()); - assertEquals("my-group", q.groupName()); - assertEquals(CU.cacheId("my-group"), q.groupId()); - assertFalse(q.removed()); - assertEquals(1, q.size()); - - q2.close(); - - assertTrue(waitForCondition(q::removed, getTestTimeout())); - - assertEquals(0, queues0.size()); - assertEquals(0, queues1.size()); - } - } - - /** */ - @Test - public void testSet() throws Exception { - try (IgniteEx g0 = startGrid(0); - IgniteEx g1 = startGrid(1)) { - - IgniteSet s0 = g0.set("set-1", new CollectionConfiguration() - .setCollocated(true) - .setBackups(1) - .setGroupName("my-group")); - IgniteSet s1 = g0.set("set-2", new CollectionConfiguration()); - - SystemView sets0 = g0.context().systemView().view(SETS_VIEW); - SystemView sets1 = g1.context().systemView().view(SETS_VIEW); - - assertEquals(2, sets0.size()); - assertEquals(0, sets1.size()); - - for (SetView q : sets0) { - if ("set-1".equals(q.name())) { - assertNotNull(q.id()); - assertEquals("set-1", q.name()); - assertTrue(q.collocated()); - assertEquals("my-group", q.groupName()); - assertEquals(CU.cacheId("my-group"), q.groupId()); - assertFalse(q.removed()); - assertEquals(0, q.size()); - - s0.add("first"); - - assertEquals(1, q.size()); - } - else { - assertNotNull(q.id()); - assertEquals("set-2", q.name()); - assertFalse(q.collocated()); - assertEquals(DEFAULT_DS_GROUP_NAME, q.groupName()); - assertEquals(CU.cacheId(DEFAULT_DS_GROUP_NAME), q.groupId()); - assertFalse(q.removed()); - assertEquals(0, q.size()); - - s1.close(); - - assertTrue(waitForCondition(q::removed, getTestTimeout())); - } - } - - IgniteSet s2 = g1.set("set-1", new CollectionConfiguration() - .setCollocated(true) - .setBackups(1) - .setGroupName("my-group")); - - assertEquals(1, sets1.size()); - - SetView s = sets1.iterator().next(); - - assertNotNull(s.id()); - assertEquals("set-1", s.name()); - assertTrue(s.collocated()); - assertEquals("my-group", s.groupName()); - assertEquals(CU.cacheId("my-group"), s.groupId()); - assertFalse(s.removed()); - assertEquals(1, s.size()); - - s2.close(); - - assertTrue(waitForCondition(s::removed, getTestTimeout())); - - assertEquals(0, sets0.size()); - assertEquals(0, sets1.size()); - } - } - - /** */ - @Test - public void testStripedExecutors() throws Exception { - try (IgniteEx g = startGrid(0)) { - checkStripeExecutorView(g.context().pools().getStripedExecutorService(), - g.context().systemView().view(SYS_POOL_QUEUE_VIEW), - "sys"); - - checkStripeExecutorView(g.context().pools().getDataStreamerExecutorService(), - g.context().systemView().view(STREAM_POOL_QUEUE_VIEW), - "data-streamer"); - } - } - - /** - * Checks striped executor system view. - * - * @param execSvc Striped executor. - * @param view System view. - * @param poolName Executor name. - */ - private void checkStripeExecutorView(IgniteStripedExecutor execSvc, SystemView view, - String poolName) throws Exception { - CountDownLatch latch = new CountDownLatch(1); - - execSvc.execute(0, new TestRunnable(latch, 0)); - execSvc.execute(0, new TestRunnable(latch, 1)); - execSvc.execute(1, new TestRunnable(latch, 2)); - execSvc.execute(1, new TestRunnable(latch, 3)); - - try { - boolean res = waitForCondition(() -> view.size() == 2, 5_000); - - assertTrue(res); - - Iterator iter = view.iterator(); - - assertTrue(iter.hasNext()); - - StripedExecutorTaskView row0 = iter.next(); - - assertEquals(0, row0.stripeIndex()); - assertEquals(TestRunnable.class.getSimpleName() + '1', row0.description()); - assertEquals(poolName + "-stripe-0", row0.threadName()); - assertEquals(TestRunnable.class.getName(), row0.taskName()); - - assertTrue(iter.hasNext()); - - StripedExecutorTaskView row1 = iter.next(); - - assertEquals(1, row1.stripeIndex()); - assertEquals(TestRunnable.class.getSimpleName() + '3', row1.description()); - assertEquals(poolName + "-stripe-1", row1.threadName()); - assertEquals(TestRunnable.class.getName(), row1.taskName()); - } - finally { - latch.countDown(); - } - } - - /** */ - public static class TestPredicate implements IgniteBiPredicate { - /** {@inheritDoc} */ - @Override public boolean apply(Integer integer, Integer integer2) { - return true; - } - - /** {@inheritDoc} */ - @Override public String toString() { - return TEST_PREDICATE; - } - } - - /** */ - public static class TestTransformer implements IgniteClosure, Integer> { - /** {@inheritDoc} */ - @Override public Integer apply(Cache.Entry entry) { - return entry.getKey(); - } - - /** {@inheritDoc} */ - @Override public String toString() { - return TEST_TRANSFORMER; - } - } - - /** */ - @Test - public void testPagesList() throws Exception { - cleanPersistenceDir(); - - try (IgniteEx ignite = startGrid(getConfiguration() - .setDataStorageConfiguration( - new DataStorageConfiguration().setDataRegionConfigurations( - new DataRegionConfiguration().setName("dr0").setMaxSize(100L * 1024 * 1024), - new DataRegionConfiguration().setName("dr1").setMaxSize(100L * 1024 * 1024) - .setPersistenceEnabled(true) - )))) { - ignite.cluster().state(ClusterState.ACTIVE); - - GridCacheDatabaseSharedManager dbMgr = (GridCacheDatabaseSharedManager)ignite.context().cache().context() - .database(); - - int pageSize = dbMgr.pageSize(); - - dbMgr.enableCheckpoints(false).get(); - - for (int i = 0; i < 2; i++) { - IgniteCache cache = ignite.getOrCreateCache(new CacheConfiguration<>("cache" + i) - .setDataRegionName("dr" + i).setAffinity(new RendezvousAffinityFunction().setPartitions(2))); - - int key = 0; - - // Fill up different free-list buckets. - for (int j = 0; j < pageSize / 2; j++) - cache.put(key++, new byte[j + 1]); - - // Put some pages to one bucket to overflow pages cache. - for (int j = 0; j < 1000; j++) - cache.put(key++, new byte[pageSize / 2]); - } - - long dr0flPages = 0; - int dr0flStripes = 0; - - SystemView dataRegionPageLists = ignite.context().systemView().view(DATA_REGION_PAGE_LIST_VIEW); - - for (PagesListView pagesListView : dataRegionPageLists) { - if (pagesListView.name().startsWith("dr0")) { - dr0flPages += pagesListView.bucketSize(); - dr0flStripes += pagesListView.stripesCount(); - } - } - - assertTrue(dr0flPages > 0); - assertTrue(dr0flStripes > 0); - - int bucketsCnt = ((PagesList)ignite.context().cache().context().database().freeList("dr0")).bucketsCount(); - int[] bucketPagesSize = new int[bucketsCnt]; - - for (PagesListView pagesListView : dataRegionPageLists) { - int bucket = pagesListView.bucketNumber(); - - if (bucketPagesSize[bucket] == 0) { - assertTrue(bucket == 0 || pagesListView.pageFreeSpace() != 0); - bucketPagesSize[bucket] = pagesListView.pageFreeSpace(); - } - else - assertEquals(bucketPagesSize[bucket], pagesListView.pageFreeSpace()); - } - - int prev = 0; - - for (int size : bucketPagesSize) { - if (size > 0) { - assertTrue(size > prev); - prev = size; - } - } - - SystemView cacheGrpPageLists = ignite.context().systemView().view(CACHE_GRP_PAGE_LIST_VIEW); - - long dr1flPages = 0; - int dr1flStripes = 0; - int dr1flCached = 0; - - for (CachePagesListView pagesListView : cacheGrpPageLists) { - if (pagesListView.cacheGroupId() == cacheId("cache1")) { - dr1flPages += pagesListView.bucketSize(); - dr1flStripes += pagesListView.stripesCount(); - dr1flCached += pagesListView.cachedPagesCount(); - } - } - - assertTrue(dr1flPages > 0); - assertTrue(dr1flStripes > 0); - assertTrue(dr1flCached > 0); - - // Test filtering. - assertTrue(cacheGrpPageLists instanceof FiltrableSystemView); - - Iterator iter = ((FiltrableSystemView)cacheGrpPageLists).iterator(Map.of( - CachePagesListViewWalker.CACHE_GROUP_ID_FILTER, cacheId("cache1"), - CachePagesListViewWalker.PARTITION_ID_FILTER, 0, - CachePagesListViewWalker.BUCKET_NUMBER_FILTER, 0 - )); - - assertEquals(1, F.size(iter)); - - iter = ((FiltrableSystemView)cacheGrpPageLists).iterator(Map.of( - CachePagesListViewWalker.CACHE_GROUP_ID_FILTER, cacheId("cache1"), - CachePagesListViewWalker.BUCKET_NUMBER_FILTER, 0 - )); - - assertEquals(2, F.size(iter)); - } - } - - /** */ - @Test - public void testBinaryMeta() throws Exception { - try (IgniteEx g = startGrid(0)) { - IgniteCache c1 = g.createCache("test-cache"); - IgniteCache c2 = g.createCache("test-enum-cache"); - - c1.put(1, new TestObjectAllTypes()); - c2.put(1, TestObjectEnum.A); - - SystemView view = g.context().systemView().view(BINARY_METADATA_VIEW); - - assertNotNull(view); - assertEquals(2, view.size()); - - for (BinaryMetadataView meta : view) { - if (TestObjectEnum.class.getName().contains(meta.typeName())) { - assertTrue(meta.isEnum()); - - assertEquals(0, meta.fieldsCount()); - } - else { - assertFalse(meta.isEnum()); - - Field[] fields = TestObjectAllTypes.class.getDeclaredFields(); - - assertEquals(fields.length, meta.fieldsCount()); - - for (Field field : fields) - assertTrue(meta.fields().contains(field.getName())); - } - } - } - } - - /** */ - @Test - public void testMetastorage() throws Exception { - cleanPersistenceDir(); - - try (IgniteEx ignite = startGrid(getConfiguration().setDataStorageConfiguration( - new DataStorageConfiguration().setDefaultDataRegionConfiguration( - new DataRegionConfiguration().setPersistenceEnabled(true) - )))) { - ignite.cluster().state(ClusterState.ACTIVE); - - IgniteCacheDatabaseSharedManager db = ignite.context().cache().context().database(); - - SystemView metaStoreView = ignite.context().systemView().view(METASTORE_VIEW); - - assertNotNull(metaStoreView); - - String name = "test-key"; - String val = "test-value"; - String unmarshalledName = "unmarshalled-key"; - String unmarshalledVal = "[Raw data. 0 bytes]"; - - db.checkpointReadLock(); - - try { - db.metaStorage().write(name, val); - db.metaStorage().writeRaw(unmarshalledName, new byte[0]); - } - finally { - db.checkpointReadUnlock(); - } - - assertNotNull(F.find(metaStoreView, null, - (IgnitePredicate)view -> - name.equals(view.name()) && val.equals(view.value()))); - - assertNotNull(F.find(metaStoreView, null, - (IgnitePredicate)view -> - unmarshalledName.equals(view.name()) && unmarshalledVal.equals(view.value()))); - - // Test filtering. - assertTrue(metaStoreView instanceof FiltrableSystemView); - - Iterator iter = ((FiltrableSystemView)metaStoreView) - .iterator(F.asMap(MetastorageViewWalker.NAME_FILTER, name)); - - assertTrue(iter.hasNext()); - - MetastorageView row = iter.next(); - - assertTrue(name.equals(row.name()) && val.equals(row.value())); - assertFalse(iter.hasNext()); - } - } - - /** */ - @Test - public void testDistributedMetastorage() throws Exception { - cleanPersistenceDir(); - - try (IgniteEx ignite = startGrid(getConfiguration().setDataStorageConfiguration( - new DataStorageConfiguration().setDefaultDataRegionConfiguration( - new DataRegionConfiguration().setPersistenceEnabled(true) - )))) { - ignite.cluster().state(ClusterState.ACTIVE); - - String histogramName = "CheckpointBeforeLockHistogram"; - - ignite.context().metric().configureHistogram(metricName(DATASTORAGE_METRIC_PREFIX, histogramName), new long[] { 1, 2, 3}); - - DistributedMetaStorage dms = ignite.context().distributedMetastorage(); - - String name = "test-distributed-key"; - String val = "test-distributed-value"; - - dms.write(name, val); - - SystemView dmsView = ignite.context().systemView().view(DISTRIBUTED_METASTORE_VIEW); - - assertNotNull(F.find( - dmsView, - null, - (IgnitePredicate)view -> name.equals(view.name()) && val.equals(view.value())) - ); - - assertNotNull(F.find( - dmsView, - null, - (IgnitePredicate) - view -> view.name().endsWith(histogramName) && "[1, 2, 3]".equals(view.value())) - ); - - // Test filtering. - assertTrue(dmsView instanceof FiltrableSystemView); - - Iterator iter = ((FiltrableSystemView)dmsView) - .iterator(F.asMap(MetastorageViewWalker.NAME_FILTER, name)); - - assertTrue(iter.hasNext()); - - MetastorageView row = iter.next(); - - assertTrue(name.equals(row.name()) && val.equals(row.value())); - assertFalse(iter.hasNext()); - } - } - - /** */ - @Test - public void testBaselineNodes() throws Exception { - cleanPersistenceDir(); - - try ( - IgniteEx ignite0 = startGrid(getConfiguration(getTestIgniteInstanceName(0)) - .setDataStorageConfiguration(new DataStorageConfiguration().setDefaultDataRegionConfiguration( - new DataRegionConfiguration().setPersistenceEnabled(true))) - .setConsistentId("consId0")); - IgniteEx ignite1 = startGrid(getConfiguration(getTestIgniteInstanceName(1)) - .setDataStorageConfiguration(new DataStorageConfiguration().setDefaultDataRegionConfiguration( - new DataRegionConfiguration().setPersistenceEnabled(true))) - .setConsistentId("consId1")); - ) { - ignite0.cluster().state(ClusterState.ACTIVE); - - ignite1.close(); - - awaitPartitionMapExchange(); - - SystemView view = ignite0.context().systemView().view(BASELINE_NODES_SYS_VIEW); - - assertEquals(2, view.size()); - assertEquals(1, F.size(view.iterator(), row -> "consId0".equals(row.consistentId()) && row.online())); - assertEquals(1, F.size(view.iterator(), row -> "consId1".equals(row.consistentId()) && !row.online())); - } - } - - /** */ - @Test - public void testBaselineNodeAttributes() throws Exception { - cleanPersistenceDir(); - - try (IgniteEx ignite = startGrid(getConfiguration() - .setDataStorageConfiguration( - new DataStorageConfiguration().setDefaultDataRegionConfiguration( - new DataRegionConfiguration().setName("pds").setPersistenceEnabled(true) - )) - .setUserAttributes(F.asMap("name", "val")) - .setConsistentId("consId")) - ) { - ignite.cluster().state(ClusterState.ACTIVE); - - SystemView view = ignite.context().systemView() - .view(BASELINE_NODE_ATTRIBUTES_SYS_VIEW); - - assertEquals(ignite.cluster().localNode().attributes().size(), view.size()); - - assertEquals(1, F.size(view.iterator(), row -> "consId".equals(row.nodeConsistentId()) && - "name".equals(row.name()) && "val".equals(row.value()))); - - // Test filtering. - assertTrue(view instanceof FiltrableSystemView); - - Iterator iter = ((FiltrableSystemView)view) - .iterator(F.asMap(BaselineNodeAttributeViewWalker.NODE_CONSISTENT_ID_FILTER, "consId", - BaselineNodeAttributeViewWalker.NAME_FILTER, "name")); - - assertEquals(1, F.size(iter)); - - iter = ((FiltrableSystemView)view).iterator( - F.asMap(BaselineNodeAttributeViewWalker.NODE_CONSISTENT_ID_FILTER, "consId")); - - assertEquals(1, F.size(iter, row -> "name".equals(row.name()))); - - iter = ((FiltrableSystemView)view).iterator( - F.asMap(BaselineNodeAttributeViewWalker.NAME_FILTER, "name")); - - assertEquals(1, F.size(iter)); - } - } - - /** */ - @Test - public void testSnapshot() throws Exception { - cleanPersistenceDir(); - - String dfltCacheGrp = "testGroup"; - - String testSnap0 = "testSnap0"; - String testSnap1 = "testSnap1"; - - try (IgniteEx ignite = startGrid(getConfiguration() - .setCacheConfiguration(new CacheConfiguration<>(DEFAULT_CACHE_NAME).setGroupName(dfltCacheGrp)) - .setDataStorageConfiguration( - new DataStorageConfiguration().setDefaultDataRegionConfiguration( - new DataRegionConfiguration().setName("pds").setPersistenceEnabled(true) - ).setWalCompactionEnabled(true))) - ) { - ignite.cluster().state(ClusterState.ACTIVE); - - ignite.cache(DEFAULT_CACHE_NAME).put(1, 1); - - ignite.snapshot().createSnapshot(testSnap0).get(); - ignite.snapshot().createSnapshot(testSnap1).get(getTestTimeout()); - ignite.snapshot().createIncrementalSnapshot(testSnap1).get(getTestTimeout()); - ignite.snapshot().createIncrementalSnapshot(testSnap1).get(getTestTimeout()); - - SystemView views = ignite.context().systemView().view(SNAPSHOT_SYS_VIEW); - - List> exp = Lists.newArrayList( - new T2<>(testSnap0, null), - new T2<>(testSnap1, null), - new T2<>(testSnap1, 1), - new T2<>(testSnap1, 2)); - - assertEquals(4, views.size()); - - for (SnapshotView v: views) { - assertTrue(exp.remove(new T2<>(v.name(), v.incrementIndex()))); - - assertEquals(ignite.localNode().consistentId().toString(), v.consistentId()); - assertNotNull(v.snapshotRecordSegment()); - assertTrue("snapshotTime should be non-zero value", - v.snapshotTime() > 0); - - Integer incIdx = v.incrementIndex(); - - if (incIdx == null) { - assertEquals(ignite.localNode().consistentId().toString(), v.baselineNodes()); - assertEquals(String.join(",", dfltCacheGrp, METASTORAGE_CACHE_NAME), v.cacheGroups()); - assertEquals("FULL", v.type()); - } - else - assertEquals("INCREMENTAL", v.type()); - } - - assertTrue(exp.isEmpty()); - } - } - - /** */ - @Test - public void testPagesTimestampHistogram() throws Exception { - int keysCnt = 50_000; - - AtomicLong curTime = new AtomicLong(System.currentTimeMillis()); - - GridTestClockTimer.timeSupplier(curTime::get); - GridTestClockTimer.update(); - - String regionName = "default"; - - DataStorageConfiguration dsCfg = new DataStorageConfiguration().setDefaultDataRegionConfiguration( - new DataRegionConfiguration() - .setMaxSize(50L * 1024 * 1024) - .setPersistenceEnabled(true) - .setName(regionName) - .setMetricsEnabled(true) - ); - - cleanPersistenceDir(); - - try (IgniteEx ignite = startGrid(getConfiguration().setDataStorageConfiguration(dsCfg))) { - ignite.cluster().state(ClusterState.ACTIVE); - - CacheConfiguration ccfg1 = new CacheConfiguration<>("test-pages-ts1") - .setAffinity(new RendezvousAffinityFunction(false, 10)); - - CacheConfiguration ccfg2 = new CacheConfiguration<>("test-pages-ts2") - .setAffinity(new RendezvousAffinityFunction(false, 10)); - - IgniteCache cache1 = ignite.createCache(ccfg1); - - long ts1 = curTime.get(); - - for (int i = 0; i < 1000; i++) - cache1.put(i, i); - - long ts2 = curTime.addAndGet(PeriodicHistogramMetricImpl.DFLT_BUCKETS_INTERVAL); - GridTestClockTimer.update(); - - for (int i = 1000; i < 2000; i++) - cache1.put(i, i); - - SystemView pagesTsHistogram = - ignite.context().systemView().view(PAGE_TS_HISTOGRAM_VIEW); - - assertNotNull(pagesTsHistogram); - - long totalCnt = 0; - - for (PagesTimestampHistogramView view : pagesTsHistogram) { - if (regionName.equals(view.dataRegionName())) { - if ((ts1 >= view.intervalStart().getTime() && ts1 <= view.intervalEnd().getTime()) || - (ts2 >= view.intervalStart().getTime() && ts2 <= view.intervalEnd().getTime())) { - assertTrue("Unexpected pages count: " + view.pagesCount(), view.pagesCount() > 0); - - totalCnt += view.pagesCount(); - } - else - assertEquals(0, view.pagesCount()); - } - } - - assertTrue(totalCnt > 0); - assertEquals(ignite.dataRegionMetrics(regionName).getPhysicalMemoryPages(), totalCnt); - - assertEquals(2, F.size(F.iterator(pagesTsHistogram, v -> v, true, v -> v.pagesCount() > 0))); - - // Check histogram after replacement. - long ts3 = curTime.addAndGet(PeriodicHistogramMetricImpl.DFLT_BUCKETS_INTERVAL); - GridTestClockTimer.update(); - - ignite.createCache(ccfg2); - - try (IgniteDataStreamer streamer = ignite.dataStreamer("test-pages-ts2")) { - for (int i = 0; i < keysCnt; i++) - streamer.addData(i, new byte[1000]); - } - - assertEquals(ignite.dataRegionMetrics(regionName).getPhysicalMemoryPages(), - F.sumInt(F.iterator(pagesTsHistogram, v -> (int)v.pagesCount(), true))); - - assertFalse(F.isEmpty(F.iterator(pagesTsHistogram, v -> v, true, v -> v.pagesCount() > 0 && - v.intervalStart().getTime() <= ts3 && ts3 <= v.intervalEnd().getTime()))); - - // Check histogram after cache destroy and remove of outdated pages. - long ts4 = curTime.addAndGet(PeriodicHistogramMetricImpl.DFLT_BUCKETS_INTERVAL); - GridTestClockTimer.update(); - - ignite.destroyCache("test-pages-ts2"); - - IgniteCache cache2 = ignite.createCache(ccfg2); - - for (int i = 0; i < keysCnt; i++) { - cache1.put(i, i); - cache2.put(i, new byte[1000]); - } - - assertEquals(ignite.dataRegionMetrics(regionName).getPhysicalMemoryPages(), - F.sumInt(F.iterator(pagesTsHistogram, v -> (int)v.pagesCount(), true))); - - assertFalse(F.isEmpty(F.iterator(pagesTsHistogram, v -> v, true, v -> v.pagesCount() > 0 && - v.intervalStart().getTime() <= ts4 && ts4 <= v.intervalEnd().getTime()))); - } - finally { - GridTestClockTimer.timeSupplier(GridTestClockTimer.DFLT_TIME_SUPPLIER); - } - } - - /** */ - @Test - public void testPagesTimestampHistogramAfterPartitionEviction() throws Exception { - int keysCnt = 50_000; - - String regionName = "default"; - - DataStorageConfiguration dsCfg = new DataStorageConfiguration().setDefaultDataRegionConfiguration( - new DataRegionConfiguration() - .setMaxSize(50L * 1024 * 1024) - .setPersistenceEnabled(true) - .setName(regionName) - .setMetricsEnabled(true) - ); - - cleanPersistenceDir(); - - try (IgniteEx ignite = startGrid(getConfiguration().setDataStorageConfiguration(dsCfg))) { - ignite.cluster().state(ClusterState.ACTIVE); - - IgniteCache cache = ignite.createCache(new CacheConfiguration<>("test-pages-ts") - .setBackups(1).setAffinity(new RendezvousAffinityFunction(false, 10))); - - try (IgniteDataStreamer streamer = ignite.dataStreamer("test-pages-ts")) { - for (int i = 0; i < keysCnt; i++) - streamer.addData(i, new byte[1000]); - } - - startGrid(getConfiguration(getTestIgniteInstanceName(1)).setDataStorageConfiguration(dsCfg)); - startGrid(getConfiguration(getTestIgniteInstanceName(2)).setDataStorageConfiguration(dsCfg)); - - resetBaselineTopology(); - - awaitPartitionMapExchange(true, true, null); - - // Force checkpoint to invalidate evicted partitions. - forceCheckpoint(ignite); - - // Check histogram after partition eviction. - SystemView pagesTsHistogram = - ignite.context().systemView().view(PAGE_TS_HISTOGRAM_VIEW); - - assertEquals(ignite.dataRegionMetrics(regionName).getPhysicalMemoryPages(), - F.sumInt(F.iterator(pagesTsHistogram, v -> (int)v.pagesCount(), true))); - - stopGrid(2); - - resetBaselineTopology(); - - // Wait until rebalance complete. - assertTrue(GridTestUtils.waitForCondition(() -> ignite.context().discovery().topologyVersionEx() - .minorTopologyVersion() >= 2, 5_000L)); - - // Check histogram after rebalance. - assertEquals(ignite.dataRegionMetrics(regionName).getPhysicalMemoryPages(), - F.sumInt(F.iterator(pagesTsHistogram, v -> (int)v.pagesCount(), true))); - - stopGrid(1); - - resetBaselineTopology(); - - // Allocate some pages after eviction. - for (int i = 0; i < 10_000; i++) - cache.put(i + keysCnt, new byte[1024]); - - // Acquire some outdated pages. - for (int i = 0; i < keysCnt + 10_000; i++) - assertNotNull(cache.get(i)); - - // Check histogram after replacement of outdated pages. - assertEquals(ignite.dataRegionMetrics(regionName).getPhysicalMemoryPages(), - F.sumInt(F.iterator(pagesTsHistogram, v -> (int)v.pagesCount(), true))); - } - finally { - stopAllGrids(); - } - } - - /** */ - @Test - public void testConfigurationView() throws Exception { - long expMaxSize = 10 * MB; - - String expName = "my-instance"; - - String expDrName = "my-dr"; - - IgniteConfiguration icfg = getConfiguration(expName) - .setIncludeEventTypes(EVT_CONSISTENCY_VIOLATION) - .setDataStorageConfiguration(new DataStorageConfiguration() - .setDefaultDataRegionConfiguration( - new DataRegionConfiguration() - .setLazyMemoryAllocation(false)) - .setDataRegionConfigurations( - new DataRegionConfiguration() - .setName(expDrName) - .setMaxSize(expMaxSize))); - - try (IgniteEx ignite = startGrid(icfg)) { - Map viewContent = new HashMap<>(); - - ignite.context().systemView().view(CFG_VIEW) - .forEach(view -> viewContent.put(view.name(), view.value())); - - assertEquals(expName, viewContent.get("IgniteInstanceName")); - assertEquals( - "false", - viewContent.get("DataStorageConfiguration.DefaultDataRegionConfiguration.LazyMemoryAllocation") - ); - assertEquals(expDrName, viewContent.get("DataStorageConfiguration.DataRegionConfigurations[0].Name")); - assertEquals( - Long.toString(expMaxSize), - viewContent.get("DataStorageConfiguration.DataRegionConfigurations[0].MaxSize") - ); - assertEquals( - CacheAtomicityMode.TRANSACTIONAL.name(), - viewContent.get("CacheConfiguration[0].AtomicityMode") - ); - assertTrue(viewContent.containsKey("AddressResolver")); - assertNull(viewContent.get("AddressResolver")); - assertEquals("[" + EVT_CONSISTENCY_VIOLATION + ']', viewContent.get("IncludeEventTypes")); - } - } - - /** */ - @Test - public void testPluginView() throws Exception { - try (IgniteEx n = startGrid(getConfiguration().setPluginProviders(new TestPluginProvider()))) { - SystemView view = n.context().systemView().view(PLUGINS_SYS_VIEW); - - PluginView testPluginView = StreamSupport.stream(view.spliterator(), false) - .filter(v -> "FOR_SYS_VIEW_PLUGIN_NAME".equals(v.name())) - .findFirst() - .orElseThrow(() -> new AssertionError("Plugin not found")); - - assertEquals("FOR_SYS_VIEW_PLUGIN_NAME", testPluginView.name()); - assertEquals("FOR_SYS_VIEW_PLUGIN_INFO", testPluginView.info()); - assertEquals("42", testPluginView.version()); - assertEquals(TestPluginProvider.TestPlugin.class.getName(), testPluginView.className()); - } - } - - /** Test node filter. */ - public static class TestNodeFilter implements IgnitePredicate { - /** {@inheritDoc} */ - @Override public boolean apply(ClusterNode node) { - return true; - } - } - - /** Test runnable. */ - public static class TestRunnable implements Runnable { - /** */ - private final CountDownLatch latch; - - /** */ - private final int idx; - - /** */ - public TestRunnable(CountDownLatch latch, int idx) { - this.latch = latch; - this.idx = idx; - } - - /** {@inheritDoc} */ - @Override public void run() { - try { - latch.await(5, TimeUnit.SECONDS); - } - catch (InterruptedException e) { - throw new IgniteException(e); - } - } - - /** {@inheritDoc} */ - @Override public String toString() { - return getClass().getSimpleName() + idx; - } - } - - /** */ - private static class UserTask implements ComputeTask { - /** {@inheritDoc} */ - @Override public @NotNull Map map( - List subgrid, - @Nullable Object arg - ) throws IgniteException { - return subgrid.stream().collect(Collectors.toMap(k -> new UserJob(), Function.identity())); - } - - /** {@inheritDoc} */ - @Override public ComputeJobResultPolicy result(ComputeJobResult res, List rcvd) throws IgniteException { - return ComputeJobResultPolicy.WAIT; - } - - /** {@inheritDoc} */ - @Nullable @Override public Object reduce(List results) throws IgniteException { - return 1; - } - - /** */ - private static class UserJob implements ComputeJob { - /** {@inheritDoc} */ - @Override public void cancel() { - // No-op. - } - - /** {@inheritDoc} */ - @Override public Object execute() throws IgniteException { - jobStartedLatch.countDown(); - - try { - assertTrue(releaseJobLatch.await(30_000, TimeUnit.MILLISECONDS)); - } - catch (InterruptedException e) { - throw new RuntimeException(e); - } - - return 1; - } - } - } - - /** */ - @GridInternal - public static class InternalTask extends UserTask { - // No-op. - } - - /** */ - private static class TestPluginProvider extends AbstractTestPluginProvider { - /** {@inheritDoc} */ - @Override public String name() { - return "FOR_SYS_VIEW_PLUGIN_NAME"; - } - - /** {@inheritDoc} */ - @Override public String version() { - return "42"; - } - - /** {@inheritDoc} */ - @Override public String info() { - return "FOR_SYS_VIEW_PLUGIN_INFO"; - } - - /** {@inheritDoc} */ - @Override public T plugin() { - return (T)new TestPlugin(); - } - - /** */ - private static class TestPlugin implements IgnitePlugin { - } - } -} diff --git a/modules/core/src/test/java/org/apache/ignite/internal/metric/SystemViewServiceTest.java b/modules/core/src/test/java/org/apache/ignite/internal/metric/SystemViewServiceTest.java new file mode 100644 index 0000000000000..d9a32a6bbcd23 --- /dev/null +++ b/modules/core/src/test/java/org/apache/ignite/internal/metric/SystemViewServiceTest.java @@ -0,0 +1,108 @@ +/* + * 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.metric; + +import org.apache.ignite.cluster.ClusterNode; +import org.apache.ignite.internal.IgniteEx; +import org.apache.ignite.internal.processors.service.DummyService; +import org.apache.ignite.internal.util.typedef.F; +import org.apache.ignite.lang.IgnitePredicate; +import org.apache.ignite.services.ServiceConfiguration; +import org.apache.ignite.spi.systemview.view.ServiceView; +import org.apache.ignite.spi.systemview.view.SystemView; +import org.junit.Test; + +import static org.apache.ignite.internal.processors.service.IgniteServiceProcessor.SVCS_VIEW; + +/** Tests for {@link SystemView} for services. */ +public class SystemViewServiceTest extends SystemViewAbstractTest { + /** Tests work of {@link SystemView} for services. */ + @Test + public void testServices() throws Exception { + try (IgniteEx g = startGrid()) { + { + ServiceConfiguration srvcCfg = new ServiceConfiguration(); + + srvcCfg.setName("service"); + srvcCfg.setMaxPerNodeCount(1); + srvcCfg.setService(new DummyService()); + srvcCfg.setNodeFilter(new TestNodeFilter()); + + g.services().deploy(srvcCfg); + + SystemView srvs = g.context().systemView().view(SVCS_VIEW); + + assertEquals(g.context().service().serviceDescriptors().size(), F.size(srvs.iterator())); + + ServiceView sview = srvs.iterator().next(); + + assertEquals(srvcCfg.getName(), sview.name()); + assertNotNull(sview.serviceId()); + assertEquals(DummyService.class, sview.serviceClass()); + assertEquals(srvcCfg.getMaxPerNodeCount(), sview.maxPerNodeCount()); + assertNull(sview.cacheName()); + assertNull(sview.affinityKey()); + assertEquals(TestNodeFilter.class, sview.nodeFilter()); + assertFalse(sview.staticallyConfigured()); + assertEquals(g.localNode().id(), sview.originNodeId()); + assertEquals(F.asMap(g.localNode().id(), 1), sview.topologySnapshot()); + } + + { + g.createCache("test-cache"); + + ServiceConfiguration srvcCfg = new ServiceConfiguration(); + + srvcCfg.setName("service-2"); + srvcCfg.setMaxPerNodeCount(2); + srvcCfg.setService(new DummyService()); + srvcCfg.setNodeFilter(new TestNodeFilter()); + srvcCfg.setCacheName("test-cache"); + srvcCfg.setAffinityKey(1L); + + g.services().deploy(srvcCfg); + + final ServiceView[] sview = {null}; + + g.context().systemView().view(SVCS_VIEW).forEach(sv -> { + if (sv.name().equals(srvcCfg.getName())) + sview[0] = sv; + }); + + assertEquals(srvcCfg.getName(), sview[0].name()); + assertNotNull(sview[0].serviceId()); + assertEquals(DummyService.class, sview[0].serviceClass()); + assertEquals(srvcCfg.getMaxPerNodeCount(), sview[0].maxPerNodeCount()); + assertEquals("test-cache", sview[0].cacheName()); + assertEquals("1", sview[0].affinityKey()); + assertEquals(TestNodeFilter.class, sview[0].nodeFilter()); + assertFalse(sview[0].staticallyConfigured()); + assertEquals(g.localNode().id(), sview[0].originNodeId()); + assertEquals(F.asMap(g.localNode().id(), 2), sview[0].topologySnapshot()); + } + } + } + + /** Test node filter. */ + public static class TestNodeFilter implements IgnitePredicate { + /** {@inheritDoc} */ + @Override public boolean apply(ClusterNode node) { + return true; + } + } +} diff --git a/modules/core/src/test/java/org/apache/ignite/internal/metric/SystemViewSnapshotsTest.java b/modules/core/src/test/java/org/apache/ignite/internal/metric/SystemViewSnapshotsTest.java new file mode 100644 index 0000000000000..e6fcf8144b0c6 --- /dev/null +++ b/modules/core/src/test/java/org/apache/ignite/internal/metric/SystemViewSnapshotsTest.java @@ -0,0 +1,95 @@ +/* + * 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.metric; + +import java.util.List; +import com.google.common.collect.Lists; +import org.apache.ignite.cluster.ClusterState; +import org.apache.ignite.configuration.CacheConfiguration; +import org.apache.ignite.configuration.DataRegionConfiguration; +import org.apache.ignite.configuration.DataStorageConfiguration; +import org.apache.ignite.internal.IgniteEx; +import org.apache.ignite.internal.util.typedef.T2; +import org.apache.ignite.spi.systemview.view.SnapshotView; +import org.apache.ignite.spi.systemview.view.SystemView; +import org.junit.Test; + +import static org.apache.ignite.internal.processors.cache.persistence.metastorage.MetaStorage.METASTORAGE_CACHE_NAME; +import static org.apache.ignite.spi.systemview.view.SnapshotView.SNAPSHOT_SYS_VIEW; + +/** Tests for {@link SystemView} for snapshots. */ +public class SystemViewSnapshotsTest extends SystemViewAbstractTest { + /** */ + @Test + public void testSnapshot() throws Exception { + cleanPersistenceDir(); + + String dfltCacheGrp = "testGroup"; + + String testSnap0 = "testSnap0"; + String testSnap1 = "testSnap1"; + + try (IgniteEx ignite = startGrid(getConfiguration() + .setCacheConfiguration(new CacheConfiguration<>(DEFAULT_CACHE_NAME).setGroupName(dfltCacheGrp)) + .setDataStorageConfiguration( + new DataStorageConfiguration().setDefaultDataRegionConfiguration( + new DataRegionConfiguration().setName("pds").setPersistenceEnabled(true) + ).setWalCompactionEnabled(true))) + ) { + ignite.cluster().state(ClusterState.ACTIVE); + + ignite.cache(DEFAULT_CACHE_NAME).put(1, 1); + + ignite.snapshot().createSnapshot(testSnap0).get(); + ignite.snapshot().createSnapshot(testSnap1).get(getTestTimeout()); + ignite.snapshot().createIncrementalSnapshot(testSnap1).get(getTestTimeout()); + ignite.snapshot().createIncrementalSnapshot(testSnap1).get(getTestTimeout()); + + SystemView views = ignite.context().systemView().view(SNAPSHOT_SYS_VIEW); + + List> exp = Lists.newArrayList( + new T2<>(testSnap0, null), + new T2<>(testSnap1, null), + new T2<>(testSnap1, 1), + new T2<>(testSnap1, 2)); + + assertEquals(4, views.size()); + + for (SnapshotView v: views) { + assertTrue(exp.remove(new T2<>(v.name(), v.incrementIndex()))); + + assertEquals(ignite.localNode().consistentId().toString(), v.consistentId()); + assertNotNull(v.snapshotRecordSegment()); + assertTrue("snapshotTime should be non-zero value", + v.snapshotTime() > 0); + + Integer incIdx = v.incrementIndex(); + + if (incIdx == null) { + assertEquals(ignite.localNode().consistentId().toString(), v.baselineNodes()); + assertEquals(String.join(",", dfltCacheGrp, METASTORAGE_CACHE_NAME), v.cacheGroups()); + assertEquals("FULL", v.type()); + } + else + assertEquals("INCREMENTAL", v.type()); + } + + assertTrue(exp.isEmpty()); + } + } +} diff --git a/modules/core/src/test/java/org/apache/ignite/internal/metric/SystemViewTransactionsTest.java b/modules/core/src/test/java/org/apache/ignite/internal/metric/SystemViewTransactionsTest.java new file mode 100644 index 0000000000000..1d07df05bff55 --- /dev/null +++ b/modules/core/src/test/java/org/apache/ignite/internal/metric/SystemViewTransactionsTest.java @@ -0,0 +1,155 @@ +/* + * 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.metric; + +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.atomic.AtomicInteger; +import org.apache.ignite.IgniteCache; +import org.apache.ignite.cache.CacheAtomicityMode; +import org.apache.ignite.configuration.CacheConfiguration; +import org.apache.ignite.internal.IgniteEx; +import org.apache.ignite.internal.util.typedef.F; +import org.apache.ignite.spi.systemview.view.SystemView; +import org.apache.ignite.spi.systemview.view.TransactionView; +import org.apache.ignite.testframework.GridTestUtils; +import org.apache.ignite.transactions.Transaction; +import org.junit.Test; + +import static org.apache.ignite.internal.processors.cache.GridCacheUtils.cacheId; +import static org.apache.ignite.internal.processors.cache.transactions.IgniteTxManager.TXS_MON_LIST; +import static org.apache.ignite.internal.util.lang.GridFunc.alwaysTrue; +import static org.apache.ignite.testframework.GridTestUtils.waitForCondition; +import static org.apache.ignite.transactions.TransactionConcurrency.OPTIMISTIC; +import static org.apache.ignite.transactions.TransactionConcurrency.PESSIMISTIC; +import static org.apache.ignite.transactions.TransactionIsolation.REPEATABLE_READ; +import static org.apache.ignite.transactions.TransactionIsolation.SERIALIZABLE; +import static org.apache.ignite.transactions.TransactionState.ACTIVE; + +/** Tests for {@link SystemView} for transactions. */ +public class SystemViewTransactionsTest extends SystemViewAbstractTest { + /** */ + @Test + public void testTransactions() throws Exception { + try (IgniteEx g = startGrid(0)) { + IgniteCache cache1 = g.createCache(new CacheConfiguration("c1") + .setAtomicityMode(CacheAtomicityMode.TRANSACTIONAL)); + + IgniteCache cache2 = g.createCache(new CacheConfiguration("c2") + .setAtomicityMode(CacheAtomicityMode.TRANSACTIONAL)); + + SystemView txs = g.context().systemView().view(TXS_MON_LIST); + + assertEquals(0, F.size(txs.iterator(), alwaysTrue())); + + CountDownLatch latch = new CountDownLatch(1); + + try { + AtomicInteger cntr = new AtomicInteger(); + + GridTestUtils.runMultiThreadedAsync(() -> { + try (Transaction tx = g.transactions().withLabel("test").txStart(PESSIMISTIC, REPEATABLE_READ)) { + cache1.put(cntr.incrementAndGet(), cntr.incrementAndGet()); + cache1.put(cntr.incrementAndGet(), cntr.incrementAndGet()); + + latch.await(); + } + catch (InterruptedException e) { + throw new RuntimeException(e); + } + }, 5, "xxx"); + + boolean res = waitForCondition(() -> txs.size() == 5, 10_000L); + + assertTrue(res); + + TransactionView txv = txs.iterator().next(); + + assertEquals(g.localNode().id(), txv.localNodeId()); + assertEquals(txv.isolation(), REPEATABLE_READ); + assertEquals(txv.concurrency(), PESSIMISTIC); + assertEquals(txv.state(), ACTIVE); + assertNotNull(txv.xid()); + assertFalse(txv.system()); + assertFalse(txv.implicit()); + assertFalse(txv.implicitSingle()); + assertTrue(txv.near()); + assertFalse(txv.dht()); + assertTrue(txv.colocated()); + assertTrue(txv.local()); + assertEquals("test", txv.label()); + assertFalse(txv.onePhaseCommit()); + assertFalse(txv.internal()); + assertEquals(0, txv.timeout()); + assertTrue(txv.startTime() <= System.currentTimeMillis()); + assertEquals(String.valueOf(cacheId(cache1.getName())), txv.cacheIds()); + + GridTestUtils.runMultiThreadedAsync(() -> { + try (Transaction tx = g.transactions().txStart(OPTIMISTIC, SERIALIZABLE)) { + cache1.put(cntr.incrementAndGet(), cntr.incrementAndGet()); + cache1.put(cntr.incrementAndGet(), cntr.incrementAndGet()); + cache2.put(cntr.incrementAndGet(), cntr.incrementAndGet()); + + latch.await(); + } + catch (InterruptedException e) { + throw new RuntimeException(e); + } + }, 5, "xxx"); + + res = waitForCondition(() -> txs.size() == 10, 10_000L); + + assertTrue(res); + + for (TransactionView tx : txs) { + if (PESSIMISTIC == tx.concurrency()) + continue; + + assertEquals(g.localNode().id(), tx.localNodeId()); + assertEquals(tx.isolation(), SERIALIZABLE); + assertEquals(tx.concurrency(), OPTIMISTIC); + assertEquals(tx.state(), ACTIVE); + assertNotNull(tx.xid()); + assertFalse(tx.system()); + assertFalse(tx.implicit()); + assertFalse(tx.implicitSingle()); + assertTrue(tx.near()); + assertFalse(tx.dht()); + assertTrue(tx.colocated()); + assertTrue(tx.local()); + assertNull(tx.label()); + assertFalse(tx.onePhaseCommit()); + assertFalse(tx.internal()); + assertEquals(0, tx.timeout()); + assertTrue(tx.startTime() <= System.currentTimeMillis()); + + String s1 = cacheId(cache1.getName()) + "," + cacheId(cache2.getName()); + String s2 = cacheId(cache2.getName()) + "," + cacheId(cache1.getName()); + + assertTrue(s1.equals(tx.cacheIds()) || s2.equals(tx.cacheIds())); + } + } + finally { + latch.countDown(); + } + + boolean res = waitForCondition(() -> txs.size() == 0, 10_000L); + + assertTrue(res); + } + } +} diff --git a/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheTestSuite13.java b/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheTestSuite13.java index a2a17c5d2b16d..4426afc205343 100644 --- a/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheTestSuite13.java +++ b/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheTestSuite13.java @@ -35,10 +35,26 @@ import org.apache.ignite.internal.metric.OutboundIoMessageQueueSizeTest; import org.apache.ignite.internal.metric.ReadMetricsOnNodeStartupTest; import org.apache.ignite.internal.metric.SystemMetricsTest; +import org.apache.ignite.internal.metric.SystemViewBinaryMetaTest; import org.apache.ignite.internal.metric.SystemViewCacheExpiryPolicyTest; +import org.apache.ignite.internal.metric.SystemViewCacheTest; +import org.apache.ignite.internal.metric.SystemViewClientTest; import org.apache.ignite.internal.metric.SystemViewClusterActivationTest; import org.apache.ignite.internal.metric.SystemViewComputeJobTest; -import org.apache.ignite.internal.metric.SystemViewSelfTest; +import org.apache.ignite.internal.metric.SystemViewComputeTaskTest; +import org.apache.ignite.internal.metric.SystemViewConfigurationTest; +import org.apache.ignite.internal.metric.SystemViewDSTest; +import org.apache.ignite.internal.metric.SystemViewExecutorsTest; +import org.apache.ignite.internal.metric.SystemViewLocksTest; +import org.apache.ignite.internal.metric.SystemViewMetastorageTest; +import org.apache.ignite.internal.metric.SystemViewNodesTest; +import org.apache.ignite.internal.metric.SystemViewPageListsTest; +import org.apache.ignite.internal.metric.SystemViewPageTimestampsTest; +import org.apache.ignite.internal.metric.SystemViewPluginTest; +import org.apache.ignite.internal.metric.SystemViewQueriesTest; +import org.apache.ignite.internal.metric.SystemViewServiceTest; +import org.apache.ignite.internal.metric.SystemViewSnapshotsTest; +import org.apache.ignite.internal.metric.SystemViewTransactionsTest; import org.apache.ignite.internal.processors.cache.CacheClearAsyncDeadlockTest; import org.apache.ignite.internal.processors.cache.CacheDistributedGetLongRunningFutureDumpTest; import org.apache.ignite.internal.processors.cache.EntriesRemoveOnShutdownTest; @@ -88,10 +104,26 @@ public static List> suite(Collection ignoredTests) { GridTestUtils.addTestIfNeeded(suite, SystemMetricsTest.class, ignoredTests); GridTestUtils.addTestIfNeeded(suite, CustomMetricsTest.class, ignoredTests); GridTestUtils.addTestIfNeeded(suite, MetricsConfigurationTest.class, ignoredTests); - GridTestUtils.addTestIfNeeded(suite, SystemViewSelfTest.class, ignoredTests); GridTestUtils.addTestIfNeeded(suite, SystemViewClusterActivationTest.class, ignoredTests); GridTestUtils.addTestIfNeeded(suite, SystemViewComputeJobTest.class, ignoredTests); GridTestUtils.addTestIfNeeded(suite, SystemViewCacheExpiryPolicyTest.class, ignoredTests); + GridTestUtils.addTestIfNeeded(suite, SystemViewCacheTest.class, ignoredTests); + GridTestUtils.addTestIfNeeded(suite, SystemViewServiceTest.class, ignoredTests); + GridTestUtils.addTestIfNeeded(suite, SystemViewComputeTaskTest.class, ignoredTests); + GridTestUtils.addTestIfNeeded(suite, SystemViewClientTest.class, ignoredTests); + GridTestUtils.addTestIfNeeded(suite, SystemViewNodesTest.class, ignoredTests); + GridTestUtils.addTestIfNeeded(suite, SystemViewTransactionsTest.class, ignoredTests); + GridTestUtils.addTestIfNeeded(suite, SystemViewDSTest.class, ignoredTests); + GridTestUtils.addTestIfNeeded(suite, SystemViewExecutorsTest.class, ignoredTests); + GridTestUtils.addTestIfNeeded(suite, SystemViewPageListsTest.class, ignoredTests); + GridTestUtils.addTestIfNeeded(suite, SystemViewBinaryMetaTest.class, ignoredTests); + GridTestUtils.addTestIfNeeded(suite, SystemViewMetastorageTest.class, ignoredTests); + GridTestUtils.addTestIfNeeded(suite, SystemViewSnapshotsTest.class, ignoredTests); + GridTestUtils.addTestIfNeeded(suite, SystemViewPageTimestampsTest.class, ignoredTests); + GridTestUtils.addTestIfNeeded(suite, SystemViewConfigurationTest.class, ignoredTests); + GridTestUtils.addTestIfNeeded(suite, SystemViewPluginTest.class, ignoredTests); + GridTestUtils.addTestIfNeeded(suite, SystemViewQueriesTest.class, ignoredTests); + GridTestUtils.addTestIfNeeded(suite, SystemViewLocksTest.class, ignoredTests); GridTestUtils.addTestIfNeeded(suite, CacheMetricsAddRemoveTest.class, ignoredTests); GridTestUtils.addTestIfNeeded(suite, CacheMetricsConflictResolverTest.class, ignoredTests); GridTestUtils.addTestIfNeeded(suite, JmxExporterSpiTest.class, ignoredTests); diff --git a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/metric/SqlViewExporterSpiTest.java b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/metric/SqlViewExporterSpiTest.java index e2b2317c44dcf..15a512dbaab88 100644 --- a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/metric/SqlViewExporterSpiTest.java +++ b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/metric/SqlViewExporterSpiTest.java @@ -63,9 +63,9 @@ import org.apache.ignite.internal.binary.mutabletest.GridBinaryTestClasses.TestObjectAllTypes; import org.apache.ignite.internal.binary.mutabletest.GridBinaryTestClasses.TestObjectEnum; import org.apache.ignite.internal.metric.AbstractExporterSpiTest; -import org.apache.ignite.internal.metric.SystemViewSelfTest.TestPredicate; -import org.apache.ignite.internal.metric.SystemViewSelfTest.TestRunnable; -import org.apache.ignite.internal.metric.SystemViewSelfTest.TestTransformer; +import org.apache.ignite.internal.metric.SystemViewExecutorsTest.TestRunnable; +import org.apache.ignite.internal.metric.SystemViewQueriesTest.TestPredicate; +import org.apache.ignite.internal.metric.SystemViewQueriesTest.TestTransformer; import org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion; import org.apache.ignite.internal.processors.cache.distributed.dht.topology.GridDhtPartitionState; import org.apache.ignite.internal.processors.cache.persistence.GridCacheDatabaseSharedManager; @@ -86,8 +86,8 @@ import org.junit.Test; import static java.util.Arrays.asList; -import static org.apache.ignite.internal.metric.SystemViewSelfTest.TEST_PREDICATE; -import static org.apache.ignite.internal.metric.SystemViewSelfTest.TEST_TRANSFORMER; +import static org.apache.ignite.internal.metric.SystemViewQueriesTest.TEST_PREDICATE; +import static org.apache.ignite.internal.metric.SystemViewQueriesTest.TEST_TRANSFORMER; import static org.apache.ignite.internal.processors.cache.GridCacheUtils.cacheGroupId; import static org.apache.ignite.internal.processors.cache.GridCacheUtils.cacheId; import static org.apache.ignite.internal.processors.cache.index.AbstractSchemaSelfTest.queryProcessor; diff --git a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/SqlSystemViewsSelfTest.java b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/SqlSystemViewsSelfTest.java index 5c74bdf53aa5a..1c7b4457f467a 100644 --- a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/SqlSystemViewsSelfTest.java +++ b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/SqlSystemViewsSelfTest.java @@ -32,6 +32,7 @@ import java.util.UUID; import java.util.concurrent.Callable; import java.util.concurrent.TimeUnit; +import java.util.concurrent.locks.Lock; import java.util.function.BiConsumer; import java.util.stream.Collectors; import java.util.stream.LongStream; @@ -81,6 +82,7 @@ import org.apache.ignite.internal.util.typedef.F; import org.apache.ignite.internal.util.typedef.G; import org.apache.ignite.internal.util.typedef.X; +import org.apache.ignite.internal.util.typedef.internal.CU; import org.apache.ignite.internal.util.typedef.internal.U; import org.apache.ignite.lang.IgniteFuture; import org.apache.ignite.lang.IgnitePredicate; @@ -92,6 +94,7 @@ import org.apache.ignite.spi.systemview.view.SystemView; import org.apache.ignite.spi.systemview.view.sql.SqlTableView; import org.apache.ignite.testframework.GridTestUtils; +import org.apache.ignite.transactions.Transaction; import org.junit.Assert; import org.junit.Test; @@ -102,6 +105,8 @@ import static org.apache.ignite.internal.processors.query.running.RunningQueryManager.SQL_QRY_VIEW; import static org.apache.ignite.internal.util.IgniteUtils.MB; import static org.apache.ignite.testframework.GridTestUtils.waitForCondition; +import static org.apache.ignite.transactions.TransactionConcurrency.PESSIMISTIC; +import static org.apache.ignite.transactions.TransactionIsolation.REPEATABLE_READ; import static org.junit.Assert.assertNotEquals; /** @@ -1896,6 +1901,56 @@ public void testPluginView() throws Exception { } } + /** */ + @Test + public void testLocksView() throws Exception { + try (IgniteEx ignite = startGrid()) { + IgniteCache cache = ignite.getOrCreateCache(new CacheConfiguration<>(DEFAULT_CACHE_NAME) + .setAtomicityMode(CacheAtomicityMode.TRANSACTIONAL)); + + Lock lock1 = cache.lock(1); + Lock lock2 = cache.lock(2); + + lock1.lock(); + lock2.lock(); + try (Transaction ignored = ignite.transactions().txStart(PESSIMISTIC, REPEATABLE_READ)) { + cache.put(3, 3); + + // Join explicit locks with key locks. + List> res = execSql("SELECT el.cache_id, el.thread_id, kl.is_owner, kl.is_tx, kl.originating_node_id " + + "FROM SYS.CACHE_EXPLICIT_LOCKS el JOIN SYS.CACHE_KEY_LOCKS kl ON el.xid = kl.xid"); + + assertEquals(2, res.size()); + + for (List lock : res) { + assertEquals(CU.cacheId(DEFAULT_CACHE_NAME), lock.get(0)); + assertEquals(Thread.currentThread().getId(), lock.get(1)); + assertEquals(true, lock.get(2)); + assertEquals(false, lock.get(3)); + assertEquals(ignite.localNode().id(), lock.get(4)); + } + + // Join transactions with key locks. + res = execSql("SELECT kl.cache_id, tx.thread_id, kl.is_owner, kl.is_tx, kl.originating_node_id " + + "FROM SYS.TRANSACTIONS tx JOIN SYS.CACHE_KEY_LOCKS kl ON tx.xid = kl.xid"); + + assertEquals(1, res.size()); + + for (List lock : res) { + assertEquals(CU.cacheId(DEFAULT_CACHE_NAME), lock.get(0)); + assertEquals(Thread.currentThread().getId(), lock.get(1)); + assertEquals(true, lock.get(2)); + assertEquals(true, lock.get(3)); + assertEquals(ignite.localNode().id(), lock.get(4)); + } + } + finally { + lock2.unlock(); + lock1.unlock(); + } + } + } + /** * Mock for {@link ClusterMetricsImpl} that always returns big (more than 24h) duration for all duration metrics. */ diff --git a/modules/indexing/src/test/java/org/apache/ignite/testsuites/IgniteBinaryCacheQueryTestSuite3.java b/modules/indexing/src/test/java/org/apache/ignite/testsuites/IgniteBinaryCacheQueryTestSuite3.java index 36154c333db41..d1d2e840db5b8 100644 --- a/modules/indexing/src/test/java/org/apache/ignite/testsuites/IgniteBinaryCacheQueryTestSuite3.java +++ b/modules/indexing/src/test/java/org/apache/ignite/testsuites/IgniteBinaryCacheQueryTestSuite3.java @@ -22,7 +22,6 @@ import org.apache.ignite.internal.cdc.CdcIndexRebuildTest; import org.apache.ignite.internal.cdc.SqlCdcTest; import org.apache.ignite.internal.dump.DumpCacheConfigTest; -import org.apache.ignite.internal.metric.SystemViewSelfTest; import org.apache.ignite.internal.processors.cache.BigEntryQueryTest; import org.apache.ignite.internal.processors.cache.BinaryMetadataConcurrentUpdateWithIndexesTest; import org.apache.ignite.internal.processors.cache.BinarySerializationQuerySelfTest; @@ -350,7 +349,6 @@ RowCountTableStatisticsSurvivesNodeRestartTest.class, SqlViewExporterSpiTest.class, - SystemViewSelfTest.class, SqlMergeTest.class, SqlMergeOnClientNodeTest.class,