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

[ignite] branch master updated: IGNITE-11955 Fix control.sh issues related to IGNITE-11876 and IGNITE-11913 - Fixes #6660.

This is an automated email from the ASF dual-hosted git repository.

dgovorukhin 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 4285e78  IGNITE-11955 Fix control.sh issues related to IGNITE-11876 and IGNITE-11913 - Fixes #6660.
4285e78 is described below

commit 4285e784cff5ad8c5d8502a3435b79776ccef097
Author: denis-chudov <dc...@gridgain.com>
AuthorDate: Wed Jul 3 13:07:11 2019 +0300

    IGNITE-11955 Fix control.sh issues related to IGNITE-11876 and IGNITE-11913 - Fixes #6660.
---
 .../internal/commandline/cache/IdleVerify.java     | 50 +++++++++++++++--
 .../cache/verify/IdleVerifyResultV2.java           | 13 +++--
 .../verify/VerifyBackupPartitionsDumpTask.java     | 42 +-------------
 .../cache/verify/VerifyBackupPartitionsTaskV2.java | 55 ++++++++-----------
 .../visor/verify/VisorIdleVerifyDumpTaskArg.java   | 38 +++----------
 .../internal/visor/verify/VisorIdleVerifyTask.java |  2 +-
 .../visor/verify/VisorIdleVerifyTaskArg.java       | 62 +++++++++++++++++++--
 .../apache/ignite/testframework/GridTestUtils.java |  2 +-
 .../apache/ignite/util/GridCommandHandlerTest.java | 64 +++++++++++++++++-----
 9 files changed, 194 insertions(+), 134 deletions(-)

diff --git a/modules/core/src/main/java/org/apache/ignite/internal/commandline/cache/IdleVerify.java b/modules/core/src/main/java/org/apache/ignite/internal/commandline/cache/IdleVerify.java
index 70e5275..d66eb94 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/commandline/cache/IdleVerify.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/commandline/cache/IdleVerify.java
@@ -23,6 +23,7 @@ import java.util.Collections;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
+import java.util.function.Consumer;
 import java.util.regex.Pattern;
 import java.util.regex.PatternSyntaxException;
 import org.apache.ignite.IgniteException;
@@ -40,6 +41,7 @@ import org.apache.ignite.internal.processors.cache.verify.IdleVerifyResultV2;
 import org.apache.ignite.internal.processors.cache.verify.PartitionHashRecord;
 import org.apache.ignite.internal.processors.cache.verify.PartitionKey;
 import org.apache.ignite.internal.processors.cache.verify.VerifyBackupPartitionsTaskV2;
+import org.apache.ignite.internal.util.typedef.internal.SB;
 import org.apache.ignite.internal.visor.verify.CacheFilterEnum;
 import org.apache.ignite.internal.visor.verify.VisorIdleVerifyDumpTask;
 import org.apache.ignite.internal.visor.verify.VisorIdleVerifyDumpTaskArg;
@@ -296,6 +298,8 @@ public class IdleVerify implements Command<IdleVerify.Arguments> {
 
         String path = executeTask(client, VisorIdleVerifyDumpTask.class, arg, clientCfg);
 
+        logParsedArgs(arg, logger::log);
+
         logger.log("VisorIdleVerifyDumpTask successfully written output to '" + path + "'");
     }
 
