| // Copyright 2014 The Bazel Authors. All rights reserved. |
| // |
| // Licensed under the Apache License, Version 2.0 (the "License"); |
| // you may not use this file except in compliance with the License. |
| // You may obtain a copy of the License at |
| // |
| // http://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, software |
| // distributed under the License is distributed on an "AS IS" BASIS, |
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| // See the License for the specific language governing permissions and |
| // limitations under the License. |
| package com.google.devtools.build.lib.testutil; |
| |
| import com.google.devtools.build.lib.util.OS; |
| |
| import java.lang.reflect.InvocationTargetException; |
| import java.lang.reflect.Method; |
| |
| /** |
| * Test annotations used to select which tests to run in a given situation. |
| */ |
| public enum Suite { |
| |
| /** |
| * It's so blazingly fast and lightweight we run it whenever we make any |
| * build.lib change. This size is the default. |
| */ |
| SMALL_TESTS, |
| |
| /** |
| * It's a bit too slow to run all the time, but it still tests some |
| * unit of functionality. May run external commands such as gcc, for example. |
| */ |
| MEDIUM_TESTS, |
| |
| /** |
| * I don't even want to think about running this one after every edit, |
| * but I don't mind if the continuous build runs it, and I'm happy to have |
| * it before making a release. |
| */ |
| LARGE_TESTS, |
| |
| /** |
| * These tests take a long time. They should only ever be run manually and probably from their |
| * own Blaze test target. |
| */ |
| ENORMOUS_TESTS; |
| |
| /** |
| * Given a class, determine the test size. |
| */ |
| public static Suite getSize(Class<?> clazz) { |
| return getAnnotationElementOrDefault(clazz, "size"); |
| } |
| |
| /** |
| * Given a class, determine the suite it belongs to. |
| */ |
| public static String getSuiteName(Class<?> clazz) { |
| return getAnnotationElementOrDefault(clazz, "suite"); |
| } |
| |
| /** |
| * Given a class, determine if it is flaky. |
| */ |
| public static boolean isFlaky(Class<?> clazz) { |
| return getAnnotationElementOrDefault(clazz, "flaky"); |
| } |
| |
| /** |
| * Given a class, determine if it can run in a remote execution environment or on the local |
| * machine only. |
| */ |
| public static boolean isLocalOnly(Class<?> clazz) { |
| return getAnnotationElementOrDefault(clazz, "localOnly"); |
| } |
| |
| /** |
| * Given a class, determine the list of operating systems its tests can run under. |
| */ |
| public static OS[] getSupportedOs(Class<?> clazz) { |
| return getAnnotationElementOrDefault(clazz, "supportedOs"); |
| } |
| |
| /** |
| * Returns the value of the given element in the {@link TestSpec} annotation of the given class, |
| * or the default value of that element if the class doesn't have a {@link TestSpec} annotation. |
| */ |
| @SuppressWarnings("unchecked") |
| private static <T> T getAnnotationElementOrDefault(Class<?> clazz, String elementName) { |
| TestSpec spec = clazz.getAnnotation(TestSpec.class); |
| try { |
| Method method = TestSpec.class.getMethod(elementName); |
| return spec != null ? (T) method.invoke(spec) : (T) method.getDefaultValue(); |
| } catch (NoSuchMethodException e) { |
| throw new IllegalStateException("no such element " + elementName, e); |
| } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) { |
| throw new IllegalStateException("can't invoke accessor for element " + elementName, e); |
| } |
| } |
| } |