Cts框架解析(8)-IBuildProvider

IBuildProvider接口中定义了三个方法

/*
 * 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.tradefed.build;

/**
 * Responsible for providing info regarding the build under test.
 */
public interface IBuildProvider {

    /**
     * Retrieve the data for build under test.
     *
     * @return the {@link IBuildInfo} for build under test or <code>null</code> if no build is
     * available for testing
     * @throws BuildRetrievalError if build info failed to be retrieved due to an unexpected error
     */
    public IBuildInfo getBuild() throws BuildRetrievalError;

    /**
     * Mark the given build as untested.
     * <p/>
     * Called in cases where TradeFederation has failed to complete testing on the build due to an
     * environment problem.
     *
     * @param info the {@link IBuildInfo} to reset
     */
    public void buildNotTested(IBuildInfo info);

    /**
     * Clean up any temporary build files.
     */
    public void cleanUp(IBuildInfo info);
}

该类主要是为了提供IBuildInfo信息的。所以目光转到IBuildInfo接口中:

/*
 * 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.tradefed.build;

import com.android.tradefed.device.ITestDevice;

import java.io.File;
import java.util.Collection;
import java.util.Map;

/**
 * Holds information about the build under test.
 */
public interface IBuildInfo {

    /**
     * Default value when build ID is unknown.
     */
    public final static String UNKNOWN_BUILD_ID = "-1";

    /**
     * Returns the unique identifier of build under test. Should never be null. Defaults to
     * {@link #UNKNOWN_BUILD_ID}.
     */
    public String getBuildId();

    /**
     * Return a unique name for the tests being run.
     */
    public String getTestTag();

    /**
     * Return complete name for the build being tested.
     * <p/>
     * A common implementation is to construct the build target name from a combination of
     * the build flavor and branch name. [ie (branch name)-(build flavor)]
     */
    public String getBuildTargetName();

    /**
     * Optional method to return the type of build being tested.
     * <p/>
     * A common implementation for Android platform builds is to return
     * (build product)-(build os)-(build variant).
     * ie generic-linux-userdebug
     *
     * @return the build flavor or <code>null</code> if unset/not applicable
     */
    public String getBuildFlavor();

    /**
     * @return the {@link ITestDevice} serial that this build was executed on. Returns <code>null
     * </code> if no device is associated with this build.
     */
    public String getDeviceSerial();

    /**
     * Set the build flavor.
     *
     * @param buildFlavor
     */
    public void setBuildFlavor(String buildFlavor);

    /**
     * Optional method to return the source control branch that the build being tested was
     * produced from.
     *
     * @return the build branch or <code>null</code> if unset/not applicable
     */
    public String getBuildBranch();

    /**
     * Set the build branch
     *
     * @param branch the branch name
     */
    public void setBuildBranch(String branch);

    /**
     * Set the {@link ITestDevice} serial associated with this build.
     *
     * @param serial the serial number of the {@link ITestDevice} that this build was executed with.
     */
    public void setDeviceSerial(String serial);

    /**
     * Get a set of name-value pairs of additional attributes describing the build.
     *
     * @return a {@link Map} of build attributes. Will not be <code>null</code>, but may be empty.
     */
    public Map<String, String> getBuildAttributes();

    /**
     * Add a build attribute
     *
     * @param attributeName the unique attribute name
     * @param attributeValue the attribute value
     */
    public void addBuildAttribute(String attributeName, String attributeValue);

    /**
     * Helper method to retrieve a file with given name.
     * @param name
     * @return the image file or <code>null</code> if not found
     */
    public File getFile(String name);

    /**
     * Returns all {@link VersionedFile}s stored in this {@link BuildInfo}.
     */
    public Collection<VersionedFile> getFiles();

    /**
     * Helper method to retrieve a file version with given name.
     * @param name
     * @return the image version or <code>null</code> if not found
     */
    public String getVersion(String name);

    /**
     * Stores an file with given name in this build info.
     *
     * @param name the unique name of the file
     * @param file the local {@link File}
     * @param version the file version
     */
    public void setFile(String name, File file, String version);

    /**
     * Clean up any temporary build files
     */
    public void cleanUp();

