PageRenderTime 57ms CodeModel.GetById 15ms RepoModel.GetById 1ms app.codeStats 0ms

/ql/src/test/org/apache/hadoop/hive/ql/QTestUtil.java

http://github.com/apache/hive
Java | 1543 lines | 1275 code | 147 blank | 121 comment | 127 complexity | 304a3faf7cce445dc0eb3e113df580ad MD5 | raw file
Possible License(s): Apache-2.0
  1. /**
  2. * Licensed to the Apache Software Foundation (ASF) under one
  3. * or more contributor license agreements. See the NOTICE file
  4. * distributed with this work for additional information
  5. * regarding copyright ownership. The ASF licenses this file
  6. * to you under the Apache License, Version 2.0 (the
  7. * "License"); you may not use this file except in compliance
  8. * with the License. You may obtain a copy of the License at
  9. *
  10. * http://www.apache.org/licenses/LICENSE-2.0
  11. *
  12. * Unless required by applicable law or agreed to in writing, software
  13. * distributed under the License is distributed on an "AS IS" BASIS,
  14. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  15. * See the License for the specific language governing permissions and
  16. * limitations under the License.
  17. */
  18. package org.apache.hadoop.hive.ql;
  19. import static org.apache.hadoop.hive.metastore.MetaStoreUtils.DEFAULT_DATABASE_NAME;
  20. import java.io.BufferedInputStream;
  21. import java.io.BufferedReader;
  22. import java.io.BufferedWriter;
  23. import java.io.File;
  24. import java.io.FileInputStream;
  25. import java.io.FileNotFoundException;
  26. import java.io.FileOutputStream;
  27. import java.io.FileReader;
  28. import java.io.FileWriter;
  29. import java.io.IOException;
  30. import java.io.InputStreamReader;
  31. import java.io.PrintStream;
  32. import java.io.Serializable;
  33. import java.io.StringWriter;
  34. import java.io.UnsupportedEncodingException;
  35. import java.util.ArrayList;
  36. import java.util.Arrays;
  37. import java.util.Collection;
  38. import java.util.Deque;
  39. import java.util.HashMap;
  40. import java.util.HashSet;
  41. import java.util.LinkedList;
  42. import java.util.List;
  43. import java.util.Set;
  44. import java.util.TreeMap;
  45. import java.util.regex.Matcher;
  46. import java.util.regex.Pattern;
  47. import org.apache.commons.io.IOUtils;
  48. import org.apache.commons.logging.Log;
  49. import org.apache.commons.logging.LogFactory;
  50. import org.apache.hadoop.fs.FileStatus;
  51. import org.apache.hadoop.fs.FileSystem;
  52. import org.apache.hadoop.fs.Path;
  53. import org.apache.hadoop.hbase.zookeeper.MiniZooKeeperCluster;
  54. import org.apache.hadoop.hive.cli.CliDriver;
  55. import org.apache.hadoop.hive.cli.CliSessionState;
  56. import org.apache.hadoop.hive.common.io.CachingPrintStream;
  57. import org.apache.hadoop.hive.conf.HiveConf;
  58. import org.apache.hadoop.hive.conf.HiveConf.ConfVars;
  59. import org.apache.hadoop.hive.metastore.MetaStoreUtils;
  60. import org.apache.hadoop.hive.metastore.api.Index;
  61. import org.apache.hadoop.hive.ql.exec.FunctionRegistry;
  62. import org.apache.hadoop.hive.ql.exec.Task;
  63. import org.apache.hadoop.hive.ql.exec.Utilities;
  64. import org.apache.hadoop.hive.ql.exec.Utilities.StreamPrinter;
  65. import org.apache.hadoop.hive.ql.exec.vector.util.AllVectorTypesRecord;
  66. import org.apache.hadoop.hive.ql.exec.vector.util.OrcFileGenerator;
  67. import org.apache.hadoop.hive.ql.io.IgnoreKeyTextOutputFormat;
  68. import org.apache.hadoop.hive.ql.lockmgr.zookeeper.ZooKeeperHiveLockManager;
  69. import org.apache.hadoop.hive.ql.metadata.Hive;
  70. import org.apache.hadoop.hive.ql.metadata.Table;
  71. import org.apache.hadoop.hive.ql.parse.ASTNode;
  72. import org.apache.hadoop.hive.ql.parse.BaseSemanticAnalyzer;
  73. import org.apache.hadoop.hive.ql.parse.ParseDriver;
  74. import org.apache.hadoop.hive.ql.parse.ParseException;
  75. import org.apache.hadoop.hive.ql.parse.SemanticAnalyzer;
  76. import org.apache.hadoop.hive.ql.parse.SemanticException;
  77. import org.apache.hadoop.hive.ql.session.SessionState;
  78. import org.apache.hadoop.hive.serde.serdeConstants;
  79. import org.apache.hadoop.hive.serde2.thrift.ThriftDeserializer;
  80. import org.apache.hadoop.hive.serde2.thrift.test.Complex;
  81. import org.apache.hadoop.hive.shims.HadoopShims;
  82. import org.apache.hadoop.hive.shims.ShimLoader;
  83. import org.apache.hadoop.mapred.SequenceFileInputFormat;
  84. import org.apache.hadoop.mapred.SequenceFileOutputFormat;
  85. import org.apache.hadoop.mapred.TextInputFormat;
  86. import org.apache.hadoop.util.Shell;
  87. import org.apache.thrift.protocol.TBinaryProtocol;
  88. import org.apache.zookeeper.ZooKeeper;
  89. /**
  90. * QTestUtil.
  91. *
  92. */
  93. public class QTestUtil {
  94. public static final String UTF_8 = "UTF-8";
  95. private static final Log LOG = LogFactory.getLog("QTestUtil");
  96. private String testWarehouse;
  97. private final String testFiles;
  98. protected final String outDir;
  99. protected final String logDir;
  100. private final TreeMap<String, String> qMap;
  101. private final Set<String> qSkipSet;
  102. private final Set<String> qSortSet;
  103. private static final String SORT_SUFFIX = ".sorted";
  104. public static final HashSet<String> srcTables = new HashSet<String>
  105. (Arrays.asList(new String [] {
  106. "src", "src1", "srcbucket", "srcbucket2", "src_json", "src_thrift",
  107. "src_sequencefile", "srcpart", "alltypesorc"
  108. }));
  109. private ParseDriver pd;
  110. private Hive db;
  111. protected HiveConf conf;
  112. private Driver drv;
  113. private BaseSemanticAnalyzer sem;
  114. private FileSystem fs;
  115. protected final boolean overWrite;
  116. private CliDriver cliDriver;
  117. private HadoopShims.MiniMrShim mr = null;
  118. private HadoopShims.MiniDFSShim dfs = null;
  119. private boolean miniMr = false;
  120. private String hadoopVer = null;
  121. private QTestSetup setup = null;
  122. public boolean deleteDirectory(File path) {
  123. if (path.exists()) {
  124. File[] files = path.listFiles();
  125. for (File file : files) {
  126. if (file.isDirectory()) {
  127. deleteDirectory(file);
  128. } else {
  129. file.delete();
  130. }
  131. }
  132. }
  133. return (path.delete());
  134. }
  135. public void copyDirectoryToLocal(Path src, Path dest) throws Exception {
  136. FileSystem srcFs = src.getFileSystem(conf);
  137. FileSystem destFs = dest.getFileSystem(conf);
  138. if (srcFs.exists(src)) {
  139. FileStatus[] files = srcFs.listStatus(src);
  140. for (FileStatus file : files) {
  141. String name = file.getPath().getName();
  142. Path dfs_path = file.getPath();
  143. Path local_path = new Path(dest, name);
  144. // If this is a source table we do not copy it out
  145. if (srcTables.contains(name)) {
  146. continue;
  147. }
  148. if (file.isDir()) {
  149. if (!destFs.exists(local_path)) {
  150. destFs.mkdirs(local_path);
  151. }
  152. copyDirectoryToLocal(dfs_path, local_path);
  153. } else {
  154. srcFs.copyToLocalFile(dfs_path, local_path);
  155. }
  156. }
  157. }
  158. }
  159. static Pattern mapTok = Pattern.compile("(\\.?)(.*)_map_(.*)");
  160. static Pattern reduceTok = Pattern.compile("(.*)(reduce_[^\\.]*)((\\..*)?)");
  161. public void normalizeNames(File path) throws Exception {
  162. if (path.isDirectory()) {
  163. File[] files = path.listFiles();
  164. for (File file : files) {
  165. normalizeNames(file);
  166. }
  167. } else {
  168. Matcher m = reduceTok.matcher(path.getName());
  169. if (m.matches()) {
  170. String name = m.group(1) + "reduce" + m.group(3);
  171. path.renameTo(new File(path.getParent(), name));
  172. } else {
  173. m = mapTok.matcher(path.getName());
  174. if (m.matches()) {
  175. String name = m.group(1) + "map_" + m.group(3);
  176. path.renameTo(new File(path.getParent(), name));
  177. }
  178. }
  179. }
  180. }
  181. public QTestUtil(String outDir, String logDir) throws Exception {
  182. this(outDir, logDir, false, "0.20");
  183. }
  184. public String getOutputDirectory() {
  185. return outDir;
  186. }
  187. public String getLogDirectory() {
  188. return logDir;
  189. }
  190. private String getHadoopMainVersion(String input) {
  191. if (input == null) {
  192. return null;
  193. }
  194. Pattern p = Pattern.compile("^(\\d+\\.\\d+).*");
  195. Matcher m = p.matcher(input);
  196. if (m.matches()) {
  197. return m.group(1);
  198. }
  199. return null;
  200. }
  201. public void initConf() throws Exception {
  202. if (Shell.WINDOWS) {
  203. convertPathsFromWindowsToHdfs();
  204. }
  205. String vectorizationEnabled = System.getProperty("test.vectorization.enabled");
  206. if(vectorizationEnabled != null && vectorizationEnabled.equalsIgnoreCase("true")) {
  207. conf.setBoolVar(ConfVars.HIVE_VECTORIZATION_ENABLED, true);
  208. }
  209. // Plug verifying metastore in for testing.
  210. conf.setVar(HiveConf.ConfVars.METASTORE_RAW_STORE_IMPL,
  211. "org.apache.hadoop.hive.metastore.VerifyingObjectStore");
  212. if (miniMr) {
  213. assert dfs != null;
  214. assert mr != null;
  215. mr.setupConfiguration(conf);
  216. // set fs.default.name to the uri of mini-dfs
  217. String dfsUriString = getHdfsUriString(dfs.getFileSystem().getUri().toString());
  218. conf.setVar(HiveConf.ConfVars.HADOOPFS, dfsUriString);
  219. // hive.metastore.warehouse.dir needs to be set relative to the mini-dfs
  220. conf.setVar(HiveConf.ConfVars.METASTOREWAREHOUSE,
  221. (new Path(dfsUriString,
  222. "/build/ql/test/data/warehouse/")).toString());
  223. }
  224. }
  225. private void convertPathsFromWindowsToHdfs() {
  226. // Following local paths are used as HDFS paths in unit tests.
  227. // It works well in Unix as the path notation in Unix and HDFS is more or less same.
  228. // But when it comes to Windows, drive letter separator ':' & backslash '\" are invalid
  229. // characters in HDFS so we need to converts these local paths to HDFS paths before using them
  230. // in unit tests.
  231. // hive.exec.scratchdir needs to be set relative to the mini-dfs
  232. String orgWarehouseDir = conf.getVar(HiveConf.ConfVars.METASTOREWAREHOUSE);
  233. conf.setVar(HiveConf.ConfVars.METASTOREWAREHOUSE, getHdfsUriString(orgWarehouseDir));
  234. String orgTestTempDir = System.getProperty("test.tmp.dir");
  235. System.setProperty("test.tmp.dir", getHdfsUriString(orgTestTempDir));
  236. String orgTestDataDir = System.getProperty("test.src.data.dir");
  237. System.setProperty("test.src.data.dir", getHdfsUriString(orgTestDataDir));
  238. String orgScratchDir = conf.getVar(HiveConf.ConfVars.SCRATCHDIR);
  239. conf.setVar(HiveConf.ConfVars.SCRATCHDIR, getHdfsUriString(orgScratchDir));
  240. if (miniMr) {
  241. String orgAuxJarFolder = conf.getAuxJars();
  242. conf.setAuxJars(getHdfsUriString("file://" + orgAuxJarFolder));
  243. }
  244. }
  245. private String getHdfsUriString(String uriStr) {
  246. assert uriStr != null;
  247. if(Shell.WINDOWS) {
  248. // If the URI conversion is from Windows to HDFS then replace the '\' with '/'
  249. // and remove the windows single drive letter & colon from absolute path.
  250. return uriStr.replace('\\', '/')
  251. .replaceFirst("/[c-zC-Z]:", "/")
  252. .replaceFirst("^[c-zC-Z]:", "");
  253. }
  254. return uriStr;
  255. }
  256. public QTestUtil(String outDir, String logDir, boolean miniMr, String hadoopVer)
  257. throws Exception {
  258. this.outDir = outDir;
  259. this.logDir = logDir;
  260. conf = new HiveConf(Driver.class);
  261. this.miniMr = miniMr;
  262. this.hadoopVer = getHadoopMainVersion(hadoopVer);
  263. qMap = new TreeMap<String, String>();
  264. qSkipSet = new HashSet<String>();
  265. qSortSet = new HashSet<String>();
  266. if (miniMr) {
  267. dfs = ShimLoader.getHadoopShims().getMiniDfs(conf, 4, true, null);
  268. FileSystem fs = dfs.getFileSystem();
  269. mr = ShimLoader.getHadoopShims().getMiniMrCluster(conf, 4, getHdfsUriString(fs.getUri().toString()), 1);
  270. }
  271. initConf();
  272. // Use the current directory if it is not specified
  273. String dataDir = conf.get("test.data.files");
  274. if (dataDir == null) {
  275. dataDir = new File(".").getAbsolutePath() + "/data/files";
  276. }
  277. testFiles = dataDir;
  278. overWrite = "true".equalsIgnoreCase(System.getProperty("test.output.overwrite"));
  279. setup = new QTestSetup();
  280. setup.preTest(conf);
  281. init();
  282. }
  283. public void shutdown() throws Exception {
  284. cleanUp();
  285. setup.tearDown();
  286. if (mr != null) {
  287. mr.shutdown();
  288. mr = null;
  289. }
  290. FileSystem.closeAll();
  291. if (dfs != null) {
  292. dfs.shutdown();
  293. dfs = null;
  294. }
  295. }
  296. public String readEntireFileIntoString(File queryFile) throws IOException {
  297. InputStreamReader isr = new InputStreamReader(
  298. new BufferedInputStream(new FileInputStream(queryFile)), QTestUtil.UTF_8);
  299. StringWriter sw = new StringWriter();
  300. try {
  301. IOUtils.copy(isr, sw);
  302. } finally {
  303. if (isr != null) {
  304. isr.close();
  305. }
  306. }
  307. return sw.toString();
  308. }
  309. public void addFile(String queryFile) throws IOException {
  310. addFile(new File(queryFile));
  311. }
  312. public void addFile(File qf) throws IOException {
  313. String query = readEntireFileIntoString(qf);
  314. qMap.put(qf.getName(), query);
  315. if(checkHadoopVersionExclude(qf.getName(), query)
  316. || checkOSExclude(qf.getName(), query)) {
  317. qSkipSet.add(qf.getName());
  318. }
  319. if (checkNeedsSort(qf.getName(), query)) {
  320. qSortSet.add(qf.getName());
  321. }
  322. }
  323. private boolean checkNeedsSort(String fileName, String query) {
  324. Pattern pattern = Pattern.compile("-- SORT_BEFORE_DIFF");
  325. Matcher matcher = pattern.matcher(query);
  326. if (matcher.find()) {
  327. return true;
  328. }
  329. return false;
  330. }
  331. private boolean checkHadoopVersionExclude(String fileName, String query){
  332. // Look for a hint to not run a test on some Hadoop versions
  333. Pattern pattern = Pattern.compile("-- (EX|IN)CLUDE_HADOOP_MAJOR_VERSIONS\\((.*)\\)");
  334. boolean excludeQuery = false;
  335. boolean includeQuery = false;
  336. Set<String> versionSet = new HashSet<String>();
  337. String hadoopVer = ShimLoader.getMajorVersion();
  338. Matcher matcher = pattern.matcher(query);
  339. // Each qfile may include at most one INCLUDE or EXCLUDE directive.
  340. //
  341. // If a qfile contains an INCLUDE directive, and hadoopVer does
  342. // not appear in the list of versions to include, then the qfile
  343. // is skipped.
  344. //
  345. // If a qfile contains an EXCLUDE directive, and hadoopVer is
  346. // listed in the list of versions to EXCLUDE, then the qfile is
  347. // skipped.
  348. //
  349. // Otherwise, the qfile is included.
  350. if (matcher.find()) {
  351. String prefix = matcher.group(1);
  352. if ("EX".equals(prefix)) {
  353. excludeQuery = true;
  354. } else {
  355. includeQuery = true;
  356. }
  357. String versions = matcher.group(2);
  358. for (String s : versions.split("\\,")) {
  359. s = s.trim();
  360. versionSet.add(s);
  361. }
  362. }
  363. if (matcher.find()) {
  364. //2nd match is not supposed to be there
  365. String message = "QTestUtil: qfile " + fileName
  366. + " contains more than one reference to (EX|IN)CLUDE_HADOOP_MAJOR_VERSIONS";
  367. throw new UnsupportedOperationException(message);
  368. }
  369. if (excludeQuery && versionSet.contains(hadoopVer)) {
  370. System.out.println("QTestUtil: " + fileName
  371. + " EXCLUDE list contains Hadoop Version " + hadoopVer + ". Skipping...");
  372. return true;
  373. } else if (includeQuery && !versionSet.contains(hadoopVer)) {
  374. System.out.println("QTestUtil: " + fileName
  375. + " INCLUDE list does not contain Hadoop Version " + hadoopVer + ". Skipping...");
  376. return true;
  377. }
  378. return false;
  379. }
  380. private boolean checkOSExclude(String fileName, String query){
  381. // Look for a hint to not run a test on some Hadoop versions
  382. Pattern pattern = Pattern.compile("-- (EX|IN)CLUDE_OS_WINDOWS");
  383. // detect whether this query wants to be excluded or included
  384. // on windows
  385. Matcher matcher = pattern.matcher(query);
  386. if (matcher.find()) {
  387. String prefix = matcher.group(1);
  388. if ("EX".equals(prefix)) {
  389. //windows is to be exluded
  390. if(Shell.WINDOWS){
  391. System.out.println("Due to the OS being windows " +
  392. "adding the query " + fileName +
  393. " to the set of tests to skip");
  394. return true;
  395. }
  396. }
  397. else if(!Shell.WINDOWS){
  398. //non windows to be exluded
  399. System.out.println("Due to the OS not being windows " +
  400. "adding the query " + fileName +
  401. " to the set of tests to skip");
  402. return true;
  403. }
  404. }
  405. return false;
  406. }
  407. /**
  408. * Clear out any side effects of running tests
  409. */
  410. public void clearPostTestEffects () throws Exception {
  411. setup.postTest(conf);
  412. }
  413. /**
  414. * Clear out any side effects of running tests
  415. */
  416. public void clearTestSideEffects () throws Exception {
  417. // Delete any tables other than the source tables
  418. // and any databases other than the default database.
  419. for (String dbName : db.getAllDatabases()) {
  420. SessionState.get().setCurrentDatabase(dbName);
  421. for (String tblName : db.getAllTables()) {
  422. if (!DEFAULT_DATABASE_NAME.equals(dbName) || !srcTables.contains(tblName)) {
  423. Table tblObj = db.getTable(tblName);
  424. // dropping index table can not be dropped directly. Dropping the base
  425. // table will automatically drop all its index table
  426. if(tblObj.isIndexTable()) {
  427. continue;
  428. }
  429. db.dropTable(dbName, tblName);
  430. } else {
  431. // this table is defined in srcTables, drop all indexes on it
  432. List<Index> indexes = db.getIndexes(dbName, tblName, (short)-1);
  433. if (indexes != null && indexes.size() > 0) {
  434. for (Index index : indexes) {
  435. db.dropIndex(dbName, tblName, index.getIndexName(), true);
  436. }
  437. }
  438. }
  439. }
  440. if (!DEFAULT_DATABASE_NAME.equals(dbName)) {
  441. db.dropDatabase(dbName);
  442. }
  443. }
  444. SessionState.get().setCurrentDatabase(DEFAULT_DATABASE_NAME);
  445. List<String> roleNames = db.getAllRoleNames();
  446. for (String roleName : roleNames) {
  447. db.dropRole(roleName);
  448. }
  449. // allocate and initialize a new conf since a test can
  450. // modify conf by using 'set' commands
  451. conf = new HiveConf (Driver.class);
  452. initConf();
  453. db = Hive.get(conf); // propagate new conf to meta store
  454. setup.preTest(conf);
  455. }
  456. public void cleanUp() throws Exception {
  457. // Drop any tables that remain due to unsuccessful runs
  458. for (String s : new String[] {"src", "src1", "src_json", "src_thrift",
  459. "src_sequencefile", "srcpart", "srcbucket", "srcbucket2", "dest1",
  460. "dest2", "dest3", "dest4", "dest4_sequencefile", "dest_j1", "dest_j2",
  461. "dest_g1", "dest_g2", "fetchtask_ioexception",
  462. AllVectorTypesRecord.TABLE_NAME}) {
  463. db.dropTable(MetaStoreUtils.DEFAULT_DATABASE_NAME, s);
  464. }
  465. // delete any contents in the warehouse dir
  466. Path p = new Path(testWarehouse);
  467. FileSystem fs = p.getFileSystem(conf);
  468. try {
  469. FileStatus [] ls = fs.listStatus(p);
  470. for (int i=0; (ls != null) && (i<ls.length); i++) {
  471. fs.delete(ls[i].getPath(), true);
  472. }
  473. } catch (FileNotFoundException e) {
  474. // Best effort
  475. }
  476. FunctionRegistry.unregisterTemporaryUDF("test_udaf");
  477. FunctionRegistry.unregisterTemporaryUDF("test_error");
  478. }
  479. private void runLoadCmd(String loadCmd) throws Exception {
  480. int ecode = 0;
  481. ecode = drv.run(loadCmd).getResponseCode();
  482. drv.close();
  483. if (ecode != 0) {
  484. throw new Exception("load command: " + loadCmd
  485. + " failed with exit code= " + ecode);
  486. }
  487. return;
  488. }
  489. private void runCreateTableCmd(String createTableCmd) throws Exception {
  490. int ecode = 0;
  491. ecode = drv.run(createTableCmd).getResponseCode();
  492. if (ecode != 0) {
  493. throw new Exception("create table command: " + createTableCmd
  494. + " failed with exit code= " + ecode);
  495. }
  496. return;
  497. }
  498. public void createSources() throws Exception {
  499. startSessionState();
  500. conf.setBoolean("hive.test.init.phase", true);
  501. // Create a bunch of tables with columns key and value
  502. LinkedList<String> cols = new LinkedList<String>();
  503. cols.add("key");
  504. cols.add("value");
  505. LinkedList<String> part_cols = new LinkedList<String>();
  506. part_cols.add("ds");
  507. part_cols.add("hr");
  508. db.createTable("srcpart", cols, part_cols, TextInputFormat.class,
  509. IgnoreKeyTextOutputFormat.class);
  510. Path fpath;
  511. HashMap<String, String> part_spec = new HashMap<String, String>();
  512. for (String ds : new String[] {"2008-04-08", "2008-04-09"}) {
  513. for (String hr : new String[] {"11", "12"}) {
  514. part_spec.clear();
  515. part_spec.put("ds", ds);
  516. part_spec.put("hr", hr);
  517. // System.out.println("Loading partition with spec: " + part_spec);
  518. // db.createPartition(srcpart, part_spec);
  519. fpath = new Path(testFiles, "kv1.txt");
  520. // db.loadPartition(fpath, srcpart.getName(), part_spec, true);
  521. runLoadCmd("LOAD DATA LOCAL INPATH '" + fpath.toUri().getPath()
  522. + "' OVERWRITE INTO TABLE srcpart PARTITION (ds='" + ds + "',hr='"
  523. + hr + "')");
  524. }
  525. }
  526. ArrayList<String> bucketCols = new ArrayList<String>();
  527. bucketCols.add("key");
  528. runCreateTableCmd("CREATE TABLE srcbucket(key int, value string) CLUSTERED BY (key) INTO 2 BUCKETS STORED AS TEXTFILE");
  529. // db.createTable("srcbucket", cols, null, TextInputFormat.class,
  530. // IgnoreKeyTextOutputFormat.class, 2, bucketCols);
  531. for (String fname : new String[] {"srcbucket0.txt", "srcbucket1.txt"}) {
  532. fpath = new Path(testFiles, fname);
  533. runLoadCmd("LOAD DATA LOCAL INPATH '" + fpath.toUri().getPath()
  534. + "' INTO TABLE srcbucket");
  535. }
  536. runCreateTableCmd("CREATE TABLE srcbucket2(key int, value string) "
  537. + "CLUSTERED BY (key) INTO 4 BUCKETS STORED AS TEXTFILE");
  538. // db.createTable("srcbucket", cols, null, TextInputFormat.class,
  539. // IgnoreKeyTextOutputFormat.class, 2, bucketCols);
  540. for (String fname : new String[] {"srcbucket20.txt", "srcbucket21.txt",
  541. "srcbucket22.txt", "srcbucket23.txt"}) {
  542. fpath = new Path(testFiles, fname);
  543. runLoadCmd("LOAD DATA LOCAL INPATH '" + fpath.toUri().getPath()
  544. + "' INTO TABLE srcbucket2");
  545. }
  546. for (String tname : new String[] {"src", "src1"}) {
  547. db.createTable(tname, cols, null, TextInputFormat.class,
  548. IgnoreKeyTextOutputFormat.class);
  549. }
  550. db.createTable("src_sequencefile", cols, null,
  551. SequenceFileInputFormat.class, SequenceFileOutputFormat.class);
  552. Table srcThrift =
  553. new Table(SessionState.get().getCurrentDatabase(), "src_thrift");
  554. srcThrift.setInputFormatClass(SequenceFileInputFormat.class.getName());
  555. srcThrift.setOutputFormatClass(SequenceFileOutputFormat.class.getName());
  556. srcThrift.setSerializationLib(ThriftDeserializer.class.getName());
  557. srcThrift.setSerdeParam(serdeConstants.SERIALIZATION_CLASS, Complex.class
  558. .getName());
  559. srcThrift.setSerdeParam(serdeConstants.SERIALIZATION_FORMAT,
  560. TBinaryProtocol.class.getName());
  561. db.createTable(srcThrift);
  562. LinkedList<String> json_cols = new LinkedList<String>();
  563. json_cols.add("json");
  564. db.createTable("src_json", json_cols, null, TextInputFormat.class,
  565. IgnoreKeyTextOutputFormat.class);
  566. // load the input data into the src table
  567. fpath = new Path(testFiles, "kv1.txt");
  568. runLoadCmd("LOAD DATA LOCAL INPATH '" + fpath.toUri().getPath() + "' INTO TABLE src");
  569. // load the input data into the src table
  570. fpath = new Path(testFiles, "kv3.txt");
  571. runLoadCmd("LOAD DATA LOCAL INPATH '" + fpath.toUri().getPath() + "' INTO TABLE src1");
  572. // load the input data into the src_sequencefile table
  573. fpath = new Path(testFiles, "kv1.seq");
  574. runLoadCmd("LOAD DATA LOCAL INPATH '" + fpath.toUri().getPath()
  575. + "' INTO TABLE src_sequencefile");
  576. // load the input data into the src_thrift table
  577. fpath = new Path(testFiles, "complex.seq");
  578. runLoadCmd("LOAD DATA LOCAL INPATH '" + fpath.toUri().getPath()
  579. + "' INTO TABLE src_thrift");
  580. // load the json data into the src_json table
  581. fpath = new Path(testFiles, "json.txt");
  582. runLoadCmd("LOAD DATA LOCAL INPATH '" + fpath.toUri().getPath()
  583. + "' INTO TABLE src_json");
  584. FileSystem localFs = FileSystem.getLocal(conf);
  585. // create and load data into orc table
  586. fpath = new Path(testFiles, AllVectorTypesRecord.TABLE_NAME);
  587. runCreateTableCmd(AllVectorTypesRecord.TABLE_CREATE_COMMAND);
  588. runLoadCmd("LOAD DATA LOCAL INPATH '" + fpath.toUri().getPath()
  589. + "' INTO TABLE "+AllVectorTypesRecord.TABLE_NAME);
  590. conf.setBoolean("hive.test.init.phase", false);
  591. }
  592. public void init() throws Exception {
  593. // System.out.println(conf.toString());
  594. testWarehouse = conf.getVar(HiveConf.ConfVars.METASTOREWAREHOUSE);
  595. // conf.logVars(System.out);
  596. // System.out.flush();
  597. SessionState.start(conf);
  598. db = Hive.get(conf);
  599. fs = FileSystem.get(conf);
  600. drv = new Driver(conf);
  601. drv.init();
  602. pd = new ParseDriver();
  603. sem = new SemanticAnalyzer(conf);
  604. }
  605. public void init(String tname) throws Exception {
  606. cleanUp();
  607. createSources();
  608. LinkedList<String> cols = new LinkedList<String>();
  609. cols.add("key");
  610. cols.add("value");
  611. LinkedList<String> part_cols = new LinkedList<String>();
  612. part_cols.add("ds");
  613. part_cols.add("hr");
  614. db.createTable("dest1", cols, null, TextInputFormat.class,
  615. IgnoreKeyTextOutputFormat.class);
  616. db.createTable("dest2", cols, null, TextInputFormat.class,
  617. IgnoreKeyTextOutputFormat.class);
  618. db.createTable("dest3", cols, part_cols, TextInputFormat.class,
  619. IgnoreKeyTextOutputFormat.class);
  620. Table dest3 = db.getTable("dest3");
  621. HashMap<String, String> part_spec = new HashMap<String, String>();
  622. part_spec.put("ds", "2008-04-08");
  623. part_spec.put("hr", "12");
  624. db.createPartition(dest3, part_spec);
  625. db.createTable("dest4", cols, null, TextInputFormat.class,
  626. IgnoreKeyTextOutputFormat.class);
  627. db.createTable("dest4_sequencefile", cols, null,
  628. SequenceFileInputFormat.class, SequenceFileOutputFormat.class);
  629. }
  630. public void cliInit(String tname) throws Exception {
  631. cliInit(tname, true);
  632. }
  633. public void cliInit(String tname, boolean recreate) throws Exception {
  634. if (recreate) {
  635. cleanUp();
  636. createSources();
  637. }
  638. HiveConf.setVar(conf, HiveConf.ConfVars.HIVE_AUTHENTICATOR_MANAGER,
  639. "org.apache.hadoop.hive.ql.security.DummyAuthenticator");
  640. CliSessionState ss = new CliSessionState(conf);
  641. assert ss != null;
  642. ss.in = System.in;
  643. File qf = new File(outDir, tname);
  644. File outf = null;
  645. outf = new File(logDir);
  646. outf = new File(outf, qf.getName().concat(".out"));
  647. FileOutputStream fo = new FileOutputStream(outf);
  648. ss.out = new PrintStream(fo, true, "UTF-8");
  649. ss.err = new CachingPrintStream(fo, true, "UTF-8");
  650. ss.setIsSilent(true);
  651. SessionState oldSs = SessionState.get();
  652. if (oldSs != null && oldSs.out != null && oldSs.out != System.out) {
  653. oldSs.out.close();
  654. }
  655. SessionState.start(ss);
  656. cliDriver = new CliDriver();
  657. if (tname.equals("init_file.q")) {
  658. ss.initFiles.add("../data/scripts/test_init_file.sql");
  659. }
  660. cliDriver.processInitFiles(ss);
  661. }
  662. private CliSessionState startSessionState()
  663. throws FileNotFoundException, UnsupportedEncodingException {
  664. HiveConf.setVar(conf, HiveConf.ConfVars.HIVE_AUTHENTICATOR_MANAGER,
  665. "org.apache.hadoop.hive.ql.security.DummyAuthenticator");
  666. CliSessionState ss = new CliSessionState(conf);
  667. assert ss != null;
  668. SessionState.start(ss);
  669. return ss;
  670. }
  671. public int executeOne(String tname) {
  672. String q = qMap.get(tname);
  673. if (q.indexOf(";") == -1) {
  674. return -1;
  675. }
  676. String q1 = q.substring(0, q.indexOf(";") + 1);
  677. String qrest = q.substring(q.indexOf(";") + 1);
  678. qMap.put(tname, qrest);
  679. System.out.println("Executing " + q1);
  680. return cliDriver.processLine(q1);
  681. }
  682. public int execute(String tname) {
  683. try {
  684. return drv.run(qMap.get(tname)).getResponseCode();
  685. } catch (CommandNeedRetryException e) {
  686. // TODO Auto-generated catch block
  687. e.printStackTrace();
  688. return -1;
  689. }
  690. }
  691. public int executeClient(String tname) {
  692. String commands = qMap.get(tname);
  693. StringBuilder newCommands = new StringBuilder(commands.length());
  694. int lastMatchEnd = 0;
  695. Matcher commentMatcher = Pattern.compile("^--.*$", Pattern.MULTILINE).matcher(commands);
  696. while (commentMatcher.find()) {
  697. newCommands.append(commands.substring(lastMatchEnd, commentMatcher.start()));
  698. newCommands.append(commentMatcher.group().replaceAll("(?<!\\\\);", "\\\\;"));
  699. lastMatchEnd = commentMatcher.end();
  700. }
  701. newCommands.append(commands.substring(lastMatchEnd, commands.length()));
  702. commands = newCommands.toString();
  703. return cliDriver.processLine(commands);
  704. }
  705. public boolean shouldBeSkipped(String tname) {
  706. return qSkipSet.contains(tname);
  707. }
  708. public void convertSequenceFileToTextFile() throws Exception {
  709. // Create an instance of hive in order to create the tables
  710. testWarehouse = conf.getVar(HiveConf.ConfVars.METASTOREWAREHOUSE);
  711. db = Hive.get(conf);
  712. // Create dest4 to replace dest4_sequencefile
  713. LinkedList<String> cols = new LinkedList<String>();
  714. cols.add("key");
  715. cols.add("value");
  716. // Move all data from dest4_sequencefile to dest4
  717. drv
  718. .run("FROM dest4_sequencefile INSERT OVERWRITE TABLE dest4 SELECT dest4_sequencefile.*");
  719. // Drop dest4_sequencefile
  720. db.dropTable(MetaStoreUtils.DEFAULT_DATABASE_NAME, "dest4_sequencefile",
  721. true, true);
  722. }
  723. public int checkNegativeResults(String tname, Exception e) throws Exception {
  724. File qf = new File(outDir, tname);
  725. String expf = outPath(outDir.toString(), tname.concat(".out"));
  726. File outf = null;
  727. outf = new File(logDir);
  728. outf = new File(outf, qf.getName().concat(".out"));
  729. FileWriter outfd = new FileWriter(outf);
  730. if (e instanceof ParseException) {
  731. outfd.write("Parse Error: ");
  732. } else if (e instanceof SemanticException) {
  733. outfd.write("Semantic Exception: \n");
  734. } else {
  735. throw e;
  736. }
  737. outfd.write(e.getMessage());
  738. outfd.close();
  739. int exitVal = executeDiffCommand(outf.getPath(), expf, false,
  740. qSortSet.contains(qf.getName()));
  741. if (exitVal != 0 && overWrite) {
  742. exitVal = overwriteResults(outf.getPath(), expf);
  743. }
  744. return exitVal;
  745. }
  746. public int checkParseResults(String tname, ASTNode tree) throws Exception {
  747. if (tree != null) {
  748. File parseDir = new File(outDir, "parse");
  749. String expf = outPath(parseDir.toString(), tname.concat(".out"));
  750. File outf = null;
  751. outf = new File(logDir);
  752. outf = new File(outf, tname.concat(".out"));
  753. FileWriter outfd = new FileWriter(outf);
  754. outfd.write(tree.toStringTree());
  755. outfd.close();
  756. int exitVal = executeDiffCommand(outf.getPath(), expf, false, false);
  757. if (exitVal != 0 && overWrite) {
  758. exitVal = overwriteResults(outf.getPath(), expf);
  759. }
  760. return exitVal;
  761. } else {
  762. throw new Exception("Parse tree is null");
  763. }
  764. }
  765. private final Pattern[] xmlPlanMask = toPattern(new String[] {
  766. "<java version=\".*\" class=\"java.beans.XMLDecoder\">",
  767. "<string>.*/tmp/.*</string>",
  768. "<string>file:.*</string>",
  769. "<string>pfile:.*</string>",
  770. "<string>[0-9]{10}</string>",
  771. "<string>/.*/warehouse/.*</string>"
  772. });
  773. public int checkPlan(String tname, List<Task<? extends Serializable>> tasks) throws Exception {
  774. if (tasks == null) {
  775. throw new Exception("Plan is null");
  776. }
  777. File planDir = new File(outDir, "plan");
  778. String planFile = outPath(planDir.toString(), tname + ".xml");
  779. File outf = null;
  780. outf = new File(logDir);
  781. outf = new File(outf, tname.concat(".xml"));
  782. FileOutputStream ofs = new FileOutputStream(outf);
  783. try {
  784. conf.set(HiveConf.ConfVars.PLAN_SERIALIZATION.varname, "javaXML");
  785. for (Task<? extends Serializable> plan : tasks) {
  786. Utilities.serializePlan(plan, ofs, conf);
  787. }
  788. fixXml4JDK7(outf.getPath());
  789. maskPatterns(xmlPlanMask, outf.getPath());
  790. int exitVal = executeDiffCommand(outf.getPath(), planFile, true, false);
  791. if (exitVal != 0 && overWrite) {
  792. exitVal = overwriteResults(outf.getPath(), planFile);
  793. }
  794. return exitVal;
  795. } finally {
  796. conf.set(HiveConf.ConfVars.PLAN_SERIALIZATION.varname, "kryo");
  797. }
  798. }
  799. /**
  800. * Given the current configurations (e.g., hadoop version and execution mode), return
  801. * the correct file name to compare with the current test run output.
  802. * @param outDir The directory where the reference log files are stored.
  803. * @param testName The test file name (terminated by ".out").
  804. * @return The file name appended with the configuration values if it exists.
  805. */
  806. public String outPath(String outDir, String testName) {
  807. String ret = (new File(outDir, testName)).getPath();
  808. // List of configurations. Currently the list consists of hadoop version and execution mode only
  809. List<String> configs = new ArrayList<String>();
  810. configs.add(this.hadoopVer);
  811. Deque<String> stack = new LinkedList<String>();
  812. StringBuilder sb = new StringBuilder();
  813. sb.append(testName);
  814. stack.push(sb.toString());
  815. // example file names are input1.q.out_0.20.0_minimr or input2.q.out_0.17
  816. for (String s: configs) {
  817. sb.append('_');
  818. sb.append(s);
  819. stack.push(sb.toString());
  820. }
  821. while (stack.size() > 0) {
  822. String fileName = stack.pop();
  823. File f = new File(outDir, fileName);
  824. if (f.exists()) {
  825. ret = f.getPath();
  826. break;
  827. }
  828. }
  829. return ret;
  830. }
  831. /**
  832. * Fix the XML generated by JDK7 which is slightly different from what's generated by JDK6,
  833. * causing 40+ test failures. There are mainly two problems:
  834. *
  835. * 1. object element's properties, id and class, are in reverse order, i.e.
  836. * <object class="org.apache.hadoop.hive.ql.exec.MapRedTask" id="MapRedTask0">
  837. * which needs to be fixed to
  838. * <object id="MapRedTask0" class="org.apache.hadoop.hive.ql.exec.MapRedTask">
  839. * 2. JDK introduces Enum as class, i.e.
  840. * <object id="GenericUDAFEvaluator$Mode0" class="java.lang.Enum">
  841. * <class>org.apache.hadoop.hive.ql.udf.generic.GenericUDAFEvaluator$Mode</class>
  842. * which needs to be fixed to
  843. * <object id="GenericUDAFEvaluator$Mode0" class="org.apache.hadoop.hive.ql.udf.generic.GenericUDAFEvaluator$Mode"
  844. * method="valueOf">
  845. *
  846. * Though not elegant, this allows these test cases to pass until we have a better serialization mechanism.
  847. *
  848. * Did I mention this is test code?
  849. *
  850. * @param fname the name of the file to fix
  851. * @throws Exception in case of IO error
  852. */
  853. private static void fixXml4JDK7(String fname) throws Exception {
  854. String version = System.getProperty("java.version");
  855. if (!version.startsWith("1.7")) {
  856. return;
  857. }
  858. BufferedReader in = new BufferedReader(new FileReader(fname));
  859. BufferedWriter out = new BufferedWriter(new FileWriter(fname + ".orig"));
  860. String line = null;
  861. while (null != (line = in.readLine())) {
  862. out.write(line);
  863. out.write('\n');
  864. }
  865. in.close();
  866. out.close();
  867. in = new BufferedReader(new FileReader(fname + ".orig"));
  868. out = new BufferedWriter(new FileWriter(fname));
  869. while (null != (line = in.readLine())) {
  870. if (line.indexOf("<object ") == -1 || line.indexOf("class=") == -1) {
  871. out.write(line);
  872. } else {
  873. StringBuilder sb = new StringBuilder();
  874. String prefix = line.substring(0, line.indexOf("<object") + 7);
  875. sb.append( prefix );
  876. String postfix = line.substring(line.lastIndexOf('"') + 1);
  877. String id = getPropertyValue(line, "id");
  878. if (id != null) {
  879. sb.append(" id=" + id);
  880. }
  881. String cls = getPropertyValue(line, "class");
  882. assert(cls != null);
  883. if (cls.equals("\"java.lang.Enum\"")) {
  884. line = in.readLine();
  885. cls = "\"" + getElementValue(line, "class") + "\"";
  886. sb.append(" class=" + cls + " method=\"valueOf\"" );
  887. } else {
  888. sb.append(" class=" + cls);
  889. }
  890. sb.append(postfix);
  891. out.write(sb.toString());
  892. }
  893. out.write('\n');
  894. }
  895. in.close();
  896. out.close();
  897. }
  898. /**
  899. * Get the value of a property in line. The returned value has original quotes
  900. */
  901. private static String getPropertyValue(String line, String name) {
  902. int start = line.indexOf( name + "=" );
  903. if (start == -1) {
  904. return null;
  905. }
  906. start += name.length() + 1;
  907. int end = line.indexOf("\"", start + 1);
  908. return line.substring( start, end + 1 );
  909. }
  910. /**
  911. * Get the value of the element in input. (Note: the returned value has no quotes.)
  912. */
  913. private static String getElementValue(String line, String name) {
  914. assert(line.contains("<" + name + ">"));
  915. int start = line.indexOf("<" + name + ">") + name.length() + 2;
  916. int end = line.indexOf("</" + name + ">");
  917. return line.substring(start, end);
  918. }
  919. private Pattern[] toPattern(String[] patternStrs) {
  920. Pattern[] patterns = new Pattern[patternStrs.length];
  921. for (int i = 0; i < patternStrs.length; i++) {
  922. patterns[i] = Pattern.compile(patternStrs[i]);
  923. }
  924. return patterns;
  925. }
  926. private void maskPatterns(Pattern[] patterns, String fname) throws Exception {
  927. String maskPattern = "#### A masked pattern was here ####";
  928. String line;
  929. BufferedReader in;
  930. BufferedWriter out;
  931. in = new BufferedReader(new FileReader(fname));
  932. out = new BufferedWriter(new FileWriter(fname + ".orig"));
  933. while (null != (line = in.readLine())) {
  934. // Ignore the empty lines on windows
  935. if(line.isEmpty() && Shell.WINDOWS) {
  936. continue;
  937. }
  938. out.write(line);
  939. out.write('\n');
  940. }
  941. in.close();
  942. out.close();
  943. in = new BufferedReader(new FileReader(fname + ".orig"));
  944. out = new BufferedWriter(new FileWriter(fname));
  945. boolean lastWasMasked = false;
  946. while (null != (line = in.readLine())) {
  947. for (Pattern pattern : patterns) {
  948. line = pattern.matcher(line).replaceAll(maskPattern);
  949. }
  950. if (line.equals(maskPattern)) {
  951. // We're folding multiple masked lines into one.
  952. if (!lastWasMasked) {
  953. out.write(line);
  954. out.write("\n");
  955. lastWasMasked = true;
  956. }
  957. } else {
  958. out.write(line);
  959. out.write("\n");
  960. lastWasMasked = false;
  961. }
  962. }
  963. in.close();
  964. out.close();
  965. }
  966. private final Pattern[] planMask = toPattern(new String[] {
  967. ".*file:.*",
  968. ".*pfile:.*",
  969. ".*hdfs:.*",
  970. ".*/tmp/.*",
  971. ".*invalidscheme:.*",
  972. ".*lastUpdateTime.*",
  973. ".*lastAccessTime.*",
  974. ".*lastModifiedTime.*",
  975. ".*[Oo]wner.*",
  976. ".*CreateTime.*",
  977. ".*LastAccessTime.*",
  978. ".*Location.*",
  979. ".*LOCATION '.*",
  980. ".*transient_lastDdlTime.*",
  981. ".*last_modified_.*",
  982. ".*at org.*",
  983. ".*at sun.*",
  984. ".*at java.*",
  985. ".*at junit.*",
  986. ".*Caused by:.*",
  987. ".*LOCK_QUERYID:.*",
  988. ".*LOCK_TIME:.*",
  989. ".*grantTime.*",
  990. ".*[.][.][.] [0-9]* more.*",
  991. ".*job_[0-9_]*.*",
  992. ".*job_local[0-9_]*.*",
  993. ".*USING 'java -cp.*",
  994. "^Deleted.*",
  995. });
  996. public int checkCliDriverResults(String tname) throws Exception {
  997. String[] cmdArray;
  998. assert(qMap.containsKey(tname));
  999. String outFileName = outPath(outDir, tname + ".out");
  1000. File f = new File(logDir, tname + ".out");
  1001. maskPatterns(planMask, f.getPath());
  1002. int exitVal = executeDiffCommand(f.getPath(),
  1003. outFileName, false,
  1004. qSortSet.contains(tname));
  1005. if (exitVal != 0 && overWrite) {
  1006. exitVal = overwriteResults(f.getPath(), outFileName);
  1007. }
  1008. return exitVal;
  1009. }
  1010. private static int overwriteResults(String inFileName, String outFileName) throws Exception {
  1011. // This method can be replaced with Files.copy(source, target, REPLACE_EXISTING)
  1012. // once Hive uses JAVA 7.
  1013. System.out.println("Overwriting results");
  1014. return executeCmd(new String[] {
  1015. "cp",
  1016. getQuotedString(inFileName),
  1017. getQuotedString(outFileName)
  1018. });
  1019. }
  1020. private static int executeDiffCommand(String inFileName,
  1021. String outFileName,
  1022. boolean ignoreWhiteSpace,
  1023. boolean sortResults
  1024. ) throws Exception {
  1025. int result = 0;
  1026. if (sortResults) {
  1027. // sort will try to open the output file in write mode on windows. We need to
  1028. // close it first.
  1029. SessionState ss = SessionState.get();
  1030. if (ss != null && ss.out != null && ss.out != System.out) {
  1031. ss.out.close();
  1032. }
  1033. String inSorted = inFileName + SORT_SUFFIX;
  1034. String outSorted = outFileName + SORT_SUFFIX;
  1035. result = sortFiles(inFileName, inSorted);
  1036. result |= sortFiles(outFileName, outSorted);
  1037. if (result != 0) {
  1038. System.err.println("ERROR: Could not sort files before comparing");
  1039. return result;
  1040. }
  1041. inFileName = inSorted;
  1042. outFileName = outSorted;
  1043. }
  1044. ArrayList<String> diffCommandArgs = new ArrayList<String>();
  1045. diffCommandArgs.add("diff");
  1046. // Text file comparison
  1047. diffCommandArgs.add("-a");
  1048. // Ignore changes in the amount of white space
  1049. if (ignoreWhiteSpace || Shell.WINDOWS) {
  1050. diffCommandArgs.add("-b");
  1051. }
  1052. // Files created on Windows machines have different line endings
  1053. // than files created on Unix/Linux. Windows uses carriage return and line feed
  1054. // ("\r\n") as a line ending, whereas Unix uses just line feed ("\n").
  1055. // Also StringBuilder.toString(), Stream to String conversions adds extra
  1056. // spaces at the end of the line.
  1057. if (Shell.WINDOWS) {
  1058. diffCommandArgs.add("--strip-trailing-cr"); // Strip trailing carriage return on input
  1059. diffCommandArgs.add("-B"); // Ignore changes whose lines are all blank
  1060. }
  1061. // Add files to compare to the arguments list
  1062. diffCommandArgs.add(getQuotedString(inFileName));
  1063. diffCommandArgs.add(getQuotedString(outFileName));
  1064. result = executeCmd(diffCommandArgs);
  1065. if (sortResults) {
  1066. new File(inFileName).delete();
  1067. new File(outFileName).delete();
  1068. }
  1069. return result;
  1070. }
  1071. private static int sortFiles(String in, String out) throws Exception {
  1072. return executeCmd(new String[] {
  1073. "sort",
  1074. getQuotedString(in),
  1075. }, out, null);
  1076. }
  1077. private static int executeCmd(Collection<String> args) throws Exception {
  1078. return executeCmd(args, null, null);
  1079. }
  1080. private static int executeCmd(String[] args) throws Exception {
  1081. return executeCmd(args, null, null);
  1082. }
  1083. private static int executeCmd(Collection<String> args, String outFile, String errFile) throws Exception {
  1084. String[] cmdArray = (String[]) args.toArray(new String[args.size()]);
  1085. return executeCmd(cmdArray, outFile, errFile);
  1086. }
  1087. private static int executeCmd(String[] args, String outFile, String errFile) throws Exception {
  1088. System.out.println("Running: " + org.apache.commons.lang.StringUtils.join(args, ' '));
  1089. PrintStream out = outFile == null ?
  1090. SessionState.getConsole().getChildOutStream() :
  1091. new PrintStream(new FileOutputStream(outFile), true);
  1092. PrintStream err = errFile == null ?
  1093. SessionState.getConsole().getChildErrStream() :
  1094. new PrintStream(new FileOutputStream(errFile), true);
  1095. Process executor = Runtime.getRuntime().exec(args);
  1096. StreamPrinter errPrinter = new StreamPrinter(executor.getErrorStream(), null, err);
  1097. StreamPrinter outPrinter = new StreamPrinter(executor.getInputStream(), null, out);
  1098. outPrinter.start();
  1099. errPrinter.start();
  1100. int result = executor.waitFor();
  1101. outPrinter.join();
  1102. errPrinter.join();
  1103. if (outFile != null) {
  1104. out.close();
  1105. }
  1106. if (errFile != null) {
  1107. err.close();
  1108. }
  1109. return result;
  1110. }
  1111. private static String getQuotedString(String str){
  1112. return Shell.WINDOWS ? String.format("\"%s\"", str) : str;
  1113. }
  1114. public ASTNode parseQuery(String tname) throws Exception {
  1115. return pd.parse(qMap.get(tname));
  1116. }
  1117. public void resetParser() throws SemanticException {
  1118. drv.init();
  1119. pd = new ParseDriver();
  1120. sem = new SemanticAnalyzer(conf);
  1121. }
  1122. public List<Task<? extends Serializable>> analyzeAST(ASTNode ast) throws Exception {
  1123. // Do semantic analysis and plan generation
  1124. Context ctx = new Context(conf);
  1125. while ((ast.getToken() == null) && (ast.getChildCount() > 0)) {
  1126. ast = (ASTNode) ast.getChild(0);
  1127. }
  1128. sem.getOutputs().clear();
  1129. sem.getInputs().clear();
  1130. sem.analyze(ast, ctx);
  1131. ctx.clear();
  1132. return sem.getRootTasks();
  1133. }
  1134. public TreeMap<String, String> getQMap() {
  1135. return qMap;
  1136. }
  1137. /**
  1138. * QTestSetup defines test fixtures which are reused across testcases,
  1139. * and are needed before any test can be run
  1140. */
  1141. public static class QTestSetup
  1142. {
  1143. private MiniZooKeeperCluster zooKeeperCluster = null;
  1144. private int zkPort;
  1145. private ZooKeeper zooKeeper;
  1146. public QTestSetup() {
  1147. }
  1148. public void preTest(HiveConf conf) throws Exception {
  1149. if (zooKeeperCluster == null) {
  1150. String tmpdir = System.getProperty("user.dir")+"/../build/ql/tmp";
  1151. zooKeeperCluster = new MiniZooKeeperCluster();
  1152. zkPort = zooKeeperCluster.startup(new File(tmpdir, "zookeeper"));
  1153. }
  1154. if (zooKeeper != null) {
  1155. zooKeeper.close();
  1156. }
  1157. int sessionTimeout = conf.getIntVar(HiveConf.ConfVars.HIVE_ZOOKEEPER_SESSION_TIMEOUT);
  1158. zooKeeper = new ZooKeeper("localhost:" + zkPort, sessionTimeout, null);
  1159. String zkServer = "localhost";
  1160. conf.set("hive.zookeeper.quorum", zkServer);
  1161. conf.set("hive.zookeeper.client.port", "" + zkPort);
  1162. }
  1163. public void postTest(HiveConf conf) throws Exception {
  1164. if (zooKeeperCluster == null) {
  1165. return;
  1166. }
  1167. if (zooKeeper != null) {
  1168. zooKeeper.close();
  1169. }
  1170. ZooKeeperHiveLockManager.releaseAllLocks(conf);
  1171. }
  1172. public void tearDown() throws Exception {
  1173. if (zooKeeperCluster != null) {
  1174. zooKeeperCluster.shutdown();
  1175. zooKeeperCluster = null;
  1176. }
  1177. }
  1178. }
  1179. /**
  1180. * QTRunner: Runnable class for running a a single query file.
  1181. *
  1182. **/
  1183. public static class QTRunner implements Runnable {
  1184. private final QTestUtil qt;
  1185. private final String fname;
  1186. public QTRunner(QTestUtil qt, String fname) {
  1187. this.qt = qt;
  1188. this.fname = fname;
  1189. }
  1190. public void run() {
  1191. try {
  1192. // assumption is that environment has already been cleaned once globally
  1193. // hence each thread does not call cleanUp() and createSources() again
  1194. qt.cliInit(fname, false);
  1195. qt.executeClient(fname);
  1196. } catch (Throwable e) {
  1197. System.err.println("Query file " + fname + " failed with exception "
  1198. + e.getMessage());
  1199. e.printStackTrace();
  1200. outputTestFailureHelpMessage();
  1201. }
  1202. }
  1203. }
  1204. /**
  1205. * Setup to execute a set of query files. Uses QTestUtil to do so.
  1206. *
  1207. * @param qfiles
  1208. * array of input query files containing arbitrary number of hive
  1209. * queries
  1210. * @param resDir
  1211. * output directory
  1212. * @param logDir
  1213. * log directory
  1214. * @return one QTestUtil for each query file
  1215. */
  1216. public static QTestUtil[] queryListRunnerSetup(File[] qfiles, String resDir,
  1217. String logDir) throws Exception
  1218. {
  1219. QTestUtil[] qt = new QTestUtil[qfiles.length];
  1220. for (int i = 0; i < qfiles.length; i++) {
  1221. qt[i] = new QTestUtil(resDir, logDir, false, "0.20");
  1222. qt[i].addFile(qfiles[i]);
  1223. qt[i].clearTestSideEffects();
  1224. }
  1225. return qt;
  1226. }
  1227. /**
  1228. * Executes a set of query files in sequence.
  1229. *
  1230. * @param qfiles
  1231. * array of input query files containing arbitrary number of hive
  1232. * queries
  1233. * @param qt
  1234. * array of QTestUtils, one per qfile
  1235. * @return true if all queries passed, false otw
  1236. */
  1237. public static boolean queryListRunnerSingleThreaded(File[] qfiles, QTestUtil[] qt)
  1238. throws Exception
  1239. {
  1240. boolean failed = false;
  1241. qt[0].cleanUp();
  1242. qt[0].createSources();
  1243. for (int i = 0; i < qfiles.length && !failed; i++) {
  1244. qt[i].clearTestSideEffects();
  1245. qt[i].cliInit(qfiles[i].getName(), false);
  1246. qt[i].executeClient(qfiles[i].getName());
  1247. int ecode = qt[i].checkCliDriverResults(qfiles[i].getName());
  1248. if (ecode != 0) {
  1249. failed = true;
  1250. System.err.println("Test " + qfiles[i].getName()
  1251. + " results check failed with error code " + ecode);
  1252. outputTestFailureHelpMessage();
  1253. }
  1254. qt[i].clearPostTestEffects();
  1255. }
  1256. return (!failed);
  1257. }
  1258. /**
  1259. * Executes a set of query files parallel.
  1260. *
  1261. * Each query file is run in a separate thread. The caller has to arrange
  1262. * that different query files do not collide (in terms of destination tables)
  1263. *
  1264. * @param qfiles
  1265. * array of input query files containing arbitrary number of hive
  1266. * queries
  1267. * @param qt
  1268. * array of QTestUtils, one per qfile
  1269. * @return true if all queries passed, false otw
  1270. *
  1271. */
  1272. public static boolean queryListRunnerMultiThreaded(File[] qfiles, QTestUtil[] qt)
  1273. throws Exception
  1274. {
  1275. boolean failed = false;
  1276. // in multithreaded mode - do cleanup/initialization just once
  1277. qt[0].cleanUp();
  1278. qt[0].createSources();
  1279. qt[0].clearTestSideEffects();
  1280. QTRunner[] qtRunners = new QTestUtil.QTRunner[qfiles.length];
  1281. Thread[] qtThread = new Thread[qfiles.length];
  1282. for (int i = 0; i < qfiles.length; i++) {
  1283. qtRunners[i] = new QTestUtil.QTRunner(qt[i], qfiles[i].getName());
  1284. qtThread[i] = new Thread(qtRunners[i]);
  1285. }
  1286. for (int i = 0; i < qfiles.length; i++) {
  1287. qtThread[i].start();
  1288. }
  1289. for (int i = 0; i < qfiles.length; i++) {
  1290. qtThread[i].join();
  1291. int ecode = qt[i].checkCliDriverResults(qfiles[i].getName());
  1292. if (ecode != 0) {
  1293. failed = true;
  1294. System.err.println("Test " + qfiles[i].getName()
  1295. + " results check failed with error code " + ecode);
  1296. outputTestFailureHelpMessage();
  1297. }
  1298. }
  1299. return (!failed);
  1300. }
  1301. public static void outputTestFailureHelpMessage() {
  1302. System.err.println("See build/ql/tmp/hive.log, "
  1303. + "or try \"ant test ... -Dtest.silent=false\" to get more logs.");
  1304. System.err.flush();
  1305. }
  1306. public static String ensurePathEndsInSlash(String path) {
  1307. if(path == null) {
  1308. throw new NullPointerException("Path cannot be null");
  1309. }
  1310. if(path.endsWith(File.separator)) {
  1311. return path;
  1312. } else {
  1313. return path + File.separator;
  1314. }
  1315. }
  1316. }