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

import java.io.IOException;

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

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.mapreduce.StatusReporter;
import org.apache.hadoop.mapreduce.TaskAttemptID;
import org.apache.hadoop.mapreduce.TaskInputOutputContext;
import org.apache.hadoop.mapreduce.TaskType;
import org.apache.hadoop.mapreduce.server.tasktracker.TTConfig;
import org.apache.hadoop.mapreduce.task.MapContextImpl;
import org.apache.hadoop.mapreduce.util.ResourceCalculatorPlugin;
import org.apache.hadoop.tools.rumen.ResourceUsageMetrics;
import org.apache.hadoop.mapred.DummyResourceCalculatorPlugin;
import org.apache.hadoop.mapred.gridmix.LoadJob.ResourceUsageMatcherRunner;
import org.apache.hadoop.mapred.gridmix.emulators.resourceusage.CumulativeCpuUsageEmulatorPlugin;
import org.apache.hadoop.mapred.gridmix.emulators.resourceusage.ResourceUsageEmulatorPlugin;
import org.apache.hadoop.mapred.gridmix.emulators.resourceusage.ResourceUsageMatcher;
import org.apache.hadoop.mapred.gridmix.emulators.resourceusage.CumulativeCpuUsageEmulatorPlugin.DefaultCpuUsageEmulator;

/**
 * Test Gridmix's resource emulator framework and supported plugins.
 */
public class TestResourceUsageEmulators {
  /**
   * A {@link ResourceUsageEmulatorPlugin} implementation for testing purpose.
   * It essentially creates a file named 'test' in the test directory.
   */
  static class TestResourceUsageEmulatorPlugin 
  implements ResourceUsageEmulatorPlugin {
    static final Path rootTempDir =
        new Path(System.getProperty("test.build.data", "/tmp"));
    static final Path tempDir = 
      new Path(rootTempDir, "TestResourceUsageEmulatorPlugin");
    static final String DEFAULT_IDENTIFIER = "test";
    
    private Path touchPath = null;
    private FileSystem fs = null;
    
    @Override
    public void emulate() throws IOException, InterruptedException {
      // add some time between 2 calls to emulate()
      try {
        Thread.sleep(1000); // sleep for 1s
      } catch (Exception e){}
      
      try {
        fs.delete(touchPath, false); // delete the touch file
        //TODO Search for a better touch utility
        fs.create(touchPath).close(); // recreate it
      } catch (Exception e) {
        throw new RuntimeException(e);
      }
    }
    
    protected String getIdentifier() {
      return DEFAULT_IDENTIFIER;
    }
    
    private static Path getFilePath(String id) {
      return new Path(tempDir, id);
    }
    
    private static Path getInitFilePath(String id) {
      return new Path(tempDir, id + ".init");
    }
    
    @Override
    public void initialize(Configuration conf, ResourceUsageMetrics metrics,
        ResourceCalculatorPlugin monitor, Progressive progress) {
      // add some time between 2 calls to initialize()
      try {
        Thread.sleep(1000); // sleep for 1s
      } catch (Exception e){}
      
      try {
        fs = FileSystem.getLocal(conf);
        
        Path initPath = getInitFilePath(getIdentifier());
        fs.delete(initPath, false); // delete the old file
        fs.create(initPath).close(); // create a new one
        
        touchPath = getFilePath(getIdentifier());
        fs.delete(touchPath, false);
      } catch (Exception e) {
        
      } finally {
        if (fs != null) {
          try {
            fs.deleteOnExit(tempDir);
          } catch (IOException ioe){}
        }
      }
    }
    
    // test if the emulation framework successfully loaded this plugin
    static long testInitialization(String id, Configuration conf) 
    throws IOException {
      Path testPath = getInitFilePath(id);
      FileSystem fs = FileSystem.getLocal(conf);
      return fs.exists(testPath) 
             ? fs.getFileStatus(testPath).getModificationTime() 
             : 0;
    }
    
    // test if the emulation framework successfully loaded this plugin
    static long testEmulation(String id, Configuration conf) 
    throws IOException {
      Path testPath = getFilePath(id);
      FileSystem fs = FileSystem.getLocal(conf);
      return fs.exists(testPath) 
             ? fs.getFileStatus(testPath).getModificationTime() 
             : 0;
    }
    
    @Override
    public float getProgress() {
      try {
        return fs.exists(touchPath) ? 1.0f : 0f;
      } catch (IOException ioe) {}
      return 0f;
    }
  }
  
