This is an automated email from the ASF dual-hosted git repository. agoncharuk pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/ignite.git
The following commit(s) were added to refs/heads/master by this push: new 0225509 IGNITE-11930 Fixed TcpDiscoverySpi to close bound server socket if discovery thread did not start - Fixes #6613. 0225509 is described below commit 022550916224c03a9e2dc2e888994c574432b5b5 Author: Alexey Goncharuk <alexey.goncha...@gmail.com> AuthorDate: Mon Jun 17 16:07:44 2019 +0300 IGNITE-11930 Fixed TcpDiscoverySpi to close bound server socket if discovery thread did not start - Fixes #6613. Signed-off-by: Alexey Goncharuk <alexey.goncha...@gmail.com> --- .../ignite/spi/discovery/tcp/ServerImpl.java | 24 +- .../IgniteClientCacheInitializationFailTest.java | 222 +-------------- .../processors/query/DummyQueryIndexing.java | 314 +++++++++++++++++++++ .../discovery/tcp/TcpDiscoveryFailedJoinTest.java | 55 ++++ 4 files changed, 383 insertions(+), 232 deletions(-) diff --git a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ServerImpl.java b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ServerImpl.java index 234f81a..bb2fec0 100644 --- a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ServerImpl.java +++ b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ServerImpl.java @@ -496,8 +496,8 @@ class ServerImpl extends TcpDiscoveryImpl { } } - U.cancel(tcpSrvr); - U.join(tcpSrvr, log); + if (tcpSrvr != null) + tcpSrvr.stop(); tcpSrvr = null; @@ -1747,8 +1747,11 @@ class ServerImpl extends TcpDiscoveryImpl { @Override void simulateNodeFailure() { U.warn(log, "Simulating node failure: " + getLocalNodeId()); - U.cancel(tcpSrvr); - U.join(tcpSrvr, log); + if (tcpSrvr != null) { + tcpSrvr.stop(); + + tcpSrvr = null; + } U.interrupt(ipFinderCleaner); U.join(ipFinderCleaner, log); @@ -6032,13 +6035,6 @@ class ServerImpl extends TcpDiscoveryImpl { @Override protected void body() throws InterruptedException { worker.run(); } - - /** {@inheritDoc} */ - @Override public void interrupt() { - super.interrupt(); - - worker.onInterruption(); - } } /** @@ -6181,8 +6177,12 @@ class ServerImpl extends TcpDiscoveryImpl { } /** */ - public void onInterruption() { + public void stop() { + cancel(); + U.close(srvrSock, log); + + U.join(TcpServer.this, log); } } diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/IgniteClientCacheInitializationFailTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/IgniteClientCacheInitializationFailTest.java index 1424a25..cb3a509 100644 --- a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/IgniteClientCacheInitializationFailTest.java +++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/IgniteClientCacheInitializationFailTest.java @@ -17,10 +17,8 @@ package org.apache.ignite.internal.processors.cache; -import java.util.Collection; import java.util.Collections; import java.util.HashSet; -import java.util.List; import java.util.Random; import java.util.Set; import java.util.concurrent.Callable; @@ -28,46 +26,15 @@ import javax.cache.CacheException; import org.apache.ignite.Ignite; import org.apache.ignite.IgniteCache; import org.apache.ignite.IgniteCheckedException; -import org.apache.ignite.IgniteDataStreamer; import org.apache.ignite.cache.CacheAtomicityMode; -import org.apache.ignite.cache.query.FieldsQueryCursor; -import org.apache.ignite.cache.query.SqlFieldsQuery; -import org.apache.ignite.cache.query.SqlQuery; import org.apache.ignite.configuration.CacheConfiguration; import org.apache.ignite.configuration.IgniteConfiguration; import org.apache.ignite.configuration.NearCacheConfiguration; -import org.apache.ignite.internal.GridKernalContext; -import org.apache.ignite.internal.IgniteInternalFuture; import org.apache.ignite.internal.IgniteKernal; -import org.apache.ignite.internal.managers.IgniteMBeansManager; -import org.apache.ignite.internal.pagemem.PageMemory; -import org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion; -import org.apache.ignite.internal.processors.cache.mvcc.MvccSnapshot; -import org.apache.ignite.internal.processors.cache.persistence.CacheDataRow; -import org.apache.ignite.internal.processors.cache.persistence.RootPage; -import org.apache.ignite.internal.processors.cache.persistence.tree.reuse.ReuseList; -import org.apache.ignite.internal.processors.odbc.jdbc.JdbcParameterMeta; -import org.apache.ignite.internal.processors.query.GridQueryCancel; -import org.apache.ignite.internal.processors.query.GridQueryFieldMetadata; -import org.apache.ignite.internal.processors.query.GridQueryIndexing; +import org.apache.ignite.internal.processors.query.DummyQueryIndexing; import org.apache.ignite.internal.processors.query.GridQueryProcessor; -import org.apache.ignite.internal.processors.query.GridQueryRowCacheCleaner; -import org.apache.ignite.internal.processors.query.GridQueryTypeDescriptor; -import org.apache.ignite.internal.processors.query.GridRunningQueryInfo; -import org.apache.ignite.internal.processors.query.QueryField; -import org.apache.ignite.internal.processors.query.QueryIndexDescriptorImpl; -import org.apache.ignite.internal.processors.query.SqlClientContext; -import org.apache.ignite.internal.processors.query.UpdateSourceIterator; -import org.apache.ignite.internal.processors.query.schema.SchemaIndexCacheVisitor; -import org.apache.ignite.internal.util.GridAtomicLong; -import org.apache.ignite.internal.util.GridSpinBusyLock; -import org.apache.ignite.internal.util.lang.GridCloseableIterator; -import org.apache.ignite.lang.IgniteBiTuple; -import org.apache.ignite.lang.IgniteFuture; -import org.apache.ignite.spi.indexing.IndexingQueryFilter; import org.apache.ignite.testframework.GridTestUtils; import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest; -import org.jetbrains.annotations.Nullable; import org.junit.Ignore; import org.junit.Test; @@ -267,88 +234,7 @@ public class IgniteClientCacheInitializationFailTest extends GridCommonAbstractT /** * To fail on cache start. */ - private static class FailedIndexing implements GridQueryIndexing { - /** {@inheritDoc} */ - @Override public void onClientDisconnect() throws IgniteCheckedException { - // No-op. - } - - /** {@inheritDoc} */ - @Override public SqlFieldsQuery generateFieldsQuery(String cacheName, SqlQuery qry) { - return null; - } - - /** {@inheritDoc} */ - @Override public void start(GridKernalContext ctx, GridSpinBusyLock busyLock) throws IgniteCheckedException { - // No-op - } - - /** {@inheritDoc} */ - @Override public void stop() throws IgniteCheckedException { - // No-op - } - - /** {@inheritDoc} */ - @Override public List<FieldsQueryCursor<List<?>>> querySqlFields( - String schemaName, - SqlFieldsQuery qry, - SqlClientContext cliCtx, - boolean keepBinary, - boolean failOnMultipleStmts, - GridQueryCancel cancel - ) { - return null; - } - - /** {@inheritDoc} */ - @Override public List<Long> streamBatchedUpdateQuery(String schemaName, String qry, List<Object[]> params, - SqlClientContext cliCtx) throws IgniteCheckedException { - return Collections.emptyList(); - } - - /** {@inheritDoc} */ - @Override public long streamUpdateQuery(String schemaName, String qry, @Nullable Object[] params, - IgniteDataStreamer<?, ?> streamer) throws IgniteCheckedException { - return 0; - } - - /** {@inheritDoc} */ - @Override public <K, V> GridCloseableIterator<IgniteBiTuple<K, V>> queryLocalText(String spaceName, - String cacheName, String qry, String typeName, IndexingQueryFilter filter) throws IgniteCheckedException { - return null; - } - - /** {@inheritDoc} */ - @Override public void dynamicIndexCreate(String spaceName, String tblName, QueryIndexDescriptorImpl idxDesc, - boolean ifNotExists, SchemaIndexCacheVisitor cacheVisitor) throws IgniteCheckedException { - // No-op - } - - /** {@inheritDoc} */ - @Override public void dynamicIndexDrop(String spaceName, String idxName, - boolean ifExists) throws IgniteCheckedException { - // No-op - } - - /** {@inheritDoc} */ - @Override public void destroyOrphanIndex(RootPage page, String indexName, int grpId, PageMemory pageMemory, - GridAtomicLong removeId, ReuseList reuseList, boolean mvccEnabled) throws IgniteCheckedException { - // No-op - } - - /** {@inheritDoc} */ - @Override public void dynamicAddColumn(String schemaName, String tblName, List<QueryField> cols, - boolean ifTblExists, boolean ifColNotExists) - throws IgniteCheckedException { - // No-op. - } - - /** {@inheritDoc} */ - @Override public void dynamicDropColumn(String schemaName, String tblName, List<String> cols, - boolean ifTblExists, boolean ifColExists) throws IgniteCheckedException { - // No-op - } - + private static class FailedIndexing extends DummyQueryIndexing { /** {@inheritDoc} */ @Override public void registerCache(String cacheName, String schemaName, GridCacheContextInfo<?, ?> cacheInfo) throws IgniteCheckedException { @@ -357,115 +243,11 @@ public class IgniteClientCacheInitializationFailTest extends GridCommonAbstractT } /** {@inheritDoc} */ - @Override public void unregisterCache(GridCacheContextInfo cacheInfo, - boolean rmvIdx) throws IgniteCheckedException { - // No-op - } - - /** {@inheritDoc} */ - @Override public UpdateSourceIterator<?> executeUpdateOnDataNodeTransactional(GridCacheContext<?, ?> cctx, int[] ids, int[] parts, - String schema, String qry, Object[] params, int flags, int pageSize, int timeout, - AffinityTopologyVersion topVer, - MvccSnapshot mvccVer, GridQueryCancel cancel) throws IgniteCheckedException { - return null; - } - - @Override public boolean registerType(GridCacheContextInfo cacheInfo, - GridQueryTypeDescriptor desc, boolean isSql) throws IgniteCheckedException { - return false; - } - - @Override public List<JdbcParameterMeta> parameterMetaData(String schemaName, SqlFieldsQuery sql) { - return null; - } - - @Override public List<GridQueryFieldMetadata> resultMetaData(String schemaName, SqlFieldsQuery sql) { - return null; - } - - /** {@inheritDoc} */ - @Override public void store(GridCacheContext cctx, GridQueryTypeDescriptor type, CacheDataRow row, - CacheDataRow prevRow, boolean prevRowAvailable) throws IgniteCheckedException { - // No-op. - } - - /** {@inheritDoc} */ - @Override public void remove(GridCacheContext cctx, GridQueryTypeDescriptor type, CacheDataRow val) { - // No-op. - } - - /** {@inheritDoc} */ - @Override public IgniteInternalFuture<?> rebuildIndexesFromHash(GridCacheContext cctx) { - return null; - } - - /** {@inheritDoc} */ - @Override public void markAsRebuildNeeded(GridCacheContext cctx) { - // No-op. - } - - /** {@inheritDoc} */ - @Override public IndexingQueryFilter backupFilter(AffinityTopologyVersion topVer, int[] parts) { - return null; - } - - /** {@inheritDoc} */ - @Override public void onDisconnected(IgniteFuture<?> reconnectFut) { - // No-op - } - - /** {@inheritDoc} */ - @Override public Collection<GridRunningQueryInfo> runningQueries(long duration) { - return null; - } - - /** {@inheritDoc} */ - @Override public void cancelQueries(Collection<Long> queries) { - // No-op - } - - /** {@inheritDoc} */ - @Override public void onKernalStop() { - // No-op - } - - /** {@inheritDoc} */ - @Override public String schema(String cacheName) { - return null; - } - - /** {@inheritDoc} */ - @Override public Set<String> schemasNames() { - return null; - } - - /** {@inheritDoc} */ - @Override public boolean isStreamableInsertStatement(String schemaName, SqlFieldsQuery sql) { - // No-op. - return true; - } - - /** {@inheritDoc} */ - @Override public GridQueryRowCacheCleaner rowCacheCleaner(int cacheGroupId) { - return null; - } - - /** {@inheritDoc} */ - @Override public GridCacheContextInfo registeredCacheInfo(String cacheName) { - return null; - } - - /** {@inheritDoc} */ @Override public boolean initCacheContext(GridCacheContext ctx) throws IgniteCheckedException { if (FAILED_CACHES.contains(ctx.name()) && ctx.kernalContext().clientNode()) throw new IgniteCheckedException("Test query exception " + ctx.name() + " " + new Random().nextInt()); return true; } - - /** {@inheritDoc} */ - @Override public void registerMxBeans(IgniteMBeansManager mbMgr) { - // No-op. - } } } diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/query/DummyQueryIndexing.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/query/DummyQueryIndexing.java new file mode 100644 index 0000000..a65232c --- /dev/null +++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/query/DummyQueryIndexing.java @@ -0,0 +1,314 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.ignite.internal.processors.query; + +import java.util.Collection; +import java.util.List; +import java.util.Set; +import org.apache.ignite.IgniteCheckedException; +import org.apache.ignite.IgniteDataStreamer; +import org.apache.ignite.cache.query.FieldsQueryCursor; +import org.apache.ignite.cache.query.SqlFieldsQuery; +import org.apache.ignite.cache.query.SqlQuery; +import org.apache.ignite.internal.GridKernalContext; +import org.apache.ignite.internal.IgniteInternalFuture; +import org.apache.ignite.internal.managers.IgniteMBeansManager; +import org.apache.ignite.internal.pagemem.PageMemory; +import org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion; +import org.apache.ignite.internal.processors.cache.GridCacheContext; +import org.apache.ignite.internal.processors.cache.GridCacheContextInfo; +import org.apache.ignite.internal.processors.cache.mvcc.MvccSnapshot; +import org.apache.ignite.internal.processors.cache.persistence.CacheDataRow; +import org.apache.ignite.internal.processors.cache.persistence.RootPage; +import org.apache.ignite.internal.processors.cache.persistence.tree.reuse.ReuseList; +import org.apache.ignite.internal.processors.odbc.jdbc.JdbcParameterMeta; +import org.apache.ignite.internal.processors.query.schema.SchemaIndexCacheVisitor; +import org.apache.ignite.internal.util.GridAtomicLong; +import org.apache.ignite.internal.util.GridSpinBusyLock; +import org.apache.ignite.internal.util.lang.GridCloseableIterator; +import org.apache.ignite.lang.IgniteBiTuple; +import org.apache.ignite.lang.IgniteFuture; +import org.apache.ignite.spi.indexing.IndexingQueryFilter; +import org.jetbrains.annotations.Nullable; + +/** + * Empty indexing class used in tests to simulate failures. + */ +@SuppressWarnings({"deprecation", "RedundantThrows"}) +public class DummyQueryIndexing implements GridQueryIndexing { + /** {@inheritDoc} */ + @Override public void start(GridKernalContext ctx, GridSpinBusyLock busyLock) throws IgniteCheckedException { + + } + + /** {@inheritDoc} */ + @Override public void stop() throws IgniteCheckedException { + + } + + /** {@inheritDoc} */ + @Override public void onClientDisconnect() throws IgniteCheckedException { + + } + + /** {@inheritDoc} */ + @Override public SqlFieldsQuery generateFieldsQuery(String cacheName, SqlQuery qry) { + return null; + } + + /** {@inheritDoc} */ + @Override public List<FieldsQueryCursor<List<?>>> querySqlFields( + String schemaName, + SqlFieldsQuery qry, + SqlClientContext cliCtx, + boolean keepBinary, + boolean failOnMultipleStmts, + GridQueryCancel cancel + ) { + return null; + } + + /** {@inheritDoc} */ + @Override public long streamUpdateQuery( + String schemaName, + String qry, + @Nullable Object[] params, + IgniteDataStreamer<?, ?> streamer + ) throws IgniteCheckedException { + return 0; + } + + /** {@inheritDoc} */ + @Override public List<Long> streamBatchedUpdateQuery( + String schemaName, + String qry, + List<Object[]> params, + SqlClientContext cliCtx + ) throws IgniteCheckedException { + return null; + } + + /** {@inheritDoc} */ + @Override public <K, V> GridCloseableIterator<IgniteBiTuple<K, V>> queryLocalText( + String schemaName, + String cacheName, + String qry, + String typeName, + IndexingQueryFilter filter + ) throws IgniteCheckedException { + return null; + } + + /** {@inheritDoc} */ + @Override public void dynamicIndexCreate( + String schemaName, + String tblName, + QueryIndexDescriptorImpl idxDesc, + boolean ifNotExists, + SchemaIndexCacheVisitor cacheVisitor + ) throws IgniteCheckedException { + + } + + /** {@inheritDoc} */ + @Override public void dynamicIndexDrop( + String schemaName, + String idxName, + boolean ifExists + ) throws IgniteCheckedException { + + } + + /** {@inheritDoc} */ + @Override public void dynamicAddColumn( + String schemaName, + String tblName, + List<QueryField> cols, + boolean ifTblExists, + boolean ifColNotExists + ) throws IgniteCheckedException { + + } + + /** {@inheritDoc} */ + @Override public void dynamicDropColumn( + String schemaName, + String tblName, + List<String> cols, + boolean ifTblExists, + boolean ifColExists + ) throws IgniteCheckedException { + + } + + /** {@inheritDoc} */ + @Override public void registerCache( + String cacheName, + String schemaName, + GridCacheContextInfo<?, ?> cacheInfo + ) throws IgniteCheckedException { + + } + + /** {@inheritDoc} */ + @Override public void unregisterCache(GridCacheContextInfo cacheInfo, boolean rmvIdx) throws IgniteCheckedException { + + } + + /** {@inheritDoc} */ + @Override public void destroyOrphanIndex( + RootPage page, + String idxName, + int grpId, + PageMemory pageMemory, + GridAtomicLong rmvId, + ReuseList reuseList, + boolean mvccEnabled + ) throws IgniteCheckedException { + + } + + /** {@inheritDoc} */ + @Override public UpdateSourceIterator<?> executeUpdateOnDataNodeTransactional( + GridCacheContext<?, ?> cctx, + int[] ids, + int[] parts, + String schema, + String qry, + Object[] params, + int flags, + int pageSize, + int timeout, + AffinityTopologyVersion topVer, + MvccSnapshot mvccSnapshot, + GridQueryCancel cancel + ) throws IgniteCheckedException { + return null; + } + + /** {@inheritDoc} */ + @Override public boolean registerType( + GridCacheContextInfo cacheInfo, + GridQueryTypeDescriptor desc, + boolean isSql + ) throws IgniteCheckedException { + return false; + } + + /** {@inheritDoc} */ + @Override public List<JdbcParameterMeta> parameterMetaData( + String schemaName, + SqlFieldsQuery sql + ) throws IgniteSQLException { + return null; + } + + /** {@inheritDoc} */ + @Override public @Nullable List<GridQueryFieldMetadata> resultMetaData( + String schemaName, + SqlFieldsQuery sql + ) throws IgniteSQLException { + return null; + } + + /** {@inheritDoc} */ + @Override public void store( + GridCacheContext cctx, + GridQueryTypeDescriptor type, + CacheDataRow row, + CacheDataRow prevRow, + boolean prevRowAvailable + ) throws IgniteCheckedException { + + } + + /** {@inheritDoc} */ + @Override public void remove(GridCacheContext cctx, GridQueryTypeDescriptor type, CacheDataRow row) { + + } + + /** {@inheritDoc} */ + @Override public IgniteInternalFuture<?> rebuildIndexesFromHash(GridCacheContext cctx) { + return null; + } + + /** {@inheritDoc} */ + @Override public void markAsRebuildNeeded(GridCacheContext cctx) { + + } + + /** {@inheritDoc} */ + @Override public IndexingQueryFilter backupFilter(AffinityTopologyVersion topVer, int[] parts) { + return null; + } + + /** {@inheritDoc} */ + @Override public void onDisconnected(IgniteFuture<?> reconnectFut) { + + } + + /** {@inheritDoc} */ + @Override public Collection<GridRunningQueryInfo> runningQueries(long duration) { + return null; + } + + /** {@inheritDoc} */ + @Override public void cancelQueries(Collection<Long> queries) { + + } + + /** {@inheritDoc} */ + @Override public void onKernalStop() { + + } + + /** {@inheritDoc} */ + @Override public String schema(String cacheName) { + return null; + } + + /** {@inheritDoc} */ + @Override public Set<String> schemasNames() { + return null; + } + + /** {@inheritDoc} */ + @Override public boolean isStreamableInsertStatement(String schemaName, SqlFieldsQuery sql) { + return false; + } + + /** {@inheritDoc} */ + @Override public GridQueryRowCacheCleaner rowCacheCleaner(int cacheGrpId) { + return null; + } + + /** {@inheritDoc} */ + @Override public @Nullable GridCacheContextInfo registeredCacheInfo(String cacheName) { + return null; + } + + /** {@inheritDoc} */ + @Override public boolean initCacheContext(GridCacheContext ctx) throws IgniteCheckedException { + return false; + } + + /** {@inheritDoc} */ + @Override public void registerMxBeans(IgniteMBeansManager mbMgr) { + + } +} diff --git a/modules/core/src/test/java/org/apache/ignite/spi/discovery/tcp/TcpDiscoveryFailedJoinTest.java b/modules/core/src/test/java/org/apache/ignite/spi/discovery/tcp/TcpDiscoveryFailedJoinTest.java index 3fa7a5c..1c59b51 100644 --- a/modules/core/src/test/java/org/apache/ignite/spi/discovery/tcp/TcpDiscoveryFailedJoinTest.java +++ b/modules/core/src/test/java/org/apache/ignite/spi/discovery/tcp/TcpDiscoveryFailedJoinTest.java @@ -20,12 +20,19 @@ package org.apache.ignite.spi.discovery.tcp; import java.io.IOException; import java.io.OutputStream; import java.net.InetSocketAddress; +import java.net.ServerSocket; import java.net.Socket; import java.net.SocketException; import java.util.Collections; import org.apache.ignite.IgniteCheckedException; +import org.apache.ignite.IgniteException; import org.apache.ignite.cluster.ClusterNode; import org.apache.ignite.configuration.IgniteConfiguration; +import org.apache.ignite.internal.GridKernalContext; +import org.apache.ignite.internal.processors.query.DummyQueryIndexing; +import org.apache.ignite.internal.processors.query.GridQueryProcessor; +import org.apache.ignite.internal.util.GridSpinBusyLock; +import org.apache.ignite.internal.util.typedef.internal.U; import org.apache.ignite.spi.IgniteSpiOperationTimeoutException; import org.apache.ignite.spi.IgniteSpiOperationTimeoutHelper; import org.apache.ignite.spi.discovery.tcp.ipfinder.vm.TcpDiscoveryVmIpFinder; @@ -46,6 +53,9 @@ public class TcpDiscoveryFailedJoinTest extends GridCommonAbstractTest { private static final int FAIL_PORT = 47503; /** */ + private static final int BIND_PORT = 47511; + + /** */ private SpiFailType failType = SpiFailType.REFUSE; /** {@inheritDoc} */ @@ -71,12 +81,45 @@ public class TcpDiscoveryFailedJoinTest extends GridCommonAbstractTest { discoSpi.setForceServerMode(gridName.contains("server")); } + if (gridName.contains("failingNode")) { + GridQueryProcessor.idxCls = FailingIndexing.class; + + cfg.setLocalHost("127.0.0.1"); + } + return cfg; } /** {@inheritDoc} */ @Override protected void afterTest() throws Exception { stopAllGrids(); + + GridQueryProcessor.idxCls = null; + } + + /** + * @throws Exception if failed. + */ + @Test + public void testPortReleasedAfterFailure() throws Exception { + try { + startGrid("failingNode-" + BIND_PORT); + + fail("Node start should fail"); + } + catch (Exception e) { + // Expected exception. Check that BIND_PORT can be re-bound. + ServerSocket sock = new ServerSocket(); + + try { + sock.setReuseAddress(true); + + sock.bind(new InetSocketAddress("127.0.0.1", BIND_PORT)); + } + finally { + U.close(sock, log); + } + } } /** @@ -197,6 +240,18 @@ public class TcpDiscoveryFailedJoinTest extends GridCommonAbstractTest { /** * */ + private static class FailingIndexing extends DummyQueryIndexing { + /** {@inheritDoc} */ + @Override public void start(GridKernalContext ctx, GridSpinBusyLock busyLock) { + ctx.discovery().consistentId(); + + throw new IgniteException("Failed to start"); + } + } + + /** + * + */ private enum SpiFailType { /** */ REFUSE,