/*
 * 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.hadoop.metrics2.source;

import org.apache.hadoop.util.GcTimeMonitor;
import org.junit.After;
import org.junit.Assert;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.Timeout;

import static org.mockito.Mockito.*;
import static org.apache.hadoop.test.MetricsAsserts.*;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.metrics2.MetricsCollector;
import org.apache.hadoop.metrics2.MetricsRecordBuilder;
import org.apache.hadoop.service.ServiceOperations;
import org.apache.hadoop.service.ServiceStateException;
import org.apache.hadoop.test.GenericTestUtils;
import org.apache.hadoop.util.JvmPauseMonitor;

import java.util.ArrayList;
import java.util.List;

import static org.apache.hadoop.metrics2.source.JvmMetricsInfo.*;
import static org.apache.hadoop.metrics2.impl.MsInfo.*;

public class TestJvmMetrics {

  @Rule
  public Timeout timeout = new Timeout(30000);
  private JvmPauseMonitor pauseMonitor;
  private GcTimeMonitor gcTimeMonitor;

  /**
   * Robust shutdown of the monitors if they haven't been stopped already.
   */
  @After
  public void teardown() {
    ServiceOperations.stop(pauseMonitor);
    if (gcTimeMonitor != null) {
      gcTimeMonitor.shutdown();
    }
  }

  @Test
  public void testJvmPauseMonitorPresence() {
    pauseMonitor = new JvmPauseMonitor();
    pauseMonitor.init(new Configuration());
    pauseMonitor.start();
    JvmMetrics jvmMetrics = new JvmMetrics("test", "test");
    jvmMetrics.setPauseMonitor(pauseMonitor);
    MetricsRecordBuilder rb = getMetrics(jvmMetrics);
    MetricsCollector mc = rb.parent();

    verify(mc).addRecord(JvmMetrics);
    verify(rb).tag(ProcessName, "test");
    verify(rb).tag(SessionId, "test");
    for (JvmMetricsInfo info : JvmMetricsInfo.values()) {
      if (info.name().startsWith("Mem")) {
        verify(rb).addGauge(eq(info), anyFloat());
      } else if (info.name().startsWith("Gc") &&
          !info.name().equals("GcTimePercentage")) {
        verify(rb).addCounter(eq(info), anyLong());
      } else if (info.name().startsWith("Threads")) {
        verify(rb).addGauge(eq(info), anyInt());
      } else if (info.name().startsWith("Log")) {
        verify(rb).addCounter(eq(info), anyLong());
      }
    }
  }

  @Test
  public void testGcTimeMonitorPresence() {
    gcTimeMonitor = new GcTimeMonitor(60000, 1000, 70, null);
    gcTimeMonitor.start();
    JvmMetrics jvmMetrics = new JvmMetrics("test", "test");
    jvmMetrics.setGcTimeMonitor(gcTimeMonitor);
    MetricsRecordBuilder rb = getMetrics(jvmMetrics);
    MetricsCollector mc = rb.parent();

    verify(mc).addRecord(JvmMetrics);
    verify(rb).tag(ProcessName, "test");
    verify(rb).tag(SessionId, "test");
    for (JvmMetricsInfo info : JvmMetricsInfo.values()) {
      if (info.name().equals("GcTimePercentage")) {
        verify(rb).addGauge(eq(info), anyInt());
      }
    }
  }

  @Test
  public void testDoubleStop() throws Throwable {
    pauseMonitor = new JvmPauseMonitor();
    pauseMonitor.init(new Configuration());
    pauseMonitor.start();
    pauseMonitor.stop();
    pauseMonitor.stop();
  }

  @Test
  public void testDoubleStart() throws Throwable {
    pauseMonitor = new JvmPauseMonitor();
    pauseMonitor.init(new Configuration());
    pauseMonitor.start();
    pauseMonitor.start();
    pauseMonitor.stop();
  }

  @Test
  public void testStopBeforeStart() throws Throwable {
    pauseMonitor = new JvmPauseMonitor();
    try {
      pauseMonitor.init(new Configuration());
      pauseMonitor.stop();
      pauseMonitor.start();
      Assert.fail("Expected an exception, got " + pauseMonitor);
    } catch (ServiceStateException e) {
      GenericTestUtils.assertExceptionContains("cannot enter state", e);
    }
  }

  @Test
  public void testStopBeforeInit() throws Throwable {
    pauseMonitor = new JvmPauseMonitor();
    try {
      pauseMonitor.stop();
      pauseMonitor.init(new Configuration());
      Assert.fail("Expected an exception, got " + pauseMonitor);
    } catch (ServiceStateException e) {
      GenericTestUtils.assertExceptionContains("cannot enter state", e);
    }
  }

  @Test
  public void testGcTimeMonitor() {
    class Alerter implements GcTimeMonitor.GcTimeAlertHandler {
      private volatile int numAlerts;
      private volatile int maxGcTimePercentage;
      @Override
      public void alert(GcTimeMonitor.GcData gcData) {
        numAlerts++;
        if (gcData.getGcTimePercentage() > maxGcTimePercentage) {
          maxGcTimePercentage = gcData.getGcTimePercentage();
        }
      }
    }
    Alerter alerter = new Alerter();

    int alertGcPerc = 10;  // Alerter should be called if GC takes >= 10%
    gcTimeMonitor = new GcTimeMonitor(60*1000, 100, alertGcPerc, alerter);
    gcTimeMonitor.start();

    int maxGcTimePercentage = 0;
    long gcCount = 0;

    // Generate a lot of garbage for some time and verify that the monitor
    // reports at least some percentage of time in GC pauses, and that the
    // alerter is invoked at least once.

    List<String> garbageStrings = new ArrayList<>();

    long startTime = System.currentTimeMillis();
    // Run this for at least 1 sec for our monitor to collect enough data
    while (System.currentTimeMillis() - startTime < 1000) {
      for (int j = 0; j < 100000; j++) {
        garbageStrings.add(
            "Long string prefix just to fill memory with garbage " + j);
      }
      garbageStrings.clear();
      System.gc();

      GcTimeMonitor.GcData gcData = gcTimeMonitor.getLatestGcData();
      int gcTimePercentage = gcData.getGcTimePercentage();
      if (gcTimePercentage > maxGcTimePercentage) {
        maxGcTimePercentage = gcTimePercentage;
      }
      gcCount = gcData.getAccumulatedGcCount();
    }

    Assert.assertTrue(maxGcTimePercentage > 0);
    Assert.assertTrue(gcCount > 0);
    Assert.assertTrue(alerter.numAlerts > 0);
    Assert.assertTrue(alerter.maxGcTimePercentage >= alertGcPerc);
  }
}
