/** @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. */
  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 Thrown if test failed. */
  public void testC() throws Exception {
    final Collection<SampleBean> set = new GridConcurrentWeakHashSet<>();

    int threadCnt = 2;

    final int cnt = 5;

    final CountDownLatch start = new CountDownLatch(1);
    final CountDownLatch stop = new CountDownLatch(threadCnt);

    Runnable r =
        new Runnable() {
          @Override
          public void run() {
            try {
              start.await();

              for (int i = 0; i < cnt; i++) {
                for (int j = 0; j < cnt; j++) set.add(new SampleBean(i));
              }
            } catch (Exception e) {
              error(e.getMessage());
            }

            stop.countDown();
          }
        };

    for (int i = 0; i < threadCnt; i++) new Thread(r).start();

    start.countDown();

    stop.await();

    assert set.size() == cnt;

    gc();

    assert set.isEmpty();
  }
  /** @throws Exception Thrown if test failed. */
  public void testD() throws Exception {
    final Collection<SampleBean> set = new GridConcurrentWeakHashSet<>();

    final int cnt = 100;

    final CountDownLatch start = new CountDownLatch(1);
    final CountDownLatch stop = new CountDownLatch(3);

    new Thread() {
      @Override
      public void run() {
        try {
          start.await();

          for (int i = 0; i < cnt; i++) {
            for (int j = 0; j < cnt; j++) set.add(new SampleBean(i));
          }
        } catch (Exception e) {
          error(e.getMessage());
        }

        stop.countDown();
      }
    }.start();

    new Thread() {
      @Override
      public void run() {
        try {
          start.await();

          for (int i = 0; i < cnt; i++) {
            for (int j = 0; j < cnt; j++) set.remove(new SampleBean(i));
          }
        } catch (Exception e) {
          error(e.getMessage());
        }

        stop.countDown();
      }
    }.start();

    new Thread() {
      @SuppressWarnings({"UnusedDeclaration"})
      @Override
      public void run() {
        try {
          start.await();

          while (stop.getCount() > 1) {
            for (SampleBean b : set) {
              // No-op.
            }
          }
        } catch (Exception e) {
          error(e.getMessage());
        }

        stop.countDown();
      }
    }.start();

    start.countDown();

    stop.await();

    gc();

    assert set.isEmpty();
  }