  /**
   * Test implementation of {@link ResourceUsageEmulatorPlugin} which creates
   * a file named 'others' in the test directory.
   */
  static class TestOthers extends TestResourceUsageEmulatorPlugin {
    static final String ID = "others";
    
    @Override
    protected String getIdentifier() {
      return ID;
    }
  }
  
  /**
   * Test implementation of {@link ResourceUsageEmulatorPlugin} which creates
   * a file named 'cpu' in the test directory.
   */
  static class TestCpu extends TestResourceUsageEmulatorPlugin {
    static final String ID = "cpu";
    
    @Override
    protected String getIdentifier() {
      return ID;
    }
  }
  
  /**
   * Test {@link ResourceUsageMatcher}.
   */
  @Test
  public void testResourceUsageMatcher() throws Exception {
    ResourceUsageMatcher matcher = new ResourceUsageMatcher();
    Configuration conf = new Configuration();
    conf.setClass(ResourceUsageMatcher.RESOURCE_USAGE_EMULATION_PLUGINS, 
                  TestResourceUsageEmulatorPlugin.class, 
                  ResourceUsageEmulatorPlugin.class);
    long currentTime = System.currentTimeMillis();
    
    matcher.configure(conf, null, null, null);
    
    matcher.matchResourceUsage();
    
    String id = TestResourceUsageEmulatorPlugin.DEFAULT_IDENTIFIER;
    long result = 
      TestResourceUsageEmulatorPlugin.testInitialization(id, conf);
    assertTrue("Resource usage matcher failed to initialize the configured"
               + " plugin", result > currentTime);
    result = TestResourceUsageEmulatorPlugin.testEmulation(id, conf);
    assertTrue("Resource usage matcher failed to load and emulate the"
               + " configured plugin", result > currentTime);
    
    // test plugin order to first emulate cpu and then others
    conf.setStrings(ResourceUsageMatcher.RESOURCE_USAGE_EMULATION_PLUGINS, 
                    TestCpu.class.getName() + "," + TestOthers.class.getName());
    
    matcher.configure(conf, null, null, null);

    // test the initialization order
    long time1 = 
           TestResourceUsageEmulatorPlugin.testInitialization(TestCpu.ID, conf);
    long time2 = 
           TestResourceUsageEmulatorPlugin.testInitialization(TestOthers.ID, 
                                                              conf);
    assertTrue("Resource usage matcher failed to initialize the configured"
               + " plugins in order", time1 < time2);
    
    matcher.matchResourceUsage();

    // Note that the cpu usage emulator plugin is configured 1st and then the
    // others plugin.
    time1 = 
      TestResourceUsageEmulatorPlugin.testInitialization(TestCpu.ID, conf);
    time2 = 
      TestResourceUsageEmulatorPlugin.testInitialization(TestOthers.ID, 
                                                         conf);
    assertTrue("Resource usage matcher failed to load the configured plugins", 
               time1 < time2);
  }
  
  /**
   * Fakes the cumulative usage using {@link FakeCpuUsageEmulatorCore}.
   */
  static class FakeResourceUsageMonitor extends DummyResourceCalculatorPlugin {
    private FakeCpuUsageEmulatorCore core;
    
    public FakeResourceUsageMonitor(FakeCpuUsageEmulatorCore core) {
      this.core = core;
    }
    
    /**
     * A dummy CPU usage monitor. Every call to 
     * {@link ResourceCalculatorPlugin#getCumulativeCpuTime()} will return the 
     * value of {@link FakeCpuUsageEmulatorCore#getNumCalls()}.
     */
    @Override
    public long getCumulativeCpuTime() {
      return core.getCpuUsage();
    }

