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 */
018
019package org.apache.hadoop.hbase;
020
021import java.io.IOException;
022import java.util.Set;
023import java.util.regex.Pattern;
024
025import org.apache.hadoop.hbase.testclassification.IntegrationTests;
026import org.apache.hadoop.hbase.util.AbstractHBaseTool;
027import org.apache.hadoop.util.ToolRunner;
028import org.junit.internal.TextListener;
029import org.junit.runner.JUnitCore;
030import org.junit.runner.Result;
031import org.slf4j.Logger;
032import org.slf4j.LoggerFactory;
033
034import org.apache.hbase.thirdparty.org.apache.commons.cli.CommandLine;
035
036/**
037 * This class drives the Integration test suite execution. Executes all
038 * tests having @Category(IntegrationTests.class) annotation against an
039 * already deployed distributed cluster.
040 */
041public class IntegrationTestsDriver extends AbstractHBaseTool {
042  private static final String SHORT_REGEX_ARG = "r";
043  private static final String LONG_REGEX_ARG = "regex";
044  private static final Logger LOG = LoggerFactory.getLogger(IntegrationTestsDriver.class);
045  private IntegrationTestFilter intTestFilter = new IntegrationTestFilter();
046
047  public static void main(String[] args) throws Exception {
048    int ret = ToolRunner.run(new IntegrationTestsDriver(), args);
049    System.exit(ret);
050  }
051
052  private class IntegrationTestFilter extends ClassTestFinder.TestClassFilter {
053    private Pattern testFilterRe = Pattern.compile(".*\\.IntegrationTest.*");
054    public IntegrationTestFilter() {
055      super(IntegrationTests.class);
056    }
057
058    public void setPattern(String pattern) {
059      testFilterRe = Pattern.compile(pattern);
060    }
061
062    @Override
063    public boolean isCandidateClass(Class<?> c) {
064      return testFilterRe.matcher(c.getName()).find() &&
065        // Our pattern will match the below NON-IntegrationTest. Rather than
066        // do exotic regex, just filter it out here
067        !c.getName().contains("IntegrationTestingUtility") &&
068        super.isCandidateClass(c);
069    }
070  }
071
072  @Override
073  protected void addOptions() {
074    addOptWithArg(SHORT_REGEX_ARG, LONG_REGEX_ARG,
075      "Java regex to use selecting tests to run: e.g. .*TestBig.*" +
076      " will select all tests that include TestBig in their name.  Default: " +
077      ".*IntegrationTest.*");
078  }
079
080  @Override
081  protected void processOptions(CommandLine cmd) {
082    String testFilterString = cmd.getOptionValue(SHORT_REGEX_ARG, null);
083    if (testFilterString != null) {
084      intTestFilter.setPattern(testFilterString);
085    }
086  }
087
088  /**
089   * Returns test classes annotated with @Category(IntegrationTests.class),
090   * according to the filter specific on the command line (if any).
091   */
092  private Class<?>[] findIntegrationTestClasses()
093    throws ClassNotFoundException, LinkageError, IOException {
094    ClassTestFinder.TestFileNameFilter nameFilter = new ClassTestFinder.TestFileNameFilter();
095    ClassFinder classFinder = new ClassFinder(nameFilter, nameFilter, intTestFilter);
096    Set<Class<?>> classes = classFinder.findClasses(true);
097    return classes.toArray(new Class<?>[classes.size()]);
098  }
099
100
101  @Override
102  protected int doWork() throws Exception {
103    //this is called from the command line, so we should set to use the distributed cluster
104    IntegrationTestingUtility.setUseDistributedCluster(conf);
105    Class<?>[] classes = findIntegrationTestClasses();
106    LOG.info("Found " + classes.length + " integration tests to run:");
107    for (Class<?> aClass : classes) {
108      LOG.info("  " + aClass);
109    }
110    JUnitCore junit = new JUnitCore();
111    junit.addListener(new TextListener(System.out));
112    Result result = junit.run(classes);
113
114    return result.wasSuccessful() ? 0 : 1;
115  }
116}