ignite-1258: supported CacheConfiguration.keepPortableInStore and 
IgniteCache.withKeepPortable flags. Completed with 
IgnitePortableObjestsTestSuite


Project: http://git-wip-us.apache.org/repos/asf/incubator-ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-ignite/commit/0b213587
Tree: http://git-wip-us.apache.org/repos/asf/incubator-ignite/tree/0b213587
Diff: http://git-wip-us.apache.org/repos/asf/incubator-ignite/diff/0b213587

Branch: refs/heads/ignite-1258
Commit: 0b2135872fd4474d39002602f97fc926e89c437e
Parents: 9698133
Author: Denis Magda <dma...@gridgain.com>
Authored: Wed Aug 19 11:44:51 2015 +0300
Committer: Denis Magda <dma...@gridgain.com>
Committed: Wed Aug 19 11:44:51 2015 +0300

----------------------------------------------------------------------
 .../java/org/apache/ignite/IgniteCache.java     |  41 +
 .../configuration/CacheConfiguration.java       |  36 +
 .../communication/GridIoMessageFactory.java     |   6 +
 .../portable/GridPortableObjectImpl.java        |   2 +-
 .../processors/cache/GridCacheProcessor.java    |   5 +
 .../processors/cache/IgniteCacheProxy.java      |   5 +
 .../cache/store/CacheOsStoreManager.java        |   3 +-
 .../GridPortableBuilderAdditionalSelfTest.java  |   5 +-
 .../portable/GridPortableBuilderSelfTest.java   |   2 +-
 .../GridPortableMarshalerAwareTestClass.java    |  62 --
 .../portable/GridPortableTestClasses.java       | 425 --------
 .../portable/GridPortableWildcardsSelfTest.java |   2 +-
 .../GridPortableMarshalerAwareTestClass.java    |  62 ++
 .../mutabletest/GridPortableTestClasses.java    | 425 ++++++++
 .../portable/mutabletest/package-info.java      |  22 +
 .../internal/portable/test/package-info.java    |  22 +
 .../portable/test/subpackage/package-info.java  |  22 +
 ...ClientNodePortableMetadataMultinodeTest.java | 277 ++++++
 ...GridCacheClientNodePortableMetadataTest.java | 280 ++++++
 ...ableObjectsAbstractDataStreamerSelfTest.java | 183 ++++
 ...bleObjectsAbstractMultiThreadedSelfTest.java | 222 +++++
 ...ridCachePortableObjectsAbstractSelfTest.java | 958 +++++++++++++++++++
 .../GridCachePortableStoreAbstractSelfTest.java | 294 ++++++
 .../GridCachePortableStoreObjectsSelfTest.java  |  55 ++
 ...GridCachePortableStorePortablesSelfTest.java |  67 ++
 ...leDuplicateIndexObjectsAbstractSelfTest.java | 153 +++
 .../DataStreamProcessorPortableSelfTest.java    |  67 ++
 .../GridDataStreamerImplSelfTest.java           | 338 +++++++
 ...arEnabledPortableEnabledFullApiSelfTest.java |  37 +
 ...lyPortableDataStreamerMultiNodeSelfTest.java |  29 +
 ...rtableDataStreamerMultithreadedSelfTest.java |  46 +
 ...artitionedOnlyPortableMultiNodeSelfTest.java |  28 +
 ...tionedOnlyPortableMultithreadedSelfTest.java |  46 +
 ...PortableEnabledFullApiMultiNodeSelfTest.java |  36 +
 ...cheAtomicPortableEnabledFullApiSelfTest.java |  36 +
 .../GridCacheMemoryModePortableSelfTest.java    |  36 +
 ...omicPortableMultiThreadedUpdateSelfTest.java |  37 +
 ...arEnabledPortableEnabledFullApiSelfTest.java |  33 +
 ...PortableEnabledFullApiMultiNodeSelfTest.java |  33 +
 ...redAtomicPortableEnabledFullApiSelfTest.java |  33 +
 ...acheOffHeapTieredAtomicPortableSelfTest.java |  48 +
 ...eapTieredEvictionAtomicPortableSelfTest.java |  96 ++
 ...heOffHeapTieredEvictionPortableSelfTest.java |  96 ++
 ...rDisabledPortableEnabledFullApiSelfTest.java |  32 +
 ...PortableEnabledFullApiMultiNodeSelfTest.java |  33 +
 ...rtitionedPortableEnabledFullApiSelfTest.java |  33 +
 .../GridCacheOffHeapTieredPortableSelfTest.java |  48 +
 ...rDisabledPortableEnabledFullApiSelfTest.java |  37 +
 ...PortableEnabledFullApiMultiNodeSelfTest.java |  37 +
 ...rtitionedPortableEnabledFullApiSelfTest.java |  36 +
 ...ateIndexObjectPartitionedAtomicSelfTest.java |  37 +
 ...xObjectPartitionedTransactionalSelfTest.java |  40 +
 ...AtomicNearDisabledOffheapTieredSelfTest.java |  29 +
 ...rtableObjectsAtomicNearDisabledSelfTest.java |  50 +
 ...tableObjectsAtomicOffheapTieredSelfTest.java |  29 +
 .../GridCachePortableObjectsAtomicSelfTest.java |  50 +
 ...tionedNearDisabledOffheapTieredSelfTest.java |  30 +
 ...eObjectsPartitionedNearDisabledSelfTest.java |  50 +
 ...ObjectsPartitionedOffheapTieredSelfTest.java |  30 +
 ...CachePortableObjectsPartitionedSelfTest.java |  50 +
 ...sNearPartitionedByteArrayValuesSelfTest.java |  41 +
 ...sPartitionedOnlyByteArrayValuesSelfTest.java |  42 +
 ...eplicatedPortableEnabledFullApiSelfTest.java |  33 +
 ...dCachePortableObjectsReplicatedSelfTest.java |  50 +
 ...eplicatedPortableEnabledFullApiSelfTest.java |  36 +
 ...omicLocalPortableEnabledFullApiSelfTest.java |  42 +
 ...acheLocalPortableEnabledFullApiSelfTest.java |  35 +
 ...omicLocalPortableEnabledFullApiSelfTest.java |  33 +
 ...eredLocalPortableEnabledFullApiSelfTest.java |  33 +
 ...CachePortableObjectsAtomicLocalSelfTest.java |  32 +
 ...rtableObjectsLocalOffheapTieredSelfTest.java |  29 +
 .../GridCachePortableObjectsLocalSelfTest.java  |  50 +
 .../multijvm/IgniteCacheProcessProxy.java       |   5 +
 .../IgnitePortableObjectsTestSuite.java         | 141 ++-
 74 files changed, 5400 insertions(+), 564 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/0b213587/modules/core/src/main/java/org/apache/ignite/IgniteCache.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/IgniteCache.java 
b/modules/core/src/main/java/org/apache/ignite/IgniteCache.java
index fd0112c..c9ff955 100644
--- a/modules/core/src/main/java/org/apache/ignite/IgniteCache.java
+++ b/modules/core/src/main/java/org/apache/ignite/IgniteCache.java
@@ -25,6 +25,7 @@ import org.apache.ignite.cache.store.*;
 import org.apache.ignite.cluster.*;
 import org.apache.ignite.configuration.*;
 import org.apache.ignite.lang.*;
+import org.apache.ignite.marshaller.portable.*;
 import org.apache.ignite.mxbean.*;
 import org.jetbrains.annotations.*;
 
@@ -35,7 +36,9 @@ import javax.cache.expiry.*;
 import javax.cache.integration.*;
 import javax.cache.processor.*;
 import java.io.*;
+import java.sql.*;
 import java.util.*;
+import java.util.Date;
 import java.util.concurrent.*;
 import java.util.concurrent.locks.*;
 
