|  | @@ -25,14 +25,11 @@ import java.nio.file.FileVisitResult;
 | 
	
		
			
				|  |  |  import java.nio.file.FileVisitor;
 | 
	
		
			
				|  |  |  import java.nio.file.Files;
 | 
	
		
			
				|  |  |  import java.nio.file.Path;
 | 
	
		
			
				|  |  | +import java.nio.file.Paths;
 | 
	
		
			
				|  |  |  import java.nio.file.attribute.BasicFileAttributes;
 | 
	
		
			
				|  |  |  import java.util.HashSet;
 | 
	
		
			
				|  |  |  import java.util.Set;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -import org.apache.lucene.util.LuceneTestCase;
 | 
	
		
			
				|  |  | -import org.elasticsearch.common.SuppressForbidden;
 | 
	
		
			
				|  |  | -import org.elasticsearch.common.io.PathUtils;
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  |  /**
 | 
	
		
			
				|  |  |   * Checks that all tests in a directory are named according to our naming conventions. This is important because tests that do not follow
 | 
	
		
			
				|  |  |   * our conventions aren't run by gradle. This was once a glorious unit test but now that Elasticsearch is a multi-module project it must be
 | 
	
	
		
			
				|  | @@ -46,11 +43,13 @@ import org.elasticsearch.common.io.PathUtils;
 | 
	
		
			
				|  |  |   * {@code --self-test} that is only run in the test:framework project.
 | 
	
		
			
				|  |  |   */
 | 
	
		
			
				|  |  |  public class NamingConventionsCheck {
 | 
	
		
			
				|  |  | -    public static void main(String[] args) throws IOException, ClassNotFoundException {
 | 
	
		
			
				|  |  | -        NamingConventionsCheck check = new NamingConventionsCheck();
 | 
	
		
			
				|  |  | +    public static void main(String[] args) throws IOException {
 | 
	
		
			
				|  |  | +        int i = 0;
 | 
	
		
			
				|  |  | +        NamingConventionsCheck check = new NamingConventionsCheck(
 | 
	
		
			
				|  |  | +                loadClassWithoutInitializing(args[i++]),
 | 
	
		
			
				|  |  | +                loadClassWithoutInitializing(args[i++]));
 | 
	
		
			
				|  |  |          boolean skipIntegTestsInDisguise = false;
 | 
	
		
			
				|  |  |          boolean selfTest = false;
 | 
	
		
			
				|  |  | -        int i = 0;
 | 
	
		
			
				|  |  |          while (true) {
 | 
	
		
			
				|  |  |              switch (args[i]) {
 | 
	
		
			
				|  |  |              case "--skip-integ-tests-in-disguise":
 | 
	
	
		
			
				|  | @@ -69,7 +68,7 @@ public class NamingConventionsCheck {
 | 
	
		
			
				|  |  |              }
 | 
	
		
			
				|  |  |              break;
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  | -        check.check(PathUtils.get(args[i]));
 | 
	
		
			
				|  |  | +        check.check(Paths.get(args[i]));
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |          if (selfTest) {
 | 
	
		
			
				|  |  |              assertViolation("WrongName", check.missingSuffix);
 | 
	
	
		
			
				|  | @@ -82,14 +81,12 @@ public class NamingConventionsCheck {
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |          // Now we should have no violations
 | 
	
		
			
				|  |  | -        assertNoViolations("Not all subclasses of " + ESTestCase.class.getSimpleName()
 | 
	
		
			
				|  |  | +        assertNoViolations("Not all subclasses of " + check.testClass.getSimpleName()
 | 
	
		
			
				|  |  |                  + " match the naming convention. Concrete classes must end with [Tests]", check.missingSuffix);
 | 
	
		
			
				|  |  |          assertNoViolations("Classes ending with [Tests] are abstract or interfaces", check.notRunnable);
 | 
	
		
			
				|  |  |          assertNoViolations("Found inner classes that are tests, which are excluded from the test runner", check.innerClasses);
 | 
	
		
			
				|  |  | -        String classesToSubclass = String.join(",", ESTestCase.class.getSimpleName(), ESTestCase.class.getSimpleName(),
 | 
	
		
			
				|  |  | -                ESTokenStreamTestCase.class.getSimpleName(), LuceneTestCase.class.getSimpleName());
 | 
	
		
			
				|  |  | -        assertNoViolations("Pure Unit-Test found must subclass one of [" + classesToSubclass + "]", check.pureUnitTest);
 | 
	
		
			
				|  |  | -        assertNoViolations("Classes ending with [Tests] must subclass [" + classesToSubclass + "]", check.notImplementing);
 | 
	
		
			
				|  |  | +        assertNoViolations("Pure Unit-Test found must subclass [" + check.testClass.getSimpleName() + "]", check.pureUnitTest);
 | 
	
		
			
				|  |  | +        assertNoViolations("Classes ending with [Tests] must subclass [" + check.testClass.getSimpleName() + "]", check.notImplementing);
 | 
	
		
			
				|  |  |          if (!skipIntegTestsInDisguise) {
 | 
	
		
			
				|  |  |              assertNoViolations("Subclasses of ESIntegTestCase should end with IT as they are integration tests",
 | 
	
		
			
				|  |  |                      check.integTestsInDisguise);
 | 
	
	
		
			
				|  | @@ -103,6 +100,14 @@ public class NamingConventionsCheck {
 | 
	
		
			
				|  |  |      private final Set<Class<?>> notRunnable = new HashSet<>();
 | 
	
		
			
				|  |  |      private final Set<Class<?>> innerClasses = new HashSet<>();
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +    private final Class<?> testClass;
 | 
	
		
			
				|  |  | +    private final Class<?> integTestClass;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    public NamingConventionsCheck(Class<?> testClass, Class<?> integTestClass) {
 | 
	
		
			
				|  |  | +        this.testClass = testClass;
 | 
	
		
			
				|  |  | +        this.integTestClass = integTestClass;
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |      public void check(Path rootPath) throws IOException {
 | 
	
		
			
				|  |  |          Files.walkFileTree(rootPath, new FileVisitor<Path>() {
 | 
	
		
			
				|  |  |              /**
 | 
	
	
		
			
				|  | @@ -136,9 +141,9 @@ public class NamingConventionsCheck {
 | 
	
		
			
				|  |  |                  String filename = file.getFileName().toString();
 | 
	
		
			
				|  |  |                  if (filename.endsWith(".class")) {
 | 
	
		
			
				|  |  |                      String className = filename.substring(0, filename.length() - ".class".length());
 | 
	
		
			
				|  |  | -                    Class<?> clazz = loadClass(className);
 | 
	
		
			
				|  |  | +                    Class<?> clazz = loadClassWithoutInitializing(packageName + className);
 | 
	
		
			
				|  |  |                      if (clazz.getName().endsWith("Tests")) {
 | 
	
		
			
				|  |  | -                        if (ESIntegTestCase.class.isAssignableFrom(clazz)) {
 | 
	
		
			
				|  |  | +                        if (integTestClass.isAssignableFrom(clazz)) {
 | 
	
		
			
				|  |  |                              integTestsInDisguise.add(clazz);
 | 
	
		
			
				|  |  |                          }
 | 
	
		
			
				|  |  |                          if (Modifier.isAbstract(clazz.getModifiers()) || Modifier.isInterface(clazz.getModifiers())) {
 | 
	
	
		
			
				|  | @@ -164,15 +169,7 @@ public class NamingConventionsCheck {
 | 
	
		
			
				|  |  |              }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |              private boolean isTestCase(Class<?> clazz) {
 | 
	
		
			
				|  |  | -                return LuceneTestCase.class.isAssignableFrom(clazz);
 | 
	
		
			
				|  |  | -            }
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -            private Class<?> loadClass(String className) {
 | 
	
		
			
				|  |  | -                try {
 | 
	
		
			
				|  |  | -                    return Thread.currentThread().getContextClassLoader().loadClass(packageName + className);
 | 
	
		
			
				|  |  | -                } catch (ClassNotFoundException e) {
 | 
	
		
			
				|  |  | -                    throw new RuntimeException(e);
 | 
	
		
			
				|  |  | -                }
 | 
	
		
			
				|  |  | +                return testClass.isAssignableFrom(clazz);
 | 
	
		
			
				|  |  |              }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |              @Override
 | 
	
	
		
			
				|  | @@ -186,7 +183,6 @@ public class NamingConventionsCheck {
 | 
	
		
			
				|  |  |       * Fail the process if there are any violations in the set. Named to look like a junit assertion even though it isn't because it is
 | 
	
		
			
				|  |  |       * similar enough.
 | 
	
		
			
				|  |  |       */
 | 
	
		
			
				|  |  | -    @SuppressForbidden(reason = "System.err/System.exit")
 | 
	
		
			
				|  |  |      private static void assertNoViolations(String message, Set<Class<?>> set) {
 | 
	
		
			
				|  |  |          if (false == set.isEmpty()) {
 | 
	
		
			
				|  |  |              System.err.println(message + ":");
 | 
	
	
		
			
				|  | @@ -201,10 +197,9 @@ public class NamingConventionsCheck {
 | 
	
		
			
				|  |  |       * Fail the process if we didn't detect a particular violation. Named to look like a junit assertion even though it isn't because it is
 | 
	
		
			
				|  |  |       * similar enough.
 | 
	
		
			
				|  |  |       */
 | 
	
		
			
				|  |  | -    @SuppressForbidden(reason = "System.err/System.exit")
 | 
	
		
			
				|  |  | -    private static void assertViolation(String className, Set<Class<?>> set) throws ClassNotFoundException {
 | 
	
		
			
				|  |  | -        className = "org.elasticsearch.test.test.NamingConventionsCheckBadClasses$" + className;
 | 
	
		
			
				|  |  | -        if (false == set.remove(Class.forName(className))) {
 | 
	
		
			
				|  |  | +    private static void assertViolation(String className, Set<Class<?>> set) {
 | 
	
		
			
				|  |  | +        className = "org.elasticsearch.test.NamingConventionsCheckBadClasses$" + className;
 | 
	
		
			
				|  |  | +        if (false == set.remove(loadClassWithoutInitializing(className))) {
 | 
	
		
			
				|  |  |              System.err.println("Error in NamingConventionsCheck! Expected [" + className + "] to be a violation but wasn't.");
 | 
	
		
			
				|  |  |              System.exit(1);
 | 
	
		
			
				|  |  |          }
 | 
	
	
		
			
				|  | @@ -213,9 +208,20 @@ public class NamingConventionsCheck {
 | 
	
		
			
				|  |  |      /**
 | 
	
		
			
				|  |  |       * Fail the process with the provided message.
 | 
	
		
			
				|  |  |       */
 | 
	
		
			
				|  |  | -    @SuppressForbidden(reason = "System.err/System.exit")
 | 
	
		
			
				|  |  |      private static void fail(String reason) {
 | 
	
		
			
				|  |  |          System.err.println(reason);
 | 
	
		
			
				|  |  |          System.exit(1);
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    static Class<?> loadClassWithoutInitializing(String name) {
 | 
	
		
			
				|  |  | +        try {
 | 
	
		
			
				|  |  | +            return Class.forName(name,
 | 
	
		
			
				|  |  | +                    // Don't initialize the class to save time. Not needed for this test and this doesn't share a VM with any other tests.
 | 
	
		
			
				|  |  | +                    false,
 | 
	
		
			
				|  |  | +                    // Use our classloader rather than the bootstrap class loader.
 | 
	
		
			
				|  |  | +                    NamingConventionsCheck.class.getClassLoader());
 | 
	
		
			
				|  |  | +        } catch (ClassNotFoundException e) {
 | 
	
		
			
				|  |  | +            throw new RuntimeException(e);
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  |  }
 |