Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
simple-mbed-cloud-client/TESTS/host_tests/sdk_host_tests.py@0:8f0bb79ddd48, 2021-05-04 (annotated)
- Committer:
- leothedragon
- Date:
- Tue May 04 08:55:12 2021 +0000
- Revision:
- 0:8f0bb79ddd48
nmn
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
leothedragon | 0:8f0bb79ddd48 | 1 | ## ---------------------------------------------------------------------------- |
leothedragon | 0:8f0bb79ddd48 | 2 | ## Copyright 2016-2018 ARM Ltd. |
leothedragon | 0:8f0bb79ddd48 | 3 | ## |
leothedragon | 0:8f0bb79ddd48 | 4 | ## SPDX-License-Identifier: Apache-2.0 |
leothedragon | 0:8f0bb79ddd48 | 5 | ## |
leothedragon | 0:8f0bb79ddd48 | 6 | ## Licensed under the Apache License, Version 2.0 (the "License"); |
leothedragon | 0:8f0bb79ddd48 | 7 | ## you may not use this file except in compliance with the License. |
leothedragon | 0:8f0bb79ddd48 | 8 | ## You may obtain a copy of the License at |
leothedragon | 0:8f0bb79ddd48 | 9 | ## |
leothedragon | 0:8f0bb79ddd48 | 10 | ## http://www.apache.org/licenses/LICENSE-2.0 |
leothedragon | 0:8f0bb79ddd48 | 11 | ## |
leothedragon | 0:8f0bb79ddd48 | 12 | ## Unless required by applicable law or agreed to in writing, software |
leothedragon | 0:8f0bb79ddd48 | 13 | ## distributed under the License is distributed on an "AS IS" BASIS, |
leothedragon | 0:8f0bb79ddd48 | 14 | ## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
leothedragon | 0:8f0bb79ddd48 | 15 | ## See the License for the specific language governing permissions and |
leothedragon | 0:8f0bb79ddd48 | 16 | ## limitations under the License. |
leothedragon | 0:8f0bb79ddd48 | 17 | ## ---------------------------------------------------------------------------- |
leothedragon | 0:8f0bb79ddd48 | 18 | |
leothedragon | 0:8f0bb79ddd48 | 19 | from mbed_host_tests import BaseHostTest |
leothedragon | 0:8f0bb79ddd48 | 20 | from mbed_host_tests.host_tests_logger import HtrunLogger |
leothedragon | 0:8f0bb79ddd48 | 21 | from mbed_cloud.device_directory import DeviceDirectoryAPI |
leothedragon | 0:8f0bb79ddd48 | 22 | from mbed_cloud.connect import ConnectAPI |
leothedragon | 0:8f0bb79ddd48 | 23 | import os |
leothedragon | 0:8f0bb79ddd48 | 24 | import time |
leothedragon | 0:8f0bb79ddd48 | 25 | import subprocess |
leothedragon | 0:8f0bb79ddd48 | 26 | import re |
leothedragon | 0:8f0bb79ddd48 | 27 | import signal |
leothedragon | 0:8f0bb79ddd48 | 28 | |
leothedragon | 0:8f0bb79ddd48 | 29 | DEFAULT_CYCLE_PERIOD = 1.0 |
leothedragon | 0:8f0bb79ddd48 | 30 | |
leothedragon | 0:8f0bb79ddd48 | 31 | class SDKTests(BaseHostTest): |
leothedragon | 0:8f0bb79ddd48 | 32 | __result = None |
leothedragon | 0:8f0bb79ddd48 | 33 | deviceApi = None |
leothedragon | 0:8f0bb79ddd48 | 34 | connectApi = None |
leothedragon | 0:8f0bb79ddd48 | 35 | deviceID = None |
leothedragon | 0:8f0bb79ddd48 | 36 | post_timeout = None |
leothedragon | 0:8f0bb79ddd48 | 37 | firmware_proc = None |
leothedragon | 0:8f0bb79ddd48 | 38 | firmware_sent = False |
leothedragon | 0:8f0bb79ddd48 | 39 | firmware_file = None |
leothedragon | 0:8f0bb79ddd48 | 40 | iteration = 0 |
leothedragon | 0:8f0bb79ddd48 | 41 | boot_cycles = 0 |
leothedragon | 0:8f0bb79ddd48 | 42 | |
leothedragon | 0:8f0bb79ddd48 | 43 | def send_safe(self, key, value): |
leothedragon | 0:8f0bb79ddd48 | 44 | #self.send_kv('dummy_start', 0) |
leothedragon | 0:8f0bb79ddd48 | 45 | self.send_kv(key, value) |
leothedragon | 0:8f0bb79ddd48 | 46 | self.send_kv(key, value) |
leothedragon | 0:8f0bb79ddd48 | 47 | self.send_kv(key, value) |
leothedragon | 0:8f0bb79ddd48 | 48 | self.send_kv(key, value) |
leothedragon | 0:8f0bb79ddd48 | 49 | self.send_kv(key, value) |
leothedragon | 0:8f0bb79ddd48 | 50 | #self.send_kv('dummy_end', 1) |
leothedragon | 0:8f0bb79ddd48 | 51 | |
leothedragon | 0:8f0bb79ddd48 | 52 | def _callback_device_booted(self, key, value, timestamp): |
leothedragon | 0:8f0bb79ddd48 | 53 | # This is used to let the device boot normally |
leothedragon | 0:8f0bb79ddd48 | 54 | self.send_safe('__sync', 0) |
leothedragon | 0:8f0bb79ddd48 | 55 | |
leothedragon | 0:8f0bb79ddd48 | 56 | def _callback_device_ready(self, key, value, timestamp): |
leothedragon | 0:8f0bb79ddd48 | 57 | # Send device iteration number after a reset |
leothedragon | 0:8f0bb79ddd48 | 58 | self.boot_cycles += 1 |
leothedragon | 0:8f0bb79ddd48 | 59 | # Prevent boot loop due to Mbed OS crash |
leothedragon | 0:8f0bb79ddd48 | 60 | if self.boot_cycles <= 5: |
leothedragon | 0:8f0bb79ddd48 | 61 | self.send_safe('iteration', self.iteration) |
leothedragon | 0:8f0bb79ddd48 | 62 | |
leothedragon | 0:8f0bb79ddd48 | 63 | def _callback_test_advance(self, key, value, timestamp): |
leothedragon | 0:8f0bb79ddd48 | 64 | # Advance test sequence |
leothedragon | 0:8f0bb79ddd48 | 65 | self.iteration = self.iteration + 1 |
leothedragon | 0:8f0bb79ddd48 | 66 | self.send_safe('reset', 0) |
leothedragon | 0:8f0bb79ddd48 | 67 | |
leothedragon | 0:8f0bb79ddd48 | 68 | def _callback_test_failed(self, key, value, timestamp): |
leothedragon | 0:8f0bb79ddd48 | 69 | # Test failed. End it. |
leothedragon | 0:8f0bb79ddd48 | 70 | self.notify_complete(False) |
leothedragon | 0:8f0bb79ddd48 | 71 | |
leothedragon | 0:8f0bb79ddd48 | 72 | """ |
leothedragon | 0:8f0bb79ddd48 | 73 | Device Register routines |
leothedragon | 0:8f0bb79ddd48 | 74 | """ |
leothedragon | 0:8f0bb79ddd48 | 75 | def _callback_verify_registration(self, key, value, timestamp): |
leothedragon | 0:8f0bb79ddd48 | 76 | try: |
leothedragon | 0:8f0bb79ddd48 | 77 | #set value for later use |
leothedragon | 0:8f0bb79ddd48 | 78 | self.deviceID = value |
leothedragon | 0:8f0bb79ddd48 | 79 | |
leothedragon | 0:8f0bb79ddd48 | 80 | # Check if device is in Mbed Cloud Device Directory |
leothedragon | 0:8f0bb79ddd48 | 81 | device = self.deviceApi.get_device(value) |
leothedragon | 0:8f0bb79ddd48 | 82 | |
leothedragon | 0:8f0bb79ddd48 | 83 | # Send registraton status to device |
leothedragon | 0:8f0bb79ddd48 | 84 | self.send_safe("registered", 1 if device.state == "registered" else 0) |
leothedragon | 0:8f0bb79ddd48 | 85 | except: |
leothedragon | 0:8f0bb79ddd48 | 86 | # SDK throws an exception if the device is not found (unsuccessful registration) or times out |
leothedragon | 0:8f0bb79ddd48 | 87 | self.send_safe("registered", 0) |
leothedragon | 0:8f0bb79ddd48 | 88 | |
leothedragon | 0:8f0bb79ddd48 | 89 | def _callback_verify_identity(self, key, value, timestamp): |
leothedragon | 0:8f0bb79ddd48 | 90 | # Send true if old DeviceID is the same as current device is |
leothedragon | 0:8f0bb79ddd48 | 91 | self.send_safe("verified", 1 if self.deviceID == value else 0) |
leothedragon | 0:8f0bb79ddd48 | 92 | |
leothedragon | 0:8f0bb79ddd48 | 93 | """ |
leothedragon | 0:8f0bb79ddd48 | 94 | Device Connect routines |
leothedragon | 0:8f0bb79ddd48 | 95 | """ |
leothedragon | 0:8f0bb79ddd48 | 96 | def _callback_verify_lwm2m_get(self, key, value, timestamp): |
leothedragon | 0:8f0bb79ddd48 | 97 | timeout = 0 |
leothedragon | 0:8f0bb79ddd48 | 98 | |
leothedragon | 0:8f0bb79ddd48 | 99 | # Get resource value from device |
leothedragon | 0:8f0bb79ddd48 | 100 | async_response = self.connectApi.get_resource_value_async(self.deviceID, value) |
leothedragon | 0:8f0bb79ddd48 | 101 | |
leothedragon | 0:8f0bb79ddd48 | 102 | # Set a 30 second timeout here. |
leothedragon | 0:8f0bb79ddd48 | 103 | while not async_response.is_done and timeout <= 50: |
leothedragon | 0:8f0bb79ddd48 | 104 | time.sleep(0.1) |
leothedragon | 0:8f0bb79ddd48 | 105 | timeout += 1 |
leothedragon | 0:8f0bb79ddd48 | 106 | |
leothedragon | 0:8f0bb79ddd48 | 107 | if not async_response.is_done: |
leothedragon | 0:8f0bb79ddd48 | 108 | # Kick the REST API |
leothedragon | 0:8f0bb79ddd48 | 109 | timeout = 0 |
leothedragon | 0:8f0bb79ddd48 | 110 | async_response = self.connectApi.get_resource_value_async(self.deviceID, value) |
leothedragon | 0:8f0bb79ddd48 | 111 | while not async_response.is_done and timeout <= 250: |
leothedragon | 0:8f0bb79ddd48 | 112 | time.sleep(0.1) |
leothedragon | 0:8f0bb79ddd48 | 113 | timeout += 1 |
leothedragon | 0:8f0bb79ddd48 | 114 | |
leothedragon | 0:8f0bb79ddd48 | 115 | if async_response.is_done: |
leothedragon | 0:8f0bb79ddd48 | 116 | # Send resource value back to device |
leothedragon | 0:8f0bb79ddd48 | 117 | self.send_safe("get_value", async_response.value) |
leothedragon | 0:8f0bb79ddd48 | 118 | else: |
leothedragon | 0:8f0bb79ddd48 | 119 | # Request timed out. |
leothedragon | 0:8f0bb79ddd48 | 120 | self.send_safe("timeout", 0) |
leothedragon | 0:8f0bb79ddd48 | 121 | |
leothedragon | 0:8f0bb79ddd48 | 122 | def _callback_verify_lwm2m_set(self, key, value, timestamp): |
leothedragon | 0:8f0bb79ddd48 | 123 | timeout = 0 |
leothedragon | 0:8f0bb79ddd48 | 124 | |
leothedragon | 0:8f0bb79ddd48 | 125 | # Get resource value from device |
leothedragon | 0:8f0bb79ddd48 | 126 | async_response = self.connectApi.get_resource_value_async(self.deviceID, value) |
leothedragon | 0:8f0bb79ddd48 | 127 | |
leothedragon | 0:8f0bb79ddd48 | 128 | # Set a 30 second timeout here. |
leothedragon | 0:8f0bb79ddd48 | 129 | while not async_response.is_done and timeout <= 300: |
leothedragon | 0:8f0bb79ddd48 | 130 | time.sleep(0.1) |
leothedragon | 0:8f0bb79ddd48 | 131 | timeout += 1 |
leothedragon | 0:8f0bb79ddd48 | 132 | |
leothedragon | 0:8f0bb79ddd48 | 133 | if async_response.is_done: |
leothedragon | 0:8f0bb79ddd48 | 134 | # Send resource value back to device |
leothedragon | 0:8f0bb79ddd48 | 135 | self.send_safe("set_value", async_response.value) |
leothedragon | 0:8f0bb79ddd48 | 136 | else: |
leothedragon | 0:8f0bb79ddd48 | 137 | # Request timed out. |
leothedragon | 0:8f0bb79ddd48 | 138 | self.send_safe("timeout", 0) |
leothedragon | 0:8f0bb79ddd48 | 139 | |
leothedragon | 0:8f0bb79ddd48 | 140 | def _callback_verify_lwm2m_put(self, key, value, timestamp): |
leothedragon | 0:8f0bb79ddd48 | 141 | timeout = 0 |
leothedragon | 0:8f0bb79ddd48 | 142 | |
leothedragon | 0:8f0bb79ddd48 | 143 | # Get resource value from device and increment it |
leothedragon | 0:8f0bb79ddd48 | 144 | resource_value = self.connectApi.get_resource_value_async(self.deviceID, value) |
leothedragon | 0:8f0bb79ddd48 | 145 | |
leothedragon | 0:8f0bb79ddd48 | 146 | # Set a 30 second timeout here. |
leothedragon | 0:8f0bb79ddd48 | 147 | while not resource_value.is_done and timeout <= 300: |
leothedragon | 0:8f0bb79ddd48 | 148 | time.sleep(0.1) |
leothedragon | 0:8f0bb79ddd48 | 149 | timeout += 1 |
leothedragon | 0:8f0bb79ddd48 | 150 | |
leothedragon | 0:8f0bb79ddd48 | 151 | if not resource_value.is_done: |
leothedragon | 0:8f0bb79ddd48 | 152 | self.send_safe("timeout", 0) |
leothedragon | 0:8f0bb79ddd48 | 153 | return |
leothedragon | 0:8f0bb79ddd48 | 154 | |
leothedragon | 0:8f0bb79ddd48 | 155 | updated_value = int(resource_value.value) + 5 |
leothedragon | 0:8f0bb79ddd48 | 156 | |
leothedragon | 0:8f0bb79ddd48 | 157 | # Set new resource value from cloud |
leothedragon | 0:8f0bb79ddd48 | 158 | async_response = self.connectApi.set_resource_value_async(self.deviceID, value, updated_value) |
leothedragon | 0:8f0bb79ddd48 | 159 | |
leothedragon | 0:8f0bb79ddd48 | 160 | # Set a 30 second timeout here. |
leothedragon | 0:8f0bb79ddd48 | 161 | while not async_response.is_done and timeout <= 300: |
leothedragon | 0:8f0bb79ddd48 | 162 | time.sleep(0.1) |
leothedragon | 0:8f0bb79ddd48 | 163 | timeout += 1 |
leothedragon | 0:8f0bb79ddd48 | 164 | |
leothedragon | 0:8f0bb79ddd48 | 165 | if not async_response.is_done: |
leothedragon | 0:8f0bb79ddd48 | 166 | self.send_safe("timeout", 0) |
leothedragon | 0:8f0bb79ddd48 | 167 | else: |
leothedragon | 0:8f0bb79ddd48 | 168 | # Send new resource value to device for verification. |
leothedragon | 0:8f0bb79ddd48 | 169 | self.send_safe("res_set", updated_value); |
leothedragon | 0:8f0bb79ddd48 | 170 | |
leothedragon | 0:8f0bb79ddd48 | 171 | def _callback_verify_lwm2m_post(self, key, value, timestamp): |
leothedragon | 0:8f0bb79ddd48 | 172 | timeout = 0 |
leothedragon | 0:8f0bb79ddd48 | 173 | |
leothedragon | 0:8f0bb79ddd48 | 174 | # Execute POST function on device |
leothedragon | 0:8f0bb79ddd48 | 175 | resource_value = self.connectApi.execute_resource_async(self.deviceID, value) |
leothedragon | 0:8f0bb79ddd48 | 176 | |
leothedragon | 0:8f0bb79ddd48 | 177 | # Set a 30 second timeout here. |
leothedragon | 0:8f0bb79ddd48 | 178 | while not resource_value.is_done and timeout <= 300: |
leothedragon | 0:8f0bb79ddd48 | 179 | time.sleep(0.1) |
leothedragon | 0:8f0bb79ddd48 | 180 | timeout += 1 |
leothedragon | 0:8f0bb79ddd48 | 181 | |
leothedragon | 0:8f0bb79ddd48 | 182 | if not resource_value.is_done: |
leothedragon | 0:8f0bb79ddd48 | 183 | self.send_safe("timeout", 0) |
leothedragon | 0:8f0bb79ddd48 | 184 | self.post_timeout = 1 |
leothedragon | 0:8f0bb79ddd48 | 185 | |
leothedragon | 0:8f0bb79ddd48 | 186 | def _callback_verify_lwm2m_post_result(self, key, value, timestamp): |
leothedragon | 0:8f0bb79ddd48 | 187 | |
leothedragon | 0:8f0bb79ddd48 | 188 | # Called from callback function on device, POST function working as expected. |
leothedragon | 0:8f0bb79ddd48 | 189 | # If post_timeout is not none, the request took longer than 30 seconds, which is |
leothedragon | 0:8f0bb79ddd48 | 190 | # a failure. Don't send this value. |
leothedragon | 0:8f0bb79ddd48 | 191 | if not self.post_timeout: |
leothedragon | 0:8f0bb79ddd48 | 192 | self.send_safe("post_test_executed", 0) |
leothedragon | 0:8f0bb79ddd48 | 193 | |
leothedragon | 0:8f0bb79ddd48 | 194 | """ |
leothedragon | 0:8f0bb79ddd48 | 195 | Device Firmware update routines |
leothedragon | 0:8f0bb79ddd48 | 196 | """ |
leothedragon | 0:8f0bb79ddd48 | 197 | def firmware_campaign_cleanup(self): |
leothedragon | 0:8f0bb79ddd48 | 198 | if self.firmware_proc: |
leothedragon | 0:8f0bb79ddd48 | 199 | if os.name == 'nt': |
leothedragon | 0:8f0bb79ddd48 | 200 | os.kill(self.firmware_proc.pid, signal.CTRL_C_EVENT) |
leothedragon | 0:8f0bb79ddd48 | 201 | os.kill(self.firmware_proc.pid, signal.CTRL_BREAK_EVENT) |
leothedragon | 0:8f0bb79ddd48 | 202 | self.firmware_proc.terminate() |
leothedragon | 0:8f0bb79ddd48 | 203 | outs, errs = self.firmware_proc.communicate() |
leothedragon | 0:8f0bb79ddd48 | 204 | self.logger.prn_inf('Firmware campaign process killed: PID %s' % self.firmware_proc.pid) |
leothedragon | 0:8f0bb79ddd48 | 205 | self.firmware_proc = None |
leothedragon | 0:8f0bb79ddd48 | 206 | |
leothedragon | 0:8f0bb79ddd48 | 207 | try: |
leothedragon | 0:8f0bb79ddd48 | 208 | time.sleep(1) # let the manifest-tool sub-process die gracefully |
leothedragon | 0:8f0bb79ddd48 | 209 | if self.firmware_file: |
leothedragon | 0:8f0bb79ddd48 | 210 | os.remove(self.firmware_file) |
leothedragon | 0:8f0bb79ddd48 | 211 | self.firmware_file = None |
leothedragon | 0:8f0bb79ddd48 | 212 | except Exception, e: |
leothedragon | 0:8f0bb79ddd48 | 213 | pass |
leothedragon | 0:8f0bb79ddd48 | 214 | |
leothedragon | 0:8f0bb79ddd48 | 215 | def _callback_firmware_ready(self, key, value, timestamp): |
leothedragon | 0:8f0bb79ddd48 | 216 | if self.firmware_sent: |
leothedragon | 0:8f0bb79ddd48 | 217 | # Firmware was sent, but wasn't applied if this callback is called |
leothedragon | 0:8f0bb79ddd48 | 218 | self.firmware_campaign_cleanup() |
leothedragon | 0:8f0bb79ddd48 | 219 | self.notify_complete(False) |
leothedragon | 0:8f0bb79ddd48 | 220 | else: |
leothedragon | 0:8f0bb79ddd48 | 221 | # Send device iteration number after a reset |
leothedragon | 0:8f0bb79ddd48 | 222 | self.send_safe('iteration', self.iteration) |
leothedragon | 0:8f0bb79ddd48 | 223 | |
leothedragon | 0:8f0bb79ddd48 | 224 | def _callback_firmware_prepare(self, key, value, timestamp): |
leothedragon | 0:8f0bb79ddd48 | 225 | if not self.deviceID: |
leothedragon | 0:8f0bb79ddd48 | 226 | self.logger.prn_err("ERROR: No DeviceID") |
leothedragon | 0:8f0bb79ddd48 | 227 | self.notify_complete(False) |
leothedragon | 0:8f0bb79ddd48 | 228 | return -1 |
leothedragon | 0:8f0bb79ddd48 | 229 | |
leothedragon | 0:8f0bb79ddd48 | 230 | target = self.get_config_item('platform_name') |
leothedragon | 0:8f0bb79ddd48 | 231 | image = self.get_config_item('image_path') |
leothedragon | 0:8f0bb79ddd48 | 232 | update_image = re.sub(r'(.+)\.([a-z0-9]+)$', r'\1_update.bin', image if image else "") |
leothedragon | 0:8f0bb79ddd48 | 233 | if not image or not os.path.exists(update_image): |
leothedragon | 0:8f0bb79ddd48 | 234 | self.logger.prn_err("ERROR: No main or update image") |
leothedragon | 0:8f0bb79ddd48 | 235 | self.notify_complete(False) |
leothedragon | 0:8f0bb79ddd48 | 236 | return -1 |
leothedragon | 0:8f0bb79ddd48 | 237 | self.logger.prn_inf('Found FW update image: "%s"' % update_image) |
leothedragon | 0:8f0bb79ddd48 | 238 | |
leothedragon | 0:8f0bb79ddd48 | 239 | try: |
leothedragon | 0:8f0bb79ddd48 | 240 | # Open the firmware update image as provided by the build system |
leothedragon | 0:8f0bb79ddd48 | 241 | with open(update_image, 'rb') as f: |
leothedragon | 0:8f0bb79ddd48 | 242 | raw = f.read() |
leothedragon | 0:8f0bb79ddd48 | 243 | # Modify the initial "spdmc_ready_chk" sequence into "firmware_update" |
leothedragon | 0:8f0bb79ddd48 | 244 | # (matching the string length) as an indication that the firmware was changed/updated |
leothedragon | 0:8f0bb79ddd48 | 245 | raw = re.sub(r'spdmc_ready_chk', r'firmware_update', raw) |
leothedragon | 0:8f0bb79ddd48 | 246 | |
leothedragon | 0:8f0bb79ddd48 | 247 | # Save the firmware into a temp place. Manifest tool has issues handling very long paths even if -n is specified |
leothedragon | 0:8f0bb79ddd48 | 248 | update_mod_image = ".%s.%s.%s" % (target, re.sub(r'.*[\\/](.+)\.([a-z0-9]+)$', r'\1_update_mod.\2', image), time.time()) |
leothedragon | 0:8f0bb79ddd48 | 249 | with open(update_mod_image, 'wb') as f: |
leothedragon | 0:8f0bb79ddd48 | 250 | f.write(raw) |
leothedragon | 0:8f0bb79ddd48 | 251 | except Exception, e: |
leothedragon | 0:8f0bb79ddd48 | 252 | self.logger.prn_err("ERROR: While preparing modified image") |
leothedragon | 0:8f0bb79ddd48 | 253 | self.notify_complete(False) |
leothedragon | 0:8f0bb79ddd48 | 254 | return -1 |
leothedragon | 0:8f0bb79ddd48 | 255 | self.logger.prn_inf('Modified FW update image: "%s"' % update_mod_image) |
leothedragon | 0:8f0bb79ddd48 | 256 | |
leothedragon | 0:8f0bb79ddd48 | 257 | # Use non-blocking call, but remember the process, so we can kill it later |
leothedragon | 0:8f0bb79ddd48 | 258 | try: |
leothedragon | 0:8f0bb79ddd48 | 259 | spargs = dict() |
leothedragon | 0:8f0bb79ddd48 | 260 | if os.name == 'posix': |
leothedragon | 0:8f0bb79ddd48 | 261 | spargs['preexec_fn'] = os.setpgrp |
leothedragon | 0:8f0bb79ddd48 | 262 | elif os.name == 'nt': |
leothedragon | 0:8f0bb79ddd48 | 263 | spargs['creationflags'] = subprocess.CREATE_NEW_PROCESS_GROUP |
leothedragon | 0:8f0bb79ddd48 | 264 | self.firmware_proc = subprocess.Popen(["mbed", "dm", "update", "device", "-p", update_mod_image, "-D", self.deviceID], stderr=subprocess.STDOUT, **spargs) |
leothedragon | 0:8f0bb79ddd48 | 265 | self.firmware_file = update_mod_image |
leothedragon | 0:8f0bb79ddd48 | 266 | except Exception, e: |
leothedragon | 0:8f0bb79ddd48 | 267 | self.logger.prn_err("ERROR: Unable to execute 'mbed dm' sub-command") |
leothedragon | 0:8f0bb79ddd48 | 268 | self.firmware_campaign_cleanup() |
leothedragon | 0:8f0bb79ddd48 | 269 | self.notify_complete(False) |
leothedragon | 0:8f0bb79ddd48 | 270 | return -1 |
leothedragon | 0:8f0bb79ddd48 | 271 | |
leothedragon | 0:8f0bb79ddd48 | 272 | # At this point the firmware should be on it's way to the device |
leothedragon | 0:8f0bb79ddd48 | 273 | self.firmware_sent = True |
leothedragon | 0:8f0bb79ddd48 | 274 | self.send_safe('firmware_sent', 1) |
leothedragon | 0:8f0bb79ddd48 | 275 | self.logger.prn_inf("Firmware sent and update campaign started. Check for download progress.") |
leothedragon | 0:8f0bb79ddd48 | 276 | |
leothedragon | 0:8f0bb79ddd48 | 277 | def _callback_firmware_update(self, key, value, timestamp): |
leothedragon | 0:8f0bb79ddd48 | 278 | self.logger.prn_inf("Firmware successfully updated!") |
leothedragon | 0:8f0bb79ddd48 | 279 | self.firmware_campaign_cleanup() |
leothedragon | 0:8f0bb79ddd48 | 280 | self.iteration = self.iteration + 1 |
leothedragon | 0:8f0bb79ddd48 | 281 | self.send_safe('iteration', self.iteration) |
leothedragon | 0:8f0bb79ddd48 | 282 | |
leothedragon | 0:8f0bb79ddd48 | 283 | |
leothedragon | 0:8f0bb79ddd48 | 284 | """ |
leothedragon | 0:8f0bb79ddd48 | 285 | Host setup routines |
leothedragon | 0:8f0bb79ddd48 | 286 | """ |
leothedragon | 0:8f0bb79ddd48 | 287 | def setup(self): |
leothedragon | 0:8f0bb79ddd48 | 288 | # Generic test routines |
leothedragon | 0:8f0bb79ddd48 | 289 | self.register_callback('device_booted', self._callback_device_booted) |
leothedragon | 0:8f0bb79ddd48 | 290 | self.register_callback('device_ready', self._callback_device_ready) |
leothedragon | 0:8f0bb79ddd48 | 291 | self.register_callback('test_advance', self._callback_test_advance) |
leothedragon | 0:8f0bb79ddd48 | 292 | self.register_callback('test_failed', self._callback_test_failed) |
leothedragon | 0:8f0bb79ddd48 | 293 | |
leothedragon | 0:8f0bb79ddd48 | 294 | # Callbacks from device registration tests |
leothedragon | 0:8f0bb79ddd48 | 295 | self.register_callback('verify_registration', self._callback_verify_registration) |
leothedragon | 0:8f0bb79ddd48 | 296 | self.register_callback('verify_identity', self._callback_verify_identity) |
leothedragon | 0:8f0bb79ddd48 | 297 | |
leothedragon | 0:8f0bb79ddd48 | 298 | # Callbacks from LWM2M tests |
leothedragon | 0:8f0bb79ddd48 | 299 | self.register_callback('verify_lwm2m_get_test', self._callback_verify_lwm2m_get) |
leothedragon | 0:8f0bb79ddd48 | 300 | self.register_callback('verify_lwm2m_set_test', self._callback_verify_lwm2m_set) |
leothedragon | 0:8f0bb79ddd48 | 301 | self.register_callback('verify_lwm2m_put_test', self._callback_verify_lwm2m_put) |
leothedragon | 0:8f0bb79ddd48 | 302 | self.register_callback('verify_lwm2m_post_test', self._callback_verify_lwm2m_post) |
leothedragon | 0:8f0bb79ddd48 | 303 | self.register_callback('verify_lwm2m_post_test_result', self._callback_verify_lwm2m_post_result) |
leothedragon | 0:8f0bb79ddd48 | 304 | |
leothedragon | 0:8f0bb79ddd48 | 305 | # Callbacks from FW update tests |
leothedragon | 0:8f0bb79ddd48 | 306 | self.register_callback('spdmc_ready_chk', self._callback_firmware_ready) |
leothedragon | 0:8f0bb79ddd48 | 307 | self.register_callback('firmware_prepare', self._callback_firmware_prepare) |
leothedragon | 0:8f0bb79ddd48 | 308 | self.register_callback('firmware_update', self._callback_firmware_update) |
leothedragon | 0:8f0bb79ddd48 | 309 | |
leothedragon | 0:8f0bb79ddd48 | 310 | # Setup API config |
leothedragon | 0:8f0bb79ddd48 | 311 | try: |
leothedragon | 0:8f0bb79ddd48 | 312 | result = subprocess.check_output(["mbed", "config", "--list"], stderr=subprocess.STDOUT) |
leothedragon | 0:8f0bb79ddd48 | 313 | except Exception, e: |
leothedragon | 0:8f0bb79ddd48 | 314 | self.logger.prn_err("ERROR: CLOUD_SDK_API_KEY global config is not set: " + str(e)) |
leothedragon | 0:8f0bb79ddd48 | 315 | return -1 |
leothedragon | 0:8f0bb79ddd48 | 316 | |
leothedragon | 0:8f0bb79ddd48 | 317 | match = re.search(r'CLOUD_SDK_API_KEY=(.*)\n', result) |
leothedragon | 0:8f0bb79ddd48 | 318 | if match == None: |
leothedragon | 0:8f0bb79ddd48 | 319 | self.logger.prn_err("ERROR: CLOUD_SDK_API_KEY global config is not set.") |
leothedragon | 0:8f0bb79ddd48 | 320 | return -1 |
leothedragon | 0:8f0bb79ddd48 | 321 | |
leothedragon | 0:8f0bb79ddd48 | 322 | api_key_val = match.group(1).strip() |
leothedragon | 0:8f0bb79ddd48 | 323 | |
leothedragon | 0:8f0bb79ddd48 | 324 | # Get API KEY and remove LF char if included |
leothedragon | 0:8f0bb79ddd48 | 325 | self.logger.prn_inf("CLOUD_SDK_API_KEY: " + api_key_val) |
leothedragon | 0:8f0bb79ddd48 | 326 | |
leothedragon | 0:8f0bb79ddd48 | 327 | api_config = {"api_key" : api_key_val, "host" : "https://api.us-east-1.mbedcloud.com"} |
leothedragon | 0:8f0bb79ddd48 | 328 | |
leothedragon | 0:8f0bb79ddd48 | 329 | self.iteration = 0 |
leothedragon | 0:8f0bb79ddd48 | 330 | self.boot_cycles = 0 |
leothedragon | 0:8f0bb79ddd48 | 331 | |
leothedragon | 0:8f0bb79ddd48 | 332 | # Instantiate Device and Connect API |
leothedragon | 0:8f0bb79ddd48 | 333 | self.deviceApi = DeviceDirectoryAPI(api_config) |
leothedragon | 0:8f0bb79ddd48 | 334 | self.connectApi = ConnectAPI(api_config) |
leothedragon | 0:8f0bb79ddd48 | 335 | |
leothedragon | 0:8f0bb79ddd48 | 336 | def result(self): |
leothedragon | 0:8f0bb79ddd48 | 337 | return self.__result |
leothedragon | 0:8f0bb79ddd48 | 338 | |
leothedragon | 0:8f0bb79ddd48 | 339 | def teardown(self): |
leothedragon | 0:8f0bb79ddd48 | 340 | # Delete device from directory so as not to hit device allocation quota. |
leothedragon | 0:8f0bb79ddd48 | 341 | if self.deviceID: |
leothedragon | 0:8f0bb79ddd48 | 342 | self.deviceApi.delete_device(self.deviceID) |
leothedragon | 0:8f0bb79ddd48 | 343 | self.firmware_campaign_cleanup() |
leothedragon | 0:8f0bb79ddd48 | 344 | |
leothedragon | 0:8f0bb79ddd48 | 345 | pass |
leothedragon | 0:8f0bb79ddd48 | 346 | |
leothedragon | 0:8f0bb79ddd48 | 347 | def __init__(self): |
leothedragon | 0:8f0bb79ddd48 | 348 | super(SDKTests, self).__init__() |
leothedragon | 0:8f0bb79ddd48 | 349 | self.logger = HtrunLogger('TEST') |