@@ -112,6 +115,44 @@ public interface IgniteCache<K, V> extends 
javax.cache.Cache<K, V>, IgniteAsyncS
     public IgniteCache<K, V> withNoRetries();
 
     /**
+     * Returns cache that will operate with portable objects.
+     * <p>
+     * Cache returned by this method will not be forced to deserialize 
portable objects,
+     * so keys and values will be returned from cache API methods without 
changes. Therefore,
+     * signature of the cache can contain only following types:
+     * <ul>
+     *     <li><code>org.apache.ignite.portable.PortableObject</code> for 
portable classes</li>
+     *     <li>All primitives (byte, int, ...) and there boxed versions (Byte, 
Integer, ...)</li>
+     *     <li>Arrays of primitives (byte[], int[], ...)</li>
+     *     <li>{@link String} and array of {@link String}s</li>
+     *     <li>{@link UUID} and array of {@link UUID}s</li>
+     *     <li>{@link Date} and array of {@link Date}s</li>
+     *     <li>{@link Timestamp} and array of {@link Timestamp}s</li>
+     *     <li>Enums and array of enums</li>
+     *     <li>
+     *         Maps, collections and array of objects (but objects inside
+     *         them will still be converted if they are portable)
+     *     </li>
+     * </ul>
+     * <p>
+     * For example, if you use {@link Integer} as a key and {@code Value} 
class as a value
+     * (which will be stored in portable format), you should acquire following 
projection
+     * to avoid deserialization:
+     * <pre>
+     * IgniteCache<Integer, PortableObject> prj = cache.withKeepPortable();
+     *
+     * // Value is not deserialized and returned in portable format.
+     * PortableObject po = prj.get(1);
+     * </pre>
+     * <p>
+     * Note that this method makes sense only if cache is working in portable 
mode ({@link PortableMarshaller} is used).
+     * If not, this method is no-op and will return current cache.
+     *
+     * @return New cache instance for portable objects.
+     */
+    public <K1, V1> IgniteCache<K1, V1> withKeepPortable();
+
+    /**
      * Executes {@link #localLoadCache(IgniteBiPredicate, Object...)} on all 
cache nodes.
      *
      * @param p Optional predicate (may be {@code null}). If provided, will be 
used to

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/0b213587/modules/core/src/main/java/org/apache/ignite/configuration/CacheConfiguration.java
----------------------------------------------------------------------
diff --git 
a/modules/core/src/main/java/org/apache/ignite/configuration/CacheConfiguration.java
 
b/modules/core/src/main/java/org/apache/ignite/configuration/CacheConfiguration.java
index 3ad0f01..4635f4c 100644
--- 
a/modules/core/src/main/java/org/apache/ignite/configuration/CacheConfiguration.java
+++ 
b/modules/core/src/main/java/org/apache/ignite/configuration/CacheConfiguration.java
@@ -205,6 +205,9 @@ public class CacheConfiguration<K, V> extends 
MutableConfiguration<K, V> {
     private Factory storeFactory;
 
     /** */
+    private boolean keepPortableInStore = true;
+
+    /** */
     private boolean loadPrevVal = DFLT_LOAD_PREV_VAL;
 
     /** Node group resolver. */
