PlanCreator.java revision 066fb2833351636637a680f087d42006ea50d5cc
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 */
16package com.android.cts.tradefed.result;
17
18import com.android.cts.tradefed.build.CtsBuildHelper;
19import com.android.cts.tradefed.testtype.CtsTest;
20import com.android.cts.tradefed.testtype.ITestPackageDef;
21import com.android.cts.tradefed.testtype.ITestPackageRepo;
22import com.android.cts.tradefed.testtype.ITestPlan;
23import com.android.cts.tradefed.testtype.TestPackageRepo;
24import com.android.cts.tradefed.testtype.TestPlan;
25import com.android.ddmlib.Log;
26import com.android.ddmlib.Log.LogLevel;
27import com.android.ddmlib.testrunner.TestIdentifier;
28import com.android.tradefed.config.ConfigurationException;
29import com.android.tradefed.config.Option;
30import com.android.tradefed.config.Option.Importance;
31import com.android.tradefed.log.LogUtil.CLog;
32
33import java.io.BufferedOutputStream;
34import java.io.File;
35import java.io.FileNotFoundException;
36import java.io.FileOutputStream;
37import java.io.IOException;
38import java.util.Collection;
39import java.util.LinkedHashSet;
40
41/**
42 * Class for creating test plans from CTS result XML.
43 */
44public 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