    /**
     * Clones the {@link IBuildInfo} object.
     */
    public IBuildInfo clone();
}

该接口中定义了一些方法都是跟属性相关的,其实现在BuildInfo中。

/*
 * 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.tradefed.build;

import com.android.tradefed.log.LogUtil.CLog;
import com.android.tradefed.util.FileUtil;
import com.android.tradefed.util.MultiMap;
import com.android.tradefed.util.UniqueMultiMap;
import com.google.common.base.Objects;

import java.io.File;
import java.io.IOException;
import java.util.Collection;
import java.util.Hashtable;
import java.util.Map;

/**
 * Generic implementation of a {@link IBuildInfo}.
 */
public class BuildInfo implements IBuildInfo {
    private String mBuildId = "0";
    private String mTestTag = "stub";
    private String mBuildTargetName = "stub";
    private final UniqueMultiMap<String, String> mBuildAttributes =
            new UniqueMultiMap<String, String>();
    private Map<String, VersionedFile> mVersionedFileMap;
    private String mBuildFlavor = null;
    private String mBuildBranch = null;
    private String mDeviceSerial = null;

    /**
     * Creates a {@link BuildInfo} using default attribute values.
     */
    public BuildInfo() {
        mVersionedFileMap = new Hashtable<String, VersionedFile>();
    }

    /**
     * Creates a {@link BuildInfo}
     *
     * @param buildId the build id
     * @param testTag the test tag name
     * @param buildTargetName the build target name
     */
    public BuildInfo(String buildId, String testTag, String buildTargetName) {
        mBuildId = buildId;
        mTestTag = testTag;
        mBuildTargetName = buildTargetName;
        mVersionedFileMap = new Hashtable<String, VersionedFile>();
    }