@@ -366,6 +369,7 @@ public class CacheConfiguration<K, V> extends 
MutableConfiguration<K, V> {
         invalidate = cc.isInvalidate();
         isReadThrough = cc.isReadThrough();
         isWriteThrough = cc.isWriteThrough();
+        keepPortableInStore = cc.isKeepPortableInStore();
         listenerConfigurations = cc.listenerConfigurations;
         loadPrevVal = cc.isLoadPreviousValue();
         longQryWarnTimeout = cc.getLongQueryWarningTimeout();
@@ -806,6 +810,38 @@ public class CacheConfiguration<K, V> extends 
MutableConfiguration<K, V> {
     }
 
     /**
+     * Flag indicating that {@link CacheStore} implementation
+     * is working with portable objects instead of Java objects.
+     * Default value of this flag is {@code true},
+     * because this is recommended behavior from performance standpoint.
+     * <p>
+     * If set to {@code false}, Ignite will deserialize keys and
+     * values stored in portable format before they are passed
+     * to cache store.
+     * <p>
+     * Note that setting this flag to {@code false} can simplify
+     * store implementation in some cases, but it can cause performance
+     * degradation due to additional serializations and deserializations
+     * of portable objects. You will also need to have key and value
+     * classes on all nodes since portables will be deserialized when
+     * store is called.
+     *
+     * @return Keep portables in store flag.
+     */
+    public boolean isKeepPortableInStore() {
+        return keepPortableInStore;
+    }
+
+    /**
+     * Sets keep portables in store flag.
+     *
+     * @param keepPortableInStore Keep portables in store flag.
+     */
+    public void setKeepPortableInStore(boolean keepPortableInStore) {
+        this.keepPortableInStore = keepPortableInStore;
+    }
+
+    /**
      * Gets key topology resolver to provide mapping from keys to nodes.
      *
      * @return Key topology resolver to provide mapping from keys to nodes.

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/0b213587/modules/core/src/main/java/org/apache/ignite/internal/managers/communication/GridIoMessageFactory.java
----------------------------------------------------------------------
diff --git 
a/modules/core/src/main/java/org/apache/ignite/internal/managers/communication/GridIoMessageFactory.java
 
b/modules/core/src/main/java/org/apache/ignite/internal/managers/communication/GridIoMessageFactory.java
index 7fe8da8..c170a24 100644
--- 
a/modules/core/src/main/java/org/apache/ignite/internal/managers/communication/GridIoMessageFactory.java
+++ 
b/modules/core/src/main/java/org/apache/ignite/internal/managers/communication/GridIoMessageFactory.java
@@ -22,6 +22,7 @@ import org.apache.ignite.internal.*;
 import org.apache.ignite.internal.managers.checkpoint.*;
 import org.apache.ignite.internal.managers.deployment.*;
 import org.apache.ignite.internal.managers.eventstorage.*;
+import org.apache.ignite.internal.portable.*;
 import org.apache.ignite.internal.processors.affinity.*;
 import org.apache.ignite.internal.processors.cache.*;
 import org.apache.ignite.internal.processors.cache.distributed.*;
@@ -600,6 +601,11 @@ public class GridIoMessageFactory implements 
MessageFactory {
 
                 break;
 
+            case 113:
+                msg = new GridPortableObjectImpl();
+
+                break;
+
             // [-3..112] - this
             // [120..123] - DR
             // [-4..-22] - SQL

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/0b213587/modules/core/src/main/java/org/apache/ignite/internal/portable/GridPortableObjectImpl.java
----------------------------------------------------------------------
diff --git 
a/modules/core/src/main/java/org/apache/ignite/internal/portable/GridPortableObjectImpl.java
 
b/modules/core/src/main/java/org/apache/ignite/internal/portable/GridPortableObjectImpl.java
index dcbc1b8..773c69d 100644
--- 
a/modules/core/src/main/java/org/apache/ignite/internal/portable/GridPortableObjectImpl.java
+++ 
b/modules/core/src/main/java/org/apache/ignite/internal/portable/GridPortableObjectImpl.java
@@ -373,7 +373,7 @@ public final class GridPortableObjectImpl extends 
GridPortableObjectEx implement
 
     /** {@inheritDoc} */
     @Override public byte directType() {
-        return 123;
+        return 113;
     }
 
     /** {@inheritDoc} */

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/0b213587/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheProcessor.java
----------------------------------------------------------------------
diff --git 
a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheProcessor.java
 
b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheProcessor.java
index a7d6bf6..e8d40fa 100644
--- 
a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheProcessor.java
+++ 
b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheProcessor.java
@@ -55,6 +55,7 @@ import org.apache.ignite.lang.*;
 import org.apache.ignite.lifecycle.*;
 import org.apache.ignite.marshaller.*;
 import org.apache.ignite.marshaller.jdk.*;
+import org.apache.ignite.marshaller.portable.*;
 import org.apache.ignite.spi.*;
 import org.jetbrains.annotations.*;
 
@@ -1027,6 +1028,10 @@ public class GridCacheProcessor extends 
GridProcessorAdapter {
 
         CacheConfiguration cfg = cacheCtx.config();
 
+        if (cfg.isKeepPortableInStore() && !(ctx.config().getMarshaller() 
instanceof PortableMarshaller))
+            U.warn(log, "CacheConfiguration.isKeepPortableInStore() 
configuration property will be ignored because " +
+                "PortableMarshaller is not used");
+
         // Start managers.
         for (GridCacheManager mgr : F.view(cacheCtx.managers(), 
F.notContains(dhtExcludes(cacheCtx))))
             mgr.start(cacheCtx);

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/0b213587/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/IgniteCacheProxy.java
----------------------------------------------------------------------
diff --git 
a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/IgniteCacheProxy.java
 
b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/IgniteCacheProxy.java
index e532778..3381403 100644
--- 
a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/IgniteCacheProxy.java
+++ 
b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/IgniteCacheProxy.java
@@ -272,6 +272,11 @@ public class IgniteCacheProxy<K, V> extends 
AsyncSupportAdapter<IgniteCache<K, V
     }
 
     /** {@inheritDoc} */
+    @Override public <K1, V1> IgniteCache<K1, V1> withKeepPortable() {
+        return keepPortable();
+    }
+
+    /** {@inheritDoc} */
     @Override public IgniteCache<K, V> withNoRetries() {
         GridCacheGateway<K, V> gate = this.gate;
 

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/0b213587/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/store/CacheOsStoreManager.java
----------------------------------------------------------------------
diff --git 
a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/store/CacheOsStoreManager.java
 
b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/store/CacheOsStoreManager.java
index 02fe679..f11df41 100644
--- 
a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/store/CacheOsStoreManager.java
+++ 
b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/store/CacheOsStoreManager.java
@@ -19,6 +19,7 @@ package org.apache.ignite.internal.processors.cache.store;
 
 import org.apache.ignite.configuration.*;
 import org.apache.ignite.internal.*;
+import org.apache.ignite.marshaller.portable.*;
 
 /**
  * Default store manager implementation.
@@ -53,6 +54,6 @@ public class CacheOsStoreManager extends 
GridCacheStoreManagerAdapter {
 
     /** {@inheritDoc} */
     @Override protected boolean convertPortable() {
-        return true;
+        return !(cfg.isKeepPortableInStore() && ctx.config().getMarshaller() 
instanceof PortableMarshaller);
     }
 }

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/0b213587/modules/core/src/test/java/org/apache/ignite/internal/portable/GridPortableBuilderAdditionalSelfTest.java
----------------------------------------------------------------------
diff --git 
a/modules/core/src/test/java/org/apache/ignite/internal/portable/GridPortableBuilderAdditionalSelfTest.java
 
b/modules/core/src/test/java/org/apache/ignite/internal/portable/GridPortableBuilderAdditionalSelfTest.java
index f3b29f7..97baa59 100644
--- 
a/modules/core/src/test/java/org/apache/ignite/internal/portable/GridPortableBuilderAdditionalSelfTest.java
+++ 
b/modules/core/src/test/java/org/apache/ignite/internal/portable/GridPortableBuilderAdditionalSelfTest.java
@@ -19,6 +19,7 @@ package org.apache.ignite.internal.portable;
 
 import org.apache.ignite.*;
 import org.apache.ignite.configuration.*;
+import org.apache.ignite.internal.portable.mutabletest.*;
 import org.apache.ignite.internal.processors.cache.portable.*;
 import org.apache.ignite.internal.util.lang.*;
 import org.apache.ignite.marshaller.portable.*;
@@ -35,7 +36,7 @@ import java.util.*;
 import java.util.Date;
 
 import static org.apache.ignite.cache.CacheMode.*;
-import static org.apache.ignite.internal.portable.GridPortableTestClasses.*;
+import static 
org.apache.ignite.internal.portable.mutabletest.GridPortableTestClasses.*;
 
 /**
  *
@@ -53,7 +54,7 @@ public class GridPortableBuilderAdditionalSelfTest extends 
GridCommonAbstractTes
 
         PortableMarshaller marsh = new PortableMarshaller();
 
-        
marsh.setClassNames(Arrays.asList("org.gridgain.grid.internal.util.portable.mutabletest.*"));
+        
marsh.setClassNames(Arrays.asList("org.apache.ignite.internal.portable.mutabletest.*"));
 
         marsh.setConvertStringToBytes(useUtf8());
 

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/0b213587/modules/core/src/test/java/org/apache/ignite/internal/portable/GridPortableBuilderSelfTest.java
----------------------------------------------------------------------
diff --git 
a/modules/core/src/test/java/org/apache/ignite/internal/portable/GridPortableBuilderSelfTest.java
 
b/modules/core/src/test/java/org/apache/ignite/internal/portable/GridPortableBuilderSelfTest.java
index a8d8b5e..a91c53e 100644
--- 
a/modules/core/src/test/java/org/apache/ignite/internal/portable/GridPortableBuilderSelfTest.java
+++ 
b/modules/core/src/test/java/org/apache/ignite/internal/portable/GridPortableBuilderSelfTest.java
@@ -27,7 +27,7 @@ import org.apache.ignite.portable.*;
 import org.apache.ignite.testframework.*;
 import org.apache.ignite.testframework.junits.common.*;
 
-import org.apache.ignite.internal.portable.GridPortableTestClasses.*;
+import 
org.apache.ignite.internal.portable.mutabletest.GridPortableTestClasses.*;
 import sun.misc.*;
 
 import java.math.*;

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/0b213587/modules/core/src/test/java/org/apache/ignite/internal/portable/GridPortableMarshalerAwareTestClass.java
----------------------------------------------------------------------
diff --git 
a/modules/core/src/test/java/org/apache/ignite/internal/portable/GridPortableMarshalerAwareTestClass.java
 
b/modules/core/src/test/java/org/apache/ignite/internal/portable/GridPortableMarshalerAwareTestClass.java
deleted file mode 100644
index 14c0070..0000000
--- 
a/modules/core/src/test/java/org/apache/ignite/internal/portable/GridPortableMarshalerAwareTestClass.java
+++ /dev/null
@@ -1,62 +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.portable;
-
-import org.apache.ignite.internal.util.typedef.internal.*;
-import org.apache.ignite.portable.*;
-import org.apache.ignite.testframework.*;
-
-/**
- *
- */
-public class GridPortableMarshalerAwareTestClass implements 
PortableMarshalAware {
-    /** */
-    public String s;
-
-    /** */
-    public String sRaw;
-
-    /** {@inheritDoc} */
-    @Override public void writePortable(PortableWriter writer) throws 
PortableException {
-        writer.writeString("s", s);
-
-        PortableRawWriter raw = writer.rawWriter();
-
-        raw.writeString(sRaw);
-    }
-
-    /** {@inheritDoc} */
-    @Override public void readPortable(PortableReader reader) throws 
PortableException {
-        s = reader.readString("s");
-
-        PortableRawReader raw = reader.rawReader();
-
-        sRaw = raw.readString();
-    }
-
-    /** {@inheritDoc} */
-    @SuppressWarnings("FloatingPointEquality")
-    @Override public boolean equals(Object other) {
-        return this == other || GridTestUtils.deepEquals(this, other);
-    }
-
-    /** {@inheritDoc} */
-    @Override public String toString() {
-        return S.toString(GridPortableMarshalerAwareTestClass.class, this);
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/0b213587/modules/core/src/test/java/org/apache/ignite/internal/portable/GridPortableTestClasses.java
----------------------------------------------------------------------
diff --git 
a/modules/core/src/test/java/org/apache/ignite/internal/portable/GridPortableTestClasses.java
 
b/modules/core/src/test/java/org/apache/ignite/internal/portable/GridPortableTestClasses.java
deleted file mode 100644
index 1917f59..0000000
--- 
a/modules/core/src/test/java/org/apache/ignite/internal/portable/GridPortableTestClasses.java
+++ /dev/null
@@ -1,425 +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.portable;
-
-import org.apache.ignite.internal.util.lang.*;
-import org.apache.ignite.portable.*;
-
-import com.google.common.base.*;
-
-import java.io.*;
-import java.util.*;
-
-/**
- *
- */
-@SuppressWarnings({"PublicInnerClass", "PublicField"})
-public class GridPortableTestClasses {
-    /**
-     *
-     */
-    public static class TestObjectContainer {
-        /** */
-        public Object foo;
-
-        /**
-         *
-         */
-        public TestObjectContainer() {
-            // No-op.
-        }
-
-        /**
-         * @param foo Object.
-         */
-        public TestObjectContainer(Object foo) {
-            this.foo = foo;
-        }
-    }
-
-    /**
-     *
-     */
-    public static class TestObjectOuter {
-        /** */
-        public TestObjectInner inner;
-
-        /** */
-        public String foo;
-
-        /**
-         *
-         */
-        public TestObjectOuter() {
-
-        }
-
-        /**
-         * @param inner Inner object.
-         */
-        public TestObjectOuter(TestObjectInner inner) {
-            this.inner = inner;
-        }
-    }
-
-    /** */
-    public static class TestObjectInner {
-        /** */
-        public Object foo;
-
-        /** */
-        public TestObjectOuter outer;
-    }
-
-    /** */
-    public static class TestObjectArrayList {
-        /** */
-        public List<String> list = new ArrayList<>();
-    }
-
-    /**
-     *
-     */
-    public static class TestObjectPlainPortable {
-        /** */
-        public PortableObject plainPortable;
-
-        /**
-         *
-         */
-        public TestObjectPlainPortable() {
-            // No-op.
-        }
-
-        /**
-         * @param plainPortable Object.
-         */
-        public TestObjectPlainPortable(PortableObject plainPortable) {
-            this.plainPortable = plainPortable;
-        }
-    }
-
-    /**
-     *
-     */
-    public static class TestObjectAllTypes implements Serializable {
-        /** */
-        public Byte b_;
-
-        /** */
-        public Short s_;
-
-        /** */
-        public Integer i_;
-
-        /** */
-        public Long l_;
-
-        /** */
-        public Float f_;
-
-        /** */
-        public Double d_;
-
-        /** */
-        public Character c_;
-
-        /** */
-        public Boolean z_;
-
-        /** */
-        public byte b;
-
-        /** */
-        public short s;
-
-        /** */
-        public int i;
-
-        /** */
-        public long l;
-
-        /** */
-        public float f;
-
-        /** */
-        public double d;
-
-        /** */
-        public char c;
-
-        /** */
-        public boolean z;
-
-        /** */
-        public String str;
-
-        /** */
-        public UUID uuid;
-
-        /** */
-        public Date date;
-
-
-        /** */
-        public byte[] bArr;
-
-        /** */
-        public short[] sArr;
-
-        /** */
-        public int[] iArr;
-
-        /** */
-        public long[] lArr;
-
-        /** */
-        public float[] fArr;
-
-        /** */
-        public double[] dArr;
-
-        /** */
-        public char[] cArr;
-
-        /** */
-        public boolean[] zArr;
-
-        /** */
-        public String[] strArr;
-
-        /** */
-        public UUID[] uuidArr;
-
-        /** */
-        public TestObjectEnum anEnum;
-
-        /** */
-        public TestObjectEnum[] enumArr;
-
-        /** */
-        public Map.Entry entry;
-
-        //public Date[] dateArr; // todo test date array.
-
-        /**
-         * @return Array.
-         */
-        private byte[] serialize() {
-            ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
-
-            try {
-                ObjectOutput out = new ObjectOutputStream(byteOut);
-
-                out.writeObject(this);
-
-                out.close();
-            }
-            catch (IOException e) {
-                Throwables.propagate(e);
-            }
-
-            return byteOut.toByteArray();
-        }
-
-        /**
-         *
-         */
-        public void setDefaultData() {
-            b_ = 11;
-            s_ = 22;
-            i_ = 33;
-            l_ = 44L;
-            f_ = 55f;
-            d_ = 66d;
-            c_ = 'e';
-            z_ = true;
-
-            b = 1;
-            s = 2;
-            i = 3;
-            l = 4;
-            f = 5;
-            d = 6;
-            c = 7;
-            z = true;
-
-            str = "abc";
-            uuid = new UUID(1, 1);
-            date = new Date(1000000);
-
-            bArr = new byte[]{1, 2, 3};
-            sArr = new short[]{1, 2, 3};
-            iArr = new int[]{1, 2, 3};
-            lArr = new long[]{1, 2, 3};
-            fArr = new float[]{1, 2, 3};
-            dArr = new double[]{1, 2, 3};
-            cArr = new char[]{1, 2, 3};
-            zArr = new boolean[]{true, false};
-
-            strArr = new String[]{"abc", "ab", "a"};
-            uuidArr = new UUID[]{new UUID(1, 1), new UUID(2, 2)};
-
-            anEnum = TestObjectEnum.A;
-
-            enumArr = new TestObjectEnum[]{TestObjectEnum.B};
-
-            entry = new GridMapEntry<>(1, "a");
-        }
-    }
-
-    /**
-     *
-     */
-    public enum TestObjectEnum {
-        A, B, C
-    }
-
-    /**
-     *
-     */
-    public static class Address {
-        /** City. */
-        public String city;
-
-        /** Street. */
-        public String street;
-
-        /** Street number. */
-        public int streetNumber;
-
-        /** Flat number. */
-        public int flatNumber;
-
-        /**
-         * Default constructor.
-         */
-        public Address() {
-            // No-op.
-        }
-
-        /**
-         * Constructor.
-         *
-         * @param city City.
-         * @param street Street.
-         * @param streetNumber Street number.
-         * @param flatNumber Flat number.
-         */
-        public Address(String city, String street, int streetNumber, int 
flatNumber) {
-            this.city = city;
-            this.street = street;
-            this.streetNumber = streetNumber;
-            this.flatNumber = flatNumber;
-        }
-    }
-
-    /**
-     *
-     */
-    public static class Company {
-        /** ID. */
-        public int id;
-
-        /** Name. */
-        public String name;
-
-        /** Size. */
-        public int size;
-
-        /** Address. */
-        public Address address;
-
-        /** Occupation. */
-        public String occupation;
-
-        /**
-         * Default constructor.
-         */
-        public Company() {
-            // No-op.
-        }
-
-        /**
-         * Constructor.
-         *
-         * @param id ID.
-         * @param name Name.
-         * @param size Size.
-         * @param address Address.
-         * @param occupation Occupation.
-         */
-        public Company(int id, String name, int size, Address address, String 
occupation) {
-            this.id = id;
-            this.name = name;
-            this.size = size;
-            this.address = address;
-            this.occupation = occupation;
-        }
-    }
-
-    /**
-     *
-     */
-    public static class AddressBook {
-        /** */
-        private Map<String, List<Company>> companyByStreet = new TreeMap<>();
-
-        /**
-         *
-         * @param street Street.
-         * @return Company.
-         */
-        public List<Company> findCompany(String street) {
-            return companyByStreet.get(street);
-        }
-
-        /**
-         *
-         * @param company Company.
-         */
-        public void addCompany(Company company) {
-            List<Company> list = companyByStreet.get(company.address.street);
-
-            if (list == null) {
-                list = new ArrayList<>();
-
-                companyByStreet.put(company.address.street, list);
-            }
-
-            list.add(company);
-        }
-
-        /**
-         *
-         * @return map
-         */
-        public Map<String, List<Company>> getCompanyByStreet() {
-            return companyByStreet;
-        }
-
-        /**
-         *
-         * @param companyByStreet map
-         */
-        public void setCompanyByStreet(Map<String, List<Company>> 
companyByStreet) {
-            this.companyByStreet = companyByStreet;
-        }
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/0b213587/modules/core/src/test/java/org/apache/ignite/internal/portable/GridPortableWildcardsSelfTest.java
----------------------------------------------------------------------
diff --git 
a/modules/core/src/test/java/org/apache/ignite/internal/portable/GridPortableWildcardsSelfTest.java
 
b/modules/core/src/test/java/org/apache/ignite/internal/portable/GridPortableWildcardsSelfTest.java
index 4e62bb1..76b9709 100644
--- 
a/modules/core/src/test/java/org/apache/ignite/internal/portable/GridPortableWildcardsSelfTest.java
+++ 
b/modules/core/src/test/java/org/apache/ignite/internal/portable/GridPortableWildcardsSelfTest.java
@@ -246,7 +246,7 @@ public class GridPortableWildcardsSelfTest extends 
GridCommonAbstractTest {
 
         PortableTypeConfiguration typeCfg = new PortableTypeConfiguration();
 
-        
typeCfg.setClassName("org.gridgain.grid.internal.util.portable.test.GridPortableTestClass2");
+        
typeCfg.setClassName("org.apache.ignite.internal.portable.test.GridPortableTestClass2");
         typeCfg.setIdMapper(new PortableIdMapper() {
             @Override public int typeId(String clsName) {
                 return 100;

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/0b213587/modules/core/src/test/java/org/apache/ignite/internal/portable/mutabletest/GridPortableMarshalerAwareTestClass.java
----------------------------------------------------------------------
diff --git 
a/modules/core/src/test/java/org/apache/ignite/internal/portable/mutabletest/GridPortableMarshalerAwareTestClass.java
 
b/modules/core/src/test/java/org/apache/ignite/internal/portable/mutabletest/GridPortableMarshalerAwareTestClass.java
new file mode 100644
index 0000000..0b1ecff
--- /dev/null
+++ 
b/modules/core/src/test/java/org/apache/ignite/internal/portable/mutabletest/GridPortableMarshalerAwareTestClass.java
@@ -0,0 +1,62 @@
+/*
+ * 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.portable.mutabletest;
+
+import org.apache.ignite.internal.util.typedef.internal.*;
+import org.apache.ignite.portable.*;
+import org.apache.ignite.testframework.*;
+
+/**
+ *
+ */
+public class GridPortableMarshalerAwareTestClass implements 
PortableMarshalAware {
+    /** */
+    public String s;
+
+    /** */
+    public String sRaw;
+
+    /** {@inheritDoc} */
+    @Override public void writePortable(PortableWriter writer) throws 
PortableException {
+        writer.writeString("s", s);
+
+        PortableRawWriter raw = writer.rawWriter();
+
+        raw.writeString(sRaw);
+    }
+
+    /** {@inheritDoc} */
+    @Override public void readPortable(PortableReader reader) throws 
PortableException {
+        s = reader.readString("s");
+
+        PortableRawReader raw = reader.rawReader();
+
+        sRaw = raw.readString();
+    }
+
+    /** {@inheritDoc} */
+    @SuppressWarnings("FloatingPointEquality")
+    @Override public boolean equals(Object other) {
+        return this == other || GridTestUtils.deepEquals(this, other);
+    }
+
+    /** {@inheritDoc} */
+    @Override public String toString() {
+        return S.toString(GridPortableMarshalerAwareTestClass.class, this);
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/0b213587/modules/core/src/test/java/org/apache/ignite/internal/portable/mutabletest/GridPortableTestClasses.java
----------------------------------------------------------------------
diff --git 
a/modules/core/src/test/java/org/apache/ignite/internal/portable/mutabletest/GridPortableTestClasses.java
 
b/modules/core/src/test/java/org/apache/ignite/internal/portable/mutabletest/GridPortableTestClasses.java
new file mode 100644
index 0000000..8407495
--- /dev/null
+++ 
b/modules/core/src/test/java/org/apache/ignite/internal/portable/mutabletest/GridPortableTestClasses.java
@@ -0,0 +1,425 @@
+/*
+ * 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.portable.mutabletest;
+
+import org.apache.ignite.internal.util.lang.*;
+import org.apache.ignite.portable.*;
+
+import com.google.common.base.*;
+
+import java.io.*;
+import java.util.*;
+
+/**
+ *
+ */
+@SuppressWarnings({"PublicInnerClass", "PublicField"})
+public class GridPortableTestClasses {
+    /**
+     *
+     */
+    public static class TestObjectContainer {
+        /** */
+        public Object foo;
+
+        /**
+         *
+         */
+        public TestObjectContainer() {
+            // No-op.
+        }
+
+        /**
+         * @param foo Object.
+         */
+        public TestObjectContainer(Object foo) {
+            this.foo = foo;
+        }
+    }
+
+    /**
+     *
+     */
+    public static class TestObjectOuter {
+        /** */
+        public TestObjectInner inner;
+
+        /** */
+        public String foo;
+
+        /**
+         *
+         */
+        public TestObjectOuter() {
+
+        }
+
+        /**
+         * @param inner Inner object.
+         */
+        public TestObjectOuter(TestObjectInner inner) {
+            this.inner = inner;
+        }
+    }
+
+    /** */
+    public static class TestObjectInner {
+        /** */
+        public Object foo;
+
+        /** */
+        public TestObjectOuter outer;
+    }
+
+    /** */
+    public static class TestObjectArrayList {
+        /** */
+        public List<String> list = new ArrayList<>();
+    }
+
+    /**
+     *
+     */
+    public static class TestObjectPlainPortable {
+        /** */
+        public PortableObject plainPortable;
+
+        /**
+         *
+         */
+        public TestObjectPlainPortable() {
+            // No-op.
+        }
+
+        /**
+         * @param plainPortable Object.
+         */
+        public TestObjectPlainPortable(PortableObject plainPortable) {
+            this.plainPortable = plainPortable;
+        }
+    }
+
+    /**
+     *
+     */
+    public static class TestObjectAllTypes implements Serializable {
+        /** */
+        public Byte b_;
+
+        /** */
+        public Short s_;
+
+        /** */
+        public Integer i_;
+
+        /** */
+        public Long l_;
+
+        /** */
+        public Float f_;
+
+        /** */
+        public Double d_;
+
+        /** */
+        public Character c_;
+
+        /** */
+        public Boolean z_;
+
+        /** */
+        public byte b;
+
+        /** */
+        public short s;
+
+        /** */
+        public int i;
+
+        /** */
+        public long l;
+
+        /** */
+        public float f;
+
+        /** */
+        public double d;
+
+        /** */
+        public char c;
+
+        /** */
+        public boolean z;
+
+        /** */
+        public String str;
+
+        /** */
+        public UUID uuid;
+
+        /** */
+        public Date date;
+
+
+        /** */
+        public byte[] bArr;
+
+        /** */
+        public short[] sArr;
+
+        /** */
+        public int[] iArr;
+
+        /** */
+        public long[] lArr;
+
+        /** */
+        public float[] fArr;
+
+        /** */
+        public double[] dArr;
+
+        /** */
+        public char[] cArr;
+
+        /** */
+        public boolean[] zArr;
+
+        /** */
+        public String[] strArr;
+
+        /** */
+        public UUID[] uuidArr;
+
+        /** */
+        public TestObjectEnum anEnum;
+
+        /** */
+        public TestObjectEnum[] enumArr;
+
+        /** */
+        public Map.Entry entry;
+
+        //public Date[] dateArr; // todo test date array.
+
+        /**
+         * @return Array.
+         */
+        private byte[] serialize() {
+            ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
+
+            try {
+                ObjectOutput out = new ObjectOutputStream(byteOut);
+
+                out.writeObject(this);
+
+                out.close();
+            }
+            catch (IOException e) {
+                Throwables.propagate(e);
+            }
+
+            return byteOut.toByteArray();
+        }
+
+        /**
+         *
+         */
+        public void setDefaultData() {
+            b_ = 11;
+            s_ = 22;
+            i_ = 33;
+            l_ = 44L;
+            f_ = 55f;
+            d_ = 66d;
+            c_ = 'e';
+            z_ = true;
+
+            b = 1;
+            s = 2;
+            i = 3;
+            l = 4;
+            f = 5;
+            d = 6;
+            c = 7;
+            z = true;
+
+            str = "abc";
+            uuid = new UUID(1, 1);
+            date = new Date(1000000);
+
+            bArr = new byte[]{1, 2, 3};
+            sArr = new short[]{1, 2, 3};
+            iArr = new int[]{1, 2, 3};
+            lArr = new long[]{1, 2, 3};
+            fArr = new float[]{1, 2, 3};
+            dArr = new double[]{1, 2, 3};
+            cArr = new char[]{1, 2, 3};
+            zArr = new boolean[]{true, false};
+
+            strArr = new String[]{"abc", "ab", "a"};
+            uuidArr = new UUID[]{new UUID(1, 1), new UUID(2, 2)};
+
+            anEnum = TestObjectEnum.A;
+
+            enumArr = new TestObjectEnum[]{TestObjectEnum.B};
+
+            entry = new GridMapEntry<>(1, "a");
+        }
+    }
+
+    /**
+     *
+     */
+    public enum TestObjectEnum {
+        A, B, C
+    }
+
+    /**
+     *
+     */
+    public static class Address {
+        /** City. */
+        public String city;
+
+        /** Street. */
+        public String street;
+
+        /** Street number. */
+        public int streetNumber;
+
+        /** Flat number. */
+        public int flatNumber;
+
+        /**
+         * Default constructor.
+         */
+        public Address() {
+            // No-op.
+        }
+
+        /**
+         * Constructor.
+         *
+         * @param city City.
+         * @param street Street.
+         * @param streetNumber Street number.
+         * @param flatNumber Flat number.
+         */
+        public Address(String city, String street, int streetNumber, int 
flatNumber) {
+            this.city = city;
+            this.street = street;
+            this.streetNumber = streetNumber;
+            this.flatNumber = flatNumber;
+        }
+    }
+
+    /**
+     *
+     */
+    public static class Company {
+        /** ID. */
+        public int id;
+
+        /** Name. */
+        public String name;
+
+        /** Size. */
+        public int size;
+
+        /** Address. */
+        public Address address;
+
+        /** Occupation. */
+        public String occupation;
+
+        /**
+         * Default constructor.
+         */
+        public Company() {
+            // No-op.
+        }
+
+        /**
+         * Constructor.
+         *
+         * @param id ID.
+         * @param name Name.
+         * @param size Size.
+         * @param address Address.
+         * @param occupation Occupation.
+         */
+        public Company(int id, String name, int size, Address address, String 
occupation) {
+            this.id = id;
+            this.name = name;
+            this.size = size;
+            this.address = address;
+            this.occupation = occupation;
+        }
+    }
+
+    /**
+     *
+     */
+    public static class AddressBook {
+        /** */
+        private Map<String, List<Company>> companyByStreet = new TreeMap<>();
+
+        /**
+         *
+         * @param street Street.
+         * @return Company.
+         */
+        public List<Company> findCompany(String street) {
+            return companyByStreet.get(street);
+        }
+
+        /**
+         *
+         * @param company Company.
+         */
+        public void addCompany(Company company) {
+            List<Company> list = companyByStreet.get(company.address.street);
+
+            if (list == null) {
+                list = new ArrayList<>();
+
+                companyByStreet.put(company.address.street, list);
+            }
+
+            list.add(company);
+        }
+
+        /**
+         *
+         * @return map
+         */
+        public Map<String, List<Company>> getCompanyByStreet() {
+            return companyByStreet;
+        }
+
+        /**
+         *
+         * @param companyByStreet map
+         */
+        public void setCompanyByStreet(Map<String, List<Company>> 
companyByStreet) {
+            this.companyByStreet = companyByStreet;
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/0b213587/modules/core/src/test/java/org/apache/ignite/internal/portable/mutabletest/package-info.java
----------------------------------------------------------------------
diff --git 
a/modules/core/src/test/java/org/apache/ignite/internal/portable/mutabletest/package-info.java
 
b/modules/core/src/test/java/org/apache/ignite/internal/portable/mutabletest/package-info.java
new file mode 100644
index 0000000..daa13d5
--- /dev/null
+++ 
b/modules/core/src/test/java/org/apache/ignite/internal/portable/mutabletest/package-info.java
@@ -0,0 +1,22 @@
+/*
+ * 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 description. -->
+ * Contains internal tests or test related classes and interfaces.
+ */
+package org.apache.ignite.internal.portable.mutabletest;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/0b213587/modules/core/src/test/java/org/apache/ignite/internal/portable/test/package-info.java
----------------------------------------------------------------------
diff --git 
a/modules/core/src/test/java/org/apache/ignite/internal/portable/test/package-info.java
 
b/modules/core/src/test/java/org/apache/ignite/internal/portable/test/package-info.java
new file mode 100644
index 0000000..e63b814
--- /dev/null
+++ 
b/modules/core/src/test/java/org/apache/ignite/internal/portable/test/package-info.java
@@ -0,0 +1,22 @@
+/*
+ * 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 description. -->
+ * Contains internal tests or test related classes and interfaces.
+ */
+package org.apache.ignite.internal.portable.test;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/0b213587/modules/core/src/test/java/org/apache/ignite/internal/portable/test/subpackage/package-info.java
----------------------------------------------------------------------
diff --git 
a/modules/core/src/test/java/org/apache/ignite/internal/portable/test/subpackage/package-info.java
 
b/modules/core/src/test/java/org/apache/ignite/internal/portable/test/subpackage/package-info.java
new file mode 100644
index 0000000..ae8ee73
--- /dev/null
+++ 
b/modules/core/src/test/java/org/apache/ignite/internal/portable/test/subpackage/package-info.java
@@ -0,0 +1,22 @@
+/*
+ * 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 description. -->
+ * Contains internal tests or test related classes and interfaces.
+ */
+package org.apache.ignite.internal.portable.test.subpackage;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/0b213587/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/portable/GridCacheClientNodePortableMetadataMultinodeTest.java
----------------------------------------------------------------------
diff --git 
a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/portable/GridCacheClientNodePortableMetadataMultinodeTest.java
 
b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/portable/GridCacheClientNodePortableMetadataMultinodeTest.java
new file mode 100644
index 0000000..bb57ab0
--- /dev/null
+++ 
b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/portable/GridCacheClientNodePortableMetadataMultinodeTest.java
@@ -0,0 +1,277 @@
+/*
+ * 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.portable;
+
+import org.apache.ignite.*;
+import org.apache.ignite.configuration.*;
+import org.apache.ignite.internal.*;
+import org.apache.ignite.internal.util.typedef.internal.*;
+import org.apache.ignite.marshaller.portable.*;
+import org.apache.ignite.portable.*;
+import org.apache.ignite.spi.discovery.tcp.*;
+import org.apache.ignite.spi.discovery.tcp.ipfinder.*;
+import org.apache.ignite.spi.discovery.tcp.ipfinder.vm.*;
+import org.apache.ignite.testframework.*;
+import org.apache.ignite.testframework.junits.common.*;
+
+import org.eclipse.jetty.util.*;
+
+import java.util.*;
+import java.util.concurrent.*;
+import java.util.concurrent.atomic.*;
+
+import static org.apache.ignite.cache.CacheWriteSynchronizationMode.*;
+
+/**
+ *
+ */
+public class GridCacheClientNodePortableMetadataMultinodeTest extends 
GridCommonAbstractTest {
+    /** */
+    protected static TcpDiscoveryIpFinder ipFinder = new 
TcpDiscoveryVmIpFinder(true);
+
+    /** */
+    private boolean client;
+
+    /** {@inheritDoc} */
+    @Override protected IgniteConfiguration getConfiguration(String gridName) 
throws Exception {
+        IgniteConfiguration cfg = super.getConfiguration(gridName);
+
+        cfg.setPeerClassLoadingEnabled(false);
+
+        
((TcpDiscoverySpi)cfg.getDiscoverySpi()).setIpFinder(ipFinder).setForceServerMode(true);
+
+        cfg.setMarshaller(new PortableMarshaller());
+
+        CacheConfiguration ccfg = new CacheConfiguration();
+
+        ccfg.setWriteSynchronizationMode(FULL_SYNC);
+
+        cfg.setCacheConfiguration(ccfg);
+
+        cfg.setClientMode(client);
+
+        return cfg;
+    }
+
+    /** {@inheritDoc} */
+    @Override protected void afterTest() throws Exception {
+        super.afterTest();
+
+        stopAllGrids();
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    public void testClientMetadataInitialization() throws Exception {
+        startGrids(2);
+
+        final AtomicBoolean stop = new AtomicBoolean();
+
+        final ConcurrentHashSet<String> allTypes = new ConcurrentHashSet<>();
+
+        IgniteInternalFuture<?> fut;
+
+        try {
+            // Update portable metadata concurrently with client nodes start.
+            fut = GridTestUtils.runMultiThreadedAsync(new Callable<Object>() {
+                @Override public Object call() throws Exception {
+                    IgnitePortables portables = ignite(0).portables();
+
+                    IgniteCache<Object, Object> cache = 
ignite(0).cache(null).withKeepPortable();
+
+                    ThreadLocalRandom rnd = ThreadLocalRandom.current();
+
+                    for (int i = 0; i < 1000; i++) {
+                        log.info("Iteration: " + i);
+
+                        String type = "portable-type-" + i;
+
+                        allTypes.add(type);
+
+                        for (int f = 0; f < 10; f++) {
+                            PortableBuilder builder = portables.builder(type);
+
+                            String fieldName = "f" + f;
+
+                            builder.setField(fieldName, i);
+
+                            cache.put(rnd.nextInt(0, 100_000), 
builder.build());
+
+                            if (f % 100 == 0)
+                                log.info("Put iteration: " + f);
+                        }
+
+                        if (stop.get())
+                            break;
+                    }
+
+                    return null;
+                }
+            }, 5, "update-thread");
+        }
+        finally {
+            stop.set(true);
+        }
+
+        client = true;
+
+        startGridsMultiThreaded(2, 5);
+
+        fut.get();
+
+        assertFalse(allTypes.isEmpty());
+
+        log.info("Expected portable types: " + allTypes.size());
+
+        assertEquals(7, ignite(0).cluster().nodes().size());
+
+        for (int i = 0; i < 7; i++) {
+            log.info("Check metadata on node: " + i);
+
+            boolean client = i > 1;
+
+            assertEquals((Object)client, 
ignite(i).configuration().isClientMode());
+
+            IgnitePortables portables = ignite(i).portables();
+
+            Collection<PortableMetadata> metaCol = portables.metadata();
+
+            assertEquals(allTypes.size(), metaCol.size());
+
+            Set<String> names = new HashSet<>();
+
+            for (PortableMetadata meta : metaCol) {
+                assertTrue(names.add(meta.typeName()));
+
+                assertNull(meta.affinityKeyFieldName());
+
+                assertEquals(10, meta.fields().size());
+            }
+
+            assertEquals(allTypes.size(), names.size());
+        }
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    public void testFailoverOnStart() throws Exception {
+        startGrids(4);
+
+        IgnitePortables portables = ignite(0).portables();
+
+        IgniteCache<Object, Object> cache = 
ignite(0).cache(null).withKeepPortable();
+
+        for (int i = 0; i < 1000; i++) {
+            PortableBuilder builder = portables.builder("type-" + i);
+
+            builder.setField("f0", i);
+
+            cache.put(i, builder.build());
+        }
+
+        client = true;
+
+        final CyclicBarrier barrier = new CyclicBarrier(6);
+
+        final AtomicInteger startIdx = new AtomicInteger(4);
+
+        IgniteInternalFuture<?> fut = GridTestUtils.runMultiThreadedAsync(new 
Callable<Object>() {
+            @Override public Object call() throws Exception {
+                barrier.await();
+
+                Ignite ignite = startGrid(startIdx.getAndIncrement());
+
+                assertTrue(ignite.configuration().isClientMode());
+
+                log.info("Started node: " + ignite.name());
+
+                return null;
+            }
+        }, 5, "start-thread");
+
+        barrier.await();
+
+        U.sleep(ThreadLocalRandom.current().nextInt(10, 100));
+
+        for (int i = 0; i < 3; i++)
+            stopGrid(i);
+
+        fut.get();
+
+        assertEquals(6, ignite(3).cluster().nodes().size());
+
+        for (int i = 3; i < 7; i++) {
+            log.info("Check metadata on node: " + i);
+
+            boolean client = i > 3;
+
+            assertEquals((Object) client, 
ignite(i).configuration().isClientMode());
+
+            portables = ignite(i).portables();
+
+            Collection<PortableMetadata> metaCol = portables.metadata();
+
+            assertEquals(1000, metaCol.size());
+
+            Set<String> names = new HashSet<>();
+
+            for (PortableMetadata meta : metaCol) {
+                assertTrue(names.add(meta.typeName()));
+
+                assertNull(meta.affinityKeyFieldName());
+
+                assertEquals(1, meta.fields().size());
+            }
+
+            assertEquals(1000, names.size());
+        }
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    public void testClientStartsFirst() throws Exception {
+        client = true;
+
+        Ignite ignite0 = startGrid(0);
+
+        assertTrue(ignite0.configuration().isClientMode());
+
+        client = false;
+
+        Ignite ignite1 = startGrid(1);
+
+        assertFalse(ignite1.configuration().isClientMode());
+
+        IgnitePortables portables = ignite(1).portables();
+
+        IgniteCache<Object, Object> cache = 
ignite(1).cache(null).withKeepPortable();
+
+        for (int i = 0; i < 100; i++) {
+            PortableBuilder builder = portables.builder("type-" + i);
+
+            builder.setField("f0", i);
+
+            cache.put(i, builder.build());
+        }
+
+        assertEquals(100, ignite(0).portables().metadata().size());
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/0b213587/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/portable/GridCacheClientNodePortableMetadataTest.java
----------------------------------------------------------------------
diff --git 
a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/portable/GridCacheClientNodePortableMetadataTest.java
 
b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/portable/GridCacheClientNodePortableMetadataTest.java
new file mode 100644
index 0000000..2ac0bf0
--- /dev/null
+++ 
b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/portable/GridCacheClientNodePortableMetadataTest.java
@@ -0,0 +1,280 @@
+/*
+ * 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.portable;
+
+import org.apache.ignite.*;
+import org.apache.ignite.cache.*;
+import org.apache.ignite.cache.affinity.*;
+import org.apache.ignite.configuration.*;
+import org.apache.ignite.internal.processors.cache.*;
+import org.apache.ignite.marshaller.portable.*;
+import org.apache.ignite.portable.*;
+import org.apache.ignite.spi.discovery.tcp.*;
+
+import java.util.*;
+
+import static org.apache.ignite.cache.CacheAtomicityMode.*;
+
+/**
+ *
+ */
+public class GridCacheClientNodePortableMetadataTest extends 
GridCacheAbstractSelfTest {
+    /** {@inheritDoc} */
+    @Override protected int gridCount() {
+        return 4;
+    }
+
+    /** {@inheritDoc} */
+    @Override protected CacheMode cacheMode() {
+        return CacheMode.PARTITIONED;
+    }
+
+    /** {@inheritDoc} */
+    @Override protected CacheAtomicityMode atomicityMode() {
+        return ATOMIC;
+    }
+
+    /** {@inheritDoc} */
+    @Override protected NearCacheConfiguration nearConfiguration() {
+        return null;
+    }
+
+    /** {@inheritDoc} */
+    @Override protected IgniteConfiguration getConfiguration(String gridName) 
throws Exception {
+        IgniteConfiguration cfg = super.getConfiguration(gridName);
+
+        PortableMarshaller marsh = new PortableMarshaller();
+
+        marsh.setClassNames(Arrays.asList(TestObject1.class.getName(), 
TestObject2.class.getName()));
+
+        PortableTypeConfiguration typeCfg = new PortableTypeConfiguration();
+
+        typeCfg.setClassName(TestObject1.class.getName());
+        typeCfg.setAffinityKeyFieldName("val2");
+
+        marsh.setTypeConfigurations(Arrays.asList(typeCfg));
+
+        if (gridName.equals(getTestGridName(gridCount() - 1)))
+            cfg.setClientMode(true);
+
+        cfg.setMarshaller(marsh);
+
+        ((TcpDiscoverySpi)cfg.getDiscoverySpi()).setForceServerMode(true);
+
+        return cfg;
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    public void testPortableMetadataOnClient() throws Exception {
+        Ignite ignite0 = ignite(gridCount() - 1);
+
+        assertTrue(ignite0.configuration().isClientMode());
+
+        Ignite ignite1 = ignite(0);
+
+        assertFalse(ignite1.configuration().isClientMode());
+
+        Affinity<Object> aff0 = ignite0.affinity(null);
+        Affinity<Object> aff1 = ignite1.affinity(null);
+
+        for (int i = 0 ; i < 100; i++) {
+            TestObject1 obj1 = new TestObject1(i, i + 1);
+
+            assertEquals(aff1.mapKeyToPrimaryAndBackups(obj1),
+                aff0.mapKeyToPrimaryAndBackups(obj1));
+
+            TestObject2 obj2 = new TestObject2(i, i + 1);
+
+            assertEquals(aff1.mapKeyToPrimaryAndBackups(obj2),
+                aff0.mapKeyToPrimaryAndBackups(obj2));
+        }
+
+        {
+            PortableBuilder builder = 
ignite0.portables().builder("TestObject3");
+
+            builder.setField("f1", 1);
+
+            ignite0.cache(null).put(0, builder.build());
+
+            IgniteCache<Integer, PortableObject> cache = 
ignite0.cache(null).withKeepPortable();
+
+            PortableObject obj = cache.get(0);
+
+            PortableMetadata meta = obj.metaData();
+
+            assertNotNull(meta);
+            assertEquals(1, meta.fields().size());
+
+            meta = ignite0.portables().metadata(TestObject1.class);
+
+            assertNotNull(meta);
+            assertEquals("val2", meta.affinityKeyFieldName());
+
+            meta = ignite0.portables().metadata(TestObject2.class);
+
+            assertNotNull(meta);
+            assertNull(meta.affinityKeyFieldName());
+        }
+
+        {
+            PortableBuilder builder = 
ignite1.portables().builder("TestObject3");
+
+            builder.setField("f2", 2);
+
+            ignite1.cache(null).put(1, builder.build());
+
+            IgniteCache<Integer, PortableObject> cache = 
ignite1.cache(null).withKeepPortable();
+
+            PortableObject obj = cache.get(0);
+
+            PortableMetadata meta = obj.metaData();
+
+            assertNotNull(meta);
+            assertEquals(2, meta.fields().size());
+
+            meta = ignite1.portables().metadata(TestObject1.class);
+
+            assertNotNull(meta);
+            assertEquals("val2", meta.affinityKeyFieldName());
+
+            meta = ignite1.portables().metadata(TestObject2.class);
+
+            assertNotNull(meta);
+            assertNull(meta.affinityKeyFieldName());
+        }
+
+        PortableMetadata meta = ignite0.portables().metadata("TestObject3");
+
+        assertNotNull(meta);
+        assertEquals(2, meta.fields().size());
+
+        IgniteCache<Integer, PortableObject> cache = 
ignite0.cache(null).withKeepPortable();
+
+        PortableObject obj = cache.get(1);
+
+        assertEquals(Integer.valueOf(2), obj.field("f2"));
+        assertNull(obj.field("f1"));
+
+        meta = obj.metaData();
+
+        assertNotNull(meta);
+        assertEquals(2, meta.fields().size());
+
+        Collection<PortableMetadata> meta1 = ignite1.portables().metadata();
+        Collection<PortableMetadata> meta2 = ignite1.portables().metadata();
+
+        assertEquals(meta1.size(), meta2.size());
+
+        for (PortableMetadata m1 : meta1) {
+            boolean found = false;
+
+            for (PortableMetadata m2 : meta1) {
+                if (m1.typeName().equals(m2.typeName())) {
+                    assertEquals(m1.affinityKeyFieldName(), 
m2.affinityKeyFieldName());
+                    assertEquals(m1.fields(), m2.fields());
+
+                    found = true;
+
+                    break;
+                }
+            }
+
+            assertTrue(found);
+        }
+    }
+
+    /**
+     *
+     */
+    static class TestObject1 {
+        /** */
+        private int val1;
+
+        /** */
+        private int val2;
+
+        /**
+         * @param val1 Value 1.
+         * @param val2 Value 2.
+         */
+        public TestObject1(int val1, int val2) {
+            this.val1 = val1;
+            this.val2 = val2;
+        }
+
+        /** {@inheritDoc} */
+        @Override public boolean equals(Object o) {
+            if (this == o)
+                return true;
+
+            if (o == null || getClass() != o.getClass())
+                return false;
+
+            TestObject1 that = (TestObject1)o;
+
+            return val1 == that.val1;
+
+        }
+
+        /** {@inheritDoc} */
+        @Override public int hashCode() {
+            return val1;
+        }
+    }
+
+    /**
+     *
+     */
+    static class TestObject2 {
+        /** */
+        private int val1;
+
+        /** */
+        private int val2;
+
+        /**
+         * @param val1 Value 1.
+         * @param val2 Value 2.
+         */
+        public TestObject2(int val1, int val2) {
+            this.val1 = val1;
+            this.val2 = val2;
+        }
+
+        /** {@inheritDoc} */
+        @Override public boolean equals(Object o) {
+            if (this == o)
+                return true;
+
+            if (o == null || getClass() != o.getClass())
+                return false;
+
+            TestObject2 that = (TestObject2)o;
+
+            return val2 == that.val2;
+
+        }
+
+        /** {@inheritDoc} */
+        @Override public int hashCode() {
+            return val2;
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/0b213587/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/portable/GridCachePortableObjectsAbstractDataStreamerSelfTest.java
----------------------------------------------------------------------
diff --git 
a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/portable/GridCachePortableObjectsAbstractDataStreamerSelfTest.java
 
b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/portable/GridCachePortableObjectsAbstractDataStreamerSelfTest.java
new file mode 100644
index 0000000..9f8f1f5
--- /dev/null
+++ 
b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/portable/GridCachePortableObjectsAbstractDataStreamerSelfTest.java
@@ -0,0 +1,183 @@
+/*
+ * 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.portable;
+
+import org.apache.ignite.*;
+import org.apache.ignite.cache.*;
+import org.apache.ignite.configuration.*;
+import org.apache.ignite.internal.*;
+import org.apache.ignite.marshaller.portable.*;
+import org.apache.ignite.portable.*;
+import org.apache.ignite.testframework.junits.common.*;
+
+import org.jsr166.*;
+
+import java.io.*;
+import java.util.*;
+import java.util.concurrent.*;
+import java.util.concurrent.atomic.*;
+
+import static org.apache.ignite.cache.CacheWriteSynchronizationMode.*;
+
+/**
+ * Test for portable objects stored in cache.
+ */
+public abstract class GridCachePortableObjectsAbstractDataStreamerSelfTest 
extends GridCommonAbstractTest {
+    /** */
+    private static final int THREAD_CNT = 64;
+
+    /** {@inheritDoc} */
+    @Override protected IgniteConfiguration getConfiguration(String gridName) 
throws Exception {
+        IgniteConfiguration cfg = super.getConfiguration(gridName);
+
+        CacheConfiguration cacheCfg = new CacheConfiguration();
+
+        cacheCfg.setCacheMode(cacheMode());
+        cacheCfg.setAtomicityMode(atomicityMode());
+        cacheCfg.setNearConfiguration(nearConfiguration());
+        cacheCfg.setWriteSynchronizationMode(writeSynchronizationMode());
+
+        cfg.setCacheConfiguration(cacheCfg);
+
+        PortableMarshaller marsh = new PortableMarshaller();
+
+        marsh.setTypeConfigurations(Arrays.asList(
+            new PortableTypeConfiguration(TestObject.class.getName())));
+
+        cfg.setMarshaller(marsh);
+
+        return cfg;
+    }
+
+    /**
+     * @return Sync mode.
+     */
+    protected CacheWriteSynchronizationMode writeSynchronizationMode() {
+        return PRIMARY_SYNC;
+    }
+
+    /** {@inheritDoc} */
+    @Override protected void beforeTestsStarted() throws Exception {
+        startGridsMultiThreaded(gridCount());
+    }
+
+    /** {@inheritDoc} */
+    @Override protected void afterTestsStopped() throws Exception {
+        stopAllGrids();
+    }
+
+    /**
+     * @return Cache mode.
+     */
+    protected abstract CacheMode cacheMode();
+
+    /**
+     * @return Atomicity mode.
+     */
+    protected abstract CacheAtomicityMode atomicityMode();
+
+    /**
+     * @return Near configuration.
+     */
+    protected abstract NearCacheConfiguration nearConfiguration();
+
+    /**
+     * @return Grid count.
+     */
+    protected int gridCount() {
+        return 1;
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    @SuppressWarnings("BusyWait")
+    public void testGetPut() throws Exception {
+        final AtomicBoolean flag = new AtomicBoolean();
+
+        final LongAdder8 cnt = new LongAdder8();
+
+        try (IgniteDataStreamer<Object, Object> ldr = 
grid(0).dataStreamer(null)) {
+            IgniteInternalFuture<?> f = multithreadedAsync(
+                new Callable<Object>() {
+                    @Override public Object call() throws Exception {
+                        ThreadLocalRandom rnd = ThreadLocalRandom.current();
+
+                        while (!flag.get()) {
+                            ldr.addData(rnd.nextInt(10000), new 
TestObject(rnd.nextInt(10000)));
+
+                            cnt.add(1);
+                        }
+
+                        return null;
+                    }
+                },
+                THREAD_CNT
+            );
+
+            for (int i = 0; i < 30 && !f.isDone(); i++)
+                Thread.sleep(1000);
+
+            flag.set(true);
+
+            f.get();
+        }
+
+        info("Operations in 30 sec: " + cnt.sum());
+    }
+
+    /**
+     */
+    private static class TestObject implements PortableMarshalAware, 
Serializable {
+        /** */
+        private int val;
+
+        /**
+         */
+        private TestObject() {
+            // No-op.
+        }
+
+        /**
+         * @param val Value.
+         */
+        private TestObject(int val) {
+            this.val = val;
+        }
+
+        /** {@inheritDoc} */
+        @Override public int hashCode() {
+            return val;
+        }
+
+        /** {@inheritDoc} */
+        @Override public boolean equals(Object obj) {
+            return obj instanceof TestObject && ((TestObject)obj).val == val;
+        }
+
+        /** {@inheritDoc} */
+        @Override public void writePortable(PortableWriter writer) throws 
PortableException {
+            writer.writeInt("val", val);
+        }
+
+        /** {@inheritDoc} */
+        @Override public void readPortable(PortableReader reader) throws 
PortableException {
+            val = reader.readInt("val");
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/0b213587/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/portable/GridCachePortableObjectsAbstractMultiThreadedSelfTest.java
----------------------------------------------------------------------
diff --git 
a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/portable/GridCachePortableObjectsAbstractMultiThreadedSelfTest.java
 
b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/portable/GridCachePortableObjectsAbstractMultiThreadedSelfTest.java
new file mode 100644
index 0000000..37e4d64
--- /dev/null
+++ 
b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/portable/GridCachePortableObjectsAbstractMultiThreadedSelfTest.java
@@ -0,0 +1,222 @@
+/*
+ * 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.portable;
+
+import org.apache.ignite.*;
+import org.apache.ignite.cache.*;
+import org.apache.ignite.configuration.*;
+import org.apache.ignite.internal.*;
+import org.apache.ignite.internal.processors.cache.*;
+import org.apache.ignite.marshaller.portable.*;
+import org.apache.ignite.portable.*;
+import org.apache.ignite.testframework.junits.common.*;
+
+import org.jsr166.*;
+
+import java.io.*;
+import java.util.*;
+import java.util.concurrent.*;
+import java.util.concurrent.atomic.*;
+
+import static org.apache.ignite.cache.CacheWriteSynchronizationMode.*;
+
+/**
+ * Test for portable objects stored in cache.
+ */
+public abstract class GridCachePortableObjectsAbstractMultiThreadedSelfTest 
extends GridCommonAbstractTest {
+    /** */
+    private static final int THREAD_CNT = 64;
+
+    /** */
+    private static final AtomicInteger idxGen = new AtomicInteger();
+
+    /** {@inheritDoc} */
+    @Override protected IgniteConfiguration getConfiguration(String gridName) 
throws Exception {
+        IgniteConfiguration cfg = super.getConfiguration(gridName);
+
+        CacheConfiguration cacheCfg = new CacheConfiguration();
+
+        cacheCfg.setCacheMode(cacheMode());
+        cacheCfg.setAtomicityMode(atomicityMode());
+        cacheCfg.setNearConfiguration(nearConfiguration());
+        cacheCfg.setWriteSynchronizationMode(writeSynchronizationMode());
+
+        cfg.setCacheConfiguration(cacheCfg);
+
+        PortableMarshaller marsh = new PortableMarshaller();
+
+        marsh.setTypeConfigurations(Arrays.asList(
+            new PortableTypeConfiguration(TestObject.class.getName())));
+
+        cfg.setMarshaller(marsh);
+
+        return cfg;
+    }
+
+    /**
+     * @return Sync mode.
+     */
+    protected CacheWriteSynchronizationMode writeSynchronizationMode() {
+        return PRIMARY_SYNC;
+    }
+
+    /** {@inheritDoc} */
+    @Override protected void beforeTestsStarted() throws Exception {
+        startGridsMultiThreaded(gridCount());
+    }
+
+    /** {@inheritDoc} */
+    @Override protected void afterTestsStopped() throws Exception {
+        stopAllGrids();
+    }
+
+    /**
+     * @return Cache mode.
+     */
+    protected abstract CacheMode cacheMode();
+
+    /**
+     * @return Atomicity mode.
+     */
+    protected abstract CacheAtomicityMode atomicityMode();
+
+    /**
+     * @return Distribution mode.
+     */
+    protected abstract NearCacheConfiguration nearConfiguration();
+
+    /**
+     * @return Grid count.
+     */
+    protected int gridCount() {
+        return 1;
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    @SuppressWarnings("BusyWait") public void testGetPut() throws Exception {
+        final AtomicBoolean flag = new AtomicBoolean();
+
+        final LongAdder8 cnt = new LongAdder8();
+
+        IgniteInternalFuture<?> f = multithreadedAsync(
+            new Callable<Object>() {
+                @Override public Object call() throws Exception {
+                    int threadId = idxGen.getAndIncrement() % 2;
+
+                    ThreadLocalRandom rnd = ThreadLocalRandom.current();
+
+                    while (!flag.get()) {
+                        IgniteCache<Object, Object> c = 
jcache(rnd.nextInt(gridCount()));
+
+                        switch (threadId) {
+                            case 0:
+                                // Put/get/remove portable -> portable.
+
+                                c.put(new TestObject(rnd.nextInt(10000)), new 
TestObject(rnd.nextInt(10000)));
+
+                                IgniteCache<Object, Object> p2 = 
((IgniteCacheProxy<Object, Object>)c).keepPortable();
+
+                                PortableObject v = (PortableObject)p2.get(new 
TestObject(rnd.nextInt(10000)));
+
+                                if (v != null)
+                                    v.deserialize();
+
+                                c.remove(new TestObject(rnd.nextInt(10000)));
+
+                                break;
+
+                            case 1:
+                                // Put/get int -> portable.
+                                c.put(rnd.nextInt(10000), new 
TestObject(rnd.nextInt(10000)));
+
+                                IgniteCache<Integer, PortableObject> p4 = 
((IgniteCacheProxy<Object, Object>)c).keepPortable();
+
+                                PortableObject v1 = p4.get(rnd.nextInt(10000));
+
+                                if (v1 != null)
+                                    v1.deserialize();
+
+                                p4.remove(rnd.nextInt(10000));
+
+                                break;
+
+                            default:
+                                assert false;
+                        }
+
+                        cnt.add(3);
+                    }
+
+                    return null;
+                }
+            },
+            THREAD_CNT
+        );
+
+        for (int i = 0; i < 30 && !f.isDone(); i++)
+            Thread.sleep(1000);
+
+        flag.set(true);
+
+        f.get();
+
+        info("Operations in 30 sec: " + cnt.sum());
+    }
+
+    /**
+     */
+    private static class TestObject implements PortableMarshalAware, 
Serializable {
+        /** */
+        private int val;
+
+        /**
+         */
+        private TestObject() {
+            // No-op.
+        }
+
+        /**
+         * @param val Value.
+         */
+        private TestObject(int val) {
+            this.val = val;
+        }
+
+        /** {@inheritDoc} */
+        @Override public int hashCode() {
+            return val;
+        }
+
+        /** {@inheritDoc} */
+        @Override public boolean equals(Object obj) {
+            return obj instanceof TestObject && ((TestObject)obj).val == val;
+        }
+
+        /** {@inheritDoc} */
+        @Override public void writePortable(PortableWriter writer) throws 
PortableException {
+            writer.writeInt("val", val);
+        }
+
+        /** {@inheritDoc} */
+        @Override public void readPortable(PortableReader reader) throws 
PortableException {
+            val = reader.readInt("val");
+        }
+    }
+}

Reply via email to