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.jupiter.api.Assertions.assertNotNull; 021import static org.junit.jupiter.api.Assertions.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.HBaseTestingUtil; 032import org.apache.hadoop.hbase.io.ImmutableBytesWritable; 033import org.apache.hadoop.hbase.testclassification.MapReduceTests; 034import org.apache.hadoop.hbase.testclassification.MediumTests; 035import org.apache.hadoop.mapreduce.Job; 036import org.apache.hadoop.mapreduce.lib.partition.TotalOrderPartitioner; 037import org.apache.hadoop.security.UserGroupInformation; 038import org.junit.jupiter.api.AfterEach; 039import org.junit.jupiter.api.BeforeEach; 040import org.junit.jupiter.api.Tag; 041import org.junit.jupiter.api.Test; 042import org.mockito.Mockito; 043import org.slf4j.Logger; 044import org.slf4j.LoggerFactory; 045 046@Tag(MapReduceTests.TAG) 047@Tag(MediumTests.TAG) 048public class TestConfigurePartitioner { 049 050 private static final Logger LOG = LoggerFactory.getLogger(TestConfigurePartitioner.class); 051 052 private static final HBaseTestingUtil UTIL = new HBaseTestingUtil(); 053 054 @BeforeEach 055 public void setUp() throws Exception { 056 UTIL.startMiniDFSCluster(1); 057 } 058 059 @AfterEach 060 public void tearDown() throws IOException { 061 UTIL.shutdownMiniDFSCluster(); 062 } 063 064 @Test 065 public void testConfigurePartitioner() throws Exception { 066 Configuration conf = UTIL.getConfiguration(); 067 // Create a user who is not the current user 068 String fooUserName = "foo1234"; 069 String fooGroupName = "group1"; 070 UserGroupInformation ugi = 071 UserGroupInformation.createUserForTesting(fooUserName, new String[] { fooGroupName }); 072 // Get user's home directory 073 Path fooHomeDirectory = ugi.doAs(new PrivilegedAction<Path>() { 074 @Override 075 public Path run() { 076 try (FileSystem fs = FileSystem.get(conf)) { 077 return fs.makeQualified(fs.getHomeDirectory()); 078 } catch (IOException ioe) { 079 LOG.error("Failed to get foo's home directory", ioe); 080 } 081 return null; 082 } 083 }); 084 // create the home directory and chown 085 FileSystem fs = FileSystem.get(conf); 086 fs.mkdirs(fooHomeDirectory); 087 fs.setOwner(fooHomeDirectory, fooUserName, fooGroupName); 088 089 Job job = Mockito.mock(Job.class); 090 Mockito.doReturn(conf).when(job).getConfiguration(); 091 ImmutableBytesWritable writable = new ImmutableBytesWritable(); 092 List<ImmutableBytesWritable> splitPoints = new ArrayList<ImmutableBytesWritable>(); 093 splitPoints.add(writable); 094 095 ugi.doAs(new PrivilegedAction<Void>() { 096 @Override 097 public Void run() { 098 try { 099 HFileOutputFormat2.configurePartitioner(job, splitPoints, false); 100 } catch (IOException ioe) { 101 LOG.error("Failed to configure partitioner", ioe); 102 } 103 return null; 104 } 105 }); 106 // verify that the job uses TotalOrderPartitioner 107 verify(job).setPartitionerClass(TotalOrderPartitioner.class); 108 // verify that TotalOrderPartitioner.setPartitionFile() is called. 109 String partitionPathString = conf.get("mapreduce.totalorderpartitioner.path"); 110 assertNotNull(partitionPathString); 111 // Make sure the partion file is in foo1234's home directory, and that 112 // the file exists. 113 assertTrue(partitionPathString.startsWith(fooHomeDirectory.toString())); 114 assertTrue(fs.exists(new Path(partitionPathString))); 115 } 116}