• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
15 package com.android;
16 
17 import static org.junit.Assert.assertFalse;
18 
19 import android.support.test.filters.LargeTest;
20 import android.support.test.filters.MediumTest;
21 import android.support.test.filters.SmallTest;
22 import android.support.test.internal.runner.ClassPathScanner;
23 import android.support.test.internal.runner.ClassPathScanner.ChainedClassNameFilter;
24 import android.support.test.internal.runner.ClassPathScanner.ExternalClassNameFilter;
25 import android.support.test.internal.runner.TestLoader;
26 import android.testing.AndroidTestingRunner;
27 import android.text.TextUtils;
28 import android.util.Log;
29 
30 import com.android.systemui.SysuiBaseFragmentTest;
31 import com.android.systemui.SysuiTestCase;
32 
33 import org.junit.Test;
34 import org.junit.runner.RunWith;
35 
36 import java.io.IOException;
37 import java.util.Arrays;
38 import java.util.Collection;
39 import 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
53 public 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
testAllClassInheritance()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 
hasSize(Class<?> cls)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 
getClassNamesFromClassPath()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 
getClsStr()124     private String getClsStr() {
125         return TextUtils.join(",", Arrays.asList(BASE_CLS_WHITELIST)
126                 .stream().map(cls -> cls.getSimpleName()).toArray());
127     }
128 }
129