Parse configuration file
CTS frame is divided into nine parts:
Pai_options: The Parameter options accepted by the command line, in the Command package.
Device_requirements: device requirements, in the device package
Device_options: Device Parameters in the device package
Builde_provider: Version provider in build package
Target_preparer: Preparation of Preset conditions, in the targetprep package
Test: Test type, which exists in the testtype package
Device_recovery: The device recovers after a device exception occurs during task execution.
Logger: log system, in the log package
Result_reporter: Result Statistics Report, in the result package
These nine components must be configured for each task. If this parameter is not configured, the framework uses its own default configuration, but it is equivalent to configuring these components, therefore, the core of the CTS framework is in configuration.
private static synchronized Map<String, ObjTypeInfo> getObjTypeMap() { if (sObjTypeMap == null) { sObjTypeMap = new HashMap<String, ObjTypeInfo>(); sObjTypeMap.put(BUILD_PROVIDER_TYPE_NAME, new ObjTypeInfo(IBuildProvider.class, false)); sObjTypeMap.put(TARGET_PREPARER_TYPE_NAME, new ObjTypeInfo(ITargetPreparer.class, true)); sObjTypeMap.put(TEST_TYPE_NAME, new ObjTypeInfo(IRemoteTest.class, true)); sObjTypeMap.put(DEVICE_RECOVERY_TYPE_NAME, new ObjTypeInfo(IDeviceRecovery.class, false)); sObjTypeMap.put(LOGGER_TYPE_NAME, new ObjTypeInfo(ILeveledLogOutput.class, false)); sObjTypeMap.put(RESULT_REPORTER_TYPE_NAME, new ObjTypeInfo(ITestInvocationListener.class, true)); sObjTypeMap.put(CMD_OPTIONS_TYPE_NAME, new ObjTypeInfo(ICommandOptions.class, false)); sObjTypeMap.put(DEVICE_REQUIREMENTS_TYPE_NAME, new ObjTypeInfo(IDeviceSelection.class, false)); sObjTypeMap.put(DEVICE_OPTIONS_TYPE_NAME, new ObjTypeInfo(TestDeviceOptions.class, false)); } return sObjTypeMap; } /** * Creates an {@link Configuration} with default config objects. */ public Configuration(String name, String description) { mName = name; mDescription = description; mConfigMap = new LinkedHashMap<String, List<Object>>(); setCommandOptions(new CommandOptions()); setDeviceRequirements(new DeviceSelectionOptions()); setDeviceOptions(new TestDeviceOptions()); setBuildProvider(new StubBuildProvider()); setTargetPreparer(new StubTargetPreparer()); setTest(new StubTest()); setDeviceRecovery(new WaitDeviceRecovery()); setLogOutput(new StdoutLogger()); setTestInvocationListener(new TextResultReporter()); }
In getobjtypemap (), we can see that the CTS framework defines the interfaces for these nine components. As long as your class implements this interface, CTS can find your class through the reflection mechanism. The configuration class constructor sets the default implementation classes for these interfaces. If you do not configure other alternative classes, CTS loads these Implementation classes by default. These classes are interfaces that implement the Mappings in the above method before they can be set as configuration items.
For all class configurations, CTS only recognizes the implementation class of the configuration class interface. if you write a class that does not inherit one of the nine classes, you add, an error will also be reported. It can be seen that the CTS is configured with the above items by default, and the default items are not configured. After this lecture, we will start from the code at the beginning of the article to learn how to complete these configurations step by step.
Debug
Start with the parsing configuration file code in the previous article:
IConfiguration config = getConfigFactory().createConfigurationFromArgs(args);
Call the configurationfactory. createconfigurationfromargs method:
/** * {@inheritDoc} */ @Override public IConfiguration createConfigurationFromArgs(String[] arrayArgs) throws ConfigurationException { List<String> listArgs = new ArrayList<String>(arrayArgs.length); IConfiguration config = internalCreateConfigurationFromArgs(arrayArgs, listArgs); config.setOptionsFromCommandLineArgs(listArgs); return config; }
This method also calls the internalcreateconfigurationfromargs method. The input is the run CTS -- Plan signature String Array and an empty string.
private IConfiguration internalCreateConfigurationFromArgs(String[] arrayArgs, List<String> optionArgsRef) throws ConfigurationException { if (arrayArgs.length == 0) { throw new ConfigurationException("Configuration to run was not specified"); } optionArgsRef.addAll(Arrays.asList(arrayArgs)); // first arg is config name final String configName = optionArgsRef.remove(0); ConfigurationDef configDef = getConfigurationDef(configName, false); return configDef.createConfiguration(); }
This method extracts the first CTS parameter and passes it into the getconfigurationdef method to obtain the configurationdef object. First, let's see what the configurationdef object is? A configurationdef is a configuration file.
public class ConfigurationDef { /** a map of object type names to config object class name(s). */ private final Map<String, List<String>> mObjectClassMap; /** a list of option name/value pairs. */ private final List<OptionDef> mOptionList; /** a cache of the frequency of every classname */ private final Map<String, Integer> mClassFrequency; static class OptionDef { final String name; final String key; final String value; OptionDef(String optionName, String optionValue) { this(optionName, null, optionValue); } OptionDef(String optionName, String optionKey, String optionValue) { this.name = optionName; this.key = optionKey; this.value = optionValue; } } /** the unique name of the configuration definition */ private final String mName; /** a short description of the configuration definition */ private String mDescription = ""; public ConfigurationDef(String name) { mName = name; // use LinkedHashMap to keep objects in same order they were added. mObjectClassMap = new LinkedHashMap<String, List<String>>(); mOptionList = new ArrayList<OptionDef>(); mClassFrequency = new HashMap<String, Integer>(); }
Focus on the following two attributes:
Mobjectclassmap: stores nine major components, such as build_provider, device_recovery, test, logger, and result_reporter.
Moptionlist: Save the option label value, for example, the above enable-root value.
Enter the debug mode to verify whether the above two attributes are saved. Place the breakpoint on configurationdef configdef = getconfigurationdef (configname, false); and delete other breakpoints. Restart debug. Press F6 to the next line. Let's take a look at the value in the variables column.
We can see that the value of mobjectclassmap is:
{build_provider=[com.android.cts.tradefed.build.CtsBuildProvider], device_recovery=[com.android.tradefed.device.WaitDeviceRecovery], test=[com.android.cts.tradefed.testtype.CtsTest], logger=[com.android.tradefed.log.FileLogger],result_reporter=[com.android.cts.tradefed.result.CtsXmlResultReporter, com.android.cts.tradefed.result.IssueReporter]}
It is the same as in the configuration file.
CTS framework analysis (5)