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