1/* 2 * Copyright (C) 2017 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file 5 * except in compliance with the License. You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software distributed under the 10 * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 11 * KIND, either express or implied. See the License for the specific language governing 12 * permissions and limitations under the License. 13 */ 14 15package com.android; 16 17import static org.junit.Assert.assertFalse; 18 19import android.support.test.filters.LargeTest; 20import android.support.test.filters.MediumTest; 21import android.support.test.filters.SmallTest; 22import android.support.test.internal.runner.ClassPathScanner; 23import android.support.test.internal.runner.ClassPathScanner.ChainedClassNameFilter; 24import android.support.test.internal.runner.ClassPathScanner.ExternalClassNameFilter; 25import android.support.test.internal.runner.TestLoader; 26import android.testing.AndroidTestingRunner; 27import android.text.TextUtils; 28import android.util.Log; 29 30import com.android.systemui.SysuiBaseFragmentTest; 31import com.android.systemui.SysuiTestCase; 32 33import org.junit.Test; 34import org.junit.runner.RunWith; 35 36import java.io.IOException; 37import java.util.Arrays; 38import java.util.Collection; 39import java.util.Collections; 40 41/** 42 * This is named AAAPlusPlusVerifySysuiRequiredTestPropertiesTest for two reasons. 43 * a) Its so awesome it deserves an AAA++ 44 * b) It should run first to draw attention to itself. 45 * 46 * For trues though: this test verifies that all the sysui tests extend the right classes. 47 * This matters because including tests with different context implementations in the same 48 * test suite causes errors, such as the incorrect settings provider being cached. 49 * For an example, see {@link com.android.systemui.DependencyTest}. 50 */ 51@RunWith(AndroidTestingRunner.class) 52@SmallTest 53public class AAAPlusPlusVerifySysuiRequiredTestPropertiesTest extends SysuiTestCase { 54 55 private static final String TAG = "AAA++VerifyTest"; 56 57 private static final Class[] BASE_CLS_WHITELIST = { 58 SysuiTestCase.class, 59 SysuiBaseFragmentTest.class, 60 }; 61 62 private static final Class[] SUPPORTED_SIZES = { 63 SmallTest.class, 64 MediumTest.class, 65 LargeTest.class, 66 android.test.suitebuilder.annotation.SmallTest.class, 67 android.test.suitebuilder.annotation.MediumTest.class, 68 android.test.suitebuilder.annotation.LargeTest.class, 69 }; 70 71 @Test 72 public void testAllClassInheritance() { 73 boolean anyClassWrong = false; 74 TestLoader loader = new TestLoader(); 75 for (String className : getClassNamesFromClassPath()) { 76 Class<?> cls = loader.loadIfTest(className); 77 if (cls == null) continue; 78 79 boolean hasParent = false; 80 for (Class<?> parent : BASE_CLS_WHITELIST) { 81 if (parent.isAssignableFrom(cls)) { 82 hasParent = true; 83 break; 84 } 85 } 86 boolean hasSize = hasSize(cls); 87 if (!hasSize) { 88 anyClassWrong = true; 89 Log.e(TAG, cls.getName() + " does not have size annotation, such as @SmallTest"); 90 } 91 if (!hasParent) { 92 anyClassWrong = true; 93 Log.e(TAG, cls.getName() + " does not extend any of " + getClsStr()); 94 } 95 } 96 97 assertFalse("All sysui test classes must have size and extend one of " + getClsStr(), 98 anyClassWrong); 99 } 100 101 private boolean hasSize(Class<?> cls) { 102 for (int i = 0; i < SUPPORTED_SIZES.length; i++) { 103 if (cls.getDeclaredAnnotation(SUPPORTED_SIZES[i]) != null) return true; 104 } 105 return false; 106 } 107 108 private Collection<String> getClassNamesFromClassPath() { 109 ClassPathScanner scanner = new ClassPathScanner(mContext.getPackageCodePath()); 110 111 ChainedClassNameFilter filter = new ChainedClassNameFilter(); 112 113 filter.add(new ExternalClassNameFilter()); 114 filter.add(s -> s.startsWith("com.android.systemui") 115 || s.startsWith("com.android.keyguard")); 116 try { 117 return scanner.getClassPathEntries(filter); 118 } catch (IOException e) { 119 Log.e(TAG, "Failed to scan classes", e); 120 } 121 return Collections.emptyList(); 122 } 123 124 private String getClsStr() { 125 return TextUtils.join(",", Arrays.asList(BASE_CLS_WHITELIST) 126 .stream().map(cls -> cls.getSimpleName()).toArray()); 127 } 128} 129