001/*
002 * Licensed to the Apache Software Foundation (ASF) under one
003 * or more contributor license agreements.  See the NOTICE file
004 * distributed with this work for additional information
005 * regarding copyright ownership.  The ASF licenses this file
006 * to you under the Apache License, Version 2.0 (the
007 * "License"); you may not use this file except in compliance
008 * with the License.  You may obtain a copy of the License at
009 *
010 *     http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing, software
013 * distributed under the License is distributed on an "AS IS" BASIS,
014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015 * See the License for the specific language governing permissions and
016 * limitations under the License.
017 */
018package org.apache.hadoop.hbase.mapreduce;
019
020import static org.junit.Assert.assertNotNull;
021import static org.junit.Assert.assertTrue;
022import static org.mockito.Mockito.verify;
023
024import java.io.IOException;
025import java.security.PrivilegedAction;
026import java.util.ArrayList;
027import java.util.List;
028import org.apache.hadoop.conf.Configuration;
029import org.apache.hadoop.fs.FileSystem;
030import org.apache.hadoop.fs.Path;
031import org.apache.hadoop.hbase.HBaseClassTestRule;
032import org.apache.hadoop.hbase.HBaseTestingUtil;
033import org.apache.hadoop.hbase.io.ImmutableBytesWritable;
034import org.apache.hadoop.hbase.testclassification.MapReduceTests;
035import org.apache.hadoop.hbase.testclassification.MediumTests;
036import org.apache.hadoop.mapreduce.Job;
037import org.apache.hadoop.mapreduce.lib.partition.TotalOrderPartitioner;
038import org.apache.hadoop.security.UserGroupInformation;
039import org.junit.After;
040import org.junit.Before;
041import org.junit.ClassRule;
042import org.junit.Test;
043import org.junit.experimental.categories.Category;
044import org.mockito.Mockito;
045import org.slf4j.Logger;
046import org.slf4j.LoggerFactory;
047
048@Category({ MapReduceTests.class, MediumTests.class })
049public class TestConfigurePartitioner {
050
051  @ClassRule
052  public static final HBaseClassTestRule CLASS_RULE =
053    HBaseClassTestRule.forClass(TestConfigurePartitioner.class);
054
055  private static final Logger LOG = LoggerFactory.getLogger(TestConfigurePartitioner.class);
056
057  private static final HBaseTestingUtil UTIL = new HBaseTestingUtil();
058
059  @Before
060  public void setUp() throws Exception {
061    UTIL.startMiniDFSCluster(1);
062  }
063
064  @After
065  public void tearDown() throws IOException {
066    UTIL.shutdownMiniDFSCluster();
067  }
068
069  @Test
070  public void testConfigurePartitioner() throws Exception {
071    Configuration conf = UTIL.getConfiguration();
072    // Create a user who is not the current user
073    String fooUserName = "foo1234";
074    String fooGroupName = "group1";
075    UserGroupInformation ugi =
076      UserGroupInformation.createUserForTesting(fooUserName, new String[] { fooGroupName });
077    // Get user's home directory
078    Path fooHomeDirectory = ugi.doAs(new PrivilegedAction<Path>() {
079      @Override
080      public Path run() {
081        try (FileSystem fs = FileSystem.get(conf)) {
082          return fs.makeQualified(fs.getHomeDirectory());
083        } catch (IOException ioe) {
084          LOG.error("Failed to get foo's home directory", ioe);
085        }
086        return null;
087      }
088    });
089    // create the home directory and chown
090    FileSystem fs = FileSystem.get(conf);
091    fs.mkdirs(fooHomeDirectory);
092    fs.setOwner(fooHomeDirectory, fooUserName, fooGroupName);
093
094    Job job = Mockito.mock(Job.class);
095    Mockito.doReturn(conf).when(job).getConfiguration();
096    ImmutableBytesWritable writable = new ImmutableBytesWritable();
097    List<ImmutableBytesWritable> splitPoints = new ArrayList<ImmutableBytesWritable>();
098    splitPoints.add(writable);
099
100    ugi.doAs(new PrivilegedAction<Void>() {
101      @Override
102      public Void run() {
103        try {
104          HFileOutputFormat2.configurePartitioner(job, splitPoints, false);
105        } catch (IOException ioe) {
106          LOG.error("Failed to configure partitioner", ioe);
107        }
108        return null;
109      }
110    });
111    // verify that the job uses TotalOrderPartitioner
112    verify(job).setPartitionerClass(TotalOrderPartitioner.class);
113    // verify that TotalOrderPartitioner.setPartitionFile() is called.
114    String partitionPathString = conf.get("mapreduce.totalorderpartitioner.path");
115    assertNotNull(partitionPathString);
116    // Make sure the partion file is in foo1234's home directory, and that
117    // the file exists.
118    assertTrue(partitionPathString.startsWith(fooHomeDirectory.toString()));
119    assertTrue(fs.exists(new Path(partitionPathString)));
120  }
121}