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 android.content.pm.PackageManager; 21 import android.os.Build; 22 import android.util.Log; 23 24 import androidx.test.InstrumentationRegistry; 25 import androidx.test.uiautomator.UiDevice; 26 27 import org.junit.rules.TestRule; 28 import org.junit.runner.Description; 29 import org.junit.runners.model.Statement; 30 31 import java.lang.annotation.ElementType; 32 import java.lang.annotation.Retention; 33 import java.lang.annotation.RetentionPolicy; 34 import java.lang.annotation.Target; 35 import java.util.regex.Matcher; 36 import java.util.regex.Pattern; 37 38 public class TestStabilityRule implements TestRule { 39 private static final String TAG = "TestStabilityRule"; 40 private static final Pattern LAUNCHER_BUILD = 41 Pattern.compile("^(" 42 + "(?<local>(BuildFromAndroidStudio|" 43 + "([0-9]+|[A-Z])-eng\\.[a-z]+\\.[0-9]+\\.[0-9]+))|" 44 + "(?<presubmit>([0-9]+|[A-Z])-P[0-9]+)|" 45 + "(?<postsubmit>([0-9]+|[A-Z])-[0-9]+)|" 46 + "(?<platform>[0-9]+|[A-Z])" 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 if ((stability.flavors() & getRunFlavor()) != 0) { 75 Log.d(TAG, "Running " + description.getDisplayName()); 76 base.evaluate(); 77 } else { 78 Log.d(TAG, "Skipping " + description.getDisplayName()); 79 } 80 } 81 }; 82 } else { 83 return base; 84 } 85 } 86 87 public static int getRunFlavor() { 88 if (sRunFlavor != 0) return sRunFlavor; 89 90 final String flavorOverride = InstrumentationRegistry.getArguments().getString("flavor"); 91 92 if (flavorOverride != null) { 93 Log.d(TAG, "Flavor override: " + flavorOverride); 94 try { 95 return (int) TestStabilityRule.class.getField(flavorOverride).get(null); 96 } catch (NoSuchFieldException e) { 97 throw new AssertionError("Unrecognized run flavor override: " + flavorOverride); 98 } catch (IllegalAccessException e) { 99 throw new RuntimeException(e); 100 } 101 } 102 103 final String launcherVersion; 104 try { 105 final String launcherPackageName = UiDevice.getInstance(getInstrumentation()) 106 .getLauncherPackageName(); 107 Log.d(TAG, "Launcher package: " + launcherPackageName); 108 109 launcherVersion = getInstrumentation(). 110 getContext(). 111 getPackageManager(). 112 getPackageInfo(launcherPackageName, 0) 113 .versionName; 114 } catch (PackageManager.NameNotFoundException e) { 115 throw new RuntimeException(e); 116 } 117 118 final String platformVersion = Build.VERSION.INCREMENTAL; 119 120 Log.d(TAG, "Launcher: " + launcherVersion + ", platform: " + platformVersion); 121 122 final Matcher launcherBuildMatcher = LAUNCHER_BUILD.matcher(launcherVersion); 123 if (!launcherBuildMatcher.find()) { 124 throw new AssertionError("Launcher build match not found"); 125 } 126 127 final Matcher platformBuildMatcher = PLATFORM_BUILD.matcher(platformVersion); 128 if (!platformBuildMatcher.find()) { 129 throw new AssertionError("Platform build match not found"); 130 } 131 132 if (launcherBuildMatcher.group("local") != null && ( 133 platformBuildMatcher.group("commandLine") != null || 134 platformBuildMatcher.group("postsubmit") != null)) { 135 Log.d(TAG, "LOCAL RUN"); 136 sRunFlavor = LOCAL; 137 } else if (launcherBuildMatcher.group("platform") != null 138 && platformBuildMatcher.group("presubmit") != null) { 139 Log.d(TAG, "PLATFORM PRESUBMIT"); 140 sRunFlavor = PLATFORM_PRESUBMIT; 141 } else if (launcherBuildMatcher.group("platform") != null 142 && (platformBuildMatcher.group("postsubmit") != null 143 || platformBuildMatcher.group("commandLine") != null)) { 144 Log.d(TAG, "PLATFORM POSTSUBMIT"); 145 sRunFlavor = PLATFORM_POSTSUBMIT; 146 } else { 147 throw new AssertionError("Unrecognized run flavor"); 148 } 149 150 return sRunFlavor; 151 } 152 } 153