前兩篇講了任務的添加和9大項配置,這篇講任務的執行。
# 任務的執行
任務的執行在CommandScheduler的run方法中,所以刪除所有的斷點,在run方法中打上斷點,重啟啟動debug:

先看while循環下面的第一行代碼
~~~
ExecutableCommand?cmd?=?dequeueConfigCommand();
~~~
~~~
private ExecutableCommand dequeueConfigCommand() {
try {
// poll for a command, rather than block indefinitely, to handle shutdown case
return mCommandQueue.poll(getCommandPollTimeMs(), TimeUnit.MILLISECONDS);
} catch (InterruptedException e) {
CLog.i("Waiting for command interrupted");
}
return null;
}
~~~
從隊列中取出第一個對象。如果隊列中沒有元素那就返回null。返回后,while中會判斷如果為null的話,就會結束再次調用
~~~
ExecutableCommand?cmd?=?dequeueConfigCommand();
~~~
直到cmd不為null。所以在
~~~
IDeviceSelection?options?=?cmd.getConfiguration().getDeviceRequirements();
~~~
打上斷點,按F8,程序會在cmd不為null時進入到上面的代碼,停下來。

首先得到系統設備要求,根據該要求,判斷是否有滿足要求的設備并分配該設備。

原生的 要求就一個S/N號,ddms會根據該SN號分配一個IDevice,然后cts根據IDevice包裝成ITestDevice對象返回。然后根據ITestDevice,IDeviceManager和ExecutableCommand開始真正的啟動任務。我們先不急于討論執行的過程,而是繼續向下看:
~~~
addInvocationThread(invThread);
if (cmd.isLoopMode()) {
addNewExecCommandToQueue(cmd.getCommandTracker());
}
~~~
先將正在執行的線程存到set中,然后將該命令再次放入任務隊列中,這樣的目的是為了能循環執行該任務。如果根據sn號沒有分配成功ITestDevice,則會再次嘗試一次,如果在規定時間內還沒找到設備則放棄。最后做一些tearDown操作,然后將case運行過程中的log保存到文件。就算執行完了。
現在回頭看一下執行任務的線程中是如何操作的:
~~~
private InvocationThread startInvocation(IDeviceManager manager, ITestDevice device,
ExecutableCommand cmd) {
final String invocationName = String.format("Invocation-%s", device.getSerialNumber());
InvocationThread invocationThread = new InvocationThread(invocationName, manager, device,
cmd);
invocationThread.start();
return invocationThread;
}
~~~
InvocationThread為CommandScheduler私有內部類,繼承與線程,這就屬于線程里啟動線程。所以直接看InvocationThread的run方法就ok了。在run方法里調用了ITestInvocation的invoke方法:

傳入的對象分別為ITestDevice、IConfiguration、IRescheduler。前兩個已經涉及到,最后一個IRescheduler是什么?自己看吧,也沒啥意義。這樣任務的前期的工作都已經搞定了,程序轉到了TestInvocation的invoke方法。放到下一篇文章來講,因為它很重要,相當于一個調度室的作用。
# 總結
寫了6篇,總結一些cts的過程。
任務的開始點是接受命令行中的參數,如果判斷為執行cts任務,那么會在Console.run方法中啟動添加命令任務的線程**ArgRunnable**和執行任務的線程**CommandScheduler**。添加任務線程**ArgRunnable**會調用**CommandScheduler**對象方法addCommand來向**ConditionPriorityBlockingQueue(采用先進先出的隊列)**這個隊列中添加,而執行任務線程**CommandScheduler**會通過調用自己的私有方法dequeueConfigCommand來從
**ConditionPriorityBlockingQueue**去取可執行的任務,每次取第一個。然后調用**InvocationThread**這個線程去執行任務。**InvocationThread**這個線程調用TestInvocation.invoke方法去執行任務。
明白了么,其實很簡單!
- 前言
- (1)-windows下cts配置
- (2)-cts調試環境的搭建
- (3)-基礎庫tradefederation配置
- (4)-任務的添加
- (5)-9大組件配置
- (6)-任務的執行
- (7)-任務執行的調度室
- (8)-IBuildProvider
- (9)-IDeviceRecovery
- (10)-TestDeviceOptions
- (11)-ICommandOptions
- (12)-ITargetPreparer
- (13)-任務執行過程
- (14)-任務執行過程
- (15)-任務執行完
- (16)-logcat信息收集系統
- (17)-fastboot狀態監聽器
- (18)-設備恢復
- (19)-設備狀態的分類以及恢復模式的分類
- (20)-cts自身log系統
- (21)-測試結果收集系統
- (22)-自動檢測設備
- (23)-設備分類
- (24)-case的組織