blob: daf864210df35d1101ae6df72115c28497717f1b [file] [log] [blame]
/*
* 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.hive.ql;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.hive.conf.HiveConf;
import org.apache.hadoop.hive.metastore.HiveMetaStoreClient;
import org.apache.hadoop.hive.metastore.IMetaStoreClient;
import org.apache.hadoop.hive.metastore.api.Table;
import org.apache.hadoop.hive.metastore.utils.TestTxnDbUtil;
import org.apache.hadoop.hive.ql.QTestMiniClusters.MiniClusterType;
import org.junit.Assert;
import org.junit.Test;
import static org.junit.Assert.fail;
/**
* Suite for testing location. e.g. if "alter table alter partition
* location" is run, do the partitions end up in the correct location.
*
* This is a special case of the regular queries as paths are typically
* ignored.
*/
public class TestLocationQueries extends BaseTestQueries {
public TestLocationQueries() {
File logDirFile = new File(logDir);
if (!(logDirFile.exists() || logDirFile.mkdirs())) {
fail("Could not create " + logDir);
}
}
/**
* Our own checker - validate the location of the partition.
*/
public static class CheckResults extends QTestUtil {
private final String locationSubdir;
/**
* Validate only that the location is correct.
* @return non-zero if it failed
*/
@Override
public QTestProcessExecResult checkCliDriverResults() throws Exception {
String tname = getInputFile().getName();
File logFile = new File(logDir, tname + ".out");
int failedCount = 0;
StringBuilder fileNames = new StringBuilder("Files failing the location check:");
FileReader fr = new FileReader(logFile);
BufferedReader in = new BufferedReader(fr);
try {
String line;
int locationCount = 0;
Pattern p = Pattern.compile("location:([^,)]+)");
while((line = in.readLine()) != null) {
Matcher m = p.matcher(line);
if (m.find()) {
File f = new File(m.group(1));
if (!f.getName().equals(locationSubdir)) {
failedCount++;
fileNames.append(f.getName()).append("\r\n");
}
locationCount++;
}
}
// we always have to find at least one location, otw the test is useless
if (locationCount == 0) {
return QTestProcessExecResult.create(Integer.MAX_VALUE, "0 locations tested");
}
} finally {
in.close();
}
return QTestProcessExecResult.create(failedCount, fileNames.toString());
}
public CheckResults(String outDir, String logDir, MiniClusterType miniMr, String locationSubdir)
throws Exception
{
super(
QTestArguments.QTestArgumentsBuilder.instance()
.withOutDir(outDir)
.withLogDir(logDir)
.withClusterType(miniMr)
.withConfDir(null)
.withInitScript("")
.withCleanupScript("")
.withLlapIo(false)
.build());
this.locationSubdir = locationSubdir;
}
}
/**
* Verify that the location of the partition is valid. In this case
* the path should end in "parta" and not "dt=a" (the default).
*
*/
@Test
public void testAlterTablePartitionLocation_alter5() throws Exception {
String[] testNames = new String[] {"alter5.q"};
File[] qfiles = setupQFiles(testNames);
QTestUtil[] qt = new QTestUtil[qfiles.length];
for (int i = 0; i < qfiles.length; i++) {
qt[i] = new CheckResults(resDir, logDir, MiniClusterType.NONE, "parta");
qt[i].postInit();
qt[i].newSession();
qt[i].setInputFile(qfiles[i]);
qt[i].clearTestSideEffects();
}
boolean success = QTestRunnerUtils.queryListRunnerSingleThreaded(qfiles, qt);
if (!success) {
fail("One or more queries failed");
}
}
/**
* Verify the delta directory name of the load data inpath command for MM acid tables.
*/
@Test
public void testAcidLoadDataLocation() throws Exception {
String[] testNames = new String[]{"acid_load_data.q"};
File[] qfiles = setupQFiles(testNames);
QTestUtil qt = new QTestUtil(QTestArguments.QTestArgumentsBuilder.instance()
.withOutDir(resDir + "/llap")
.withLogDir(logDir)
.withClusterType(MiniClusterType.LLAP_LOCAL)
.withConfDir(null)
.withInitScript("")
.withCleanupScript("")
.withLlapIo(false)
.build());
HiveConf hiveConf = qt.getConf();
TestTxnDbUtil.setConfValues(hiveConf);
TestTxnDbUtil.cleanDb(hiveConf);
TestTxnDbUtil.prepDb(hiveConf);
qt.postInit();
qt.newSession();
qt.setInputFile(qfiles[0]);
qt.clearTestSideEffects();
boolean success = QTestRunnerUtils.queryListRunnerSingleThreaded(qfiles, new QTestUtil[]{qt});
if (success) {
IMetaStoreClient hmsClient = new HiveMetaStoreClient(hiveConf);
Table table = hmsClient.getTable("default", "kv_mm");
FileSystem fs = FileSystem.get(hiveConf);
String location = table.getSd().getLocation();
Path delta = fs.listStatus(new Path(location))[0].getPath();
Assert.assertEquals("Delta directory name mismatch!", "delta_0000001_0000001_0000", delta.getName());
} else {
fail("One or more queries failed");
}
}
}