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