@@ -307,16 +311,44 @@ public class IdleVerify implements Command<IdleVerify.Arguments> {
         GridClient client,
         GridClientConfiguration clientCfg
     ) throws GridClientException {
-        IdleVerifyResultV2 res = executeTask(
-            client,
-            VisorIdleVerifyTaskV2.class,
-            new VisorIdleVerifyTaskArg(args.caches(), args.excludeCaches(), args.idleCheckCrc()),
-            clientCfg);
+        VisorIdleVerifyTaskArg taskArg = new VisorIdleVerifyTaskArg(
+            args.caches(),
+            args.excludeCaches(),
+            args.isSkipZeros(),
+            args.getCacheFilterEnum(),
+            args.idleCheckCrc()
+        );
+
+        IdleVerifyResultV2 res = executeTask(client, VisorIdleVerifyTaskV2.class, taskArg, clientCfg);
+
+        logParsedArgs(taskArg, System.out::print);
 
         res.print(System.out::print);
     }
 
     /**
+     * Passes idle_verify parsed arguments to given log consumer.
+     *
+     * @param args idle_verify arguments.
+     * @param logConsumer Logger.
+     */
+    public static void logParsedArgs(VisorIdleVerifyTaskArg args, Consumer<String> logConsumer) {
+        SB options = new SB("idle_verify task was executed with the following args: ");
+
+        options
+            .a("caches=[")
+            .a(args.caches() == null ? "" : String.join(", ", args.caches()))
+            .a("], excluded=[")
+            .a(args.excludeCaches() == null ? "" : String.join(", ", args.excludeCaches()))
+            .a("]")
+            .a(", cacheFilter=[")
+            .a(args.cacheFilterEnum().toString())
+            .a("]\n");
+
+        logConsumer.accept(options.toString());
+    }
+
+    /**
      * @param client Client.
      * @param clientCfg Client configuration.
      */
@@ -328,7 +360,13 @@ public class IdleVerify implements Command<IdleVerify.Arguments> {
         VisorIdleVerifyTaskResult res = executeTask(
             client,
             VisorIdleVerifyTask.class,
-            new VisorIdleVerifyTaskArg(args.caches(), args.excludeCaches(), args.idleCheckCrc()),
+            new VisorIdleVerifyTaskArg(
+                args.caches(),
+                args.excludeCaches(),
+                args.isSkipZeros(),
+                args.getCacheFilterEnum(),
+                args.idleCheckCrc()
+            ),
             clientCfg);
 
         Map<PartitionKey, List<PartitionHashRecord>> conflicts = res.getConflicts();
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/verify/IdleVerifyResultV2.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/verify/IdleVerifyResultV2.java
index b6b347c..3726664 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/verify/IdleVerifyResultV2.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/verify/IdleVerifyResultV2.java
@@ -232,24 +232,25 @@ public class IdleVerifyResultV2 extends VisorDataTransferObject {
             }
         }
         else {
-            printer.accept("idle_verify failed.");
+            printer.accept("\nidle_verify failed.\n");
 
             if (noMatchingCaches)
-                printer.accept("There are no caches matching given filter options.");
+                printer.accept("\nThere are no caches matching given filter options.\n");
         }
 
         if (!F.isEmpty(exceptions())) {
-            printer.accept("Idle verify failed on nodes:\n");
+            printer.accept("\nIdle verify failed on nodes:\n");
 
             for (Map.Entry<ClusterNode, Exception> e : exceptions().entrySet()) {
                 ClusterNode n = e.getKey();
 
-                printer.accept("Node ID: " + n.id() + " " + n.addresses() + " consistent ID: " + n.consistentId() + "\n");
+                printer.accept("\nNode ID: " + n.id() + " " + n.addresses() + "\nConsistent ID: " + n.consistentId() + "\n");
 
                 if (printExceptionMessages) {
-                    printer.accept("Exception message:" + "\n");
+                    String msg = e.getValue().getMessage();
 
-                    printer.accept(e.getValue().getMessage() + "\n");
+                    printer.accept("Exception: " + e.getValue().getClass().getCanonicalName() + "\n");
+                    printer.accept(msg == null ? "" : msg + "\n");
                 }
             }
         }
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/verify/VerifyBackupPartitionsDumpTask.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/verify/VerifyBackupPartitionsDumpTask.java
index de7b369..5057281 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/verify/VerifyBackupPartitionsDumpTask.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/verify/VerifyBackupPartitionsDumpTask.java
@@ -38,15 +38,13 @@ import org.apache.ignite.compute.ComputeJobResultPolicy;
 import org.apache.ignite.compute.ComputeTaskAdapter;
 import org.apache.ignite.internal.processors.task.GridInternal;
 import org.apache.ignite.internal.util.typedef.F;
-import org.apache.ignite.internal.visor.verify.CacheFilterEnum;
 import org.apache.ignite.internal.visor.verify.VisorIdleVerifyDumpTaskArg;
 import org.apache.ignite.internal.visor.verify.VisorIdleVerifyTaskArg;
 import org.apache.ignite.resources.IgniteInstanceResource;
 import org.apache.ignite.resources.LoggerResource;
 import org.jetbrains.annotations.Nullable;
 
