blob: 3639a9c9e74a7e4258a600f7c139dd23595a51bd [file] [log] [blame]
/*
* Copyright (C) 2010 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.cts.tradefed.testtype;
import com.android.ddmlib.testrunner.TestIdentifier;
import com.android.tradefed.util.ArrayUtil;
import com.android.tradefed.util.xml.AbstractXmlParser;
import org.kxml2.io.KXmlSerializer;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
/**
* Implementation of {@link TestPlan}.
*/
public class TestPlan extends AbstractXmlParser implements ITestPlan {
/**
* Map of uri names found in plan, and their excluded tests
*/
private Map<String, TestFilter> mUriExcludedTestsMap;
private static final String ENTRY_TAG = "Entry";
private static final String TEST_DELIM = ";";
private static final String METHOD_DELIM = "#";
private static final String EXCLUDE_ATTR = "exclude";
private static final String URI_ATTR = "uri";
private final String mName;
/**
* SAX callback object. Handles parsing data from the xml tags.
*/
private class EntryHandler extends DefaultHandler {
@Override
public void startElement(String uri, String localName, String name, Attributes attributes)
throws SAXException {
if (ENTRY_TAG.equals(localName)) {
final String entryUriValue = attributes.getValue(URI_ATTR);
TestFilter filter = parseExcludedTests(attributes.getValue(EXCLUDE_ATTR));
mUriExcludedTestsMap.put(entryUriValue, filter);
}
}
/**
* Parse the semi colon separated list of tests to exclude.
* <p/>
* Expected format:
* testClassName[#testMethodName][;testClassName2...]
*
* @param excludedString the excluded string list
* @return
*/
private TestFilter parseExcludedTests(String excludedString) {
TestFilter filter = new TestFilter();
if (excludedString != null) {
String[] testStrings = excludedString.split(TEST_DELIM);
for (String testString : testStrings) {
String[] classMethodPair = testString.split(METHOD_DELIM);
if (classMethodPair.length == 2) {
filter.addExcludedTest(new TestIdentifier(classMethodPair[0],
classMethodPair[1]));
} else {
filter.addExcludedClass(testString);
}
}
}
return filter;
}
}
public TestPlan(String name) {
mName = name;
// Uses a LinkedHashMap to have predictable iteration order
mUriExcludedTestsMap = new LinkedHashMap<String, TestFilter>();
}
/**
* {@inheritDoc}
*/
@Override
public String getName() {
return mName;
}
/**
* {@inheritDoc}
*/
@Override
public Collection<String> getTestUris() {
return mUriExcludedTestsMap.keySet();
}
/**
* {@inheritDoc}
*/
@Override
public TestFilter getExcludedTestFilter(String uri) {
return mUriExcludedTestsMap.get(uri);
}
/**
* {@inheritDoc}
*/
@Override
public void addPackage(String uri) {
mUriExcludedTestsMap.put(uri, new TestFilter());
}
/**
* {@inheritDoc}
*/
@Override
protected DefaultHandler createXmlHandler() {
return new EntryHandler();
}
/**
* {@inheritDoc}
*/
@Override
public void addExcludedTest(String uri, TestIdentifier testToExclude) {
TestFilter filter = mUriExcludedTestsMap.get(uri);
if (filter != null) {
filter.addExcludedTest(testToExclude);
} else {
throw new IllegalArgumentException(String.format("Could not find package %s", uri));
}
}
/**
* {@inheritDoc}
*/
@Override
public void addExcludedTests(String uri, Collection<TestIdentifier> excludedTests) {
TestFilter filter = mUriExcludedTestsMap.get(uri);
if (filter != null) {
filter.getExcludedTests().addAll(excludedTests);
} else {
throw new IllegalArgumentException(String.format("Could not find package %s", uri));
}
}
/**
* {@inheritDoc}
*/
@Override
public void serialize(OutputStream stream) throws IOException {
KXmlSerializer serializer = new KXmlSerializer();
serializer.setOutput(stream, "UTF-8");
serializer.startDocument("UTF-8", false);
serializer.setFeature(
"http://xmlpull.org/v1/doc/features.html#indent-output", true);
serializer.startTag(null, "TestPlan");
serializer.attribute(null, "version", "1.0");
for (Map.Entry<String, TestFilter> packageEntry : mUriExcludedTestsMap.entrySet()) {
serializer.startTag(null, ENTRY_TAG);
serializer.attribute(null, "uri", packageEntry.getKey());
serializeFilter(serializer, packageEntry.getValue());
serializer.endTag(null, ENTRY_TAG);
}
serializer.endTag(null, "TestPlan");
serializer.endDocument();
}
/**
* Adds an xml attribute containing {@link TestFilter} contents.
* <p/>
* If {@link TestFilter} is empty, no data will be outputted.
*
* @param serializer
* @param value
* @throws IOException
*/
private void serializeFilter(KXmlSerializer serializer, TestFilter testFilter)
throws IOException {
if (!testFilter.hasExclusion()) {
return;
}
List<String> exclusionStrings = new ArrayList<String>();
exclusionStrings.addAll(testFilter.getExcludedClasses());
for (TestIdentifier test : testFilter.getExcludedTests()) {
// TODO: this relies on TestIdentifier.toString() using METHOD_DELIM.
exclusionStrings.add(test.toString());
}
String exclusionAttrValue = ArrayUtil.join(TEST_DELIM, exclusionStrings);
serializer.attribute(null, EXCLUDE_ATTR, exclusionAttrValue);
}
}