/**
 * 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.mapreduce;

import java.util.Random;

import org.junit.Test;
import static org.junit.Assert.*;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.hadoop.mapreduce.counters.LimitExceededException;
import org.apache.hadoop.mapreduce.counters.Limits;

/**
 * TestCounters checks the sanity and recoverability of {@code Counters}
 */
public class TestCounters {

  static final Log LOG = LogFactory.getLog(TestCounters.class);

  /**
   * Verify counter value works
   */
  @Test
  public void testCounterValue() {
    final int NUMBER_TESTS = 100;
    final int NUMBER_INC = 10;
    final Random rand = new Random();
    for (int i = 0; i < NUMBER_TESTS; i++) {
      long initValue = rand.nextInt();
      long expectedValue = initValue;
      Counter counter = new Counters().findCounter("test", "foo");
      counter.setValue(initValue);
      assertEquals("Counter value is not initialized correctly",
          expectedValue, counter.getValue());
      for (int j = 0; j < NUMBER_INC; j++) {
        int incValue = rand.nextInt();
        counter.increment(incValue);
        expectedValue += incValue;
        assertEquals("Counter value is not incremented correctly",
            expectedValue, counter.getValue());
      }
      expectedValue = rand.nextInt();
      counter.setValue(expectedValue);
      assertEquals("Counter value is not set correctly",
          expectedValue, counter.getValue());
    }
  }

  @Test public void testLimits() {
    for (int i = 0; i < 3; ++i) {
      // make sure limits apply to separate containers
      testMaxCounters(new Counters());
      testMaxGroups(new Counters());
    }
  }
  
  @Test
  public void testCountersIncrement() {
    Counters fCounters = new Counters();
    Counter fCounter = fCounters.findCounter(FRAMEWORK_COUNTER);
    fCounter.setValue(100);
    Counter gCounter = fCounters.findCounter("test", "foo");
    gCounter.setValue(200);

    Counters counters = new Counters();
    counters.incrAllCounters(fCounters);
    Counter counter;
    for (CounterGroup cg : fCounters) {
      CounterGroup group = counters.getGroup(cg.getName());
      if (group.getName().equals("test")) {
        counter = counters.findCounter("test", "foo");
        assertEquals(200, counter.getValue());
      } else {
        counter = counters.findCounter(FRAMEWORK_COUNTER);
        assertEquals(100, counter.getValue());
      }
    }
  }

  static final Enum<?> FRAMEWORK_COUNTER = TaskCounter.CPU_MILLISECONDS;
  static final long FRAMEWORK_COUNTER_VALUE = 8;
  static final String FS_SCHEME = "HDFS";
  static final FileSystemCounter FS_COUNTER = FileSystemCounter.BYTES_READ;
  static final long FS_COUNTER_VALUE = 10;

  private void testMaxCounters(final Counters counters) {
    LOG.info("counters max="+ Limits.COUNTERS_MAX);
    for (int i = 0; i < Limits.COUNTERS_MAX; ++i) {
      counters.findCounter("test", "test"+ i);
    }
    setExpected(counters);
    shouldThrow(LimitExceededException.class, new Runnable() {
      public void run() {
        counters.findCounter("test", "bad");
      }
    });
    checkExpected(counters);
  }

  private void testMaxGroups(final Counters counters) {
    LOG.info("counter groups max="+ Limits.GROUPS_MAX);
    for (int i = 0; i < Limits.GROUPS_MAX; ++i) {
      // assuming COUNTERS_MAX > GROUPS_MAX
      counters.findCounter("test"+ i, "test");
    }
    setExpected(counters);
    shouldThrow(LimitExceededException.class, new Runnable() {
      public void run() {
        counters.findCounter("bad", "test");
      }
    });
    checkExpected(counters);
  }

  private void setExpected(Counters counters) {
    counters.findCounter(FRAMEWORK_COUNTER).setValue(FRAMEWORK_COUNTER_VALUE);
    counters.findCounter(FS_SCHEME, FS_COUNTER).setValue(FS_COUNTER_VALUE);
  }

  private void checkExpected(Counters counters) {
    assertEquals(FRAMEWORK_COUNTER_VALUE,
                 counters.findCounter(FRAMEWORK_COUNTER).getValue());
    assertEquals(FS_COUNTER_VALUE,
                 counters.findCounter(FS_SCHEME, FS_COUNTER).getValue());
  }

  private void shouldThrow(Class<? extends Exception> ecls, Runnable runnable) {
    try {
      runnable.run();
    } catch (Exception e) {
      assertSame(ecls, e.getClass());
      LOG.info("got expected: "+ e);
      return;
    }
    assertTrue("Should've thrown "+ ecls.getSimpleName(), false);
  }
}