-import static org.apache.ignite.internal.commandline.cache.argument.IdleVerifyCommandArg.CACHE_FILTER;
-import static org.apache.ignite.internal.commandline.cache.argument.IdleVerifyCommandArg.EXCLUDE_CACHES;
+import static org.apache.ignite.internal.commandline.cache.IdleVerify.logParsedArgs;
 
 /**
  * Task for collection checksums primary and backup partitions of specified caches. <br> Argument: Set of cache names,
@@ -141,7 +139,7 @@ public class VerifyBackupPartitionsDumpTask extends ComputeTaskAdapter<VisorIdle
      * @return {@code true} if this records should be add to result and {@code false} otherwise.
      */
     private boolean needToAdd(List<PartitionHashRecordV2> records) {
-        if (records.isEmpty() || (taskArg != null && !taskArg.isSkipZeros()))
+        if (records.isEmpty() || (taskArg != null && !taskArg.skipZeros()))
             return true;
 
         PartitionHashRecordV2 record = records.get(0);
@@ -228,7 +226,7 @@ public class VerifyBackupPartitionsDumpTask extends ComputeTaskAdapter<VisorIdle
         if (!partitions.isEmpty())
             writer.write("idle_verify check has finished, found " + partitions.size() + " partitions\n");
 
-        writer.write("idle_verify task was executed with the following args: " + taskArgsAsCmd() + "\n");
+        logParsedArgs(taskArg, writer::write);
 
         if (skippedRecords > 0)
             writer.write(skippedRecords + " partitions was skipped\n");
@@ -249,40 +247,6 @@ public class VerifyBackupPartitionsDumpTask extends ComputeTaskAdapter<VisorIdle
     }
 
     /**
-     * Method that builds command line string from the taskArg field.
-     *
-     * @return command line argument string
-     */
-    private String taskArgsAsCmd() {
-        StringBuilder result = new StringBuilder();
-
-        if (!F.isEmpty(taskArg.getCaches())) {
-            for (String cache : taskArg.getCaches()) {
-                result.append(cache);
-                result.append(" ");
-            }
-        }
-
-        if (taskArg.getCacheFilterEnum() != null && taskArg.getCacheFilterEnum() != CacheFilterEnum.DEFAULT) {
-            result.append(CACHE_FILTER);
-            result.append(" ");
-            result.append(taskArg.getCacheFilterEnum());
-            result.append(" ");
-        }
-
-        if (!F.isEmpty(taskArg.getExcludeCaches())) {
-            result.append(EXCLUDE_CACHES + " ");
-
-            for (String excluded : taskArg.getExcludeCaches()) {
-                result.append(excluded);
-                result.append(" ");
-            }
-        }
-
-        return result.toString();
-    }
-
-    /**
      * @return Comparator for {@link PartitionHashRecordV2}.
      */
     private Comparator<PartitionHashRecordV2> buildRecordComparator() {
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/verify/VerifyBackupPartitionsTaskV2.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/verify/VerifyBackupPartitionsTaskV2.java
index a4fd83d..4a68fc0 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/verify/VerifyBackupPartitionsTaskV2.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/verify/VerifyBackupPartitionsTaskV2.java
@@ -62,7 +62,6 @@ import org.apache.ignite.internal.util.lang.GridIterator;
 import org.apache.ignite.internal.util.typedef.F;
 import org.apache.ignite.internal.util.typedef.internal.SB;
 import org.apache.ignite.internal.util.typedef.internal.U;
-import org.apache.ignite.internal.visor.verify.VisorIdleVerifyDumpTaskArg;
 import org.apache.ignite.internal.visor.verify.VisorIdleVerifyTaskArg;
 import org.apache.ignite.lang.IgniteInClosure;
 import org.apache.ignite.lang.IgniteProductVersion;
@@ -253,7 +252,7 @@ public class VerifyBackupPartitionsTaskV2 extends ComputeTaskAdapter<VisorIdleVe
 
             DbCheckpointListener lsnr = null;
 
-            if (arg.isCheckCrc() &&
+            if (arg.checkCrc() &&
                 ignite.context().cache().context().database() instanceof GridCacheDatabaseSharedManager) {
                 db = (GridCacheDatabaseSharedManager)ignite.context().cache().context().database();
 
@@ -276,7 +275,7 @@ public class VerifyBackupPartitionsTaskV2 extends ComputeTaskAdapter<VisorIdleVe
             }
 
             try {
-                if (arg.isCheckCrc() && IdleVerifyUtility.isCheckpointNow(db))
+                if (arg.checkCrc() && IdleVerifyUtility.isCheckpointNow(db))
                     throw new GridNotIdleException(IdleVerifyUtility.CLUSTER_NOT_IDLE_MSG);
 
                 List<Future<Map<PartitionKeyV2, PartitionHashRecordV2>>> partHashCalcFuts =
@@ -422,10 +421,10 @@ public class VerifyBackupPartitionsTaskV2 extends ComputeTaskAdapter<VisorIdleVe
          * @param cachesToFilter cache groups to filter
          */
         private void filterByExcludeCaches(Set<CacheGroupContext> cachesToFilter) {
-            if (!F.isEmpty(arg.getExcludeCaches())) {
+            if (!F.isEmpty(arg.excludeCaches())) {
                 Set<Pattern> excludedNamesPatterns = new HashSet<>();
 
-                for (String excluded : arg.getExcludeCaches())
+                for (String excluded : arg.excludeCaches())
                     excludedNamesPatterns.add(Pattern.compile(excluded));
 
                 cachesToFilter.removeIf(grp -> doesGrpMatchOneOfPatterns(grp, excludedNamesPatterns));
@@ -448,10 +447,10 @@ public class VerifyBackupPartitionsTaskV2 extends ComputeTaskAdapter<VisorIdleVe
          * @param cachesToFilter cache groups to filter
          */
         private void filterByCacheNames(Set<CacheGroupContext> cachesToFilter) {
-            if (!F.isEmpty(arg.getCaches())) {
+            if (!F.isEmpty(arg.caches())) {
                 Set<Pattern> cacheNamesPatterns = new HashSet<>();
 
-                for (String cacheNameRegexp : arg.getCaches())
+                for (String cacheNameRegexp : arg.caches())
                     cacheNamesPatterns.add(Pattern.compile(cacheNameRegexp));
 
                 cachesToFilter.removeIf(grp -> !doesGrpMatchOneOfPatterns(grp, cacheNamesPatterns));
@@ -500,38 +499,32 @@ public class VerifyBackupPartitionsTaskV2 extends ComputeTaskAdapter<VisorIdleVe
          * @param desc Cache descriptor.
          */
         private boolean isCacheMatchFilter(DynamicCacheDescriptor desc) {
-            if (arg instanceof VisorIdleVerifyDumpTaskArg) {
-                DataStorageConfiguration dsCfg = ignite.context().config().getDataStorageConfiguration();
+            DataStorageConfiguration dsCfg = ignite.context().config().getDataStorageConfiguration();
 
-                CacheConfiguration cc = desc.cacheConfiguration();
+            CacheConfiguration cc = desc.cacheConfiguration();
 
-                VisorIdleVerifyDumpTaskArg vdta = (VisorIdleVerifyDumpTaskArg)arg;
+            switch (arg.cacheFilterEnum()) {
+                case DEFAULT:
+                    return desc.cacheType().userCache() || !F.isEmpty(arg.caches());
 
-                switch (vdta.getCacheFilterEnum()) {
-                    case DEFAULT:
-                        return desc.cacheType().userCache() || !F.isEmpty(arg.getCaches());
+                case USER:
+                    return desc.cacheType().userCache();
 
-                    case USER:
-                        return desc.cacheType().userCache();
+                case SYSTEM:
+                    return !desc.cacheType().userCache();
 
-                    case SYSTEM:
-                        return !desc.cacheType().userCache();
+                case NOT_PERSISTENT:
+                    return desc.cacheType().userCache() && !GridCacheUtils.isPersistentCache(cc, dsCfg);
 
-                    case NOT_PERSISTENT:
-                        return desc.cacheType().userCache() && !GridCacheUtils.isPersistentCache(cc, dsCfg);
+                case PERSISTENT:
+                    return desc.cacheType().userCache() && GridCacheUtils.isPersistentCache(cc, dsCfg);
 
-                    case PERSISTENT:
-                        return desc.cacheType().userCache() && GridCacheUtils.isPersistentCache(cc, dsCfg);
-
-                    case ALL:
-                        return true;
+                case ALL:
+                    return true;
 
-                    default:
-                        assert false : "Illegal cache filter: " + vdta.getCacheFilterEnum();
-                }
+                default:
+                    throw new IgniteException("Illegal cache filter: " + arg.cacheFilterEnum());
             }
-
-            return desc.cacheType().userCache() || !F.isEmpty(arg.getCaches());
         }
 
         /**
@@ -582,7 +575,7 @@ public class VerifyBackupPartitionsTaskV2 extends ComputeTaskAdapter<VisorIdleVe
 
                 partSize = part.dataStore().fullSize();
 
-                if (arg.isCheckCrc())
+                if (arg.checkCrc())
                     checkPartitionCrc(grpCtx, part, cpFlag);
 
                 GridIterator<CacheDataRow> it = grpCtx.offheap().partitionIterator(part.id());
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/visor/verify/VisorIdleVerifyDumpTaskArg.java b/modules/core/src/main/java/org/apache/ignite/internal/visor/verify/VisorIdleVerifyDumpTaskArg.java
index 4224dc2..08aecb5 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/visor/verify/VisorIdleVerifyDumpTaskArg.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/visor/verify/VisorIdleVerifyDumpTaskArg.java
@@ -31,12 +31,6 @@ public class VisorIdleVerifyDumpTaskArg extends VisorIdleVerifyTaskArg {
     /** */
     private static final long serialVersionUID = 0L;
 
-    /** */
-    private boolean skipZeros;
-
-    /** Cache kind. */
-    private CacheFilterEnum cacheFilterEnum;
-
     /**
      * Default constructor.
      */
@@ -57,30 +51,14 @@ public class VisorIdleVerifyDumpTaskArg extends VisorIdleVerifyTaskArg {
         CacheFilterEnum cacheFilterEnum,
         boolean checkCrc
     ) {
-        super(caches, excludeCaches, checkCrc);
-        this.skipZeros = skipZeros;
-        this.cacheFilterEnum = cacheFilterEnum;
-    }
-
-    /**
-     * @return Skip zeros partitions.
-     */
-    public boolean isSkipZeros() {
-        return skipZeros;
-    }
-
-    /**
-     * @return Kind fo cache.
-     */
-    public CacheFilterEnum getCacheFilterEnum() {
-        return cacheFilterEnum;
+        super(caches, excludeCaches, skipZeros, cacheFilterEnum, checkCrc);
     }
 
     /** {@inheritDoc} */
     @Override protected void writeExternalData(ObjectOutput out) throws IOException {
         super.writeExternalData(out);
 
-        out.writeBoolean(skipZeros);
+        out.writeBoolean(skipZeros());
 
         /**
          * Since protocol version 2 we must save class instance new fields to end of output object. It's needs for
@@ -89,11 +67,11 @@ public class VisorIdleVerifyDumpTaskArg extends VisorIdleVerifyTaskArg {
          * TODO: https://issues.apache.org/jira/browse/IGNITE-10932 Will remove in 3.0
          */
         if (instanceOfCurrentClass()) {
-            U.writeEnum(out, cacheFilterEnum);
+            U.writeEnum(out, cacheFilterEnum());
 
-            U.writeCollection(out, getExcludeCaches());
+            U.writeCollection(out, excludeCaches());
 
-            out.writeBoolean(isCheckCrc());
+            out.writeBoolean(checkCrc());
         }
     }
 
@@ -104,7 +82,7 @@ public class VisorIdleVerifyDumpTaskArg extends VisorIdleVerifyTaskArg {
     ) throws IOException, ClassNotFoundException {
         super.readExternalData(protoVer, in);
 
-        skipZeros = in.readBoolean();
+        skipZeros(in.readBoolean());
 
         /**
          * Since protocol version 2 we must read class instance new fields from end of input object. It's needs for
@@ -114,9 +92,9 @@ public class VisorIdleVerifyDumpTaskArg extends VisorIdleVerifyTaskArg {
          */
         if (instanceOfCurrentClass()) {
             if (protoVer >= V2)
-                cacheFilterEnum = CacheFilterEnum.fromOrdinal(in.readByte());
+                cacheFilterEnum(CacheFilterEnum.fromOrdinal(in.readByte()));
             else
-                cacheFilterEnum = CacheFilterEnum.DEFAULT;
+                cacheFilterEnum(CacheFilterEnum.DEFAULT);
 
             if (protoVer >= V2)
                 excludeCaches(U.readSet(in));
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/visor/verify/VisorIdleVerifyTask.java b/modules/core/src/main/java/org/apache/ignite/internal/visor/verify/VisorIdleVerifyTask.java
index e67c681..164712f 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/visor/verify/VisorIdleVerifyTask.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/visor/verify/VisorIdleVerifyTask.java
@@ -73,7 +73,7 @@ public class VisorIdleVerifyTask extends VisorOneNodeTask<VisorIdleVerifyTaskArg
         /** {@inheritDoc} */
         @Override protected VisorIdleVerifyTaskResult run(VisorIdleVerifyTaskArg arg) throws IgniteException {
             if (fut == null) {
-                fut = ignite.compute().executeAsync(VerifyBackupPartitionsTask.class, arg.getCaches());
+                fut = ignite.compute().executeAsync(VerifyBackupPartitionsTask.class, arg.caches());
 
                 if (!fut.isDone()) {
                     jobCtx.holdcc();
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/visor/verify/VisorIdleVerifyTaskArg.java b/modules/core/src/main/java/org/apache/ignite/internal/visor/verify/VisorIdleVerifyTaskArg.java
index 2bcf4bf..1f04bfc 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/visor/verify/VisorIdleVerifyTaskArg.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/visor/verify/VisorIdleVerifyTaskArg.java
@@ -42,6 +42,12 @@ public class VisorIdleVerifyTaskArg extends VisorDataTransferObject {
     /** Check CRC */
     private boolean checkCrc;
 
+    /** */
+    private boolean skipZeros;
+
+    /** Cache kind. */
+    private CacheFilterEnum cacheFilterEnum;
+
     /**
      * Default constructor.
      */
@@ -52,11 +58,21 @@ public class VisorIdleVerifyTaskArg extends VisorDataTransferObject {
     /**
      * @param caches Caches.
      * @param excludeCaches Exclude caches or group.
+     * @param skipZeros Skip zeros partitions.
+     * @param cacheFilterEnum Cache kind.
      * @param checkCrc Check CRC sum on stored pages on disk.
      */
-    public VisorIdleVerifyTaskArg(Set<String> caches, Set<String> excludeCaches, boolean checkCrc) {
+    public VisorIdleVerifyTaskArg(
+        Set<String> caches,
+        Set<String> excludeCaches,
+        boolean skipZeros,
+        CacheFilterEnum cacheFilterEnum,
+        boolean checkCrc
+    ) {
         this.caches = caches;
         this.excludeCaches = excludeCaches;
+        this.skipZeros = skipZeros;
+        this.cacheFilterEnum = (cacheFilterEnum == null ? CacheFilterEnum.DEFAULT : cacheFilterEnum);
         this.checkCrc = checkCrc;
     }
 
@@ -77,27 +93,27 @@ public class VisorIdleVerifyTaskArg extends VisorDataTransferObject {
     }
 
     /** */
-    public boolean isCheckCrc() {
+    public boolean checkCrc() {
         return checkCrc;
     }
 
     /**
      * @return Caches.
      */
-    public Set<String> getCaches() {
+    public Set<String> caches() {
         return caches;
     }
 
     /**
      * @return Exclude caches or groups.
      */
-    public Set<String> getExcludeCaches() {
+    public Set<String> excludeCaches() {
         return excludeCaches;
     }
 
     /** {@inheritDoc} */
     @Override public byte getProtocolVersion() {
-        return V3;
+        return V4;
     }
 
     /** {@inheritDoc} */
@@ -114,6 +130,10 @@ public class VisorIdleVerifyTaskArg extends VisorDataTransferObject {
             U.writeCollection(out, excludeCaches);
 
             out.writeBoolean(checkCrc);
+
+            out.writeBoolean(skipZeros);
+
+            U.writeEnum(out, cacheFilterEnum);
         }
     }
 
@@ -136,6 +156,14 @@ public class VisorIdleVerifyTaskArg extends VisorDataTransferObject {
 
             if (protoVer >= V3)
                 checkCrc = in.readBoolean();
+
+            if (protoVer >= V4) {
+                skipZeros = in.readBoolean();
+
+                CacheFilterEnum cfe = CacheFilterEnum.fromOrdinal(in.readByte());
+
+                cacheFilterEnum = (cfe == null ? CacheFilterEnum.DEFAULT : cfe);
+            }
         }
     }
 
@@ -149,6 +177,30 @@ public class VisorIdleVerifyTaskArg extends VisorDataTransferObject {
         this.checkCrc = checkCrc;
     }
 
+    /**
+     * @return Skip zeros partitions.
+     */
+    public boolean skipZeros() {
+        return skipZeros;
+    }
+
+    /** */
+    protected void skipZeros(boolean skipZeros) {
+        this.skipZeros = skipZeros;
+    }
+
+    /** */
+    protected void cacheFilterEnum(CacheFilterEnum cacheFilterEnum) {
+        this.cacheFilterEnum = (cacheFilterEnum == null ? CacheFilterEnum.DEFAULT : cacheFilterEnum);
+    }
+
+    /**
+     * @return Kind fo cache.
+     */
+    public CacheFilterEnum cacheFilterEnum() {
+        return cacheFilterEnum;
+    }
+
     /** {@inheritDoc} */
     @Override public String toString() {
         return S.toString(VisorIdleVerifyTaskArg.class, this);
diff --git a/modules/core/src/test/java/org/apache/ignite/testframework/GridTestUtils.java b/modules/core/src/test/java/org/apache/ignite/testframework/GridTestUtils.java
index 0d24c7c..e794f0a 100644
--- a/modules/core/src/test/java/org/apache/ignite/testframework/GridTestUtils.java
+++ b/modules/core/src/test/java/org/apache/ignite/testframework/GridTestUtils.java
@@ -330,7 +330,7 @@ public final class GridTestUtils {
      */
     public static void assertContains(@Nullable IgniteLogger log, String str, String substr) {
         try {
-            assertTrue(str.contains(substr));
+            assertTrue(str != null && str.contains(substr));
         } catch (AssertionError e) {
             U.warn(log, String.format("String does not contain substring: '%s':", substr));
             U.warn(log, "String:");
diff --git a/modules/core/src/test/java/org/apache/ignite/util/GridCommandHandlerTest.java b/modules/core/src/test/java/org/apache/ignite/util/GridCommandHandlerTest.java
index 3dc0a9c..e4ea004 100644
--- a/modules/core/src/test/java/org/apache/ignite/util/GridCommandHandlerTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/util/GridCommandHandlerTest.java
@@ -1490,8 +1490,8 @@ public class GridCommandHandlerTest extends GridCommandHandlerAbstractTest {
 
         testCacheIdleVerifyMultipleCacheFilterOptionsCommon(
             true,
-            "idle_verify check has finished, found 100 partitions",
-            "idle_verify task was executed with the following args: --cache-filter SYSTEM --exclude-caches wrong.* ",
+            "idle_verify check has finished, found",
+            "idle_verify task was executed with the following args: caches=[], excluded=[wrong.*], cacheFilter=[SYSTEM]",
             "--cache", "idle_verify", "--dump", "--cache-filter", "SYSTEM", "--exclude-caches", "wrong.*"
         );
         testCacheIdleVerifyMultipleCacheFilterOptionsCommon(
@@ -1526,7 +1526,7 @@ public class GridCommandHandlerTest extends GridCommandHandlerAbstractTest {
         );
         testCacheIdleVerifyMultipleCacheFilterOptionsCommon(
             true,
-            "There are no caches matching given filter options.",
+            "There are no caches matching given filter options",
             null,
             "--cache", "idle_verify", "--exclude-caches", ".*"
         );
@@ -1548,6 +1548,12 @@ public class GridCommandHandlerTest extends GridCommandHandlerAbstractTest {
             null,
             "--cache", "idle_verify", "--dump", "--cache-filter", "PERSISTENT"
         );
+        testCacheIdleVerifyMultipleCacheFilterOptionsCommon(
+            true,
+            "There are no caches matching given filter options.",
+            null,
+            "--cache", "idle_verify", "--cache-filter", "NOT_PERSISTENT"
+        );
     }
 
     /** */
@@ -1692,14 +1698,33 @@ public class GridCommandHandlerTest extends GridCommandHandlerAbstractTest {
 
         injectTestSystemOut();
 
-        corruptingAndCheckDefaultCache(ignite, "USER");
+        corruptingAndCheckDefaultCache(ignite, "USER", true);
+    }
+
+    /**
+     * Tests that idle verify print partitions info while launched without dump option.
+     *
+     * @throws Exception If failed.
+     */
+    @Test
+    public void testCacheIdleVerifyForCorruptedData() throws Exception {
+        IgniteEx ignite = startGrids(3);
+
+        ignite.cluster().active(true);
+
+        createCacheAndPreload(ignite, 100);
+
+        injectTestSystemOut();
+
+        corruptingAndCheckDefaultCache(ignite, "USER", false);
     }
 
     /**
      * @param ignite Ignite.
      * @param cacheFilter cacheFilter.
+     * @param dump Whether idle_verify should be launched with dump option or not.
      */
-    private void corruptingAndCheckDefaultCache(IgniteEx ignite, String cacheFilter) throws IOException {
+    private void corruptingAndCheckDefaultCache(IgniteEx ignite, String cacheFilter, boolean dump) throws IOException {
         injectTestSystemOut();
 
         GridCacheContext<Object, Object> cacheCtx = ignite.cachex(DEFAULT_CACHE_NAME).context();
@@ -1708,19 +1733,28 @@ public class GridCommandHandlerTest extends GridCommandHandlerAbstractTest {
 
         corruptDataEntry(cacheCtx, cacheCtx.config().getAffinity().partitions() / 2, false, true);
 
-        assertEquals(EXIT_CODE_OK, execute("--cache", "idle_verify", "--dump", "--cache-filter", cacheFilter));
+        String resReport = null;
 
-        Matcher fileNameMatcher = dumpFileNameMatcher();
+        if (dump) {
+            assertEquals(EXIT_CODE_OK, execute("--cache", "idle_verify", "--dump", "--cache-filter", cacheFilter));
 
-        if (fileNameMatcher.find()) {
-            String dumpWithConflicts = new String(Files.readAllBytes(Paths.get(fileNameMatcher.group(1))));
+            Matcher fileNameMatcher = dumpFileNameMatcher();
 
-            log.info(dumpWithConflicts);
+            if (fileNameMatcher.find()) {
+                resReport = new String(Files.readAllBytes(Paths.get(fileNameMatcher.group(1))));
 
-            assertContains(log, dumpWithConflicts, "found 2 conflict partitions: [counterConflicts=1, hashConflicts=1]");
+                log.info(resReport);
+            }
+            else
+                fail("Should be found dump with conflicts");
         }
-        else
-            fail("Should be found dump with conflicts");
+        else {
+            assertEquals(EXIT_CODE_OK, execute("--cache", "idle_verify", "--cache-filter", cacheFilter));
+
+            resReport = testOut.toString();
+        }
+
+        assertContains(log, resReport, "found 2 conflict partitions: [counterConflicts=1, hashConflicts=1]");
     }
 
     /**
@@ -2000,7 +2034,7 @@ public class GridCommandHandlerTest extends GridCommandHandlerAbstractTest {
 
         createCacheAndPreload(ignite, 100);
 
-        corruptingAndCheckDefaultCache(ignite, "PERSISTENT");
+        corruptingAndCheckDefaultCache(ignite, "PERSISTENT", true);
     }
 
     /**
@@ -2091,7 +2125,7 @@ public class GridCommandHandlerTest extends GridCommandHandlerAbstractTest {
         if (fileNameMatcher.find()) {
             String dumpWithConflicts = new String(Files.readAllBytes(Paths.get(fileNameMatcher.group(1))));
 
-            assertContains(log, dumpWithConflicts, "There are no caches matching given filter options.");
+            assertContains(log, dumpWithConflicts, "There are no caches matching given filter options");
         }
         else
             fail("Should be found dump with conflicts");