    /**
     * Creates a {@link BuildInfo}, populated with attributes given in another build.
     *
     * @param buildToCopy
     */
    BuildInfo(BuildInfo buildToCopy) {
        this(buildToCopy.getBuildId(), buildToCopy.getTestTag(), buildToCopy.getBuildTargetName());
        addAllBuildAttributes(buildToCopy);
        try {
            addAllFiles(buildToCopy);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public String getBuildId() {
        return mBuildId;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public String getTestTag() {
        return mTestTag;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public String getDeviceSerial() {
        return mDeviceSerial;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public Map<String, String> getBuildAttributes() {
        return mBuildAttributes.getUniqueMap();
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public String getBuildTargetName() {
        return mBuildTargetName;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void addBuildAttribute(String attributeName, String attributeValue) {
        mBuildAttributes.put(attributeName, attributeValue);
    }

    /**
     * Helper method to copy build attributes, branch, and flavor from other build.
     */
    protected void addAllBuildAttributes(BuildInfo build) {
        mBuildAttributes.putAll(build.getAttributesMultiMap());
        setBuildFlavor(build.getBuildFlavor());
        setBuildBranch(build.getBuildBranch());
    }

    protected MultiMap<String, String> getAttributesMultiMap() {
        return mBuildAttributes;
    }

    /**
     * Helper method to copy all files from the other build.
     * <p>
     * Creates new hardlinks to the files so that each build will have a unique file path to the
     * file.
     * </p>
     *
     * @throws IOException if an exception is thrown when creating the hardlinks.
     */
    protected void addAllFiles(BuildInfo build) throws IOException {
        for (Map.Entry<String, VersionedFile> fileEntry : build.getVersionedFileMap().entrySet()) {
            File origFile = fileEntry.getValue().getFile();
            File copyFile;
            if (origFile.isDirectory()) {
                copyFile = FileUtil.createTempDir(fileEntry.getKey());
                FileUtil.recursiveHardlink(origFile, copyFile);
            } else {
                // Only using createTempFile to create a unique dest filename
                copyFile = FileUtil.createTempFile(fileEntry.getKey(),
                        FileUtil.getExtension(origFile.getName()));
                copyFile.delete();
                FileUtil.hardlinkFile(origFile, copyFile);
            }
            setFile(fileEntry.getKey(), copyFile, fileEntry.getValue().getVersion());
        }
    }

    protected Map<String, VersionedFile> getVersionedFileMap() {
        return mVersionedFileMap;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public File getFile(String name) {
        VersionedFile fileRecord = mVersionedFileMap.get(name);
        if (fileRecord != null) {
            return fileRecord.getFile();
        }
        return null;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public Collection<VersionedFile> getFiles() {
        return mVersionedFileMap.values();
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public String getVersion(String name) {
        VersionedFile fileRecord = mVersionedFileMap.get(name);
        if (fileRecord != null) {
            return fileRecord.getVersion();
        }
        return null;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void setFile(String name, File file, String version) {
        if (mVersionedFileMap.containsKey(name)) {
            CLog.e("Device build already contains a file for %s in thread %s", name,
                    Thread.currentThread().getName());
            return;
        }
        mVersionedFileMap.put(name, new VersionedFile(file, version));
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void cleanUp() {
        for (VersionedFile fileRecord : mVersionedFileMap.values()) {
            FileUtil.recursiveDelete(fileRecord.getFile());
        }
        mVersionedFileMap.clear();
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public IBuildInfo clone() {
        BuildInfo copy = new BuildInfo(mBuildId, mTestTag, mBuildTargetName);
        copy.addAllBuildAttributes(this);
        try {
            copy.addAllFiles(this);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        copy.setBuildBranch(mBuildBranch);
        copy.setBuildFlavor(mBuildFlavor);

        return copy;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public String getBuildFlavor() {
        return mBuildFlavor;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void setBuildFlavor(String buildFlavor) {
        mBuildFlavor = buildFlavor;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public String getBuildBranch() {
        return mBuildBranch;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void setBuildBranch(String branch) {
        mBuildBranch = branch;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void setDeviceSerial(String serial) {
        mDeviceSerial = serial;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public int hashCode() {
        return Objects.hashCode(mBuildAttributes, mBuildBranch, mBuildFlavor, mBuildId,
                mBuildTargetName, mTestTag, mDeviceSerial);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public boolean equals(Object obj) {
        if (this == obj) {
            return true;
        }
        if (obj == null) {
            return false;
        }
        if (getClass() != obj.getClass()) {
            return false;
        }
        BuildInfo other = (BuildInfo) obj;
        return Objects.equal(mBuildAttributes, other.mBuildAttributes) &&
                Objects.equal(mBuildBranch, other.mBuildBranch) &&
                Objects.equal(mBuildFlavor, other.mBuildFlavor) &&
                Objects.equal(mBuildId, other.mBuildId) &&
                Objects.equal(mBuildTargetName, other.mBuildTargetName) &&
                Objects.equal(mTestTag, other.mTestTag) &&
                Objects.equal(mDeviceSerial, other.mDeviceSerial);
    }
}

提供的属性有build的id号,build的目标名称,测试标签,根目录,build的分支,测试类型。关机要理解build是什么意思,我还不是太了解build这个意义,暂时先用build来代替吧,等我了解了,再做解释。在原生的cts中,使用的是CtsBuildProvider,很简单的就是把cts的根目录属性设置上,然后是buildId,测试目标,build命令设置好就返回了。但是你如果要添加你自己的实现类,肯定不是简单的这么一点代码。比如你要做的测试时测试你的系统,那么这里面提供的东西就多了。首先你的系统存放的地址,分支号,要build的版本号等等都要在这里面获取并存到buildinfo对象中返回给TestInvocation中。

/*
 * 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.build;

import com.android.tradefed.build.FolderBuildInfo;
import com.android.tradefed.build.IBuildInfo;
import com.android.tradefed.build.IBuildProvider;
import com.android.tradefed.build.IFolderBuildInfo;
import com.android.tradefed.config.Option;

import java.io.File;

/**
 * A simple {@link IBuildProvider} that uses a pre-existing CTS install.
 */
public class CtsBuildProvider implements IBuildProvider {

    @Option(name="cts-install-path", description="the path to the cts installation to use")
    private String mCtsRootDirPath = System.getProperty("CTS_ROOT");

    public static final String CTS_BUILD_VERSION = "4.4_r1.95";

    /**
     * {@inheritDoc}
     */
    @Override
    public IBuildInfo getBuild() {
        if (mCtsRootDirPath == null) {
            throw new IllegalArgumentException("Missing --cts-install-path");
        }
        IFolderBuildInfo ctsBuild = new FolderBuildInfo(CTS_BUILD_VERSION, "cts", "cts");
        ctsBuild.setRootDir(new File(mCtsRootDirPath));
        return ctsBuild;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void buildNotTested(IBuildInfo info) {
        // ignore
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void cleanUp(IBuildInfo info) {
        // ignore
    }
}
时间: 2024-10-13 15:54:13

Cts框架解析(8)-IBuildProvider的相关文章

Cts框架解析(5)

解析配置文件 Cts框架分为9大部分: cmd_options:命令行接受的参数选项,command包中. device_requirements:设备相关要求,device包中 device_options:设备参数,device包中 builde_provider:版本提供者,build包中 target_preparer:预置条件准备,targetprep包中 test:测试类型,存在testtype包中 device_recovery:任务执行过程中设备异常后的设备恢复,device包中

Cts框架解析(2)-cts调试环境的搭建

上一篇文章中说了怎样在windows搭建cts以及执行cts进行測试.这篇文章来讲讲怎样在eclipse中配置源代码,进行debug调试. 下载 cts源代码地址:https://android.googlesource.com/platform/cts 能够使用git下载到本地. 文件夹结构 watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvaXRmb290YmFsbA==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFC

Cts框架解析(9)-IDeviceRecovery

当设备处于offline状态时,cts框架就要调用IDeviceRecovery接口类去做相应的恢复工作. 接口 /* * 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 Licens

Cts框架解析(13)-任务执行过程

因为测试任务是个很复杂的过程,所以要单独拿出来讲,里面还涉及了result_reporter的内容.所以这是一个大块.首先把断点打在CtsTest的run方法中,删除其他断点,重新启动debug模式: 首先会调用checkFields检查一下命令行参数.然后生成plan里的包名信息.(要理解plan的意思,plan就是cts目录下plan文件下的xml文件,它里面配置的entry代表一个测试项,一个测试项里又包含多个测试的case).本程序执行的是Signature计划,我们就来看看这个xml文

Cts框架解析(7)-任务执行的调度室

TestInvocation /** * {@inheritDoc} */ @Override public void invoke(ITestDevice device, IConfiguration config, IRescheduler rescheduler) throws DeviceNotAvailableException, Throwable { try { mStatus = "fetching build"; config.getLogOutput().init(

Cts框架解析(6)-任务的运行

前两篇讲了任务的加入和9大项配置,这篇讲任务的运行. 任务的运行 任务的运行在CommandScheduler的run方法中,所以删除全部的断点,在run方法中打上断点,重新启动启动debug: 先看while循环以下的第一行代码 ExecutableCommand cmd = dequeueConfigCommand(); private ExecutableCommand dequeueConfigCommand() { try { // poll for a command, rather

Cts框架解析(1)-windows下cts配置

环境搭建 下载 cts工具的下载地址:http://source.android.com/compatibility/downloads.html windows选择Android4.4 R3 Compatibility Test Suite (CTS) - ARM下载. 文件夹结构 解压后的文件夹结构例如以下: watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvaXRmb290YmFsbA==/font/5a6L5L2T/fontsize/400/fil

Cts框架解析(6)-任务的执行

前两篇讲了任务的添加和9大项配置,这篇讲任务的执行. 任务的执行 任务的执行在CommandScheduler的run方法中,所以删除所有的断点,在run方法中打上断点,重启启动debug: 先看while循环下面的第一行代码 ExecutableCommand cmd = dequeueConfigCommand(); private ExecutableCommand dequeueConfigCommand() { try { // poll for a command, rather t

Cts框架解析(3)

cts是建立在tradefederation项目上的,cts中的tradefed-prebuild.jar就是该项目编译后的jar包.在debug调试的时候少不了这个项目,所以现在开始把这个项目添加到eclipse中. 下载 如果有可以翻墙的话,建议下载最新的版本,我上传的tradefederation应该不是最新的,但是我翻不了墙,所以还是拿这个项目debug. 下载地址:http://download.csdn.net/detail/qhshiniba/8050545 配置 下载后解压后的文