

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

# MQTT
<a name="device-advisor-tests-mqtt"></a>

## CONNECT、DISCONNECT 和 RECONNECT
<a name="connect"></a>

**“设备发送 CONNECT 到 Amazon IoT Core （Happy case）”**  <a name="MQTT_Connect"></a>
验证被测设备是否发送 CONNECT 请求。  
*API 测试用例定义：*  
`EXECUTION_TIMEOUT` 的默认值为 5 分钟。我们建议将超时值设置为 2 分钟。

```
"tests":[
   {
      "name":"my_mqtt_connect_test",
      "configuration": {
         // optional:
         "EXECUTION_TIMEOUT":"300",   // in seconds
      },
      "test":{
         "id":"MQTT_Connect",
         "version":"0.0.0"
      }
   }
]
```

**“设备可以将 PUBACK 返回到 QoS1 的任意主题”**  
如果客户端在使用 QoS1 订阅到主题后收到来自代理的发布消息，则此测试案例将检查设备（客户端）是否能够返回 PUBACK 消息。  
可针对此测试使用案例配置有效载荷内容和有效载荷大小。如果配置了有效载荷大小，Device Advisor 将覆盖有效载荷内容的值，并将预定义的具有所需大小的有效载荷发送到设备。有效载荷大小的值介于 0 到 128 之间，不能超过 128KB。 Amazon IoT Core 拒绝大于 128KB 的发布和连接请求，如 [Amazon IoT Core 消息代理及协议限制和限额](https://docs.amazonaws.cn/general/latest/gr/iot-core.html#message-broker-limits)页面所示。  
*API 测试用例定义：*  
`EXECUTION_TIMEOUT` 的默认值为 5 分钟。我们建议超时值为 2 分钟。`PAYLOAD_SIZE` 可以配置为 0 到 128KB 之间的值。定义有效载荷大小会覆盖有效载荷内容，因为 Device Advisor 会将具有给定大小的预定义有效载荷发送回设备。

```
"tests":[                            
{
        "name":"my_mqtt_client_puback_qos1",
        "configuration": {
            // optional:"TRIGGER_TOPIC": "myTopic",
            "EXECUTION_TIMEOUT":"300", // in seconds
            "PAYLOAD_FOR_PUBLISH_VALIDATION":"custom payload",
            "PAYLOAD_SIZE":"100" // in kilobytes
        },
        "test": {
            "id": "MQTT_Client_Puback_QoS1",
            "version": "0.0.0"
        }
    }
]
```

**“设备以抖动退避功能重新连接 - 没有 CONNACK 响应”**  <a name="MQTT_ConnectJitterBackoff"></a>
验证被测设备与代理重新连接至少五次时是否使用了正确的抖动退避。代理记录被测设备的 CONNECT 请求时间戳，执行数据包验证，暂停而不向被测设备发送 CONNACK，并等待被测设备重新发送请求。允许第六次连接尝试通过，并允许 CONNACK 流回到被测设备。  
将再次执行上述过程。总体而言，此测试使用案例要求设备总共至少连接 12 次。收集的时间戳用于验证被测设备是否使用了抖动退避。如果被测设备具有严格的指数退避延迟，则此测试使用案例将通过但带有警告。  
我们建议实施[指数退避和抖动](https://www.amazonaws.cn/blogs//architecture/exponential-backoff-and-jitter/)在所测试设备上的机制通过此测试案例。  
*API 测试用例定义：*  
`EXECUTION_TIMEOUT` 的默认值为 5 分钟。我们建议将超时值设置为 4 分钟。

```
"tests":[
   {
      "name":"my_mqtt_jitter_backoff_retries_test",
      "configuration": {
         // optional:
         "EXECUTION_TIMEOUT":"300",    // in seconds
      },
      "test":{
         "id":"MQTT_Connect_Jitter_Backoff_Retries",
         "version":"0.0.0"
      }
   }
]
```

**“设备使用指数退避重新连接 - 没有 CONNACK 响应”**  
验证被测设备与代理重新连接至少五次时是否使用了正确的指数退避。代理记录被测设备的 CONNECT 请求时间戳，执行数据包验证，暂停而不向客户端设备发送 CONNACK，并等待被测设备重新发送请求。收集的时间戳用于验证被测设备是否使用了指数退避。  
我们建议实施[指数退避和抖动](https://www.amazonaws.cn/blogs//architecture/exponential-backoff-and-jitter/)在所测试设备上的机制通过此测试案例。  
*API 测试用例定义：*  
`EXECUTION_TIMEOUT` 的默认值为 5 分钟。我们建议将超时值设置为 4 分钟。

```
"tests":[
   {
      "name":"my_mqtt_exponential_backoff_retries_test",
      "configuration": {
         // optional:
         "EXECUTION_TIMEOUT":"600",  // in seconds
      },
      "test":{
         "id":"MQTT_Connect_Exponential_Backoff_Retries",
         "version":"0.0.0"
      }
   }
]
```

**“使用抖动退避重新连接设备-服务器断开连接后”**  
验证正在测试的设备在与服务器断开连接后重新连接时是否使用必要的抖动和回退。Device Advisor 至少将设备与服务器断开五次，并观察设备的 MQTT 重新连接的行为。Device Advisor 记录被测设备的连接请求的时间戳，执行数据包验证，暂停而不向客户端设备发送连接，并等待被测设备重新发送请求。收集的时间戳用于验证被测设备在重新连接时是否使用抖动和退避。如果被测设备具有严格的指数退避或未实现适当的抖动退避机制，此测试用例将通过但是带有警告。如果被测设备实施了线性退避或恒定退避机制，测试将失败。  
要通过此测试用例，我们建议在所测试设备上实施[指数退避和抖动](https://www.amazonaws.cn/blogs//architecture/exponential-backoff-and-jitter/)机制。  
*API 测试用例定义：*  
`EXECUTION_TIMEOUT` 的默认值为 5 分钟。我们建议将超时值设置为 4 分钟。  
通过指定 `RECONNECTION_ATTEMPTS`，可以更改验证退避的重新连接尝试次数。该数字必须介于 5 到 10 之间。默认值是 5。

```
"tests":[
   {
      "name":"my_mqtt_reconnect_backoff_retries_on_server_disconnect",
      "configuration":{
         // optional:
         "EXECUTION_TIMEOUT":"300",  // in seconds
         "RECONNECTION_ATTEMPTS": 5
      },
      "test":{
         "id":"MQTT_Reconnect_Backoff_Retries_On_Server_Disconnect",
         "version":"0.0.0"
      }
   }
]
```

**“设备以抖动退避功能重新连接 - 连接不稳定”**  
验证被测设备在不稳定连接上重新连接时是否使用了必要的抖动和退避。Device Advisor 在五次成功连接后将设备与服务器断开连接，并观察设备的 MQTT 重新连接的行为。Device Advisor 记录被测设备的 CONNECT（连接）请求的时间戳，执行数据包验证，发送回 CONNACK，断开连接，记录断开连接的时间戳，并等待被测设备重新发送请求。收集的时间戳用于验证被测设备在成功但不稳定的连接后重新连接时，是否使用抖动和退避。如果被测设备具有严格的指数退避或未实现适当的抖动退避机制，此测试用例将通过但是带有警告。如果被测设备实施了线性退避或恒定退避机制，测试将失败。  
要通过此测试用例，我们建议在所测试设备上实施[指数退避和抖动](https://www.amazonaws.cn/blogs//architecture/exponential-backoff-and-jitter/)机制。  
*API 测试用例定义：*  
`EXECUTION_TIMEOUT` 的默认值为 5 分钟。我们建议将超时值设置为 4 分钟。  
通过指定 `RECONNECTION_ATTEMPTS`，可以更改验证退避的重新连接尝试次数。该数字必须介于 5 到 10 之间。默认值是 5。

```
"tests":[
   {
      "name":"my_mqtt_reconnect_backoff_retries_on_unstable_connection",
      "configuration":{
         // optional:
         "EXECUTION_TIMEOUT":"300",  // in seconds
         "RECONNECTION_ATTEMPTS": 5
      },
      "test":{
         "id":"MQTT_Reconnect_Backoff_Retries_On_Unstable_Connection",
         "version":"0.0.0"
      }
   }
]
```

## 发布
<a name="publish"></a>

**“QoS0（快乐使用案例）”**  <a name="MQTT_Publish"></a>
验证测试设备是使用 QoS0 还是 QoS1 发布消息。您还可以通过在测试设置中指定此主题值和有效载荷来验证消息的主题和有效载荷。  
`EXECUTION_TIMEOUT` 的默认值为 5 分钟。我们建议将超时值设置为 2 分钟。

```
"tests":[
   {
      "name":"my_mqtt_publish_test",
      "configuration":{
         // optional:
         "EXECUTION_TIMEOUT":"300",  // in seconds
         "TOPIC_FOR_PUBLISH_VALIDATION": "my_TOPIC_FOR_PUBLISH_VALIDATION",
         "PAYLOAD_FOR_PUBLISH_VALIDATION": "my_PAYLOAD_FOR_PUBLISH_VALIDATION",
      },
      "test":{
         "id":"MQTT_Publish",
         "version":"0.0.0"
      }
   }
]
```

**“QoS1 发布重试 - 没有 PUBACK”**  
如果代理没有发送 PUBACK，则验证被测设备是否重新发布了随 QoS1 发送的消息。您还可以通过在测试设置中指定此主题来验证消息的主题。在重新发布消息之前，客户端设备不得断开连接。此测试还验证重新发布的消息与原始消息是否具有相同的数据包标识符。在测试执行期间，如果设备丢失连接并重新连接，则测试用例将顺利重置，并且设备必须重新执行测试用例步骤。  
*API 测试用例定义：*  
`EXECUTION_TIMEOUT` 的默认值为 5 分钟。建议至少 4 分钟。

```
"tests":[
   {
      "name":"my_mqtt_publish_retry_test",
      "configuration":{
         // optional:
         "EXECUTION_TIMEOUT":"300",  // in seconds
         "TOPIC_FOR_PUBLISH_VALIDATION": "my_TOPIC_FOR_PUBLISH_VALIDATION",
         "PAYLOAD_FOR_PUBLISH_VALIDATION": "my_PAYLOAD_FOR_PUBLISH_VALIDATION",
      },
      "test":{
         "id":"MQTT_Publish_Retry_No_Puback",
         "version":"0.0.0"
      }
   }
]
```

**“发布保留消息”**  
验证被测设备是否发布 `retainFlag` 设置为 true 的消息。您可以通过在测试设置中设置主题值和有效载荷来验证消息的主题和有效载荷。如果未将 PUBLISH 数据包中发送的 `retainFlag` 设置为 true，则测试使用案例将失败。  
*API 测试用例定义：*  
`EXECUTION_TIMEOUT` 的默认值为 5 分钟。我们建议将超时值设置为 2 分钟。要运行此测试使用案例，请在您的 [device role](https://docs.amazonaws.cn/iot/latest/developerguide/device-advisor-setting-up.html#da-iam-role)（设备角色）中添加 `iot:RetainPublish` 操作。

```
"tests":[
   {
      "name":"my_mqtt_publish_retained_messages_test",
      "configuration":{
         // optional:
         "EXECUTION_TIMEOUT":"300",  // in seconds
         "TOPIC_FOR_PUBLISH_RETAINED_VALIDATION": "my_TOPIC_FOR_PUBLISH_RETAINED_VALIDATION",
         "PAYLOAD_FOR_PUBLISH_RETAINED_VALIDATION": "my_PAYLOAD_FOR_PUBLISH_RETAINED_VALIDATION",
      },
      "test":{
         "id":"MQTT_Publish_Retained_Messages",
         "version":"0.0.0"
      }
   }
]
```

**“使用用户属性发布”**  
验证被测设备是否使用正确的用户属性发布消息。您可以通过在测试设置中设置名称-值对来验证用户属性。如果未提供用户属性或用户属性不匹配，则测试使用案例将失败。  
*API 测试用例定义：*  
这是 MQTT5 唯一的测试用例。  
`EXECUTION_TIMEOUT` 的默认值为 5 分钟。我们建议将超时值设置为 2 分钟。

```
"tests":[
   {
      "name":"my_mqtt_user_property_test",
      "test":{
        "USER_PROPERTIES": [
            {"name": "name1", "value":"value1"},
            {"name": "name2", "value":"value2"}
        ],
        "EXECUTION_TIMEOUT":"300",  // in seconds
      },
      "test":{
         "id":"MQTT_Publish_User_Property",
         "version":"0.0.0"
      }
   }
]
```

## Subscribe
<a name="subscribe"></a>

**“可以订阅（快乐使用案例）”**  <a name="MQTT_Subscribe"></a>
验证被测设备是否订阅了 MQTT 主题。您还可以通过在测试设置中指定此主题来验证被测设备订阅的主题。  
*API 测试用例定义：*  
`EXECUTION_TIMEOUT` 的默认值为 5 分钟。我们建议将超时值设置为 2 分钟。

```
"tests":[
   {
      "name":"my_mqtt_subscribe_test",
      "configuration":{
         // optional:
         "EXECUTION_TIMEOUT":"300",  // in seconds
         "TOPIC_LIST_FOR_SUBSCRIPTION_VALIDATION":["my_TOPIC_FOR_PUBLISH_VALIDATION_a","my_TOPIC_FOR_PUBLISH_VALIDATION_b"]
      },
      "test":{
         "id":"MQTT_Subscribe",
         "version":"0.0.0"
      }
   }
]
```

**“订阅重试 - 无 SUBACK”**  
验证被测设备是否重试 MQTT 主题的失败订阅。然后，服务器会等待，不发送 SUBACK。如果客户端设备未重试订阅，则测试失败。客户端设备必须使用相同的数据包 ID 重试失败的订阅。您还可以通过在测试设置中指定此主题来验证被测设备订阅的主题。在测试执行期间，如果设备丢失连接并重新连接，则测试用例将顺利重置，并且设备必须重新执行测试用例步骤。  
*API 测试用例定义：*  
`EXECUTION_TIMEOUT` 的默认值为 5 分钟。我们建议将超时值设置为 4 分钟。

```
"tests":[
   {
      "name":"my_mqtt_subscribe_retry_test",
      "configuration":{
         "EXECUTION_TIMEOUT":"300",  // in seconds
         // optional:
         "TOPIC_LIST_FOR_SUBSCRIPTION_VALIDATION":["myTOPIC_FOR_PUBLISH_VALIDATION_a","my_TOPIC_FOR_PUBLISH_VALIDATION_b"]
      },
      "test":{
         "id":"MQTT_Subscribe_Retry_No_Suback",
         "version":"0.0.0"
      }
   }
]
```

## Keep-Alive
<a name="keep-alive"></a>

**“Mattt No Ack PingResp”**  
此测试使用案例验证被测设备在未收到 ping 响应时是否断开连接。作为此测试用例的一部分，设备顾问会屏蔽来自 Amazon IoT Core 的发布、订阅和 ping 请求的响应。它还验证正在测试的设备是否断开了 MQTT 连接。  
*API 测试用例定义：*  
`EXECUTION_TIMEOUT` 的默认值为 5 分钟。我们建议超时时间大于 `keepAliveTime` 值的 1.5 倍。  
 此测试的最大 `keepAliveTime` 不得超过 230 秒。

```
"tests":[
    {
       "name":"Mqtt No Ack PingResp",
       "configuration": 
          //optional:
          "EXECUTION_TIMEOUT":"306",   // in seconds
       },
       "test":{
          "id":"MQTT_No_Ack_PingResp",
          "version":"0.0.0"
       }
    }
]
```

## 持久会话
<a name="persistent-session"></a>

**“持久会话（快乐使用案例）”**  
此测试使用案例验证设备在与持久会话断开连接时的行为。该测试使用案例检查设备是否可以重新连接，恢复对其触发器主题的订阅而无需显式重新订阅，接收主题中存储的消息以及在持久会话期间按预期工作。当此测试用例通过时，它表明客户端设备能够以预期的方式与 Amazon IoT Core 代理保持持续会话。有关 Amazon IoT 持久会话的更多信息，请参阅[使用 MQTT 持久会话](https://docs.amazonaws.cn/iot/latest/developerguide/mqtt.html#mqtt-persistent-sessions)。  
在此测试使用案例中，客户端设备应该与 Amazon IoT Core 进行连接 [clean session（清理会话）标志设置为 false]，然后订阅一个触发器主题。成功订阅后，设备顾问将断开 Amazon IoT Core 设备连接。当设备处于断开连接状态时，该主题中将存储 QoS 1 消息有效载荷。然后，Device Advisor 将允许客户端设备与测试端点重新连接。此时，由于存在持久会话，客户端设备应该恢复其主题订阅而不发送任何其他 SUBSCRIBE 数据包，然后接收来自代理的 QoS 1 消息。重新连接后，如果客户端设备未能从触发主题接收存储的消息，通过发送额外的 SUBSCRIBE 数据包再次订阅其触发主题， and/or 则测试用例将失败。  
*API 测试用例定义：*  
`EXECUTION_TIMEOUT` 的默认值为 5 分钟。我们建议将超时值设置为至少 4 分钟。在第一个连接中，客户端设备需要显式订阅之前没有订阅的 `TRIGGER_TOPIC`。要通过测试使用案例，客户端设备必须使用 QoS 1 成功订阅 `TRIGGER_TOPIC`。重新连接后，客户端设备应该了解存在活动的持久会话；因此它应该接受由触发器主题发送的已存储消息，然后对该特定消息返回 PUBACK。

```
"tests":[
   {
      "name":"my_mqtt_persistent_session_happy_case",
      "configuration":{
         //required:
         "TRIGGER_TOPIC": "myTrigger/topic",
         // optional:
         // if Payload not provided, a string will be stored in the trigger topic to be sent back to the client device
         "PAYLOAD": "The message which should be received from AWS IoT Broker after re-connecting to a persistent session from the specified trigger topic.",            
         "EXECUTION_TIMEOUT":"300" // in seconds
      },
      "test":{
         "id":"MQTT_Persistent_Session_Happy_Case",
         "version":"0.0.0"
      }
   }
]
```

**“持久会话 - 会话到期”**  
此测试使用案例有助于验证断开连接的设备重新连接到过期的持久会话时的设备行为。会话过期后，我们希望设备通过显式发送新的 SUBSUBE 数据包来重新订阅之前订阅的主题。  
在第一次连接期间，我们希望测试设备与 Amazon 物联网代理连接，因为其`CleanSession`标志设置为 false 即可启动持续会话。然后，设备应该订阅触发器主题。然后，在成功订阅并启动持续会话后， Amazon IoT Core 设备顾问将断开设备的连接。断开连接后， Amazon IoT Core 设备顾问允许测试设备与测试端点重新连接。此时，当测试设备发送另一个 CONNECT 数据包时， Amazon IoT Core 设备顾问会发回一个 CONNACK 数据包，表示持续会话已过期。测试设备需要正确地解释此数据包，并且在持久会话终止时，它应该会再次重新订阅同一触发器主题。如果测试设备不再重新订阅其主题触发器，测试使用案例将失败。要通过测试，设备需要了解持久会话已经结束，然后为第二个连接中的相同触发器主题发回一个新的 SUBSCRIBE 数据包。  
如果测试设备的此测试使用案例获得通过，则表示该设备能够按照预期方式在持久会话到期时进行重新连接。  
*API 测试用例定义：*  
`EXECUTION_TIMEOUT` 的默认值为 5 分钟。我们建议将超时值设置为至少 4 分钟。测试设备需要显式订阅之前没有订阅的 `TRIGGER_TOPIC`。要通过测试使用案例，测试设备必须发送 CONNECT 数据包（`CleanSession` 标志设置为 false），并使用 QoS 1 成功订阅触发器主题。成功连接后， Amazon IoT Core 设备顾问会断开设备的连接。断开连接后， Amazon IoT Core Device Advisor 允许设备重新连接，并且设备应该重新订阅相同的连接，`TRIGGER_TOPIC`因为 Amazon IoT Core 设备顾问本来会终止持续会话。

```
"tests":[
   {
      "name":"my_expired_persistent_session_test",
      "configuration":{
         //required:
         "TRIGGER_TOPIC": "myTrigger/topic",
         // optional:       
         "EXECUTION_TIMEOUT":"300" // in seconds
      },
      "test":{
         "id":"MQTT_Expired_Persistent_Session",
         "version":"0.0.0"
      }
   }
]
```