    /**
     * Returns a {@link ProcResourceValues} with cumulative cpu usage  
     * computed using {@link #getCumulativeCpuTime()}.
     */
    @Override
    public ProcResourceValues getProcResourceValues() {
      long usageValue = getCumulativeCpuTime();
      return new ProcResourceValues(usageValue, -1, -1);
    }
  }
  
  /**
   * A dummy {@link Progressive} implementation that allows users to set the
   * progress for testing. The {@link Progressive#getProgress()} call will 
   * return the last progress value set using 
   * {@link FakeProgressive#setProgress(float)}.
   */
  static class FakeProgressive implements Progressive {
    private float progress = 0F;
    @Override
    public float getProgress() {
      return progress;
    }
    
    void setProgress(float progress) {
      this.progress = progress;
    }
  }
  
  /**
   * A dummy reporter for {@link LoadJob.ResourceUsageMatcherRunner}.
   */
  private static class DummyReporter extends StatusReporter {
    private Progressive progress;
    
    DummyReporter(Progressive progress) {
      this.progress = progress;
    }
    
    @Override
    public org.apache.hadoop.mapreduce.Counter getCounter(Enum<?> name) {
      return null;
    }
    
    @Override
    public org.apache.hadoop.mapreduce.Counter getCounter(String group,
                                                          String name) {
      return null;
    }
    
    @Override
    public void progress() {
    }
    
    @Override
    public float getProgress() {
      return progress.getProgress();
    }
    
    @Override
    public void setStatus(String status) {
    }
  }
  
  // Extends ResourceUsageMatcherRunner for testing.
  @SuppressWarnings("unchecked")
  private static class FakeResourceUsageMatcherRunner 
  extends ResourceUsageMatcherRunner {
    FakeResourceUsageMatcherRunner(TaskInputOutputContext context, 
                                   ResourceUsageMetrics metrics) {
      super(context, metrics);
    }
    
    // test ResourceUsageMatcherRunner
    void test() throws Exception {
      super.match();
    }
  }
  
  /**
   * Test {@link LoadJob.ResourceUsageMatcherRunner}.
   */
  @Test
  @SuppressWarnings("unchecked")
  public void testResourceUsageMatcherRunner() throws Exception {
    Configuration conf = new Configuration();
    FakeProgressive progress = new FakeProgressive();
    
    // set the resource calculator plugin
    conf.setClass(TTConfig.TT_RESOURCE_CALCULATOR_PLUGIN,
                  DummyResourceCalculatorPlugin.class, 
                  ResourceCalculatorPlugin.class);
    // set the resources
    // set the resource implementation class
    conf.setClass(ResourceUsageMatcher.RESOURCE_USAGE_EMULATION_PLUGINS, 
                  TestResourceUsageEmulatorPlugin.class, 
                  ResourceUsageEmulatorPlugin.class);
    
    long currentTime = System.currentTimeMillis();
    
    // initialize the matcher class
    TaskAttemptID id = new TaskAttemptID("test", 1, TaskType.MAP, 1, 1);
    StatusReporter reporter = new DummyReporter(progress);
    TaskInputOutputContext context = 
      new MapContextImpl(conf, id, null, null, null, reporter, null);
    FakeResourceUsageMatcherRunner matcher = 
      new FakeResourceUsageMatcherRunner(context, null);
    
    // check if the matcher initialized the plugin
    String identifier = TestResourceUsageEmulatorPlugin.DEFAULT_IDENTIFIER;
    long initTime = 
      TestResourceUsageEmulatorPlugin.testInitialization(identifier, conf);
    assertTrue("ResourceUsageMatcherRunner failed to initialize the"
               + " configured plugin", initTime > currentTime);
    
    // check the progress
    assertEquals("Progress mismatch in ResourceUsageMatcherRunner", 
                 0, progress.getProgress(), 0D);
    
    // call match() and check progress
    progress.setProgress(0.01f);
    currentTime = System.currentTimeMillis();
    matcher.test();
    long emulateTime = 
      TestResourceUsageEmulatorPlugin.testEmulation(identifier, conf);
    assertTrue("ProgressBasedResourceUsageMatcher failed to load and emulate"
               + " the configured plugin", emulateTime > currentTime);
  }
  
