/** @throws Exception If failed. */
  public void testClusterNodeMetrics() throws Exception {
    final Ignite ignite0 = grid();
    final Ignite ignite1 = startGrid(1);

    GridTestUtils.waitForCondition(
        new GridAbsPredicate() {
          @Override
          public boolean apply() {
            return ignite0.cluster().nodes().size() == 2 && ignite1.cluster().nodes().size() == 2;
          }
        },
        3000L);

    ClusterMetrics metrics0 = ignite0.cluster().localNode().metrics();

    ClusterMetrics nodesMetrics =
        ignite0
            .cluster()
            .forNode(ignite0.cluster().localNode(), ignite1.cluster().localNode())
            .metrics();

    assertEquals(metrics0.getTotalCpus(), nodesMetrics.getTotalCpus());
    assertEquals(1, metrics0.getTotalNodes());
    assertEquals(2, nodesMetrics.getTotalNodes());

    assert metrics0.getHeapMemoryUsed() > 0;
    assert metrics0.getHeapMemoryTotal() > 0;
    assert metrics0.getNonHeapMemoryMaximum() > 0;
  }
  /** @throws Exception If failed. */
  public void testIoMetrics() throws Exception {
    Ignite ignite0 = grid();
    Ignite ignite1 = startGrid(1);

    Object msg = new TestMessage();

    int size = ignite0.configuration().getMarshaller().marshal(msg).length;

    assert size > MSG_SIZE;

    final CountDownLatch latch = new CountDownLatch(MSG_CNT);

    ignite0
        .message()
        .localListen(
            null,
            new MessagingListenActor<TestMessage>() {
              @Override
              protected void receive(UUID nodeId, TestMessage rcvMsg) throws Throwable {
                latch.countDown();
              }
            });

    ignite1
        .message()
        .localListen(
            null,
            new MessagingListenActor<TestMessage>() {
              @Override
              protected void receive(UUID nodeId, TestMessage rcvMsg) throws Throwable {
                respond(rcvMsg);
              }
            });

    for (int i = 0; i < MSG_CNT; i++) message(ignite0.cluster().forRemotes()).send(null, msg);

    latch.await();

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

    info("Node 0 metrics: " + metrics);

    // Time sync messages are being sent.
    assert metrics.getSentMessagesCount() >= MSG_CNT;
    assert metrics.getSentBytesCount() > size * MSG_CNT;
    assert metrics.getReceivedMessagesCount() >= MSG_CNT;
    assert metrics.getReceivedBytesCount() > size * MSG_CNT;

    metrics = ignite1.cluster().localNode().metrics();

    info("Node 1 metrics: " + metrics);

    // Time sync messages are being sent.
    assert metrics.getSentMessagesCount() >= MSG_CNT;
    assert metrics.getSentBytesCount() > size * MSG_CNT;
    assert metrics.getReceivedMessagesCount() >= MSG_CNT;
    assert metrics.getReceivedBytesCount() > size * MSG_CNT;
  }
  /** @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("unchecked")
  public void testDeployment() throws Exception {
    Ignite ignite = startGrid(GRID_NAME);

    Class cls = getExternalClassLoader().loadClass(TEST_TASK_1);

    compute(ignite.cluster().forRemotes()).execute(cls, null);

    stopGrid(GRID_NAME);

    ignite = startGrid(GRID_NAME);

    cls = getExternalClassLoader().loadClass(TEST_TASK_2);

    compute(ignite.cluster().forRemotes()).execute(cls, null);

    stopGrid(GRID_NAME);
  }
  /** @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);
    }
  }