1 // Copyright 2023 The Chromium Authors 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 package org.chromium.testing.local; 6 7 import org.json.JSONArray; 8 import org.json.JSONException; 9 import org.json.JSONObject; 10 import org.junit.runner.Description; 11 import org.junit.runner.manipulation.Filter; 12 13 import java.util.HashMap; 14 import java.util.HashSet; 15 import java.util.Iterator; 16 import java.util.Map; 17 import java.util.Set; 18 19 /** Filters tests to only those listed in the JSON config. */ 20 class ConfigFilter extends Filter { 21 private final Map<String, Set<String>> mTestsByClass; 22 ConfigFilter(JSONObject configJson)23 public ConfigFilter(JSONObject configJson) throws JSONException { 24 Map<String, Set<String>> testsByClass = new HashMap<>(); 25 JSONObject configsObj = configJson.getJSONObject("configs"); 26 JSONObject classesObj = configsObj.getJSONObject(configsObj.keys().next()); 27 Iterator<String> classNames = classesObj.keys(); 28 while (classNames.hasNext()) { 29 String className = classNames.next(); 30 JSONArray methodNamesArr = classesObj.getJSONArray(className); 31 Set<String> methodsSet = new HashSet<>(methodNamesArr.length()); 32 for (int i = 0, len = methodNamesArr.length(); i < len; ++i) { 33 methodsSet.add(methodNamesArr.getString(i)); 34 } 35 testsByClass.put(className, methodsSet); 36 } 37 mTestsByClass = testsByClass; 38 } 39 classesFromConfig(JSONObject configJson)40 static Class[] classesFromConfig(JSONObject configJson) 41 throws JSONException, ClassNotFoundException { 42 JSONObject configsObj = configJson.getJSONObject("configs"); 43 if (configsObj.length() != 1) { 44 throw new IllegalArgumentException( 45 "JSON Config had " + configsObj.length() + " entries"); 46 } 47 JSONObject classesObj = configsObj.getJSONObject(configsObj.keys().next()); 48 Class[] ret = new Class[classesObj.length()]; 49 int i = 0; 50 Iterator<String> classNames = classesObj.keys(); 51 ClassLoader classLoader = JunitTestMain.class.getClassLoader(); 52 while (classNames.hasNext()) { 53 ret[i++] = Class.forName(classNames.next(), false, classLoader); 54 } 55 return ret; 56 } 57 58 @Override shouldRun(Description description)59 public boolean shouldRun(Description description) { 60 if (description.getMethodName() == null) { 61 return true; 62 } 63 Set<String> methodsSet = mTestsByClass.get(description.getClassName()); 64 if (methodsSet == null) { 65 return false; 66 } 67 return methodsSet.contains(description.getMethodName()); 68 } 69 70 @Override describe()71 public String describe() { 72 return "JSON Config filter"; 73 } 74 } 75