This is an automated email from the ASF dual-hosted git repository.
av pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/ignite.git
The following commit(s) were added to refs/heads/master by this push:
new 2d3b96d83c9 IGNITE-20816 in-memory server node is crashed by
TcpIgniteClient.putAllConflict() if cache objects transformation applied
(#11037)
2d3b96d83c9 is described below
commit 2d3b96d83c9763d14a07c84bdddb590191647fd4
Author: Anton Vinogradov <[email protected]>
AuthorDate: Thu Nov 16 16:02:15 2023 +0300
IGNITE-20816 in-memory server node is crashed by
TcpIgniteClient.putAllConflict() if cache objects transformation applied
(#11037)
---
.../apache/ignite/internal/binary/BinaryUtils.java | 2 +
.../cacheobject/PlatformCacheObjectImpl.java | 71 ++++++
.../platform/client/ClientMessageParser.java | 4 +-
.../cache/ClientCachePutAllConflictRequest.java | 4 +-
.../cache/ClientCacheRemoveAllConflictRequest.java | 2 +-
.../streamer/ClientDataStreamerAddDataRequest.java | 4 +-
.../client/streamer/ClientDataStreamerReader.java | 9 +-
.../streamer/ClientDataStreamerStartRequest.java | 4 +-
.../processors/platform/utils/PlatformUtils.java | 8 +-
.../CacheObjectTransformationCacheApiTest.java | 282 +++++++++++++++++++++
.../ignite/testsuites/IgniteCacheTestSuite13.java | 3 +
11 files changed, 373 insertions(+), 20 deletions(-)
diff --git
a/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryUtils.java
b/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryUtils.java
index 60a00441737..f513d3ddd2f 100644
---
a/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryUtils.java
+++
b/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryUtils.java
@@ -70,6 +70,7 @@ import
org.apache.ignite.internal.binary.streams.BinaryInputStream;
import org.apache.ignite.internal.processors.cache.CacheObjectByteArrayImpl;
import org.apache.ignite.internal.processors.cache.CacheObjectImpl;
import org.apache.ignite.internal.processors.cache.KeyCacheObjectImpl;
+import
org.apache.ignite.internal.processors.cacheobject.PlatformCacheObjectImpl;
import
org.apache.ignite.internal.processors.cacheobject.UserCacheObjectByteArrayImpl;
import org.apache.ignite.internal.processors.cacheobject.UserCacheObjectImpl;
import
org.apache.ignite.internal.processors.cacheobject.UserKeyCacheObjectImpl;
@@ -749,6 +750,7 @@ public class BinaryUtils {
cls == BinaryEnumObjectImpl.class ||
cls == UserKeyCacheObjectImpl.class ||
cls == UserCacheObjectImpl.class ||
+ cls == PlatformCacheObjectImpl.class ||
cls == UserCacheObjectByteArrayImpl.class;
}
diff --git
a/modules/core/src/main/java/org/apache/ignite/internal/processors/cacheobject/PlatformCacheObjectImpl.java
b/modules/core/src/main/java/org/apache/ignite/internal/processors/cacheobject/PlatformCacheObjectImpl.java
new file mode 100644
index 00000000000..d89ea657bad
--- /dev/null
+++
b/modules/core/src/main/java/org/apache/ignite/internal/processors/cacheobject/PlatformCacheObjectImpl.java
@@ -0,0 +1,71 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.internal.processors.cacheobject;
+
+import org.apache.ignite.internal.GridDirectTransient;
+import org.apache.ignite.internal.processors.cache.CacheObject;
+import org.apache.ignite.internal.processors.cache.CacheObjectContext;
+import org.apache.ignite.internal.processors.cache.CacheObjectImpl;
+import org.apache.ignite.internal.processors.cache.CacheObjectTransformerUtils;
+import org.apache.ignite.internal.processors.cache.CacheObjectValueContext;
+
+/**
+ * Wraps value provided by platform, must be transformed before stored in
cache.
+ */
+public class PlatformCacheObjectImpl extends CacheObjectImpl {
+ /** */
+ private static final long serialVersionUID = 0L;
+
+ /** */
+ @GridDirectTransient
+ private byte[] arr;
+
+ /**
+ *
+ */
+ public PlatformCacheObjectImpl() {
+ //No-op.
+ }
+
+ /**
+ * @param val Value.
+ * @param arr Value bytes.
+ */
+ public PlatformCacheObjectImpl(Object val, byte[] arr) {
+ super(val, null);
+
+ this.arr = arr;
+ }
+
+ /**
+ * @return Value bytes.
+ */
+ private byte[] valueBytesFromArray(CacheObjectValueContext ctx) {
+ assert arr != null;
+
+ return CacheObjectTransformerUtils.transformIfNecessary(arr, 0,
arr.length, ctx);
+ }
+
+ /** {@inheritDoc} */
+ @Override public CacheObject prepareForCache(CacheObjectContext ctx) {
+ if (valBytes == null)
+ valBytes = valueBytesFromArray(ctx);
+
+ return this;
+ }
+}
diff --git
a/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/client/ClientMessageParser.java
b/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/client/ClientMessageParser.java
index ab3fe4c1608..6a7562f1a1c 100644
---
a/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/client/ClientMessageParser.java
+++
b/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/client/ClientMessageParser.java
@@ -631,10 +631,10 @@ public class ClientMessageParser implements
ClientListenerMessageParser {
return new ClientServiceGetDescriptorRequest(reader);
case OP_DATA_STREAMER_START:
- return new ClientDataStreamerStartRequest(reader, ctx);
+ return new ClientDataStreamerStartRequest(reader);
case OP_DATA_STREAMER_ADD_DATA:
- return new ClientDataStreamerAddDataRequest(reader, ctx);
+ return new ClientDataStreamerAddDataRequest(reader);
case OP_ATOMIC_LONG_CREATE:
return new ClientAtomicLongCreateRequest(reader);
diff --git
a/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/client/cache/ClientCachePutAllConflictRequest.java
b/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/client/cache/ClientCachePutAllConflictRequest.java
index 4701f654e66..ac3182b751b 100644
---
a/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/client/cache/ClientCachePutAllConflictRequest.java
+++
b/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/client/cache/ClientCachePutAllConflictRequest.java
@@ -60,8 +60,8 @@ public class ClientCachePutAllConflictRequest extends
ClientCacheDataRequest imp
map = new LinkedHashMap<>(cnt);
for (int i = 0; i < cnt; i++) {
- KeyCacheObject key = readCacheObject(reader, true, ctx);
- CacheObject val = readCacheObject(reader, false, ctx);
+ KeyCacheObject key = readCacheObject(reader, true);
+ CacheObject val = readCacheObject(reader, false);
GridCacheVersion ver =
(GridCacheVersion)reader.readObjectDetached();
long expireTime = reader.readLong();
diff --git
a/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/client/cache/ClientCacheRemoveAllConflictRequest.java
b/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/client/cache/ClientCacheRemoveAllConflictRequest.java
index 168585bb099..c6e1a35f1d2 100644
---
a/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/client/cache/ClientCacheRemoveAllConflictRequest.java
+++
b/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/client/cache/ClientCacheRemoveAllConflictRequest.java
@@ -51,7 +51,7 @@ public class ClientCacheRemoveAllConflictRequest extends
ClientCacheDataRequest
map = new LinkedHashMap<>(cnt);
for (int i = 0; i < cnt; i++) {
- KeyCacheObject key = readCacheObject(reader, true, null);
+ KeyCacheObject key = readCacheObject(reader, true);
GridCacheVersion ver =
(GridCacheVersion)reader.readObjectDetached();
map.put(key, ver);
diff --git
a/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/client/streamer/ClientDataStreamerAddDataRequest.java
b/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/client/streamer/ClientDataStreamerAddDataRequest.java
index 9eaaec9e2e9..094e7ea02e0 100644
---
a/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/client/streamer/ClientDataStreamerAddDataRequest.java
+++
b/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/client/streamer/ClientDataStreamerAddDataRequest.java
@@ -47,12 +47,12 @@ public class ClientDataStreamerAddDataRequest extends
ClientDataStreamerRequest
*
* @param reader Data reader.
*/
- public ClientDataStreamerAddDataRequest(BinaryReaderExImpl reader,
ClientConnectionContext ctx) {
+ public ClientDataStreamerAddDataRequest(BinaryReaderExImpl reader) {
super(reader);
streamerId = reader.readLong();
flags = reader.readByte();
- entries = ClientDataStreamerReader.read(reader, ctx);
+ entries = ClientDataStreamerReader.read(reader);
}
/**
diff --git
a/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/client/streamer/ClientDataStreamerReader.java
b/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/client/streamer/ClientDataStreamerReader.java
index da1ea65bef8..278910459d1 100644
---
a/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/client/streamer/ClientDataStreamerReader.java
+++
b/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/client/streamer/ClientDataStreamerReader.java
@@ -21,7 +21,6 @@ import java.util.ArrayList;
import java.util.Collection;
import org.apache.ignite.internal.binary.BinaryReaderExImpl;
import org.apache.ignite.internal.processors.datastreamer.DataStreamerEntry;
-import
org.apache.ignite.internal.processors.platform.client.ClientConnectionContext;
import static
org.apache.ignite.internal.processors.platform.utils.PlatformUtils.readCacheObject;
@@ -35,7 +34,7 @@ class ClientDataStreamerReader {
* @param reader Data reader.
* @return Streamer entry.
*/
- public static Collection<DataStreamerEntry> read(BinaryReaderExImpl
reader, ClientConnectionContext ctx) {
+ public static Collection<DataStreamerEntry> read(BinaryReaderExImpl
reader) {
int entriesCnt = reader.readInt();
if (entriesCnt == 0)
@@ -43,10 +42,8 @@ class ClientDataStreamerReader {
Collection<DataStreamerEntry> entries = new ArrayList<>(entriesCnt);
- for (int i = 0; i < entriesCnt; i++) {
- entries.add(new DataStreamerEntry(readCacheObject(reader, true,
ctx),
- readCacheObject(reader, false, ctx)));
- }
+ for (int i = 0; i < entriesCnt; i++)
+ entries.add(new DataStreamerEntry(readCacheObject(reader, true),
readCacheObject(reader, false)));
return entries;
}
diff --git
a/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/client/streamer/ClientDataStreamerStartRequest.java
b/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/client/streamer/ClientDataStreamerStartRequest.java
index 7c96f423e69..6ea88a4c49b 100644
---
a/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/client/streamer/ClientDataStreamerStartRequest.java
+++
b/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/client/streamer/ClientDataStreamerStartRequest.java
@@ -72,7 +72,7 @@ public class ClientDataStreamerStartRequest extends
ClientDataStreamerRequest {
*
* @param reader Data reader.
*/
- public ClientDataStreamerStartRequest(BinaryReaderExImpl reader,
ClientConnectionContext ctx) {
+ public ClientDataStreamerStartRequest(BinaryReaderExImpl reader) {
super(reader);
cacheId = reader.readInt();
@@ -81,7 +81,7 @@ public class ClientDataStreamerStartRequest extends
ClientDataStreamerRequest {
perThreadBufferSize = reader.readInt();
receiverObj = reader.readObjectDetached();
receiverPlatform = receiverObj == null ? 0 : reader.readByte();
- entries = ClientDataStreamerReader.read(reader, ctx);
+ entries = ClientDataStreamerReader.read(reader);
}
/** {@inheritDoc} */
diff --git
a/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/utils/PlatformUtils.java
b/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/utils/PlatformUtils.java
index 94b99943d89..0690e145aab 100644
---
a/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/utils/PlatformUtils.java
+++
b/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/utils/PlatformUtils.java
@@ -61,14 +61,13 @@ import org.apache.ignite.internal.binary.BinaryUtils;
import org.apache.ignite.internal.binary.GridBinaryMarshaller;
import org.apache.ignite.internal.binary.streams.BinaryInputStream;
import org.apache.ignite.internal.processors.cache.CacheObject;
-import org.apache.ignite.internal.processors.cache.CacheObjectImpl;
import org.apache.ignite.internal.processors.cache.KeyCacheObjectImpl;
import
org.apache.ignite.internal.processors.cache.binary.CacheObjectBinaryProcessorImpl;
+import
org.apache.ignite.internal.processors.cacheobject.PlatformCacheObjectImpl;
import org.apache.ignite.internal.processors.platform.PlatformContext;
import
org.apache.ignite.internal.processors.platform.PlatformExtendedException;
import org.apache.ignite.internal.processors.platform.PlatformNativeException;
import org.apache.ignite.internal.processors.platform.PlatformProcessor;
-import
org.apache.ignite.internal.processors.platform.client.ClientConnectionContext;
import
org.apache.ignite.internal.processors.platform.dotnet.PlatformDotNetServiceImpl;
import
org.apache.ignite.internal.processors.platform.memory.PlatformInputStream;
import org.apache.ignite.internal.processors.platform.memory.PlatformMemory;
@@ -1374,9 +1373,8 @@ public class PlatformUtils {
*
* @param reader Reader.
* @param isKey {@code True} if object is a key.
- * @param ctx Client connection context.
*/
- public static <T extends CacheObject> T readCacheObject(BinaryReaderExImpl
reader, boolean isKey, ClientConnectionContext ctx) {
+ public static <T extends CacheObject> T readCacheObject(BinaryReaderExImpl
reader, boolean isKey) {
BinaryInputStream in = reader.in();
int pos0 = in.position();
@@ -1397,7 +1395,7 @@ public class PlatformUtils {
return isKey ?
(T)new KeyCacheObjectImpl(obj, objBytes, -1) :
- (T)new CacheObjectImpl(obj, ctx.kernalContext().transformer() ==
null ? objBytes : null);
+ (T)new PlatformCacheObjectImpl(obj, objBytes);
}
/**
diff --git
a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/transform/CacheObjectTransformationCacheApiTest.java
b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/transform/CacheObjectTransformationCacheApiTest.java
new file mode 100644
index 00000000000..4912ed91d97
--- /dev/null
+++
b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/transform/CacheObjectTransformationCacheApiTest.java
@@ -0,0 +1,282 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.internal.processors.cache.transform;
+
+import java.nio.ByteBuffer;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.function.Function;
+import org.apache.ignite.Ignite;
+import org.apache.ignite.IgniteCache;
+import org.apache.ignite.cache.CacheAtomicityMode;
+import org.apache.ignite.client.ClientCache;
+import org.apache.ignite.client.IgniteClient;
+import org.apache.ignite.cluster.ClusterState;
+import org.apache.ignite.configuration.CacheConfiguration;
+import org.apache.ignite.configuration.ClientConfiguration;
+import org.apache.ignite.configuration.DataRegionConfiguration;
+import org.apache.ignite.configuration.IgniteConfiguration;
+import org.apache.ignite.internal.client.thin.TcpClientCache;
+import org.apache.ignite.internal.processors.cache.version.GridCacheVersion;
+import org.apache.ignite.internal.util.typedef.G;
+import org.apache.ignite.internal.util.typedef.T3;
+import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+import static
org.apache.ignite.internal.binary.GridBinaryMarshaller.TRANSFORMED;
+
+/**
+ * Checks transformation works via public and private cache API.
+ */
+@RunWith(Parameterized.class)
+public class CacheObjectTransformationCacheApiTest extends
GridCommonAbstractTest {
+ /** Region name. */
+ private static final String REGION_NAME = "region";
+
+ /** Cache name. */
+ protected static final String CACHE_NAME = "data";
+
+ /** Nodes count. */
+ protected static final int NODES = 3;
+
+ /** Atomicity mode. */
+ @Parameterized.Parameter()
+ public CacheAtomicityMode mode;
+
+ /** Persistence enabled flag. */
+ @Parameterized.Parameter(1)
+ public boolean persistence;
+
+ /** Generator. */
+ @Parameterized.Parameter(2)
+ public Gen gen;
+
+ /** @return Test parameters. */
+ @Parameterized.Parameters(name = "mode={0}, persistence={1}, gen={2}")
+ public static Collection<?> parameters() {
+ List<Object[]> res = new ArrayList<>();
+
+ for (CacheAtomicityMode mode : CacheAtomicityMode.values())
+ for (boolean persistence : new boolean[] {true, false})
+ for (Gen gen : Gen.values())
+ res.add(new Object[] {mode, persistence, gen});
+
+ return res;
+ }
+
+ /** {@inheritDoc} */
+ @Override protected void beforeTest() throws Exception {
+ super.beforeTest();
+
+ cleanPersistenceDir();
+
+ Ignite ignite = startGrids(NODES);
+
+ if (persistence)
+ ignite.cluster().state(ClusterState.ACTIVE);
+
+ awaitPartitionMapExchange();
+ }
+
+ /** {@inheritDoc} */
+ @Override protected void afterTest() throws Exception {
+ super.afterTest();
+
+ stopAllGrids();
+
+ cleanPersistenceDir();
+ }
+
+ /** {@inheritDoc} */
+ @Override protected IgniteConfiguration getConfiguration(String
igniteInstanceName) throws Exception {
+ IgniteConfiguration cfg = super.getConfiguration(igniteInstanceName);
+
+ DataRegionConfiguration drCgf = new DataRegionConfiguration()
+ .setName(REGION_NAME)
+ .setMaxSize(1000L * 1024 * 1024)
+ .setInitialSize(1000L * 1024 * 1024);
+
+ if (persistence)
+ drCgf.setPersistenceEnabled(true);
+
+ cfg.setPluginProviders(
+ new TestCacheObjectTransformerPluginProvider(new
CacheObjectDuplicatorTransformer()));
+
+ CacheConfiguration<?, ?> cCfg = new
CacheConfiguration<>(CACHE_NAME).setAtomicityMode(mode);
+
+ cfg.setCacheConfiguration(cCfg);
+
+ return cfg;
+ }
+
+ /** */
+ @Test
+ public void testCachePut() {
+ Ignite ignite = grid(0);
+
+ IgniteCache<Object, Object> cache =
ignite.getOrCreateCache(CACHE_NAME);
+
+ for (int i = 0; i < 100; i++) {
+ Object val = gen.apply(i);
+
+ cache.put(i, val);
+ cache.put(i, val); // Override check.
+
+ assertEqualsArraysAware(cache.get(i), val);
+ }
+ }
+
+ /** */
+ @Test
+ public void testClientCachePut() {
+ Ignite ignite = grid(0);
+
+ String host = ignite.configuration().getLocalHost();
+ int port =
ignite.configuration().getClientConnectorConfiguration().getPort();
+
+ try (IgniteClient client = G.startClient(new
ClientConfiguration().setAddresses(host + ":" + port))) {
+ ClientCache<Object, Object> cache = client.cache(CACHE_NAME);
+
+ for (int i = 0; i < 100; i++) {
+ Object val = gen.apply(i);
+
+ if (i % 2 == 0) {
+ cache.put(i, val);
+ cache.put(i, val); // Override check.
+ }
+ else {
+ Map<Object, T3<Object, GridCacheVersion, Long>> data = new
HashMap<>();
+
+ GridCacheVersion otherVer = new GridCacheVersion(1, 1, 1,
0);
+
+ data.put(i, new T3<>(val, otherVer, 0L));
+
+ ((TcpClientCache)cache).putAllConflict(data);
+ ((TcpClientCache)cache).putAllConflict(data); // Override
check.
+ }
+
+ assertEqualsArraysAware(cache.get(i), val);
+ }
+ }
+ }
+
+ /**
+ * Transforms each object with a shift.
+ */
+ private static final class CacheObjectDuplicatorTransformer extends
TestCacheObjectTransformerProcessorAdapter {
+ /** {@inheritDoc} */
+ @Override public ByteBuffer transform(ByteBuffer original) {
+ ByteBuffer transformed = ByteBuffer.wrap(new
byte[original.remaining() * 2 + 1]);
+
+ transformed.put(TRANSFORMED);
+
+ while (original.hasRemaining()) {
+ byte b = original.get();
+
+ transformed.put(b);
+ transformed.put(b);
+ }
+
+ transformed.flip();
+
+ return transformed;
+ }
+
+ /** {@inheritDoc} */
+ @Override public ByteBuffer restore(ByteBuffer transformed) {
+ ByteBuffer restored = ByteBuffer.wrap(new
byte[transformed.remaining() / 2]);
+
+ while (transformed.hasRemaining()) {
+ byte b1 = transformed.get();
+ byte b2 = transformed.get();
+
+ assertEquals(b1, b2);
+
+ restored.put(b1);
+ }
+
+ restored.flip();
+
+ return restored;
+ }
+ }
+
+ /** */
+ private static final class TestData {
+ /** */
+ int i;
+
+ /** */
+ public TestData(int i) {
+ this.i = i;
+ }
+
+ /** {@inheritDoc} */
+ @Override public boolean equals(Object o) {
+ if (this == o)
+ return true;
+ if (o == null || getClass() != o.getClass())
+ return false;
+
+ TestData data = (TestData)o;
+
+ return i == data.i;
+ }
+
+ /** {@inheritDoc} */
+ @Override public int hashCode() {
+ return i;
+ }
+ }
+
+ /** */
+ private enum Gen {
+ /** */
+ INT((i) -> i),
+
+ /** */
+ ARR((i) -> new int[] {i}),
+
+ /** */
+ STR(String::valueOf),
+
+ /** */
+ OBJ(TestData::new),
+
+ /** */
+ ARR_OBJ((i) -> new TestData[] {new TestData(i)});
+
+ /** */
+ private final Function<Integer, Object> gen;
+
+ /** */
+ Gen(Function<Integer, Object> gen) {
+ this.gen = gen;
+ }
+
+ /** */
+ private Object apply(Integer i) {
+ return gen.apply(i);
+ }
+ }
+}
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 dd1729f44b2..0759c5f8f01 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
@@ -42,6 +42,7 @@ import
org.apache.ignite.internal.processors.cache.distributed.FailBackupOnAtomi
import
org.apache.ignite.internal.processors.cache.distributed.rebalancing.RebalanceStatisticsTest;
import
org.apache.ignite.internal.processors.cache.transactions.TxAsyncOpsSemaphorePermitsExceededTest;
import
org.apache.ignite.internal.processors.cache.transactions.TxRecoveryOnCoordniatorFailTest;
+import
org.apache.ignite.internal.processors.cache.transform.CacheObjectTransformationCacheApiTest;
import
org.apache.ignite.internal.processors.cache.transform.CacheObjectTransformationEvolutionTest;
import
org.apache.ignite.internal.processors.cache.transform.CacheObjectTransformationTest;
import
org.apache.ignite.internal.processors.cluster.ClusterNameBeforeActivation;
@@ -106,6 +107,8 @@ public class IgniteCacheTestSuite13 {
GridTestUtils.addTestIfNeeded(suite,
CacheObjectTransformationTest.class, ignoredTests);
GridTestUtils.addTestIfNeeded(suite,
CacheObjectTransformationEvolutionTest.class, ignoredTests);
+ GridTestUtils.addTestIfNeeded(suite,
CacheObjectTransformationCacheApiTest.class, ignoredTests);
+
GridTestUtils.addTestIfNeeded(suite,
ContinuousQueryBuffersCleanupTest.class, ignoredTests);
return suite;