content: /*
   * The Alluxio Open Foundation licenses this work under the Apache License, version 2.0
   * (the "License"). You may not use this work except in compliance with the License, which is
   * available at www.apache.org/licenses/LICENSE-2.0
   *
   * This software is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
   * either express or implied, as more fully set forth in the License.
   *
   * See the NOTICE file distributed with this work for information regarding copyright ownership.
   */
  
  package alluxio.cli.hdfs;
  
  import static org.hamcrest.core.StringContains.containsString;
  import static org.junit.Assert.assertEquals;
  import static org.junit.Assert.assertThat;
  
  import alluxio.cli.ValidationTaskResult;
  import alluxio.cli.ValidationUtils;
  import alluxio.conf.Configuration;
  import alluxio.conf.InstancedConfiguration;
  import alluxio.conf.PropertyKey;
  import alluxio.util.ShellUtils;
  
  import com.google.common.collect.ImmutableMap;
  import org.junit.After;
  import org.junit.Test;
  import org.junit.runner.RunWith;
  import org.mockito.BDDMockito;
  import org.powermock.api.mockito.PowerMockito;
  import org.powermock.core.classloader.annotations.PrepareForTest;
  import org.powermock.modules.junit4.PowerMockRunner;
  
  @RunWith(PowerMockRunner.class)
  @PrepareForTest(ShellUtils.class)
  public class HdfsVersionValidationTaskTest {
    private static final InstancedConfiguration CONF = Configuration.copyGlobal();
  
    @Test
    public void versionNotMatchedDefault() throws Exception {
      PowerMockito.mockStatic(ShellUtils.class);
      String[] cmd = new String[]{"hadoop", "version"};
      BDDMockito.given(ShellUtils.execCommand(cmd)).willReturn("Hadoop 2.2");
  
      HdfsVersionValidationTask task = new HdfsVersionValidationTask(CONF);
      ValidationTaskResult result = task.validateImpl(ImmutableMap.of());
      assertEquals(ValidationUtils.State.FAILED, result.getState());
      assertThat(result.getResult(), containsString("2.2 does not match alluxio.underfs.version"));
      assertThat(result.getAdvice(), containsString("configure alluxio.underfs.version"));
    }
  
    @Test
    public void versionNotMatched() throws Exception {
      PowerMockito.mockStatic(ShellUtils.class);
      String[] cmd = new String[]{"hadoop", "version"};
      BDDMockito.given(ShellUtils.execCommand(cmd)).willReturn("Hadoop 2.7");
      CONF.set(PropertyKey.UNDERFS_VERSION, "2.6");
  
      HdfsVersionValidationTask task = new HdfsVersionValidationTask(CONF);
      ValidationTaskResult result = task.validateImpl(ImmutableMap.of());
      assertEquals(ValidationUtils.State.FAILED, result.getState());
      assertThat(result.getResult(), containsString(
              "2.7 does not match alluxio.underfs.version=2.6"));
      assertThat(result.getAdvice(), containsString("configure alluxio.underfs.version"));
    }
  
    @Test
    public void versionMatched() throws Exception {
      PowerMockito.mockStatic(ShellUtils.class);
      String[] cmd = new String[]{"hadoop", "version"};
      BDDMockito.given(ShellUtils.execCommand(cmd)).willReturn("Hadoop 2.6");
      CONF.set(PropertyKey.UNDERFS_VERSION, "2.6");
  
      HdfsVersionValidationTask task = new HdfsVersionValidationTask(CONF);
      ValidationTaskResult result = task.validateImpl(ImmutableMap.of());
      assertEquals(ValidationUtils.State.OK, result.getState());
    }
  
    @Test
    public void minorVersionAccepted() throws Exception {
      PowerMockito.mockStatic(ShellUtils.class);
      String[] cmd = new String[]{"hadoop", "version"};
      // The minor version is not defined in Alluxio, which should work
      BDDMockito.given(ShellUtils.execCommand(cmd)).willReturn("Hadoop 2.6.2");
      CONF.set(PropertyKey.UNDERFS_VERSION, "2.6");
  
      HdfsVersionValidationTask task = new HdfsVersionValidationTask(CONF);
      ValidationTaskResult result = task.validateImpl(ImmutableMap.of());
      assertEquals(ValidationUtils.State.OK, result.getState());
    }
  
    @Test
    public void minorVersionConflict() throws Exception {
      PowerMockito.mockStatic(ShellUtils.class);
      String[] cmd = new String[]{"hadoop", "version"};
      // Alluxio defines a different minor version, which should not work
      BDDMockito.given(ShellUtils.execCommand(cmd)).willReturn("Hadoop 2.6.2");
      CONF.set(PropertyKey.UNDERFS_VERSION, "2.6.3");
  
      HdfsVersionValidationTask task = new HdfsVersionValidationTask(CONF);
      ValidationTaskResult result = task.validateImpl(ImmutableMap.of());
      assertEquals(ValidationUtils.State.FAILED, result.getState());
      assertThat(result.getResult(), containsString(
              "Hadoop version 2.6.2 does not match alluxio.underfs.version=2.6.3"));
    }
  
    @Test
    public void versionParsing() {
      String versionStr = "Hadoop 2.7.2\n"
              + "Subversion https://git-wip-us.apache.org/repos/asf/hadoop.git "
              + "-r b165c4fe8a74265c792ce23f546c64604acf0e41\n"
              + "Compiled by jenkins on 2016-01-26T00:08Z\n"
              + "Compiled with protoc 2.5.0\n"
              + "From source with checksum d0fda26633fa762bff87ec759ebe689c\n"
              + "This command was run using "
              + "/tmp/hadoop/share/hadoop/common/hadoop-common-2.7.2.jar";
  
      HdfsVersionValidationTask task = new HdfsVersionValidationTask(CONF);
      String version = task.parseVersion(versionStr);
      assertEquals("2.7.2", version);
    }
  
    @Test
    public void cdhVersionParsing() {
      String versionStr = "Hadoop 2.6.0-cdh5.16.2\n"
              + "Subversion http://github.com/cloudera/hadoop -r "
              + "4f94d60caa4cbb9af0709a2fd96dc3861af9cf20\n"
              + "Compiled by jenkins on 2019-06-03T10:41Z\n"
              + "Compiled with protoc 2.5.0\n"
              + "From source with checksum 79b9b24a29c6358b53597c3b49575e37\n"
              + "This command was run using /usr/lib/hadoop/hadoop-common-2.6.0-cdh5.16.2.jar";
  
      HdfsVersionValidationTask task = new HdfsVersionValidationTask(CONF);
      String version = task.parseVersion(versionStr);
      assertEquals("cdh5.16.2", version);
    }
  
    @After
    public void resetConfig() {
      CONF.unset(PropertyKey.UNDERFS_VERSION);
    }
  }
  