  /**
   * Test {@link CumulativeCpuUsageEmulatorPlugin}'s core CPU usage emulation 
   * engine.
   */
  @Test
  public void testCpuUsageEmulator() throws IOException {
    // test CpuUsageEmulator calibration with fake resource calculator plugin
    long target = 100000L; // 100 secs
    int unitUsage = 50;
    FakeCpuUsageEmulatorCore fakeCpuEmulator = new FakeCpuUsageEmulatorCore();
    fakeCpuEmulator.setUnitUsage(unitUsage);
    FakeResourceUsageMonitor fakeMonitor = 
      new FakeResourceUsageMonitor(fakeCpuEmulator);
    
    // calibrate for 100ms
    fakeCpuEmulator.calibrate(fakeMonitor, target);
    
    // by default, CpuUsageEmulator.calibrate() will consume 100ms of CPU usage
    assertEquals("Fake calibration failed", 
                 100, fakeMonitor.getCumulativeCpuTime());
    assertEquals("Fake calibration failed", 
                 100, fakeCpuEmulator.getCpuUsage());
    // by default, CpuUsageEmulator.performUnitComputation() will be called 
    // twice
    assertEquals("Fake calibration failed", 
                 2, fakeCpuEmulator.getNumCalls());
  }
  
  /**
   * This is a dummy class that fakes CPU usage.
   */
  private static class FakeCpuUsageEmulatorCore 
  extends DefaultCpuUsageEmulator {
    private int numCalls = 0;
    private int unitUsage = 1;
    private int cpuUsage = 0;
    
    @Override
    protected void performUnitComputation() {
      ++numCalls;
      cpuUsage += unitUsage;
    }
    
    int getNumCalls() {
      return numCalls;
    }
    
    int getCpuUsage() {
      return cpuUsage;
    }
    
    void reset() {
      numCalls = 0;
      cpuUsage = 0;
    }
    
    void setUnitUsage(int unitUsage) {
      this.unitUsage = unitUsage;
    }
  }
  
  // Creates a ResourceUsageMetrics object from the target usage
  static ResourceUsageMetrics createMetrics(long target) {
    ResourceUsageMetrics metrics = new ResourceUsageMetrics();
    metrics.setCumulativeCpuUsage(target);
    metrics.setVirtualMemoryUsage(target);
    metrics.setPhysicalMemoryUsage(target);
    metrics.setHeapUsage(target);
    return metrics;
  }
  
