1 /* 2 * Copyright (C) 2019 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 * use this file except in compliance with the License. You may obtain a copy of 6 * the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 * License for the specific language governing permissions and limitations under 14 * the License. 15 */ 16 package com.android.launcher3.util.rule; 17 18 import static androidx.test.InstrumentationRegistry.getInstrumentation; 19 20 import static org.junit.Assume.assumeTrue; 21 22 import android.content.pm.PackageManager; 23 import android.os.Build; 24 import android.util.Log; 25 26 import androidx.test.InstrumentationRegistry; 27 import androidx.test.uiautomator.UiDevice; 28 29 import org.junit.rules.TestRule; 30 import org.junit.runner.Description; 31 import org.junit.runners.model.Statement; 32 33 import java.lang.annotation.ElementType; 34 import java.lang.annotation.Retention; 35 import java.lang.annotation.RetentionPolicy; 36 import java.lang.annotation.Target; 37 import java.util.regex.Matcher; 38 import java.util.regex.Pattern; 39 40 public class TestStabilityRule implements TestRule { 41 private static final String TAG = "TestStabilityRule"; 42 private static final Pattern LAUNCHER_BUILD = 43 Pattern.compile("^(" 44 + "(?<local>(BuildFromAndroidStudio|" 45 + "([0-9]+|[A-Z])-eng\\.[a-z]+\\.[0-9]+\\.[0-9]+))|" 46 + "(?<platform>([A-Z][a-z]*[0-9]*|[0-9]+)*)" 47 + ")$"); 48 private static final Pattern PLATFORM_BUILD = 49 Pattern.compile("^(" 50 + "(?<commandLine>eng\\.[a-z]+\\.[0-9]+\\.[0-9]+)|" 51 + "(?<presubmit>P[0-9]+)|" 52 + "(?<postsubmit>[0-9]+)" 53 + ")$"); 54 55 public static final int LOCAL = 0x1; 56 public static final int PLATFORM_PRESUBMIT = 0x8; 57 public static final int PLATFORM_POSTSUBMIT = 0x10; 58 59 private static int sRunFlavor; 60 61 @Retention(RetentionPolicy.RUNTIME) 62 @Target(ElementType.METHOD) 63 public @interface Stability { flavors()64 int flavors(); 65 } 66 67 @Override apply(Statement base, Description description)68 public Statement apply(Statement base, Description description) { 69 final Stability stability = description.getAnnotation(Stability.class); 70 if (stability != null) { 71 return new Statement() { 72 @Override 73 public void evaluate() throws Throwable { 74 assumeTrue("Ignoring the test due to @Stability annotation", 75 (stability.flavors() & getRunFlavor()) != 0); 76 base.evaluate(); 77 } 78 }; 79 } else { 80 return base; 81 } 82 } 83 84 public static int getRunFlavor() { 85 if (sRunFlavor != 0) return sRunFlavor; 86 87 final String flavorOverride = InstrumentationRegistry.getArguments().getString("flavor"); 88 89 if (flavorOverride != null) { 90 Log.d(TAG, "Flavor override: " + flavorOverride); 91 try { 92 return (int) TestStabilityRule.class.getField(flavorOverride).get(null); 93 } catch (NoSuchFieldException e) { 94 throw new AssertionError("Unrecognized run flavor override: " + flavorOverride); 95 } catch (IllegalAccessException e) { 96 throw new RuntimeException(e); 97 } 98 } 99 100 final String launcherVersion; 101 try { 102 final String launcherPackageName = UiDevice.getInstance(getInstrumentation()) 103 .getLauncherPackageName(); 104 Log.d(TAG, "Launcher package: " + launcherPackageName); 105 106 launcherVersion = getInstrumentation(). 107 getContext(). 108 getPackageManager(). 109 getPackageInfo(launcherPackageName, 0) 110 .versionName; 111 } catch (PackageManager.NameNotFoundException e) { 112 throw new RuntimeException(e); 113 } 114 115 final String platformVersion = Build.VERSION.INCREMENTAL; 116 117 Log.d(TAG, "Launcher: " + launcherVersion + ", platform: " + platformVersion); 118 119 final Matcher launcherBuildMatcher = LAUNCHER_BUILD.matcher(launcherVersion); 120 if (!launcherBuildMatcher.find()) { 121 throw new AssertionError("Launcher build match not found"); 122 } 123 124 final Matcher platformBuildMatcher = PLATFORM_BUILD.matcher(platformVersion); 125 if (!platformBuildMatcher.find()) { 126 throw new AssertionError("Platform build match not found"); 127 } 128 129 if (launcherBuildMatcher.group("local") != null && ( 130 platformBuildMatcher.group("commandLine") != null || 131 platformBuildMatcher.group("postsubmit") != null)) { 132 Log.d(TAG, "LOCAL RUN"); 133 sRunFlavor = LOCAL; 134 } else if (launcherBuildMatcher.group("platform") != null 135 && platformBuildMatcher.group("presubmit") != null) { 136 Log.d(TAG, "PLATFORM PRESUBMIT"); 137 sRunFlavor = PLATFORM_PRESUBMIT; 138 } else if (launcherBuildMatcher.group("platform") != null 139 && (platformBuildMatcher.group("postsubmit") != null 140 || platformBuildMatcher.group("commandLine") != null)) { 141 Log.d(TAG, "PLATFORM POSTSUBMIT"); 142 sRunFlavor = PLATFORM_POSTSUBMIT; 143 } else { 144 throw new AssertionError("Unrecognized run flavor"); 145 } 146 147 return sRunFlavor; 148 } 149 } 150