1 /* 2 * Copyright (C) 2011 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 package com.android.cts.tradefed.result; 17 18 import com.android.cts.tradefed.build.CtsBuildHelper; 19 import com.android.cts.tradefed.testtype.CtsTest; 20 import com.android.cts.tradefed.testtype.ITestPackageDef; 21 import com.android.cts.tradefed.testtype.ITestPackageRepo; 22 import com.android.cts.tradefed.testtype.ITestPlan; 23 import com.android.cts.tradefed.testtype.TestPackageRepo; 24 import com.android.cts.tradefed.testtype.TestPlan; 25 import com.android.ddmlib.Log; 26 import com.android.ddmlib.Log.LogLevel; 27 import com.android.ddmlib.testrunner.TestIdentifier; 28 import com.android.tradefed.config.ConfigurationException; 29 import com.android.tradefed.config.Option; 30 import com.android.tradefed.config.Option.Importance; 31 import com.android.tradefed.log.LogUtil.CLog; 32 33 import java.io.BufferedOutputStream; 34 import java.io.File; 35 import java.io.FileNotFoundException; 36 import java.io.FileOutputStream; 37 import java.io.IOException; 38 import java.util.Collection; 39 import java.util.LinkedHashSet; 40 41 /** 42 * Class for creating test plans from CTS result XML. 43 */ 44 public class PlanCreator { 45 46 @Option (name = "plan", shortName = 'p', description = "the name of the plan to create", 47 importance=Importance.IF_UNSET) 48 private String mPlanName = null; 49 50 @Option (name = "session", shortName = 's', description = "the session id to derive from", 51 importance=Importance.IF_UNSET) 52 private Integer mSessionId = null; 53 54 @Option (name = "result", shortName = 'r', 55 description = "the result type to filter. One of pass, fail, notExecuted.", 56 importance=Importance.IF_UNSET) 57 private String mResultFilterString = null; 58 59 @Option(name = CtsTest.RUN_KNOWN_FAILURES_OPTION) 60 private boolean mIncludeKnownFailures = false; 61 62 private CtsTestStatus mResultFilter = null; 63 private TestResults mResult = null; 64 65 private File mPlanFile; 66 67 /** 68 * Create an empty {@link PlanCreator}. 69 * <p/> 70 * All {@link Option} fields must be populated via 71 * {@link com.android.tradefed.config.ArgsOptionParser} 72 */ 73 public PlanCreator() { 74 } 75 76 /** 77 * Create a {@link PlanCreator} using the specified option values. 78 */ 79 public PlanCreator(String planName, int session, CtsTestStatus result) { 80 mPlanName = planName; 81 mSessionId = session; 82 mResultFilterString = result.getValue(); 83 } 84 85 /** 86 * Create and serialize a test plan derived from a result. 87 * <p/> 88 * {@link Option} values must all be set before this is called. 89 * @throws ConfigurationException 90 */ 91 public void createAndSerializeDerivedPlan(CtsBuildHelper build) throws ConfigurationException { 92 ITestPlan derivedPlan = createDerivedPlan(build); 93 if (derivedPlan != null) { 94 try { 95 derivedPlan.serialize(new BufferedOutputStream(new FileOutputStream(mPlanFile))); 96 } catch (IOException e) { 97 Log.logAndDisplay(LogLevel.ERROR, "", String.format("Failed to create plan file %s", 98 mPlanName)); 99 CLog.e(e); 100 } 101 } 102 } 103 104 /** 105 * Create a test plan derived from a result. 106 * <p/> 107 * {@link Option} values must all be set before this is called. 108 * 109 * @param build 110 * @return test plan 111 * @throws ConfigurationException 112 */ 113 public ITestPlan createDerivedPlan(CtsBuildHelper build) throws ConfigurationException { 114 checkFields(build); 115 ITestPackageRepo pkgDefRepo = new TestPackageRepo(build.getTestCasesDir(), 116 mIncludeKnownFailures); 117 ITestPlan derivedPlan = new TestPlan(mPlanName); 118 for (TestPackageResult pkg : mResult.getPackages()) { 119 Collection<TestIdentifier> filteredTests = pkg.getTestsWithStatus(mResultFilter); 120 if (!filteredTests.isEmpty()) { 121 String pkgUri = pkg.getAppPackageName(); 122 ITestPackageDef pkgDef = pkgDefRepo.getTestPackage(pkgUri); 123 if (pkgDef != null) { 124 Collection<TestIdentifier> excludedTests = new LinkedHashSet<TestIdentifier>( 125 pkgDef.getTests()); 126 excludedTests.removeAll(filteredTests); 127 derivedPlan.addPackage(pkgUri); 128 derivedPlan.addExcludedTests(pkgUri, excludedTests); 129 } else { 130 CLog.e("Could not find package %s in repository", pkgUri); 131 } 132 } 133 } 134 return derivedPlan; 135 } 136 137 /** 138 * Check that all {@Option}s have been populated with valid values. 139 * @param build 140 * @throws ConfigurationException if any option has an invalid value 141 */ 142 private void checkFields(CtsBuildHelper build) throws ConfigurationException { 143 if (mSessionId == null) { 144 throw new ConfigurationException("Missing --session argument"); 145 } 146 ITestResultRepo repo = new TestResultRepo(build.getResultsDir()); 147 mResult = repo.getResult(mSessionId); 148 if (mResult == null) { 149 throw new ConfigurationException(String.format("Could not find session with id %d", 150 mSessionId)); 151 } 152 if (mResultFilterString == null) { 153 throw new ConfigurationException("Missing --result argument"); 154 } 155 mResultFilter = CtsTestStatus.getStatus(mResultFilterString); 156 if (mResultFilter == null) { 157 throw new ConfigurationException( 158 "Invalid result argument. Expected one of pass,fail,notExecuted"); 159 } 160 if (mPlanName == null) { 161 throw new ConfigurationException("Missing --plan argument"); 162 } 163 try { 164 mPlanFile = build.getTestPlanFile(mPlanName); 165 if (mPlanFile.exists()) { 166 throw new ConfigurationException(String.format("Test plan %s already exists", 167 mPlanName)); 168 } 169 } catch (FileNotFoundException e) { 170 throw new ConfigurationException("Could not find plans directory"); 171 } 172 } 173 } 174