  /**
   * Test {@link CumulativeCpuUsageEmulatorPlugin}.
   */
  @Test
  public void testCumulativeCpuUsageEmulatorPlugin() throws Exception {
    Configuration conf = new Configuration();
    long targetCpuUsage = 1000L;
    int unitCpuUsage = 50;
    
    // fake progress indicator
    FakeProgressive fakeProgress = new FakeProgressive();
    
    // fake cpu usage generator
    FakeCpuUsageEmulatorCore fakeCore = new FakeCpuUsageEmulatorCore();
    fakeCore.setUnitUsage(unitCpuUsage);
    
    // a cumulative cpu usage emulator with fake core
    CumulativeCpuUsageEmulatorPlugin cpuPlugin = 
      new CumulativeCpuUsageEmulatorPlugin(fakeCore);
    
    // test with invalid or missing resource usage value
    ResourceUsageMetrics invalidUsage = createMetrics(0);
    cpuPlugin.initialize(conf, invalidUsage, null, null);
    
    // test if disabled cpu emulation plugin's emulate() call is a no-operation
    // this will test if the emulation plugin is disabled or not
    int numCallsPre = fakeCore.getNumCalls();
    long cpuUsagePre = fakeCore.getCpuUsage();
    cpuPlugin.emulate();
    int numCallsPost = fakeCore.getNumCalls();
    long cpuUsagePost = fakeCore.getCpuUsage();
    
    //  test if no calls are made cpu usage emulator core
    assertEquals("Disabled cumulative CPU usage emulation plugin works!", 
                 numCallsPre, numCallsPost);
    
    //  test if no calls are made cpu usage emulator core
    assertEquals("Disabled cumulative CPU usage emulation plugin works!", 
                 cpuUsagePre, cpuUsagePost);
    
    // test with get progress
    float progress = cpuPlugin.getProgress();
    assertEquals("Invalid progress of disabled cumulative CPU usage emulation " 
                 + "plugin!", 1.0f, progress, 0f);
    
    // test with valid resource usage value
    ResourceUsageMetrics metrics = createMetrics(targetCpuUsage);
    
    // fake monitor
    ResourceCalculatorPlugin monitor = new FakeResourceUsageMonitor(fakeCore);
    
    // test with default emulation interval
    testEmulationAccuracy(conf, fakeCore, monitor, metrics, cpuPlugin, 
                          targetCpuUsage, targetCpuUsage / unitCpuUsage);
    
    // test with custom value for emulation interval of 20%
    conf.setFloat(CumulativeCpuUsageEmulatorPlugin.CPU_EMULATION_PROGRESS_INTERVAL,
                  0.2F);
    testEmulationAccuracy(conf, fakeCore, monitor, metrics, cpuPlugin, 
                          targetCpuUsage, targetCpuUsage / unitCpuUsage);
    
    // test if emulation interval boundary is respected (unit usage = 1)
    //  test the case where the current progress is less than threshold
    fakeProgress = new FakeProgressive(); // initialize
    fakeCore.reset();
    fakeCore.setUnitUsage(1);
    conf.setFloat(CumulativeCpuUsageEmulatorPlugin.CPU_EMULATION_PROGRESS_INTERVAL,
                  0.25F);
    cpuPlugin.initialize(conf, metrics, monitor, fakeProgress);
    // take a snapshot after the initialization
    long initCpuUsage = monitor.getCumulativeCpuTime();
    long initNumCalls = fakeCore.getNumCalls();
    // test with 0 progress
    testEmulationBoundary(0F, fakeCore, fakeProgress, cpuPlugin, initCpuUsage, 
                          initNumCalls, "[no-op, 0 progress]");
    // test with 24% progress
    testEmulationBoundary(0.24F, fakeCore, fakeProgress, cpuPlugin, 
                          initCpuUsage, initNumCalls, "[no-op, 24% progress]");
    // test with 25% progress
    //  target = 1000ms, target emulation at 25% = 250ms, 
    //  weighed target = 1000 * 0.25^4 (we are using progress^4 as the weight)
    //                 ~ 4
    //  but current usage = init-usage = 100, hence expected = 100
    testEmulationBoundary(0.25F, fakeCore, fakeProgress, cpuPlugin, 
                          initCpuUsage, initNumCalls, "[op, 25% progress]");
    
    // test with 80% progress
    //  target = 1000ms, target emulation at 80% = 800ms, 
    //  weighed target = 1000 * 0.25^4 (we are using progress^4 as the weight)
    //                 ~ 410
    //  current-usage = init-usage = 100, hence expected-usage = 410
    testEmulationBoundary(0.80F, fakeCore, fakeProgress, cpuPlugin, 410, 410, 
                          "[op, 80% progress]");
    
    // now test if the final call with 100% progress ramps up the CPU usage
    testEmulationBoundary(1F, fakeCore, fakeProgress, cpuPlugin, targetCpuUsage,
                          targetCpuUsage, "[op, 100% progress]");
    
    // test if emulation interval boundary is respected (unit usage = 50)
    //  test the case where the current progress is less than threshold
    fakeProgress = new FakeProgressive(); // initialize
    fakeCore.reset();
    fakeCore.setUnitUsage(unitCpuUsage);
    conf.setFloat(CumulativeCpuUsageEmulatorPlugin.CPU_EMULATION_PROGRESS_INTERVAL,
                  0.40F);
    cpuPlugin.initialize(conf, metrics, monitor, fakeProgress);
    // take a snapshot after the initialization
    initCpuUsage = monitor.getCumulativeCpuTime();
    initNumCalls = fakeCore.getNumCalls();
    // test with 0 progress
    testEmulationBoundary(0F, fakeCore, fakeProgress, cpuPlugin, initCpuUsage, 
                          initNumCalls, "[no-op, 0 progress]");
    // test with 39% progress
    testEmulationBoundary(0.39F, fakeCore, fakeProgress, cpuPlugin, 
                          initCpuUsage, initNumCalls, "[no-op, 39% progress]");
    // test with 40% progress
    //  target = 1000ms, target emulation at 40% = 4000ms, 
    //  weighed target = 1000 * 0.40^4 (we are using progress^4 as the weight)
    //                 ~ 26
    // current-usage = init-usage = 100, hence expected-usage = 100
    testEmulationBoundary(0.40F, fakeCore, fakeProgress, cpuPlugin, 
                          initCpuUsage, initNumCalls, "[op, 40% progress]");
    
    // test with 90% progress
    //  target = 1000ms, target emulation at 90% = 900ms, 
    //  weighed target = 1000 * 0.90^4 (we are using progress^4 as the weight)
    //                 ~ 657
    //  current-usage = init-usage = 100, hence expected-usage = 657 but 
    //  the fake-core increases in steps of 50, hence final target = 700
    testEmulationBoundary(0.90F, fakeCore, fakeProgress, cpuPlugin, 700, 
                          700 / unitCpuUsage, "[op, 90% progress]");
    
    // now test if the final call with 100% progress ramps up the CPU usage
    testEmulationBoundary(1F, fakeCore, fakeProgress, cpuPlugin, targetCpuUsage,
                          targetCpuUsage / unitCpuUsage, "[op, 100% progress]");
  }
  
