http://git-wip-us.apache.org/repos/asf/ignite/blob/a64b941d/modules/zookeeper/src/test/java/org/apache/ZookeeperNodeStart.java ---------------------------------------------------------------------- diff --git a/modules/zookeeper/src/test/java/org/apache/ZookeeperNodeStart.java b/modules/zookeeper/src/test/java/org/apache/ZookeeperNodeStart.java new file mode 100644 index 0000000..ef4d5f4 --- /dev/null +++ b/modules/zookeeper/src/test/java/org/apache/ZookeeperNodeStart.java @@ -0,0 +1,46 @@ +/* + * 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; + +import org.apache.ignite.Ignition; +import org.apache.ignite.configuration.IgniteConfiguration; +import org.apache.ignite.spi.discovery.zk.ZookeeperDiscoverySpi; + +/** + * + */ +public class ZookeeperNodeStart { + public static void main(String[] args) throws Exception { + try { + IgniteConfiguration cfg = new IgniteConfiguration(); + + ZookeeperDiscoverySpi spi = new ZookeeperDiscoverySpi(); + + spi.setZkConnectionString("localhost:2181"); + + cfg.setDiscoverySpi(spi); + + Ignition.start(cfg); + } + catch (Throwable e) { + e.printStackTrace(System.out); + + System.exit(1); + } + } +}
http://git-wip-us.apache.org/repos/asf/ignite/blob/a64b941d/modules/zookeeper/src/test/java/org/apache/ignite/spi/discovery/zk/IgniteCacheEntryListenerWithZkDiscoAtomicTest.java ---------------------------------------------------------------------- diff --git a/modules/zookeeper/src/test/java/org/apache/ignite/spi/discovery/zk/IgniteCacheEntryListenerWithZkDiscoAtomicTest.java b/modules/zookeeper/src/test/java/org/apache/ignite/spi/discovery/zk/IgniteCacheEntryListenerWithZkDiscoAtomicTest.java new file mode 100644 index 0000000..754a6bf --- /dev/null +++ b/modules/zookeeper/src/test/java/org/apache/ignite/spi/discovery/zk/IgniteCacheEntryListenerWithZkDiscoAtomicTest.java @@ -0,0 +1,32 @@ +/* + * 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.discovery.zk; + +import org.apache.ignite.internal.processors.cache.IgniteCacheEntryListenerAtomicTest; + +/** + * Class is added to mute {@link #testConcurrentRegisterDeregister} test in ZooKeeper suite + * (see related ticket). + * + * When slow down is tracked down and fixed this class can be replaced back with its parent. + */ +public class IgniteCacheEntryListenerWithZkDiscoAtomicTest extends IgniteCacheEntryListenerAtomicTest { + /** {@inheritDoc} */ + @Override public void testConcurrentRegisterDeregister() throws Exception { + fail("https://issues.apache.org/jira/browse/IGNITE-8109"); + } +} http://git-wip-us.apache.org/repos/asf/ignite/blob/a64b941d/modules/zookeeper/src/test/java/org/apache/ignite/spi/discovery/zk/ZookeeperDiscoverySpiAbstractTestSuite.java ---------------------------------------------------------------------- diff --git a/modules/zookeeper/src/test/java/org/apache/ignite/spi/discovery/zk/ZookeeperDiscoverySpiAbstractTestSuite.java b/modules/zookeeper/src/test/java/org/apache/ignite/spi/discovery/zk/ZookeeperDiscoverySpiAbstractTestSuite.java new file mode 100644 index 0000000..766635c --- /dev/null +++ b/modules/zookeeper/src/test/java/org/apache/ignite/spi/discovery/zk/ZookeeperDiscoverySpiAbstractTestSuite.java @@ -0,0 +1,118 @@ +/* + * 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.discovery.zk; + +import java.io.File; +import java.util.ArrayList; +import java.util.List; +import junit.framework.TestSuite; +import org.apache.curator.test.InstanceSpec; +import org.apache.curator.test.TestingCluster; +import org.apache.ignite.IgniteException; +import org.apache.ignite.configuration.IgniteConfiguration; +import org.apache.ignite.spi.discovery.DiscoverySpi; +import org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi; +import org.apache.ignite.testframework.config.GridTestProperties; + +/** + * Allows to run regular Ignite tests with {@link org.apache.ignite.spi.discovery.zk.ZookeeperDiscoverySpi}. + */ +public abstract class ZookeeperDiscoverySpiAbstractTestSuite extends TestSuite { + /** */ + private static TestingCluster testingCluster; + + /** + * @throws Exception If failed. + */ + public static void initSuite() throws Exception { + System.setProperty("zookeeper.forceSync", "false"); + + testingCluster = createTestingCluster(3); + + testingCluster.start(); + + System.setProperty(GridTestProperties.IGNITE_CFG_PREPROCESSOR_CLS, ZookeeperDiscoverySpiAbstractTestSuite.class.getName()); + } + + /** + * Called via reflection by {@link org.apache.ignite.testframework.junits.GridAbstractTest}. + * + * @param cfg Configuration to change. + */ + public synchronized static void preprocessConfiguration(IgniteConfiguration cfg) { + if (testingCluster == null) + throw new IllegalStateException("Test Zookeeper cluster is not started."); + + ZookeeperDiscoverySpi zkSpi = new ZookeeperDiscoverySpi(); + + DiscoverySpi spi = cfg.getDiscoverySpi(); + + if (spi instanceof TcpDiscoverySpi) + zkSpi.setClientReconnectDisabled(((TcpDiscoverySpi)spi).isClientReconnectDisabled()); + + zkSpi.setSessionTimeout(30_000); + zkSpi.setZkConnectionString(testingCluster.getConnectString()); + + cfg.setDiscoverySpi(zkSpi); + } + + /** + * @param instances Number of instances in + * @return Test cluster. + */ + public static TestingCluster createTestingCluster(int instances) { + String tmpDir = System.getProperty("java.io.tmpdir"); + + List<InstanceSpec> specs = new ArrayList<>(); + + for (int i = 0; i < instances; i++) { + File file = new File(tmpDir, "apacheIgniteTestZk-" + i); + + if (file.isDirectory()) + deleteRecursively0(file); + else { + if (!file.mkdirs()) + throw new IgniteException("Failed to create directory for test Zookeeper server: " + file.getAbsolutePath()); + } + + specs.add(new InstanceSpec(file, -1, -1, -1, true, -1, -1, 500)); + } + + return new TestingCluster(specs); + } + + /** + * @param file File or directory to delete. + */ + private static void deleteRecursively0(File file) { + File[] files = file.listFiles(); + + if (files == null) + return; + + for (File f : files) { + if (f.isDirectory()) + deleteRecursively0(f); + else { + if (!f.delete()) + throw new IgniteException("Failed to delete file: " + f.getAbsolutePath()); + } + } + } + +} http://git-wip-us.apache.org/repos/asf/ignite/blob/a64b941d/modules/zookeeper/src/test/java/org/apache/ignite/spi/discovery/zk/ZookeeperDiscoverySpiTestSuite1.java ---------------------------------------------------------------------- diff --git a/modules/zookeeper/src/test/java/org/apache/ignite/spi/discovery/zk/ZookeeperDiscoverySpiTestSuite1.java b/modules/zookeeper/src/test/java/org/apache/ignite/spi/discovery/zk/ZookeeperDiscoverySpiTestSuite1.java new file mode 100644 index 0000000..860488b --- /dev/null +++ b/modules/zookeeper/src/test/java/org/apache/ignite/spi/discovery/zk/ZookeeperDiscoverySpiTestSuite1.java @@ -0,0 +1,44 @@ +/* + * 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.discovery.zk; + +import junit.framework.TestSuite; +import org.apache.ignite.spi.discovery.zk.internal.ZookeeperClientTest; +import org.apache.ignite.spi.discovery.zk.internal.ZookeeperDiscoverySpiSaslSuccessfulAuthTest; +import org.apache.ignite.spi.discovery.zk.internal.ZookeeperDiscoverySpiTest; + +/** + * + */ +public class ZookeeperDiscoverySpiTestSuite1 extends TestSuite { + /** + * @return Test suite. + * @throws Exception Thrown in case of the failure. + */ + public static TestSuite suite() throws Exception { + System.setProperty("zookeeper.forceSync", "false"); + + TestSuite suite = new TestSuite("ZookeeperDiscoverySpi Test Suite"); + + suite.addTestSuite(ZookeeperClientTest.class); + suite.addTestSuite(ZookeeperDiscoverySpiTest.class); + suite.addTestSuite(ZookeeperDiscoverySpiSaslSuccessfulAuthTest.class); + + return suite; + } +} http://git-wip-us.apache.org/repos/asf/ignite/blob/a64b941d/modules/zookeeper/src/test/java/org/apache/ignite/spi/discovery/zk/ZookeeperDiscoverySpiTestSuite2.java ---------------------------------------------------------------------- diff --git a/modules/zookeeper/src/test/java/org/apache/ignite/spi/discovery/zk/ZookeeperDiscoverySpiTestSuite2.java b/modules/zookeeper/src/test/java/org/apache/ignite/spi/discovery/zk/ZookeeperDiscoverySpiTestSuite2.java new file mode 100644 index 0000000..3775aa1 --- /dev/null +++ b/modules/zookeeper/src/test/java/org/apache/ignite/spi/discovery/zk/ZookeeperDiscoverySpiTestSuite2.java @@ -0,0 +1,94 @@ +/* + * 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.discovery.zk; + +import junit.framework.TestSuite; +import org.apache.curator.test.TestingCluster; +import org.apache.ignite.internal.ClusterNodeMetricsUpdateTest; +import org.apache.ignite.internal.IgniteClientReconnectCacheTest; +import org.apache.ignite.internal.processors.cache.IgniteCacheEntryListenerAtomicTest; +import org.apache.ignite.internal.processors.cache.datastructures.IgniteClientDataStructuresTest; +import org.apache.ignite.internal.processors.cache.datastructures.partitioned.GridCachePartitionedNodeRestartTxSelfTest; +import org.apache.ignite.internal.processors.cache.datastructures.partitioned.GridCachePartitionedSequenceApiSelfTest; +import org.apache.ignite.internal.processors.cache.datastructures.replicated.GridCacheReplicatedSequenceApiSelfTest; +import org.apache.ignite.internal.processors.cache.distributed.dht.IgniteCachePutRetryAtomicSelfTest; +import org.apache.ignite.internal.processors.cache.distributed.dht.IgniteCachePutRetryTransactionalSelfTest; +import org.apache.ignite.internal.processors.cache.distributed.near.GridCacheAtomicMultiNodeFullApiSelfTest; +import org.apache.ignite.internal.processors.cache.distributed.near.GridCachePartitionedMultiNodeFullApiSelfTest; +import org.apache.ignite.internal.processors.cache.distributed.near.GridCachePartitionedNodeRestartTest; +import org.apache.ignite.internal.processors.cache.distributed.replicated.GridCacheReplicatedAtomicMultiNodeFullApiSelfTest; +import org.apache.ignite.internal.processors.cache.distributed.replicated.GridCacheReplicatedMultiNodeFullApiSelfTest; +import org.apache.ignite.internal.processors.cache.distributed.replicated.GridCacheReplicatedNodeRestartSelfTest; +import org.apache.ignite.internal.processors.cache.distributed.replicated.IgniteCacheReplicatedQuerySelfTest; +import org.apache.ignite.internal.processors.cache.multijvm.GridCacheAtomicMultiJvmFullApiSelfTest; +import org.apache.ignite.internal.processors.cache.multijvm.GridCachePartitionedMultiJvmFullApiSelfTest; +import org.apache.ignite.internal.processors.continuous.GridEventConsumeSelfTest; + +/** + * Regular Ignite tests executed with {@link org.apache.ignite.spi.discovery.zk.ZookeeperDiscoverySpi}. + */ +public class ZookeeperDiscoverySpiTestSuite2 extends ZookeeperDiscoverySpiAbstractTestSuite { + /** */ + private static TestingCluster testingCluster; + + /** + * @return Test suite. + * @throws Exception Thrown in case of the failure. + */ + public static TestSuite suite() throws Exception { + System.setProperty("H2_JDBC_CONNECTIONS", "500"); // For multi-jvm tests. + + initSuite(); + + TestSuite suite = new TestSuite("ZookeeperDiscoverySpi Test Suite"); + + suite.addTestSuite(ZookeeperDiscoverySuitePreprocessorTest.class); + + suite.addTestSuite(GridCacheReplicatedNodeRestartSelfTest.class); + suite.addTestSuite(GridCachePartitionedNodeRestartTest.class); + + suite.addTestSuite(IgniteCacheEntryListenerWithZkDiscoAtomicTest.class); + + suite.addTestSuite(GridEventConsumeSelfTest.class); + + suite.addTestSuite(IgniteClientReconnectCacheTest.class); + + suite.addTestSuite(IgniteCachePutRetryAtomicSelfTest.class); + suite.addTestSuite(IgniteCachePutRetryTransactionalSelfTest.class); + + suite.addTestSuite(ClusterNodeMetricsUpdateTest.class); + + suite.addTestSuite(GridCachePartitionedMultiNodeFullApiSelfTest.class); + suite.addTestSuite(GridCacheReplicatedMultiNodeFullApiSelfTest.class); + + suite.addTestSuite(GridCacheAtomicMultiNodeFullApiSelfTest.class); + suite.addTestSuite(GridCacheReplicatedAtomicMultiNodeFullApiSelfTest.class); + + suite.addTestSuite(GridCachePartitionedNodeRestartTxSelfTest.class); + suite.addTestSuite(IgniteClientDataStructuresTest.class); + suite.addTestSuite(GridCacheReplicatedSequenceApiSelfTest.class); + suite.addTestSuite(GridCachePartitionedSequenceApiSelfTest.class); + + suite.addTestSuite(IgniteCacheReplicatedQuerySelfTest.class); + + suite.addTestSuite(GridCacheAtomicMultiJvmFullApiSelfTest.class); + suite.addTestSuite(GridCachePartitionedMultiJvmFullApiSelfTest.class); + + return suite; + } +} http://git-wip-us.apache.org/repos/asf/ignite/blob/a64b941d/modules/zookeeper/src/test/java/org/apache/ignite/spi/discovery/zk/ZookeeperDiscoverySuitePreprocessorTest.java ---------------------------------------------------------------------- diff --git a/modules/zookeeper/src/test/java/org/apache/ignite/spi/discovery/zk/ZookeeperDiscoverySuitePreprocessorTest.java b/modules/zookeeper/src/test/java/org/apache/ignite/spi/discovery/zk/ZookeeperDiscoverySuitePreprocessorTest.java new file mode 100644 index 0000000..28cf17f --- /dev/null +++ b/modules/zookeeper/src/test/java/org/apache/ignite/spi/discovery/zk/ZookeeperDiscoverySuitePreprocessorTest.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.discovery.zk; + +import java.util.List; +import org.apache.ignite.Ignite; +import org.apache.ignite.configuration.IgniteConfiguration; +import org.apache.ignite.internal.util.typedef.G; +import org.apache.ignite.spi.discovery.DiscoverySpi; +import org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi; +import org.apache.ignite.spi.discovery.tcp.ipfinder.TcpDiscoveryIpFinder; +import org.apache.ignite.spi.discovery.tcp.ipfinder.vm.TcpDiscoveryVmIpFinder; +import org.apache.ignite.testframework.config.GridTestProperties; +import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest; + +/** + * Sanity test verifying that configuration callback specified via + * {@link GridTestProperties#IGNITE_CFG_PREPROCESSOR_CLS} really works. + * <p> + * This test should be run as part of {@link ZookeeperDiscoverySpiTestSuite2}. + */ +public class ZookeeperDiscoverySuitePreprocessorTest extends GridCommonAbstractTest { + /** */ + private static final TcpDiscoveryIpFinder IP_FINDER = new TcpDiscoveryVmIpFinder(true); + + /** {@inheritDoc} */ + @Override protected IgniteConfiguration getConfiguration(String igniteInstanceName) throws Exception { + IgniteConfiguration cfg = super.getConfiguration(igniteInstanceName); + + // Test sets TcpDiscoverySpi, but it should be automatically changed to ZookeeperDiscoverySpi. + TcpDiscoverySpi spi = new TcpDiscoverySpi(); + + spi.setIpFinder(IP_FINDER); + + cfg.setDiscoverySpi(spi); + + return cfg; + } + + /** {@inheritDoc} */ + @Override protected void afterTest() throws Exception { + stopAllGrids(); + + super.afterTest(); + } + + /** + * @throws Exception If failed. + */ + public void testSpiConfigurationIsChanged() throws Exception { + startGrid(0); + + checkDiscoverySpi(1); + + startGrid(1); + + checkDiscoverySpi(2); + + startGridsMultiThreaded(2, 2); + + checkDiscoverySpi(4); + + startGrid(); + + checkDiscoverySpi(5); + } + + /** + * @param expNodes Expected nodes number. + * @throws Exception If failed. + */ + private void checkDiscoverySpi(int expNodes) throws Exception { + List<Ignite> nodes = G.allGrids(); + + assertEquals(expNodes, nodes.size()); + + for (Ignite node : nodes) { + DiscoverySpi spi = node.configuration().getDiscoverySpi(); + + assertTrue("Node should be started with " + ZookeeperDiscoverySpi.class.getName(), + spi instanceof ZookeeperDiscoverySpi); + } + + waitForTopology(expNodes); + } +} http://git-wip-us.apache.org/repos/asf/ignite/blob/a64b941d/modules/zookeeper/src/test/java/org/apache/ignite/spi/discovery/zk/internal/ZookeeperClientTest.java ---------------------------------------------------------------------- diff --git a/modules/zookeeper/src/test/java/org/apache/ignite/spi/discovery/zk/internal/ZookeeperClientTest.java b/modules/zookeeper/src/test/java/org/apache/ignite/spi/discovery/zk/internal/ZookeeperClientTest.java new file mode 100644 index 0000000..e7cb97a --- /dev/null +++ b/modules/zookeeper/src/test/java/org/apache/ignite/spi/discovery/zk/internal/ZookeeperClientTest.java @@ -0,0 +1,495 @@ +/* + * 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.discovery.zk.internal; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.concurrent.Callable; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.ThreadLocalRandom; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicBoolean; +import org.apache.curator.test.TestingCluster; +import org.apache.ignite.internal.IgniteInternalFuture; +import org.apache.ignite.internal.util.future.GridFutureAdapter; +import org.apache.ignite.internal.util.typedef.internal.U; +import org.apache.ignite.lang.IgniteRunnable; +import org.apache.ignite.testframework.GridTestUtils; +import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest; +import org.apache.zookeeper.AsyncCallback; +import org.apache.zookeeper.CreateMode; +import org.apache.zookeeper.ZooDefs; +import org.apache.zookeeper.ZooKeeper; +import org.apache.zookeeper.data.Stat; + +/** + * + */ +public class ZookeeperClientTest extends GridCommonAbstractTest { + /** */ + private static final int SES_TIMEOUT = 60_000; + + /** */ + private TestingCluster zkCluster; + + /** {@inheritDoc} */ + @Override protected void afterTest() throws Exception { + closeZK(); + + super.afterTest(); + } + + /** + * @param sesTimeout Session timeout. + * @return Client. + * @throws Exception If failed. + */ + private ZookeeperClient createClient(int sesTimeout) throws Exception { + return new ZookeeperClient(log, zkCluster.getConnectString(), sesTimeout, null); + } + + /** + * @throws Exception If failed. + */ + public void testSaveLargeValue() throws Exception { + startZK(1); + + final ZookeeperClient client = createClient(SES_TIMEOUT); + + byte[] data = new byte[1024 * 1024]; + + String basePath = "/ignite"; + + assertTrue(client.needSplitNodeData(basePath, data, 2)); + + List<byte[]> parts = client.splitNodeData(basePath, data, 2); + + assertTrue(parts.size() > 1); + + ZooKeeper zk = client.zk(); + + for (int i = 0; i < parts.size(); i++) { + byte[] part = parts.get(i); + + assertTrue(part.length > 0); + + String path0 = basePath + ":" + i; + + zk.create(path0, part, ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT); + } + } + + /** + * @throws Exception If failed. + */ + public void testClose() throws Exception { + startZK(1); + + final ZookeeperClient client = createClient(SES_TIMEOUT); + + client.createIfNeeded("/apacheIgnite1", null, CreateMode.PERSISTENT); + + client.zk().close(); + + GridTestUtils.assertThrows(log, new Callable<Void>() { + @Override public Void call() throws Exception { + client.createIfNeeded("/apacheIgnite2", null, CreateMode.PERSISTENT); + + return null; + } + }, ZookeeperClientFailedException.class, null); + } + + /** + * @throws Exception If failed. + */ + public void testCreateAll() throws Exception { + startZK(1); + + ZookeeperClient client = createClient(SES_TIMEOUT); + + client.createIfNeeded("/apacheIgnite", null, CreateMode.PERSISTENT); + + List<String> paths = new ArrayList<>(); + + paths.add("/apacheIgnite/1"); + paths.add("/apacheIgnite/2"); + paths.add("/apacheIgnite/3"); + + client.createAll(paths, CreateMode.PERSISTENT); + + assertEquals(3, client.getChildren("/apacheIgnite").size()); + } + + /** + * @throws Exception If failed. + */ + public void testDeleteAll() throws Exception { + startZK(1); + + ZookeeperClient client = createClient(SES_TIMEOUT); + + client.createIfNeeded("/apacheIgnite", null, CreateMode.PERSISTENT); + client.createIfNeeded("/apacheIgnite/1", null, CreateMode.PERSISTENT); + client.createIfNeeded("/apacheIgnite/2", null, CreateMode.PERSISTENT); + + client.deleteAll("/apacheIgnite", Arrays.asList("1", "2"), -1); + + assertTrue(client.getChildren("/apacheIgnite").isEmpty()); + + client.createIfNeeded("/apacheIgnite/1", null, CreateMode.PERSISTENT); + client.deleteAll("/apacheIgnite", Collections.singletonList("1"), -1); + + assertTrue(client.getChildren("/apacheIgnite").isEmpty()); + } + + /** + * @throws Exception If failed. + */ + public void testConnectionLoss1() throws Exception { + ZookeeperClient client = new ZookeeperClient(log, "localhost:2200", 3000, null); + + try { + client.createIfNeeded("/apacheIgnite", null, CreateMode.PERSISTENT); + + fail(); + } + catch (ZookeeperClientFailedException e) { + info("Expected error: " + e); + } + } + + /** + * @throws Exception If failed. + */ + public void testConnectionLoss2() throws Exception { + startZK(1); + + ZookeeperClient client = createClient(3000); + + client.createIfNeeded("/apacheIgnite1", null, CreateMode.PERSISTENT); + + closeZK(); + + try { + client.createIfNeeded("/apacheIgnite2", null, CreateMode.PERSISTENT); + + fail(); + } + catch (ZookeeperClientFailedException e) { + info("Expected error: " + e); + } + } + + /** + * @throws Exception If failed. + */ + public void testConnectionLoss3() throws Exception { + startZK(1); + + CallbackFuture cb = new CallbackFuture(); + + ZookeeperClient client = new ZookeeperClient(log, zkCluster.getConnectString(), 3000, cb); + + client.createIfNeeded("/apacheIgnite1", null, CreateMode.PERSISTENT); + + closeZK(); + + final AtomicBoolean res = new AtomicBoolean(); + + client.getChildrenAsync("/apacheIgnite1", null, new AsyncCallback.Children2Callback() { + @Override public void processResult(int rc, String path, Object ctx, List<String> children, Stat stat) { + if (rc == 0) + res.set(true); + } + }); + + cb.get(60_000); + + assertFalse(res.get()); + } + + /** + * @throws Exception If failed. + */ + public void testConnectionLoss4() throws Exception { + startZK(1); + + CallbackFuture cb = new CallbackFuture(); + + final ZookeeperClient client = new ZookeeperClient(log, zkCluster.getConnectString(), 3000, cb); + + client.createIfNeeded("/apacheIgnite1", null, CreateMode.PERSISTENT); + + final CountDownLatch l = new CountDownLatch(1); + + client.getChildrenAsync("/apacheIgnite1", null, new AsyncCallback.Children2Callback() { + @Override public void processResult(int rc, String path, Object ctx, List<String> children, Stat stat) { + closeZK(); + + try { + client.createIfNeeded("/apacheIgnite2", null, CreateMode.PERSISTENT); + } + catch (ZookeeperClientFailedException e) { + info("Expected error: " + e); + + l.countDown(); + } + catch (Exception e) { + fail("Unexpected error: " + e); + } + } + }); + + assertTrue(l.await(10, TimeUnit.SECONDS)); + + cb.get(); + } + + /** + * @throws Exception If failed. + */ + public void testReconnect1() throws Exception { + startZK(1); + + ZookeeperClient client = createClient(SES_TIMEOUT); + + client.createIfNeeded("/apacheIgnite1", null, CreateMode.PERSISTENT); + + zkCluster.getServers().get(0).stop(); + + IgniteInternalFuture fut = GridTestUtils.runAsync(new Callable<Void>() { + @Override public Void call() throws Exception { + U.sleep(2000); + + info("Restart zookeeper server"); + + zkCluster.getServers().get(0).restart(); + + info("Zookeeper server restarted"); + + return null; + } + }, "start-zk"); + + client.createIfNeeded("/apacheIgnite2", null, CreateMode.PERSISTENT); + + fut.get(); + } + + /** + * @throws Exception If failed. + */ + public void testReconnect1_Callback() throws Exception { + startZK(1); + + ZookeeperClient client = createClient(SES_TIMEOUT); + + client.createIfNeeded("/apacheIgnite1", null, CreateMode.PERSISTENT); + + zkCluster.getServers().get(0).stop(); + + final CountDownLatch l = new CountDownLatch(1); + + client.getChildrenAsync("/apacheIgnite1", null, new AsyncCallback.Children2Callback() { + @Override public void processResult(int rc, String path, Object ctx, List<String> children, Stat stat) { + info("Callback: " + rc); + + if (rc == 0) + l.countDown(); + } + }); + + IgniteInternalFuture fut = GridTestUtils.runAsync(new Callable<Void>() { + @Override public Void call() throws Exception { + U.sleep(2000); + + info("Restart zookeeper server"); + + zkCluster.getServers().get(0).restart(); + + info("Zookeeper server restarted"); + + return null; + } + }, "start-zk"); + + assertTrue(l.await(10, TimeUnit.SECONDS)); + + fut.get(); + } + + /** + * @throws Exception If failed. + */ + public void testReconnect1_InCallback() throws Exception { + startZK(1); + + final ZookeeperClient client = createClient(SES_TIMEOUT); + + client.createIfNeeded("/apacheIgnite1", null, CreateMode.PERSISTENT); + + final CountDownLatch l = new CountDownLatch(1); + + client.getChildrenAsync("/apacheIgnite1", null, new AsyncCallback.Children2Callback() { + @Override public void processResult(int rc, String path, Object ctx, List<String> children, Stat stat) { + try { + zkCluster.getServers().get(0).stop(); + + IgniteInternalFuture fut = GridTestUtils.runAsync(new Callable<Void>() { + @Override public Void call() throws Exception { + U.sleep(2000); + + info("Restart zookeeper server"); + + zkCluster.getServers().get(0).restart(); + + info("Zookeeper server restarted"); + + return null; + } + }, "start-zk"); + + client.createIfNeeded("/apacheIgnite2", null, CreateMode.PERSISTENT); + + l.countDown(); + + fut.get(); + } + catch (Exception e) { + fail("Unexpected error: " + e); + } + } + }); + + assertTrue(l.await(10, TimeUnit.SECONDS)); + } + + /** + * @throws Exception If failed. + */ + public void testReconnect2() throws Exception { + startZK(1); + + ZookeeperClient client = createClient(SES_TIMEOUT); + + client.createIfNeeded("/apacheIgnite1", null, CreateMode.PERSISTENT); + + zkCluster.getServers().get(0).restart(); + + client.createIfNeeded("/apacheIgnite2", null, CreateMode.PERSISTENT); + } + + /** + * @throws Exception If failed. + */ + public void testReconnect3() throws Exception { + startZK(3); + + ZookeeperClient client = createClient(SES_TIMEOUT); + + ThreadLocalRandom rnd = ThreadLocalRandom.current(); + + for (int i = 0; i < 30; i++) { + info("Iteration: " + i); + + int idx = rnd.nextInt(3); + + zkCluster.getServers().get(idx).restart(); + + doSleep(rnd.nextLong(100) + 1); + + client.createIfNeeded("/apacheIgnite" + i, null, CreateMode.PERSISTENT); + } + } + + /** + * @throws Exception If failed. + */ + public void testReconnect4() throws Exception { + startZK(3); + + ZookeeperClient client = new ZookeeperClient(log, + zkCluster.getServers().get(2).getInstanceSpec().getConnectString(), + 60_000, + null); + + client.createIfNeeded("/apacheIgnite1", null, CreateMode.PERSISTENT); + + zkCluster.getServers().get(0).stop(); + zkCluster.getServers().get(1).stop(); + + IgniteInternalFuture fut = GridTestUtils.runAsync(new Callable<Void>() { + @Override public Void call() throws Exception { + U.sleep(2000); + + info("Restart zookeeper server"); + + zkCluster.getServers().get(0).restart(); + + info("Zookeeper server restarted"); + + return null; + } + }, "start-zk"); + + client.createIfNeeded("/apacheIgnite2", null, CreateMode.PERSISTENT); + + fut.get(); + } + + /** + * @param instances Number of servers in ZK ensemble. + * @throws Exception If failed. + */ + private void startZK(int instances) throws Exception { + assert zkCluster == null; + + zkCluster = new TestingCluster(instances); + + zkCluster.start(); + } + + /** + * + */ + private void closeZK() { + if (zkCluster != null) { + try { + zkCluster.close(); + } + catch (Exception e) { + U.error(log, "Failed to stop Zookeeper client: " + e, e); + } + + zkCluster = null; + } + } + + /** + * + */ + private static class CallbackFuture extends GridFutureAdapter<Void> implements IgniteRunnable { + /** {@inheritDoc} */ + @Override public void run() { + onDone(); + } + } +} http://git-wip-us.apache.org/repos/asf/ignite/blob/a64b941d/modules/zookeeper/src/test/java/org/apache/ignite/spi/discovery/zk/internal/ZookeeperDiscoverySpiSaslAuthAbstractTest.java ---------------------------------------------------------------------- diff --git a/modules/zookeeper/src/test/java/org/apache/ignite/spi/discovery/zk/internal/ZookeeperDiscoverySpiSaslAuthAbstractTest.java b/modules/zookeeper/src/test/java/org/apache/ignite/spi/discovery/zk/internal/ZookeeperDiscoverySpiSaslAuthAbstractTest.java new file mode 100644 index 0000000..ac94bf2 --- /dev/null +++ b/modules/zookeeper/src/test/java/org/apache/ignite/spi/discovery/zk/internal/ZookeeperDiscoverySpiSaslAuthAbstractTest.java @@ -0,0 +1,247 @@ +/* + * 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.discovery.zk.internal; + +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; +import java.nio.file.Paths; +import org.apache.ignite.IgniteCheckedException; +import org.apache.ignite.configuration.IgniteConfiguration; +import org.apache.ignite.internal.util.typedef.internal.U; +import org.apache.ignite.spi.discovery.zk.ZookeeperDiscoverySpi; +import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest; +import org.apache.zookeeper.client.ZooKeeperSaslClient; +import org.apache.zookeeper.server.ServerCnxnFactory; +import org.apache.zookeeper.server.ZKDatabase; +import org.apache.zookeeper.server.ZooKeeperServer; + +import static org.apache.curator.test.DirectoryUtils.deleteRecursively; + +/** + * Implements methods to prepare SASL tests infrastructure: jaas.conf files, starting up ZooKeeper server, + * clean up procedures when the test has finished etc. + */ +public abstract class ZookeeperDiscoverySpiSaslAuthAbstractTest extends GridCommonAbstractTest { + /** */ + private File tmpDir = createTmpDir(); + + /** */ + private static final String JAAS_CONF_FILE = "jaas.conf"; + + /** */ + private static final String AUTH_PROVIDER = "zookeeper.authProvider.1"; + + /** */ + private static final String SASL_CONFIG = "java.security.auth.login.config"; + + /** */ + private long joinTimeout = 2_000; + + /** */ + private long sesTimeout = 10_000; + + /** */ + private ServerCnxnFactory serverFactory; + + /** */ + private String hostPort = "localhost:2181"; + + /** */ + private int maxCnxns; + + /** {@inheritDoc} */ + @Override protected IgniteConfiguration getConfiguration(String instanceName) throws Exception { + IgniteConfiguration cfg = super.getConfiguration(instanceName); + + ZookeeperDiscoverySpi zkSpi = new ZookeeperDiscoverySpi(); + + if (joinTimeout != 0) + zkSpi.setJoinTimeout(joinTimeout); + + zkSpi.setSessionTimeout(sesTimeout > 0 ? sesTimeout : 10_000); + + zkSpi.setZkConnectionString(hostPort); + + cfg.setDiscoverySpi(zkSpi); + + return cfg; + } + + /** {@inheritDoc} */ + @Override protected void beforeTest() throws Exception { + prepareJaasConfigFile(); + + prepareSaslSystemProperties(); + + startZooKeeperServer(); + } + + /** {@inheritDoc} */ + @Override protected void afterTest() throws Exception { + stopZooKeeperServer(); + + stopAllGrids(); + + clearSaslSystemProperties(); + + clearTmpDir(); + } + + /** */ + private void clearTmpDir() throws Exception { + deleteRecursively(tmpDir); + } + + /** */ + protected void clearSaslSystemProperties() { + System.clearProperty(AUTH_PROVIDER); + + System.clearProperty(SASL_CONFIG); + + System.clearProperty(ZooKeeperSaslClient.LOGIN_CONTEXT_NAME_KEY); + } + + /** + * @throws Exception If failed. + */ + private void prepareJaasConfigFile() throws Exception { + U.ensureDirectory(tmpDir, "Temp directory for JAAS configuration file wasn't created", null); + + File saslConfFile = new File(tmpDir, JAAS_CONF_FILE); + + FileWriter fwriter = new FileWriter(saslConfFile); + + writeServerConfigSection(fwriter, "validPassword"); + + writeClientConfigSection(fwriter, "ValidZookeeperClient", "validPassword"); + + writeClientConfigSection(fwriter, "InvalidZookeeperClient", "invalidPassword"); + + fwriter.close(); + } + + /** */ + private void prepareSaslSystemProperties() { + System.setProperty(SASL_CONFIG, Paths.get(tmpDir.getPath().toString(), JAAS_CONF_FILE).toString()); + + System.setProperty(AUTH_PROVIDER, "org.apache.zookeeper.server.auth.SASLAuthenticationProvider"); + } + + /** */ + private void writeClientConfigSection(FileWriter fwriter, String clientName, String pass) throws IOException { + fwriter.write(clientName + "{\n" + + " org.apache.zookeeper.server.auth.DigestLoginModule required\n" + + " username=\"zkUser\"\n" + + " password=\"" + pass + "\";\n" + + "};" + "\n"); + } + + /** */ + private void writeServerConfigSection(FileWriter fwriter, String pass) throws IOException { + fwriter.write("Server {\n" + + " org.apache.zookeeper.server.auth.DigestLoginModule required\n" + + " user_zkUser=\"" + pass + "\";\n" + + "};\n"); + } + + /** */ + private File createTmpDir() { + File jaasConfDir = Paths.get(System.getProperty("java.io.tmpdir"), "zk_disco_spi_test").toFile(); + + try { + U.ensureDirectory(jaasConfDir, "", null); + } + catch (IgniteCheckedException e) { + // ignored + } + + return jaasConfDir; + } + + /** */ + private void stopZooKeeperServer() throws Exception { + shutdownServerInstance(serverFactory); + serverFactory = null; + } + + /** */ + private void shutdownServerInstance(ServerCnxnFactory factory) + { + if (factory != null) { + ZKDatabase zkDb = null; + { + ZooKeeperServer zs = getServer(factory); + if (zs != null) + zkDb = zs.getZKDatabase(); + } + factory.shutdown(); + try { + if (zkDb != null) + zkDb.close(); + } catch (IOException ie) { + // ignore + } + } + } + + /** */ + private ZooKeeperServer getServer(ServerCnxnFactory fac) { + ZooKeeperServer zs = U.field(fac, "zkServer"); + + return zs; + } + + /** */ + private void startZooKeeperServer() throws Exception { + serverFactory = createNewServerInstance(serverFactory, hostPort, + maxCnxns); + startServerInstance(tmpDir, serverFactory); + } + + /** */ + private ServerCnxnFactory createNewServerInstance( + ServerCnxnFactory factory, String hostPort, int maxCnxns) + throws IOException { + final int port = getPort(hostPort); + + if (factory == null) + factory = ServerCnxnFactory.createFactory(port, maxCnxns); + + return factory; + } + + /** */ + private void startServerInstance(File dataDir, + ServerCnxnFactory factory) throws IOException, + InterruptedException { + ZooKeeperServer zks = new ZooKeeperServer(dataDir, dataDir, 3000); + factory.startup(zks); + } + + /** */ + private int getPort(String hostPort) { + String[] split = hostPort.split(":"); + String portstr = split[split.length-1]; + String[] pc = portstr.split("/"); + + if (pc.length > 1) + portstr = pc[0]; + + return Integer.parseInt(portstr); + } +} http://git-wip-us.apache.org/repos/asf/ignite/blob/a64b941d/modules/zookeeper/src/test/java/org/apache/ignite/spi/discovery/zk/internal/ZookeeperDiscoverySpiSaslFailedAuthTest.java ---------------------------------------------------------------------- diff --git a/modules/zookeeper/src/test/java/org/apache/ignite/spi/discovery/zk/internal/ZookeeperDiscoverySpiSaslFailedAuthTest.java b/modules/zookeeper/src/test/java/org/apache/ignite/spi/discovery/zk/internal/ZookeeperDiscoverySpiSaslFailedAuthTest.java new file mode 100644 index 0000000..864ac96 --- /dev/null +++ b/modules/zookeeper/src/test/java/org/apache/ignite/spi/discovery/zk/internal/ZookeeperDiscoverySpiSaslFailedAuthTest.java @@ -0,0 +1,44 @@ +/* + * 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.discovery.zk.internal; + +import org.apache.zookeeper.client.ZooKeeperSaslClient; +import org.junit.Assert; + +/** + * + */ +public class ZookeeperDiscoverySpiSaslFailedAuthTest extends ZookeeperDiscoverySpiSaslAuthAbstractTest { + /** + * @throws Exception If failed. + */ + public void testIgniteNodeWithInvalidPasswordFailsToJoin() throws Exception { + System.setProperty(ZooKeeperSaslClient.LOGIN_CONTEXT_NAME_KEY, + "InvalidZookeeperClient"); + + System.setProperty("IGNITE_ZOOKEEPER_DISCOVERY_MAX_RETRY_COUNT", Integer.toString(1)); + + try { + startGrid(0); + + Assert.fail("Ignite node with invalid password should fail on join."); + } + catch (Exception e) { + //ignored + } + } +} http://git-wip-us.apache.org/repos/asf/ignite/blob/a64b941d/modules/zookeeper/src/test/java/org/apache/ignite/spi/discovery/zk/internal/ZookeeperDiscoverySpiSaslSuccessfulAuthTest.java ---------------------------------------------------------------------- diff --git a/modules/zookeeper/src/test/java/org/apache/ignite/spi/discovery/zk/internal/ZookeeperDiscoverySpiSaslSuccessfulAuthTest.java b/modules/zookeeper/src/test/java/org/apache/ignite/spi/discovery/zk/internal/ZookeeperDiscoverySpiSaslSuccessfulAuthTest.java new file mode 100644 index 0000000..5ee0a43 --- /dev/null +++ b/modules/zookeeper/src/test/java/org/apache/ignite/spi/discovery/zk/internal/ZookeeperDiscoverySpiSaslSuccessfulAuthTest.java @@ -0,0 +1,48 @@ +/* + * 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.discovery.zk.internal; + +import org.apache.zookeeper.client.ZooKeeperSaslClient; + +/** + * + */ +public class ZookeeperDiscoverySpiSaslSuccessfulAuthTest extends ZookeeperDiscoverySpiSaslAuthAbstractTest { + /** + * @throws Exception If failed. + */ + public void testIgniteNodesWithValidPasswordSuccessfullyJoins() throws Exception { + System.setProperty(ZooKeeperSaslClient.LOGIN_CONTEXT_NAME_KEY, + "ValidZookeeperClient"); + + startGrids(3); + + waitForTopology(3); + } + + /** + * @throws Exception If failed. + */ + public void testIgniteNodeWithoutSaslConfigurationSuccessfullyJoins() throws Exception { + //clearing SASL-related system properties that were set in beforeTest + clearSaslSystemProperties(); + + startGrid(0); + + waitForTopology(1); + } +}