/** @throws Exception If failed. */
  public void testInternalTaskMetrics() throws Exception {
    Ignite ignite = grid();

    // Visor task is internal and should not affect metrics.
    ignite.compute().withName("visor-test-task").execute(new TestInternalTask(), "testArg");

    // Let metrics update twice.
    final CountDownLatch latch = new CountDownLatch(2);

    ignite
        .events()
        .localListen(
            new IgnitePredicate<Event>() {
              @Override
              public boolean apply(Event evt) {
                assert evt.type() == EVT_NODE_METRICS_UPDATED;

                latch.countDown();

                return true;
              }
            },
            EVT_NODE_METRICS_UPDATED);

    // Wait for metrics update.
    latch.await();

    ClusterMetrics metrics = ignite.cluster().localNode().metrics();

    info("Node metrics: " + metrics);

    assert metrics.getAverageActiveJobs() == 0;
    assert metrics.getAverageCancelledJobs() == 0;
    assert metrics.getAverageJobExecuteTime() == 0;
    assert metrics.getAverageJobWaitTime() == 0;
    assert metrics.getAverageRejectedJobs() == 0;
    assert metrics.getAverageWaitingJobs() == 0;
    assert metrics.getCurrentActiveJobs() == 0;
    assert metrics.getCurrentCancelledJobs() == 0;
    assert metrics.getCurrentJobExecuteTime() == 0;
    assert metrics.getCurrentJobWaitTime() == 0;
    assert metrics.getCurrentWaitingJobs() == 0;
    assert metrics.getMaximumActiveJobs() == 0;
    assert metrics.getMaximumCancelledJobs() == 0;
    assert metrics.getMaximumJobExecuteTime() == 0;
    assert metrics.getMaximumJobWaitTime() == 0;
    assert metrics.getMaximumRejectedJobs() == 0;
    assert metrics.getMaximumWaitingJobs() == 0;
    assert metrics.getTotalCancelledJobs() == 0;
    assert metrics.getTotalExecutedJobs() == 0;
    assert metrics.getTotalRejectedJobs() == 0;
    assert metrics.getTotalExecutedTasks() == 0;

    assertTrue(
        "MaximumJobExecuteTime="
            + metrics.getMaximumJobExecuteTime()
            + " is less than AverageJobExecuteTime="
            + metrics.getAverageJobExecuteTime(),
        metrics.getMaximumJobExecuteTime() >= metrics.getAverageJobExecuteTime());
  }
  /** @throws Exception If failed. */
  @SuppressWarnings({"AssignmentToCatchBlockParameter"})
  public void testCancel() throws Exception {
    Ignite ignite = G.ignite(getTestGridName());

    ignite
        .compute()
        .localDeployTask(GridCancelTestTask.class, GridCancelTestTask.class.getClassLoader());

    ComputeTaskFuture<?> res0 =
        executeAsync(
            ignite.compute().withTimeout(maxJobExecTime * 2),
            GridCancelTestTask.class.getName(),
            null);

    try {
      Object res = res0.get();

      info("Cancel test result: " + res);

      synchronized (mux) {
        // Every execute must be called.
        assert execCnt <= SPLIT_COUNT : "Invalid execute count: " + execCnt;

        // Job returns 1 if was cancelled.
        assert (Integer) res <= SPLIT_COUNT : "Invalid task result: " + res;

        // Should be exactly the same as Jobs number.
        assert cancelCnt <= SPLIT_COUNT : "Invalid cancel count: " + cancelCnt;

        // One per start and one per stop and some that come with heartbeats.
        assert colResolutionCnt > SPLIT_COUNT + 1
            : "Invalid collision resolution count: " + colResolutionCnt;
      }
    } catch (ComputeTaskTimeoutException e) {
      error("Task execution got timed out.", e);
    } catch (Exception e) {
      assert e.getCause() != null;

      if (e.getCause() instanceof IgniteCheckedException) e = (Exception) e.getCause();

      if (e.getCause() instanceof IOException) e = (Exception) e.getCause();

      assert e.getCause() instanceof InterruptedException
          : "Invalid exception cause: " + e.getCause();
    }
  }
  /** @throws Exception if error occur. */
  @SuppressWarnings("unchecked")
  private void checkGar() throws Exception {
    initGar = true;

    String garDir = "modules/extdata/p2p/deploy";
    String garFileName = "p2p.gar";

    File origGarPath = U.resolveIgnitePath(garDir + '/' + garFileName);

    File tmpPath = new File(System.getProperty("java.io.tmpdir"), UUID.randomUUID().toString());

    if (!tmpPath.mkdir()) throw new IOException("Can not create temp directory");

    try {
      File newGarFile = new File(tmpPath, garFileName);

      U.copy(origGarPath, newGarFile, false);

      assert newGarFile.exists();

      try {
        garFile = "file:///" + tmpPath.getAbsolutePath();

        try {
          Ignite ignite1 = startGrid(1);
          Ignite ignite2 = startGrid(2);

          Integer res =
              ignite1
                  .compute()
                  .<UUID, Integer>execute(TASK_NAME, ignite2.cluster().localNode().id());

          assert res != null;
        } finally {
          stopGrid(1);
          stopGrid(2);
        }
      } finally {
        if (newGarFile != null && !newGarFile.delete()) error("Can not delete temp gar file");
      }
    } finally {
      if (!tmpPath.delete()) error("Can not delete temp directory");
    }
  }
  /**
   * Test what happens if peer class loading is disabled.
   *
   * @throws Exception if error occur.
   */
  @SuppressWarnings("unchecked")
  private void checkClassNotFound() throws Exception {
    initGar = false;

    try {
      Ignite ignite1 = startGrid(1);
      Ignite ignite2 = startGrid(2);

      Class task = extLdr.loadClass(TASK_NAME);

      try {
        ignite1.compute().execute(task, ignite2.cluster().localNode().id());

        assert false;
      } catch (IgniteException e) {
        info("Received expected exception: " + e);
      }
    } finally {
      stopGrid(1);
      stopGrid(2);
    }
  }