  // test whether the CPU usage emulator achieves the desired target using
  // desired calls to the underling core engine.
  private static void testEmulationAccuracy(Configuration conf, 
                        FakeCpuUsageEmulatorCore fakeCore,
                        ResourceCalculatorPlugin monitor,
                        ResourceUsageMetrics metrics,
                        CumulativeCpuUsageEmulatorPlugin cpuPlugin,
                        long expectedTotalCpuUsage, long expectedTotalNumCalls) 
  throws Exception {
    FakeProgressive fakeProgress = new FakeProgressive();
    fakeCore.reset();
    cpuPlugin.initialize(conf, metrics, monitor, fakeProgress);
    int numLoops = 0;
    while (fakeProgress.getProgress() < 1) {
      ++numLoops;
      float progress = (float)numLoops / 100;
      fakeProgress.setProgress(progress);
      cpuPlugin.emulate();
    }
    
    // test if the resource plugin shows the expected invocations
    assertEquals("Cumulative cpu usage emulator plugin failed (num calls)!", 
                 expectedTotalNumCalls, fakeCore.getNumCalls(), 0L);
    // test if the resource plugin shows the expected usage
    assertEquals("Cumulative cpu usage emulator plugin failed (total usage)!", 
                 expectedTotalCpuUsage, fakeCore.getCpuUsage(), 0L);
  }
  
  // tests if the CPU usage emulation plugin emulates only at the expected
  // progress gaps
  private static void testEmulationBoundary(float progress, 
      FakeCpuUsageEmulatorCore fakeCore, FakeProgressive fakeProgress, 
      CumulativeCpuUsageEmulatorPlugin cpuPlugin, long expectedTotalCpuUsage, 
      long expectedTotalNumCalls, String info) throws Exception {
    fakeProgress.setProgress(progress);
    cpuPlugin.emulate();
    
    assertEquals("Emulation interval test for cpu usage failed " + info + "!", 
                 expectedTotalCpuUsage, fakeCore.getCpuUsage(), 0L);
    assertEquals("Emulation interval test for num calls failed " + info + "!", 
                 expectedTotalNumCalls, fakeCore.getNumCalls(), 0L);
  }
}
