You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by ni...@apache.org on 2018/10/05 10:03:46 UTC

[3/6] ignite git commit: IGNITE-8485: TDE implementation. - Fixes #4167.

http://git-wip-us.apache.org/repos/asf/ignite/blob/aabacfa0/modules/core/src/main/java/org/apache/ignite/spi/encryption/keystore/package-info.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/spi/encryption/keystore/package-info.java b/modules/core/src/main/java/org/apache/ignite/spi/encryption/keystore/package-info.java
new file mode 100644
index 0000000..71f1634
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/spi/encryption/keystore/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 encryption SPI implementation based on standard jdk keystore.
+ */
+package org.apache.ignite.spi.encryption.keystore;

http://git-wip-us.apache.org/repos/asf/ignite/blob/aabacfa0/modules/core/src/main/java/org/apache/ignite/spi/encryption/noop/NoopEncryptionSpi.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/spi/encryption/noop/NoopEncryptionSpi.java b/modules/core/src/main/java/org/apache/ignite/spi/encryption/noop/NoopEncryptionSpi.java
new file mode 100644
index 0000000..1de64d9
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/spi/encryption/noop/NoopEncryptionSpi.java
@@ -0,0 +1,101 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.spi.encryption.noop;
+
+import java.io.Serializable;
+import java.nio.ByteBuffer;
+import org.apache.ignite.IgniteException;
+import org.apache.ignite.spi.IgniteSpiAdapter;
+import org.apache.ignite.spi.IgniteSpiException;
+import org.apache.ignite.spi.IgniteSpiNoop;
+import org.apache.ignite.spi.encryption.EncryptionSpi;
+import org.apache.ignite.spi.encryption.keystore.KeystoreEncryptionSpi;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * No operation {@code EncryptionSPI} implementation.
+ *
+ * @see EncryptionSpi
+ * @see KeystoreEncryptionSpi
+ */
+@IgniteSpiNoop
+public class NoopEncryptionSpi extends IgniteSpiAdapter implements EncryptionSpi {
+    /** {@inheritDoc} */
+    @Override public byte[] masterKeyDigest() {
+        return null;
+    }
+
+    /** {@inheritDoc} */
+    @Override public Serializable create() throws IgniteException {
+        throw new IgniteSpiException("You have to configure custom EncryptionSpi implementation.");
+    }
+
+    /** {@inheritDoc} */
+    @Override public void encrypt(ByteBuffer data, Serializable key, ByteBuffer res) {
+        throw new IgniteSpiException("You have to configure custom EncryptionSpi implementation.");
+    }
+
+    /** {@inheritDoc} */
+    @Override public void encryptNoPadding(ByteBuffer data, Serializable key, ByteBuffer res) {
+        throw new IgniteSpiException("You have to configure custom EncryptionSpi implementation.");
+    }
+
+    /** {@inheritDoc} */
+    @Override public byte[] decrypt(byte[] data, Serializable key) {
+        throw new IgniteSpiException("You have to configure custom EncryptionSpi implementation.");
+    }
+
+    /** {@inheritDoc} */
+    @Override public void decryptNoPadding(ByteBuffer data, Serializable key, ByteBuffer res) {
+        throw new IgniteSpiException("You have to configure custom EncryptionSpi implementation.");
+    }
+
+    /** {@inheritDoc} */
+    @Override public byte[] encryptKey(Serializable key) {
+        throw new IgniteSpiException("You have to configure custom EncryptionSpi implementation.");
+    }
+
+    /** {@inheritDoc} */
+    @Override public Serializable decryptKey(byte[] key) {
+        throw new IgniteSpiException("You have to configure custom EncryptionSpi implementation.");
+    }
+
+    /** {@inheritDoc} */
+    @Override public int encryptedSize(int dataSize) {
+        return dataSize;
+    }
+
+    /** {@inheritDoc} */
+    @Override public int encryptedSizeNoPadding(int dataSize) {
+        return dataSize;
+    }
+
+    @Override public int blockSize() {
+        return 0;
+    }
+
+    /** {@inheritDoc} */
+    @Override public void spiStart(@Nullable String igniteInstanceName) throws IgniteSpiException {
+        // No-op.
+    }
+
+    /** {@inheritDoc} */
+    @Override public void spiStop() throws IgniteSpiException {
+        // No-op.
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/aabacfa0/modules/core/src/main/java/org/apache/ignite/spi/encryption/package-info.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/spi/encryption/package-info.java b/modules/core/src/main/java/org/apache/ignite/spi/encryption/package-info.java
new file mode 100644
index 0000000..9805aaf
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/spi/encryption/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 APIs for encryption SPI.
+ */
+package org.apache.ignite.spi.encryption;

http://git-wip-us.apache.org/repos/asf/ignite/blob/aabacfa0/modules/core/src/test/java/org/apache/ignite/internal/encryption/AbstractEncryptionTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/encryption/AbstractEncryptionTest.java b/modules/core/src/test/java/org/apache/ignite/internal/encryption/AbstractEncryptionTest.java
new file mode 100644
index 0000000..f267186
--- /dev/null
+++ b/modules/core/src/test/java/org/apache/ignite/internal/encryption/AbstractEncryptionTest.java
@@ -0,0 +1,245 @@
+/*
+ * 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.encryption;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.OutputStream;
+import java.security.KeyStore;
+import java.util.HashSet;
+import java.util.Set;
+import javax.crypto.KeyGenerator;
+import javax.crypto.SecretKey;
+import org.apache.ignite.IgniteCache;
+import org.apache.ignite.configuration.CacheConfiguration;
+import org.apache.ignite.configuration.DataRegionConfiguration;
+import org.apache.ignite.configuration.DataStorageConfiguration;
+import org.apache.ignite.configuration.IgniteConfiguration;
+import org.apache.ignite.internal.IgniteEx;
+import org.apache.ignite.internal.IgniteInterruptedCheckedException;
+import org.apache.ignite.internal.processors.cache.IgniteInternalCache;
+import org.apache.ignite.internal.util.IgniteUtils;
+import org.apache.ignite.internal.util.typedef.T2;
+import org.apache.ignite.internal.util.typedef.internal.CU;
+import org.apache.ignite.spi.encryption.keystore.KeystoreEncryptionKey;
+import org.apache.ignite.spi.encryption.keystore.KeystoreEncryptionSpi;
+import org.apache.ignite.testframework.GridTestUtils;
+import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import static org.apache.ignite.cache.CacheWriteSynchronizationMode.FULL_SYNC;
+import static org.apache.ignite.configuration.WALMode.FSYNC;
+import static org.apache.ignite.spi.encryption.keystore.KeystoreEncryptionSpi.CIPHER_ALGO;
+import static org.apache.ignite.spi.encryption.keystore.KeystoreEncryptionSpi.DEFAULT_MASTER_KEY_NAME;
+
+/**
+ * Abstract encryption test.
+ */
+public abstract class AbstractEncryptionTest extends GridCommonAbstractTest {
+    /** */
+    static final String ENCRYPTED_CACHE = "encrypted";
+
+    /** */
+    public static final String KEYSTORE_PATH =
+        IgniteUtils.resolveIgnitePath("modules/core/src/test/resources/tde.jks").getAbsolutePath();
+
+    /** */
+    static final String GRID_0 = "grid-0";
+
+    /** */
+    static final String GRID_1 = "grid-1";
+
+    /** */
+    public static final String KEYSTORE_PASSWORD = "love_sex_god";
+
+    /** {@inheritDoc} */
+    @Override protected IgniteConfiguration getConfiguration(String name) throws Exception {
+        IgniteConfiguration cfg = super.getConfiguration(name);
+
+        KeystoreEncryptionSpi encSpi = new KeystoreEncryptionSpi();
+
+        encSpi.setKeyStorePath(keystorePath());
+        encSpi.setKeyStorePassword(keystorePassword());
+
+        cfg.setEncryptionSpi(encSpi);
+
+        DataStorageConfiguration memCfg = new DataStorageConfiguration()
+            .setDefaultDataRegionConfiguration(
+                new DataRegionConfiguration()
+                    .setMaxSize(10L * 1024 * 1024)
+                    .setPersistenceEnabled(true))
+            .setPageSize(4 * 1024)
+            .setWalMode(FSYNC);
+
+        cfg.setDataStorageConfiguration(memCfg);
+
+        return cfg;
+    }
+
+    /** */
+    private char[] keystorePassword() {
+        return KEYSTORE_PASSWORD.toCharArray();
+    }
+
+    /** */
+    protected String keystorePath() {
+        return KEYSTORE_PATH;
+    }
+
+    /** */
+    void checkEncryptedCaches(IgniteEx grid0, IgniteEx grid1) {
+        Set<String> cacheNames = new HashSet<>(grid0.cacheNames());
+
+        cacheNames.addAll(grid1.cacheNames());
+
+        for (String cacheName : cacheNames) {
+            CacheConfiguration ccfg = grid1.cache(cacheName).getConfiguration(CacheConfiguration.class);
+
+            if (!ccfg.isEncryptionEnabled())
+                continue;
+
+            IgniteInternalCache<?, ?> encrypted0 = grid0.cachex(cacheName);
+
+            int grpId = CU.cacheGroupId(cacheName, ccfg.getGroupName());
+
+            assertNotNull(encrypted0);
+
+            IgniteInternalCache<?, ?> encrypted1 = grid1.cachex(cacheName);
+
+            assertNotNull(encrypted1);
+
+            assertTrue(encrypted1.configuration().isEncryptionEnabled());
+
+            KeystoreEncryptionKey encKey0 = (KeystoreEncryptionKey)grid0.context().encryption().groupKey(grpId);
+
+            assertNotNull(encKey0);
+            assertNotNull(encKey0.key());
+
+            if (!grid1.configuration().isClientMode()) {
+                KeystoreEncryptionKey encKey1 = (KeystoreEncryptionKey)grid1.context().encryption().groupKey(grpId);
+
+                assertNotNull(encKey1);
+                assertNotNull(encKey1.key());
+
+                assertEquals(encKey0.key(), encKey1.key());
+            }
+            else
+                assertNull(grid1.context().encryption().groupKey(grpId));
+        }
+
+        checkData(grid0);
+    }
+
+    /** */
+    protected void checkData(IgniteEx grid0) {
+        IgniteCache<Long, String> cache = grid0.cache(cacheName());
+
+        assertNotNull(cache);
+
+        for (long i=0; i<100; i++)
+            assertEquals("" + i, cache.get(i));
+    }
+
+    /** */
+    protected void createEncryptedCache(IgniteEx grid0, @Nullable IgniteEx grid1, String cacheName, String cacheGroup)
+        throws IgniteInterruptedCheckedException {
+        createEncryptedCache(grid0, grid1, cacheName, cacheGroup, true);
+    }
+
+    /** */
+    protected void createEncryptedCache(IgniteEx grid0, @Nullable IgniteEx grid1, String cacheName, String cacheGroup,
+        boolean putData) throws IgniteInterruptedCheckedException {
+        CacheConfiguration<Long, String> ccfg = new CacheConfiguration<Long, String>(cacheName)
+            .setWriteSynchronizationMode(FULL_SYNC)
+            .setGroupName(cacheGroup)
+            .setEncryptionEnabled(true);
+
+        IgniteCache<Long, String> cache = grid0.createCache(ccfg);
+
+        if (grid1 != null)
+            GridTestUtils.waitForCondition(() -> grid1.cachex(cacheName()) != null, 2_000L);
+
+        if (putData) {
+            for (long i = 0; i < 100; i++)
+                cache.put(i, "" + i);
+
+            for (long i = 0; i < 100; i++)
+                assertEquals("" + i, cache.get(i));
+        }
+    }
+
+    /**
+     * Starts tests grid instances.
+     *
+     * @param clnPersDir If {@code true} than before start persistence dir are cleaned.
+     * @return Started grids.
+     * @throws Exception If failed.
+     */
+    protected T2<IgniteEx, IgniteEx> startTestGrids(boolean clnPersDir) throws Exception {
+        if (clnPersDir)
+            cleanPersistenceDir();
+
+        IgniteEx grid0 = startGrid(GRID_0);
+
+        IgniteEx grid1 = startGrid(GRID_1);
+
+        grid0.cluster().active(true);
+
+        awaitPartitionMapExchange();
+
+        return new T2<>(grid0, grid1);
+    }
+
+    /** */
+    @NotNull protected String cacheName() {
+        return ENCRYPTED_CACHE;
+    }
+
+    /**
+     * Method to create new keystore.
+     * Use it whenever you need special keystore for an encryption tests.
+     */
+    @SuppressWarnings("unused")
+    protected File createKeyStore(String keystorePath) throws Exception {
+        KeyStore ks = KeyStore.getInstance("PKCS12");
+
+        ks.load(null, null);
+
+        KeyGenerator gen = KeyGenerator.getInstance(CIPHER_ALGO);
+
+        gen.init(KeystoreEncryptionSpi.DEFAULT_KEY_SIZE);
+
+        SecretKey key = gen.generateKey();
+
+        ks.setEntry(
+            DEFAULT_MASTER_KEY_NAME,
+            new KeyStore.SecretKeyEntry(key),
+            new KeyStore.PasswordProtection(KEYSTORE_PASSWORD.toCharArray()));
+
+        File keyStoreFile = new File(keystorePath);
+
+        keyStoreFile.createNewFile();
+
+        try (OutputStream os = new FileOutputStream(keyStoreFile)) {
+            ks.store(os, KEYSTORE_PASSWORD.toCharArray());
+        }
+
+        return keyStoreFile;
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/aabacfa0/modules/core/src/test/java/org/apache/ignite/internal/encryption/EncryptedCacheBigEntryTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/encryption/EncryptedCacheBigEntryTest.java b/modules/core/src/test/java/org/apache/ignite/internal/encryption/EncryptedCacheBigEntryTest.java
new file mode 100644
index 0000000..deb72e4
--- /dev/null
+++ b/modules/core/src/test/java/org/apache/ignite/internal/encryption/EncryptedCacheBigEntryTest.java
@@ -0,0 +1,114 @@
+/*
+ * 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.encryption;
+
+import java.util.Arrays;
+import org.apache.ignite.IgniteCache;
+import org.apache.ignite.configuration.CacheConfiguration;
+import org.apache.ignite.internal.IgniteEx;
+import org.apache.ignite.internal.IgniteInterruptedCheckedException;
+import org.apache.ignite.internal.util.typedef.T2;
+import org.apache.ignite.internal.util.typedef.internal.CU;
+import org.apache.ignite.spi.encryption.keystore.KeystoreEncryptionKey;
+import org.apache.ignite.testframework.GridTestUtils;
+import org.jetbrains.annotations.Nullable;
+
+import static org.apache.ignite.cache.CacheWriteSynchronizationMode.FULL_SYNC;
+
+/**
+ * Tests to check encryption of entry bigger then page size.
+ */
+public class EncryptedCacheBigEntryTest extends AbstractEncryptionTest {
+    /** {@inheritDoc} */
+    @Override protected void afterTestsStopped() throws Exception {
+        cleanPersistenceDir();
+    }
+
+    /** {@inheritDoc} */
+    @Override protected void afterTest() throws Exception {
+        stopAllGrids(false);
+
+        cleanPersistenceDir();
+    }
+
+    /** @throws Exception If failed. */
+    public void testCreateEncryptedCacheWithBigEntry() throws Exception {
+        T2<IgniteEx, IgniteEx> grids = startTestGrids(true);
+
+        createEncryptedCache(grids.get1(), grids.get2(), cacheName(), null);
+
+        checkEncryptedCaches(grids.get1(), grids.get2());
+
+        int grpId = CU.cacheGroupId(cacheName(), null);
+
+        KeystoreEncryptionKey keyBeforeRestart =
+            (KeystoreEncryptionKey)grids.get1().context().encryption().groupKey(grpId);
+
+        stopAllGrids();
+
+        grids = startTestGrids(false);
+
+        checkEncryptedCaches(grids.get1(), grids.get2());
+
+        KeystoreEncryptionKey keyAfterRestart = (KeystoreEncryptionKey)grids.get1().context().encryption().groupKey(grpId);
+
+        assertNotNull(keyAfterRestart);
+        assertNotNull(keyAfterRestart.key());
+
+        assertEquals(keyBeforeRestart.key(), keyAfterRestart.key());
+    }
+
+    /** {@inheritDoc} */
+    @Override protected void createEncryptedCache(IgniteEx grid0, @Nullable IgniteEx grid1, String cacheName,
+        String cacheGroup, boolean putData) throws IgniteInterruptedCheckedException {
+        CacheConfiguration<Integer, byte[]> ccfg = new CacheConfiguration<Integer, byte[]>(cacheName)
+            .setWriteSynchronizationMode(FULL_SYNC)
+            .setGroupName(cacheGroup)
+            .setEncryptionEnabled(true);
+
+        IgniteCache<Integer, byte[]> cache = grid0.createCache(ccfg);
+
+        if (grid1 != null)
+            GridTestUtils.waitForCondition(() -> grid1.cachex(cacheName()) != null, 2_000L);
+
+        if (putData) {
+            cache.put(1, bigArray(grid0));
+
+            assertTrue(Arrays.equals(bigArray(grid0), cache.get(1)));
+        }
+    }
+
+    /** {@inheritDoc} */
+    @Override protected void checkData(IgniteEx grid0) {
+        IgniteCache<Integer, byte[]> cache = grid0.cache(cacheName());
+
+        assertTrue(Arrays.equals(bigArray(grid0), cache.get(1)));
+    }
+
+    /** */
+    private byte[] bigArray(IgniteEx grid) {
+        int arrSz = grid.configuration().getDataStorageConfiguration().getPageSize() * 3;
+
+        byte[] bigArr = new byte[arrSz];
+
+        for (int i=0; i<bigArr.length; i++)
+            bigArr[i] = (byte)i;
+
+        return bigArr;
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/aabacfa0/modules/core/src/test/java/org/apache/ignite/internal/encryption/EncryptedCacheCreateTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/encryption/EncryptedCacheCreateTest.java b/modules/core/src/test/java/org/apache/ignite/internal/encryption/EncryptedCacheCreateTest.java
new file mode 100644
index 0000000..47d8d8f
--- /dev/null
+++ b/modules/core/src/test/java/org/apache/ignite/internal/encryption/EncryptedCacheCreateTest.java
@@ -0,0 +1,164 @@
+/*
+ * 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.encryption;
+
+import com.google.common.primitives.Bytes;
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import org.apache.ignite.IgniteCache;
+import org.apache.ignite.IgniteCheckedException;
+import org.apache.ignite.configuration.CacheConfiguration;
+import org.apache.ignite.configuration.DataRegionConfiguration;
+import org.apache.ignite.configuration.DataStorageConfiguration;
+import org.apache.ignite.configuration.IgniteConfiguration;
+import org.apache.ignite.internal.IgniteEx;
+import org.apache.ignite.internal.processors.cache.IgniteInternalCache;
+import org.apache.ignite.internal.util.typedef.internal.CU;
+import org.apache.ignite.internal.util.typedef.internal.U;
+import org.apache.ignite.spi.encryption.keystore.KeystoreEncryptionKey;
+import org.apache.ignite.testframework.GridTestUtils;
+
+/** */
+public class EncryptedCacheCreateTest extends AbstractEncryptionTest {
+    /** Non-persistent data region name. */
+    private static final String NO_PERSISTENCE_REGION = "no-persistence-region";
+
+    /** {@inheritDoc} */
+    @Override protected void afterTest() throws Exception {
+        stopAllGrids();
+
+        cleanPersistenceDir();
+    }
+
+    /** {@inheritDoc} */
+    @Override protected void beforeTest() throws Exception {
+        cleanPersistenceDir();
+
+        IgniteEx igniteEx = startGrid(0);
+
+        startGrid(1);
+
+        igniteEx.cluster().active(true);
+
+        awaitPartitionMapExchange();
+    }
+
+    /** {@inheritDoc} */
+    @Override protected IgniteConfiguration getConfiguration(String name) throws Exception {
+        IgniteConfiguration cfg = super.getConfiguration(name);
+
+        DataStorageConfiguration memCfg = cfg.getDataStorageConfiguration();
+
+        memCfg.setDataRegionConfigurations(new DataRegionConfiguration()
+            .setMaxSize(10L * 1024 * 1024)
+            .setName(NO_PERSISTENCE_REGION)
+            .setPersistenceEnabled(false));
+
+        return cfg;
+    }
+
+    /** @throws Exception If failed. */
+    public void testCreateEncryptedCache() throws Exception {
+        CacheConfiguration<Long, String> ccfg = new CacheConfiguration<>(ENCRYPTED_CACHE);
+
+        ccfg.setEncryptionEnabled(true);
+
+        IgniteEx grid = grid(0);
+
+        grid.createCache(ccfg);
+
+        IgniteInternalCache<Object, Object> enc = grid.cachex(ENCRYPTED_CACHE);
+
+        assertNotNull(enc);
+
+        KeystoreEncryptionKey key =
+            (KeystoreEncryptionKey)grid.context().encryption().groupKey(CU.cacheGroupId(ENCRYPTED_CACHE, null));
+
+        assertNotNull(key);
+        assertNotNull(key.key());
+    }
+
+    /** @throws Exception If failed. */
+    public void testCreateEncryptedNotPersistedCacheFail() throws Exception {
+        fail("https://issues.apache.org/jira/browse/IGNITE-8640");
+
+        GridTestUtils.assertThrowsWithCause(() -> {
+            CacheConfiguration<Long, String> ccfg = new CacheConfiguration<>(NO_PERSISTENCE_REGION);
+
+            ccfg.setEncryptionEnabled(true);
+            ccfg.setDataRegionName(NO_PERSISTENCE_REGION);
+
+            grid(0).createCache(ccfg);
+        }, IgniteCheckedException.class);
+    }
+
+    /** @throws Exception If failed. */
+    public void testPersistedContentEncrypted() throws Exception {
+        IgniteCache<Integer, String> enc = grid(0).createCache(
+            new CacheConfiguration<Integer, String>(ENCRYPTED_CACHE)
+                .setEncryptionEnabled(true));
+
+        IgniteCache<Integer, String> plain = grid(0).createCache(new CacheConfiguration<>("plain-cache"));
+
+        assertNotNull(enc);
+
+        String encValPart = "AAAAAAAAAA";
+        String plainValPart = "BBBBBBBBBB";
+
+        StringBuilder longEncVal = new StringBuilder(encValPart.length()*100);
+        StringBuilder longPlainVal = new StringBuilder(plainValPart.length()*100);
+
+        for (int i = 0; i < 100; i++) {
+            longEncVal.append(encValPart);
+            longPlainVal.append(plainValPart);
+        }
+
+        enc.put(1, longEncVal.toString());
+        plain.put(1, longPlainVal.toString());
+
+        stopAllGrids(false);
+
+        byte[] encValBytes = encValPart.getBytes(StandardCharsets.UTF_8);
+        byte[] plainValBytes = plainValPart.getBytes(StandardCharsets.UTF_8);
+
+        final boolean[] plainBytesFound = {false};
+
+        Files.walk(U.resolveWorkDirectory(U.defaultWorkDirectory(), "db", false).toPath())
+            .filter(Files::isRegularFile)
+            .forEach(f -> {
+                try {
+                    if (Files.size(f) == 0)
+                        return;
+
+                    byte[] fileBytes = Files.readAllBytes(f);
+
+                    boolean notFound = Bytes.indexOf(fileBytes, encValBytes) == -1;
+
+                    assertTrue("Value should be encrypted in persisted file. " + f.getFileName(), notFound);
+
+                    plainBytesFound[0] = plainBytesFound[0] || Bytes.indexOf(fileBytes, plainValBytes) != -1;
+
+                } catch (IOException e) {
+                    throw new RuntimeException(e);
+                }
+            });
+
+        assertTrue("Plain value should be found in persistent store", plainBytesFound[0]);
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/aabacfa0/modules/core/src/test/java/org/apache/ignite/internal/encryption/EncryptedCacheDestroyTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/encryption/EncryptedCacheDestroyTest.java b/modules/core/src/test/java/org/apache/ignite/internal/encryption/EncryptedCacheDestroyTest.java
new file mode 100644
index 0000000..11855ec
--- /dev/null
+++ b/modules/core/src/test/java/org/apache/ignite/internal/encryption/EncryptedCacheDestroyTest.java
@@ -0,0 +1,127 @@
+/*
+ * 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.encryption;
+
+import java.util.Collection;
+import org.apache.ignite.internal.IgniteEx;
+import org.apache.ignite.internal.processors.cache.persistence.metastorage.MetaStorage;
+import org.apache.ignite.internal.util.typedef.T2;
+import org.apache.ignite.internal.util.typedef.internal.CU;
+import org.apache.ignite.spi.encryption.keystore.KeystoreEncryptionKey;
+
+import static org.apache.ignite.internal.managers.encryption.GridEncryptionManager.ENCRYPTION_KEY_PREFIX;
+
+/**
+ */
+public class EncryptedCacheDestroyTest extends AbstractEncryptionTest {
+    /** {@inheritDoc} */
+    @Override protected void afterTest() throws Exception {
+        stopAllGrids();
+
+        cleanPersistenceDir();
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    public void testEncryptedCacheDestroy() throws Exception {
+        T2<IgniteEx, IgniteEx> grids = startTestGrids(true);
+
+        createEncryptedCache(grids.get1(), grids.get2(), cacheName(), null);
+
+        checkEncryptedCaches(grids.get1(), grids.get2());
+
+        String encryptedCacheName = cacheName();
+
+        grids.get1().destroyCache(encryptedCacheName);
+
+        checkCacheDestroyed(grids.get2(), encryptedCacheName, null, true);
+
+        stopAllGrids(true);
+
+        grids = startTestGrids(false);
+
+        checkCacheDestroyed(grids.get1(), encryptedCacheName, null, true);
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    public void testEncryptedCacheFromGroupDestroy() throws Exception {
+        T2<IgniteEx, IgniteEx> grids = startTestGrids(true);
+
+        String encCacheName = cacheName();
+
+        String grpName = "group1";
+
+        createEncryptedCache(grids.get1(), grids.get2(), encCacheName + "2", grpName);
+        createEncryptedCache(grids.get1(), grids.get2(), encCacheName, grpName);
+
+        checkEncryptedCaches(grids.get1(), grids.get2());
+
+        grids.get1().destroyCache(encCacheName);
+
+        checkCacheDestroyed(grids.get2(), encCacheName, grpName, false);
+
+        stopAllGrids(true);
+
+        grids = startTestGrids(false);
+
+        checkCacheDestroyed(grids.get1(), encCacheName, grpName, false);
+
+        grids.get1().destroyCache(encCacheName + "2");
+
+        checkCacheDestroyed(grids.get1(), encCacheName + "2", grpName, true);
+
+        stopAllGrids(true);
+
+        grids = startTestGrids(false);
+
+        checkCacheDestroyed(grids.get1(), encCacheName, grpName, true);
+
+        checkCacheDestroyed(grids.get1(), encCacheName + "2", grpName, true);
+    }
+
+    /** */
+    private void checkCacheDestroyed(IgniteEx grid, String encCacheName, String grpName, boolean keyShouldBeEmpty)
+        throws Exception {
+        awaitPartitionMapExchange();
+
+        Collection<String> cacheNames = grid.cacheNames();
+
+        for (String cacheName : cacheNames) {
+            if (cacheName.equals(encCacheName))
+                fail(encCacheName + " should be destroyed.");
+        }
+
+        int grpId = CU.cacheGroupId(encCacheName, grpName);
+
+        KeystoreEncryptionKey encKey = (KeystoreEncryptionKey)grid.context().encryption().groupKey(grpId);
+        MetaStorage metaStore = grid.context().cache().context().database().metaStorage();
+
+        if (keyShouldBeEmpty) {
+            assertNull(encKey);
+
+            assertNull(metaStore.getData(ENCRYPTION_KEY_PREFIX + grpId));
+        } else {
+            assertNotNull(encKey);
+
+            assertNotNull(metaStore.getData(ENCRYPTION_KEY_PREFIX + grpId));
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/aabacfa0/modules/core/src/test/java/org/apache/ignite/internal/encryption/EncryptedCacheGroupCreateTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/encryption/EncryptedCacheGroupCreateTest.java b/modules/core/src/test/java/org/apache/ignite/internal/encryption/EncryptedCacheGroupCreateTest.java
new file mode 100644
index 0000000..56f578d
--- /dev/null
+++ b/modules/core/src/test/java/org/apache/ignite/internal/encryption/EncryptedCacheGroupCreateTest.java
@@ -0,0 +1,116 @@
+/*
+ * 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.encryption;
+
+import org.apache.ignite.IgniteCheckedException;
+import org.apache.ignite.configuration.CacheConfiguration;
+import org.apache.ignite.internal.IgniteEx;
+import org.apache.ignite.internal.managers.encryption.GridEncryptionManager;
+import org.apache.ignite.internal.processors.cache.IgniteInternalCache;
+import org.apache.ignite.internal.util.typedef.internal.CU;
+import org.apache.ignite.spi.encryption.keystore.KeystoreEncryptionKey;
+import org.apache.ignite.testframework.GridTestUtils;
+
+/**
+ */
+public class EncryptedCacheGroupCreateTest extends AbstractEncryptionTest {
+    /** */
+    public static final String ENCRYPTED_GROUP = "encrypted-group";
+
+    /** {@inheritDoc} */
+    @Override protected void afterTestsStopped() throws Exception {
+        stopAllGrids();
+
+        cleanPersistenceDir();
+    }
+
+    /** {@inheritDoc} */
+    @Override protected void beforeTestsStarted() throws Exception {
+        cleanPersistenceDir();
+
+        IgniteEx igniteEx = startGrid(0);
+
+        startGrid(1);
+
+        igniteEx.cluster().active(true);
+
+        awaitPartitionMapExchange();
+    }
+
+    /** @throws Exception If failed. */
+    public void testCreateEncryptedCacheGroup() throws Exception {
+        KeystoreEncryptionKey key = createEncryptedCache(ENCRYPTED_CACHE, ENCRYPTED_GROUP);
+
+        CacheConfiguration<Long, String> ccfg = new CacheConfiguration<>(ENCRYPTED_CACHE + "2");
+
+        ccfg.setEncryptionEnabled(true);
+        ccfg.setGroupName(ENCRYPTED_GROUP);
+
+        IgniteEx grid = grid(0);
+
+        grid.createCache(ccfg);
+
+        IgniteInternalCache<Object, Object> encrypted2 = grid.cachex(ENCRYPTED_CACHE + "2");
+
+        GridEncryptionManager encMgr = encrypted2.context().kernalContext().encryption();
+
+        KeystoreEncryptionKey key2 = (KeystoreEncryptionKey)encMgr.groupKey(CU.cacheGroupId(ENCRYPTED_CACHE, ENCRYPTED_GROUP));
+
+        assertNotNull(key2);
+        assertNotNull(key2.key());
+
+        assertEquals(key.key(), key2.key());
+    }
+
+    /** @throws Exception If failed. */
+    public void testCreateNotEncryptedCacheInEncryptedGroupFails() throws Exception {
+        createEncryptedCache(ENCRYPTED_CACHE + "3", ENCRYPTED_GROUP + "3");
+
+        IgniteEx grid = grid(0);
+
+        GridTestUtils.assertThrowsWithCause(() -> {
+            grid.createCache(new CacheConfiguration<>(ENCRYPTED_CACHE + "4")
+                .setEncryptionEnabled(false)
+                .setGroupName(ENCRYPTED_GROUP + "3"));
+        }, IgniteCheckedException.class);
+    }
+
+    /** */
+    private KeystoreEncryptionKey createEncryptedCache(String cacheName, String grpName) {
+        CacheConfiguration<Long, String> ccfg = new CacheConfiguration<>(cacheName);
+
+        ccfg.setEncryptionEnabled(true);
+        ccfg.setGroupName(grpName);
+
+        IgniteEx grid = grid(0);
+
+        grid.createCache(ccfg);
+
+        IgniteInternalCache<Object, Object> enc = grid.cachex(cacheName);
+
+        assertNotNull(enc);
+
+        KeystoreEncryptionKey key =
+            (KeystoreEncryptionKey)grid.context().encryption().groupKey(CU.cacheGroupId(cacheName, grpName));
+
+        assertNotNull(key);
+        assertNotNull(key.key());
+
+        return key;
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/aabacfa0/modules/core/src/test/java/org/apache/ignite/internal/encryption/EncryptedCacheNodeJoinTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/encryption/EncryptedCacheNodeJoinTest.java b/modules/core/src/test/java/org/apache/ignite/internal/encryption/EncryptedCacheNodeJoinTest.java
new file mode 100644
index 0000000..41a250c
--- /dev/null
+++ b/modules/core/src/test/java/org/apache/ignite/internal/encryption/EncryptedCacheNodeJoinTest.java
@@ -0,0 +1,237 @@
+/*
+ * 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.encryption;
+
+import org.apache.ignite.IgniteCheckedException;
+import org.apache.ignite.configuration.CacheConfiguration;
+import org.apache.ignite.configuration.IgniteConfiguration;
+import org.apache.ignite.internal.IgniteEx;
+import org.apache.ignite.internal.util.IgniteUtils;
+import org.apache.ignite.spi.encryption.keystore.KeystoreEncryptionSpi;
+
+import static org.apache.ignite.testframework.GridTestUtils.assertThrowsWithCause;
+
+/**
+ */
+public class EncryptedCacheNodeJoinTest extends AbstractEncryptionTest {
+    /** */
+    private static final String GRID_2 = "grid-2";
+
+    /** */
+    private static final String GRID_3 = "grid-3";
+
+    /** */
+    private static final String GRID_4 = "grid-4";
+
+    /** */
+    private static final String GRID_5 = "grid-5";
+
+    /** */
+    public static final String CLIENT = "client";
+
+    /** */
+    private boolean configureCache;
+
+    /** */
+    private static final String KEYSTORE_PATH_2 =
+        IgniteUtils.resolveIgnitePath("modules/core/src/test/resources/other_tde_keystore.jks").getAbsolutePath();
+
+    /** {@inheritDoc} */
+    @Override protected void beforeTestsStarted() throws Exception {
+        cleanPersistenceDir();
+    }
+
+    /** {@inheritDoc} */
+    @Override protected void afterTest() throws Exception {
+        stopAllGrids();
+
+        cleanPersistenceDir();
+
+        configureCache = false;
+    }
+
+    /** {@inheritDoc} */
+    @Override protected IgniteConfiguration getConfiguration(String grid) throws Exception {
+        IgniteConfiguration cfg = super.getConfiguration(grid);
+
+        cfg.setConsistentId(grid);
+
+        if (grid.equals(GRID_0) ||
+            grid.equals(GRID_2) ||
+            grid.equals(GRID_3) ||
+            grid.equals(GRID_4) ||
+            grid.equals(GRID_5)) {
+            KeystoreEncryptionSpi encSpi = new KeystoreEncryptionSpi();
+
+            encSpi.setKeyStorePath(grid.equals(GRID_2) ? KEYSTORE_PATH_2 : KEYSTORE_PATH);
+            encSpi.setKeyStorePassword(KEYSTORE_PASSWORD.toCharArray());
+
+            cfg.setEncryptionSpi(encSpi);
+        }
+        else
+            cfg.setEncryptionSpi(null);
+
+        cfg.setClientMode(grid.equals(CLIENT));
+
+        if (configureCache)
+            cfg.setCacheConfiguration(cacheConfiguration(grid));
+
+        return cfg;
+    }
+
+    /** */
+    protected CacheConfiguration cacheConfiguration(String gridName) {
+        CacheConfiguration ccfg = defaultCacheConfiguration();
+
+        ccfg.setName(cacheName());
+        ccfg.setEncryptionEnabled(gridName.equals(GRID_0));
+
+        return ccfg;
+    }
+
+    /** */
+    public void testNodeCantJoinWithoutEncryptionSpi() throws Exception {
+        startGrid(GRID_0);
+
+        assertThrowsWithCause(() -> {
+            try {
+                startGrid(GRID_1);
+            }
+            catch (Exception e) {
+                throw new RuntimeException(e);
+            }
+        }, IgniteCheckedException.class);
+    }
+
+    /** */
+    public void testNodeCantJoinWithDifferentKeyStore() throws Exception {
+        startGrid(GRID_0);
+
+        assertThrowsWithCause(() -> {
+            try {
+                startGrid(GRID_2);
+            }
+            catch (Exception e) {
+                throw new RuntimeException(e);
+            }
+        }, IgniteCheckedException.class);
+    }
+
+    /** */
+    public void testNodeCanJoin() throws Exception {
+        startGrid(GRID_0);
+
+        startGrid(GRID_3).cluster().active(true);
+    }
+
+    /** */
+    public void testNodeCantJoinWithDifferentCacheKeys() throws Exception {
+        IgniteEx grid0 = startGrid(GRID_0);
+        startGrid(GRID_3);
+
+        grid0.cluster().active(true);
+
+        stopGrid(GRID_3, false);
+
+        createEncryptedCache(grid0, null, cacheName(), null, false);
+
+        stopGrid(GRID_0, false);
+        IgniteEx grid3 = startGrid(GRID_3);
+
+        grid3.cluster().active(true);
+
+        createEncryptedCache(grid3, null, cacheName(), null, false);
+
+        assertThrowsWithCause(() -> {
+            try {
+                startGrid(GRID_0);
+            }
+            catch (Exception e) {
+                throw new RuntimeException(e);
+            }
+        }, IgniteCheckedException.class);
+    }
+
+    /** */
+    public void testThirdNodeCanJoin() throws Exception {
+        IgniteEx grid0 = startGrid(GRID_0);
+
+        IgniteEx grid3 = startGrid(GRID_3);
+
+        grid3.cluster().active(true);
+
+        createEncryptedCache(grid0, grid3, cacheName(), null);
+
+        checkEncryptedCaches(grid0, grid3);
+
+        IgniteEx grid4 = startGrid(GRID_4);
+
+        awaitPartitionMapExchange();
+
+        checkEncryptedCaches(grid0, grid4);
+    }
+
+    /** */
+    public void testClientNodeJoin() throws Exception {
+        IgniteEx grid0 = startGrid(GRID_0);
+
+        IgniteEx grid3 = startGrid(GRID_3);
+
+        grid3.cluster().active(true);
+
+        IgniteEx client = startGrid(CLIENT);
+
+        createEncryptedCache(client, grid0, cacheName(), null);
+    }
+
+    /** */
+    public void testNodeCantJoinWithSameNameButNotEncCache() throws Exception {
+        configureCache = true;
+
+        IgniteEx grid0 = startGrid(GRID_0);
+
+        grid0.cluster().active(true);
+
+        assertThrowsWithCause(() -> {
+            try {
+                startGrid(GRID_5);
+            }
+            catch (Exception e) {
+                throw new RuntimeException(e);
+            }
+        }, IgniteCheckedException.class);
+    }
+
+    /** */
+    public void testNodeCantJoinWithSameNameButEncCache() throws Exception {
+        configureCache = true;
+
+        IgniteEx grid0 = startGrid(GRID_5);
+
+        grid0.cluster().active(true);
+
+        assertThrowsWithCause(() -> {
+            try {
+                startGrid(GRID_0);
+            }
+            catch (Exception e) {
+                throw new RuntimeException(e);
+            }
+        }, IgniteCheckedException.class);
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/aabacfa0/modules/core/src/test/java/org/apache/ignite/internal/encryption/EncryptedCachePreconfiguredRestartTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/encryption/EncryptedCachePreconfiguredRestartTest.java b/modules/core/src/test/java/org/apache/ignite/internal/encryption/EncryptedCachePreconfiguredRestartTest.java
new file mode 100644
index 0000000..2e13340
--- /dev/null
+++ b/modules/core/src/test/java/org/apache/ignite/internal/encryption/EncryptedCachePreconfiguredRestartTest.java
@@ -0,0 +1,87 @@
+/*
+ * 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.encryption;
+
+import org.apache.ignite.IgniteCache;
+import org.apache.ignite.configuration.CacheConfiguration;
+import org.apache.ignite.configuration.IgniteConfiguration;
+import org.apache.ignite.internal.IgniteEx;
+import org.jetbrains.annotations.NotNull;
+
+/** */
+public class EncryptedCachePreconfiguredRestartTest extends EncryptedCacheRestartTest {
+    /** */
+    private boolean differentCachesOnNodes;
+
+    /** {@inheritDoc} */
+    @Override protected void afterTestsStopped() throws Exception {
+        stopAllGrids();
+
+        cleanPersistenceDir();
+    }
+
+    /** {@inheritDoc} */
+    @Override protected void beforeTestsStarted() throws Exception {
+        cleanPersistenceDir();
+    }
+
+    /** @throws Exception If failed. */
+    public void testDifferentPreconfiguredCachesOnNodes() throws Exception {
+        differentCachesOnNodes = true;
+
+        super.testCreateEncryptedCache();
+    }
+
+    /** {@inheritDoc} */
+    @Override public void testCreateEncryptedCache() throws Exception {
+        differentCachesOnNodes = false;
+
+        super.testCreateEncryptedCache();
+    }
+
+    /** {@inheritDoc} */
+    @Override protected IgniteConfiguration getConfiguration(String igniteInstanceName) throws Exception {
+        IgniteConfiguration cfg = super.getConfiguration(igniteInstanceName);
+
+        String cacheName = ENCRYPTED_CACHE + (differentCachesOnNodes ? "." + igniteInstanceName : "");
+
+        CacheConfiguration ccfg = new CacheConfiguration(cacheName)
+            .setEncryptionEnabled(true);
+
+        cfg.setCacheConfiguration(ccfg);
+
+        return cfg;
+    }
+
+    /**
+     * @return Cache name.
+     */
+    @NotNull @Override protected String cacheName() {
+        return ENCRYPTED_CACHE + (differentCachesOnNodes ? "." + GRID_1 : "");
+    }
+
+    /**
+     * Creates encrypted cache.
+     */
+    @Override protected void createEncryptedCache(IgniteEx grid0, IgniteEx grid1, String cacheName, String groupName) {
+        IgniteCache<Long, String> cache = grid0.cache(cacheName());
+
+        for (long i=0; i<100; i++)
+            cache.put(i, "" + i);
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/aabacfa0/modules/core/src/test/java/org/apache/ignite/internal/encryption/EncryptedCacheRestartTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/encryption/EncryptedCacheRestartTest.java b/modules/core/src/test/java/org/apache/ignite/internal/encryption/EncryptedCacheRestartTest.java
new file mode 100644
index 0000000..2b01072
--- /dev/null
+++ b/modules/core/src/test/java/org/apache/ignite/internal/encryption/EncryptedCacheRestartTest.java
@@ -0,0 +1,64 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.internal.encryption;
+
+import org.apache.ignite.internal.IgniteEx;
+import org.apache.ignite.internal.util.typedef.T2;
+import org.apache.ignite.internal.util.typedef.internal.CU;
+import org.apache.ignite.spi.encryption.keystore.KeystoreEncryptionKey;
+
+/** */
+public class EncryptedCacheRestartTest extends AbstractEncryptionTest {
+    /** {@inheritDoc} */
+    @Override protected void afterTestsStopped() throws Exception {
+        cleanPersistenceDir();
+    }
+
+    /** {@inheritDoc} */
+    @Override protected void afterTest() throws Exception {
+        stopAllGrids(false);
+
+        cleanPersistenceDir();
+    }
+
+    /** @throws Exception If failed. */
+    public void testCreateEncryptedCache() throws Exception {
+        T2<IgniteEx, IgniteEx> grids = startTestGrids(true);
+
+        createEncryptedCache(grids.get1(), grids.get2(), cacheName(), null);
+
+        checkEncryptedCaches(grids.get1(), grids.get2());
+
+        int grpId = CU.cacheGroupId(cacheName(), null);
+
+        KeystoreEncryptionKey keyBeforeRestart = (KeystoreEncryptionKey)grids.get1().context().encryption().groupKey(grpId);
+
+        stopAllGrids();
+
+        grids = startTestGrids(false);
+
+        checkEncryptedCaches(grids.get1(), grids.get2());
+
+        KeystoreEncryptionKey keyAfterRestart = (KeystoreEncryptionKey)grids.get1().context().encryption().groupKey(grpId);
+
+        assertNotNull(keyAfterRestart);
+        assertNotNull(keyAfterRestart.key());
+
+        assertEquals(keyBeforeRestart.key(), keyAfterRestart.key());
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/aabacfa0/modules/core/src/test/java/org/apache/ignite/internal/pagemem/impl/PageMemoryNoLoadSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/pagemem/impl/PageMemoryNoLoadSelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/pagemem/impl/PageMemoryNoLoadSelfTest.java
index c5988e3..b393634 100644
--- a/modules/core/src/test/java/org/apache/ignite/internal/pagemem/impl/PageMemoryNoLoadSelfTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/internal/pagemem/impl/PageMemoryNoLoadSelfTest.java
@@ -77,8 +77,8 @@ public class PageMemoryNoLoadSelfTest extends GridCommonAbstractTest {
                     ", page2Id=" + fullId2.pageId() + ", page2=" + page2 + ']');
 
                 try {
-                    writePage(mem, fullId1.pageId(), page1, 1);
-                    writePage(mem, fullId2.pageId(), page2, 2);
+                    writePage(mem, fullId1, page1, 1);
+                    writePage(mem, fullId2, page2, 2);
 
                     readPage(mem, fullId1.pageId(), page1, 1);
                     readPage(mem, fullId2.pageId(), page2, 2);
@@ -149,7 +149,7 @@ public class PageMemoryNoLoadSelfTest extends GridCommonAbstractTest {
                     if (i % 64 == 0)
                         info("Writing page [idx=" + i + ", pageId=" + fullId.pageId() + ", page=" + page + ']');
 
-                    writePage(mem, fullId.pageId(), page, i + 1);
+                    writePage(mem, fullId, page, i + 1);
                 }
                 finally {
                     mem.releasePage(fullId.groupId(), fullId.pageId(), page);
@@ -230,7 +230,7 @@ public class PageMemoryNoLoadSelfTest extends GridCommonAbstractTest {
                     assertNotNull(pageAddr);
 
                     try {
-                        PAGE_IO.initNewPage(pageAddr, id.pageId(), mem.pageSize());
+                        PAGE_IO.initNewPage(pageAddr, id.pageId(), mem.realPageSize(id.groupId()));
 
                         long updId = PageIdUtils.rotatePageId(id.pageId());
 
@@ -332,21 +332,21 @@ public class PageMemoryNoLoadSelfTest extends GridCommonAbstractTest {
 
     /**
      * @param mem Page memory.
-     * @param pageId Page ID.
+     * @param fullId Page ID.
      * @param page Page pointer.
      * @param val Value to write.
      */
-    private void writePage(PageMemory mem, long pageId, long page, int val) {
-        long pageAddr = mem.writeLock(-1, pageId, page);
+    private void writePage(PageMemory mem, FullPageId fullId, long page, int val) {
+        long pageAddr = mem.writeLock(-1, fullId.pageId(), page);
 
         try {
-            PAGE_IO.initNewPage(pageAddr, pageId, mem.pageSize());
+            PAGE_IO.initNewPage(pageAddr, fullId.pageId(), mem.realPageSize(fullId.groupId()));
 
             for (int i = PageIO.COMMON_HEADER_END; i < PAGE_SIZE; i++)
                 PageUtils.putByte(pageAddr, i, (byte)val);
         }
         finally {
-            mem.writeUnlock(-1, pageId, page, null, true);
+            mem.writeUnlock(-1, fullId.pageId(), page, null, true);
         }
     }
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/aabacfa0/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/IgnitePdsRecoveryAfterFileCorruptionTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/IgnitePdsRecoveryAfterFileCorruptionTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/IgnitePdsRecoveryAfterFileCorruptionTest.java
index af6c8b7..15205e0 100644
--- a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/IgnitePdsRecoveryAfterFileCorruptionTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/IgnitePdsRecoveryAfterFileCorruptionTest.java
@@ -202,7 +202,7 @@ public class IgnitePdsRecoveryAfterFileCorruptionTest extends GridCommonAbstract
             final long pageAddr = mem.writeLock(fullId.groupId(), fullId.pageId(), page);
 
             try {
-                pageIO.initNewPage(pageAddr, fullId.pageId(), mem.pageSize());
+                pageIO.initNewPage(pageAddr, fullId.pageId(), mem.realPageSize(fullId.groupId()));
             }
             finally {
                 mem.writeUnlock(fullId.groupId(), fullId.pageId(), page, null, true);
@@ -261,7 +261,7 @@ public class IgnitePdsRecoveryAfterFileCorruptionTest extends GridCommonAbstract
                 try {
                     long pageAddr = mem.readLock(fullId.groupId(), fullId.pageId(), page);
 
-                    for (int j = PageIO.COMMON_HEADER_END; j < mem.pageSize(); j += 4)
+                    for (int j = PageIO.COMMON_HEADER_END; j < mem.realPageSize(fullId.groupId()); j += 4)
                         assertEquals(j + (int)fullId.pageId(), PageUtils.getInt(pageAddr, j));
 
                     mem.readUnlock(fullId.groupId(), fullId.pageId(), page);
@@ -305,7 +305,7 @@ public class IgnitePdsRecoveryAfterFileCorruptionTest extends GridCommonAbstract
                 PageIO.setPageId(pageAddr, fullId.pageId());
 
                 try {
-                    for (int j = PageIO.COMMON_HEADER_END; j < mem.pageSize(); j += 4)
+                    for (int j = PageIO.COMMON_HEADER_END; j < mem.realPageSize(fullId.groupId()); j += 4)
                         PageUtils.putInt(pageAddr, j, j + (int)fullId.pageId());
                 }
                 finally {
@@ -346,7 +346,7 @@ public class IgnitePdsRecoveryAfterFileCorruptionTest extends GridCommonAbstract
                     cp += cpEnd - cpStart;
                     tmpBuf.rewind();
 
-                    for (int j = PageIO.COMMON_HEADER_END; j < mem.pageSize(); j += 4)
+                    for (int j = PageIO.COMMON_HEADER_END; j < mem.realPageSize(fullId.groupId()); j += 4)
                         assertEquals(j + (int)fullId.pageId(), tmpBuf.getInt(j));
 
                     tmpBuf.rewind();

http://git-wip-us.apache.org/repos/asf/ignite/blob/aabacfa0/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/db/file/IgnitePdsCheckpointSimulationWithRealCpDisabledTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/db/file/IgnitePdsCheckpointSimulationWithRealCpDisabledTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/db/file/IgnitePdsCheckpointSimulationWithRealCpDisabledTest.java
index 5fa618b..620814f 100644
--- a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/db/file/IgnitePdsCheckpointSimulationWithRealCpDisabledTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/db/file/IgnitePdsCheckpointSimulationWithRealCpDisabledTest.java
@@ -238,12 +238,13 @@ public class IgnitePdsCheckpointSimulationWithRealCpDisabledTest extends GridCom
                     long pageAddr = mem.writeLock(fullId.groupId(), fullId.pageId(), page);
 
                     try {
-                        DataPageIO.VERSIONS.latest().initNewPage(pageAddr, fullId.pageId(), mem.pageSize());
+                        DataPageIO.VERSIONS.latest().initNewPage(pageAddr, fullId.pageId(),
+                            mem.realPageSize(fullId.groupId()));
 
                         for (int i = PageIO.COMMON_HEADER_END + DataPageIO.ITEMS_OFF; i < mem.pageSize(); i++)
                             PageUtils.putByte(pageAddr, i, (byte)0xAB);
 
-                        PageIO.printPage(pageAddr, mem.pageSize());
+                        PageIO.printPage(pageAddr, mem.realPageSize(fullId.groupId()));
                     }
                     finally {
                         mem.writeUnlock(fullId.groupId(), fullId.pageId(), page, null, true);
@@ -544,7 +545,7 @@ public class IgnitePdsCheckpointSimulationWithRealCpDisabledTest extends GridCom
                     long pageAddr = mem.writeLock(fullId.groupId(), fullId.pageId(), page);
 
                     try {
-                        pageIO.initNewPage(pageAddr, fullId.pageId(), mem.pageSize());
+                        pageIO.initNewPage(pageAddr, fullId.pageId(), mem.realPageSize(fullId.groupId()));
 
                         assertTrue(mem.isDirty(fullId.groupId(), fullId.pageId(), page));
                     }
@@ -632,7 +633,7 @@ public class IgnitePdsCheckpointSimulationWithRealCpDisabledTest extends GridCom
             long pageAddr = mem.writeLock(fullId.groupId(), fullId.pageId(), page);
 
             try {
-                DataPageIO.VERSIONS.latest().initNewPage(pageAddr, fullId.pageId(), mem.pageSize());
+                DataPageIO.VERSIONS.latest().initNewPage(pageAddr, fullId.pageId(), mem.realPageSize(fullId.groupId()));
 
                 ThreadLocalRandom rnd = ThreadLocalRandom.current();
 
@@ -707,7 +708,7 @@ public class IgnitePdsCheckpointSimulationWithRealCpDisabledTest extends GridCom
                 long pageAddr = mem.readLock(fullId.groupId(), fullId.pageId(), page);
 
                 try {
-                    for (int i = PageIO.COMMON_HEADER_END; i < mem.pageSize(); i++) {
+                    for (int i = PageIO.COMMON_HEADER_END; i < mem.realPageSize(fullId.groupId()); i++) {
                         int expState = state & 0xFF;
                         int pageState = PageUtils.getByte(pageAddr, i) & 0xFF;
                         int walState = walData[i] & 0xFF;
@@ -818,7 +819,8 @@ public class IgnitePdsCheckpointSimulationWithRealCpDisabledTest extends GridCom
                                                 ", bhc=" + U.hexLong(System.identityHashCode(pageAddr)) +
                                                 ", page=" + U.hexLong(System.identityHashCode(page)) + ']');
 
-                                        for (int i = PageIO.COMMON_HEADER_END; i < mem.pageSize(); i++)
+                                        for (int i = PageIO.COMMON_HEADER_END; i < mem.realPageSize(fullId.groupId());
+                                            i++) {
                                             assertEquals("Verify page failed [fullId=" + fullId +
                                                     ", i=" + i +
                                                     ", state=" + state +
@@ -826,6 +828,7 @@ public class IgnitePdsCheckpointSimulationWithRealCpDisabledTest extends GridCom
                                                     ", bhc=" + U.hexLong(System.identityHashCode(pageAddr)) +
                                                     ", page=" + U.hexLong(System.identityHashCode(page)) + ']',
                                                 state & 0xFF, PageUtils.getByte(pageAddr, i) & 0xFF);
+                                        }
                                     }
 
                                     state = (state + 1) & 0xFF;
@@ -836,7 +839,7 @@ public class IgnitePdsCheckpointSimulationWithRealCpDisabledTest extends GridCom
                                             ", bhc=" + U.hexLong(System.identityHashCode(pageAddr)) +
                                             ", page=" + U.hexLong(System.identityHashCode(page)) + ']');
 
-                                    for (int i = PageIO.COMMON_HEADER_END; i < mem.pageSize(); i++)
+                                    for (int i = PageIO.COMMON_HEADER_END; i < mem.realPageSize(fullId.groupId()); i++)
                                         PageUtils.putByte(pageAddr, i, (byte)state);
 
                                     resMap.put(fullId, state);
@@ -926,7 +929,7 @@ public class IgnitePdsCheckpointSimulationWithRealCpDisabledTest extends GridCom
 
                         Integer first = null;
 
-                        for (int i = PageIO.COMMON_HEADER_END; i < mem.pageSize(); i++) {
+                        for (int i = PageIO.COMMON_HEADER_END; i < mem.realPageSize(fullId.groupId()); i++) {
                             int val = tmpBuf.get(i) & 0xFF;
 
                             if (first == null)
@@ -1027,7 +1030,7 @@ public class IgnitePdsCheckpointSimulationWithRealCpDisabledTest extends GridCom
             final long pageAddr = mem.writeLock(fullId.groupId(), fullId.pageId(), page);
 
             try {
-                pageIO.initNewPage(pageAddr, fullId.pageId(), mem.pageSize());
+                pageIO.initNewPage(pageAddr, fullId.pageId(), mem.realPageSize(fullId.groupId()));
             }
             finally {
                 mem.writeUnlock(fullId.groupId(), fullId.pageId(), page, null, true);

http://git-wip-us.apache.org/repos/asf/ignite/blob/aabacfa0/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/db/file/IgnitePdsPageReplacementTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/db/file/IgnitePdsPageReplacementTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/db/file/IgnitePdsPageReplacementTest.java
index 432393e..2697c01 100644
--- a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/db/file/IgnitePdsPageReplacementTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/db/file/IgnitePdsPageReplacementTest.java
@@ -201,7 +201,7 @@ public class IgnitePdsPageReplacementTest extends GridCommonAbstractTest {
             final long pageAddr = mem.writeLock(fullId.groupId(), fullId.pageId(), page);
 
             try {
-                pageIO.initNewPage(pageAddr, fullId.pageId(), mem.pageSize());
+                pageIO.initNewPage(pageAddr, fullId.pageId(), mem.realPageSize(fullId.groupId()));
             }
             finally {
                 mem.writeUnlock(fullId.groupId(), fullId.pageId(), page, null, true);

http://git-wip-us.apache.org/repos/asf/ignite/blob/aabacfa0/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/db/wal/WalCompactionTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/db/wal/WalCompactionTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/db/wal/WalCompactionTest.java
index e617455..dcc2280 100644
--- a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/db/wal/WalCompactionTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/db/wal/WalCompactionTest.java
@@ -149,8 +149,10 @@ public class WalCompactionTest extends GridCommonAbstractTest {
         }
 
         // Spam WAL to move all data records to compressible WAL zone.
-        for (int i = 0; i < WAL_SEGMENT_SIZE / DFLT_PAGE_SIZE * 2; i++)
-            ig.context().cache().context().wal().log(new PageSnapshot(new FullPageId(-1, -1), new byte[DFLT_PAGE_SIZE]));
+        for (int i = 0; i < WAL_SEGMENT_SIZE / DFLT_PAGE_SIZE * 2; i++) {
+            ig.context().cache().context().wal().log(new PageSnapshot(new FullPageId(-1, -1), new byte[DFLT_PAGE_SIZE],
+                DFLT_PAGE_SIZE));
+        }
 
         // WAL archive segment is allowed to be compressed when it's at least one checkpoint away from current WAL head.
         ig.context().cache().context().database().wakeupForCheckpoint("Forced checkpoint").get();
@@ -347,8 +349,10 @@ public class WalCompactionTest extends GridCommonAbstractTest {
         }
 
         // Spam WAL to move all data records to compressible WAL zone.
-        for (int i = 0; i < WAL_SEGMENT_SIZE / DFLT_PAGE_SIZE * 2; i++)
-            ig.context().cache().context().wal().log(new PageSnapshot(new FullPageId(-1, -1), new byte[DFLT_PAGE_SIZE]));
+        for (int i = 0; i < WAL_SEGMENT_SIZE / DFLT_PAGE_SIZE * 2; i++) {
+            ig.context().cache().context().wal().log(new PageSnapshot(new FullPageId(-1, -1), new byte[DFLT_PAGE_SIZE],
+                DFLT_PAGE_SIZE));
+        }
 
         // WAL archive segment is allowed to be compressed when it's at least one checkpoint away from current WAL head.
         ig.context().cache().context().database().wakeupForCheckpoint("Forced checkpoint").get();

http://git-wip-us.apache.org/repos/asf/ignite/blob/aabacfa0/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/pagemem/BPlusTreePageMemoryImplTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/pagemem/BPlusTreePageMemoryImplTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/pagemem/BPlusTreePageMemoryImplTest.java
index 7719b43..bb0c416 100644
--- a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/pagemem/BPlusTreePageMemoryImplTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/pagemem/BPlusTreePageMemoryImplTest.java
@@ -17,17 +17,25 @@
 
 package org.apache.ignite.internal.processors.cache.persistence.pagemem;
 
+import java.util.Collections;
 import org.apache.ignite.configuration.DataRegionConfiguration;
+import org.apache.ignite.configuration.IgniteConfiguration;
+import org.apache.ignite.internal.managers.encryption.GridEncryptionManager;
 import org.apache.ignite.internal.mem.DirectMemoryProvider;
 import org.apache.ignite.internal.mem.unsafe.UnsafeMemoryProvider;
 import org.apache.ignite.internal.pagemem.FullPageId;
 import org.apache.ignite.internal.pagemem.PageMemory;
 import org.apache.ignite.internal.processors.cache.GridCacheSharedContext;
+import org.apache.ignite.internal.processors.cache.persistence.CheckpointWriteProgressSupplier;
 import org.apache.ignite.internal.processors.cache.persistence.DataRegionMetricsImpl;
 import org.apache.ignite.internal.processors.cache.persistence.IgniteCacheDatabaseSharedManager;
 import org.apache.ignite.internal.processors.database.BPlusTreeSelfTest;
+import org.apache.ignite.internal.processors.plugin.IgnitePluginProcessor;
+import org.apache.ignite.internal.processors.subscription.GridInternalSubscriptionProcessor;
 import org.apache.ignite.internal.util.typedef.CIX3;
+import org.apache.ignite.spi.encryption.noop.NoopEncryptionSpi;
 import org.apache.ignite.testframework.junits.GridTestKernalContext;
+import org.mockito.Mockito;
 
 /**
  *
@@ -44,8 +52,18 @@ public class BPlusTreePageMemoryImplTest extends BPlusTreeSelfTest {
 
         DirectMemoryProvider provider = new UnsafeMemoryProvider(log);
 
+        IgniteConfiguration cfg = new IgniteConfiguration();
+
+        cfg.setEncryptionSpi(new NoopEncryptionSpi());
+
+        GridTestKernalContext cctx = new GridTestKernalContext(log, cfg);
+
+        cctx.add(new IgnitePluginProcessor(cctx, cfg, Collections.emptyList()));
+        cctx.add(new GridInternalSubscriptionProcessor(cctx));
+        cctx.add(new GridEncryptionManager(cctx));
+
         GridCacheSharedContext<Object, Object> sharedCtx = new GridCacheSharedContext<>(
-            new GridTestKernalContext(log),
+            cctx,
             null,
             null,
             null,
@@ -78,7 +96,7 @@ public class BPlusTreePageMemoryImplTest extends BPlusTreeSelfTest {
             () -> true,
             new DataRegionMetricsImpl(new DataRegionConfiguration()),
             PageMemoryImpl.ThrottlingPolicy.DISABLED,
-            null
+            Mockito.mock(CheckpointWriteProgressSupplier.class)
         );
 
         mem.start();

http://git-wip-us.apache.org/repos/asf/ignite/blob/aabacfa0/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/pagemem/BPlusTreeReuseListPageMemoryImplTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/pagemem/BPlusTreeReuseListPageMemoryImplTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/pagemem/BPlusTreeReuseListPageMemoryImplTest.java
index 71eb129..71e308b 100644
--- a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/pagemem/BPlusTreeReuseListPageMemoryImplTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/pagemem/BPlusTreeReuseListPageMemoryImplTest.java
@@ -17,7 +17,10 @@
 
 package org.apache.ignite.internal.processors.cache.persistence.pagemem;
 
+import java.util.Collections;
 import org.apache.ignite.configuration.DataRegionConfiguration;
+import org.apache.ignite.configuration.IgniteConfiguration;
+import org.apache.ignite.internal.managers.encryption.GridEncryptionManager;
 import org.apache.ignite.internal.mem.DirectMemoryProvider;
 import org.apache.ignite.internal.mem.unsafe.UnsafeMemoryProvider;
 import org.apache.ignite.internal.pagemem.FullPageId;
@@ -27,7 +30,10 @@ import org.apache.ignite.internal.processors.cache.persistence.CheckpointWritePr
 import org.apache.ignite.internal.processors.cache.persistence.DataRegionMetricsImpl;
 import org.apache.ignite.internal.processors.cache.persistence.IgniteCacheDatabaseSharedManager;
 import org.apache.ignite.internal.processors.database.BPlusTreeReuseSelfTest;
+import org.apache.ignite.internal.processors.plugin.IgnitePluginProcessor;
+import org.apache.ignite.internal.processors.subscription.GridInternalSubscriptionProcessor;
 import org.apache.ignite.internal.util.lang.GridInClosure3X;
+import org.apache.ignite.spi.encryption.noop.NoopEncryptionSpi;
 import org.apache.ignite.testframework.junits.GridTestKernalContext;
 import org.mockito.Mockito;
 
@@ -46,8 +52,18 @@ public class BPlusTreeReuseListPageMemoryImplTest extends BPlusTreeReuseSelfTest
 
         DirectMemoryProvider provider = new UnsafeMemoryProvider(log);
 
+        IgniteConfiguration cfg = new IgniteConfiguration();
+
+        cfg.setEncryptionSpi(new NoopEncryptionSpi());
+
+        GridTestKernalContext cctx = new GridTestKernalContext(log, cfg);
+
+        cctx.add(new IgnitePluginProcessor(cctx, cfg, Collections.emptyList()));
+        cctx.add(new GridInternalSubscriptionProcessor(cctx));
+        cctx.add(new GridEncryptionManager(cctx));
+
         GridCacheSharedContext<Object, Object> sharedCtx = new GridCacheSharedContext<>(
-            new GridTestKernalContext(log),
+            cctx,
             null,
             null,
             null,

http://git-wip-us.apache.org/repos/asf/ignite/blob/aabacfa0/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/pagemem/IgnitePageMemReplaceDelayedWriteUnitTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/pagemem/IgnitePageMemReplaceDelayedWriteUnitTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/pagemem/IgnitePageMemReplaceDelayedWriteUnitTest.java
index 5c965b1..b6031fa 100644
--- a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/pagemem/IgnitePageMemReplaceDelayedWriteUnitTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/pagemem/IgnitePageMemReplaceDelayedWriteUnitTest.java
@@ -36,12 +36,14 @@ import org.apache.ignite.internal.mem.unsafe.UnsafeMemoryProvider;
 import org.apache.ignite.internal.pagemem.FullPageId;
 import org.apache.ignite.internal.pagemem.PageIdAllocator;
 import org.apache.ignite.internal.processors.cache.GridCacheSharedContext;
+import org.apache.ignite.internal.processors.cache.persistence.CheckpointWriteProgressSupplier;
 import org.apache.ignite.internal.processors.cache.persistence.DataRegionMetricsImpl;
 import org.apache.ignite.internal.processors.cache.persistence.GridCacheDatabaseSharedManager;
 import org.apache.ignite.internal.processors.cache.persistence.IgniteCacheDatabaseSharedManager;
 import org.apache.ignite.internal.util.GridMultiCollectionWrapper;
 import org.apache.ignite.internal.util.typedef.internal.U;
 import org.apache.ignite.logger.NullLogger;
+import org.apache.ignite.spi.encryption.noop.NoopEncryptionSpi;
 import org.apache.ignite.testframework.GridTestUtils;
 import org.jetbrains.annotations.NotNull;
 import org.junit.Rule;
@@ -231,7 +233,8 @@ public class IgnitePageMemReplaceDelayedWriteUnitTest {
         DirectMemoryProvider provider = new UnsafeMemoryProvider(log);
 
         PageMemoryImpl memory = new PageMemoryImpl(provider, sizes, sctx, pageSize,
-            pageWriter, null, () -> true, memMetrics, PageMemoryImpl.ThrottlingPolicy.DISABLED, null);
+            pageWriter, null, () -> true, memMetrics, PageMemoryImpl.ThrottlingPolicy.DISABLED,
+            mock(CheckpointWriteProgressSupplier.class));
 
         memory.start();
         return memory;
@@ -244,6 +247,8 @@ public class IgnitePageMemReplaceDelayedWriteUnitTest {
     @NotNull private IgniteConfiguration getConfiguration(long overallSize) {
         IgniteConfiguration cfg = new IgniteConfiguration();
 
+        cfg.setEncryptionSpi(new NoopEncryptionSpi());
+
         cfg.setDataStorageConfiguration(
             new DataStorageConfiguration()
                 .setDefaultDataRegionConfiguration(

http://git-wip-us.apache.org/repos/asf/ignite/blob/aabacfa0/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/pagemem/IndexStoragePageMemoryImplTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/pagemem/IndexStoragePageMemoryImplTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/pagemem/IndexStoragePageMemoryImplTest.java
index 43fbb6e..d3530b4 100644
--- a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/pagemem/IndexStoragePageMemoryImplTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/pagemem/IndexStoragePageMemoryImplTest.java
@@ -18,18 +18,26 @@
 package org.apache.ignite.internal.processors.cache.persistence.pagemem;
 
 import java.io.File;
+import java.util.Collections;
 import org.apache.ignite.configuration.DataRegionConfiguration;
+import org.apache.ignite.configuration.IgniteConfiguration;
+import org.apache.ignite.internal.managers.encryption.GridEncryptionManager;
 import org.apache.ignite.internal.mem.DirectMemoryProvider;
 import org.apache.ignite.internal.mem.file.MappedFileMemoryProvider;
 import org.apache.ignite.internal.pagemem.FullPageId;
 import org.apache.ignite.internal.pagemem.PageMemory;
 import org.apache.ignite.internal.processors.cache.GridCacheSharedContext;
+import org.apache.ignite.internal.processors.cache.persistence.CheckpointWriteProgressSupplier;
 import org.apache.ignite.internal.processors.cache.persistence.DataRegionMetricsImpl;
 import org.apache.ignite.internal.processors.cache.persistence.IgniteCacheDatabaseSharedManager;
 import org.apache.ignite.internal.processors.database.IndexStorageSelfTest;
+import org.apache.ignite.internal.processors.plugin.IgnitePluginProcessor;
+import org.apache.ignite.internal.processors.subscription.GridInternalSubscriptionProcessor;
 import org.apache.ignite.internal.util.lang.GridInClosure3X;
 import org.apache.ignite.internal.util.typedef.internal.U;
+import org.apache.ignite.spi.encryption.noop.NoopEncryptionSpi;
 import org.apache.ignite.testframework.junits.GridTestKernalContext;
+import org.mockito.Mockito;
 
 /**
  *
@@ -59,8 +67,18 @@ public class IndexStoragePageMemoryImplTest extends IndexStorageSelfTest {
 
         DirectMemoryProvider provider = new MappedFileMemoryProvider(log(), allocationPath);
 
+        IgniteConfiguration cfg = new IgniteConfiguration();
+
+        cfg.setEncryptionSpi(new NoopEncryptionSpi());
+
+        GridTestKernalContext cctx = new GridTestKernalContext(log, cfg);
+
+        cctx.add(new IgnitePluginProcessor(cctx, cfg, Collections.emptyList()));
+        cctx.add(new GridInternalSubscriptionProcessor(cctx));
+        cctx.add(new GridEncryptionManager(cctx));
+
         GridCacheSharedContext<Object, Object> sharedCtx = new GridCacheSharedContext<>(
-            new GridTestKernalContext(log),
+            cctx,
             null,
             null,
             null,
@@ -93,7 +111,7 @@ public class IndexStoragePageMemoryImplTest extends IndexStorageSelfTest {
             () -> true,
             new DataRegionMetricsImpl(new DataRegionConfiguration()),
             PageMemoryImpl.ThrottlingPolicy.DISABLED,
-            null
+            Mockito.mock(CheckpointWriteProgressSupplier.class)
         );
     }
 }

http://git-wip-us.apache.org/repos/asf/ignite/blob/aabacfa0/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/pagemem/PageMemoryImplNoLoadTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/pagemem/PageMemoryImplNoLoadTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/pagemem/PageMemoryImplNoLoadTest.java
index 52aff0c..83e1894 100644
--- a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/pagemem/PageMemoryImplNoLoadTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/pagemem/PageMemoryImplNoLoadTest.java
@@ -18,7 +18,10 @@
 package org.apache.ignite.internal.processors.cache.persistence.pagemem;
 
 import java.io.File;
+import java.util.Collections;
 import org.apache.ignite.configuration.DataRegionConfiguration;
+import org.apache.ignite.configuration.IgniteConfiguration;
+import org.apache.ignite.internal.managers.encryption.GridEncryptionManager;
 import org.apache.ignite.internal.mem.DirectMemoryProvider;
 import org.apache.ignite.internal.mem.file.MappedFileMemoryProvider;
 import org.apache.ignite.internal.pagemem.FullPageId;
@@ -26,11 +29,16 @@ import org.apache.ignite.internal.pagemem.PageMemory;
 import org.apache.ignite.internal.pagemem.impl.PageMemoryNoLoadSelfTest;
 import org.apache.ignite.internal.processors.cache.GridCacheSharedContext;
 import org.apache.ignite.internal.processors.cache.persistence.CheckpointLockStateChecker;
+import org.apache.ignite.internal.processors.cache.persistence.CheckpointWriteProgressSupplier;
 import org.apache.ignite.internal.processors.cache.persistence.DataRegionMetricsImpl;
 import org.apache.ignite.internal.processors.cache.persistence.IgniteCacheDatabaseSharedManager;
+import org.apache.ignite.internal.processors.plugin.IgnitePluginProcessor;
+import org.apache.ignite.internal.processors.subscription.GridInternalSubscriptionProcessor;
 import org.apache.ignite.internal.util.lang.GridInClosure3X;
 import org.apache.ignite.internal.util.typedef.internal.U;
+import org.apache.ignite.spi.encryption.noop.NoopEncryptionSpi;
 import org.apache.ignite.testframework.junits.GridTestKernalContext;
+import org.mockito.Mockito;
 
 /**
  *
@@ -49,8 +57,18 @@ public class PageMemoryImplNoLoadTest extends PageMemoryNoLoadSelfTest {
 
         DirectMemoryProvider provider = new MappedFileMemoryProvider(log(), memDir);
 
+        IgniteConfiguration cfg = new IgniteConfiguration();
+
+        cfg.setEncryptionSpi(new NoopEncryptionSpi());
+
+        GridTestKernalContext cctx = new GridTestKernalContext(log, cfg);
+
+        cctx.add(new IgnitePluginProcessor(cctx, cfg, Collections.emptyList()));
+        cctx.add(new GridInternalSubscriptionProcessor(cctx));
+        cctx.add(new GridEncryptionManager(cctx));
+
         GridCacheSharedContext<Object, Object> sharedCtx = new GridCacheSharedContext<>(
-            new GridTestKernalContext(log),
+            cctx,
             null,
             null,
             null,
@@ -88,7 +106,7 @@ public class PageMemoryImplNoLoadTest extends PageMemoryNoLoadSelfTest {
             },
             new DataRegionMetricsImpl(new DataRegionConfiguration()),
             PageMemoryImpl.ThrottlingPolicy.DISABLED,
-            null
+            Mockito.mock(CheckpointWriteProgressSupplier.class)
         );
     }
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/aabacfa0/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/pagemem/PageMemoryImplTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/pagemem/PageMemoryImplTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/pagemem/PageMemoryImplTest.java
index 000131a..fe79105 100644
--- a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/pagemem/PageMemoryImplTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/pagemem/PageMemoryImplTest.java
@@ -30,6 +30,7 @@ import org.apache.ignite.configuration.DataStorageConfiguration;
 import org.apache.ignite.configuration.IgniteConfiguration;
 import org.apache.ignite.failure.NoOpFailureHandler;
 import org.apache.ignite.internal.IgniteFutureTimeoutCheckedException;
+import org.apache.ignite.internal.managers.encryption.GridEncryptionManager;
 import org.apache.ignite.internal.mem.DirectMemoryProvider;
 import org.apache.ignite.internal.mem.IgniteOutOfMemoryException;
 import org.apache.ignite.internal.mem.unsafe.UnsafeMemoryProvider;
@@ -44,8 +45,10 @@ import org.apache.ignite.internal.processors.cache.persistence.IgniteCacheDataba
 import org.apache.ignite.internal.processors.cache.persistence.tree.io.PageIO;
 import org.apache.ignite.internal.processors.failure.FailureProcessor;
 import org.apache.ignite.internal.processors.plugin.IgnitePluginProcessor;
+import org.apache.ignite.internal.processors.subscription.GridInternalSubscriptionProcessor;
 import org.apache.ignite.internal.util.lang.GridInClosure3X;
 import org.apache.ignite.plugin.PluginProvider;
+import org.apache.ignite.spi.encryption.noop.NoopEncryptionSpi;
 import org.apache.ignite.testframework.GridTestUtils;
 import org.apache.ignite.testframework.junits.GridTestKernalContext;
 import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
@@ -271,9 +274,13 @@ public class PageMemoryImplTest extends GridCommonAbstractTest {
         IgniteConfiguration igniteCfg = new IgniteConfiguration();
         igniteCfg.setDataStorageConfiguration(new DataStorageConfiguration());
         igniteCfg.setFailureHandler(new NoOpFailureHandler());
+        igniteCfg.setEncryptionSpi(new NoopEncryptionSpi());
 
         GridTestKernalContext kernalCtx = new GridTestKernalContext(new GridTestLog4jLogger(), igniteCfg);
+
         kernalCtx.add(new IgnitePluginProcessor(kernalCtx, igniteCfg, Collections.<PluginProvider>emptyList()));
+        kernalCtx.add(new GridInternalSubscriptionProcessor(kernalCtx));
+        kernalCtx.add(new GridEncryptionManager(kernalCtx));
 
         FailureProcessor failureProc = new FailureProcessor(kernalCtx);
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/aabacfa0/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/wal/memtracker/PageMemoryTracker.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/wal/memtracker/PageMemoryTracker.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/wal/memtracker/PageMemoryTracker.java
index 661b6c7..09cacfb 100644
--- a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/wal/memtracker/PageMemoryTracker.java
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/wal/memtracker/PageMemoryTracker.java
@@ -32,6 +32,7 @@ import java.util.concurrent.locks.ReentrantLock;
 import org.apache.ignite.IgniteCheckedException;
 import org.apache.ignite.IgniteLogger;
 import org.apache.ignite.configuration.WALMode;
+import org.apache.ignite.spi.encryption.EncryptionSpi;
 import org.apache.ignite.internal.GridKernalContext;
 import org.apache.ignite.internal.IgniteEx;
 import org.apache.ignite.internal.mem.DirectMemoryProvider;
@@ -222,9 +223,21 @@ public class PageMemoryTracker implements IgnitePlugin {
 
         pageSize = ctx.igniteConfiguration().getDataStorageConfiguration().getPageSize();
 
+        EncryptionSpi encSpi = ctx.igniteConfiguration().getEncryptionSpi();
+
         pageMemoryMock = Mockito.mock(PageMemory.class);
 
         Mockito.doReturn(pageSize).when(pageMemoryMock).pageSize();
+        Mockito.when(pageMemoryMock.realPageSize(Mockito.anyInt())).then(mock -> {
+            int grpId = (Integer) mock.getArguments()[0];
+
+            if (gridCtx.encryption().groupKey(grpId) == null)
+                return pageSize;
+
+            return pageSize
+                - (encSpi.encryptedSizeNoPadding(pageSize) - pageSize)
+                - encSpi.blockSize() /* For CRC. */;
+        });
 
         GridCacheSharedContext sharedCtx = gridCtx.cache().context();