1 /* 2 * Copyright (C) 2019 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of 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, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package android.server.wm.intent; 18 19 import static androidx.test.InstrumentationRegistry.getInstrumentation; 20 21 import android.content.ComponentName; 22 import android.content.Context; 23 import android.content.res.AssetManager; 24 import android.os.Environment; 25 import android.platform.test.annotations.Presubmit; 26 import android.server.wm.intent.Persistence.IntentFlag; 27 import android.server.wm.intent.Persistence.TestCase; 28 29 import androidx.test.filters.FlakyTest; 30 import androidx.test.filters.LargeTest; 31 32 import com.google.common.collect.Lists; 33 34 import org.json.JSONException; 35 import org.json.JSONObject; 36 import org.junit.Test; 37 import org.junit.runner.RunWith; 38 import org.junit.runners.Parameterized; 39 40 import java.io.BufferedInputStream; 41 import java.io.BufferedReader; 42 import java.io.File; 43 import java.io.IOException; 44 import java.io.InputStreamReader; 45 import java.nio.file.Files; 46 import java.nio.file.Path; 47 import java.util.Collection; 48 import java.util.List; 49 import java.util.Map; 50 import java.util.stream.Collectors; 51 52 /** 53 * This test will verify every intent_test json file in a separately run test, through JUnits 54 * Parameterized runner. 55 * 56 * Running a single test using this class is not supported. 57 * For this use case look at {@link IntentGenerationTests#verifySingle()} 58 * 59 * Note: atest CtsWindowManagerDeviceTestCases:IntentTests#verify does not work because the 60 * Parameterized runner won't expose the test that way to atest. 61 * 62 * Build/Install/Run: 63 * atest CtsWindowManagerDeviceTestCases:IntentTests 64 */ 65 @FlakyTest(detail = "Promote once confirmed non-flaky") 66 @Presubmit 67 @LargeTest 68 @RunWith(Parameterized.class) 69 public class IntentTests extends IntentTestBase { 70 private static final Cases CASES = new Cases(); 71 72 /** 73 * The flag parsing table used to parse the json files. 74 */ 75 private static final Map<String, IntentFlag> TABLE = CASES.createFlagParsingTable(); 76 private static Context TARGET_CONTEXT = getInstrumentation().getTargetContext(); 77 78 private static final int JSON_INDENTATION_LEVEL = 4; 79 80 /** 81 * The runner used to verify the recorded test cases. 82 */ 83 private LaunchRunner mLaunchRunner; 84 85 /** 86 * The Test case we are currently verifying. 87 */ 88 private TestCase mTestCase; 89 IntentTests(TestCase testCase, String name)90 public IntentTests(TestCase testCase, String name) { 91 mTestCase = testCase; 92 } 93 94 /** 95 * Read all the tests in the assets of the application and create a separate test to run for 96 * each of them using the {@link org.junit.runners.Parameterized} 97 */ 98 @Parameterized.Parameters(name = "{1}") data()99 public static Collection<Object[]> data() throws IOException, JSONException { 100 return readAllFromAssets().stream().map( 101 test -> new Object[]{test, test.getName()}).collect( 102 Collectors.toList()); 103 } 104 105 @Test verify()106 public void verify() { 107 mLaunchRunner.verify(TARGET_CONTEXT, mTestCase); 108 } 109 110 111 @Override setUp()112 public void setUp() throws Exception { 113 super.setUp(); 114 mLaunchRunner = new LaunchRunner(this); 115 } 116 117 @Override activitiesUsedInTest()118 List<ComponentName> activitiesUsedInTest() { 119 return mTestCase.getSetup().componentsInCase(); 120 } 121 readAllFromAssets()122 public static List<TestCase> readAllFromAssets() throws IOException, JSONException { 123 List<TestCase> testCases = Lists.newArrayList(); 124 AssetManager assets = TARGET_CONTEXT.getAssets(); 125 126 List<String> testFiles = Lists.newArrayList(); 127 for (String dir : assets.list("")) { 128 for (String file : assets.list(dir)) { 129 if (file.endsWith(".json")) { 130 testFiles.add(dir + "/" + file); 131 } 132 } 133 } 134 135 for (String testFile : testFiles) { 136 try (BufferedReader bufferedReader = new BufferedReader(new InputStreamReader( 137 new BufferedInputStream(assets.open(testFile))))) { 138 String jsonData = bufferedReader.lines().collect( 139 Collectors.joining("\n")); 140 141 TestCase testCase = TestCase.fromJson( 142 new JSONObject(jsonData), TABLE, testFile); 143 144 testCases.add(testCase); 145 } 146 } 147 148 return testCases; 149 } 150 writeToDocumentsStorage(TestCase testCase, int number, String dirName)151 static void writeToDocumentsStorage(TestCase testCase, int number, String dirName) 152 throws JSONException, IOException { 153 File documentsDirectory = Environment.getExternalStoragePublicDirectory( 154 Environment.DIRECTORY_DOCUMENTS); 155 Path testsFilePath = documentsDirectory.toPath().resolve(dirName); 156 157 if (!Files.exists(testsFilePath)) { 158 Files.createDirectories(testsFilePath); 159 } 160 Files.write(testsFilePath.resolve("test-" + number + ".json"), 161 Lists.newArrayList(testCase.toJson().toString(JSON_INDENTATION_LEVEL))); 162 } 163 } 164 165