

终止支持通知：2026 年 10 月 7 日， AWS 将停止对的支持。 AWS IoT Greengrass Version 1 2026 年 10 月 7 日之后，您将无法再访问这些 AWS IoT Greengrass V1 资源。如需了解更多信息，请访问[迁移自 AWS IoT Greengrass Version 1](https://docs.aws.amazon.com/greengrass/v2/developerguide/migrate-from-v1.html)。

本文属于机器翻译版本。若本译文内容与英语原文存在差异，则一律以英文原文为准。

# 使用适用于 AWS IoT Greengrass V1 的 AWS IoT 设备测试器
<a name="device-tester-for-greengrass-ug"></a>

AWS IoT 设备测试器 (IDT) 是一个可下载的测试框架，可让您验证物联网设备。由于 AWS IoT Greengrass Version 1 已进入[维护模式](https://docs.aws.amazon.com/greengrass/v1/developerguide/maintenance-policy.html)，IDT for AWS IoT Greengrass V1 不再生成签名的资格报告。您将无法再通过设备资格[认证计划使新 AWS IoT Greengrass V1 设备符合在[AWS Partner 设备目录](https://devices.amazonaws.com/)中发布的AWS 资格](https://aws.amazon.com/partners/dqp/)。但是，你可以继续使用 IDT AWS IoT Greengrass V1 来测试你的 Greengrass V1 设备。我们建议您使用[适用于 AWS IoT Greengrass V2的 IDT](https://docs.aws.amazon.com/greengrass/v2/developerguide/device-tester-for-greengrass-ug.html) 来进行资格认证并在 [AWS Partner 设备目录](https://devices.amazonaws.com/)中列示 Greengrass 设备。

请注意在连接到待测试设备的主机（Windows、macOS 或 Linux）上 AWS IoT Greengrass 运行。它运行测试并聚合结果。它还提供命令行界面来管理测试过程。

## AWS IoT Greengrass 资格套件
<a name="gg-qual-suite"></a>

使用 IDT 验证 AWS IoT Greengrass 核心软件是否在您的硬件上运行并且可以与通信。 AWS IoT Greengrass AWS 云它还使用执行 end-to-end测试 AWS IoT Core。例如，它验证您的设备是否能够发送和接收 MQTT 消息并正确处理它们。

![\[概述 AWS IoT 设备测试器如何验证 AWS IoT Greengrass 核心软件是否在您的硬件上运行以及是否可以与之 AWS 云通信。\]](http://docs.aws.amazon.com/zh_cn/greengrass/v1/developerguide/images/devicetester_gg.png)


AWS IoT Device Tester for 使用*测试套件*和*测试组*的概念 AWS IoT Greengrass 组织测试。<a name="idt-test-suites-groups"></a>
+ 测试套件是一组测试组，用于验证设备运行的是否为特定版本的 AWS IoT Greengrass。
+ 测试组是与特定功能相关的一组单独测试，例如 Greengrass 组部署和 MQTT 消息传递。

 有关更多信息，请参阅 [使用 IDT 运行 AWS IoT Greengrass 资格套件](idt-gg-qualification.md)。

## 自定义测试套件
<a name="custom-test-suite"></a>

<a name="idt-byotc"></a>从 IDT v4.0.0 开始，IDT for 将标准化配置设置和结果格式与测试套件环境 AWS IoT Greengrass 相结合，使您能够为设备和设备软件开发自定义测试套件。您可以添加自定义测试来用于自己的内部验证，也可以将其提供给客户进行设备验证。

测试编写者如何配置自定义测试套件决定了运行自定义测试套件需要的设置配置。有关更多信息，请参阅 [使用 IDT 开发和运行自己的测试套件](idt-custom-tests.md)。

# AWS IoT Greengrass V1 版 AWS IoT 设备测试器支持的版本
<a name="dev-test-versions"></a>

由于 AWS IoT Greengrass Version 1 已进入[维护模式](https://docs.aws.amazon.com/greengrass/v1/developerguide/maintenance-policy.html)，IDT for AWS IoT Greengrass V1 不再生成签名的资格报告。我们建议使用[适用于 AWS IoT Greengrass V2的 IDT](https://docs.aws.amazon.com/greengrass/v2/developerguide/device-tester-for-greengrass-ug.html)。

有关 IDT for AWS IoT Greengrass V2 的信息，请参阅《*AWS IoT Greengrass V2 开发人员*指南》 AWS IoT Greengrass V2中的[使用 AWS IoT 设备测试器](https://docs.aws.amazon.com/greengrass/v2/developerguide/device-tester-for-greengrass-ug.html)。

**注意**  
如果 IDT for 与 AWS IoT Greengrass 您正在使用的版本不兼容，则在开始测试运行时会收到通知。 AWS IoT Greengrass 

下载此软件即表示您同意 [AWS IoT Device Tester 许可协议](https://docs.aws.amazon.com/greengrass/latest/developerguide/idt-license.html)。



## 不支持的 IDT 版本 AWS IoT Greengrass
<a name="idt-unsupported-versions"></a>

本主题列出了不支持的 IDT 版本。 AWS IoT Greengrass不受支持的版本不会收到错误修复或更新。有关更多信息，请参阅 [AWS IoT 设备测试器的 Support 政策 AWS IoT Greengrass V1](idt-support-policy.md)。

**IDT v4.4.1 适用于 v1.11.6、v1.10. AWS IoT Greengrass 5**     
发行说明：  
+ 使您能够验证和鉴定运行 AWS IoT Greengrass 核心软件 v1.11.6 和 v1.10.5 的设备。
+ 包含次要错误修复。  
测试套件版本：    
`GGQ_1.3.1`  
+ 已发布时间：2021 年 12 月 20 日

**适用于 v1.11.4、v1.10.4 AWS IoT Greengrass 版本的 IDT v4.1.0**     
发行说明：  
+ 使您能够验证和鉴定运行 AWS IoT Greengrass 核心软件 v1.11.4 和 v1.10.4 的设备。
+ 修复了一个问题，该问题导致测试运行期间显示的日志使用冗余的标签。  
测试套件版本：    
`GGQ_1.3.0`  
+ 已发布时间：2021 年 6 月 23 日
+ 添加对 Lambda、IAM 的 API 调用的重试次数， AWS STS 并改进对限制或服务器问题的处理。
+ 在 ML 和 Docker 测试用例中添加了对 Python 3.8 的支持。

**适用于 v1.11.1、v1.11.0、v1.10.3 AWS IoT Greengrass 版本的 IDT v4.0.2**   
发行说明：  
+ 修复了导致 IDT 掩盖硬件安全集成 (HSI) 错误的问题。
+ 使您能够使用 AWS IoT 适用于 Device Tester 开发和运行自定义测试套件 AWS IoT Greengrass。有关更多信息，请参阅 [使用 IDT 开发和运行自己的测试套件](idt-custom-tests.md)。
+ 提供适用于 macOS 和 Windows 的代码签名 IDT 应用程序。在 macOS 中，如果显示安全警告消息，您可能需要为 IDT 授予安全例外。有关更多信息，请参阅 [macOS 上的安全例外](idt-troubleshooting.md#macos-notarization-exception)。
AWS IoT Greengrass 不为核心软件的 1.11.1 版本提供 Dockerfile 或 Docker 镜像。 AWS IoT Greengrass 要测试您的设备是否符合 Docker 资格，请使用早期版本的 AWS IoT Greengrass Core 软件。
 

**适用于 v1.11.0、v1.10.1、v1.10.0 AWS IoT Greengrass 版本的 IDT v3.2.0**  
发行说明：  
+ 默认情况下，IDT 仅运行必要的资格测试。要获得其他功能的资格，您可以修改 [`device.json`](set-config.md#device-config) 文件。
+ 在 `device.json` 中添加了一个可配置用于 SSH 连接配置的端口号。
+ Docker 仅在无容器化情况下支持[流管理器](stream-manager.md)和机器学习 (ML)。容器、Docker 和硬件安全集成 (HSI) 不适用于 Docker 设备。
+ 我们将 `device-ml.json` 和 `device-hsm.json` 合并成了 `device.json`。
 

**IDT v3.1.3 适用于以下 AWS IoT Greengrass 版本：v1.10.x、v1.9.x、v1.8.x**  
发行说明：  
+ 为 AWS IoT Greengrass v1.10.x 和 v1.9.x 添加了对机器学习功能限定的支持。现在，您可以使用 IDT 验证您的设备是否可以使用在云中存储和训练的模型在本地执行 ML 推理。
+ 为 `run-suite` 命令添加了 `--stop-on-first-failure`。您可以使用此选项将 IDT 配置为在第一次失败时停止运行。建议在调试阶段在测试组级别使用此选项。
+ 为 MQTT 测试添加了时钟偏移检查，以确保被测设备使用正确的系统时间。使用的时间必须在可接受的时间范围之内。
+ 为 `run-suite` 命令添加了 `--update-idt`。您可以使用此选项设置对更新 IDT 的提示的响应。
+ 为 `run-suite` 命令添加了 `--update-managed-policy`。您可以使用此选项设置对更新托管策略的提示的响应。
+ 为自动更新 IDT 测试套件版本添加了错误修复。该修复可确保 IDT 可以下载适用于您的 AWS IoT Greengrass 版本的最新测试套件。
 

**IDT v3.0.1 适用于 AWS IoT Greengrass**  
发行说明：  
+ 增加了对 AWS IoT Greengrass v1.10.1 的支持。
+ IDT 测试套件版本的自动更新。IDT 可以下载适用于您的 AWS IoT Greengrass 版本的最新测试套件。通过此功能：
  + 测试套件使用 `major.minor.patch` 格式进行版本化。初始测试套件版本为 `GGQ_1.0.0`。
  + 您可以在命令行界面中以交互方式下载新的测试套件，或在启动 IDT 时设置 `upgrade-test-suite` 标记。

  有关更多信息，请参阅 [测试套件版本](idt-gg-qualification.md#idt-test-suite-versions)。
+ 增加了 `list-supported-products`。您可以使用此命令列出已安装的 IDT 版本支持的 AWS IoT Greengrass 和测试套件版本。
+ 增加了 `list-test-cases`。您可以使用此命令列出测试组中可用的测试用例。
+ 为 `run-suite` 命令添加了 `test-id`。您可以使用此选项运行测试组中的单个测试用例。
 

**适用于 v AWS IoT Greengrass 1.10、v1.9.x 和 v1.8.x 的 IDT v2.3.0**  
在物理设备上进行测试时，支持 AWS IoT Greengrass v1.10、1.9.x 和 v1.8.x。  
在 Docker 容器中进行测试时，支持 AWS IoT Greengrass v1.10 和 1.9.x 版本。  
发行说明：  
+ 增加了对 [AWS IoT Greengrass 在 Docker 容器中运行](run-gg-in-docker-container.md) 的支持。现在，您可以使用 IDT 来鉴定和验证您的设备是否可以在 Docker AWS IoT Greengrass 容器中运行。
+ 添加了[AWS 托管策略](https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_managed-vs-inline.html#aws-managed-policies) (`AWSIoTDeviceTesterForGreengrassFullAccess`)，该策略定义了运行 AWS IoT 设备测试器所需的权限。如果新版本需要额外的权限，请将其 AWS 添加到此托管策略中，这样您就不必更新自己的 IAM 权限。
+ 引入了检查，用于先验证您的环境（例如，设备连接和 Internet 连接）是否已正确设置，然后再运行测试用例。
+ 改进了 IDT 中的 Greengrass 依赖项检查程序，使其可以更灵活地检查设备上的 libc。
 

**适用于 v AWS IoT Greengrass 1.10、v1.9.x 和 v1.8.x 的 IDT v2.2.0**  
发行说明：  
+ 增加了对 AWS IoT Greengrass v1.10 的支持。
+ 增加了对 [Greengrass Docker 应用程序部署](docker-app-connector.md)连接器的支持。
+ 增加了对 AWS IoT Greengrass [直播管理器的](stream-manager.md)支持。
+  AWS IoT Greengrass 在中国（北京）区域增加了对的支持。
 

**适用于 v1. AWS IoT Greengrass 9.x、v1.8.x 和 v1.7.x 的 IDT v2.1.0**  
发行说明：  
+ 增加了对 AWS IoT Greengrass v1.9.4 的支持。
+ 增加了对 Linux ARMv6l 设备的支持。
 

**适用于 v1.9.3、v1.9.2、v.1.9.1、 AWS IoT Greengrass v1.9.0、v1.8.4、v1.8.3 和 v1.8.2 的 IDT v2.0.0**  
发行说明：  
+ 删除了所测试设备对 Python 的依赖。
+ 测试套件的执行时间减少了 50％ 以上，从而使鉴定过程更快。
+ 可执行文件大小减少了 50% 以上，使下载和安装过程更快。
+ 改进了对所有测试用例的[超时乘数支持](idt-troubleshooting.md#test-timeout)。
+ 增强的诊断后消息，可更快地排除错误。
+ 更新了运行 IDT 所需的权限策略模板。
+ 增加了对 AWS IoT Greengrass v1.9.3 的支持。
 

**适用于 v1.9.2、v1.9.1、v1. AWS IoT Greengrass 9.0、v1.8.3 和 v1.8.2 的 IDT v1.3.3**  
发行说明：  
+ 添加了对 Greengrass 1.9.1 和 1.8.3 版本的支持。
+ 增加了对 Greengrass OpenWrt 的支持。
+ 添加了 SSH 用户名和密码设备登录。
+ 为 OpenWrtARMv7l 平台添加了原生测试错误修复。
 

**适用于 v1.8.1 的 IDT v1.2 AWS IoT Greengrass **  
发行说明：  
+ 添加了一个可配置的超时乘数，用于查找和排除超时问题（例如，低带宽连接）。
 

**适用于 v1.8.0 的 IDT v1.1 AWS IoT Greengrass **  
发行说明：  
+ 增加了对 AWS IoT Greengrass 硬件安全集成 (HSI) 的支持。
+ 增加了对 AWS IoT Greengrass 容器和无容器的支持。
+ 添加了自动创建 AWS IoT Greengrass 服务角色的功能。
+ 改进了测试资源清理。
+ 添加了测试执行摘要报告。
 

**适用于 v1.7.1 的 IDT v1.1 AWS IoT Greengrass **  
发行说明：  
+ 增加了对 AWS IoT Greengrass 硬件安全集成 (HSI) 的支持。
+ 增加了对 AWS IoT Greengrass 容器和无容器的支持。
+ 添加了自动创建 AWS IoT Greengrass 服务角色的功能。
+ 改进了测试资源清理。
+ 添加了测试执行摘要报告。
 

**适用于 v1.6.1 的 IDT v1.0 AWS IoT Greengrass **  
发行说明：  
+ 为兼容 future AWS IoT Greengrass 版本添加了 OTA 测试错误修复。
[如果你使用的是 1. AWS IoT Greengrass 6.1 版本的 IDT v1.0，则必须创建一个 Greengrass 服务角色。](service-role.md)在更高版本中，IDT 会为您创建服务角色。

# 使用 IDT 运行 AWS IoT Greengrass 资格套件
<a name="idt-gg-qualification"></a>

您可以使用 AWS IoT 设备测试器 (IDT) AWS IoT Greengrass 来验证 AWS IoT Greengrass 核心软件是否在您的硬件上运行并且可以与通信。 AWS 云它还使用执行 end-to-end测试 AWS IoT Core。例如，它验证您的设备是否能够发送和接收 MQTT 消息并正确处理它们。

由于 AWS IoT Greengrass Version 1 已进入[维护模式](https://docs.aws.amazon.com/greengrass/v1/developerguide/maintenance-policy.html)，IDT for AWS IoT Greengrass V1 不再生成签名的资格报告。如果要将硬件添加到 AWS Partner 设备目录中，请运行 AWS IoT Greengrass V2 资格套件以生成可以提交到的测试报告 AWS IoT。有关更多信息，请参阅[AWS 设备资格认证计划](https://aws.amazon.com/partners/dqp/)和[AWS IoT Greengrass V2 IDT 支持的版本。](https://docs.aws.amazon.com/greengrass/v2/developerguide/dev-test-versions.html)

除了测试设备外，IDT 还会在中 AWS IoT Greengrass 创建资源（例如， AWS IoT 事物、 AWS IoT Greengrass 群组、Lambda 函数等），以简化认证 AWS 账户 流程。

<a name="idt-aws-credentials"></a>要创建这些资源，IDT fo AWS IoT Greengrass r 使用`config.json`文件中配置的 AWS 凭据代表您进行 API 调用。这些资源将在测试过程的不同时间进行预置。

当您使用 IDT AWS IoT Greengrass 来运行 AWS IoT Greengrass 资格套件时，IDT 会执行以下步骤：

1. 加载和验证您的设备和凭证配置。

1. 使用所需的本地资源和云资源执行选定测试。

1. 清除本地资源和云资源。

1. 生成测试报告，指明您的设备是否已通过资格认证所需的测试。

## 测试套件版本
<a name="idt-test-suite-versions"></a>

IDT for 将测试 AWS IoT Greengrass 组织到测试套件和测试组中。<a name="idt-test-suites-groups"></a>
+ 测试套件是一组测试组，用于验证设备运行的是否为特定版本的 AWS IoT Greengrass。
+ 测试组是与特定功能相关的一组单独测试，例如 Greengrass 组部署和 MQTT 消息传递。

从 IDT v3.0.0 开始，测试套件使用 `major.minor.patch` 格式进行版本化，例如，`GGQ_1.0.0`。当您下载 IDT 时，数据包中包含最新的测试套件版本。

**重要**  
IDT 支持三个最新的测试套件版本以获得设备资格认证。有关更多信息，请参阅 [AWS IoT 设备测试器的 Support 政策 AWS IoT Greengrass V1](idt-support-policy.md)。  
您可以运行列`list-supported-products`出当前版本的 IDT 支持的版本 AWS IoT Greengrass 和测试套件。不受支持的测试套件版本进行的测试对于设备资格认证无效。IDT 不会为不受支持的版本打印资格认证报告。

### IDT 配置设置的更新
<a name="idt-test-suite-versions-config-changes"></a>

新测试可能会引入新的 IDT 配置设置。
+ 如果设置是可选的，IDT 将继续运行测试。
+ 如果需要这些设置，IDT 会通知您并停止运行。配置设置后，请重新启动测试运行。

  配置设置位于 `<device-tester-extract-location>/configs` 文件夹中。有关更多信息，请参阅 [配置 IDT 设置以运行 AWS IoT Greengrass 资格套件](set-config.md)。

如果更新的测试套件版本添加了配置设置，IDT 会在 `<device-tester-extract-location>/configs` 中创建原始配置文件的副本。

## 测试组描述
<a name="dt-test-groups"></a>

------
#### [ IDT v2.0.0 and later ]

**核心资格必备测试组**  
这些测试组必须使您的 AWS IoT Greengrass 设备符合 AWS Partner 设备目录的资格。    
AWS IoT Greengrass 核心依赖关系  
验证您的设备是否满足 C AWS IoT Greengrass ore 软件的所有软件和硬件要求。  
在 [Docker 容器](docker-config-setup.md)中进行测试时，此测试组中的 `Software Packages Dependencies` 测试用例不适用。  
部署  
验证 Lambda 函数是否可以部署到您的设备上。  
MQTT  
通过检查 Greengrass 核心和客户端设备（即本地物联网设备）之间的本地通信来验证 AWS IoT Greengrass 消息路由器的功能。  
Over-the-Air （OTA）  
验证您的设备能否成功执行 C AWS IoT Greengrass ore 软件的 OTA 更新。  
<a name="n-a-docker"></a>在 [Docker 容器](docker-config-setup.md)中进行测试时，此测试组不适用。  
版本  
检查 AWS IoT Greengrass 提供的版本是否与您正在使用的 AWS IoT 设备测试器版本兼容。

**可选测试组**  
这些测试组可选。如果您选择符合可选测试的资格，则您的设备将在 AWS Partner 设备目录中列出其他功能。    
容器依赖项  
<a name="description-container"></a>验证设备是否满足在 Greengrass 核心上以容器模式运行 Lambda 函数的所有软硬件要求。  
<a name="n-a-docker"></a>在 [Docker 容器](docker-config-setup.md)中进行测试时，此测试组不适用。  
部署容器  
<a name="description-deployment-container"></a>验证 Lambda 函数是否可以部署在设备上并在 Greengrass 核心上以容器模式运行。  
<a name="n-a-docker"></a>在 [Docker 容器](docker-config-setup.md)中进行测试时，此测试组不适用。  
Docker 依赖项（IDT v2.2.0 和更高版本支持）  
<a name="description-docker"></a>验证设备是否满足使用 Greengrass Docker 应用程序部署连接器以运行容器的所有必要技术依赖项  
<a name="n-a-docker"></a>在 [Docker 容器](docker-config-setup.md)中进行测试时，此测试组不适用。  
硬件安全性集成 (HSI)  
<a name="description-hsi"></a>验证提供的 HSI 共享库是否可以与硬件安全模块 (HSM) 接口并正确实现所需的 PKCS \$111。 APIs HSM 和共享库必须能够签署 CSR，执行 TLS 操作，并提供正确的密钥长度和公有密钥算法。  
流管理器依赖项（IDT v2.2.0 及更高版本支持）  
<a name="description-sm"></a>验证设备是否满足运行 AWS IoT Greengrass 直播管理器所需的所有技术依赖项。  
机器学习依赖项（IDT 版本 3.1.0 及更高版本支持）  
<a name="description-ml"></a>验证设备是否满足在本地执行 ML 推理所需的所有技术依赖项。  
机器学习推理测试（IDT 版本 3.1.0 及更高版本支持）  
<a name="description-mlit"></a>验证是否可以在给定的被测设备上执行 ML 推理。有关更多信息，请参阅 [可选：配置设备进行 ML 资格认证](idt-ml-qualification.md)。  
机器学习推理容器测试（IDT 版本 3.1.0 及更高版本支持）  
<a name="description-mlict"></a>验证是否可以在给定的被测设备上执行 ML 推理，以及是否可以在 Greengrass 核心上以容器模式运行 ML 推理。有关更多信息，请参阅 [可选：配置设备进行 ML 资格认证](idt-ml-qualification.md)。

------
#### [ IDT v1.3.3 and earlier ]

**核心资格必备测试组**  
必须进行这些测试才能使您的 AWS IoT Greengrass 设备符合 AWS Partner 设备目录的资格。    
AWS IoT Greengrass 核心依赖关系  
验证您的设备是否满足 C AWS IoT Greengrass ore 软件的所有软件和硬件要求。  
Combination（设备安全交互）  
通过更改云中 Greengrass 组的连接信息来验证 Greengrass 核心设备上的设备证书管理器和 IP 检测的功能。测试组轮换 AWS IoT Greengrass 服务器证书并验证是否 AWS IoT Greengrass 允许连接。  
部署（是 IDT v1.2 及更早版本所必需的）  
验证 Lambda 函数是否可以部署到您的设备上。  
Device Certificate Manager (DCM)  
验证 AWS IoT Greengrass 设备证书管理器是否可以在启动时生成服务器证书，如果证书接近到期，则可以轮换证书。  
IP 检测 (IPD)  
验证当 Greengrass 核心设备的 IP 地址更改时，核心的连接信息是否会更新。有关更多信息，请参阅 [激活自动 IP 检测](gg-core.md#ip-auto-detect)。  
日志记录  
验证 AWS IoT Greengrass 日志服务是否可以使用用 Python 编写的用户 Lambda 函数写入日志文件。  
MQTT  
通过发送有关路由到两个 Lambda 函数的主题的消息来验证消息路由器的功能。 AWS IoT Greengrass   
Native  
验证是否 AWS IoT Greengrass 可以运行本机（已编译的）Lambda 函数。  
Over-the-Air （OTA）  
验证您的设备能否成功执行 C AWS IoT Greengrass ore 软件的 OTA 更新。  
Penetration  
如果未启用硬链接/软链接保护和 s [eccom](https://www.kernel.org/doc/Documentation/prctl/seccomp_filter.txt) p，则验证 AWS IoT Greengrass 核心软件是否无法启动。它还可用于验证其他与安全相关的功能。  
影子  
验证本地影子和影子云同步功能。  
Spooler  
验证 MQTT 消息是否依据默认后台处理程序配置进行排队。  
Token Exchange Service (TES)  
验证是否 AWS IoT Greengrass 可以将其核心证书交换为有效 AWS 凭证。  
版本  
检查 AWS IoT Greengrass 提供的版本是否与您正在使用的 AWS IoT 设备测试器版本兼容。

**可选测试组**  
这些测试是可选的。如果您选择符合可选测试的资格，则您的设备将在 AWS Partner 设备目录中列出其他功能。    
容器依赖项  
检查设备是否满足在容器模式下运行 Lambda 函数所需的所有依赖项。  
硬件安全性集成 (HSI)  
验证提供的 HSI 共享库是否可以与硬件安全模块 (HSM) 接口并正确实现所需的 PKCS \$111。 APIs HSM 和共享库必须能够签署 CSR，执行 TLS 操作，并提供正确的密钥长度和公有密钥算法。  
本地资源访问  
 AWS IoT Greengrass 通过 LRA 向容器化 Lambda 函数提供对各种 Linux 用户和组拥有的本地文件和目录的访问权限，从而验证的本地资源访问 (LRA) 功能。 AWS IoT Greengrass APIs应基于本地资源访问配置允许或拒绝 Lambda 函数访问本地资源。  
网络  
验证是否可以从 Lambda 函数建立套接字连接。应根据 Greengrass 核心配置来允许或拒绝这些套接字连接。

------

# 运行 AWS IoT Greengrass 资格套件的先决条件
<a name="dev-tst-prereqs"></a>

本节介绍使用 AWS IoT 设备测试器 (IDT) 运行 AWS IoT Greengrass 资格套件的 AWS IoT Greengrass 先决条件。

## 下载最新版本的 AWS IoT 设备测试器 AWS IoT Greengrass
<a name="install-dev-tst-gg"></a>

下载 IDT 的[最新版本](dev-test-versions.md)并将软件提取到文件系统中您具有读取和写入权限的位置。

**注意**  
<a name="unzip-package-to-local-drive"></a>IDT 不支持由多个用户从共享位置（如 NFS 目录或 Windows 网络共享文件夹）运行。建议您将 IDT 包解压缩到本地驱动器，并在本地工作站上运行 IDT 二进制文件。  
Windows 的路径长度限制为 260 个字符。如果您使用的是 Windows，请将 IDT 提取到根目录（如 `C:\ ` 或 `D:\`）以使路径长度不超过 260 个字符的限制。

## 创建和配置 AWS 账户
<a name="config-aws-account-for-idt"></a>

在使用 IDT 之前 AWS IoT Greengrass，必须执行以下步骤：

1. [创建一个 AWS 账户.]() 如果您已经有 AWS 账户，请跳至步骤 2。

1. [为 IDT 配置权限。]()

这些账户权限允许 IDT 代表您访问 AWS 服务和创建 AWS 资源，例如 AWS IoT 事物、Greengrass 群组和 Lambda 函数。

<a name="idt-aws-credentials"></a>要创建这些资源，IDT fo AWS IoT Greengrass r 使用`config.json`文件中配置的 AWS 凭据代表您进行 API 调用。这些资源将在测试过程的不同时间进行预置。

**注意**  <a name="free-tier-tests"></a>
尽管大多数测试都符合 [Amazon Web Services 免费套餐](https://aws.amazon.com/free)的要求，但您在注册 AWS 账户时必须提供信用卡。有关更多信息，请参阅[我的账户使用的是免费套餐，为什么还需要提供付款方式？](https://aws.amazon.com/premiumsupport/knowledge-center/free-tier-payment-method/)

### 步骤 1：创建一个 AWS 账户
<a name="create-aws-account-for-idt"></a>

在此步骤中，将创建并配置 AWS 账户。如果您已经有 AWS 账户，请跳至[步骤 2：为 IDT 配置权限](#configure-idt-permissions)。

#### 注册获取 AWS 账户
<a name="sign-up-for-aws"></a>

如果您没有 AWS 账户，请完成以下步骤来创建一个。

**要注册 AWS 账户**

1. 打开[https://portal.aws.amazon.com/billing/注册。](https://portal.aws.amazon.com/billing/signup)

1. 按照屏幕上的说明操作。

   在注册时，将接到电话或收到短信，要求使用电话键盘输入一个验证码。

   当您注册时 AWS 账户，就会创建*AWS 账户根用户*一个。根用户有权访问该账户中的所有 AWS 服务 和资源。作为最佳安全实践，请为用户分配管理访问权限，并且只使用根用户来执行[需要根用户访问权限的任务](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_root-user.html#root-user-tasks)。

AWS 注册过程完成后会向您发送一封确认电子邮件。您可以随时前往 [https://aws.amazon.com/](https://aws.amazon.com/)并选择 “**我的账户”，查看当前账户活动并管理您的账户**。

#### 创建具有管理访问权限的用户
<a name="create-an-admin"></a>

注册后，请保护您的安全 AWS 账户 AWS 账户根用户 AWS IAM Identity Center，启用并创建管理用户，这样您就不会使用 root 用户执行日常任务。

**保护你的 AWS 账户根用户**

1.  选择 **Root 用户**并输入您的 AWS 账户 电子邮件地址，以账户所有者的身份登录。[AWS 管理控制台](https://console.aws.amazon.com/)在下一页上，输入您的密码。

   要获取使用根用户登录方面的帮助，请参阅《AWS 登录 用户指南》**中的 [Signing in as the root user](https://docs.aws.amazon.com/signin/latest/userguide/console-sign-in-tutorials.html#introduction-to-root-user-sign-in-tutorial)。

1. 为您的根用户启用多重身份验证（MFA）。

   有关说明，请参阅 I [A *M* 用户指南中的为 AWS 账户 根用户启用虚拟 MFA 设备（控制台）](https://docs.aws.amazon.com/IAM/latest/UserGuide/enable-virt-mfa-for-root.html)。

**创建具有管理访问权限的用户**

1. 启用 IAM Identity Center。

   有关说明，请参阅**《AWS IAM Identity Center 用户指南》中的[启用 AWS IAM Identity Center](https://docs.aws.amazon.com//singlesignon/latest/userguide/get-set-up-for-idc.html)。

1. 在 IAM Identity Center 中，为用户授予管理访问权限。

   有关使用 IAM Identity Center 目录 作为身份源的教程，请参阅《[用户*指南》 IAM Identity Center 目录中的使用默认设置配置AWS IAM Identity Center 用户*访问权限](https://docs.aws.amazon.com//singlesignon/latest/userguide/quick-start-default-idc.html)。

**以具有管理访问权限的用户身份登录**
+ 要使用您的 IAM Identity Center 用户身份登录，请使用您在创建 IAM Identity Center 用户时发送到您的电子邮件地址的登录 URL。

  有关使用 IAM Identity Center 用户[登录的帮助，请参阅*AWS 登录 用户指南*中的登录 AWS 访问门户](https://docs.aws.amazon.com/signin/latest/userguide/iam-id-center-sign-in-tutorial.html)。

**将访问权限分配给其他用户**

1. 在 IAM Identity Center 中，创建一个权限集，该权限集遵循应用最低权限的最佳做法。

   有关说明，请参阅《AWS IAM Identity Center 用户指南》**中的 [Create a permission set](https://docs.aws.amazon.com//singlesignon/latest/userguide/get-started-create-a-permission-set.html)。

1. 将用户分配到一个组，然后为该组分配单点登录访问权限。

   有关说明，请参阅《AWS IAM Identity Center 用户指南》**中的 [Add groups](https://docs.aws.amazon.com//singlesignon/latest/userguide/addgroups.html)。

### 步骤 2：为 IDT 配置权限
<a name="configure-idt-permissions"></a>

在此步骤中，配置 IDT 用于运行测试和收集 IDT AWS IoT Greengrass 使用情况数据的权限。您可以使用 AWS 管理控制台 或 AWS Command Line Interface (AWS CLI) 为 IDT 创建 IAM 策略和测试用户，然后将策略附加到该用户。如果您已经为 IDT 创建了测试用户，请跳转至 [配置设备以运行 IDT 测试](device-config-setup.md) 或 [可选：为 IDT 配置你的 Docker 容器 AWS IoT Greengrass](docker-config-setup.md)。
+ [为 IDT 配置权限（控制台）](#configure-idt-permissions-console)
+ [为 IDT 配置权限 (AWS CLI)](#configure-idt-permissions-cli)<a name="configure-idt-permissions-console"></a>

**为 IDT 配置权限（控制台）**

请按照以下步骤使用控制台为 IDT for AWS IoT Greengrass配置权限。

1. 登录 [IAM 控制台](https://console.aws.amazon.com/iam)。

1. 创建客户托管策略，该策略授权创建具有特定权限的角色。

   1. 在导航窗格中，选择 **策略**，然后选择 **创建策略**。

   1. 在 **JSON** 选项卡中，将占位符内容替换为以下策略。

------
#### [ JSON ]

****  

      ```
      {
          "Version":"2012-10-17",		 	 	 
          "Statement": [
              {
                  "Sid": "ManageRolePoliciesForIDTGreengrass",
                  "Effect": "Allow",
                  "Action": [
                      "iam:DetachRolePolicy",
                      "iam:AttachRolePolicy"
                  ],
                  "Resource": [
                      "arn:aws:iam::*:role/idt-*",
                      "arn:aws:iam::*:role/GreengrassServiceRole"
                  ],
                  "Condition": {
                      "ArnEquals": {
                          "iam:PolicyARN": [
                              "arn:aws:iam::aws:policy/service-role/AWSGreengrassResourceAccessRolePolicy",
                              "arn:aws:iam::aws:policy/service-role/GreengrassOTAUpdateArtifactAccess",
                              "arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole"
                          ]
                      }
                  }
              },
              {
                  "Sid": "ManageRolesForIDTGreengrass",
                  "Effect": "Allow",
                  "Action": [
                      "iam:CreateRole",
                      "iam:DeleteRole",
                      "iam:PassRole",
                      "iam:GetRole"
                  ],
                  "Resource": [
                    "arn:aws:iam::123456789012:role/idt-*",
                    "arn:aws:iam::123456789012:role/GreengrassServiceRole"
                  ]
              }
          ]
      }
      ```

------
**重要**  <a name="policy-grants-role-perms"></a>
以下策略授权来创建和管理适用于 AWS IoT Greengrass的 IDT 所需的角色。这包括附加以下 AWS 托管策略的权限：  
[AWSGreengrassResourceAccessRolePolicy](https://console.aws.amazon.com/iam/home#/policies/arn:aws:iam::aws:policy/service-role/AWSGreengrassResourceAccessRolePolicy)
[Greengrass OTAUpdate ArtifactAccess](https://console.aws.amazon.com/iam/home#/policies/arn:aws:iam::aws:policy/service-role/GreengrassOTAUpdateArtifactAccess)
[AWSLambdaBasicExecutionRole](https://console.aws.amazon.com/iam/home#/policies/arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole)

   1. 选择**下一步：标签**。

   1. 选择**下一步：审核**。

   1. 对于**名称**，请输入 **IDTGreengrassIAMPermissions**。在 **Summary (摘要)** 下，查看策略授予的权限。

   1. 选择**创建策略**。

1. 创建 IAM 用户并附加 IDT for AWS IoT Greengrass所需的权限。

   1. 创建 IAM 用户。按照 *IAM 用户指南*的[创建 IAM 用户（控制台）](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_users_create.html#id_users_create_console)中的步骤 1 到 5 操作。

   1. 将权限附加到您的 IAM 用户：

      1. 在 **设置权限** 页面上，选择 **直接附加现有策略**。

      1. 搜索您在上一步中创建的**IDTGreengrassIAMPermissions**策略。选中复选框。

      1. 搜索**AWSIoTDeviceTesterForGreengrassFullAccess**政策。选中复选框。
**注意**  <a name="AWSIoTDeviceTesterForGreengrassFullAccess"></a>
[AWSIoTDeviceTesterForGreengrassFullAccess](https://console.aws.amazon.com/iam/home#/policies/arn:aws:iam::aws:policy/AWSIoTDeviceTesterForGreengrassFullAccess)是一种 AWS 托管策略，它定义了 IDT 创建和访问用于测试的 AWS 资源所需的权限。有关更多信息，请参阅 [AWS AWS IoT 设备测试器的托管策略](#idt-managed-policy)。

   1. 选择**下一步：标签**。

   1. 选择 **Next: Review (下一步：审核)** 以查看您的选择摘要。

   1. 选择**创建用户**。

   1. 要查看用户的访问密钥（访问密钥 IDs 和私有访问密钥），请选择密码和访问密钥旁边的**显示**。要保存访问密钥，请选择**Download.csv (下载 .csv)**，然后将文件保存到安全位置。稍后您可以使用此信息配置 AWS 凭证文件。

1. <a name="aws-account-config-next-steps"></a>下一步：配置[物理设备](device-config-setup.md)。

 <a name="configure-idt-permissions-cli"></a>

**为 IDT 配置权限 (AWS CLI)**

按照以下步骤 AWS CLI 使用配置 IDT 的 AWS IoT Greengrass权限。如果您已在控制台中配置权限，请跳转至 [配置设备以运行 IDT 测试](device-config-setup.md) 或 [可选：为 IDT 配置你的 Docker 容器 AWS IoT Greengrass](docker-config-setup.md)。

1.  AWS CLI 如果尚未安装，请在您的计算机上进行安装和配置。按照《AWS Command Line Interface 用户指南》**中[安装 AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-install.html) 的步骤来操作。
**注意**  
 AWS CLI 是一个开源工具，可用于通过命令行 shell 与 AWS 服务进行交互。

1. 创建用于授予管理 IDT 和 AWS IoT Greengrass 角色的权限的客户托管策略。

------
#### [ Linux, macOS, or Unix ]

   ```
   aws iam create-policy --policy-name IDTGreengrassIAMPermissions --policy-document '{
       "Version":"2012-10-17",		 	 	 
       "Statement": [
           {
               "Sid": "ManageRolePoliciesForIDTGreengrass",
               "Effect": "Allow",
               "Action": [
                   "iam:DetachRolePolicy",
                   "iam:AttachRolePolicy"
               ],
               "Resource": [
                   "arn:aws:iam::*:role/idt-*",
                   "arn:aws:iam::*:role/GreengrassServiceRole"
               ],
               "Condition": {
                   "ArnEquals": {
                       "iam:PolicyARN": [
                           "arn:aws:iam::aws:policy/service-role/AWSGreengrassResourceAccessRolePolicy",
                           "arn:aws:iam::aws:policy/service-role/GreengrassOTAUpdateArtifactAccess",
                           "arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole"
                       ]
                   }
               }
           },
           {
               "Sid": "ManageRolesForIDTGreengrass",
               "Effect": "Allow",
               "Action": [
                   "iam:CreateRole",
                   "iam:DeleteRole",
                   "iam:PassRole",
                   "iam:GetRole"
               ],
               "Resource": [
                 "arn:aws:iam::123456789012:role/idt-*",
                 "arn:aws:iam::123456789012:role/GreengrassServiceRole"
               ]
           }
       ]
   }'
   ```

------
#### [ Windows command prompt ]

   ```
   aws iam create-policy --policy-name IDTGreengrassIAMPermissions --policy-document '{\"Version\": \"2012-10-17\",		 	 	  \"Statement\": [{\"Sid\": \"ManageRolePoliciesForIDTGreengrass\",\"Effect\": \"Allow\",\"Action\": [\"iam:DetachRolePolicy\", \"iam:AttachRolePolicy\"], \"Resource\": [\"arn:aws:iam::*:role/idt-*\",\"arn:aws:iam::*:role/GreengrassServiceRole\"],\"Condition\": {\"ArnEquals\": {\"iam:PolicyARN\": [\"arn:aws:iam::aws:policy/service-role/AWSGreengrassResourceAccessRolePolicy\",\"arn:aws:iam::aws:policy/service-role/GreengrassOTAUpdateArtifactAccess\",\"arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole\"]}}},{\"Sid\": \"ManageRolesForIDTGreengrass\",\"Effect\": \"Allow\",\"Action\": [\"iam:CreateRole\",\"iam:DeleteRole\", \"iam:PassRole\", \"iam:GetRole\"],\"Resource\": [\"arn:aws:iam::*:role/idt-*\",\"arn:aws:iam::*:role/GreengrassServiceRole\"]}]}'
   ```

**注意**  
此步骤包含一个 Windows 命令提示符示例，因为它使用的 JSON 语法与 Linux、macOS 或 Unix 终端命令不同。

------

1. 创建 IAM 用户并附加适用于 AWS IoT Greengrass的 IDT 所需的权限。

   1. 创建 IAM 用户。在此示例设置中，用户被命名为 `IDTGreengrassUser`。

      ```
      aws iam create-user --user-name IDTGreengrassUser
      ```

   1. 将您在步骤 2 中创建的 `IDTGreengrassIAMPermissions` 策略附加到您的 IAM 用户。*<account-id>*在命令中替换为您的 ID AWS 账户。

      ```
      aws iam attach-user-policy --user-name IDTGreengrassUser --policy-arn arn:aws:iam::<account-id>:policy/IDTGreengrassIAMPermissions
      ```

   1. 将 `AWSIoTDeviceTesterForGreengrassFullAccess` 策略附加到您的 IAM 用户。

      ```
      aws iam attach-user-policy --user-name IDTGreengrassUser --policy-arn arn:aws:iam::aws:policy/AWSIoTDeviceTesterForGreengrassFullAccess
      ```
**注意**  <a name="AWSIoTDeviceTesterForGreengrassFullAccess"></a>
[AWSIoTDeviceTesterForGreengrassFullAccess](https://console.aws.amazon.com/iam/home#/policies/arn:aws:iam::aws:policy/AWSIoTDeviceTesterForGreengrassFullAccess)是一种 AWS 托管策略，它定义了 IDT 创建和访问用于测试的 AWS 资源所需的权限。有关更多信息，请参阅 [AWS AWS IoT 设备测试器的托管策略](#idt-managed-policy)。

1. 为用户创建私密访问密钥。

   ```
   aws iam create-access-key --user-name IDTGreengrassUser
   ```

   将输出存储在安全位置。稍后您将使用此信息来配置您的 AWS 凭据文件。

1. <a name="aws-account-config-next-steps"></a>下一步：配置[物理设备](device-config-setup.md)。

## AWS AWS IoT 设备测试器的托管策略
<a name="idt-managed-policy"></a>

[AWSIoTDeviceTesterForGreengrassFullAccess](https://console.aws.amazon.com/iam/home#/policies/arn:aws:iam::aws:policy/AWSIoTDeviceTesterForGreengrassFullAccess)托管策略允许 IDT 运行操作和收集使用量指标。此策略授予以下 IDT 权限：
+ `iot-device-tester:CheckVersion`。 检查一组 AWS IoT Greengrass测试套件和 IDT 版本是否兼容。
+ `iot-device-tester:DownloadTestSuite`. 下载测试套件。
+ `iot-device-tester:LatestIdt`. 获取有关可供下载的最新 IDT 版本的信息。
+ `iot-device-tester:SendMetrics`. 发布 IDT 收集的有关测试的使用情况数据。
+ `iot-device-tester:SupportedVersion`。 获取 IDT 支持的测试套件版本列表 AWS IoT Greengrass 和测试套件版本。此信息显示在命令行窗口中。

# 配置设备以运行 IDT 测试
<a name="device-config-setup"></a>

要配置您的设备，您必须安装 AWS IoT Greengrass 依赖项、配置 AWS IoT Greengrass Core 软件、配置主机以访问您的设备，并在设备上配置用户权限。

## 验证与被测设备的 AWS IoT Greengrass 依赖关系
<a name="install-gg-dependencies"></a>

在 IDT f AWS IoT Greengrass or 测试您的设备之前，请确保您已[按照 AWS IoT Greengrass入门](https://docs.aws.amazon.com/greengrass/latest/developerguide/gg-gs.html)中所述设置设备。有关支持的平台的信息，请参阅[支持的平台](https://docs.aws.amazon.com/greengrass/latest/developerguide/what-is-gg.html#gg-platforms)。

## 配置 AWS IoT Greengrass 软件
<a name="config-gg"></a>

IDT 用于 AWS IoT Greengrass 测试您的设备是否与特定版本的 AWS IoT Greengrass兼容。IDT 提供了两种 AWS IoT Greengrass 在您的设备上进行测试的选项：
+ 下载并使用某一版本的 [AWS IoT Greengrass 核心软件](what-is-gg.md#gg-core-download-tab)。IDT 为您安装此软件。
+ 使用设备上已安装的 AWS IoT Greengrass Core 软件版本。

**注意**  
的 AWS IoT Greengrass 每个版本都有相应的 IDT 版本。您必须下载与 AWS IoT Greengrass 您正在使用的版本相对应的 IDT 版本。

以下各节介绍了这些选项。您只需要使用其中一个选项。

### 选项 1：下载 AWS IoT Greengrass 核心软件并配置 AWS IoT 设备测试器以使用它
<a name="download-gg"></a>

您可以从 AWS IoT Greengrass 核心软件下载页面下载[AWS IoT Greengrass 核心软件](what-is-gg.md#gg-core-download-tab)。

1. 找到正确的架构和 Linux 发行版，然后选择 **Download (下载)**。

1. 将该 tar.gz 文件复制到 `<device-tester-extract-location>/products/greengrass/ggc`。

**注意**  
请勿更改 AWS IoT Greengrass tar.gz 文件的名称。对于相同的操作系统和架构，请勿在此目录中放置多个文件。例如，在该目录中同时放置 `greengrass-linux-armv7l-1.7.1.tar.gz` 和 `greengrass-linux-armv7l-1.8.1.tar.gz` 文件将导致测试失败。

### 选项 2：将现有安装的 AWS IoT Greengrass 与 AWS IoT 设备测试器一起使用
<a name="existing-gg"></a>

通过向`<device-tester-extract-location>/configs`文件夹中的`device.json`文件添加`greengrassLocation`属性，配置 IDT 以测试设备上安装的 C AWS IoT Greengrass ore 软件。例如：

```
"greengrassLocation" : "<path-to-greengrass-on-device>"
```

有关 `device.json` 文件的更多信息，请参阅[配置 device.json](set-config.md#device-config)。

在 Linux 设备上， AWS IoT Greengrass 核心软件的默认位置是`/greengrass`。

**注意**  
您的设备应该安装了尚未启动的 AWS IoT Greengrass Core 软件。  
确保您已在设备上添加 `ggc_user` 用户和 `ggc_group`。有关更多信息，请参阅 [AWS IoT Greengrass的环境设置](https://docs.aws.amazon.com/greengrass/latest/developerguide/module1.html)。

## 配置主机以访问被测设备
<a name="configure-host"></a>

IDT 在主机上运行，并且必须能够使用 SSH 连接到您的设备。有两个选项允许 IDT 获得对被测设备的 SSH 访问权限：

1. 按照此处的说明创建一个 SSH 密钥对并授权您的密钥，以便登录被测设备而无需指定密码。

1. 在 `device.json` 文件中为每个设备提供用户名和密码。有关更多信息，请参阅 [配置 device.json](set-config.md#device-config)。

您可以使用任何 SSL 实现创建 SSH 密钥。以下说明向你展示了如何使用 [SSH-KEYGEN](https://www.ssh.com/ssh/keygen/) 或 [Pu TTYgen](https://www.ssh.com/ssh/putty/windows/puttygen)（适用于 Windows）。如果您使用的是另一个 SSL 实现，请参阅该实现的文档。

IDT 使用 SSH 密钥对被测设备进行身份验证。

**使用 SSH-KEYGEN 创建 SSH 密钥**

1. 创建 SSH 密钥。

   您可以使用 Open SSH **ssh-keygen** 命令创建 SSH 密钥对。如果您的主机上已有一个 SSH 密钥对，则最佳做法是专门为 IDT 创建一个 SSH 密钥对。这样，完成测试后，如果没有输入密码，主机将无法再连接到设备。它还使您能够仅向需要访问远程设备的人员授予访问权限。
**注意**  
Windows 没有安装 SSH 客户端。有关在 Windows 上安装 SSH 客户端的信息，请参阅[下载 SSH 客户端软件](https://www.ssh.com/ssh/#sec-Download-client-software)。

   **ssh-keygen** 命令会提示您输入要存储密钥对的名称和路径。默认情况下，密钥对文件的名称为 `id_rsa`（私有密钥）和 `id_rsa.pub`（公有密钥）。在 macOS 和 Linux 上，这些文件的默认位置为 `~/.ssh/`。在 Windows 上，默认位置为 `C:\Users\<user-name>\.ssh`。

   根据提示，输入密钥短语来保护您的 SSH 密钥。有关更多信息，请参阅[生成新的 SSH 密钥](https://www.ssh.com/ssh/keygen/)。

1. 向被测设备添加经过授权的 SSH 密钥。

   IDT 必须使用您的 SSH 私有密钥登录被测设备。要授权 SSH 私有密钥以登录被测设备，请在主机上使用 **ssh-copy-id** 命令。此命令会将您的公有密钥添加到被测设备上的 `~/.ssh/authorized_keys` 文件中。例如：

   **\$1 ssh-copy-id *<remote-ssh-user>*@*<remote-device-ip>***

   哪里*remote-ssh-user*是用于登录被测设备的用户名，以及*remote-device-ip*用于运行测试的被测设备的 IP 地址。例如：

   **ssh-copy-id pi@192.168.1.5**

   系统提示时，输入在 **ssh-copy-id** 命令中指定的用户名所对应的密码。

   **ssh-copy-id** 公有密钥的名称为 `id_rsa.pub` 并且存储在默认位置（macOS 和 Linux 上的位置为 `~/.ssh/`，Windows 上的位置为 `C:\Users\<user-name>\.ssh`）。如果公有密钥采用其他名称或存储在其他位置，则必须使用 **-i** 选项与 **ssh-copy-id** 指定 SSH 公有密钥的完全限定路径（例如，**ssh-copy-id -i \$1/my/path/myKey.pub**）。有关创建 SSH 密钥和复制公有密钥的更多信息，请参阅 [SSH-COPY-ID](https://www.ssh.com/ssh/copy-id)。

**使用 Pu 创建 SSH 密钥TTYgen （仅限 Windows）**

1. 确保您在被测设备上安装了 OpenSSH 服务器和客户端。有关更多信息，请参阅 [OpenSSH](https://www.openssh.com/)。

1. 在被测设备TTYgen上安装 [Pu](https://www.puttygen.com/)。

1. 打开 Pu TTYgen。

1. 选择 **Generate (生成)**，然后在框中移动鼠标光标以生成私有密钥。

1. 从 **Conversions (转换)** 菜单中，选择 **Export OpenSSH key (导出 OpenSSH 密钥)**，然后使用 `.pem` 文件扩展名保存私有密钥 。

1. 将公有密钥添加到被测设备上的 `/home/<user>/.ssh/authorized_keys` 文件中。

   1. 从 Pu TTYgen 窗口复制公钥文本。

   1. 使用 PuTTY 在被测设备上创建会话。

      1. 从命令提示符或 Windows Powershell 窗口中，运行以下命令：

         **C:/*<path-to-putty>*/putty.exe -ssh *<user>*@*<dut-ip-address>***

      1. 在系统提示时，输入您的设备密码。

      1. 使用 vi 或其他文本编辑器将公有密钥附加到被测设备上的 `/home/<user>/.ssh/authorized_keys` 文件中。

1. 使用您的用户名、IP 地址以及您刚刚为每个被测设备保存在主机上的私钥文件的路径更新 `device.json` 文件。有关更多信息，请参阅 [配置 device.json](set-config.md#device-config)。确保提供私有密钥的完整路径和文件名，并使用正斜杠（“/”）。例如，对于 Windows 路径 `C:\DT\privatekey.pem`，请在 `device.json` 文件中使用 `C:/DT/privatekey.pem`。

## 在您的设备上配置用户权限
<a name="root-access"></a>

IDT 将对被测设备中的各种目录和文件执行操作。其中一些操作需要升级权限（使用 **sudo**）。要自动执行这些操作，IDT fo AWS IoT Greengrass r 必须能够在不被提示输入密码的情况下使用 sudo 运行命令。

请在被测设备上执行以下步骤，以允许在不提示输入密码的情况下进行 sudo 访问。

**注意**  
`username` 是指 IDT 用来访问被测设备的 SSH 用户。

**将用户添加到 sudo 组**

1. 在被测设备上，运行 `sudo usermod -aG sudo <username>`。

1. 注销，然后重新登录，以使变更生效。

1. 要验证您的用户名是否已成功添加，请运行 **sudo echo test**。如果系统未提示您输入密码，则说明已正确配置您的用户。

1. 打开 `/etc/sudoers` 文件，并将以下行添加到文件末尾：

   `<ssh-username> ALL=(ALL) NOPASSWD: ALL`

## 配置设备以测试可选功能
<a name="optional-feature-config"></a>

以下主题介绍如何配置设备以针对可选功能运行 IDT 测试。请仅在要测试这些功能时才执行以下配置步骤。否则，请继续查看 [配置 IDT 设置以运行 AWS IoT Greengrass 资格套件](set-config.md)。

**Topics**
+ [验证与被测设备的 AWS IoT Greengrass 依赖关系](#install-gg-dependencies)
+ [配置 AWS IoT Greengrass 软件](#config-gg)
+ [配置主机以访问被测设备](#configure-host)
+ [在您的设备上配置用户权限](#root-access)
+ [配置设备以测试可选功能](#optional-feature-config)
+ [可选：为 IDT 配置你的 Docker 容器 AWS IoT Greengrass](docker-config-setup.md)
+ [可选：配置设备进行 ML 资格认证](idt-ml-qualification.md)

# 可选：为 IDT 配置你的 Docker 容器 AWS IoT Greengrass
<a name="docker-config-setup"></a>

AWS IoT Greengrass 提供了 Docker 镜像和 Dockerfile，可以更轻松地在 Docker 容器中运行 AWS IoT Greengrass 核心软件。设置 AWS IoT Greengrass 容器后，您可以运行 IDT 测试。目前，只有 x86\$164 Docker 架构支持运行适用于 AWS IoT Greengrass的 IDT。

此功能需要 IDT v2.3.0 或更高版本。

设置 Docker 容器以运行 IDT 测试的过程取决于您使用的是提供的 Docker 镜像还是使用的 Dockerfile。 AWS IoT Greengrass
+ [使用 Docker 映像](#docker-config-setup-docker-image)。Docker 镜像安装了 AWS IoT Greengrass 核心软件和依赖项。
+ [使用 Dockerfile](#docker-config-setup-dockerfile)。Dockerfile 包含可用于构建自定义 AWS IoT Greengrass 容器镜像的源代码。可对镜像进行修改以在不同的平台架构上运行或减少镜像的大小。
**注意**  
AWS IoT Greengrass 不为 AWS IoT Greengrass 核心软件版本 1.11.1 提供 Dockerfile 或 Docker 镜像。要对您自己的自定义容器映像运行 IDT 测试，您的映像必须包含在提供的 Dockerfile 中定义的依赖关系。 AWS IoT Greengrass

在 Docker 容器 AWS IoT Greengrass 中运行时，以下功能不可用：<a name="docker-image-unsupported-features"></a>
+ 在 **Greengrass 容器模式**下运行的[连接器](connectors.md)。要在 Docker 容器中运行连接器，该连接器必须在**无容器**模式下运行。要查找支持**无容器**模式的连接器，请参阅[AWS提供的 Greengrass 连接器](connectors-list.md)。其中一些连接器具有隔离模式参数，您必须将此参数设为**无容器**。
+ [本地设备和卷资源](access-local-resources.md)。在 Docker 容器中运行的用户定义 Lambda 函数必须直接访问核心上的设备和卷。

## 配置由提供的 Docker 镜像 AWS IoT Greengrass
<a name="docker-config-setup-docker-image"></a>

按照以下步骤配置 AWS IoT Greengrass Docker 镜像以运行 IDT 测试。

**先决条件**

在开始本教程之前，必须执行以下操作。<a name="docker-image-prereq-list"></a>
+ 您必须根据您选择的 AWS Command Line Interface (AWS CLI) 版本在主机上安装以下软件和版本。

------
#### [ AWS CLI version 2 ]
  + [Docker](https://docs.docker.com/install/) 版本 18.09 或更高版本。早期版本也可能有效，但我们建议使用 18.09 或更高版本。
  + AWS CLI 版本 2.0.0 或更高版本。
    + 要安装 AWS CLI 版本 2，请参阅[安装 AWS CLI 版本 2](https://docs.aws.amazon.com/cli/latest/userguide/install-cliv2.html)。
    + 要配置 AWS CLI，请参阅[配置 AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-configure.html)。
**注意**  
要在 Windows 计算机上升级到更高 AWS CLI 版本 2，必须重复 [MSI 安装](https://docs.aws.amazon.com/cli/latest/userguide/install-cliv2-windows.html)过程。

------
#### [ AWS CLI version 1 ]
  + [Docker](https://docs.docker.com/install/) 版本 18.09 或更高版本。早期版本也可能有效，但我们建议使用 18.09 或更高版本。
  + [Python](https://www.python.org/downloads/) 版本 3.6 或更高版本。
  + [pip](https://pip.pypa.io/en/stable/installing) 版本 18.1 或更高版本。
  + AWS CLI 版本 1.17.10 或更高版本
    + 要安装 AWS CLI 版本 1，请参阅[安装 AWS CLI 版本 1](https://docs.aws.amazon.com/cli/latest/userguide/install-cliv1.html)。
    + 要配置 AWS CLI，请参阅[配置 AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-configure.html)。
    + 要升级到版本 1 的最新 AWS CLI 版本，请运行以下命令。

      ```
      pip install awscli --upgrade --user
      ```
**注意**  
如果你在 Windows 上使用 [MSI 安装](https://docs.aws.amazon.com/cli/latest/userguide/install-windows.html#msi-on-windows) AWS CLI 版本 1，请注意以下几点：  
如果 AWS CLI 版本 1 安装无法安装 botocore，请尝试使用 Pyth [on 和 pip](https://docs.aws.amazon.com/cli/latest/userguide/awscli-install-windows.html#awscli-install-windows-pip) 安装。
要升级到更高 AWS CLI 版本 1，必须重复 MSI 安装过程。

------
+ 要访问 Amazon Elastic Container Registry (Amazon ECR) 资源，您必须授予以下权限。
  + Amazon ECR 要求用户通过 AWS Identity and Access Management (IAM) 策略授予`ecr:GetAuthorizationToken`权限，然后才能向注册表进行身份验证以及从 Amazon ECR 存储库推送或拉取映像。有关更多信息，请参阅 *Amazon Elastic Container Registry 用户指南*中的 [Amazon ECR 存储库策略示例](https://docs.aws.amazon.com/AmazonECR/latest/userguide/repository-policy-examples.html)和[访问一个 Amazon ECR 存储库](https://docs.aws.amazon.com/AmazonECR/latest/userguide/security_iam_id-based-policy-examples.html#security_iam_id-based-policy-examples-access-one-bucket)。

 

1. 下载 Docker 映像并配置容器。您可以从 [Docker Hub](https://hub.docker.com/r/amazon/aws-iot-greengrass) 或 [Amazon Elastic Container Registry](https://docs.aws.amazon.com/AmazonECR/latest/userguide/what-is-ecr.html) (Amazon ECR) 下载预构建的映像并在 Windows、macOS 和 Linux (x86\$164) 平台上运行它。

   要从 Amazon ECR 下载 Docker 映像，请完成 [第 1 步：从 Amazon ECR 获取 AWS IoT Greengrass 容器镜像](run-gg-in-docker-container.md#docker-pull-image) 中的所有步骤。然后，返回到本主题以继续配置。

1. <a name="docker-linux-non-root"></a>仅限 Linux 用户：请确保运行 IDT 的用户有权运行 Docker 命令。有关更多信息，请参阅 Docker 文档中的[以非根用户身份管理 Docker](https://docs.docker.com/install/linux/linux-postinstall/#manage-docker-as-a-non-root-user)。

1. <a name="docker-run-gg-container"></a>要运行 AWS IoT Greengrass 容器，请使用适用于您的操作系统的命令：

------
#### [ Linux ]

   ```
   docker run --rm --init -it -d --name aws-iot-greengrass \
   -p 8883:8883 \
   -v <host-path-to-kernel-config-file>:<container-path> \
   <image-repository>:<tag>
   ```
   + *<host-path-to-kernel-config-file>*替换为主机上内核配置文件的路径以及*<container-path>*容器中装入卷的路径。

     主机上的内核配置文件通常位于 `/proc/config.gz` 或 `/boot/config-<kernel-release-date>` 中。你可以跑`uname -r`去找*<kernel-release-date>*值。

     **示例：**从 `/boot/config-<kernel-release-date>` 装载 Config 文件

     ```
     -v /boot/config-4.15.0-74-generic:/boot/config-4.15.0-74-generic \
     ```

     **示例：**从 `proc/config.gz` 装载 Config 文件

     ```
     -v /proc/config.gz:/proc/config.gz \
     ```
   + 将*<image-repository>*：*<tag>*在命令中替换为存储库的名称和目标图像的标签。

     **示例：**指向最新版本的 AWS IoT Greengrass Core 软件

     ```
     216483018798.dkr.ecr.us-west-2.amazonaws.com/aws-iot-greengrass:latest
     ```

     要获取 AWS IoT Greengrass Docker 镜像列表，请运行以下命令。

     ```
     aws ecr list-images --region us-west-2 --registry-id 216483018798 --repository-name aws-iot-greengrass
     ```

------
#### [ macOS ]

   ```
   docker run --rm --init -it -d --name aws-iot-greengrass \
   -p 8883:8883 \
   <image-repository>:<tag>
   ```
   + 将*<image-repository>*：*<tag>*在命令中替换为存储库的名称和目标图像的标签。

     **示例：**指向最新版本的 AWS IoT Greengrass Core 软件

     ```
     216483018798.dkr.ecr.us-west-2.amazonaws.com/aws-iot-greengrass:latest
     ```

     要获取 AWS IoT Greengrass Docker 镜像列表，请运行以下命令：

     ```
     aws ecr list-images --region us-west-2 --registry-id 216483018798 --repository-name aws-iot-greengrass
     ```

------
#### [ Windows ]

   ```
   docker run --rm --init -it -d --name aws-iot-greengrass \
   -p 8883:8883 \
   <image-repository>:<tag>
   ```
   + 将*<image-repository>*：*<tag>*在命令中替换为存储库的名称和目标图像的标签。

     **示例：**指向最新版本的 AWS IoT Greengrass Core 软件

     ```
     216483018798.dkr.ecr.us-west-2.amazonaws.com/aws-iot-greengrass:latest
     ```

     要获取 AWS IoT Greengrass Docker 镜像列表，请运行以下命令：

     ```
     aws ecr list-images --region us-west-2 --registry-id 216483018798 --repository-name aws-iot-greengrass
     ```

------
**重要**  
使用 IDT 进行测试时，请勿包含用于运行图像以供一般 AWS IoT Greengrass 用途的`--entrypoint /greengrass-entrypoint.sh \`参数。

1. <a name="docker-config-next-steps"></a>下一步：[配置您的 AWS 凭据和`device.json`文件](set-config.md)。

## 配置由提供的 dockerfile AWS IoT Greengrass
<a name="docker-config-setup-dockerfile"></a>

按照以下步骤配置从 Dockerf AWS IoT Greengrass ile 构建的 Docker 镜像以运行 IDT 测试。

1. 从 [AWS IoT Greengrass Docker 软件](what-is-gg.md#gg-docker-download)，将 Dockerfile 包下载到您的主机并将其解压缩。

1. 打开 `README.md`。接下来的三个步骤将参考此文件中的部分。

1. 请确保您满足**先决条件**部分中的要求。

1. 仅限 Linux 用户：完成**启用符号链接和硬链接保护**以及**启用 IPv4 网络转发步骤**。

1. 要构建 Docker 映像，请完成**步骤 1。构建 AWS IoT Greengrass Docker 镜像**。然后，返回到本主题以继续配置。

1. <a name="docker-run-gg-container"></a>要运行 AWS IoT Greengrass 容器，请使用适用于您的操作系统的命令：

------
#### [ Linux ]

   ```
   docker run --rm --init -it -d --name aws-iot-greengrass \
   -p 8883:8883 \
   -v <host-path-to-kernel-config-file>:<container-path> \
   <image-repository>:<tag>
   ```
   + *<host-path-to-kernel-config-file>*替换为主机上内核配置文件的路径以及*<container-path>*容器中装入卷的路径。

     主机上的内核配置文件通常位于 `/proc/config.gz` 或 `/boot/config-<kernel-release-date>` 中。你可以跑`uname -r`去找*<kernel-release-date>*值。

     **示例：**从 `/boot/config-<kernel-release-date>` 装载 Config 文件

     ```
     -v /boot/config-4.15.0-74-generic:/boot/config-4.15.0-74-generic \
     ```

     **示例：**从 `proc/config.gz` 装载 Config 文件

     ```
     -v /proc/config.gz:/proc/config.gz \
     ```
   + 将*<image-repository>*：*<tag>*在命令中替换为存储库的名称和目标图像的标签。

     **示例：**指向最新版本的 AWS IoT Greengrass Core 软件

     ```
     216483018798.dkr.ecr.us-west-2.amazonaws.com/aws-iot-greengrass:latest
     ```

     要获取 AWS IoT Greengrass Docker 镜像列表，请运行以下命令。

     ```
     aws ecr list-images --region us-west-2 --registry-id 216483018798 --repository-name aws-iot-greengrass
     ```

------
#### [ macOS ]

   ```
   docker run --rm --init -it -d --name aws-iot-greengrass \
   -p 8883:8883 \
   <image-repository>:<tag>
   ```
   + 将*<image-repository>*：*<tag>*在命令中替换为存储库的名称和目标图像的标签。

     **示例：**指向最新版本的 AWS IoT Greengrass Core 软件

     ```
     216483018798.dkr.ecr.us-west-2.amazonaws.com/aws-iot-greengrass:latest
     ```

     要获取 AWS IoT Greengrass Docker 镜像列表，请运行以下命令：

     ```
     aws ecr list-images --region us-west-2 --registry-id 216483018798 --repository-name aws-iot-greengrass
     ```

------
#### [ Windows ]

   ```
   docker run --rm --init -it -d --name aws-iot-greengrass \
   -p 8883:8883 \
   <image-repository>:<tag>
   ```
   + 将*<image-repository>*：*<tag>*在命令中替换为存储库的名称和目标图像的标签。

     **示例：**指向最新版本的 AWS IoT Greengrass Core 软件

     ```
     216483018798.dkr.ecr.us-west-2.amazonaws.com/aws-iot-greengrass:latest
     ```

     要获取 AWS IoT Greengrass Docker 镜像列表，请运行以下命令：

     ```
     aws ecr list-images --region us-west-2 --registry-id 216483018798 --repository-name aws-iot-greengrass
     ```

------
**重要**  
使用 IDT 进行测试时，请勿包含用于运行图像以供一般 AWS IoT Greengrass 用途的`--entrypoint /greengrass-entrypoint.sh \`参数。

1. <a name="docker-config-next-steps"></a>下一步：[配置您的 AWS 凭据和`device.json`文件](set-config.md)。

## 对适用于 IDT 的 Docker 容器设置进行故障排除 AWS IoT Greengrass
<a name="docker-config-setup-troubleshooting"></a>

使用以下信息来帮助解决运行适用于 IDT 的 Docker 容器进行测试时遇到的问题。 AWS IoT Greengrass 

### 警告：加载配置时出错 <user>//.docker file:/home/user/.docker/config.json - stat /home /config.json：权限被拒绝
<a name="docker-config-permissions-linux"></a>

如果在 Linux 上运行 `docker` 命令时出现此错误，请运行以下命令。将以下命令替换*<user>*为运行 IDT 的用户。

```
sudo chown <user>:<user> /home/<user>/.docker -R
sudo chmod g+rwx /home/<user>/.docker -R
```

# 可选：配置设备进行 ML 资格认证
<a name="idt-ml-qualification"></a>

IDT fo AWS IoT Greengrass r 提供机器学习 (ML) 资格测试，以验证您的设备是否可以使用云训练模型在本地执行 ML 推理。

要运行 ML 资格认证测试，必须先按照[配置设备以运行 IDT 测试](device-config-setup.md)中的说明配置设备。然后，按照本主题中的步骤安装要运行的 ML 框架的依赖项。

需要有 IDT v3.1.0 或更高版本才能运行 ML 资格认证测试。

## 安装 ML 框架依赖项
<a name="ml-qualification-framework-dependencies"></a>

所有 ML 框架依赖项都必须安装在 `/usr/local/lib/python3.x/site-packages` 目录下。为确保将这些依赖项安装在正确的目录下，建议您在安装时使用 `sudo` root 权限。资格认证测试不支持虚拟环境。

**注意**  
如果您正在测试使用[容器化](lambda-group-config.md#lambda-containerization-considerations)运行的 Lambda 函数（在 **Greengrass 容器**模式下），则不支持为 `/usr/local/lib/python3.x` 下的 Python 库创建符号链接。为避免错误，必须在正确的目录下安装依赖项。

按照以下步骤安装目标框架的依赖项：
+ [安装 MXNet 依赖关系](#ml-qualification-mxnet-dependencies)
+ [安装 TensorFlow 依赖关系](#ml-qualification-tensorflow-dependencies)
+ [安装 DLR 依赖项](#ml-qualification-dlr-dependencies)

 

## 安装 Apache 依赖项 MXNet
<a name="ml-qualification-mxnet-dependencies"></a>

<a name="test-framework-dependencies"></a>此框架的 IDT 资格认证测试具有以下依赖项：
+ <a name="ml-qualification-python-req"></a>Python 3.6 或 Python 3.7。
**注意**  <a name="python-symlink-command"></a>
如果您使用的是 Python 3.6，则必须创建从 Python 3.7 二进制文件到 Python 3.6 二进制文件的符号链接。这会将设备配置为满足 AWS IoT Greengrass的 Python 要求。例如：  

  ```
  sudo ln -s path-to-python-3.6/python3.6 path-to-python-3.7/python3.7
  ```
+ Apache MXNet v1.2.1 或更高版本。
+ NumPy。 该版本必须与您的 MXNet 版本兼容。

### 正在安装 MXNet
<a name="ml-qualification-mxnet-install"></a>

按照 MXNet 文档中的说明进行[安装 MXNet](https://mxnet.apache.org/get_started/?platform=linux&language=python&processor=cpu&environ=pip&)。

**注意**  
<a name="run-python3-commands"></a>如果设备上同时安装了 Python 2.x 和 Python 3.x，请在运行来安装依赖项的命令中使用 Python 3.x。

### 正在验证安装 MXNet
<a name="ml-qualification-mxnet-validate"></a>

选择以下选项之一来验证 MXNet 安装。

#### 方式 1：通过 SSH 接入设备并运行脚本
<a name="ml-qualification-validate-mxnet-option-1"></a>

1. <a name="ssh-validate-framework-install-ssh"></a>通过 SSH 接入设备。

1. <a name="ssh-validate-framework-install-run-scripts"></a>运行以下脚本，验证是否正确安装了依赖项。

   ```
   sudo python3.7 -c "import mxnet; print(mxnet.__version__)"
   ```

   ```
   sudo python3.7 -c "import numpy; print(numpy.__version__)"
   ```

   <a name="ssh-passed-mldependencies"></a>结果将输出版本号，而脚本应该顺利退出。

#### 方式 2：运行 IDT 依赖项测试
<a name="ml-qualification-validate-mxnet-option-2"></a>

1. <a name="idt-validate-framework-install-check-config"></a>确保已配置 `device.json` 用于执行 ML 资格认证。有关更多信息，请参阅 [为 ML 资格认证配置 device.json](set-config.md#device-json-ml-qualification)。

1. <a name="idt-validate-framework-install-run-test"></a>运行框架的依赖项测试。

   ```
   devicetester_[linux | mac | win_x86-64] run-suite --group-id mldependencies --test-id mxnet_dependency_check
   ```

   <a name="idt-passed-mldependencies"></a>测试摘要会为 `mldependencies` 显示 `PASSED` 结果。

 

## 安装 TensorFlow 依赖关系
<a name="ml-qualification-tensorflow-dependencies"></a>

<a name="test-framework-dependencies"></a>此框架的 IDT 资格认证测试具有以下依赖项：
+ <a name="ml-qualification-python-req"></a>Python 3.6 或 Python 3.7。
**注意**  <a name="python-symlink-command"></a>
如果您使用的是 Python 3.6，则必须创建从 Python 3.7 二进制文件到 Python 3.6 二进制文件的符号链接。这会将设备配置为满足 AWS IoT Greengrass的 Python 要求。例如：  

  ```
  sudo ln -s path-to-python-3.6/python3.6 path-to-python-3.7/python3.7
  ```
+ TensorFlow 1.x。

### 正在安装 TensorFlow
<a name="ml-qualification-tensorflow-install"></a>

按照 TensorFlow 文档中的说明使用 [pip 或[从源](https://www.tensorflow.org/install/source)代码](https://www.tensorflow.org/install/pip)安装 TensorFlow 1.x。

**注意**  
<a name="run-python3-commands"></a>如果设备上同时安装了 Python 2.x 和 Python 3.x，请在运行来安装依赖项的命令中使用 Python 3.x。

### 正在验证安装 TensorFlow
<a name="ml-qualification-tensorflow-validate"></a>

选择以下选项之一来验证 TensorFlow 安装。

#### 方式 1：通过 SSH 接入设备并运行脚本
<a name="ml-qualification-validate-tensorflow-option-1"></a>

1. <a name="ssh-validate-framework-install-ssh"></a>通过 SSH 接入设备。

1. 运行以下脚本，验证是否正确安装了依赖项。

   ```
   sudo python3.7 -c "import tensorflow; print(tensorflow.__version__)"
   ```

   <a name="ssh-passed-mldependencies"></a>结果将输出版本号，而脚本应该顺利退出。

#### 方式 2：运行 IDT 依赖项测试
<a name="ml-qualification-validate-tensorflow-option-2"></a>

1. <a name="idt-validate-framework-install-check-config"></a>确保已配置 `device.json` 用于执行 ML 资格认证。有关更多信息，请参阅 [为 ML 资格认证配置 device.json](set-config.md#device-json-ml-qualification)。

1. <a name="idt-validate-framework-install-run-test"></a>运行框架的依赖项测试。

   ```
   devicetester_[linux | mac | win_x86-64] run-suite --group-id mldependencies --test-id tensorflow_dependency_check
   ```

   <a name="idt-passed-mldependencies"></a>测试摘要会为 `mldependencies` 显示 `PASSED` 结果。

 

## 安装 Amazon SageMaker AI Neo 深度学习运行时 (DLR) 依赖项
<a name="ml-qualification-dlr-dependencies"></a>

<a name="test-framework-dependencies"></a>此框架的 IDT 资格认证测试具有以下依赖项：
+ <a name="ml-qualification-python-req"></a>Python 3.6 或 Python 3.7。
**注意**  <a name="python-symlink-command"></a>
如果您使用的是 Python 3.6，则必须创建从 Python 3.7 二进制文件到 Python 3.6 二进制文件的符号链接。这会将设备配置为满足 AWS IoT Greengrass的 Python 要求。例如：  

  ```
  sudo ln -s path-to-python-3.6/python3.6 path-to-python-3.7/python3.7
  ```
+ SageMaker AI Neo DLR。
+ numpy。

安装 DLR 测试依赖项后，必须[编译模型](#ml-qualification-dlr-compile-model)。

### 安装 DLR
<a name="ml-qualification-dlr-install"></a>

按照 DLR 文档中的说明[安装 Neo DLR](https://neo-ai-dlr.readthedocs.io/en/latest/install.html#building-on-linux)。

**注意**  
<a name="run-python3-commands"></a>如果设备上同时安装了 Python 2.x 和 Python 3.x，请在运行来安装依赖项的命令中使用 Python 3.x。

### 验证 DLR 安装
<a name="ml-qualification-dlr-validate"></a>

选择以下一种选项来验证 DLR 安装。

#### 方式 1：通过 SSH 接入设备并运行脚本
<a name="ml-qualification-validate-dlr-option-1"></a>

1. <a name="ssh-validate-framework-install-ssh"></a>通过 SSH 接入设备。

1. <a name="ssh-validate-framework-install-run-scripts"></a>运行以下脚本，验证是否正确安装了依赖项。

   ```
   sudo python3.7 -c "import dlr; print(dlr.__version__)"
   ```

   ```
   sudo python3.7 -c "import numpy; print(numpy.__version__)"
   ```

   <a name="ssh-passed-mldependencies"></a>结果将输出版本号，而脚本应该顺利退出。

#### 方式 2：运行 IDT 依赖项测试
<a name="ml-qualification-validate-dlr-option-2"></a>

1. <a name="idt-validate-framework-install-check-config"></a>确保已配置 `device.json` 用于执行 ML 资格认证。有关更多信息，请参阅 [为 ML 资格认证配置 device.json](set-config.md#device-json-ml-qualification)。

1. <a name="idt-validate-framework-install-run-test"></a>运行框架的依赖项测试。

   ```
   devicetester_[linux | mac | win_x86-64] run-suite --group-id mldependencies --test-id dlr_dependency_check
   ```

   <a name="idt-passed-mldependencies"></a>测试摘要会为 `mldependencies` 显示 `PASSED` 结果。

## 编译 DLR 模型
<a name="ml-qualification-dlr-compile-model"></a>

必须先编译 DLR 模型，然后才能将其用于 ML 资格认证测试。有关具体步骤，请选择以下一种选项：

### 选项 1：使用 Amazon SageMaker AI 编译模型
<a name="ml-qualification-compile-dlr-option-1"></a>

按照以下步骤使用 SageMaker AI 编译 IDT 提供的机器学习模型。此模型已使用 Ap MXNet ache 进行预训练。

1. 验证 A SageMaker I 是否支持您的设备类型。有关更多信息，请参阅 *Amazon AI AP SageMaker I 参考*中的[目标设备选项](https://docs.aws.amazon.com/sagemaker/latest/APIReference/API_OutputConfig.html#sagemaker-Type-OutputConfig-TargetDevice)。如果 SageMaker AI 目前不支持您的设备类型，请按照中的步骤操作[方式 2：使用 TVM 编译 DLR 模型](#ml-qualification-compile-dlr-option-2)。
**注意**  
使用 SageMaker AI 编译的模型运行 DLR 测试可能需要 4 或 5 分钟。在此过程中请勿停止 IDT。

1. <a name="compile-dlr-download-uncompiled-model"></a>下载包含未编译、预训练的 DLR MXNet 模型的 tarball 文件：
   + [dlr-noncompiled-model-1.0.tar.gz](https://docs.aws.amazon.com/greengrass/latest/developerguide/download-dlr-noncompiled-model-1.0.html)

1. <a name="compile-dlr-decompress-uncompiled-model"></a>解压缩该 tarball 文件。此命令会生成以下目录结构。  
![\[resnet18 目录中包含三个文件。\]](http://docs.aws.amazon.com/zh_cn/greengrass/v1/developerguide/images/idt/idt-ml-qualification-dlr-uncompiled.png)

1. 将 `synset.txt` 移出 `resnet18` 目录。记下新位置。稍后，您需要将此文件复制到已编译的模型目录中。

1. 压缩 `resnet18` 目录的内容。

   ```
   tar cvfz model.tar.gz resnet18v1-symbol.json resnet18v1-0000.params
   ```

1. 将压缩文件上传到您的 Amazon S3 存储桶 AWS 账户，然后按照[编译模型（控制台）](https://docs.aws.amazon.com/sagemaker/latest/dg/neo-job-compilation-console.html)中的步骤创建编译任务。

   1. 对于**输入配置**，请使用以下值：
      + 对于**数据输入配置**，请输入 `{"data": [1, 3, 224, 224]}`。
      + 对于**机器学习框架**，请选择 `MXNet`。

   1. 对于**输出配置**，请使用以下值：
      + 对于 **S3 输出位置**，请输入要存储已编译模型的 Amazon S3 存储桶或文件夹的路径。
      + 对于**目标设备**，请选择您的设备类型。

1. 从指定的输出位置下载已编译的模型，然后解压缩该文件。

1. 将 `synset.txt` 复制到已编译的模型目录中。

1. 将已编译的模型目录的名称更改为 `resnet18`。

   已编译的模型目录必须具有以下目录结构。  
![\[已编译的 resnet18 模型目录中包含四个文件。\]](http://docs.aws.amazon.com/zh_cn/greengrass/v1/developerguide/images/idt/idt-ml-qualification-dlr-compiled-sm.png)

### 方式 2：使用 TVM 编译 DLR 模型
<a name="ml-qualification-compile-dlr-option-2"></a>

按照以下步骤使用 TVM 编译 IDT 提供的 ML 模型。此模型已使用 Apache 进行预训练 MXNet，因此必须安装 MXNet 在编译模型的计算机或设备上。要安装 MXNet，请按照[ MXNet 文档](https://mxnet.apache.org/get_started/?platform=linux&language=python&processor=cpu&environ=pip&)中的说明进行操作。

**注意**  
我们建议您在目标设备上编译模型。此做法是可选的，但它可以帮助确保兼容性并减少潜在问题。

 

1. <a name="compile-dlr-download-uncompiled-model"></a>下载包含未编译、预训练的 DLR MXNet 模型的 tarball 文件：
   + [dlr-noncompiled-model-1.0.tar.gz](https://docs.aws.amazon.com/greengrass/latest/developerguide/download-dlr-noncompiled-model-1.0.html)

1. <a name="compile-dlr-decompress-uncompiled-model"></a>解压缩该 tarball 文件。此命令会生成以下目录结构。  
![\[resnet18 目录中包含三个文件。\]](http://docs.aws.amazon.com/zh_cn/greengrass/v1/developerguide/images/idt/idt-ml-qualification-dlr-uncompiled.png)

1. 按照 TVM 文档中的说明，[从源代码为平台构建和安装 TVM](https://docs.tvm.ai/install/from_source.html)。

1. 构建 TVM 后，为 resnet18 模型运行 TVM 编译。以下步骤根据 TVM 文档中的[编译深度学习模型快速入门教程](https://tvm.apache.org/docs/tutorial/relay_quick_start.html#sphx-glr-tutorials-get-started-relay-quick-start-py)的内容设计而成。

   1. 从克隆的 TVM 存储库中打开 `relay_quick_start.py` 文件。

   1. 更新[在 Relay 中定义神经网络](https://tvm.apache.org/docs/tutorial/relay_quick_start.html#define-neural-network-in-relay)的代码。可以使用以下选项之一：
      + 选项 1：使用 `mxnet.gluon.model_zoo.vision.get_model` 获取 Relay 模块和参数：

        ```
        from mxnet.gluon.model_zoo.vision import get_model
        block = get_model('resnet18_v1', pretrained=True)
        mod, params = relay.frontend.from_mxnet(block, {"data": data_shape})
        ```
      + 选项 2：将您在步骤 1 中下载的未编译模型中的以下文件复制到 `relay_quick_start.py` 文件所在的目录。这些文件中包含了 Relay 模块和参数。
        + `resnet18v1-symbol.json`
        + `resnet18v1-0000.params`

   1. 将[保存和加载已编译模块](https://tvm.apache.org/docs/tutorial/relay_quick_start.html#save-and-load-compiled-module)的代码更新为以下代码。

      ```
      from tvm.contrib import util
      path_lib = "deploy_lib.so"
      #  Export the model library based on your device architecture
      lib.export_library("deploy_lib.so", cc="aarch64-linux-gnu-g++")
      with open("deploy_graph.json", "w") as fo:
          fo.write(graph)
      with open("deploy_param.params", "wb") as fo:
          fo.write(relay.save_param_dict(params))
      ```

   1. 构建模型：

      ```
      python3 tutorials/relay_quick_start.py --build-dir ./model
      ```

      此命令会生成以下文件。
      + `deploy_graph.json`
      + `deploy_lib.so`
      + `deploy_param.params`

1. 将生成的模型文件复制到名为 `resnet18` 的目录中。这是已编译的模型目录。

1. 将已编译的模型目录复制到主机计算机。然后，将您在步骤 1 中下载的未编译模型中的 `synset.txt` 复制到已编译的模型目录中。

   已编译的模型目录必须具有以下目录结构。  
![\[已编译的 resnet18 模型目录中包含四个文件。\]](http://docs.aws.amazon.com/zh_cn/greengrass/v1/developerguide/images/idt/idt-ml-qualification-dlr-compiled-tvm.png)

接下来，[配置您的 AWS 凭据和`device.json`文件](set-config.md)。

# 配置 IDT 设置以运行 AWS IoT Greengrass 资格套件
<a name="set-config"></a>

在运行测试之前，您必须在主机上配置 AWS 凭据和设备的设置。

## 配置您的 AWS 凭证
<a name="cfg-aws-gg"></a>

您必须在 `<device-tester-extract-location> /configs/config.json` 文件中配置 IAM 用户凭证。使用中创建的 AWS IoT Greengrass 用户的 IDT 凭证。[创建和配置 AWS 账户](dev-tst-prereqs.md#config-aws-account-for-idt)您可以采用以下两种方法之一来指定凭证：
+ 凭证文件
+ 环境变量

### 使用 AWS 凭证文件配置凭证
<a name="config-cred-file"></a>

IDT 使用与 AWS CLI相同的凭证文件。有关更多信息，请参阅[配置和凭证文件](https://docs.aws.amazon.com/cli/latest/userguide/cli-config-files.html)。

凭证文件的位置因您使用的操作系统而异：
+ macOS、Linux：`~/.aws/credentials`
+ Windows：`C:\Users\UserName\.aws\credentials`

按以下格式将您的 AWS 凭证添加到`credentials`文件中：

```
[default]
aws_access_key_id = <your_access_key_id>
aws_secret_access_key = <your_secret_access_key>
```

要将 IDT 配置 AWS IoT Greengrass 为使用`credentials`文件中的 AWS 凭据，请按如下方式编辑您的`config.json`文件：

```
{
	"awsRegion": "us-west-2",
	"auth": {
		"method": "file",
		"credentials": {
			"profile": "default"
		}
	}
}
```

**注意**  
如果您不使用`default` AWS 配置文件，请务必更改文件中的配置`config.json`文件名称。有关更多信息，请参阅[命名配置文件](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-profiles.html)。

### 使用环境变量配置 AWS 凭证
<a name="config-env-vars"></a>

环境变量是由操作系统维护且由系统命令使用的变量。如果您关闭 SSH 会话，则不会保存它们。IDT fo AWS IoT Greengrass r 可以使用`AWS_ACCESS_KEY_ID`和`AWS_SECRET_ACCESS_KEY`环境变量来存储您的 AWS 证书。

要在 Linux、macOS 或 Unix 上设置这些变量，请使用 **export**：

```
export AWS_ACCESS_KEY_ID=<your_access_key_id>
export AWS_SECRET_ACCESS_KEY=<your_secret_access_key>
```

要在 Windows 上设置这些变量，请使用 **set**：

```
set AWS_ACCESS_KEY_ID=<your_access_key_id>
set AWS_SECRET_ACCESS_KEY=<your_secret_access_key>
```

要配置 IDT 以使用环境变量，请编辑 `config.json` 文件中的 `auth` 部分。示例如下：

```
{
	"awsRegion": "us-west-2",
	"auth": {
		"method": "environment"
	}
}
```

## 配置 device.json
<a name="device-config"></a>

除了 AWS 凭据外，IDT 还 AWS IoT Greengrass 需要有关运行测试的设备的信息（例如 IP 地址、登录信息、操作系统和 CPU 架构）。

您必须使用位于 ` <device_tester_extract_location>/configs/device.json` 中的 `device.json` 模板提供此信息：

------
#### [ Physical device ]

```
[
  {
    "id": "<pool-id>",
    "sku": "<sku>",
    "features": [
      {
        "name": "os",
        "value": "linux | ubuntu | openwrt"
      },
      {
        "name": "arch",
        "value": "x86_64 | armv6l | armv7l | aarch64"
      },
      {
        "name": "container",
        "value": "yes | no"
      },
      {
        "name": "docker",
        "value": "yes | no"
      },
      {
        "name": "streamManagement",
        "value": "yes | no"
      },
      {
        "name": "hsi",
        "value": "yes | no"
      },
      {
        "name": "ml",
        "value": "mxnet | tensorflow | dlr | mxnet,dlr,tensorflow | no"
      },
      *********** Remove the section below if the device is not qualifying for ML **************,
      {
        "name": "mlLambdaContainerizationMode",
        "value": "container | process | both"
      },
      {
        "name": "processor",
        "value": "cpu | gpu"
      },
      ******************************************************************************************
    ],
    *********** Remove the section below if the device is not qualifying for HSI ***************
    "hsm": {
      "p11Provider": "/path/to/pkcs11ProviderLibrary",
      "slotLabel": "<slot_label>",
      "slotUserPin": "<slot_pin>",
      "privateKeyLabel": "<key_label>",
      "openSSLEngine": "/path/to/openssl/engine"
    },
    ********************************************************************************************
    *********** Remove the section below if the device is not qualifying for ML ****************
    "machineLearning": {
      "dlrModelPath": "/path/to/compiled/dlr/model",
      "environmentVariables": [
        {
          "key": "<environment-variable-name>",
          "value": "<Path:$PATH>"
        }
      ],
      "deviceResources": [
        {
          "name": "<resource-name>",
          "path": "<resource-path>",
          "type": "device | volume"
        }
      ]
    },
    ******************************************************************************************
    "kernelConfigLocation": "",
    "greengrassLocation": "",
    "devices": [
      {
        "id": "<device-id>",
        "connectivity": {
          "protocol": "ssh",
          "ip": "<ip-address>",
          "port": 22,
          "auth": {
            "method": "pki | password",
            "credentials": {
              "user": "<user-name>",
              "privKeyPath": "/path/to/private/key",
              "password": "<password>"
            }
          }
        }
      }
    ]
  }
]
```

**注意**  
只有当 `method` 设置为 `pki` 时才指定 `privKeyPath`。  
只有当 `method` 设置为 `password` 时才指定 `password`。

------
#### [ Docker container ]

```
[
  {
    "id": "<pool-id>",
    "sku": "<sku>",
    "features": [
      {
        "name": "os",
        "value": "linux | ubuntu | openwrt"
      },
      {
        "name": "arch",
        "value": "x86_64"
      },
      {
        "name": "container",
        "value": "no"
      },
      {
        "name": "docker",
        "value": "no"
      },
      {
        "name": "streamManagement",
        "value": "yes | no"
      },
      {
        "name": "hsi",
        "value": "no"
      },
      {
        "name": "ml",
        "value": "mxnet | tensorflow | dlr | mxnet,dlr,tensorflow | no"
      },
      *********** Remove the section below if the device is not qualifying for ML **************,
      {
        "name": "mlLambdaContainerizationMode",
        "value": "process"
      },
      {
        "name": "processor",
        "value": "cpu | gpu"
      },
      ******************************************************************************************
    ],
    *********** Remove the section below if the device is not qualifying for ML ****************
    "machineLearning": {
      "dlrModelPath": "/path/to/compiled/dlr/model",
      "environmentVariables": [
        {
          "key": "<environment-variable-name>",
          "value": "<Path:$PATH>"
        }
      ],
      "deviceResources": [
        {
          "name": "<resource-name>",
          "path": "<resource-path>",
          "type": "device | volume"
        }
      ]
    },
    ******************************************************************************************
    "kernelConfigLocation": "",
    "greengrassLocation": "",
    "devices": [
      {
        "id": "<device-id>",
        "connectivity": {
          "protocol": "docker",
          "containerId": "<container-name | container-id>",
          "containerUser": "<user>"
        }
      }
    ]
  }
]
```

------

包含值的所有字段都为必填字段，如下所述：

`id`  
一个用户定义的字母数字 ID，用于唯一地标识称作*设备池*的设备集合。属于池的设备必须具有相同的硬件。运行一组测试时，池中的设备将用于对工作负载进行并行化处理。多个设备用于运行不同测试。

`sku`  
唯一标识所测试设备的字母数字值。该 SKU 用于跟踪符合条件的主板。  
如果您想在 AWS Partner 设备目录中发布您的主板，则在此处指定的 SKU 必须与您在发布过程中使用的 SKU 相匹配。

`features`  
包含设备支持的功能的数组。所有功能都是必需的。    
`os` 和 `arch`  
  
支持的操作系统 (OS) 和架构组合：  
+ `linux`, `x86_64`
+ `linux`, `armv6l`
+ `linux`, `armv7l`
+ `linux`, `aarch64`
+ `ubuntu`, `x86_64`
+ `openwrt`, `armv7l`
+ `openwrt`, `aarch64`
如果您使用 IDT 测试在 Docker 容器中 AWS IoT Greengrass 运行，则仅支持 x86\$164 Docker 架构。  
`container`  
<a name="description-container"></a>验证设备是否满足在 Greengrass 核心上以容器模式运行 Lambda 函数的所有软硬件要求。  
有效值为 `yes` 或 `no`。  
`docker`  
<a name="description-docker"></a>验证设备是否满足使用 Greengrass Docker 应用程序部署连接器以运行容器的所有必要技术依赖项  
有效值为 `yes` 或 `no`。  
`streamManagement`  
<a name="description-sm"></a>验证设备是否满足运行 AWS IoT Greengrass 直播管理器所需的所有技术依赖项。  
有效值为 `yes` 或 `no`。  
`hsi`  
<a name="description-hsi"></a>验证提供的 HSI 共享库是否可以与硬件安全模块 (HSM) 接口并正确实现所需的 PKCS \$111。 APIs HSM 和共享库必须能够签署 CSR，执行 TLS 操作，并提供正确的密钥长度和公有密钥算法。  
有效值为 `yes` 或 `no`。  
`ml`  
<a name="description-ml"></a>验证设备是否满足在本地执行 ML 推理所需的所有技术依赖项。  
有效值可以是 `mxnet`、`tensorflow`、`dlr` 和 `no` 的任意组合（例如 `mxnet`、`mxnet,tensorflow`、`mxnet,tensorflow,dlr` 或 `no`）。  
`mlLambdaContainerizationMode`  
验证设备是否满足在 Greengrass 设备的容器模式下执行 ML 推理所需的所有技术依赖关系。  
有效值为 `container`、`process` 或 `both`。  
`processor`  
验证设备是否满足指定处理器类型的所有硬件要求。  
有效值为 `cpu` 或 `gpu`。
如果您不想使用 `container`、`docker`、`streamManager`、`hsi` 或 `ml` 功能，则可以将对应的 `value` 设置为 `no`。  
Docker 仅支持 `streamManagement` 和`ml` 的功能资格认证。

`machineLearning`  
可选。ML 资格认证测试的配置信息。有关更多信息，请参阅 [为 ML 资格认证配置 device.json](#device-json-ml-qualification)。

`hsm`  
可选。用于使用 AWS IoT Greengrass 硬件安全模块 (HSM) 进行测试的配置信息。否则，应忽略 `hsm` 属性。有关更多信息，请参阅 [硬件安全性集成](hardware-security.md)。  
<a name="connectivity-protocol-ssh-only"></a>此属性仅在 `connectivity.protocol` 设置为 `ssh` 时适用。    
`hsm.p11Provider`  
PKCS\$111 实施的 libdl-loadable 库的绝对路径。  
`hsm.slotLabel`  
用于标识硬件模块的槽标签。  
`hsm.slotUserPin`  
用于向模块验证 AWS IoT Greengrass 核心的用户 PIN。  
`hsm.privateKeyLabel`  
用于标识硬件模块中的键的标签。  
`hsm.openSSLEngine`  
指向 OpenSSL 引擎的 `.so` 文件（用于在 OpenSSL 上启用 PKCS \$1 11 支持）的绝对路径。由 AWS IoT Greengrass OTA 更新代理使用。

`devices.id`  
用户定义的测试的设备的唯一标识符。

`connectivity.protocol`  
用于与此设备通信的通信协议。目前，唯一支持的值，对于物理设备为 `ssh`，对于 Docker 容器为 `docker`。

`connectivity.ip`  
测试的设备 IP 地址。  
<a name="connectivity-protocol-ssh-only"></a>此属性仅在 `connectivity.protocol` 设置为 `ssh` 时适用。

`connectivity.containerId`  
所测试的 Docker 容器的容器 ID 或名称。  
<a name="connectivity-protocol-docker-only"></a>此属性仅在 `connectivity.protocol` 设置为 `docker` 时适用。

`connectivity.auth`  
连接的身份验证信息。  
<a name="connectivity-protocol-ssh-only"></a>此属性仅在 `connectivity.protocol` 设置为 `ssh` 时适用。    
`connectivity.auth.method`  
用于通过给定的连接协议访问设备的身份验证方法。  
支持的值为：  
+ `pki`
+ `password`  
`connectivity.auth.credentials`  
用于身份验证的凭证。    
`connectivity.auth.credentials.password`  
该密码用于登录到正在测试的设备。  
此值仅在 `connectivity.auth.method` 设置为 `password` 时适用。  
`connectivity.auth.credentials.privKeyPath`  
用于登录所测试设备的私有密钥的完整路径。  
此值仅在 `connectivity.auth.method` 设置为 `pki` 时适用。  
`connectivity.auth.credentials.user`  
用于登录所测试设备的用户名。  
`connectivity.auth.credentials.privKeyPath`  
用于登录所测试设备的私有密钥的完整路径。

`connectivity.port`  
可选。用于 SSH 连接的端口号。  
默认值为 22。  
此属性仅在 `connectivity.protocol` 设置为 `ssh` 时适用。

`greengrassLocation`  
 AWS IoT Greengrass Core 软件在您的设备上的位置。  
对于物理设备，只有在使用现有安装时才使用此值 AWS IoT Greengrass。使用该属性可告知 IDT 使用设备上安装的 AWS IoT Greengrass 核心软件版本。  
通过提供的 Docker 镜像或 Dockerfile 在 Docker 容器中运行测试时 AWS IoT Greengrass，请将此值设置为。`/greengrass`

`kernelConfigLocation`  
可选。内核配置文件的路径。 AWS IoT 设备测试器使用此文件来检查设备是否启用了所需的内核功能。如果未指定，IDT 将使用以下路径搜索内核配置文件：`/proc/config.gz`和`/boot/config-<kernel-version>`。 AWS IoT Device Tester 使用它所找到的第一个路径。

## 为 ML 资格认证配置 device.json
<a name="device-json-ml-qualification"></a>

本节介绍设备配置文件中适用于 ML 资格认证的可选属性。如果计划运行 ML 资格认证测试，则必须定义适用于您的使用案例的属性。

您可以使用 `device-ml.json` 模板来定义设备的配置设置。此模板包含可选的 ML 属性。您也可以使用 `device.json` 并添加 ML 资格认证属性。这些文件位于 `<device-tester-extract-location>/configs` 中，包括 ML 资格认证属性。如果使用 `device-ml.json`，则必须将该文件重命名为 `device.json`，然后再运行 IDT 测试。

有关不适用于 ML 资格认证的设备配置属性的信息，请参阅[配置 device.json](#device-config)。

 

`features` 数组中的 `ml`  
您的主板支持的 ML 框架。<a name="idt-version-ml-qualification"></a>此属性需要 IDT v3.1.0 或更高版本。  
+ 如果您的主板仅支持一个框架，请指定该框架。例如：

  ```
  {
      "name": "ml",
      "value": "mxnet"
  }
  ```
+ 如果您的主板支持多个框架，请以逗号分隔列表的形式指定这些框架。例如：

  ```
  {
      "name": "ml",
      "value": "mxnet,tensorflow"
  }
  ```

`features` 数组中的 `mlLambdaContainerizationMode`  
测试将采用的[容器化模式](lambda-group-config.md#lambda-containerization-considerations)。<a name="idt-version-ml-qualification"></a>此属性需要 IDT v3.1.0 或更高版本。  
+ 选择 `process`，将使用非容器化的 Lambda 函数运行 ML 推理代码。此选项需要 AWS IoT Greengrass v1.10.x 或更高版本。
+ 选择 `container`，将使用容器化的 Lambda 函数运行 ML 推理代码。
+ 选择 `both`，可在两种模式下运行 ML 推理代码。此选项需要 AWS IoT Greengrass v1.10.x 或更高版本。

`features` 数组中的 `processor`  
指示您的主板支持的硬件加速器。<a name="idt-version-ml-qualification"></a>此属性需要 IDT v3.1.0 或更高版本。  
+ 如果主板使用 CPU 作为处理器，则选择 `cpu`。
+ 如果主板使用 GPU 作为处理器，则选择 `gpu`。

`machineLearning`  
可选。ML 资格认证测试的配置信息。<a name="idt-version-ml-qualification"></a>此属性需要 IDT v3.1.0 或更高版本。    
`dlrModelPath`  
使用 `dlr` 框架时需要。DLR 已编译模型目录的绝对路径，必须命名为 `resnet18`。有关更多信息，请参阅 [编译 DLR 模型](idt-ml-qualification.md#ml-qualification-dlr-compile-model)。  
以下是 macOS 上的路径示例：`/Users/<user>/Downloads/resnet18`。  
`environmentVariables`  
可将设置动态传递给 ML 推理测试的键值对数组。对于 CPU 设备为可选。您可以使用此部分添加设备类型所需的特定于框架的环境变量。有关这些要求的信息，请参阅框架或设备的官方网站。例如，要在某些设备上运行 MXNet 推理测试，可能需要以下环境变量。  

```
"environmentVariables": [
    ...
    {
        "key": "PYTHONPATH",      
        "value": "$MXNET_HOME/python:$PYTHONPATH"    
    },
    {
        "key": "MXNET_HOME",
        "value": "$HOME/mxnet/"
    },
    ...
]
```
该`value`字段可能因您的 MXNet 安装而异。
如果您要测试在 GPU 设备上使用[容器化](lambda-group-config.md#lambda-containerization-considerations)运行的 Lambda 函数，请为 GPU 库添加环境变量。这将使得 GPU 执行计算成为可能。要使用不同的 GPU 库，请参阅库或设备的官方文档。  
如果将 `mlLambdaContainerizationMode` 功能设置为 `container` 或 `both`，请配置以下键。

```
"environmentVariables": [
    {
        "key": "PATH",      
        "value": "<path/to/software/bin>:$PATH"    
    },
    {
        "key": "LD_LIBRARY_PATH",      
        "value": "<path/to/ld/lib>"    
    },
    ...
]
```  
`deviceResources`  
对于 GPU 设备为必需。包含可通过 Lambda 函数访问的[本地资源](access-local-resources.md#lra-resource-types)。可使用此部分来添加本地设备和卷资源。  
+ 对于设备资源，请指定 `"type": "device"`。对于 GPU 设备，设备资源应为 `/dev` 下的与 GPU 相关的设备文件。
**注意**  
但 `/dev/shm` 目录除外。只能将其配置为卷资源。
+ 对于卷资源，请指定 `"type": "volume"`。

# 运行 AWS IoT Greengrass 资格套件
<a name="run-tests"></a>

[设置所需的配置](set-config.md)后，就可以开始测试了。完整测试套件的运行时取决于您的硬件。作为参考，在 Raspberry Pi 3B 上完成完整的测试套件大约需要 30 分钟。

以下 `run-suite` 命令示例介绍如何针对某个设备池运行资格测试。设备池是一组相同的设备。

------
#### [ IDT v3.0.0 and later ]

在指定的测试套件中运行所有测试组。  

```
devicetester_[linux | mac | win_x86-64] run-suite --suite-id GGQ_1.0.0 --pool-id <pool-id>
```
使用 `list-suites` 命令列出 `tests` 文件夹中的测试套件。

在测试套件中运行特定的测试组。  

```
devicetester_[linux | mac | win_x86-64] run-suite --suite-id GGQ_1.0.0 --group-id <group-id> --pool-id <pool-id>
```
使用 `list-groups` 命令列出测试套件中的测试组。

在测试组中运行特定测试用例。  

```
devicetester_[linux | mac | win_x86-64] run-suite --group-id <group-id> --test-id <test-id>
```

在测试组中运行多个测试用例。  

```
devicetester_[linux | mac | win_x86-64] run-suite --group-id <group-id> --test-id <test-id1>,<test-id2>
```

列出测试组中的测试用例。  

```
devicetester_[linux | mac | win_x86-64] list-test-cases --group-id <group-id>
```

`run-suite` 命令的选项是可选的。例如，如果您的 `device.json` 文件中只定义了一个设备池，则可以忽略 `pool-id`。或者，如果您要在 `tests` 文件夹中运行最新的测试套件版本，则可以忽略 `suite-id`。

**注意**  
如果在线提供了更新的测试套件版本，IDT 会提示您。有关更多信息，请参阅 [设置默认更新行为](#idt-update-behavior)。

有关 `run-suite` 和其他 IDT 命令的更多信息，请参阅 [命令的同意 AWS IoT Greengrass](#bk-cli)。

------
#### [ IDT v2.3.0 and earlier ]

在指定套件中运行所有测试组。  

```
devicetester_[linux | mac | win_x86-64] run-suite --suite-id GGQ_1 --pool-id <pool-id>
```

运行特定测试组。  

```
devicetester_[linux | mac | win_x86-64] run-suite --suite-id GGQ_1 --group-id <group-id> --pool-id <pool-id>
```
如果您在单个设备池上运行单个测试套件，则 `suite-id` 和 `pool-id` 是可选的。这意味着您的 `device.json` 文件中只定义了一个设备池。

------

## 检查 Greengrass 的依赖关系
<a name="idt-dependency-checker"></a>

我们建议您运行依赖项检查程序测试组，以确保在运行相关测试组之前已安装所有 Greengrass 依赖项。例如：
+ 在运行核心资格测试组之前运行 `ggcdependencies`。
+ 在运行特定于容器的测试组之前运行 `containerdependencies`。
+ 在运行特定于 Docker 的测试组之前运行 `dockerdependencies`。
+ 在运行特定于流管理器的测试组之前运行 `ggcstreammanagementdependencies`。

## 设置默认更新行为
<a name="idt-update-behavior"></a>

当您开始测试运行时，IDT 会在线检查是否有更新的测试套件版本。如果有，IDT 会提示您更新到最新的可用版本。您可以设置 `upgrade-test-suite`（或 `u`）标记来控制默认更新行为。有效值为：
+ `y`. IDT 会下载并使用最新的可用版本。
+ `n` (默认值)。IDT 会使用 `suite-id` 选项中指定的版本。如果未指定 `suite-id`，IDT 将使用 `tests` 文件夹中的最新版本。

如果您未使用 `upgrade-test-suite` 标记，IDT 会在有更新可用时提示您，并会等待 30 秒让您输入（`y` 或 `n`）。如果您未输入信息，则默认为 `n` 并继续运行测试。

以下示例显示了此功能的常见用例：

**自动使用可用于测试组的最新测试。**  

```
devicetester_linux run-suite -u y --group-id mqtt --pool-id DevicePool1
```

**在特定测试套件版本中运行测试。**  

```
devicetester_linux run-suite -u n --suite-id GGQ_1.0.0 --group-id mqtt --pool-id DevicePool1
```

**运行时提示更新。**  

```
devicetester_linux run-suite --pool-id DevicePool1
```

## 命令的同意 AWS IoT Greengrass
<a name="bk-cli"></a>

IDT 命令位于 `<device-tester-extract-location>/bin` 目录中。它们可以用于以下操作：

------
#### [ IDT v3.0.0 and later ]

`help`  <a name="idt-command-help"></a>
列出有关指定命令的信息。

`list-groups`  <a name="idt-command-list-groups"></a>
列出给定测试套件中的组。

`list-suites`  <a name="idt-command-list-suites"></a>
列出可用的测试套件。

`list-supported-products`  
列出当前 IDT AWS IoT Greengrass 版本支持的产品（在本例中为版本）和测试套件版本。

`list-test-cases`  
列出给定测试组中的测试用例。支持以下选项：  
+ `group-id`. 要搜索的测试组。此选项是必需的，必须指定单个组。

`run-suite`  
对某个设备池运行一组测试。以下是一些受支持的选项：  
+ `suite-id`. 要运行的测试套件版本。如果未指定，IDT 将使用 `tests` 文件夹中的最新版本。
+ `group-id`. 要以逗号分隔的列表形式运行的测试组。如果未指定，IDT 将运行测试套件中的所有测试组。
+ `test-id`. 要以逗号分隔的列表形式运行的测试用例。指定后，`group-id` 必须指定单个组。
+ `pool-id`. 要测试的设备池。如果您在 `device.json` 文件中定义了多个设备池，则必须指定一个池。
+ `upgrade-test-suite`. 控制如何处理测试套件版本更新。从 IDT v3.0.0 开始，IDT 在线检查更新的测试套件版本。有关更多信息，请参阅 [测试套件版本](idt-gg-qualification.md#idt-test-suite-versions)。
+ `stop-on-first-failure`. 将 IDT 配置为在第一次失败时停止执行。应将此选项与 `group-id` 结合使用来调试指定的测试组。在运行完整测试套件以生成资格认证报告时，请勿使用此选项。
+ `update-idt`. 设置对更新 IDT 的提示的响应。如果 IDT 检测到有更新的版本，输入 `Y` 将会停止执行测试。输入 `N` 将会继续执行测试。
+ `update-managed-policy`。如果 IDT 检测到用户的托管策略未更新，输入 `Y` 将会停止执行测试。输入 `N` 将会继续执行测试。
有关 `run-suite` 选项的更多信息，请使用 `help` 选项：  

```
devicetester_[linux | mac | win_x86-64] run-suite -h
```

------
#### [ IDT v2.3.0 and earlier ]

`help`  <a name="idt-command-help"></a>
列出有关指定命令的信息。

`list-groups`  <a name="idt-command-list-groups"></a>
列出给定测试套件中的组。

`list-suites`  <a name="idt-command-list-suites"></a>
列出可用的测试套件。

`run-suite`  
对某个设备池运行一组测试。  
有关 `run-suite` 选项的更多信息，请使用 `help` 选项：  

```
devicetester_[linux | mac | win_x86-64] run-suite -h
```

------

# 了解结果和日志
<a name="results-logs"></a>

本节介绍如何查看和解释 IDT 结果报告和日志。

## 查看结果
<a name="view-results"></a>

在运行时，IDT 会将错误写入控制台、日志文件和测试报告中。IDT 在完成资格测试套件后，会生成两个测试报告。可在 `<device-tester-extract-location>/results/<execution-id>/` 中找到这些报告。两个报告都捕获资格测试套件执行的结果。

`awsiotdevicetester_report.xml`这是您提交给的资格测试报告， AWS 用于在设备目录中列出您的 AWS Partner 设备。该报告包含以下元素：
+ IDT 版本。
+ 测试过的 AWS IoT Greengrass 版本。
+ `device.json` 文件中指定的 SKU 和设备池名称。
+ `device.json` 文件中指定的设备池的功能。
+ 测试结果的摘要汇总。
+ 按照基于设备功能（例如，本地资源访问、影子、MQTT 等）测试的库细分的测试结果。

该`GGQ_Result.xml`报告采用 [JUnit XML 格式](https://llg.cubic.org/docs/junit/)。您可以将它集成到持续集成和开发平台，例如 [Jenkins](https://jenkins.io/)、[Bamboo](https://www.atlassian.com/software/bamboo) 等。该报告包含以下元素：
+ 测试结果的摘要汇总。
+ 按测试的 AWS IoT Greengrass 功能细分测试结果。

## 解读 IDT 报告
<a name="interpreting-results-gg"></a>

`awsiotdevicetester_report.xml` 或 `awsiotdevicetester_report.xml` 中的报告部分列出了运行的测试以及结果。

第一个 XML 标签 `<testsuites>` 包含测试执行情况的摘要。例如：

```
<testsuites name="GGQ results" time="2299" tests="28" failures="0" errors="0" disabled="0">
````<testsuites>` 标签中使用的属性

`name`  
测试套件的名称。

`time`  
运行资格套件所用的时间（以秒为单位）。

`tests`  
执行的测试数。

`failures`  
已运行但未通过的测试数。

`errors`  
IDT 无法执行的测试数。

`disabled`  
此属性未使用，可以忽略。

`awsiotdevicetester_report.xml` 文件包含一个 `<awsproduct>` 标签，其中包含有关正测试的产品以及在运行测试套件后验证的产品功能的信息。`<awsproduct>` 标签中使用的属性

`name`  
所测试的产品的名称。

`version`  
所测试的产品的版本。

`features`  
验证的功能。标记为 `required` 的功能需要提交您的主板信息以供资格审核。以下代码段演示了此信息在 `awsiotdevicetester_report.xml` 文件中的显示方式。  

```
<feature name="aws-iot-greengrass-no-container" value="supported" type="required"></feature>
```
标记为 `optional` 的功能不是资格认证所必需的。以下代码段显示了可选功能。  

```
<feature name="aws-iot-greengrass-container" value="supported" type="optional"></feature> 
<feature name="aws-iot-greengrass-hsi" value="not-supported" type="optional"></feature>
```

如果所需功能没有测试失败或错误，则您的设备符合运行的技术要求 AWS IoT Greengrass 并且可以与 AWS IoT 服务互操作。如果您想在设备目录中列出您的 AWS Partner 设备，则可以使用此报告作为资格证据。

如果出现测试失败或错误，则可以通过检查 `<testsuites>` XML 标签来确定失败的测试。`<testsuites>` 标签内的 `<testsuite>` XML 标签显示了测试组的测试结果摘要。例如：

```
<testsuite name="combination" package="" tests="1" failures="0" time="161" disabled="0" errors="0" skipped="0">
```

其格式与 `<testsuites>` 标签类似，但包含一个未使用并可忽略的 `skipped` 属性。在每个 `<testsuite>` XML 标签内部，对于一个测试组，所执行的每个测试都有 `<testcase>` 标签。例如：

```
<testcase classname="Security Combination (IPD + DCM) Test Context" name="Security Combination IP Change Tests sec4_test_1: Should rotate server cert when IPD disabled and following changes are made:Add CIS conn info and Add another CIS conn info" attempts="1"></testcase>>
````<testcase>` 标签中使用的属性

`name`  
测试的名称。

`attempts`  
IDT 执行测试用例的次数。

当测试失败或出现错误时，将会在 `<testcase>` 标签中添加包含用于故障排除的信息的 `<failure>` 或 `<error>` 标签。例如：

```
<testcase classname="mcu.Full_MQTT" name="AFQP_MQTT_Connect_HappyCase" attempts="1">
	<failure type="Failure">Reason for the test failure</failure>
	<error>Reason for the test execution error</error>
</testcase>
```

## 查看日志
<a name="view-logs-gg"></a>

IDT 从测试执行生成的日志位于 `<devicetester-extract-location>/results/<execution-id>/logs` 中。它会生成两组日志：

`test_manager.log`  
从 Dev AWS IoT ice Tester 的 Test Manager 组件生成的日志（例如，与配置、测试排序和报告生成相关的日志）。

`<test_case_id>.log (for example, ota.log)`  
测试组的日志，包括来自所测试设备的日志。当测试失败时，将创建一个 tar.gz 文件，其中包含关于该测试的所测试设备日志（例如，`ota_prod_test_1_ggc_logs.tar.gz`）。

有关更多信息，请参阅 [用于故障排除的 IDT AWS IoT Greengrass](idt-troubleshooting.md)。

# 使用 IDT 开发和运行自己的测试套件
<a name="idt-custom-tests"></a>

<a name="idt-byotc"></a>从 IDT v4.0.0 开始，IDT for 将标准化配置设置和结果格式与测试套件环境 AWS IoT Greengrass 相结合，使您能够为设备和设备软件开发自定义测试套件。您可以添加自定义测试来用于自己的内部验证，也可以将其提供给客户进行设备验证。

使用 IDT 开发和运行自定义测试套件，如下所示：

**开发自定义测试套件**  
+ 使用自定义测试逻辑为要测试的 Greengrass 设备创建测试套件。
+ 向 IDT 提供您的自定义测试套件以供测试运行者使用。包括有关测试套件的特定设置配置的信息。

**运行自定义测试套件**  
+ 设置要测试的设备。
+ 根据要使用的测试套件的要求实现设置配置。
+ 使用 IDT 运行您的自定义测试套件。
+ 查看 IDT 运行的测试的测试结果和执行日志。

## 下载最新版本的 Dev AWS IoT ice Tester AWS IoT Greengrass
<a name="install-dev-tst-gg"></a>

下载 IDT 的[最新版本](dev-test-versions.md)并将软件提取到文件系统中您具有读取和写入权限的位置。

**注意**  
<a name="unzip-package-to-local-drive"></a>IDT 不支持由多个用户从共享位置（如 NFS 目录或 Windows 网络共享文件夹）运行。建议您将 IDT 包解压缩到本地驱动器，并在本地工作站上运行 IDT 二进制文件。  
Windows 的路径长度限制为 260 个字符。如果您使用的是 Windows，请将 IDT 提取到根目录（如 `C:\ ` 或 `D:\`）以使路径长度不超过 260 个字符的限制。

## 测试套件创建工作流程
<a name="custom-test-workflow"></a>

测试套件由三种类型的文件组成：
+ JSON 配置文件，为 IDT 提供了有关如何执行测试套件的信息。
+ 测试 IDT 用来运行测试用例的可执行文件。
+ 运行测试所需的其他文件。

完成以下基本步骤来创建自定义 IDT 测试：

1. 为您的测试套件[创建 JSON 配置文件](idt-json-config.md)。

1. [创建包含测试套件测试逻辑的测试用例可执行文件](test-executables.md)。

1. 验证并记录[测试运行器运行测试套件所需的配置信息](set-config-custom.md)。

1. 验证 IDT 能否按预期运行您的测试套件并生成[测试结果](run-tests-custom.md)。

要快速构建示例自定义套件并运行它，请按照 [教程：构建和运行示例 IDT 测试套件](build-sample-suite.md) 中的说明进行操作。

要开始使用 Python 创建自定义测试套件，请参阅[教程：开发一个简单的 IDT 测试套件](create-custom-tests.md)。

# 教程：构建和运行示例 IDT 测试套件
<a name="build-sample-suite"></a>

 AWS IoT 设备测试器下载内容包括示例测试套件的源代码。您可以完成本教程来构建和运行示例测试套件，以了解如何使用 AWS IoT Device Tester AWS IoT Greengrass 来运行自定义测试套件。

 在本教程中，您将完成以下步骤：

1. [构建示例测试套件](#build-sample)

1. [使用 IDT 运行示例测试套件](#run-sample)

## 先决条件
<a name="prereqs-tutorial-sample"></a>

要完成本教程，您需要：<a name="prereqs-list"></a>
+ 

**主机要求**
  + 最新版本的 AWS IoT 设备测试器
  + [Python](https://www.python.org/downloads/) 3.7 或更高版本

    要检查您计算机安装的 Python 版本，请运行以下命令：

    ```
    python3 --version
    ```

    在 Windows 上，如果运行此命令时返回错误，则可改用 `python --version`。如果返回的版本号为 3.7 或更高版本，则可通过在 Powershell 终端中运行以下命令将 `python3` 设置为 `python` 命令的别名。

    ```
    Set-Alias -Name "python3" -Value "python"
    ```

    如果没有返回版本信息，或者版本号小于 3.7，则按照[下载 Python](https://wiki.python.org/moin/BeginnersGuide/Download) 中的说明安装 Python 3.7\$1。有关更多信息，请参阅 [Python 文档](https://docs.python.org)。
  + [urllib3](https://urllib3.readthedocs.io/en/latest/)

    要验证 `urllib3` 是否已正确安装，请运行以下命令：

    ```
    python3 -c 'import urllib3'
    ```

    如果未安装 `urllib3`，请运行以下命令进行安装：

    ```
    python3 -m pip install urllib3
    ```
+ 

**设备要求**
  + 一种运行 Linux 操作系统的设备，其网络连接到与您主机相同的网络。

    我们建议您使用搭载 Raspberry Pi 操作系统的 [Raspberry Pi](https://www.raspberrypi.org/)。请确保您设置 Raspberry Pi 上的 [SSH](https://www.raspberrypi.org/documentation/remote-access/ssh/) 才能远程连接到它。

## 配置 IDT 的设备信息
<a name="configure-idt-sample"></a>

配置您的设备信息，以便 IDT 运行测试。您必须使用以下信息，更新位于 `<device-tester-extract-location>/configs` 文件夹中的 `device.json` 模板。

```
[
  {
    "id": "pool",
    "sku": "N/A",
    "devices": [
      {
        "id": "<device-id>",
        "connectivity": {
          "protocol": "ssh",
          "ip": "<ip-address>",
          "port": "<port>",
          "auth": {
            "method": "pki | password",
            "credentials": {
              "user": "<user-name>",
              "privKeyPath": "/path/to/private/key",
              "password": "<password>"
            }
          }
        }
      }
    ]
  }
]
```

在 `devices` 对象中，提供以下信息：

`id`  
专属于您设备的用户定义唯一标识符。

`connectivity.ip`  
您设备的 IP 地址。

`connectivity.port`  
可选。用于通过 SSH 连接到您的设备的端口号。

`connectivity.auth`  
连接的身份验证信息。  
此属性仅在 `connectivity.protocol` 设置为 `ssh` 时适用。    
`connectivity.auth.method`  
用于通过给定的连接协议访问设备的身份验证方法。  
支持的值为：  
+ `pki`
+ `password`  
`connectivity.auth.credentials`  
用于身份验证的凭证。    
`connectivity.auth.credentials.user`  
用于登录您的设备的用户名。  
`connectivity.auth.credentials.privKeyPath`  
用于登录您设备的私有密钥的完整路径。  
此值仅在 `connectivity.auth.method` 设置为 `pki` 时适用。  
`devices.connectivity.auth.credentials.password`  
该密码用于登录到您的设备。  
此值仅在 `connectivity.auth.method` 设置为 `password` 时适用。

**注意**  
只有当 `method` 设置为 `pki` 时才指定 `privKeyPath`。  
只有当 `method` 设置为 `password` 时才指定 `password`。

## 构建示例测试套件
<a name="build-sample"></a>

`<device-tester-extract-location>/samples/python` 文件夹包含示例配置文件、源代码和 IDT 客户端软件开发工具包，您可以使用提供的构建脚本将其组合成一个测试套件。以下目录树显示了这些示例文件的位置：

```
<device-tester-extract-location>
├── ...
├── tests
├── samples
│   ├── ...
│   └── python
│       ├── configuration
│       ├── src
│       └── build-scripts
│           ├── build.sh
│           └── build.ps1
└── sdks
    ├── ...
    └── python
        └── idt_client
```

要构建测试套件，请在主机上运行以下命令：

------
#### [ Windows ]

```
cd <device-tester-extract-location>/samples/python/build-scripts
./build.ps1
```

------
#### [ Linux, macOS, or UNIX ]

```
cd <device-tester-extract-location>/samples/python/build-scripts
./build.sh
```

------

这将在该 `<device-tester-extract-location>/tests` 文件夹下的 `IDTSampleSuitePython_1.0.0` 文件夹中创建示例测试套件。检查 `IDTSampleSuitePython_1.0.0`文件夹中的文件，以了解示例测试套件的结构，并查看测试用例可执行文件和测试配置 JSON 文件的各种示例。

下一步：使用 IDT [运行您创建的示例测试套件](#run-sample)。

## 使用 IDT 运行示例测试套件
<a name="run-sample"></a>

要运行示例测试套件，请在主机上运行以下命令：

```
cd <device-tester-extract-location>/bin
./devicetester_[linux | mac | win_x86-64] run-suite --suite-id IDTSampleSuitePython
```

IDT 会运行示例测试套件，并将结果流式传输到控制台。测试运行完毕后，您会看到以下信息：

```
========== Test Summary ==========
Execution Time:         5s
Tests Completed:        4
Tests Passed:           4
Tests Failed:           0
Tests Skipped:          0
----------------------------------
Test Groups:
    sample_group:       PASSED
----------------------------------
Path to IoT Device Tester Report: /path/to/devicetester/results/87e673c6-1226-11eb-9269-8c8590419f30/awsiotdevicetester_report.xml
Path to Test Execution Logs: /path/to/devicetester/results/87e673c6-1226-11eb-9269-8c8590419f30/logs
Path to Aggregated JUnit Report: /path/to/devicetester/results/87e673c6-1226-11eb-9269-8c8590419f30/IDTSampleSuitePython_Report.xml
```

## 问题排查
<a name="tutorial-troubleshooting-custom"></a>

使用以下信息，以帮助解决在完成本教程时遇到的任何问题。

**测试用例未成功运行**  
如果测试运行失败，IDT 会将错误日志流式传输到控制台，以帮助您对测试运行进行故障排除。请确保满足本教程的所有[先决条件](#prereqs-tutorial-sample)。

**无法连接到被测设备**

请验证以下内容：
+ 您的 `device.json` 文件包含正确的 IP 地址、端口和身份验证信息。
+ 您可以通过 SSH 从主机连接到您的设备。

# 教程：开发一个简单的 IDT 测试套件
<a name="create-custom-tests"></a>

测试套件结合了以下内容：
+ 包含测试逻辑的测试可执行文件
+ 描述测试套件的 JSON 配置文件

本教程向您展示如何使用 IDT AWS IoT Greengrass 来开发包含单个测试用例的 Python 测试套件。在本教程中，您将完成以下步骤：

1. [创建测试套件目录](#test-suite-dir)

1. [创建 JSON 配置文件](#test-suite-json)

1. [创建测试用例可执行文件](#test-suite-exe)

1. [运行测试套件](#run-test-suite)

## 先决条件
<a name="prereqs-tutorial-custom"></a>

要完成本教程，您需要：<a name="prereqs-list"></a>
+ 

**主机要求**
  + 最新版本的 AWS IoT 设备测试器
  + [Python](https://www.python.org/downloads/) 3.7 或更高版本

    要检查您计算机安装的 Python 版本，请运行以下命令：

    ```
    python3 --version
    ```

    在 Windows 上，如果运行此命令时返回错误，则可改用 `python --version`。如果返回的版本号为 3.7 或更高版本，则可通过在 Powershell 终端中运行以下命令将 `python3` 设置为 `python` 命令的别名。

    ```
    Set-Alias -Name "python3" -Value "python"
    ```

    如果没有返回版本信息，或者版本号小于 3.7，则按照[下载 Python](https://wiki.python.org/moin/BeginnersGuide/Download) 中的说明安装 Python 3.7\$1。有关更多信息，请参阅 [Python 文档](https://docs.python.org)。
  + [urllib3](https://urllib3.readthedocs.io/en/latest/)

    要验证 `urllib3` 是否已正确安装，请运行以下命令：

    ```
    python3 -c 'import urllib3'
    ```

    如果未安装 `urllib3`，请运行以下命令进行安装：

    ```
    python3 -m pip install urllib3
    ```
+ 

**设备要求**
  + 一种运行 Linux 操作系统的设备，其网络连接到与您主机相同的网络。

    我们建议您使用搭载 Raspberry Pi 操作系统的 [Raspberry Pi](https://www.raspberrypi.org/)。请确保您设置 Raspberry Pi 上的 [SSH](https://www.raspberrypi.org/documentation/remote-access/ssh/) 才能远程连接到它。

## 创建测试套件目录
<a name="test-suite-dir"></a>

IDT 在逻辑上将测试用例分成每个测试套件中的测试组。每个测试用例都必须位于测试组中。在本教程中，创建一个名为 `MyTestSuite_1.0.0` 的文件夹，并在此文件夹中创建以下目录树：

```
MyTestSuite_1.0.0
└── suite
    └── myTestGroup
        └── myTestCase
```

## 创建 JSON 配置文件
<a name="test-suite-json"></a>

您的测试套件必须包含以下必需的 [JSON 配置文件](idt-json-config.md)：<a name="required-json"></a>所需的 JSON 文件

`suite.json`  
包含有关测试套件的信息。请参阅[配置 suite.json](idt-json-config.md#suite-json)。

`group.json`  
包含有关测试组的信息。您必须为测试套件中的每个测试组创建一个 `group.json` 文件。请参阅[配置 group.json](idt-json-config.md#group-json)。

`test.json`  
包含有关测试用例的信息。您必须为测试套件中的每个测试用例创建一个 `test.json` 文件。请参阅[配置 test.json](idt-json-config.md#test-json)。

1. 在 `MyTestSuite_1.0.0/suite` 文件夹中，创建以下文件夹结构的 `suite.json`：

   ```
   {
       "id": "MyTestSuite_1.0.0",
       "title": "My Test Suite",
       "details": "This is my test suite.",
       "userDataRequired": false
   }
   ```

1. 在 `MyTestSuite_1.0.0/myTestGroup` 文件夹中，创建以下文件夹结构的 `group.json`：

   ```
   {
       "id": "MyTestGroup",
       "title": "My Test Group",
       "details": "This is my test group.",
       "optional": false
   }
   ```

1. 在 `MyTestSuite_1.0.0/myTestGroup/myTestCase` 文件夹中，创建以下文件夹结构的 `test.json`：

   ```
   {
       "id": "MyTestCase",
       "title": "My Test Case",
       "details": "This is my test case.",
       "execution": {
           "timeout": 300000,
           "linux": {
               "cmd": "python3",
               "args": [
                   "myTestCase.py"
               ]
           },
           "mac": {
               "cmd": "python3",
               "args": [
                   "myTestCase.py"
               ]
           },
           "win": {
               "cmd": "python3",
               "args": [
                   "myTestCase.py"
               ]
           }
       }
   }
   ```

您的 `MyTestSuite_1.0.0` 文件夹应类似于以下内容：

```
MyTestSuite_1.0.0
└── suite
    ├── suite.json
    └── myTestGroup
        ├── group.json
        └── myTestCase
            └── test.json
```

## 获取 IDT 客户端 SDK
<a name="add-idt-sdk"></a>

您可以使用 [IDT 客户端 SDK](test-executables.md#idt-client-sdk) 让 IDT 与被测设备进行交互并报告测试结果。在本教程中，您将使用 Python 版本的软件开发工具包。

从 `<device-tester-extract-location>/sdks/python/` 文件夹，将 `idt_client` 文件夹复制到您的 `MyTestSuite_1.0.0/suite/myTestGroup/myTestCase` 文件夹。

要验证 SDK 是否复制，可以运行以下命令。

```
cd MyTestSuite_1.0.0/suite/myTestGroup/myTestCase
python3 -c 'import idt_client'
```

## 创建测试用例可执行文件
<a name="test-suite-exe"></a>

测试用例可执行文件包含要运行的测试逻辑。一个测试套件可以包含多个测试用例可执行文件。在本教程中，您将只创建一个测试用例可执行文件。

1. 创建测试套件文件。

   在 `MyTestSuite_1.0.0/suite/myTestGroup/myTestCase` 文件夹中，创建使用以下内容的 `myTestCase.py` 文件：

   ```
   from idt_client import *
   
   def main():
       # Use the client SDK to communicate with IDT
       client = Client()
   
   if __name__ == "__main__":
       main()
   ```

1. 使用客户端 SDK 函数将以下测试逻辑添加到您的 `myTestCase.py` 文件中：

   1. 在被测设备上运行 SSH 命令。

      ```
      from idt_client import *
      
      def main():
          # Use the client SDK to communicate with IDT
          client = Client()
          
          # Create an execute on device request
          exec_req = ExecuteOnDeviceRequest(ExecuteOnDeviceCommand("echo 'hello world'"))
          
          # Run the command
          exec_resp = client.execute_on_device(exec_req)
          
          # Print the standard output
          print(exec_resp.stdout)
      
      if __name__ == "__main__":
          main()
      ```

   1. 将测试结果发送给 IDT。

      ```
      from idt_client import *
      
      def main():
          # Use the client SDK to communicate with IDT
          client = Client()
          
          # Create an execute on device request
          exec_req = ExecuteOnDeviceRequest(ExecuteOnDeviceCommand("echo 'hello world'"))
          
          # Run the command
          exec_resp = client.execute_on_device(exec_req)
          
          # Print the standard output
          print(exec_resp.stdout)
      
          # Create a send result request
          sr_req = SendResultRequest(TestResult(passed=True))
           
          # Send the result
          client.send_result(sr_req)
             
      if __name__ == "__main__":
          main()
      ```

## 配置 IDT 的设备信息
<a name="configure-idt-sample"></a>

配置您的设备信息，以便 IDT 运行测试。您必须使用以下信息，更新位于 `<device-tester-extract-location>/configs` 文件夹中的 `device.json` 模板。

```
[
  {
    "id": "pool",
    "sku": "N/A",
    "devices": [
      {
        "id": "<device-id>",
        "connectivity": {
          "protocol": "ssh",
          "ip": "<ip-address>",
          "port": "<port>",
          "auth": {
            "method": "pki | password",
            "credentials": {
              "user": "<user-name>",
              "privKeyPath": "/path/to/private/key",
              "password": "<password>"
            }
          }
        }
      }
    ]
  }
]
```

在 `devices` 对象中，提供以下信息：

`id`  
专属于您设备的用户定义唯一标识符。

`connectivity.ip`  
您设备的 IP 地址。

`connectivity.port`  
可选。用于通过 SSH 连接到您的设备的端口号。

`connectivity.auth`  
连接的身份验证信息。  
此属性仅在 `connectivity.protocol` 设置为 `ssh` 时适用。    
`connectivity.auth.method`  
用于通过给定的连接协议访问设备的身份验证方法。  
支持的值为：  
+ `pki`
+ `password`  
`connectivity.auth.credentials`  
用于身份验证的凭证。    
`connectivity.auth.credentials.user`  
用于登录您的设备的用户名。  
`connectivity.auth.credentials.privKeyPath`  
用于登录您设备的私有密钥的完整路径。  
此值仅在 `connectivity.auth.method` 设置为 `pki` 时适用。  
`devices.connectivity.auth.credentials.password`  
该密码用于登录到您的设备。  
此值仅在 `connectivity.auth.method` 设置为 `password` 时适用。

**注意**  
只有当 `method` 设置为 `pki` 时才指定 `privKeyPath`。  
只有当 `method` 设置为 `password` 时才指定 `password`。

## 运行测试套件
<a name="run-test-suite"></a>

创建测试套件后，您需要确保其按预期运行。要使用现有设备池运行测试套件，请完成以下步骤。

1. 将您的 `MyTestSuite_1.0.0` 文件夹复制到 `<device-tester-extract-location>/tests`。

1. 运行以下 命令：

   ```
   cd <device-tester-extract-location>/bin
   ./devicetester_[linux | mac | win_x86-64] run-suite --suite-id MyTestSuite
   ```

IDT 会运行您的测试套件，并将结果流式传输到控制台。测试运行完毕后，您会看到以下信息：

```
time="2020-10-19T09:24:47-07:00" level=info msg=Using pool: pool
time="2020-10-19T09:24:47-07:00" level=info msg=Using test suite "MyTestSuite_1.0.0" for execution
time="2020-10-19T09:24:47-07:00" level=info msg=b'hello world\n' suiteId=MyTestSuite groupId=myTestGroup testCaseId=myTestCase deviceId=my-device executionId=9a52f362-1227-11eb-86c9-8c8590419f30
time="2020-10-19T09:24:47-07:00" level=info msg=All tests finished. executionId=9a52f362-1227-11eb-86c9-8c8590419f30
time="2020-10-19T09:24:48-07:00" level=info msg=

========== Test Summary ==========
Execution Time:         1s
Tests Completed:        1
Tests Passed:           1
Tests Failed:           0
Tests Skipped:          0
----------------------------------
Test Groups:
    myTestGroup:        PASSED
----------------------------------
Path to IoT Device Tester Report: /path/to/devicetester/results/9a52f362-1227-11eb-86c9-8c8590419f30/awsiotdevicetester_report.xml
Path to Test Execution Logs: /path/to/devicetester/results/9a52f362-1227-11eb-86c9-8c8590419f30/logs
Path to Aggregated JUnit Report: /path/to/devicetester/results/9a52f362-1227-11eb-86c9-8c8590419f30/MyTestSuite_Report.xml
```

## 问题排查
<a name="tutorial-troubleshooting"></a>

使用以下信息，以帮助解决在完成本教程时遇到的任何问题。

**测试用例未成功运行**

如果测试运行失败，IDT 会将错误日志流式传输到控制台，以帮助您对测试运行进行故障排除。检查错误日志之前，请验证以下内容：
+ 如[本步骤](#add-idt-sdk)所述，IDT 客户端 SDK 位于正确的文件夹中。
+ 您已满足本教程的所有[先决条件](#prereqs-tutorial-custom)。

**无法连接到被测设备**

请验证以下内容：
+ 您的 `device.json` 文件包含正确的 IP 地址、端口和身份验证信息。
+ 您可以通过 SSH 从主机连接到您的设备。

# 创建 IDT 测试套件配置文件
<a name="idt-json-config"></a>

本节介绍创建 JSON 配置文件时使用的格式，您在编写自定义测试套件时包含了这些文件。<a name="required-json"></a>所需的 JSON 文件

`suite.json`  
包含有关测试套件的信息。请参阅 [配置 suite.json](#suite-json)。

`group.json`  
包含有关测试组的信息。您必须为测试套件中的每个测试组创建一个 `group.json` 文件。请参阅 [配置 group.json](#group-json)。

`test.json`  
包含有关测试用例的信息。您必须为测试套件中的每个测试用例创建一个 `test.json` 文件。请参阅 [配置 test.json](#test-json)。可选 JSON 文件

`state_machine.json`  
定义 IDT 运行测试套件时运行测试的方式。请参阅 [配置 state\$1machine.json](#state-machine-json)。

`userdata_schema.json`  
定义测试运行器可以在其设置配置中包含的[`userdata.json`文件](set-config-custom.md#userdata-config-custom)架构。`userdata.json` 文件用于存储运行测试所需但 `device.json` 文件中不存在的任何其他配置信息。请参阅 [配置 userdata\$1schema.json](#userdata-schema-json)。

JSON 配置文件放置在您的 `<custom-test-suite-folder>` 中，如下所示。

```
<custom-test-suite-folder>
└── suite
    ├── suite.json
    ├── state_machine.json
    ├── userdata_schema.json
    ├── <test-group-folder>
        ├── group.json
        ├── <test-case-folder>
            └── test.json
```

## 配置 suite.json
<a name="suite-json"></a>

`suite.json` 文件设置环境变量并确定运行测试套件是否需要用户数据。使用以下模板来配置您的 `<custom-test-suite-folder>/suite/suite.json` 文件：

```
{
    "id": "<suite-name>_<suite-version>",
    "title": "<suite-title>",
    "details": "<suite-details>",
    "userDataRequired": true | false,
    "environmentVariables": [
        {
            "key": "<name>",
            "value": "<value>",
        },
        ...
        {
            "key": "<name>",
            "value": "<value>",
        }
    ]
}
```

包含值的所有字段都为必填字段，如下所述：

`id`  
测试套件的唯一用户定义 ID。`id` 的值必须与 `suite.json` 文件所在的测试套件文件夹的名称相匹配。套件名称和套件版本还必须满足以下要求：  
+ `<suite-name>` 不可以包含下划线。
+ `<suite-version>` 表示为 `x.x.x`，其中 `x` 为数字。
ID 显示在 IDT 生成的测试报告中。

`title`  
此测试套件正在测试的产品或功能的用户定义名称。该名称显示在 IDT CLI 中供测试运行器使用。

`details`  
测试套件用途的简短描述。

`userDataRequired`  
定义测试运行器是否需要在 `userdata.json` 文件中包含自定义信息。如果将此值设置为 `true`，还必须将[`userdata_schema.json` 文件](#userdata-schema-json)包含在测试套件文件夹中。

`environmentVariables`  
可选。一组要为此测试套件设置的环境变量。    
`environmentVariables.key`  
环境变量的名称。  
`environmentVariables.value`  
环境变量的值。

## 配置 group.json
<a name="group-json"></a>

`group.json` 文件定义测试组是必需的还是可选的。使用以下模板来配置您的 `<custom-test-suite-folder>/suite/<test-group>/group.json` 文件：

```
{
    "id": "<group-id>",
    "title": "<group-title>",
    "details": "<group-details>",
    "optional": true | false,
}
```

包含值的所有字段都为必填字段，如下所述：

`id`  
测试组的唯一用户定义 ID。`id` 的值必须与 `group.json` 文件所在的测试组文件夹的名称相匹配，并且不得包含下划线 (`_`)。ID 用于 IDT 生成的测试报告中。

`title`  
测试组的描述性名称。该名称显示在 IDT CLI 中供测试运行器使用。

`details`  
测试组用途的简短描述。

`optional`  
可选。设置为 `true` 以便在 IDT 完成运行所需测试后，将此测试组显示为可选组。默认值为 `false`。

## 配置 test.json
<a name="test-json"></a>

`test.json` 文件确定测试用例的可执行文件和测试用例使用的环境变量。有关创建测试用例可执行文件的更多信息，请参阅 [创建 IDT 测试用例可执行文件](test-executables.md)。

使用以下模板来配置您的 `<custom-test-suite-folder>/suite/<test-group>/<test-case>/test.json` 文件：

```
{
    "id": "<test-id>",
    "title": "<test-title>",
    "details": "<test-details>",
    "requireDUT": true | false,
    "requiredResources": [
        {
            "name": "<resource-name>",
            "features": [
                {
                    "name": "<feature-name>",
                    "version": "<feature-version>",
                    "jobSlots": <job-slots>
                }
            ]
        }
    ],
    "execution": {
        "timeout": <timeout>,
        "mac": {
            "cmd": "/path/to/executable",
            "args": [
                "<argument>"
            ],
        },
        "linux": {
            "cmd": "/path/to/executable",
            "args": [
                "<argument>"
            ],
        },
        "win": {
            "cmd": "/path/to/executable",
            "args": [
                "<argument>"
            ]
        }
    },
    "environmentVariables": [
        {
            "key": "<name>",
            "value": "<value>",
        }
    ]
}
```

包含值的所有字段都为必填字段，如下所述：

`id`  
测试用例的唯一用户定义 ID。`id` 的值必须与 `test.json` 文件所在的测试用例文件夹的名称相匹配，并且不得包含下划线 (`_`)。ID 用于 IDT 生成的测试报告中。

`title`  
测试用例的描述性名称。该名称显示在 IDT CLI 中供测试运行器使用。

`details`  
测试用例用途的简短描述。

`requireDUT`  
可选。如果需要设备才能运行此测试，则设置为 `true`，否则设置为 `false`。默认值为 `true`。测试运行器将在其 `device.json` 文件中配置将用来运行测试的设备。

`requiredResources`  
可选。一个阵列，提供有关运行此测试所需资源设备的信息。    
`requiredResources.name`  
运行此测试时为资源设备提供的唯一名称。  
`requiredResources.features`  
一系列用户定义的资源设备功能。    
`requiredResources.features.name`  
功能的名称。您要使用此设备的设备功能。此名称与 `resource.json` 文件中测试运行器提供的功能名称相匹配。  
`requiredResources.features.version`  
可选。功能的版本。此值与 `resource.json` 文件中测试运行器提供的功能版本相匹配。如果未提供版本，则不检查该功能。如果功能不需要版本号，请将此字段留为空白。  
`requiredResources.features.jobSlots`  
可选。此功能可以支持的同时测试的数量。默认值为 `1`。如果您希望 IDT 使用不同的设备来实现各项功能，我们建议您将此值设置为 `1`。

`execution.timeout`  
IDT 等待测试完成运行的时间长度（以毫秒为单位）。有关设置该值的更多信息，请参阅 [创建 IDT 测试用例可执行文件](test-executables.md)。

`execution.os`  
要运行的测试用例可执行文件基于运行 IDT 的主机操作系统。支持的值有`linux`、`mac`和`win`。    
`execution.os.cmd`  
要在指定操作系统上运行的测试用例可执行文件的路径。此位置必须位于系统路径中。  
`execution.os.args`  
可选。为运行测试用例可执行文件而提供的参数。

`environmentVariables`  
可选。一组要为此测试用例设置的环境变量。    
`environmentVariables.key`  
环境变量的名称。  
`environmentVariables.value`  
环境变量的值。
如果在 `test.json` 文件和 `suite.json` 文件中指定相同的环境变量，则 `test.json` 文件中的值优先。

## 配置 state\$1machine.json
<a name="state-machine-json"></a>

状态机是一种控制测试套件执行流程的构造。它决定测试套件的起始状态，根据用户定义的规则管理状态转换，并继续在这些状态之间进行转换，直到达到结束状态。

如果您的测试套件不包含用户定义的状态机，IDT 将为您生成状态机。默认状态机执行以下功能：
+ 使测试运行器能够选择和运行特定的测试组，而不是整个测试套件。
+ 如果未选择特定的测试组，则按随机顺序运行测试套件中的每个测试组。
+ 生成报告并打印控制台摘要，其中显示每个测试组和测试用例的测试结果。

有关 IDT 状态机工作原理的更多信息，请参阅 [配置 IDT 状态机](idt-state-machine.md)。

## 配置 userdata\$1schema.json
<a name="userdata-schema-json"></a>

`userdata_schema.json` 文件确定了测试运行器提供用户数据的架构。如果您的测试套件需要 `device.json` 文件中不存在的信息，则需要用户数据。例如，您的测试可能需要 Wi-Fi 网络凭证、特定的开放端口或用户必须提供的证书。此信息可提供给 IDT，作为用户在其 `<device-tester-extract-location>/config` 文件夹中创建的输入参数，称为 `userdata`，其值是一个 `userdata.json` 文件。`userdata.json` 文件的格式取决于您在测试套件中包含的 `userdata_schema.json` 文件。

要指示测试运行器必须提供 `userdata.json` 文件：

1. 在 `suite.json` 文件中设置 `userDataRequired` 为 `true`。

1. 在您的 `<custom-test-suite-folder>` 中，创建一个 `userdata_schema.json` 文件。

1. 编辑 `userdata_schema.json` 文件以创建有效的 [IETF 草稿 v4 JSON 架构](https://json-schema.org/specification-links.html#draft-4)。

当 IDT 运行您的测试套件时，它会自动读取架构并使用它来验证测试运行器提供的 `userdata.json` 文件。如果有效，则 `userdata.json` 文件内容在 [IDT 上下文](idt-context.md)和[状态机上下文](idt-state-machine.md#state-machine-context)中均可用。

# 配置 IDT 状态机
<a name="idt-state-machine"></a>

状态机是一种控制测试套件执行流程的构造。它决定测试套件的起始状态，根据用户定义的规则管理状态转换，并继续在这些状态之间进行转换，直到达到结束状态。

如果您的测试套件不包含用户定义的状态机，IDT 将为您生成状态机。默认状态机执行以下功能：
+ 使测试运行器能够选择和运行特定的测试组，而不是整个测试套件。
+ 如果未选择特定的测试组，则按随机顺序运行测试套件中的每个测试组。
+ 生成报告并打印控制台摘要，其中显示每个测试组和测试用例的测试结果。

IDT 测试套件的状态机必须满足以下条件：
+ 每个状态都对应于 IDT 要采取的操作，例如运行测试组或产品报告文件。
+ 过渡到状态会执行与该状态关联的操作。
+ 每个状态都定义了下一个状态的过渡规则。
+ 结束状态必须为 `Succeed` 或 `Fail`。

## 状态机格式
<a name="state-machine-format"></a>

您可以使用以下模板来配置自己的`<custom-test-suite-folder>/suite/state_machine.json`文件：

```
{
  "Comment": "<description>",
  "StartAt": "<state-name>",
  "States": {
    "<state-name>": {
      "Type": "<state-type>",
      // Additional state configuration
    }
    
    // Required states
    "Succeed": {
      "Type": "Succeed"
    },
    "Fail": {
      "Type": "Fail"
    }
  }
}
```

包含值的所有字段都为必填字段，如下所述：

`Comment`  
状态机的描述。

`StartAt`  
IDT 开始运行测试套件的状态名称。`StartAt` 的值必须设置为 `States` 对象中列出的其中一个状态。

`States`  
将用户定义的状态名称映射到有效的 IDT 状态的对象。每个州。 *state-name*对象包含映射到. 的有效状态的定义*state-name*。  
`States` 对象必须包含 `Succeed` 和 `Fail` 状态。有关有效状态的信息，请参阅[有效状态和状态定义](#valid-states)。

## 有效状态和状态定义
<a name="valid-states"></a>

本节介绍可在 IDT 状态机中使用的所有有效状态的状态定义。以下某些状态支持测试用例级别的配置。但是，除非绝对必要，否则我们建议您在测试组级别而不是测试用例级别配置状态转换规则。

**Topics**
+ [RunTask](#state-runtask)
+ [Choice](#state-choice)
+ [Parallel](#state-parallel)
+ [AddProductFeatures](#state-addproductfeatures)
+ [报告](#state-report)
+ [LogMessage](#state-logmessage)
+ [SelectGroup](#state-selectgroup)
+ [Fail](#state-fail)
+ [Succeed](#state-succeed)

### RunTask
<a name="state-runtask"></a>

`RunTask` 状态运行测试套件中定义的测试组中的测试用例。

```
{
    "Type": "RunTask",
    "Next": "<state-name>",
    "TestGroup": "<group-id>",
    "TestCases": [
        "<test-id>"
    ],
    "ResultVar": "<result-name>"
}
```

包含值的所有字段都为必填字段，如下所述：

`Next`  
在当前状态下执行操作后要过渡到的状态的名称。

`TestGroup`  
可选。要运行的测试组的 ID。如果未指定此值，则 IDT 将运行测试运行器选择的测试组。

`TestCases`  
可选。 IDs 来自中指定组的测试用例数组`TestGroup`。IDT 根据 `TestGroup` 和 `TestCases` 的值确定测试执行行为，如下所示：  
+ 同时指定 `TestGroup` 和 `TestCases` 时，IDT 会运行测试组中的指定测试用例。
+ 如果 `TestCases` 已指定但 `TestGroup` 未指定，IDT 将运行指定的测试用例。
+ 如果 `TestGroup` 已指定但 `TestCases` 未指定，则 IDT 将运行指定测试组中的所有测试用例。
+ 如果未指定 `TestGroup` 或 `TestCases`，IDT 将运行测试运行器从 IDT CLI 中选择的测试组中的所有测试用例。要为测试运行器启用组选择，必须在 `statemachine.json` 文件中同时包含 `RunTask` 和 `Choice` 状态。有关其工作原理的示例，请参阅[状态机示例：运行用户选择的测试组](#allow-specific-groups)。

  有关为测试运行器启用 IDT CLI 命令的更多信息，请参阅 [启用 IDT CLI 命令](test-executables.md#idt-cli-coop)。

`ResultVar`  
要与测试运行结果一起设置的上下文变量的名称。如果您没有为指定值，请不要指定此值 `TestGroup`。基于以下内容，IDT 将您在 `ResultVar` 中定义的变量的值设置为 `true` 或 `false`：  
+ 如果变量名称的形式为 `text_text_passed`，则该值设置为第一个测试组中的所有测试均已通过或跳过。
+ 在所有其他情况下，该值设置为所有测试组中的所有测试已通过或跳过。

通常，您将使用`RunTask`状态来指定测试组 ID，而不指定单个测试用例 IDs，这样 IDT 将运行指定测试组中的所有测试用例。在此状态下运行的所有测试用例均按随机顺序并行运行。但是，如果所有测试用例都需要一台设备运行，并且只有一台设备可用，则测试用例将按顺序运行。

**错误处理**

如果任何指定的测试组或测试用例 IDs 无效，则此状态会发出`RunTaskError`执行错误。如果状态遇到执行错误，则它还会将状态机上下文中的 `hasExecutionError` 变量设置为 `true`。

### Choice
<a name="state-choice"></a>

`Choice` 状态允许您根据用户定义的条件动态设置要过渡到的下一个状态。

```
{
    "Type": "Choice",
    "Default": "<state-name>", 
    "FallthroughOnError": true | false,
    "Choices": [
        {
            "Expression": "<expression>",
            "Next": "<state-name>"
        }
    ]
}
```

包含值的所有字段都为必填字段，如下所述：

`Default`  
如果 `Choices` 中定义的表达式都无法评估到 `true`，则设置要过渡到的默认状态。

`FallthroughOnError`  
可选。指定状态在评估表达式时遇到错误时的行为。如果要在评估结果出错时跳过表达式，则设置为 `true`。如果没有匹配的表达式，则状态机将过渡到 `Default` 状态。如果 `FallthroughOnError` 的值未指定，将默认为 `false`。

`Choices`  
一组表达式和状态，用于确定在当前状态下执行操作后要过渡到哪个状态。    
`Choices.Expression`  
计算结果为布尔值的表达式字符串。如果表达式的评估结果为 `true`，则状态机将过渡到 `Choices.Next` 中定义的状态。表达式字符串从状态机上下文中检索值，然后对它们执行操作以得出布尔值。有关访问状态机上下文的信息，请参见 [状态机上下文](#state-machine-context)。  
`Choices.Next`  
如果 `Choices.Expression` 中定义的表达式的评估结果为 `true`，则设置要过渡到的状态的名称。

**错误处理**

在以下情况下，`Choice` 状态可能需要错误处理：
+ 选择表达式中的某些变量在状态机上下文中不存在。
+ 表达式的结果不是布尔值。
+ JSON 查询的结果不是字符串、数字或布尔值。

在这种状态下，不能使用 `Catch` 数据块来处理错误。如果要在状态机遇到错误时停止执行它，则必须将 `FallthroughOnError` 设置为 `false`。但是，建议您将 `FallthroughOnError` 设置为 `true`，并根据您的用例，执行以下操作之一：
+ 如果您正在访问的变量预计在某些情况下不存在，则使用的值 `Default` 和其他 `Choices` 数据块来指定下一个状态。
+ 如果您正在访问的变量应始终存在，则将 `Default` 状态设置为 `Fail`。

### Parallel
<a name="state-parallel"></a>

`Parallel` 状态允许您并行地定义和运行新的状态机。

```
{
    "Type": "Parallel",
    "Next": "<state-name>",
    "Branches": [
        <state-machine-definition>
    ]
}
```

包含值的所有字段都为必填字段，如下所述：

`Next`  
在当前状态下执行操作后要过渡到的状态的名称。

`Branches`  
要运行的状态机定义阵列。每个状态机定义都必须包含自己的`StartAt`、`Succeed` 和 `Fail` 状态。此阵列中的状态机定义不能引用其自身定义之外的状态。  
由于每个分支状态机共享相同的状态机上下文，因此在一个分支中设置变量然后从另一个分支读取这些变量可能会导致意外行为。

只有在 `Parallel` 运行所有分支状态机之后，该状态才会移动到下一个状态。每种需要设备的状态都将等到设备可用后才运行。如果有多个设备可用，则此状态会并行运行来自多个组的测试用例。如果没有足够的设备可用，则测试用例将按顺序运行。由于测试用例在并行运行时按随机顺序运行，因此可能会使用不同的设备来运行来自同一个测试组的测试。

**错误处理**

确保分支状态机和父状态机都过渡到 `Fail` 状态以处理执行错误。

由于分支状态机不会将执行错误传输到父状态机，因此您不能使用 `Catch` 数据块来处理分支状态机中的执行错误。相反，在共享状态机上下文中使用 `hasExecutionErrors` 值。有关如何执行此操作的示例，请参阅 [状态机示例：并行运行两个测试组](#run-in-parallel)。

### AddProductFeatures
<a name="state-addproductfeatures"></a>

`AddProductFeatures` 状态允许您将产品功能添加到 IDT 生成的 `awsiotdevicetester_report.xml` 文件中。

产品功能是关于设备可能符合的特定标准的用户定义信息。例如，`MQTT` 产品功能可以指定设备正确发布 MQTT 消息。在报告中，根据指定的测试是否通过，将产品功能设置为 `supported`、`not-supported` 或自定义值。



**注意**  
`AddProductFeatures` 状态本身不生成报告。此状态必须过渡到[`Report`状态](#state-report)才能生成报告。

```
{
    "Type": "Parallel",
    "Next": "<state-name>",
    "Features": [
        {
            "Feature": "<feature-name>", 
            "Groups": [
                "<group-id>"
            ],
            "OneOfGroups": [
                "<group-id>"
            ],
            "TestCases": [
                "<test-id>"
            ],
            "IsRequired": true | false,
            "ExecutionMethods": [
                "<execution-method>"
            ]
        }
    ]
}
```

包含值的所有字段都为必填字段，如下所述：

`Next`  
在当前状态下执行操作后要过渡到的状态的名称。

`Features`  
要在 `awsiotdevicetester_report.xml` 文件中显示的一系列产品功能。    
`Feature`  
功能的名称  
`FeatureValue`  
可选。要在报告中使用的自定义值，而不是 `supported`。如果未指定此值，则根据测试结果，将特征值设置为 `supported` 或 `not-supported`。  
如果您使用 `FeatureValue` 自定义值，则可以在不同的条件下测试相同的功能，IDT 会将支持条件的特征值串联起来。例如，以下摘录显示具有两个独立 `MyFeature` 特征值的要素：  

```
...
{
    "Feature": "MyFeature",
    "FeatureValue": "first-feature-supported",
    "Groups": ["first-feature-group"]
},
{
    "Feature": "MyFeature",
    "FeatureValue": "second-feature-supported",
    "Groups": ["second-feature-group"]
},
...
```
如果两个测试组都通过，则特征值将设置为 `first-feature-supported, second-feature-supported`。  
`Groups`  
可选。一组测试组 IDs。每个指定测试组中的所有测试都必须通过才能支持该功能。  
`OneOfGroups`  
可选。一组测试组 IDs。至少一个指定测试组中的所有测试都必须通过才能支持该功能。  
`TestCases`  
可选。一系列测试用例 IDs。如果您指定此值，则适用以下条件：  
+ 必须通过所有指定的测试用例才能支持该功能。
+ `Groups` 必须仅包含一个测试组 ID。
+ `OneOfGroups` 不得指定。  
`IsRequired`  
可选。设置为 `false` 可在报告中将此功能标记为可选功能。默认值为 `true`。  
`ExecutionMethods`  
可选。与 `device.json` 文件中指定的 `protocol` 值相匹配的执行方法阵列。如果指定了此值，则测试运行器必须指定与该阵列中的一个 `protocol` 值相匹配的值，才能将该功能包含在报告中。如果未指定此值，则该要素将始终包含在报告中。

要使用 `AddProductFeatures` 状态，必须将 `RunTask` 状态 `ResultVar` 中的值设置为以下值之一：
+ 如果您指定了单个测试用例 IDs，则将设置`ResultVar`为`group-id_test-id_passed`。
+ 如果您未指定单个测试用例 IDs，则将设置`ResultVar`为`group-id_passed`。

`AddProductFeatures` 状态通过以下方式检查测试结果：
+ 如果您未指定任何测试用例 IDs，则每个测试组的结果将根据状态机上下文中的`group-id_passed`变量值确定。
+ 如果您确实指定了测试用例 IDs，则每个测试的结果都是根据状态机上下文中`group-id_test-id_passed`变量的值确定的。

**错误处理**

如果在此状态下提供的群组 ID 不是有效的组 ID，则此状态会导致 `AddProductFeaturesError` 执行错误。如果状态遇到执行错误，则它还会将状态机上下文中的 `hasExecutionErrors` 变量设置为 `true`。

### 报告
<a name="state-report"></a>

`Report` 状态会生成 `suite-name_Report.xml` 和 `awsiotdevicetester_report.xml` 文件。此状态还会将报告流式传输到控制台。

```
{
    "Type": "Report",
    "Next": "<state-name>"
}
```

包含值的所有字段都为必填字段，如下所述：

`Next`  
在当前状态下执行操作后要过渡到的状态的名称。

您应始终过渡到测试执行流程即将结束时的 `Report` 状态，以便测试运行器可以查看测试结果。通常，此状态之后的下一个状态是 `Succeed`。

**错误处理**

如果此状态在生成报告时遇到问题，则会发出 `ReportError` 执行错误。

### LogMessage
<a name="state-logmessage"></a>

`LogMessage` 状态生成 `test_manager.log` 文件并将日志消息流式传输到控制台。

```
{
    "Type": "LogMessage",
    "Next": "<state-name>"
    "Level": "info | warn | error"
    "Message": "<message>"
}
```

包含值的所有字段都为必填字段，如下所述：

`Next`  
在当前状态下执行操作后要过渡到的状态的名称。

`Level`  
创建日志消息的错误级别。如果您指定的级别无效，则此状态会生成一条错误消息并将其丢弃。

`Message`  
要记入日志的消息。

### SelectGroup
<a name="state-selectgroup"></a>

`SelectGroup` 状态会更新状态机上下文以指示选择了哪些组。任何后续 `Choice` 状态都使用此状态设置的值。

```
{
    "Type": "SelectGroup",
    "Next": "<state-name>"
    "TestGroups": [
        <group-id>"
    ]
}
```

包含值的所有字段都为必填字段，如下所述：

`Next`  
在当前状态下执行操作后要过渡到的状态的名称。

`TestGroups`  
一组将被标记为选中的测试组。对于此阵列中的每个测试组 ID，`group-id_selected` 变量在上下文中都设置为 `true`。请确保提供有效的测试组， IDs 因为 IDT 不会验证指定的组是否存在。

### Fail
<a name="state-fail"></a>

`Fail` 状态表示状态机未正确执行。这是状态机的结束状态，每个状态机定义都必须包含此状态。

```
{
    "Type": "Fail"
}
```

### Succeed
<a name="state-succeed"></a>

`Succeed` 状态表示状态机已正确执行。这是状态机的结束状态，每个状态机定义都必须包含此状态。

```
{
    "Type": "Succeed"
}
```

## 状态机上下文
<a name="state-machine-context"></a>

状态机上下文是一个只读 JSON 文档，其中包含在执行期间可供状态机使用的数据。状态机上下文只能从状态机访问，并且包含决定测试流程的信息。例如，您可以使用 `userdata.json` 文件中测试运行器配置的信息来确定是否需要运行特定的测试。

状态机上下文使用以下格式：

```
{
    "pool": {
        <device-json-pool-element>
    },
    "userData": {
        <userdata-json-content>
    },
    "config": {
        <config-json-content>
    },
    "suiteFailed": true | false,
    "specificTestGroups": [
        "<group-id>"
    ],
    "specificTestCases": [
        "<test-id>"
    ],
    "hasExecutionErrors": true
}
```

`pool`  
有关为测试运行选择的设备池的信息。对于选定的设备池，此信息将从 `device.json` 文件中定义的相应顶级设备池阵列元素中检索。

`userData`  
`userdata.json` 文件中的信息

`config`  
信息会锁定 `config.json` 文件。

`suiteFailed`  
该值在状态机启动时设置为 `false`。如果测试组在某种 `RunTask` 状态下失败，则在状态机执行的剩余时间内，该值将设置为 `true`。

`specificTestGroups`  
如果测试运行者选择特定的测试组而不是整个测试套件来运行，则会创建此密钥并包含特定测试组的列表 IDs。

`specificTestCases`  
如果测试运行器选择要运行的特定测试用例而不是整个测试套件，则会创建此密钥并包含特定测试用例的列表 IDs。

`hasExecutionErrors`  
状态机启动时不退出。如果任何状态遇到执行错误，则会在状态机执行的剩余时间内创建此变量并将其设置为 `true`。

您可以使用 JSONPath 符号查询上下文。状态定义中 JSONPath 查询的语法是`{{$.query}}`。在某些状态下，您可以将 JSONPath 查询用作占位符字符串。IDT 将占位符字符串替换为来自上下文的已评估 JSONPath 查询的值。您可以对占位符使用以下值：
+ `RunTask`状态的 `TestCases` 值。
+ `Expression` 值 `Choice` 状态。

当您访问状态机上下文中的数据时，请确保满足以下条件：
+ JSON 路径必须以 `$.` 开头
+ 每个值的计算结果必须为字符串、数字或布尔值。

有关使用 JSONPath 符号从上下文访问数据的更多信息，请参阅[使用 IDT 上下文](idt-context.md)。

## 执行错误
<a name="execution-errors"></a>

执行错误是状态机在执行状态时遇到的状态机定义中的错误。IDT 在 `test_manager.log` 文件中记录有关每个错误的信息，并将日志消息流式传输到控制台。

您可以使用以下方法来处理执行错误：
+ 在状态定义中添加一个[`Catch` 数据块](#catch)。
+ 在状态机上下文中检查 [`hasExecutionErrors`值](#context)。

### 捕获
<a name="catch"></a>

要使用 `Catch`，请将以下内容添加到您的状态定义中：

```
"Catch": [
    {    
        "ErrorEquals": [
            "<error-type>"
        ]
        "Next": "<state-name>" 
    }
]
```

包含值的所有字段都为必填字段，如下所述：

`Catch.ErrorEquals`  
要捕获的错误类型的数组。如果执行错误与其中一个指定值匹配，则状态机将转换为 `Catch.Next` 中指定的状态。有关其产生的错误类型的信息，请参阅每个状态定义。

`Catch.Next`  
当前状态遇到与 `Catch.ErrorEquals` 中指定值之一相匹配的执行错误时，设置要过渡到的下一个状态。

捕获数据块按顺序处理，直到匹配。如果没有错误与捕获数据块中列出的错误相匹配，则状态机将继续执行。由于执行错误是由状态定义不正确造成的，因此我们建议您在状态遇到执行错误时过渡到失败状态。

### hasExecutionError
<a name="context"></a>

当某些状态遇到执行错误时，除了发出错误外，它们还会在状态机上下文中将 `hasExecutionError` 值设置为 `true`。您可以使用此值来检测何时发生错误，然后使用 `Choice` 状态将状态机过渡到 `Fail` 状态。

该方式具有以下特征。
+ 状态机不以分配给 `hasExecutionError` 的任何值启动，并且在特定状态设置该值之前，该值不可用。这意味着必须将访问此值的 `Choice` 状态的 `FallthroughOnError` 明确设置为 `false`，以防止在没有发生执行错误时状态机停止。
+ 一旦将其设置为 `true`，`hasExecutionError` 就永远不会设置为 false 或将其从上下文中删除。这意味着该值仅在首次设置为 `true` 时才有用，并且对于所有后续状态，它不会提供有意义的值。
+ `hasExecutionError` 值与处于 `Parallel` 状态的所有分支状态机共享，这可能会导致意想不到的结果，具体取决于访问该值的顺序。

由于这些特性，如果您可以改用捕获数据块，我们不建议您使用此方法。

## 示例状态机
<a name="state-machine-examples"></a>

本部分提供了一些状态机配置示例。

**Topics**
+ [状态机示例：运行单个测试组](#single-test-group)
+ [状态机示例：运行用户选择的测试组](#allow-specific-groups)
+ [状态机示例：使用产品功能运行单个测试组](#run-with-product-features)
+ [状态机示例：并行运行两个测试组](#run-in-parallel)

### 状态机示例：运行单个测试组
<a name="single-test-group"></a>

该状态机：
+ 运行带有 id `GroupA` 的测试组，该组必须以 `group.json` 文件形式存在于套件中。
+ 检查是否存在执行错误，如果发现任何错误，则过渡到 `Fail`。
+ 生成报告，如果没有错误，则过渡到 `Succeed`，否则过渡到 `Fail`。

```
{
    "Comment": "Runs a single group and then generates a report.",
    "StartAt": "RunGroupA",
    "States": {
        "RunGroupA": {
            "Type": "RunTask",
            "Next": "Report",
            "TestGroup": "GroupA",
            "Catch": [
                {
                    "ErrorEquals": [
                        "RunTaskError"
                    ],
                    "Next": "Fail"
                }
            ]
        },
        "Report": {
            "Type": "Report",
            "Next": "Succeed",
            "Catch": [
                {
                    "ErrorEquals": [
                        "ReportError"
                    ],
                    "Next": "Fail"
                }
            ]
        },
        "Succeed": {
            "Type": "Succeed"
        },
        "Fail": {
            "Type": "Fail"
        }
    }
}
```

### 状态机示例：运行用户选择的测试组
<a name="allow-specific-groups"></a>

该状态机：
+ 检查测试运行器是否选择了特定的测试组。状态机不检查特定的测试用例，因为如果不选择测试组，测试运行器就无法选择测试用例。
+ 如果选择了测试组：
  + 在选定的测试组中运行测试用例。为此，状态机不会明确指定处于 `RunTask` 状态中的任何测试组或测试用例。
  + 运行所有测试后生成报告并退出。
+ 如果未选择测试组：
  + 在测试组 `GroupA` 中运行测试。
  + 生成报告并退出。

```
{
    "Comment": "Runs specific groups if the test runner chose to do that, otherwise runs GroupA.",
    "StartAt": "SpecificGroupsCheck",
    "States": {
        "SpecificGroupsCheck": {
            "Type": "Choice",
            "Default": "RunGroupA",
            "FallthroughOnError": true,
            "Choices": [
                {
                    "Expression": "{{$.specificTestGroups[0]}} != ''",
                    "Next": "RunSpecificGroups"
                }
            ]
        },
        "RunSpecificGroups": {
            "Type": "RunTask",
            "Next": "Report",
            "Catch": [
                {
                    "ErrorEquals": [
                        "RunTaskError"
                    ],
                    "Next": "Fail"
                }
            ]
        },
        "RunGroupA": {
            "Type": "RunTask",
            "Next": "Report",
            "TestGroup": "GroupA",
            "Catch": [
                {
                    "ErrorEquals": [
                        "RunTaskError"
                    ],
                    "Next": "Fail"
                }
            ]
        },
        "Report": {
            "Type": "Report",
            "Next": "Succeed",
            "Catch": [
                {
                    "ErrorEquals": [
                        "ReportError"
                    ],
                    "Next": "Fail"
                }
            ]
        },
        "Succeed": {
            "Type": "Succeed"
        },
        "Fail": {
            "Type": "Fail"
        }
    }
}
```

### 状态机示例：使用产品功能运行单个测试组
<a name="run-with-product-features"></a>

该状态机：
+ 运行测试组 `GroupA`。
+ 检查是否存在执行错误，如果发现任何错误，则过渡到 `Fail`。
+ 将 `FeatureThatDependsOnGroupA` 功能添加到 `awsiotdevicetester_report.xml` 文件中：
  + 如果 `GroupA` 通过，则该功能将设置为 `supported`。
  + 报告中未将该功能标记为可选。
+ 生成报告，如果没有错误，则过渡到 `Succeed`，否则过渡到 `Fail`

```
{
    "Comment": "Runs GroupA and adds product features based on GroupA",
    "StartAt": "RunGroupA",
    "States": {
        "RunGroupA": {
            "Type": "RunTask",
            "Next": "AddProductFeatures",
            "TestGroup": "GroupA",
            "ResultVar": "GroupA_passed",
            "Catch": [
                {
                    "ErrorEquals": [
                        "RunTaskError"
                    ],
                    "Next": "Fail"
                }
            ]
        },
        "AddProductFeatures": {
            "Type": "AddProductFeatures",
            "Next": "Report",
            "Features": [
                {
                    "Feature": "FeatureThatDependsOnGroupA",
                    "Groups": [
                        "GroupA"
                    ],
                    "IsRequired": true
                }
            ]
        },
        "Report": {
            "Type": "Report",
            "Next": "Succeed",
            "Catch": [
                {
                    "ErrorEquals": [
                        "ReportError"
                    ],
                    "Next": "Fail"
                }
            ]
        },
        "Succeed": {
            "Type": "Succeed"
        },
        "Fail": {
            "Type": "Fail"
        }
    }
}
```

### 状态机示例：并行运行两个测试组
<a name="run-in-parallel"></a>

该状态机：
+ 并行运行 `GroupA` 和 `GroupB` 测试组。通过分支状态机中的 `RunTask` 状态存储在上下文中的 `ResultVar` 变量可供 `AddProductFeatures` 状态使用。
+ 检查是否存在执行错误，如果发现任何错误，则过渡到 `Fail`。此状态机不使用 `Catch` 数据块，因为该方法不会检测分支状态机中的执行错误。
+ 根据通过的群组向 `awsiotdevicetester_report.xml` 文件添加功能
  + 如果 `GroupA` 通过，则该功能将设置为 `supported`。
  + 报告中未将该功能标记为可选。
+ 生成报告，如果没有错误，则过渡到 `Succeed`，否则过渡到 `Fail`

如果在设备池中配置了两个设备，则 `GroupA` 和 `GroupB` 可以同时运行。但是，如果其中一个 `GroupA` 或 `GroupB` 有多个测试，则两个设备都可能分配给这些测试。如果只配置了一台设备，则测试组将按顺序运行。

```
{
    "Comment": "Runs GroupA and GroupB in parallel",
    "StartAt": "RunGroupAAndB",
    "States": {
        "RunGroupAAndB": {
            "Type": "Parallel",
            "Next": "CheckForErrors",
            "Branches": [
                {
                    "Comment": "Run GroupA state machine",
                    "StartAt": "RunGroupA",
                    "States": {
                        "RunGroupA": {
                            "Type": "RunTask",
                            "Next": "Succeed",
                            "TestGroup": "GroupA",
                            "ResultVar": "GroupA_passed",
                            "Catch": [
                                {
                                    "ErrorEquals": [
                                        "RunTaskError"
                                    ],
                                    "Next": "Fail"
                                }
                            ]
                        },
                        "Succeed": {
                            "Type": "Succeed"
                        },
                        "Fail": {
                            "Type": "Fail"
                        }
                    }
                },
                {
                    "Comment": "Run GroupB state machine",
                    "StartAt": "RunGroupB",
                    "States": {
                        "RunGroupA": {
                            "Type": "RunTask",
                            "Next": "Succeed",
                            "TestGroup": "GroupB",
                            "ResultVar": "GroupB_passed",
                            "Catch": [
                                {
                                    "ErrorEquals": [
                                        "RunTaskError"
                                    ],
                                    "Next": "Fail"
                                }
                            ]
                        },
                        "Succeed": {
                            "Type": "Succeed"
                        },
                        "Fail": {
                            "Type": "Fail"
                        }
                    }
                }
            ]
        },
        "CheckForErrors": {
            "Type": "Choice",
            "Default": "AddProductFeatures",
            "FallthroughOnError": true,
            "Choices": [
                {
                    "Expression": "{{$.hasExecutionErrors}} == true",
                    "Next": "Fail"
                }
            ]
        },
        "AddProductFeatures": {
            "Type": "AddProductFeatures",
            "Next": "Report",
            "Features": [
                {
                    "Feature": "FeatureThatDependsOnGroupA",
                    "Groups": [
                        "GroupA"
                    ],
                    "IsRequired": true
                },
                {
                    "Feature": "FeatureThatDependsOnGroupB",
                    "Groups": [
                        "GroupB"
                    ],
                    "IsRequired": true
                }
            ]
        },
        "Report": {
            "Type": "Report",
            "Next": "Succeed",
            "Catch": [
                {
                    "ErrorEquals": [
                        "ReportError"
                    ],
                    "Next": "Fail"
                }
            ]
        },
        "Succeed": {
            "Type": "Succeed"
        },
        "Fail": {
            "Type": "Fail"
        }
    }
}
```

# 创建 IDT 测试用例可执行文件
<a name="test-executables"></a>

您可以通过以下方式，创建测试用例可执行文件并将其放在测试套件文件夹中：
+ 如果测试套件使用 `test.json` 文件中的参数或环境变量来确定要运行哪些测试，您可以为整个测试套件创建一个测试用例可执行文件，也可为测试套件中的每个测试组分别创建一个测试可执行文件。
+ 对于要基于指定命令运行特定测试的测试套件，您可以为测试套件中的每个测试用例创建一个测试用例可执行文件。

作为测试编写者，您可以决定哪一种方法适合您的用例，并相应地构建测试用例可执行文件。请确保在每个 `test.json` 文件中提供正确的测试用例可执行文件路径，并且指定的可执行文件能够正确地运行。

当所有设备都准备好运行测试用例时，IDT 将会读取以下文件：
+ 所选测试用例的 `test.json` 决定了要启动的进程以及要设置的环境变量。
+ 测试套件的 `suite.json` 决定了要设置的环境变量。

IDT 根据 `test.json` 文件中指定的命令和参数启动所需的测试可执行文件进程，并将必要的环境变量传递给这个进程。

## 使用 IDT 客户端软件开发工具包
<a name="idt-client-sdk"></a>

IDT 客户端 SDKs 允许您使用 API 命令简化在测试可执行文件中编写测试逻辑的方式，这些命令可用于与 IDT 和被测设备交互。IDT 目前提供以下内容： SDKs
+ 适用于 Python 的 IDT 客户端软件开发工具包
+ 适用于 Go 的 IDT 客户端软件开发工具包

 SDKs 它们位于`<device-tester-extract-location>/sdks`文件夹中。创建新的测试用例可执行文件时，您必须将要使用的软件开发工具包复制到包含测试用例可执行文件的文件夹中，并在代码中引用这个软件开发工具包。本节简要描述了可以在测试用例可执行文件中使用的 API 命令。

**Topics**
+ [设备交互](#api-device-interaction)
+ [IDT 交互](#api-idt-interaction)
+ [主机交互](#api-host-interaction)

### 设备交互
<a name="api-device-interaction"></a>

通过运行以下命令，您无需实施任何其他设备交互和连接管理功能，即可与被测设备通信。

`ExecuteOnDevice`  
允许测试套件在支持 SSH 或 Docker shell 连接的设备上运行 shell 命令。

`CopyToDevice`  
允许测试套件将本地文件从运行 IDT 的主机复制到支持 SSH 或 Docker shell 连接的设备上的指定位置。

`ReadFromDevice`  
允许测试套件从支持 UART 连接的设备的串行端口进行读取。

**注意**  
由于 IDT 不管理使用上下文中设备访问信息与设备建立的直接连接，因此我们建议在测试用例可执行文件中使用这些设备交互 API 命令。但是，如果这些命令不满足测试用例要求，您可以从 IDT 环境中检索设备访问信息，并使用该信息从测试套件建立与设备的直接连接。  
要建立直接连接，请分别在 `device.connectivity` 和 `resource.devices.connectivity` 字段中检索被测设备和资源设备的信息。有关使用 IDT 上下文的更多信息，请参阅 [使用 IDT 上下文](idt-context.md)。

### IDT 交互
<a name="api-idt-interaction"></a>

您可以通过运行以下命令，使测试套件与 IDT 进行通信。

`PollForNotifications`  
允许测试套件检查来自 IDT 的通知。

`GetContextValue ` 和 `GetContextString`  
允许测试套件从 IDT 上下文中检索值。有关更多信息，请参阅 [使用 IDT 上下文](idt-context.md)。

`SendResult`  
允许测试套件向 IDT 报告测试用例结果。此命令必须在测试套件中每个测试用例结束时进行调用。

### 主机交互
<a name="api-host-interaction"></a>

您可以通过运行以下命令，使测试套件与主机进行通信。

`PollForNotifications`  
允许测试套件检查来自 IDT 的通知。

`GetContextValue ` 和 `GetContextString`  
允许测试套件从 IDT 上下文中检索值。有关更多信息，请参阅 [使用 IDT 上下文](idt-context.md)。

`ExecuteOnHost`  
允许测试套件在本地计算机上运行命令，并使 IDT 能够管理测试用例可执行文件的生命周期。

## 启用 IDT CLI 命令
<a name="idt-cli-coop"></a>

IDT CLI `run-suite` 命令提供了多个选项，允许测试运行器自定义测试执行。要允许测试运行器使用这些选项来运行您的自定义测试套件，您需要实施对 IDT CLI 的支持。如果您不实施支持，测试运行器仍然可以运行测试，但是某些 CLI 选项将无法正常运作。为了提供理想的客户体验，我们建议您在 IDT CLI 中实施对以下 `run-suite` 命令参数的支持：

`timeout-multiplier`  
指定一个大于 1.0 的值，该值将应用于测试运行期间的所有超时。  
测试运行器可以使用此参数来延长他们想要运行的测试用例的超时时间。测试运行器在其 `run-suite` 命令中指定此参数后，IDT 会使用它来计算 IDT\$1TEST\$1TIMEOUT 环境变量的值，并在 IDT 上下文中设置 `config.timeoutMultiplier` 字段。要支持这个参数，您必须执行以下操作：  
+ 读取 IDT\$1TEST\$1TIMEOUT 环境变量来获取正确计算的超时值，而不是直接使用 `test.json` 文件中的超时值。
+ 从 IDT 上下文中检索 `config.timeoutMultiplier` 值，并将其应用于长时间运行的超时。
有关因超时事件而提前退出的更多信息，请参阅[指定退出行为](#test-exec-exiting)。

`stop-on-first-failure`  
指定 IDT 在遇到故障时应当停止运行所有测试。  
测试运行器在其 `run-suite` 命令中指定此参数后，IDT 会在遇到故障时立即停止运行测试。但是，如果测试用例是并行运行的，可能会导致意外的结果。要实施支持，请确保当 IDT 遇到此事件时，您的测试逻辑会指示所有运行中的测试用例停止运行、清理临时资源并向 IDT 报告测试结果。有关失败时提早退出的更多信息，请参阅 [指定退出行为](#test-exec-exiting)。

`group-id` 和 `test-id`  
指定 IDT 应当仅运行选定的测试组或测试用例。  
测试运行器可以在 `run-suite` 命令中使用这些参数来指定以下测试执行行为：  
+ 在指定的测试组中运行所有测试。
+ 运行一组来自指定测试组的测试。
为了支持这些参数，测试套件的状态机必须在状态机中包含一组特定的 `RunTask` 和 `Choice` 状态。如果您不使用自定义状态机，默认 IDT 状态机包含了所需的状态，您无需采取其他操作。但是，如果您要使用自定义状态机，则可以将 [状态机示例：运行用户选择的测试组](idt-state-machine.md#allow-specific-groups) 作为示例，在状态机中添加所需的状态。

有关 IDT CLI 命令的更多信息，请参阅 [调试和运行自定义测试套件](run-tests-custom.md)。

## 写入事件日志
<a name="test-exec-logs"></a>

在测试运行期间，您可以通过向 `stdout` 和 `stderr` 发送数据，将事件日志和错误消息写入控制台。有关控制台消息格式的信息，请参阅 [控制台消息格式](idt-review-results-logs.md#idt-console-format)。

IDT 运行完测试套件后，也可以在 `<devicetester-extract-location>/results/<execution-id>/logs` 文件夹下的 `test_manager.log` 文件中找到此信息。

您可以将每个测试用例配置为将其测试运行的日志（包括来自被测设备的日志）写入 `<device-tester-extract-location>/results/execution-id/logs` 文件夹下的 `<group-id>_<test-id>` 文件中。为此，请使用 `testData.logFilePath` 查询从 IDT 上下文中检索日志文件的路径，在该路径上创建一个文件，然后将所需的内容写入这个文件中。IDT 会根据正在运行的测试用例来自动更新路径。如果您选择不为测试用例创建日志文件，则不会为该测试用例生成任何文件。

此外，也可将文本可执行文件设置为按需在 `<device-tester-extract-location>/logs` 文件夹中创建其他日志文件。我们建议您为日志文件名指定唯一的前缀，以避免您的文件被覆盖。

## 向 IDT 报告结果
<a name="test-exec-results"></a>

IDT 将测试结果写入 `awsiotdevicetester_report.xml` 和 `suite-name_report.xml` 文件中。这些报告文件位于 `<device-tester-extract-location>/results/<execution-id>/` 下。两个报告都捕获测试套件执行的结果。有关 IDT 用于这些报告的架构的更多信息，请参阅 [查看 IDT 测试结果和日志](idt-review-results-logs.md)

要在 `suite-name_report.xml` 文件中填充内容，您必须在测试执行结束前使用 `SendResult` 命令向 IDT 报告测试结果。如果 IDT 找不到测试结果，则会针对该测试用例发出错误。以下 Python 摘录显示了用于向 IDT 发送测试结果的命令：

```
request-variable = SendResultRequest(TestResult(result))
client.send_result(request-variable)
```

如果您不通过 API 报告结果，IDT 会在测试构件文件夹中查找测试结果。此文件夹的路径存储在 IDT 上下文中的 `testData.testArtifactsPath` 文件中。在此文件夹中，IDT 将找到的第一个按字母顺序排序的 XML 文件用作测试结果。

如果您的测试逻辑生成 JUnit XML 结果，则可以将测试结果写入 artifacts 文件夹中的 XML 文件中，直接向 IDT 提供结果，而不必解析结果然后使用 API 将其提交给 IDT。

如果使用此方法，请确保您的测试逻辑准确汇总了测试结果，并将结果文件格式化为与 `suite-name_report.xml` 文件相同的格式。IDT 不会对您提供的数据进行任何验证，但以下情况除外：
+ IDT 会忽略 `testsuites` 标签的所有属性。相反，它会从其他报告的测试组结果计算标签属性。
+ `testsuites` 中必须至少存在一个 `testsuite` 标签。

IDT 对所有测试用例使用相同的构件文件夹，并且不会在两次测试运行之间删除结果文件。因此，如果 IDT 读取了错误的文件，此方法也可能会导致错误的报告。我们建议您在所有测试用例中对生成的 XML 结果文件使用相同的名称，以覆盖每个测试用例的结果，并将正确的结果提供给 IDT 使用。您可以在测试套件中使用混合方法来进行报告，即：对某些测试用例使用 XML 结果文件，同时通过 API 提交其他测试用例的结果。但是，我们不建议采用这种方法。

## 指定退出行为
<a name="test-exec-exiting"></a>

将您的文本可执行文件配置为始终以退出代码 0 退出，即使测试用例报告失败或错误结果时也不例外。仅使用非零退出代码来表示测试用例未运行，或者表示测试用例可执行文件无法向 IDT 传达任何结果。当 IDT 收到非零退出代码时，这表示测试用例遇到了阻碍其运行的错误。

在以下事件中，IDT 可能会请求或期望测试用例在完成之前停止运行。您可以使用此信息来配置测试用例可执行文件，以检测测试用例中的每个事件：

**超时**  
当测试用例的运行时间超过 `test.json` 文件中指定的超时值时发生。如果测试运行器使用 `timeout-multiplier` 参数来指定超时乘数，则 IDT 会使用该乘数来计算超时值。  
要检测此事件，请使用 IDT\$1TEST\$1TIMEOUT 环境变量。当测试运行器启动测试时，IDT 会将 IDT\$1TEST\$1TIMEOUT 环境变量的值设置为计算得出的超时值（以秒为单位），并将该变量传递给测试用例可执行文件。您可以读取变量值来设置相应的计时器。

**中断**  
在测试运行器中断 IDT 时发生。例如，按下 Ctrl\$1C。  
终端会将信号传播到所有子进程，因此您只需在测试用例中配置信号处理程序来检测中断信号即可。  
或者，也可以定期轮询 API 以检查 `PollForNotifications` API 响应中 `CancellationRequested` 布尔值的值。当 IDT 收到中断信号时，它会将 `CancellationRequested` 布尔值设置为 `true`。

**首次失败时停止**  
发生的条件为：与当前测试用例并行运行的测试用例失败，并且测试运行器使用了 `stop-on-first-failure` 参数来指定 IDT 应当在遇到任何失败时停止运行。  
要检测此事件，您可以定期轮询 API 以检查 `PollForNotifications` API 响应中 `CancellationRequested` 布尔值的值。如果 IDT 遇到故障并且已配置为在首次失败时停止，它会将 `CancellationRequested` 布尔值设置为 `true`。

发生其中任何一个事件时，IDT 会等待 5 分钟，让当前正在运行的测试用例完成运行。如果所有正在运行的测试用例未能在 5 分钟内退出，IDT 会强制停止它们的每个进程。如果 IDT 没有在进程结束之前收到测试结果，它会将测试用例标记为已超时。作为一种最佳实践，您应确保测试用例在遇到其中一个事件时执行以下操作：

1. 停止运行正常的测试逻辑。

1. 清理所有的临时资源，例如被测设备上的测试构件。

1. 向 IDT 报告测试结果，例如测试失败或错误。

1. 退出。

# 使用 IDT 上下文
<a name="idt-context"></a>

IDT 运行测试套件时，测试套件可以访问一组数据，这些数据可用于确定每个测试的运行方式。这些数据被称为 IDT 上下文。例如，测试运行器在 `userdata.json` 文件中提供的用户数据配置可用于 IDT 环境中的测试套件。

IDT 上下文可以被视为只读 JSON 文档。测试套件可以使用对象、阵列、数字等标准 JSON 数据类型从上下文中检索数据并将数据写入上下文。

## 上下文架构
<a name="idt-context-schema"></a>

IDT 上下文采用以下格式：

```
{
    "config": {
        <config-json-content>
        "timeoutMultiplier": timeout-multiplier
    },
    "device": {
        <device-json-device-element>
    },
    "devicePool": {
        <device-json-pool-element>
    },
    "resource": {
        "devices": [
            {
                <resource-json-device-element>
                "name": "<resource-name>"
            }
        ]
    },
    "testData": {
        "awsCredentials": {
            "awsAccessKeyId": "<access-key-id>",
            "awsSecretAccessKey": "<secret-access-key>",
            "awsSessionToken": "<session-token>"
        },
        "logFilePath": "/path/to/log/file"
    },
    "userData": {
        <userdata-json-content>
    }
}
```

`config`  
[`config.json`文件](gg-core.md#config-json)中的信息。`config` 字段还包含以下附加字段：    
`config.timeoutMultiplier`  
测试套件使用的任何超时值的乘数。此值由 IDT CLI 中的测试运行器指定。默认值为 `1`。

`device`  
有关为测试运行选择的设备的信息。此信息等同于所选设备[`device.json`文件](set-config-custom.md#device-config-custom)中的 `devices` 阵列元素。

`devicePool`  
有关为测试运行选择的设备池的信息。此信息等同于 `device.json` 文件中为所选设备池定义的顶级设备池阵列元素。

`resource`  
`resource.json` 文件中有关资源设备的信息。    
`resource.devices`  
此信息等同于 `resource.json` 文件中定义的 `devices` 阵列。每个 `devices` 元素都包括以下附加字段：    
`resource.device.name`  
资源的名称。此值设置为 `test.json` 文件中的 `requiredResource.name` 值。

`testData.awsCredentials`  
测试用于连接到 AWS 云的 AWS 凭据。此信息是从 `config.json` 文件中获得的。

`testData.logFilePath`  
测试用例写入日志消息的日志文件的路径。如果日志文件不存在，则会创建。

`userData`  
[`userdata.json`文件](set-config-custom.md#userdata-config-custom)中由测试运行器提供的信息。

## 在上下文中访问数据
<a name="accessing-context-data"></a>

您可以使用 JSON 文件中的 JSONPath 符号以及带有和的文本可执行文件中的符号来`GetContextValue`查询上下文`GetContextString` APIs。用于访问 IDT 上下文的 JSONPath 字符串的语法各不相同，如下所示：
+ 在 `suite.json` 和`test.json` 中，使用 `{{query}}`。也就是说，不要使用根元素 `$.` 开始表达式。
+ 在 `statemachine.json` 中，使用 `{{$.query}}`。
+ 在 API 命令中，根据命令的不同，您可以使用 `query` 或 `{{$.query}}`。有关更多信息，请参阅中的内联文档 SDKs。

下表描述了典型 JSONPath表达式中的运算符：


| 运算符  | 描述  | 
| --- |--- |
| \$1 | 根元素。由于 IDT 的顶级上下文值是一个对象，因此，您通常会使用 \$1. 来启动查询。 | 
| .childName | 使用来自对象的名称 childName 访问子元素。如果应用到数组，则生成一个新数组，并将此运算符应用到每个元素。该元素名称区分大小写。例如，访问 config 对象中 awsRegion 值的查询是 \$1.config.awsRegion。 | 
| [start:end] | 筛选数组中的元素，检索从 start 索引开始直到 end 索引的项目（包括首尾）。 | 
| [index1, index2, ... , indexN] | 筛选数组中的元素，仅从指定索引检索项目。 | 
| [?(expr)] | 使用 expr 表达式筛选数组中的元素。该表达式的计算结果必须为布尔值。 | 

要创建筛选表达式，请使用以下语法：

```
<jsonpath> | <value> operator <jsonpath> | <value> 
```

在此语法中：
+ `jsonpath`是 JSONPath 使用标准 JSON 语法的。
+ `value` 是使用标准 JSON 语法的任何自定义值。
+ `operator` 下列运算符之一：
  + `<`（小于）
  + `<=`（小于或等于）
  + `==`（等于）

    如果表达式中的 JSONPath 或值是数组、布尔值或对象值，则这是您可以使用的唯一支持的二进制运算符。
  + `>=`（大于或等于）
  + `>`（大于）
  + `=~`（正则表达式匹配）。要在筛选表达式中使用此运算符，表达式左侧的 JSONPath 或值必须计算为字符串，而右侧的值必须是遵循该[RE2语法](https://github.com/google/re2/wiki/Syntax)的模式值。

您可以使用 \$1\$1*query*\$1\$1 形式的 JSONPath 查询作为文件和字段中`args`以及`test.json`文件中`environmentVariables`字段中的占位符字符串。`environmentVariables` `suite.json`IDT 执行上下文查找，并使用查询的评估值填充字段。例如，在 `suite.json` 文件中，您可以使用占位符字符串来指定随每个测试用例而变化的环境变量值，IDT 将使用每个测试用例的正确值填充环境变量。但是，当您在 `test.json` 和 `suite.json` 文件中使用占位符字符串时，以下注意事项适用于您的查询：
+ 查询中每次出现的 `devicePool` 密钥都必须全部使用小写字母。也就是说，改用 `devicepool`。
+ 对于数组，只能使用字符串数组。此外，数组使用非标准 `item1, item2,...,itemN` 格式。如果数组仅包含一个元素，则将其序列化为 `item`，使其与字符串字段没有区别。
+ 不能使用占位符从上下文中检索对象。

出于这些考虑，我们建议您尽可能使用 API 来访问测试逻辑中的上下文，而不是 `test.json` 和 `suite.json` 文件中的占位符字符串。但是，在某些情况下，使用 JSONPath 占位符检索要设置为环境变量的单个字符串可能会更方便。

# 为测试运行者配置设置
<a name="set-config-custom"></a>

要运行自定义测试套件，测试运行者必须根据他们要运行的测试套件配置设置。设置是根据位于该 `<device-tester-extract-location>/configs/` 文件夹中的 JSON 配置文件模板指定的。如果需要，测试运行者还必须设置 IDT 用于连接 AWS 云的 AWS 凭据。

作为测试编写者，您需要配置这些文件来[调试您的测试套件](run-tests-custom.md)。您必须向测试运行器提供说明，以便他们可以根据需要配置以下设置来运行您的测试套件。

## 配置 device.json
<a name="device-config-custom"></a>

`device.json` 文件包含有关运行测试的设备的信息（例如，IP 地址、登录信息、操作系统和 CPU 架构）。

测试运行器可以使用位于 `<device-tester-extract-location>/configs/` 文件夹中的以下模板 `device.json` 文件来提供此信息。

```
[
    {
        "id": "<pool-id>",
        "sku": "<pool-sku>",
        "features": [
            {
                "name": "<feature-name>",             
                "value": "<feature-value>",                
                "configs": [
                    {
                        "name": "<config-name>",                    
                        "value": "<config-value>"
                    }
                ],
            }
        ],     
        "devices": [
            {
                "id": "<device-id>",              
                "connectivity": {
                    "protocol": "ssh | uart | docker",                   
                    // ssh
                    "ip": "<ip-address>",
                    "port": <port-number>,
                    "auth": {
                        "method": "pki | password",
                        "credentials": {
                            "user": "<user-name>", 
                            // pki
                            "privKeyPath": "/path/to/private/key",
                                         
                            // password
                            "password": "<password>",
                        }
                    },
                    
                    // uart
                    "serialPort": "<serial-port>",
                    
                    // docker
                    "containerId": "<container-id>",
                    "containerUser": "<container-user-name>",
                }
            }
        ]
    }
]
```

包含值的所有字段都为必填字段，如下所述：

`id`  
一个用户定义的字母数字 ID，用于唯一地标识称作*设备池*的设备集合。属于池的设备必须具有相同的硬件。运行一组测试时，池中的设备将用于对工作负载进行并行化处理。多个设备用于运行不同测试。

`sku`  
唯一标识所测试设备的字母数字值。该 SKU 用于跟踪符合条件的设备。  
如果您想在 AWS Partner 设备目录中发布您的主板，则在此处指定的 SKU 必须与您在发布过程中使用的 SKU 相匹配。

`features`  
可选。包含设备支持的功能的数组。设备功能是您在测试套件中配置的用户定义值。您必须向测试运行器提供有关要包含在 `device.json` 文件中的功能名称和值的信息。例如，如果您想测试一台可充当其他设备的 MQTT 服务器的设备，则可以配置测试逻辑来验证名为 `MQTT_QOS` 的功能的特定支持级别。测试运行器提供此功能名称，并将该功能值设置为其设备支持的 QOS 级别。您可以通过查询从 [IDT 上下文](idt-context.md)中检索所提供的信息，也可以通过`devicePool.features`查询从[状态机上下文](idt-state-machine.md#state-machine-context)中检索所`pool.features`提供的信息。    
`features.name`  
功能的名称。  
`features.value`  
支持的功能值。  
`features.configs`  
该功能的配置设置（如果需要）。    
`features.config.name`  
配置设置的名称。  
`features.config.value`  
支持的设置值。

`devices`  
池中待测试的设备阵列。至少需要选择一个设备。  <a name="device-array-fields"></a>  
`devices.id`  
用户定义的测试的设备的唯一标识符。  
`connectivity.protocol`  
用于与此设备通信的通信协议。池中的每台设备都必须使用相同的协议。  
目前，唯一支持的值，对于物理设备为 `ssh` 和 `uart`，对于 Docker 容器为 `docker`。  
`connectivity.ip`  
测试的设备 IP 地址。  
<a name="connectivity-protocol-ssh-only"></a>此属性仅在 `connectivity.protocol` 设置为 `ssh` 时适用。  
`connectivity.port`  
可选。用于 SSH 连接的端口号。  
默认值为 22。  
<a name="connectivity-protocol-ssh-only"></a>此属性仅在 `connectivity.protocol` 设置为 `ssh` 时适用。  
`connectivity.auth`  
连接的身份验证信息。  
<a name="connectivity-protocol-ssh-only"></a>此属性仅在 `connectivity.protocol` 设置为 `ssh` 时适用。    
`connectivity.auth.method`  
用于通过给定的连接协议访问设备的身份验证方法。  
支持的值为：  
+ `pki`
+ `password`  
`connectivity.auth.credentials`  
用于身份验证的凭证。    
`connectivity.auth.credentials.password`  
该密码用于登录到正在测试的设备。  
此值仅在 `connectivity.auth.method` 设置为 `password` 时适用。  
`connectivity.auth.credentials.privKeyPath`  
用于登录所测试设备的私有密钥的完整路径。  
此值仅在 `connectivity.auth.method` 设置为 `pki` 时适用。  
`connectivity.auth.credentials.user`  
用于登录所测试设备的用户名。  
`connectivity.serialPort`  
可选。设备所连接的串行端口。  
此属性仅在 `connectivity.protocol` 设置为 `uart` 时适用。  
`connectivity.containerId`  
所测试的 Docker 容器的容器 ID 或名称。  
<a name="connectivity-protocol-docker-only"></a>此属性仅在 `connectivity.protocol` 设置为 `docker` 时适用。  
`connectivity.containerUser`  
可选。容器内用户对用户的名称。默认值为 Dockerfile 中提供的用户。  
默认值为 22。  
<a name="connectivity-protocol-docker-only"></a>此属性仅在 `connectivity.protocol` 设置为 `docker` 时适用。
要检查测试运行器是否为测试配置了错误的设备连接，可以从状态机上下文中检索 `pool.Devices[0].Connectivity.Protocol`，并将其与 `Choice` 状态下的预期值进行比较。如果使用的协议不正确，则使用 `LogMessage` 状态打印一条消息并过渡到 `Fail` 状态。  
或者，您可以使用错误处理代码来报告错误设备类型的测试失败。

## （可选）配置 userdata.json
<a name="userdata-config-custom"></a>

`userdata.json` 文件包含测试套件所需但 `device.json` 文件中未指定的任何其他信息。此文件的格式取决于测试套件中定义的[`userdata_scheme.json`文件](idt-json-config.md#userdata-schema-json)。如果您是测试编写者，请务必将此信息提供给将运行您编写的测试套件的用户。

## （可选）配置 resource.json
<a name="resource-config-custom"></a>

`resource.json` 文件包含有关将用作资源设备的所有设备的信息。资源设备是测试被测设备的某些功能所需的设备。例如，要测试设备的蓝牙功能，您可以使用资源设备来测试您的设备能否成功连接到该设备。资源设备是可选的，您可以根据需要任意数量的资源设备。作为测试编写者，您可以使用 [test.json 文件](idt-json-config.md#test-json)来定义测试所需的资源设备功能。然后，测试运行器使用 `resource.json` 文件提供具有所需功能的资源设备池。请务必将此信息提供给将运行您编写的测试套件的用户。

测试运行器可以使用位于 `<device-tester-extract-location>/configs/` 文件夹中的以下模板 `resource.json` 文件来提供此信息。

```
[
    {
        "id": "<pool-id>",
        "features": [
            {
                "name": "<feature-name>",             
                "version": "<feature-value>",                
                "jobSlots": <job-slots>
            }
        ],     
        "devices": [
            {
                "id": "<device-id>",              
                "connectivity": {
                    "protocol": "ssh | uart | docker",                   
                    // ssh
                    "ip": "<ip-address>",
                    "port": <port-number>,
                    "auth": {
                        "method": "pki | password",
                        "credentials": {
                            "user": "<user-name>", 
                            // pki
                            "privKeyPath": "/path/to/private/key",
                                         
                            // password
                            "password": "<password>",
                        }
                    },
                    
                    // uart
                    "serialPort": "<serial-port>",
                    
                    // docker
                    "containerId": "<container-id>",
                    "containerUser": "<container-user-name>",
                }
            }
        ]
    }
]
```

包含值的所有字段都为必填字段，如下所述：

`id`  
一个用户定义的字母数字 ID，用于唯一地标识称作*设备池*的设备集合。属于池的设备必须具有相同的硬件。运行一组测试时，池中的设备将用于对工作负载进行并行化处理。多个设备用于运行不同测试。

`features`  
可选。包含设备支持的功能的数组。此字段中所需的信息在测试套件的 [test.json 文件](idt-json-config.md#test-json)中定义，这些信息用于确定要运行哪些测试以及如何运行这些测试。如果测试套件不需要任何功能，则此字段不是必填字段。    
`features.name`  
功能的名称。  
`features.version`  
功能版本。  
`features.jobSlots`  
用于指明可以同时使用该设备的测试次数的设置。默认值为 `1`。

`devices`  <a name="device-array"></a>
池中待测试的设备阵列。至少需要选择一个设备。  <a name="device-array-fields"></a>  
`devices.id`  
用户定义的测试的设备的唯一标识符。  
`connectivity.protocol`  
用于与此设备通信的通信协议。池中的每台设备都必须使用相同的协议。  
目前，唯一支持的值，对于物理设备为 `ssh` 和 `uart`，对于 Docker 容器为 `docker`。  
`connectivity.ip`  
测试的设备 IP 地址。  
<a name="connectivity-protocol-ssh-only"></a>此属性仅在 `connectivity.protocol` 设置为 `ssh` 时适用。  
`connectivity.port`  
可选。用于 SSH 连接的端口号。  
默认值为 22。  
<a name="connectivity-protocol-ssh-only"></a>此属性仅在 `connectivity.protocol` 设置为 `ssh` 时适用。  
`connectivity.auth`  
连接的身份验证信息。  
<a name="connectivity-protocol-ssh-only"></a>此属性仅在 `connectivity.protocol` 设置为 `ssh` 时适用。    
`connectivity.auth.method`  
用于通过给定的连接协议访问设备的身份验证方法。  
支持的值为：  
+ `pki`
+ `password`  
`connectivity.auth.credentials`  
用于身份验证的凭证。    
`connectivity.auth.credentials.password`  
该密码用于登录到正在测试的设备。  
此值仅在 `connectivity.auth.method` 设置为 `password` 时适用。  
`connectivity.auth.credentials.privKeyPath`  
用于登录所测试设备的私有密钥的完整路径。  
此值仅在 `connectivity.auth.method` 设置为 `pki` 时适用。  
`connectivity.auth.credentials.user`  
用于登录所测试设备的用户名。  
`connectivity.serialPort`  
可选。设备所连接的串行端口。  
此属性仅在 `connectivity.protocol` 设置为 `uart` 时适用。  
`connectivity.containerId`  
所测试的 Docker 容器的容器 ID 或名称。  
<a name="connectivity-protocol-docker-only"></a>此属性仅在 `connectivity.protocol` 设置为 `docker` 时适用。  
`connectivity.containerUser`  
可选。容器内用户对用户的名称。默认值为 Dockerfile 中提供的用户。  
默认值为 22。  
<a name="connectivity-protocol-docker-only"></a>此属性仅在 `connectivity.protocol` 设置为 `docker` 时适用。

## （可选）配置 config.json
<a name="config-json-custom"></a>

`config.json` 文件包含 IDT 的配置信息。通常，测试运行者无需修改此文件，除非提供他们的 IDT AWS 用户凭证和 AWS 区域（可选）。如果提供了具有所需权限的 AWS 凭证，则 AWS IoT 设备测试人员会收集使用情况指标并将其提交给 AWS。这是一项可选功能，用来改进 IDT 功能。有关更多信息，请参阅 [IDT 使用量指标](idt-usage-metrics.md)。

测试运行者可以通过以下方式之一配置其 AWS 凭证：
+ **凭证文件**

  IDT 使用与 AWS CLI相同的凭证文件。有关更多信息，请参阅[配置和凭证文件](https://docs.aws.amazon.com/cli/latest/userguide/cli-config-files.html)。

  凭证文件的位置因您使用的操作系统而异：
  + macOS、Linux：`~/.aws/credentials`
  + Windows：`C:\Users\UserName\.aws\credentials`
+ **环境变量**

  环境变量是由操作系统维护且由系统命令使用的变量。在 SSH 会话期间定义的变量在该会话关闭后不可用。IDT 可以使用`AWS_ACCESS_KEY_ID`和`AWS_SECRET_ACCESS_KEY`环境变量来存储凭证 AWS 

  要在 Linux、macOS 或 Unix 上设置这些变量，请使用 **export**：

  ```
  export AWS_ACCESS_KEY_ID=<your_access_key_id>
  export AWS_SECRET_ACCESS_KEY=<your_secret_access_key>
  ```

  要在 Windows 上设置这些变量，请使用 **set**：

  ```
  set AWS_ACCESS_KEY_ID=<your_access_key_id>
  set AWS_SECRET_ACCESS_KEY=<your_secret_access_key>
  ```

要配置 IDT 的 AWS 凭据，测试运行者需要编辑该`<device-tester-extract-location>/configs/`文件夹中`config.json`文件中的`auth`部分。

```
{
    "log": {
        "location": "logs"
    },
    "configFiles": {
        "root": "configs",
        "device": "configs/device.json"
    },
    "testPath": "tests",
    "reportPath": "results",
    "awsRegion": "<region>",
    "auth": {
        "method": "file | environment",
        "credentials": {
            "profile": "<profile-name>"
        }
    }
}
]
```

包含值的所有字段都为必填字段，如下所述：

**注意**  
此文件中的所有路径都是相对于定义的*<device-tester-extract-location>*。

`log.location`  
中日志文件夹的路径*<device-tester-extract-location>*。

`configFiles.root`  
包含配置文件的文件夹的路径。

`configFiles.device`  
`device.json` 文件的路径。

`testPath`  
包含测试套件的文件夹的路径。

`reportPath`  
IDT 运行测试套件后将包含测试结果的文件夹的路径。

`awsRegion`  
可选。测试套件将使用的 AWS 区域。如果未设置，则测试套件将使用每个测试套件中指定的默认区域。

`auth.method`  
IDT 用于检索 AWS 凭证的方法。支持的值是用于从凭证文件中检索凭证的 `file`，以及使用环境变量检索凭证的 `environment`。

`auth.credentials.profile`  
要从凭证文件中使用的凭证配置文件。此属性仅在 `auth.method` 设置为 `file` 时适用。

# 调试和运行自定义测试套件
<a name="run-tests-custom"></a>

设置[所需的配置](set-config-custom.md)后，IDT 就可以运行您的测试套件了。完整测试套件的运行时取决于硬件和测试套件的组成。作为参考，在 Raspberry Pi 3B 上完成完整的 AWS IoT Greengrass 资格测试套件大约需要 30 分钟。

在编写测试套件时，您可以使用 IDT 在调试模式下运行测试套件，以便在运行代码之前检查代码或将其提供给测试运行器。

## 在调试模式下运行 IDT
<a name="idt-debug-mode"></a>

由于测试套件依赖于 IDT 来与设备交互、提供上下文和接收结果，因此如果没有任何 IDT 交互，您就无法在 IDE 中简单地调试测试套件。为此，IDT CLI 提供了 `debug-test-suite` 命令，供您用于在调试模式下运行 IDT。运行以下命令以查看 `debug-test-suite` 的可用选项：

```
devicetester_[linux | mac | win_x86-64] debug-test-suite -h
```

当您在调试模式下运行 IDT 时，IDT 实际上并不启动测试套件或运行状态机；相反，它会与您的 IDE 交互以响应从 IDE 中运行的测试套件所发出的请求，并将日志打印到控制台。IDT 不会超时，而会等待退出，直到手动中断。在调试模式下，IDT 也不运行状态机，并且不会生成任何报告文件。要调试测试套件，您必须使用 IDE 来提供 IDT 通常从配置 JSON 文件中获得的一些信息。务必提供以下信息：
+ 每个测试的环境变量和参数。IDT 不会从 `test.json` 或 `suite.json` 中读取此信息。
+ 用于选择资源设备的参数。IDT 不会从 `test.json` 中读取此信息。

要调试您的测试套件，请完成以下步骤：

1.  创建运行测试套件所需的设置配置文件。例如，如果您的测试套件需要 `device.json`、`resource.json` 和 `user data.json`，请确保根据需要来配置所有测试套件。

1. 运行以下命令将 IDT 置于调试模式，然后选择运行测试需要的所有设备。

   ```
   devicetester_[linux | mac | win_x86-64] debug-test-suite [options]
   ```

   运行此命令后，IDT 会等待来自测试套件的请求，然后响应这些请求。IDT 还会生成 IDT 客户端软件开发工具包案例处理所需的环境变量。

1. 在您的 IDE 中，使用 `run` 或 `debug` 配置来执行以下操作：

   1. 设置 IDT 生成的环境变量的值。

   1. 设置您在 `test.json` 和 `suite.json` 文件中指定的任何环境变量或参数的值。

   1. 根据需要设置断点。

1. 在 IDE 中运行测试套件。

   您可以根据需要多次调试和重新运行测试套件。IDT 在调试模式下不会超时。

1.  完成调试后，请中断 IDT 以退出调试模式。

## 用于运行测试的 IDT CLI 命令
<a name="idt-cli-commands"></a>

以下小节介绍了 IDT CLI 命令。

------
#### [ IDT v4.0.0 ]

`help`  <a name="idt-command-help"></a>
列出有关指定命令的信息。

`list-groups`  <a name="idt-command-list-groups"></a>
列出给定测试套件中的组。

`list-suites`  <a name="idt-command-list-suites"></a>
列出可用的测试套件。

`list-supported-products`  
列出您的 IDT 版本支持的产品（在本例中为 AWS IoT Greengrass 版本），以及适用于当前 IDT 版本的 AWS IoT Greengrass 资格测试套件版本。

`list-test-cases`  
列出给定测试组中的测试用例。支持以下选项：  
+ `group-id`. 要搜索的测试组。此选项是必需的，必须指定单个组。

`run-suite`  
对某个设备池运行一组测试。以下是一些常用的选项：  
+ `suite-id`. 要运行的测试套件版本。如果未指定，IDT 将使用 `tests` 文件夹中的最新版本。
+ `group-id`. 要以逗号分隔的列表形式运行的测试组。如果未指定，IDT 将运行测试套件中的所有测试组。
+ `test-id`. 要以逗号分隔的列表形式运行的测试用例。指定后，`group-id` 必须指定单个组。
+ `pool-id`. 要测试的设备池。如果您在 `device.json` 文件中定义了多个设备池，则测试运行器必须指定一个池。
+ `timeout-multiplier`。将 IDT 配置为使用用户定义的乘数来修改 `test.json` 文件中为测试指定的测试执行超时。
+ `stop-on-first-failure`. 将 IDT 配置为在第一次失败时停止执行。应将此选项与 `group-id` 结合使用来调试指定的测试组。
+ `userdata`。设置包含运行测试套件所需用户数据信息的文件。只有在测试套件的 `suite.json` 文件中 `userdataRequired` 被设置为 true 时，才需要这样做。
有关 `run-suite` 选项的更多信息，请使用 `help` 选项：  

```
devicetester_[linux | mac | win_x86-64] run-suite -h
```

`debug-test-suite`  
在调试模式下运行测试套件。有关更多信息，请参阅 [在调试模式下运行 IDT](#idt-debug-mode)。

------

# 查看 IDT 测试结果和日志
<a name="idt-review-results-logs"></a>

本节介绍 IDT 生成控制台日志和测试报告的格式。

## 控制台消息格式
<a name="idt-console-format"></a>

AWS IoT Device Tester 在启动测试套件时使用标准格式将消息打印到控制台。以下摘录显示了一个由 IDT 生成的控制台消息示例。

```
time="2000-01-02T03:04:05-07:00" level=info msg=Using suite: MyTestSuite_1.0.0 
executionId=9a52f362-1227-11eb-86c9-8c8590419f30
```

大多数控制台消息都包含以下字段：

`time`  
所记录事件的完整 ISO 8601 时间戳。

`level`  
所记录事件的消息级别。通常，记录的消息级别为 `info`、`warn` 或 `error`。如果遇到导致其提前退出的预期事件，IDT 会发出 `fatal` 或 `panic` 消息。

`msg`  
记录的消息。

`executionId`  
当前 IDT 流程的唯一 ID 字符串。此 ID 用于区分各个 IDT 运行。

测试套件生成的控制台消息提供了有关被测设备以及 IDT 运行的测试套件、测试组和测试用例的更多信息。以下摘录显示了从测试套件生成的控制台消息的示例。

```
time="2000-01-02T03:04:05-07:00" level=info msg=Hello world! suiteId=MyTestSuite
groupId=myTestGroup testCaseId=myTestCase deviceId=my-device
executionId=9a52f362-1227-11eb-86c9-8c8590419f30
```

控制台消息中特定于测试套件的部分包含以下字段：

`suiteId`  
当前正在运行的测试套件的名称。

`groupId`  
当前正在运行的测试组的 ID。

`testCaseId`  
当前正在运行的测试用例的 ID。

`deviceId`  
当前测试用例正在使用的被测设备的 ID。

要在 IDT 完成测试运行后将测试摘要打印到控制台，您必须在状态机中包含一个[`Report` 状态](idt-state-machine.md#state-report)。测试摘要包含有关测试套件、每个已运行组的测试结果以及生成的日志和报告文件位置的信息。以下示例显示了测试摘要消息。

```
========== Test Summary ==========
Execution Time:     5m00s
Tests Completed:    4
Tests Passed:       3
Tests Failed:       1
Tests Skipped:      0
----------------------------------
Test Groups:
    GroupA:         PASSED
    GroupB:         FAILED
----------------------------------
Failed Tests:
    Group Name: GroupB
        Test Name: TestB1
            Reason: Something bad happened
----------------------------------
Path to IoT Device Tester Report: /path/to/awsiotdevicetester_report.xml
Path to Test Execution Logs: /path/to/logs
Path to Aggregated JUnit Report: /path/to/MyTestSuite_Report.xml
```

## AWS IoT 设备测试器报告架构
<a name="idt-report"></a>

 `awsiotdevicetester_report.xml` 是一份包含以下信息的签名报告：
+ IDT 版本。
+ 测试套件版本。
+ 用于对报告进行签名的报告签名和密钥。
+ `device.json` 文件中指定的设备 SKU 和设备池名称。
+ 经过测试的产品版本和设备功能。
+ 测试结果的摘要汇总。此信息与 `suite-name_report.xml` 文件中包含的信息相同。

```
<apnreport>
    <awsiotdevicetesterversion>idt-version</awsiotdevicetesterversion>
    <testsuiteversion>test-suite-version</testsuiteversion>
    <signature>signature</signature>
    <keyname>keyname</keyname>
    <session>
        <testsession>execution-id</testsession>
        <starttime>start-time</starttime>
        <endtime>end-time</endtime>
    </session>
    <awsproduct>
        <name>product-name</name>
        <version>product-version</version>
        <features>
            <feature name="<feature-name>" value="supported | not-supported | <feature-value>" type="optional | required"/>
        </features>
    </awsproduct>
    <device>
        <sku>device-sku</sku>
        <name>device-name</name>
        <features>
            <feature name="<feature-name>" value="<feature-value>"/>
        </features>
        <executionMethod>ssh | uart | docker</executionMethod>
    </device>
    <devenvironment>
        <os name="<os-name>"/>
    </devenvironment>
    <report>
        <suite-name-report-contents>
    </report>
</apnreport>
```

`awsiotdevicetester_report.xml` 文件包含一个 `<awsproduct>` 标签，其中包含有关正测试的产品以及在运行测试套件后验证的产品功能的信息。`<awsproduct>` 标签中使用的属性

`name`  
所测试的产品的名称。

`version`  
所测试的产品的版本。

`features`  
验证的功能。标记为 `required` 的功能是测试套件验证设备所必需的。以下代码段演示了此信息在 `awsiotdevicetester_report.xml` 文件中的显示方式。  

```
<feature name="ssh" value="supported" type="required"></feature>
```
标记为 `optional` 的功能不是验证所必需的。以下代码段显示了可选功能。  

```
<feature name="hsi" value="supported" type="optional"></feature> 
<feature name="mqtt" value="not-supported" type="optional"></feature>
```

## 测试套件报告架构
<a name="suite-report"></a>

该`suite-name_Result.xml`报告采用 [JUnit XML 格式](https://llg.cubic.org/docs/junit/)。您可以将它集成到持续集成和开发平台，例如 [Jenkins](https://jenkins.io/)、[Bamboo](https://www.atlassian.com/software/bamboo) 等。报告包含测试结果的摘要汇总。

```
<testsuites name="<suite-name> results" time="<run-duration>" tests="<number-of-test>" failures="<number-of-tests>" skipped="<number-of-tests>" errors="<number-of-tests>" disabled="0">
    <testsuite name="<test-group-id>" package="" tests="<number-of-tests>" failures="<number-of-tests>" skipped="<number-of-tests>" errors="<number-of-tests>" disabled="0">
        <!--success-->
        <testcase classname="<classname>" name="<name>" time="<run-duration>"/>
        <!--failure-->
        <testcase classname="<classname>" name="<name>" time="<run-duration>">
            <failure type="<failure-type>">
                reason
            </failure>
        </testcase>
        <!--skipped-->
        <testcase classname="<classname>" name="<name>" time="<run-duration>">
            <skipped>
                reason
            </skipped>
        </testcase>
        <!--error-->
        <testcase classname="<classname>" name="<name>" time="<run-duration>">
            <error>
                reason
            </error>
        </testcase>
    </testsuite>
</testsuites>
```

`awsiotdevicetester_report.xml` 或 `suite-name_report.xml` 中的报告部分列出了运行的测试以及结果。

第一个 XML 标签 `<testsuites>` 包含测试执行情况的摘要。例如：

```
<testsuites name="MyTestSuite results" time="2299" tests="28" failures="0" errors="0" disabled="0">
````<testsuites>` 标签中使用的属性

`name`  
测试套件的名称。

`time`  
运行测试套件所用的时间（以秒为单位）。

`tests`  
执行的测试数。

`failures`  
已运行但未通过的测试数。

`errors`  
IDT 无法执行的测试数。

`disabled`  
此属性未使用，可以忽略。

如果出现测试失败或错误，则可以通过检查 `<testsuites>` XML 标签来确定失败的测试。`<testsuites>` 标签内的 `<testsuite>` XML 标签显示了测试组的测试结果摘要。例如：

```
<testsuite name="combination" package="" tests="1" failures="0" time="161" disabled="0" errors="0" skipped="0">
```

其格式与 `<testsuites>` 标签类似，但包含一个未使用并可忽略的 `skipped` 属性。在每个 `<testsuite>` XML 标签内部，对于一个测试组，所执行的每个测试都有 `<testcase>` 标签。例如：

```
<testcase classname="Security Test" name="IP Change Tests" attempts="1"></testcase>>
````<testcase>` 标签中使用的属性

`name`  
测试的名称。

`attempts`  
IDT 执行测试用例的次数。

当测试失败或出现错误时，将会在 `<testcase>` 标签中添加包含用于故障排除的信息的 `<failure>` 或 `<error>` 标签。例如：

```
<testcase classname="mcu.Full_MQTT" name="MQTT_TestCase" attempts="1">
	<failure type="Failure">Reason for the test failure</failure>
	<error>Reason for the test execution error</error>
</testcase>
```

# IDT 使用量指标
<a name="idt-usage-metrics"></a>

如果您提供具有所需权限的 AWS 凭证， AWS IoT 设备测试人员会收集使用情况指标并将其提交给 AWS。这是一项可选功能，用来改进 IDT 功能。IDT 将收集以下信息：
+ 用于运行 AWS 账户 IDT 的 ID
+  用于运行测试的 IDT CLI 命令
+ 正在运行的测试套件
+ *<device-tester-extract-location>*文件夹中的测试套件
+ 设备池中配置的设备数量
+ 测试用例名称和运行时间
+ 测试结果信息，例如测试是通过、失败、遇到错误，还是已被跳过
+ 测试的产品功能
+ IDT 退出行为，例如意外退出或提前退出 

 IDT 发送的所有信息也会记录到 `<device-tester-extract-location>/results/<execution-id>/` 文件夹下的 `metrics.log` 文件中。您可以查看日志文件以检查在测试运行期间收集的信息。只有选择了收集使用量指标后，才会生成此文件。

要禁用指标收集，您无需采取其他操作。请不要存储您的 AWS 凭据，如果您确实存储了 AWS 凭据，也不要将 `config.jso` n 文件配置为访问它们。

## 配置您的 AWS 凭证
<a name="configure-aws-creds-for-metrics"></a>

如果您还没有 AWS 账户，则必须[创建一个](#idt-metrics-aws-account)。如果您已经拥有 AWS 账户，则只需为您的账户[配置所需的权限](#idt-metrics-permissions)，以允许 IDT 代表您向其发送使用量指标。 AWS 

### 步骤 1：创建一个 AWS 账户
<a name="idt-metrics-aws-account"></a>

在此步骤中，将创建并配置 AWS 账户。如果您已经有 AWS 账户，请跳至[步骤 2：为 IDT 配置权限](#idt-metrics-permissions)。

#### 注册获取 AWS 账户
<a name="sign-up-for-aws"></a>

如果您没有 AWS 账户，请完成以下步骤来创建一个。

**报名参加 AWS 账户**

1. 打开[https://portal.aws.amazon.com/billing/注册。](https://portal.aws.amazon.com/billing/signup)

1. 按照屏幕上的说明操作。

   在注册时，将接到电话或收到短信，要求使用电话键盘输入一个验证码。

   当您注册时 AWS 账户，就会创建*AWS 账户根用户*一个。根用户有权访问该账户中的所有 AWS 服务 和资源。作为最佳安全实践，请为用户分配管理访问权限，并且只使用根用户来执行[需要根用户访问权限的任务](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_root-user.html#root-user-tasks)。

AWS 注册过程完成后会向您发送一封确认电子邮件。您可以随时前往 [https://aws.amazon.com/](https://aws.amazon.com/)并选择 “**我的账户”，查看您当前的账户活动并管理您的账户**。

#### 创建具有管理访问权限的用户
<a name="create-an-admin"></a>

注册后，请保护您的安全 AWS 账户 AWS 账户根用户 AWS IAM Identity Center，启用并创建管理用户，这样您就不会使用 root 用户执行日常任务。

**保护你的 AWS 账户根用户**

1.  选择 **Root 用户**并输入您的 AWS 账户 电子邮件地址，以账户所有者的身份登录。[AWS 管理控制台](https://console.aws.amazon.com/)在下一页上，输入您的密码。

   要获取使用根用户登录方面的帮助，请参阅《AWS 登录 用户指南》**中的 [Signing in as the root user](https://docs.aws.amazon.com/signin/latest/userguide/console-sign-in-tutorials.html#introduction-to-root-user-sign-in-tutorial)。

1. 为您的根用户启用多重身份验证（MFA）。

   有关说明，请参阅 I [A *M* 用户指南中的为 AWS 账户 根用户启用虚拟 MFA 设备（控制台）](https://docs.aws.amazon.com/IAM/latest/UserGuide/enable-virt-mfa-for-root.html)。

**创建具有管理访问权限的用户**

1. 启用 IAM Identity Center。

   有关说明，请参阅**《AWS IAM Identity Center 用户指南》中的[启用 AWS IAM Identity Center](https://docs.aws.amazon.com//singlesignon/latest/userguide/get-set-up-for-idc.html)。

1. 在 IAM Identity Center 中，为用户授予管理访问权限。

   有关使用 IAM Identity Center 目录 作为身份源的教程，请参阅《[用户*指南》 IAM Identity Center 目录中的使用默认设置配置AWS IAM Identity Center 用户*访问权限](https://docs.aws.amazon.com//singlesignon/latest/userguide/quick-start-default-idc.html)。

**以具有管理访问权限的用户身份登录**
+ 要使用您的 IAM Identity Center 用户身份登录，请使用您在创建 IAM Identity Center 用户时发送到您的电子邮件地址的登录 URL。

  有关使用 IAM Identity Center 用户[登录的帮助，请参阅*AWS 登录 用户指南*中的登录 AWS 访问门户](https://docs.aws.amazon.com/signin/latest/userguide/iam-id-center-sign-in-tutorial.html)。

**将访问权限分配给其他用户**

1. 在 IAM Identity Center 中，创建一个权限集，该权限集遵循应用最低权限的最佳做法。

   有关说明，请参阅《AWS IAM Identity Center 用户指南》**中的 [Create a permission set](https://docs.aws.amazon.com//singlesignon/latest/userguide/get-started-create-a-permission-set.html)。

1. 将用户分配到一个组，然后为该组分配单点登录访问权限。

   有关说明，请参阅《AWS IAM Identity Center 用户指南》**中的 [Add groups](https://docs.aws.amazon.com//singlesignon/latest/userguide/addgroups.html)。

### 步骤 2：为 IDT 配置权限
<a name="idt-metrics-permissions"></a>

在此步骤中，将配置 IDT 运行测试和收集 IDT 使用情况数据所需的权限。您可以使用 AWS 管理控制台 或 AWS Command Line Interface (AWS CLI) 为 IDT 创建 IAM 策略和用户，然后将策略附加到该用户。
+ [为 IDT 配置权限（控制台）](#idt-metrics-permissions-console)
+ [为 IDT 配置权限 (AWS CLI)](#idt-metrics-permissions-cli)<a name="idt-metrics-permissions-console"></a>

**为 IDT 配置权限（控制台）**

请按照以下步骤使用控制台为 IDT for AWS IoT Greengrass配置权限。

1. 登录 [IAM 控制台](https://console.aws.amazon.com/iam)。

1. 创建客户托管策略，该策略授权创建具有特定权限的角色。

   1. 在导航窗格中，选择 **策略**，然后选择 **创建策略**。

   1. 在 **JSON** 选项卡中，将占位符内容替换为以下策略。

------
#### [ JSON ]

****  

      ```
      {
          "Version":"2012-10-17",		 	 	 
          "Statement": [
              {
                  "Effect": "Allow",
                  "Action": [
                      "iot-device-tester:SendMetrics"
                  ],
                  "Resource": "*"
              }
          ]
      }
      ```

------

   1. 选择**下一步：标签**。

   1. 选择**下一步：审核**。

   1. 对于**名称**，请输入 **IDTUsageMetricsIAMPermissions**。在 **Summary (摘要)** 下，查看策略授予的权限。

   1. 选择**创建策略**。

1. 创建 IAM 用户并将权限附加到该用户。

   1. 创建 IAM 用户。按照 *IAM 用户指南*的[创建 IAM 用户（控制台）](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_users_create.html#id_users_create_console)中的步骤 1 到 5 操作。如果您已创建 IAM 用户，请跳到下一步。

   1. 将权限附加到您的 IAM 用户：

      1. 在 **设置权限** 页面上，选择 **直接附加现有策略**。

      1. 搜索您在上一步中创建的**IDTUsage指标IAMPermissions**策略。选中复选框。

   1. 选择**下一步：标签**。

   1. 选择 **Next: Review (下一步：审核)** 以查看您的选择摘要。

   1. 选择**创建用户**。

   1. 要查看用户的访问密钥（访问密钥 IDs 和私有访问密钥），请选择密码和访问密钥旁边的**显示**。要保存访问密钥，请选择**Download.csv (下载 .csv)**，然后将文件保存到安全位置。您稍后将使用此信息来配置您的 AWS 凭证文件。

 <a name="idt-metrics-permissions-cli"></a>

**为 IDT 配置权限 (AWS CLI)**

按照以下步骤 AWS CLI 使用配置 IDT 的 AWS IoT Greengrass权限。如果您已在控制台中配置权限，请跳转至 [配置设备以运行 IDT 测试](device-config-setup.md) 或 [可选：为 IDT 配置你的 Docker 容器 AWS IoT Greengrass](docker-config-setup.md)。

1.  AWS CLI 如果尚未安装，请在您的计算机上进行安装和配置。按照《AWS Command Line Interface 用户指南》**中[安装 AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-install.html) 的步骤来操作。
**注意**  
 AWS CLI 是一个开源工具，可用于通过命令行 shell 与 AWS 服务进行交互。

1. 创建以下客户托管策略，授予管理 IDT 和 AWS IoT Greengrass 角色的权限。

------
#### [ Linux, macOS, or Unix ]

   ```
   aws iam create-policy --policy-name IDTUsageMetricsIAMPermissions --policy-document '{
       "Version": "2012-10-17",		 	 	 
       "Statement": [
           {
               "Effect": "Allow",
               "Action": [
                   "iot-device-tester:SendMetrics"
               ],
               "Resource": "*"
           }
       ]
   }'
   ```

------
#### [ Windows command prompt ]

   ```
   aws iam create-policy --policy-name IDTUsageMetricsIAMPermissions --policy-document
                                           '{\"Version\": \"2012-10-17\",		 	 	  \"Statement\": [{\"Effect\": \"Allow\", \"Action\": [\"iot-device-tester:SendMetrics\"], \"Resource": \"*\"}]}'
   ```

**注意**  
此步骤包含一个 Windows 命令提示符示例，因为它使用的 JSON 语法与 Linux、macOS 或 Unix 终端命令不同。

------

1. 创建 IAM 用户并附加适用于 AWS IoT Greengrass的 IDT 所需的权限。

   1. 创建 IAM 用户。

      ```
      aws iam create-user --user-name user-name
      ```

   1. 将您创建的 `IDTUsageMetricsIAMPermissions` 策略附加到 IAM 用户。*user-name*替换为您的 IAM 用户名，*<account-id>*在命令中替换为您的 ID AWS 账户。

      ```
      aws iam attach-user-policy --user-name user-name --policy-arn arn:aws:iam::<account-id>:policy/IDTGreengrassIAMPermissions
      ```

1. 为用户创建私密访问密钥。

   ```
   aws iam create-access-key --user-name user-name
   ```

   将输出存储在安全位置。您稍后将使用此信息来配置您的 AWS 凭证文件。

## 向 ID AWS T 提供凭证
<a name="idt-metrics-creds"></a>

要允许 IDT 访问您的 AWS 凭证并向其提交指标 AWS，请执行以下操作：

1. 将您的 IAM 用户的 AWS 证书存储为环境变量或存储在证书文件中：

   1. 要使用环境变量，请运行以下命令：

      ```
      AWS_ACCESS_KEY_ID=access-key
      AWS_SECRET_ACCESS_KEY=secret-access-key
      ```

   1. 要使用凭证文件，请将以下信息添加到 `.aws/credentials file:`：

      ```
      [profile-name]
      aws_access_key_id=access-key
      aws_secret_access_key=secret-access-key
      ```

1. 配置 `config.json` 文件的 `auth` 部分。有关更多信息，请参阅 [（可选）配置 config.json](set-config-custom.md#config-json-custom)。

# 用于故障排除的 IDT AWS IoT Greengrass
<a name="idt-troubleshooting"></a>

IDT fo AWS IoT Greengrass r 根据错误的类型将这些错误写入不同的位置。错误将被写入到控制台、日志文件和测试报告。

## 错误代码
<a name="bk-error-codes"></a>

下表列出了由适用于 AWS IoT Greengrass的 IDT 生成的错误代码。


| 错误代码 | 错误代码名称 | 可能的根本原因 | 故障排查 | 
| --- | --- | --- | --- | 
|  101  |  InternalError  |  出现内部错误。  |  检查 `<device-tester-extract-location>/results` 目录下的日志。如果您无法调试该问题，请联系 [AWS 开发人员支持](https://aws.amazon.com/premiumsupport/plans/developers/)。  | 
|  102  |  TimeoutError  |  测试无法在限定的时间范围内完成。在以下条件下会出现这种情况： [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/greengrass/v1/developerguide/idt-troubleshooting.html)  |  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/greengrass/v1/developerguide/idt-troubleshooting.html)  | 
|  103  |  PlatformNotSupportError  |  `device.json` 中指定的操作系统/架构组合不正确。  |  将您的配置更改为支持的组合之一： [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/greengrass/v1/developerguide/idt-troubleshooting.html) 有关更多信息，请参阅 [配置 device.json](set-config.md#device-config)。  | 
|  104  |  VersionNotSupportError  |  您正在使用的 IDT 版本不支持 AWS IoT Greengrass 核心软件版本。  |  使用**device\$1tester\$1bin version**命令查找 C AWS IoT Greengrass ore 软件支持的版本。例如，如果您使用的是 macOS，请使用 **./devicetester\$1mac\$1x86\$164 version**。 要查找您正在使用的 AWS IoT Greengrass 酷睿软件版本，请执行以下操作： [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/greengrass/v1/developerguide/idt-troubleshooting.html) 您可以测试不同版本的 AWS IoT Greengrass Core 软件。有关更多信息，请参阅 [入门 AWS IoT Greengrass](gg-gs.md)。  | 
|  105  |  LanguageNotSupportError  |  IDT SDKs 仅在 AWS IoT Greengrass 库中支持 Python。  |  确保： [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/greengrass/v1/developerguide/idt-troubleshooting.html)  | 
|  106  |  ValidationError  |  `device.json` 或 `config.json` 中的有些字段无效。  |  检查报告中错误代码右侧的错误消息。 [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/greengrass/v1/developerguide/idt-troubleshooting.html)  | 
|  107  |  SSHConnection失败了  |  测试计算机无法连接到已配置的设备。  |  验证 `device.json` 文件中的以下字段是否正确： [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/greengrass/v1/developerguide/idt-troubleshooting.html) 有关更多信息，请参阅 [配置 device.json](set-config.md#device-config)。  | 
|  108  |  RunCommandError  |  测试在测试中的设备上执行命令失败。  |  验证是否允许在 `device.json` 中配置的用户拥有根访问权限。 当通过根访问权限执行命令时，某些设备需要密码。确保在使用不密码的情况下允许获得根访问权限。有关更多信息，请参阅设备的文档。 尝试在您的设备上手动运行失败的命令以查看是否发生错误。  | 
|  109  |  PermissionDeniedError  |  无根访问权限。  |  在您的设备上为配置的用户设置根访问权限。  | 
|  110  |  CreateFileError  |  无法创建文件。  |  检查您设备的磁盘空间和目录权限。  | 
|  111  |  CreateDirError  |  无法创建目录。  |  检查您设备的磁盘空间和目录权限。  | 
|  112  |  InvalidPathError  |   AWS IoT Greengrass Core 软件的路径不正确。  |  验证错误消息中的路径是有效的。请勿编辑 `devicetester_greengrass_<os>` 目录下的任何文件。  | 
|  113  |  InvalidFileError  |  文件无效。  |  验证错误消息中的文件是否有效。  | 
|  114  |  ReadFileError  |  无法读取指定的文件。  |  请验证以下内容： [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/greengrass/v1/developerguide/idt-troubleshooting.html) 如果您正在 macOS 上进行测试，请增加打开文件数量限制。默认限制为 256，这足够用于测试。  | 
|  115  |  FileNotFoundError  |  找不到所需的文件。  |  请验证以下内容： [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/greengrass/v1/developerguide/idt-troubleshooting.html)  | 
|  116  |  OpenFileFailed  |  无法打开指定的文件。  |  请验证以下内容： [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/greengrass/v1/developerguide/idt-troubleshooting.html) 如果您正在 macOS 上进行测试，请增加打开文件数量限制。默认限制为 256，这足够用于测试。  | 
|  117  |  WriteFileFailed  |  无法写入文件（可以是 DUT 或测试机）。  |  验证错误消息中指定的目录是否存在，并且您是否具有写入权限。  | 
|  118  |  FileCleanUpError  |  测试未能删除指定的文件或目录，或未能在远程设备上卸载指定的文件。  |  如果二进制文件仍在运行，则文件可能被锁定。结束进程并删除指定的文件。  | 
|  119  |  InvalidInputError  |  配置无效。  |  验证 `suite.json` 文件是否有效。  | 
|  120  |  InvalidCredentialError  |   AWS 凭证无效。  |  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/greengrass/v1/developerguide/idt-troubleshooting.html)  | 
|  121  |  AWSSession错误  |  创建会 AWS 话失败。  |  如果 AWS 凭证无效或互联网连接不稳定，则可能会发生此错误。尝试使用 AWS CLI 调用 AWS API 操作。  | 
|  122  |  AWSApiCallError  |  出现了 AWS API 错误。  |  此错误可能是由于网络问题导致的。检查您的网络，然后重试测试组。  | 
|  123  |  IpNotExistError  |  IP 地址未包含在连接信息中。  |  检查您的 Internet 连接。您可以使用 AWS IoT Greengrass 控制台检查测试使用的 AWS IoT Greengrass 核心设备的连接信息。如果连接信息中包含 10 个端点，则您可以删除部分或所有端点并重新运行测试。有关更多信息，请参阅[连接信息](https://docs.aws.amazon.com/cli/latest/reference/greengrass/get-connectivity-info.html)。  | 
|  124  |  OTAJobNotCompleteError  |  一个 OTA 作业未完成。  |  检查您的 Internet 连接并重试 OTA 测试组。  | 
|  125  |  CreateGreengrassServiceRoleError  |  发生了以下错误之一： [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/greengrass/v1/developerguide/idt-troubleshooting.html)  |  配置 AWS IoT Greengrass 服务角色。有关更多信息，请参阅 [Greengrass 服务角色](service-role.md)。  | 
|  126  |  DependenciesNotPresentError  |  设备上不存在特定测试所需的一个或多个依赖项。  |  检查测试日志以查看该设备上缺少哪些依赖项：`<device-tester-extract-location>/results/<execution-id>/logs/<test-case-name.log>`  | 
|  127  |  无效 HSMConfiguration  |  提供的 HSM/PKCS 配置不正确。  |  在 `device.json` 文件中，提供使用 PKCS＃11 与 HSM 交互所需的配置。  | 
|  128  |  OTAJobNotSuccededError  |  该 OTA 作业没有获得成功。  |  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/greengrass/v1/developerguide/idt-troubleshooting.html)  | 
|  129  |  NoConnectivityError  |  主机代理无法连接到 Internet。  |  请检查您的网络连接和防火墙设置。连接问题得到解决后，重试此测试组。  | 
|  130  |  NoPermissionError  |  您用于运行 IDT 的 IAM 用户 AWS IoT Greengrass 无权创建运行 IDT 所需的 AWS 资源。  |  请参阅[权限策略模板](https://docs.aws.amazon.com/greengrass/latest/developerguide/policy-template.html)，以了解授予运行适用于 AWS IoT Greengrass的 IDT 所需的权限的策略模板。  | 
|  131  |  LeftoverAgentExistError  |  当您尝试启动 IDT 时，您的设备正在运行 AWS IoT Greengrass 进程。 AWS IoT Greengrass  |  确保您的设备上没有正在运行的 Greengrass 守护程序。 [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/greengrass/v1/developerguide/idt-troubleshooting.html)  如果您使用的是 AWS IoT Greengrass 配置为在重新启动后自动启动的现有安装，则必须在重新启动后和运行测试套件之前停止守护程序。   | 
|  132  |  DeviceTimeOffsetError  |  设备的时间不正确。  |  将设备设置为正确的时间。  | 
|  133  |  无效 MLConfiguration  |  提供的 ML 配置不正确。  |  在 `device.json` 文件中，提供运行 ML 推理测试所需的正确配置。有关更多信息，请参阅 [可选：配置设备进行 ML 资格认证](idt-ml-qualification.md)。  | 

## 解决 IDT 中的错误 AWS IoT Greengrass
<a name="idt-gg-resolve-errors"></a>

使用 IDT 时，必须先准备好正确的配置文件，然后才能运行 IDT。 AWS IoT Greengrass如果出现解析和配置错误，第一步应找到并使用适合您的环境的配置模板。

如果仍有问题，请参阅以下调试过程。

**Topics**
+ [应该在哪里寻找错误？](#where-to-look)
+ [解析错误](#parse-error)
+ [缺少必需参数错误](#param-missing)
+ [无法启动测试错误](#could-not-start-test)
+ [无权访问资源错误](#not-authorized-to-access-resource)
+ [权限被拒绝错误](#pwd-sudo)
+ [SSH 连接错误](#ssh-connect-errors)
+ [超时错误](#test-timeout)
+ [测试时出现找不到命令错误](#cmd-not-found)
+ [macOS 上的安全例外](#macos-notarization-exception)

### 应该在哪里寻找错误？
<a name="where-to-look"></a>

在执行期间，控制台上会显示高级别错误，并且在所有测试完成后会显示失败测试及其错误的摘要。`awsiotdevicetester_report.xml` 包含导致测试失败的所有错误的摘要。每次测试运行的日志文件都存储在一个以 UUID 命名的目录中，用于在测试运行期间在控制台上显示的测试执行。

测试日志目录位于 `<device-tester-extract-location>/results/<execution-id>/logs/`。此目录包含以下对调试有用的文件。


| 文件 | 描述 | 
| --- | --- | 
| test\$1manager.log |  在测试执行期间写入控制台的所有日志。结果的摘要位于该文件的末尾，其中包含失败的测试的列表。 此文件中的警告和错误日志可以为您提供有关失败的一些信息。  | 
| <test-group-id>\$1\$1<test-name>.log | 特定测试的详细日志。 | 
| <test-name>\$1ggc\$1logs.tar.gz |  AWS IoT Greengrass 核心守护程序在测试期间生成的所有日志的压缩集合。有关更多信息，请参阅[故障排除 AWS IoT Greengrass](https://docs.aws.amazon.com/greengrass/latest/developerguide/gg-troubleshooting.html)。 | 
| <test-name>\$1ota\$1logs.tar.gz |  AWS IoT Greengrass OTA 代理在测试期间生成的压缩日志集合。仅适用于 OTA 测试。 | 
| <test-name>\$1basic\$1assertion\$1publisher\$1ggad\$1logs.tar.gz | 测试期间由 AWS IoT 发布者设备生成的日志的压缩集合。 | 
| <test-name>\$1basic\$1assertion\$1subscriber\$1ggad\$1logs.tar.gz | 测试期间由 AWS IoT 订阅者设备生成的日志的压缩集合。 | 

### 解析错误
<a name="parse-error"></a>

有时候，JSON 配置中的输入错误会导致解析错误。大部分情况下，问题是因 JSON 文件中漏掉括号、逗号或引号所导致。IDT 执行 JSON 验证并输入调试信息。它输出发生错误的行、行号以及语法错误的列号。这些信息应该足以帮助您修复错误，但是如果您仍然无法找到错误，则可以在IDE、Atom或Sublime等文本编辑器中手动进行验证，也可以通过诸如此类的在线工具进行验证。 JSONLint

### 缺少必需参数错误
<a name="param-missing"></a>

由于将新功能添加到 IDT 中，可能会对配置文件进行更改。使用旧配置文件可能会破坏您的配置。如果出现这种情况，`/results/<execution-id>/logs` 下的 `<test_case_id>.log` 文件明确列出了所有缺少的参数。IDT 还将验证 JSON 配置文件架构，以确保使用支持的最新版本。

### 无法启动测试错误
<a name="could-not-start-test"></a>

在测试启动期间，您可能遇到指示失败的错误。有几种可能的原因，因此，请执行以下操作：
+ 确保包含在执行命令中的池名称实际存在。池名称将从您的 `device.json` 文件中直接引用。
+ 确保池中的设备具有正确的配置参数。

### 无权访问资源错误
<a name="not-authorized-to-access-resource"></a>

您可能会在终端输出或 `/results/<execution-id>/logs` 下的 `test_manager.log` 文件中看到 `<user or role> is not authorized to access this resource` 错误消息。要解决此问题，请将 `AWSIoTDeviceTesterForGreengrassFullAccess` 托管策略附加到您的测试用户。有关更多信息，请参阅 [创建和配置 AWS 账户](dev-tst-prereqs.md#config-aws-account-for-idt)。

### 权限被拒绝错误
<a name="pwd-sudo"></a>

IDT 将对被测设备中的各种目录和文件执行操作。其中一些操作需要根用户访问权限。要自动执行这些操作，IDT 必须能够在不键入密码的情况下使用 sudo 运行命令。

请按照以下步骤操作，以允许在不键入密码的情况下进行 sudo 访问。

**注意**  
`user` 和 `username` 是指 IDT 用来访问所测试设备的 SSH 用户。

1. 使用 **sudo usermod -aG sudo *<ssh-username>*** 将 SSH 用户添加到 sudo 组。

1. 注销，然后重新登录，以使更改生效。

1. 打开 `/etc/sudoers` 文件，并将以下行添加到文件末尾：`<ssh-username> ALL=(ALL) NOPASSWD: ALL`
**注意**  
作为最佳实践，我们建议您在编辑 `/etc/sudoers` 时使用 **sudo visudo**。

### SSH 连接错误
<a name="ssh-connect-errors"></a>

当 IDT 无法连接到所测试设备时，会在 `/results/<execution-id>/logs/<test-case-id>.log` 中记录连接失败。SSH 失败消息将显示在此日志文件的顶部，因为连接到所测试设备是 IDT 最先执行的操作之一。

大多数 Windows 设置使用 Pu TTy 终端应用程序连接到 Linux 主机。该应用程序要求将标准 PEM 私有密钥文件转换为称为 PPK 的专有 Windows 格式。在 `device.json` 文件中配置 IDT 时，仅使用 PEM 文件。如果您使用 PPK 文件，IDT 将无法与 AWS IoT Greengrass 设备建立 SSH 连接，也无法运行测试。

### 超时错误
<a name="test-timeout"></a>

您可以通过指定超时乘数来增加每个测试的超时，该超时乘数应用于每个测试超时的默认值。为此标志配置的任何值都必须大于或等于 1.0。

要使用超时乘数，请在运行测试时使用标志 `--timeout-multiplier`。例如：

```
./devicetester_linux run-suite --suite-id GGQ_1.0.0 --pool-id DevicePool1 --timeout-multiplier 2.5
```

有关更多信息，请运行 `run-suite --help`。

### 测试时出现找不到命令错误
<a name="cmd-not-found"></a>

你需要旧版本的 OpenSSL 库 (libssl1.0.0) 才能在设备上运行测试。 AWS IoT Greengrass 当前的大多数 Linux 发行版都使用 libssl 1.0.2 或更高版本 (v1.1.0)。

例如，在 Raspberry Pi 上，可以运行以下命令来安装所需的 libssl 版本：

1. 

   ```
   wget http://ftp.us.debian.org/debian/pool/main/o/openssl/libssl1.0.0_1.0.2l-1~bpo8+1_armhf.deb
   ```

1. 

   ```
   sudo dpkg -i libssl1.0.0_1.0.2l-1~bpo8+1_armhf.deb
   ```

### macOS 上的安全例外
<a name="macos-notarization-exception"></a>

当在使用 macOS 10.15 的主机上运行 IDT 时，系统无法正确检测到 IDT 的公证票证，而且 IDT 也会被阻止运行。要运行 IDT，您需要为 `devicetester_mac_x86-64` 可执行文件授予安全例外。

**为 IDT 可执行文件授予安全例外**

1. 从 Apple 菜单中启动**系统偏好设置**。

1. 选择 **安全与隐私**，然后在**通用**选项卡上，单击小锁图标以更改安全设置。

1. 查找以下消息并选择**仍然允许**：`"devicetester_mac_x86-64" was blocked from use because it is not from an identified developer.`。

1. 接受安全警告。

如果您对 IDT 支持策略有疑问，请联系 [AWS 客户支持](https://aws.amazon.com/contact-us/)。

# AWS IoT 设备测试器的 Support 政策 AWS IoT Greengrass V1
<a name="idt-support-policy"></a>

AWS IoT Device Tester (IDT) AWS IoT Greengrass 是一个可下载的测试框架，它允许您验证和[确认](https://aws.amazon.com/partners/dqp/)您的 AWS IoT Greengrass 设备是否包含在[AWS Partner 设备](https://devices.amazonaws.com/)目录中。我们建议您使用最新版本的 AWS IoT Greengrass 和 IDT 来测试或鉴定您的设备。有关更多信息，请参阅 *AWS IoT Greengrass Version 2 开发人员指南*中的[支持的适用于 AWS IoT Greengrass V2的 IDT 版本](https://docs.aws.amazon.com/greengrass/v2/developerguide/dev-test-versions.html)。

您也可以使用任何支持的版本 AWS IoT Greengrass 和 IDT 来测试或鉴定您的设备。尽管您可以继续使用[不受支持的 IDT 版本](dev-test-versions.md#idt-unsupported-versions)，但这些版本不会收到错误修复或更新。

**重要**  
自 2022 年 4 月 4 日起，的 AWS IoT 设备测试器 (IDT) AWS IoT Greengrass V1 不再生成签名的资格报告。您不能再通过 AWS IoT Greengrass V1 设备资格[认证计划将新AWS Partner 设备列入 “AWS 设备](https://aws.amazon.com/partners/programs/dqp/)[目录”](https://devices.amazonaws.com/)。虽然你无法获得 Greengrass V1 设备的资格，但你可以继续使用 IDT 来测试你的 Greengrass V1 设备。 AWS IoT Greengrass V1 我们建议您使用[适用于 AWS IoT Greengrass V2的 IDT](https://docs.aws.amazon.com/greengrass/v2/developerguide/device-tester-for-greengrass-ug.html) 来进行资格认证并在 [AWS Partner 设备目录](https://devices.amazonaws.com/)中列示 Greengrass 设备。

如果您对支持策略有疑问，请联系 [AWS 客户支持](https://aws.amazon.com/contact-us/)。