From 419d4682da127563b0544f4368d6a415fa1fccc3 Mon Sep 17 00:00:00 2001 From: Tiangang Song Date: Fri, 14 Aug 2020 14:29:26 -0700 Subject: [PATCH 1/4] Fix some OTA E2E tests We should start the first OTA update only after we build everything. Sometimes it takes long time to build and first OTA update could already finish before we finish the second build and proceed to cancel it. --- .../aws_ota_test_case_2_updates_cancel_1st.py | 14 ++++++++++++-- .../aws_ota_test_case_cancel_then_update.py | 17 ++++++++++++++--- ...ws_ota_test_case_disconnect_cancel_update.py | 16 +++++++++++++--- 3 files changed, 39 insertions(+), 8 deletions(-) diff --git a/tools/ota_e2e_tests/aws_ota_test/aws_ota_test_case_2_updates_cancel_1st.py b/tools/ota_e2e_tests/aws_ota_test/aws_ota_test_case_2_updates_cancel_1st.py index 8319dc85612..3a7a670e4ba 100644 --- a/tools/ota_e2e_tests/aws_ota_test/aws_ota_test_case_2_updates_cancel_1st.py +++ b/tools/ota_e2e_tests/aws_ota_test/aws_ota_test_case_2_updates_cancel_1st.py @@ -24,6 +24,7 @@ """ import time +import shutil from pathlib import Path import boto3 from botocore.exceptions import ClientError @@ -56,12 +57,18 @@ def run(self): self._otaProject.setApplicationVersion(0, 9, 1) # Build the OTA image. self._otaProject.buildProject() - # Create 1st OTA update. - otaUpdateId_1 = self._otaAwsAgent.quickCreateOtaUpdate(self._otaConfig, [self._protocol]) + # Make a copy of the firmware. + firmware = Path(self._otaConfig['ota_firmware_file_path']) + first_firmware = firmware.with_name('first' + firmware.suffix) + shutil.copy(firmware, first_firmware) # Prepare another image to be updated. self._otaProject.setApplicationVersion(0, 9, 2) self._otaProject.buildProject() + # Create 1st OTA update. + self._otaConfig['ota_firmware_file_path'] = str(first_firmware) + otaUpdateId_1 = self._otaAwsAgent.quickCreateOtaUpdate(self._otaConfig, [self._protocol]) # Create 2nd OTA update. + self._otaConfig['ota_firmware_file_path'] = str(firmware) otaUpdateId_2 = self._otaAwsAgent.quickCreateOtaUpdate(self._otaConfig, [self._protocol]) # Wait until the job is in progress. @@ -74,6 +81,9 @@ def run(self): if exec_status == 'QUEUED': return OtaTestResult(testName=self._name, result=OtaTestResult.ERROR, summary='Timeout waiting for OTA job status.') + if exec_status == 'SUCCEEDED': + return OtaTestResult(testName=self._name, result=OtaTestResult.ERROR, + summary='OTA update complete too fast before we can cancel the job.') # Force cancel the first job that's in progress, device should pick up the 2nd update and succeed. iot_client = boto3.client('iot') diff --git a/tools/ota_e2e_tests/aws_ota_test/aws_ota_test_case_cancel_then_update.py b/tools/ota_e2e_tests/aws_ota_test/aws_ota_test_case_cancel_then_update.py index fe30104048e..43c24f50785 100644 --- a/tools/ota_e2e_tests/aws_ota_test/aws_ota_test_case_cancel_then_update.py +++ b/tools/ota_e2e_tests/aws_ota_test/aws_ota_test_case_cancel_then_update.py @@ -24,6 +24,7 @@ """ import time +import shutil from pathlib import Path import boto3 from botocore.exceptions import ClientError @@ -57,11 +58,16 @@ def run(self): self._otaProject.setApplicationVersion(0, 9, 1) # Build the OTA image. self._otaProject.buildProject() - # Start an OTA Update. - otaUpdateId = self._otaAwsAgent.quickCreateOtaUpdate(self._otaConfig, [self._protocol]) + # Make a copy of the firmware. + firmware = Path(self._otaConfig['ota_firmware_file_path']) + first_firmware = firmware.with_name('first' + firmware.suffix) + shutil.copy(firmware, first_firmware) # Prepare another image to be updated later self._otaProject.setApplicationVersion(0, 9, 2) self._otaProject.buildProject() + # Start first OTA Update. + self._otaConfig['ota_firmware_file_path'] = str(first_firmware) + otaUpdateId = self._otaAwsAgent.quickCreateOtaUpdate(self._otaConfig, [self._protocol]) # Wait until the job is in progress. thing_name = self._otaAwsAgent._iotThing.thing_name @@ -73,11 +79,16 @@ def run(self): if exec_status == 'QUEUED': return OtaTestResult(testName=self._name, result=OtaTestResult.ERROR, summary='Timeout waiting for OTA job status.') + if exec_status == 'SUCCEEDED': + return OtaTestResult(testName=self._name, result=OtaTestResult.ERROR, + summary='OTA update complete too fast before we can cancel the job.') # Force cancel the job that's in progress. iot_client = boto3.client('iot') iot_client.cancel_job_execution(jobId=f'AFR_OTA-{otaUpdateId}', thingName=thing_name, force=True) - # Do another OTA update, this should succeed. + + # Do another OTA update with second build, this should succeed. + self._otaConfig['ota_firmware_file_path'] = str(firmware) otaUpdateId = self._otaAwsAgent.quickCreateOtaUpdate(self._otaConfig, [self._protocol]) return self.getTestResultAfterOtaUpdateCompletion(otaUpdateId) diff --git a/tools/ota_e2e_tests/aws_ota_test/aws_ota_test_case_disconnect_cancel_update.py b/tools/ota_e2e_tests/aws_ota_test/aws_ota_test_case_disconnect_cancel_update.py index 82f3f93c145..3cb2c80323a 100644 --- a/tools/ota_e2e_tests/aws_ota_test/aws_ota_test_case_disconnect_cancel_update.py +++ b/tools/ota_e2e_tests/aws_ota_test/aws_ota_test_case_disconnect_cancel_update.py @@ -24,6 +24,7 @@ """ import time +import shutil from pathlib import Path import boto3 from botocore.exceptions import ClientError @@ -74,11 +75,16 @@ def run(self): self._otaProject.setApplicationVersion(0, 9, 1) # Build the OTA image. self._otaProject.buildProject() - # Start an OTA Update. - otaUpdateId = self._otaAwsAgent.quickCreateOtaUpdate(self._otaConfig, [self._protocol]) + # Make a copy of the firmware. + firmware = Path(self._otaConfig['ota_firmware_file_path']) + first_firmware = firmware.with_name('first' + firmware.suffix) + shutil.copy(firmware, first_firmware) # Prepare another image to be updated later self._otaProject.setApplicationVersion(0, 9, 2) self._otaProject.buildProject() + # Start first OTA Update. + self._otaConfig['ota_firmware_file_path'] = str(first_firmware) + otaUpdateId = self._otaAwsAgent.quickCreateOtaUpdate(self._otaConfig, [self._protocol]) # Wait until the job is in progress. thing_name = self._otaAwsAgent._iotThing.thing_name @@ -90,6 +96,9 @@ def run(self): if exec_status == 'QUEUED': return OtaTestResult(testName=self._name, result=OtaTestResult.ERROR, summary='Timeout waiting for OTA job status.') + if exec_status == 'SUCCEEDED': + return OtaTestResult(testName=self._name, result=OtaTestResult.ERROR, + summary='OTA update complete too fast before we can cancel the job.') # Connect to IoT core with same thing name, this should disconnect the device from IoT core. # Note: currently there's no way to load the cert/key from memory, this is a limitation from @@ -114,7 +123,8 @@ def run(self): iot_client = boto3.client('iot') iot_client.cancel_job_execution(jobId=f'AFR_OTA-{otaUpdateId}', thingName=thing_name, force=True) - # Do another OTA update, this should succeed. + # Do another OTA update with second build, this should succeed. + self._otaConfig['ota_firmware_file_path'] = str(firmware) otaUpdateId = self._otaAwsAgent.quickCreateOtaUpdate(self._otaConfig, [self._protocol]) return self.getTestResultAfterOtaUpdateCompletion(otaUpdateId) else: From 7bbbca130db60c58d05c079331ee23772f371e43 Mon Sep 17 00:00:00 2001 From: Tiangang Song Date: Fri, 14 Aug 2020 17:30:14 -0700 Subject: [PATCH 2/4] Switch to junitparser for OTA E2E --- .../aws_ota_test/aws_ota_test_main.py | 21 +- tools/ota_e2e_tests/poetry.lock | 181 +++++++++--------- tools/ota_e2e_tests/pyproject.toml | 2 +- 3 files changed, 101 insertions(+), 103 deletions(-) diff --git a/tools/ota_e2e_tests/aws_ota_test/aws_ota_test_main.py b/tools/ota_e2e_tests/aws_ota_test/aws_ota_test_main.py index 947454c003a..bd68d61bafd 100644 --- a/tools/ota_e2e_tests/aws_ota_test/aws_ota_test_main.py +++ b/tools/ota_e2e_tests/aws_ota_test/aws_ota_test_main.py @@ -30,7 +30,8 @@ from threading import Thread from functools import reduce from operator import add -from junit_xml import TestSuite, TestCase + +import junitparser as junit from .aws_ota_test_runner import * from .aws_ota_test_result import OtaTestResult @@ -154,20 +155,20 @@ def createJunitTestResults(boardToResults, fileName): boardToResults(dict[str:obj(OtaTestResult)]): Dictionary of the board name to it's OtaTestResult. fileName: The name of the junit test file to create. """ - testSuites = [] + report = junit.JUnitXml() for board in boardToResults.keys(): - testCases = [] + group_suite = junit.TestSuite(board + '.OTAEndToEndTests') for otaTestResult in boardToResults[board]: - testCase = TestCase(otaTestResult.testName, classname=board + '.OTAEndToEndTests') - testCases.append(testCase) + test_case = junit.TestCase(otaTestResult.testName) if otaTestResult.result == OtaTestResult.FAIL: - testCases[-1].add_failure_info(message=otaTestResult.summary) + test_case.result = junit.Failure(otaTestResult.summary) elif otaTestResult.result == OtaTestResult.ERROR: - testCases[-1].add_skipped_info(message=otaTestResult.summary) - testSuites.append(TestSuite(board, test_cases=testCases, package=board)) + test_case.result = junit.Skipped(otaTestResult.summary) + group_suite.add_testcase(test_case) + report.add_testsuite(group_suite) - with open(fileName, 'w') as f: - TestSuite.to_file(f, testSuites) + report.update_statistics() + report.write(fileName, pretty=True) def getStageParameters(args): stageParams = {} diff --git a/tools/ota_e2e_tests/poetry.lock b/tools/ota_e2e_tests/poetry.lock index 731f97a8048..8a3788a0a21 100644 --- a/tools/ota_e2e_tests/poetry.lock +++ b/tools/ota_e2e_tests/poetry.lock @@ -4,10 +4,10 @@ description = "The AWS SDK for Python" name = "boto3" optional = false python-versions = "*" -version = "1.11.5" +version = "1.14.43" [package.dependencies] -botocore = ">=1.14.5,<1.15.0" +botocore = ">=1.17.43,<1.18.0" jmespath = ">=0.7.1,<1.0.0" s3transfer = ">=0.3.0,<0.4.0" @@ -17,13 +17,13 @@ description = "Low-level, data-driven core of boto 3." name = "botocore" optional = false python-versions = "*" -version = "1.14.5" +version = "1.17.43" [package.dependencies] docutils = ">=0.10,<0.16" jmespath = ">=0.7.1,<1.0.0" python-dateutil = ">=2.1,<3.0.0" -urllib3 = ">=1.20,<1.26" +urllib3 = {version = ">=1.20,<1.26", markers = "python_version != \"3.4\""} [[package]] category = "main" @@ -31,7 +31,7 @@ description = "Foreign Function Interface for Python calling C code." name = "cffi" optional = false python-versions = "*" -version = "1.13.2" +version = "1.14.1" [package.dependencies] pycparser = "*" @@ -41,18 +41,19 @@ category = "main" description = "cryptography is a package which provides cryptographic recipes and primitives to Python developers." name = "cryptography" optional = false -python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*" -version = "2.8" +python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*" +version = "3.0" [package.dependencies] cffi = ">=1.8,<1.11.3 || >1.11.3" six = ">=1.4.1" [package.extras] -docs = ["sphinx (>=1.6.5,<1.8.0 || >1.8.0)", "sphinx-rtd-theme"] +docs = ["sphinx (>=1.6.5,<1.8.0 || >1.8.0,<3.1.0 || >3.1.0,<3.1.1 || >3.1.1)", "sphinx-rtd-theme"] docstest = ["doc8", "pyenchant (>=1.6.11)", "twine (>=1.12.0)", "sphinxcontrib-spelling (>=4.0.1)"] idna = ["idna (>=2.1)"] -pep8test = ["flake8", "flake8-import-order", "pep8-naming"] +pep8test = ["black", "flake8", "flake8-import-order", "pep8-naming"] +ssh = ["bcrypt (>=3.1.5)"] test = ["pytest (>=3.6.0,<3.9.0 || >3.9.0,<3.9.1 || >3.9.1,<3.9.2 || >3.9.2)", "pretend", "iso8601", "pytz", "hypothesis (>=1.11.4,<3.79.2 || >3.79.2)"] [[package]] @@ -76,19 +77,19 @@ category = "main" description = "JSON Matching Expressions" name = "jmespath" optional = false -python-versions = "*" -version = "0.9.4" +python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" +version = "0.10.0" [[package]] category = "main" -description = "Creates JUnit XML test result documents that can be read by tools such as Jenkins" -name = "junit-xml" +description = "Manipulates JUnit/xUnit Result XML files" +name = "junitparser" optional = false python-versions = "*" -version = "1.8" +version = "1.4.1" [package.dependencies] -six = "*" +future = "*" [[package]] category = "main" @@ -107,7 +108,7 @@ description = "C parser in Python" name = "pycparser" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" -version = "2.19" +version = "2.20" [[package]] category = "main" @@ -158,10 +159,10 @@ description = "An Amazon S3 Transfer Manager" name = "s3transfer" optional = false python-versions = "*" -version = "0.3.1" +version = "0.3.3" [package.dependencies] -botocore = ">=1.12.36,<2.0.0" +botocore = ">=1.12.36,<2.0a.0" [[package]] category = "main" @@ -169,91 +170,85 @@ description = "Python 2 and 3 compatibility utilities" name = "six" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" -version = "1.14.0" +version = "1.15.0" [[package]] category = "main" description = "HTTP library with thread-safe connection pooling, file post, and more." name = "urllib3" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, <4" -version = "1.25.7" +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, <4" +version = "1.25.10" [package.extras] brotli = ["brotlipy (>=0.6.0)"] -secure = ["pyOpenSSL (>=0.14)", "cryptography (>=1.3.4)", "idna (>=2.0.0)", "certifi", "ipaddress"] +secure = ["certifi", "cryptography (>=1.3.4)", "idna (>=2.0.0)", "pyOpenSSL (>=0.14)", "ipaddress"] socks = ["PySocks (>=1.5.6,<1.5.7 || >1.5.7,<2.0)"] [metadata] -content-hash = "314433c1fb895c575324a2a87ba390683a7129ecd3f6866bc8efcc5016126701" +content-hash = "8486964c5d538b20c7f0e50a54c738bc86d4ed911199c2a2abaabf11f73a2827" +lock-version = "1.1" python-versions = "^3.6" [metadata.files] boto3 = [ - {file = "boto3-1.11.5-py2.py3-none-any.whl", hash = "sha256:ca36aabfa5e7fa9ee8f84f82c3faffb4ffe078923f935f572f70dc49154ef6a0"}, - {file = "boto3-1.11.5.tar.gz", hash = "sha256:7aaccacc199cd633b5ac14f0d544c9d592c53275a79cf4d230a9f66215331665"}, + {file = "boto3-1.14.43-py2.py3-none-any.whl", hash = "sha256:640a8372ce0edfbb84a8f63584a0b64c78d61a751a27c2a47f92d2ebaf021ce4"}, + {file = "boto3-1.14.43.tar.gz", hash = "sha256:a6c9a3d3abbad2ff2e5751af599492a9271633a7c9fef343482524464c53e451"}, ] botocore = [ - {file = "botocore-1.14.5-py2.py3-none-any.whl", hash = "sha256:f0feffde6e1312c6361a96e24385a58889683a3d6a007be4d4804bc209384b3f"}, - {file = "botocore-1.14.5.tar.gz", hash = "sha256:96a16e64c96d34fa2e535c1d5a0024bf55eee853b939be0331318cd060b3d395"}, + {file = "botocore-1.17.43-py2.py3-none-any.whl", hash = "sha256:f8801ce7f7603922ccab1c86c448e802f94183e31d99457e85fb9985a20d3abc"}, + {file = "botocore-1.17.43.tar.gz", hash = "sha256:3fb144d2b5d705127f394f7483737ece6fa79577ca7c493e4f42047ac8636200"}, ] cffi = [ - {file = "cffi-1.13.2-cp27-cp27m-macosx_10_6_intel.whl", hash = "sha256:3c9fff570f13480b201e9ab69453108f6d98244a7f495e91b6c654a47486ba43"}, - {file = "cffi-1.13.2-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:2c5e309ec482556397cb21ede0350c5e82f0eb2621de04b2633588d118da4396"}, - {file = "cffi-1.13.2-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:19db0cdd6e516f13329cba4903368bff9bb5a9331d3410b1b448daaadc495e54"}, - {file = "cffi-1.13.2-cp27-cp27m-win32.whl", hash = "sha256:5c4fae4e9cdd18c82ba3a134be256e98dc0596af1e7285a3d2602c97dcfa5159"}, - {file = "cffi-1.13.2-cp27-cp27m-win_amd64.whl", hash = "sha256:32a262e2b90ffcfdd97c7a5e24a6012a43c61f1f5a57789ad80af1d26c6acd97"}, - {file = "cffi-1.13.2-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:4a43c91840bda5f55249413037b7a9b79c90b1184ed504883b72c4df70778579"}, - {file = "cffi-1.13.2-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:8169cf44dd8f9071b2b9248c35fc35e8677451c52f795daa2bb4643f32a540bc"}, - {file = "cffi-1.13.2-cp34-cp34m-macosx_10_6_intel.whl", hash = "sha256:71a608532ab3bd26223c8d841dde43f3516aa5d2bf37b50ac410bb5e99053e8f"}, - {file = "cffi-1.13.2-cp34-cp34m-manylinux1_i686.whl", hash = "sha256:7f627141a26b551bdebbc4855c1157feeef18241b4b8366ed22a5c7d672ef858"}, - {file = "cffi-1.13.2-cp34-cp34m-manylinux1_x86_64.whl", hash = "sha256:0b49274afc941c626b605fb59b59c3485c17dc776dc3cc7cc14aca74cc19cc42"}, - {file = "cffi-1.13.2-cp34-cp34m-win32.whl", hash = "sha256:4424e42199e86b21fc4db83bd76909a6fc2a2aefb352cb5414833c030f6ed71b"}, - {file = "cffi-1.13.2-cp34-cp34m-win_amd64.whl", hash = "sha256:7d4751da932caaec419d514eaa4215eaf14b612cff66398dd51129ac22680b20"}, - {file = "cffi-1.13.2-cp35-cp35m-macosx_10_6_intel.whl", hash = "sha256:ccb032fda0873254380aa2bfad2582aedc2959186cce61e3a17abc1a55ff89c3"}, - {file = "cffi-1.13.2-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:dcd65317dd15bc0451f3e01c80da2216a31916bdcffd6221ca1202d96584aa25"}, - {file = "cffi-1.13.2-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:135f69aecbf4517d5b3d6429207b2dff49c876be724ac0c8bf8e1ea99df3d7e5"}, - {file = "cffi-1.13.2-cp35-cp35m-win32.whl", hash = "sha256:7b93a885bb13073afb0aa73ad82059a4c41f4b7d8eb8368980448b52d4c7dc2c"}, - {file = "cffi-1.13.2-cp35-cp35m-win_amd64.whl", hash = "sha256:e570d3ab32e2c2861c4ebe6ffcad6a8abf9347432a37608fe1fbd157b3f0036b"}, - {file = "cffi-1.13.2-cp36-cp36m-macosx_10_6_intel.whl", hash = "sha256:0e3ea92942cb1168e38c05c1d56b0527ce31f1a370f6117f1d490b8dcd6b3a04"}, - {file = "cffi-1.13.2-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:5ecfa867dea6fabe2a58f03ac9186ea64da1386af2159196da51c4904e11d652"}, - {file = "cffi-1.13.2-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:291f7c42e21d72144bb1c1b2e825ec60f46d0a7468f5346841860454c7aa8f57"}, - {file = "cffi-1.13.2-cp36-cp36m-win32.whl", hash = "sha256:62f2578358d3a92e4ab2d830cd1c2049c9c0d0e6d3c58322993cc341bdeac22e"}, - {file = "cffi-1.13.2-cp36-cp36m-win_amd64.whl", hash = "sha256:fd43a88e045cf992ed09fa724b5315b790525f2676883a6ea64e3263bae6549d"}, - {file = "cffi-1.13.2-cp37-cp37m-macosx_10_6_intel.whl", hash = "sha256:d75c461e20e29afc0aee7172a0950157c704ff0dd51613506bd7d82b718e7410"}, - {file = "cffi-1.13.2-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:aa00d66c0fab27373ae44ae26a66a9e43ff2a678bf63a9c7c1a9a4d61172827a"}, - {file = "cffi-1.13.2-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:2e9c80a8c3344a92cb04661115898a9129c074f7ab82011ef4b612f645939f12"}, - {file = "cffi-1.13.2-cp37-cp37m-win32.whl", hash = "sha256:d754f39e0d1603b5b24a7f8484b22d2904fa551fe865fd0d4c3332f078d20d4e"}, - {file = "cffi-1.13.2-cp37-cp37m-win_amd64.whl", hash = "sha256:6471a82d5abea994e38d2c2abc77164b4f7fbaaf80261cb98394d5793f11b12a"}, - {file = "cffi-1.13.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:74a1d8c85fb6ff0b30fbfa8ad0ac23cd601a138f7509dc617ebc65ef305bb98d"}, - {file = "cffi-1.13.2-cp38-cp38-manylinux1_i686.whl", hash = "sha256:42194f54c11abc8583417a7cf4eaff544ce0de8187abaf5d29029c91b1725ad3"}, - {file = "cffi-1.13.2-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:415bdc7ca8c1c634a6d7163d43fb0ea885a07e9618a64bda407e04b04333b7db"}, - {file = "cffi-1.13.2-cp38-cp38-win32.whl", hash = "sha256:6d4f18483d040e18546108eb13b1dfa1000a089bcf8529e30346116ea6240506"}, - {file = "cffi-1.13.2-cp38-cp38-win_amd64.whl", hash = "sha256:2781e9ad0e9d47173c0093321bb5435a9dfae0ed6a762aabafa13108f5f7b2ba"}, - {file = "cffi-1.13.2.tar.gz", hash = "sha256:599a1e8ff057ac530c9ad1778293c665cb81a791421f46922d80a86473c13346"}, + {file = "cffi-1.14.1-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:66dd45eb9530e3dde8f7c009f84568bc7cac489b93d04ac86e3111fb46e470c2"}, + {file = "cffi-1.14.1-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:4f53e4128c81ca3212ff4cf097c797ab44646a40b42ec02a891155cd7a2ba4d8"}, + {file = "cffi-1.14.1-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:833401b15de1bb92791d7b6fb353d4af60dc688eaa521bd97203dcd2d124a7c1"}, + {file = "cffi-1.14.1-cp27-cp27m-win32.whl", hash = "sha256:26f33e8f6a70c255767e3c3f957ccafc7f1f706b966e110b855bfe944511f1f9"}, + {file = "cffi-1.14.1-cp27-cp27m-win_amd64.whl", hash = "sha256:b87dfa9f10a470eee7f24234a37d1d5f51e5f5fa9eeffda7c282e2b8f5162eb1"}, + {file = "cffi-1.14.1-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:effd2ba52cee4ceff1a77f20d2a9f9bf8d50353c854a282b8760ac15b9833168"}, + {file = "cffi-1.14.1-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:bac0d6f7728a9cc3c1e06d4fcbac12aaa70e9379b3025b27ec1226f0e2d404cf"}, + {file = "cffi-1.14.1-cp35-cp35m-macosx_10_9_x86_64.whl", hash = "sha256:d6033b4ffa34ef70f0b8086fd4c3df4bf801fee485a8a7d4519399818351aa8e"}, + {file = "cffi-1.14.1-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:8416ed88ddc057bab0526d4e4e9f3660f614ac2394b5e019a628cdfff3733849"}, + {file = "cffi-1.14.1-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:892daa86384994fdf4856cb43c93f40cbe80f7f95bb5da94971b39c7f54b3a9c"}, + {file = "cffi-1.14.1-cp35-cp35m-win32.whl", hash = "sha256:c991112622baee0ae4d55c008380c32ecfd0ad417bcd0417ba432e6ba7328caa"}, + {file = "cffi-1.14.1-cp35-cp35m-win_amd64.whl", hash = "sha256:fcf32bf76dc25e30ed793145a57426064520890d7c02866eb93d3e4abe516948"}, + {file = "cffi-1.14.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:f960375e9823ae6a07072ff7f8a85954e5a6434f97869f50d0e41649a1c8144f"}, + {file = "cffi-1.14.1-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:a6d28e7f14ecf3b2ad67c4f106841218c8ab12a0683b1528534a6c87d2307af3"}, + {file = "cffi-1.14.1-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:cda422d54ee7905bfc53ee6915ab68fe7b230cacf581110df4272ee10462aadc"}, + {file = "cffi-1.14.1-cp36-cp36m-win32.whl", hash = "sha256:4a03416915b82b81af5502459a8a9dd62a3c299b295dcdf470877cb948d655f2"}, + {file = "cffi-1.14.1-cp36-cp36m-win_amd64.whl", hash = "sha256:4ce1e995aeecf7cc32380bc11598bfdfa017d592259d5da00fc7ded11e61d022"}, + {file = "cffi-1.14.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:e23cb7f1d8e0f93addf0cae3c5b6f00324cccb4a7949ee558d7b6ca973ab8ae9"}, + {file = "cffi-1.14.1-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:ddff0b2bd7edcc8c82d1adde6dbbf5e60d57ce985402541cd2985c27f7bec2a0"}, + {file = "cffi-1.14.1-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:f90c2267101010de42f7273c94a1f026e56cbc043f9330acd8a80e64300aba33"}, + {file = "cffi-1.14.1-cp37-cp37m-win32.whl", hash = "sha256:3cd2c044517f38d1b577f05927fb9729d3396f1d44d0c659a445599e79519792"}, + {file = "cffi-1.14.1-cp37-cp37m-win_amd64.whl", hash = "sha256:4fa72a52a906425416f41738728268072d5acfd48cbe7796af07a923236bcf96"}, + {file = "cffi-1.14.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:267adcf6e68d77ba154334a3e4fc921b8e63cbb38ca00d33d40655d4228502bc"}, + {file = "cffi-1.14.1-cp38-cp38-manylinux1_i686.whl", hash = "sha256:d3148b6ba3923c5850ea197a91a42683f946dba7e8eb82dfa211ab7e708de939"}, + {file = "cffi-1.14.1-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:98be759efdb5e5fa161e46d404f4e0ce388e72fbf7d9baf010aff16689e22abe"}, + {file = "cffi-1.14.1-cp38-cp38-win32.whl", hash = "sha256:6923d077d9ae9e8bacbdb1c07ae78405a9306c8fd1af13bfa06ca891095eb995"}, + {file = "cffi-1.14.1-cp38-cp38-win_amd64.whl", hash = "sha256:b1d6ebc891607e71fd9da71688fcf332a6630b7f5b7f5549e6e631821c0e5d90"}, + {file = "cffi-1.14.1.tar.gz", hash = "sha256:b2a2b0d276a136146e012154baefaea2758ef1f56ae9f4e01c612b0831e0bd2f"}, ] cryptography = [ - {file = "cryptography-2.8-cp27-cp27m-macosx_10_6_intel.whl", hash = "sha256:fb81c17e0ebe3358486cd8cc3ad78adbae58af12fc2bf2bc0bb84e8090fa5ce8"}, - {file = "cryptography-2.8-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:44ff04138935882fef7c686878e1c8fd80a723161ad6a98da31e14b7553170c2"}, - {file = "cryptography-2.8-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:369d2346db5934345787451504853ad9d342d7f721ae82d098083e1f49a582ad"}, - {file = "cryptography-2.8-cp27-cp27m-win32.whl", hash = "sha256:df6b4dca2e11865e6cfbfb708e800efb18370f5a46fd601d3755bc7f85b3a8a2"}, - {file = "cryptography-2.8-cp27-cp27m-win_amd64.whl", hash = "sha256:7f09806ed4fbea8f51585231ba742b58cbcfbfe823ea197d8c89a5e433c7e912"}, - {file = "cryptography-2.8-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:58363dbd966afb4f89b3b11dfb8ff200058fbc3b947507675c19ceb46104b48d"}, - {file = "cryptography-2.8-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:6ec280fb24d27e3d97aa731e16207d58bd8ae94ef6eab97249a2afe4ba643d42"}, - {file = "cryptography-2.8-cp34-abi3-macosx_10_6_intel.whl", hash = "sha256:b43f53f29816ba1db8525f006fa6f49292e9b029554b3eb56a189a70f2a40879"}, - {file = "cryptography-2.8-cp34-abi3-manylinux1_x86_64.whl", hash = "sha256:7270a6c29199adc1297776937a05b59720e8a782531f1f122f2eb8467f9aab4d"}, - {file = "cryptography-2.8-cp34-abi3-manylinux2010_x86_64.whl", hash = "sha256:de96157ec73458a7f14e3d26f17f8128c959084931e8997b9e655a39c8fde9f9"}, - {file = "cryptography-2.8-cp34-cp34m-win32.whl", hash = "sha256:02079a6addc7b5140ba0825f542c0869ff4df9a69c360e339ecead5baefa843c"}, - {file = "cryptography-2.8-cp34-cp34m-win_amd64.whl", hash = "sha256:b0de590a8b0979649ebeef8bb9f54394d3a41f66c5584fff4220901739b6b2f0"}, - {file = "cryptography-2.8-cp35-cp35m-win32.whl", hash = "sha256:ecadccc7ba52193963c0475ac9f6fa28ac01e01349a2ca48509667ef41ffd2cf"}, - {file = "cryptography-2.8-cp35-cp35m-win_amd64.whl", hash = "sha256:90df0cc93e1f8d2fba8365fb59a858f51a11a394d64dbf3ef844f783844cc793"}, - {file = "cryptography-2.8-cp36-cp36m-win32.whl", hash = "sha256:1df22371fbf2004c6f64e927668734070a8953362cd8370ddd336774d6743595"}, - {file = "cryptography-2.8-cp36-cp36m-win_amd64.whl", hash = "sha256:a518c153a2b5ed6b8cc03f7ae79d5ffad7315ad4569b2d5333a13c38d64bd8d7"}, - {file = "cryptography-2.8-cp37-cp37m-win32.whl", hash = "sha256:4b1030728872c59687badcca1e225a9103440e467c17d6d1730ab3d2d64bfeff"}, - {file = "cryptography-2.8-cp37-cp37m-win_amd64.whl", hash = "sha256:d31402aad60ed889c7e57934a03477b572a03af7794fa8fb1780f21ea8f6551f"}, - {file = "cryptography-2.8-cp38-cp38-win32.whl", hash = "sha256:73fd30c57fa2d0a1d7a49c561c40c2f79c7d6c374cc7750e9ac7c99176f6428e"}, - {file = "cryptography-2.8-cp38-cp38-win_amd64.whl", hash = "sha256:971221ed40f058f5662a604bd1ae6e4521d84e6cad0b7b170564cc34169c8f13"}, - {file = "cryptography-2.8.tar.gz", hash = "sha256:3cda1f0ed8747339bbdf71b9f38ca74c7b592f24f65cdb3ab3765e4b02871651"}, + {file = "cryptography-3.0-cp27-cp27m-macosx_10_10_x86_64.whl", hash = "sha256:ab49edd5bea8d8b39a44b3db618e4783ef84c19c8b47286bf05dfdb3efb01c83"}, + {file = "cryptography-3.0-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:124af7255ffc8e964d9ff26971b3a6153e1a8a220b9a685dc407976ecb27a06a"}, + {file = "cryptography-3.0-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:51e40123083d2f946794f9fe4adeeee2922b581fa3602128ce85ff813d85b81f"}, + {file = "cryptography-3.0-cp27-cp27m-win32.whl", hash = "sha256:dea0ba7fe6f9461d244679efa968d215ea1f989b9c1957d7f10c21e5c7c09ad6"}, + {file = "cryptography-3.0-cp27-cp27m-win_amd64.whl", hash = "sha256:8ecf9400d0893836ff41b6f977a33972145a855b6efeb605b49ee273c5e6469f"}, + {file = "cryptography-3.0-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:0c608ff4d4adad9e39b5057de43657515c7da1ccb1807c3a27d4cf31fc923b4b"}, + {file = "cryptography-3.0-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:bec7568c6970b865f2bcebbe84d547c52bb2abadf74cefce396ba07571109c67"}, + {file = "cryptography-3.0-cp35-abi3-macosx_10_10_x86_64.whl", hash = "sha256:0cbfed8ea74631fe4de00630f4bb592dad564d57f73150d6f6796a24e76c76cd"}, + {file = "cryptography-3.0-cp35-abi3-manylinux1_x86_64.whl", hash = "sha256:a09fd9c1cca9a46b6ad4bea0a1f86ab1de3c0c932364dbcf9a6c2a5eeb44fa77"}, + {file = "cryptography-3.0-cp35-abi3-manylinux2010_x86_64.whl", hash = "sha256:ce82cc06588e5cbc2a7df3c8a9c778f2cb722f56835a23a68b5a7264726bb00c"}, + {file = "cryptography-3.0-cp35-cp35m-win32.whl", hash = "sha256:9367d00e14dee8d02134c6c9524bb4bd39d4c162456343d07191e2a0b5ec8b3b"}, + {file = "cryptography-3.0-cp35-cp35m-win_amd64.whl", hash = "sha256:384d7c681b1ab904fff3400a6909261cae1d0939cc483a68bdedab282fb89a07"}, + {file = "cryptography-3.0-cp36-cp36m-win32.whl", hash = "sha256:4d355f2aee4a29063c10164b032d9fa8a82e2c30768737a2fd56d256146ad559"}, + {file = "cryptography-3.0-cp36-cp36m-win_amd64.whl", hash = "sha256:45741f5499150593178fc98d2c1a9c6722df88b99c821ad6ae298eff0ba1ae71"}, + {file = "cryptography-3.0-cp37-cp37m-win32.whl", hash = "sha256:8ecef21ac982aa78309bb6f092d1677812927e8b5ef204a10c326fc29f1367e2"}, + {file = "cryptography-3.0-cp37-cp37m-win_amd64.whl", hash = "sha256:4b9303507254ccb1181d1803a2080a798910ba89b1a3c9f53639885c90f7a756"}, + {file = "cryptography-3.0-cp38-cp38-win32.whl", hash = "sha256:8713ddb888119b0d2a1462357d5946b8911be01ddbf31451e1d07eaa5077a261"}, + {file = "cryptography-3.0-cp38-cp38-win_amd64.whl", hash = "sha256:bea0b0468f89cdea625bb3f692cd7a4222d80a6bdafd6fb923963f2b9da0e15f"}, + {file = "cryptography-3.0.tar.gz", hash = "sha256:8e924dbc025206e97756e8903039662aa58aa9ba357d8e1d8fc29e3092322053"}, ] docutils = [ {file = "docutils-0.15.2-py2-none-any.whl", hash = "sha256:9e4d7ecfc600058e07ba661411a2b7de2fd0fafa17d1a7f7361cd47b1175c827"}, @@ -264,17 +259,19 @@ future = [ {file = "future-0.17.1.tar.gz", hash = "sha256:67045236dcfd6816dc439556d009594abf643e5eb48992e36beac09c2ca659b8"}, ] jmespath = [ - {file = "jmespath-0.9.4-py2.py3-none-any.whl", hash = "sha256:3720a4b1bd659dd2eecad0666459b9788813e032b83e7ba58578e48254e0a0e6"}, - {file = "jmespath-0.9.4.tar.gz", hash = "sha256:bde2aef6f44302dfb30320115b17d030798de8c4110e28d5cf6cf91a7a31074c"}, + {file = "jmespath-0.10.0-py2.py3-none-any.whl", hash = "sha256:cdf6525904cc597730141d61b36f2e4b8ecc257c420fa2f4549bac2c2d0cb72f"}, + {file = "jmespath-0.10.0.tar.gz", hash = "sha256:b85d0567b8666149a93172712e68920734333c0ce7e89b78b3e987f71e5ed4f9"}, ] -junit-xml = [ - {file = "junit-xml-1.8.tar.gz", hash = "sha256:602f1c480a19d64edb452bf7632f76b5f2cb92c1938c6e071dcda8ff9541dc21"}, +junitparser = [ + {file = "junitparser-1.4.1-py2.py3-none-any.whl", hash = "sha256:9d8cd9909f115d4e0fe1f445ebd816524123c34cf0178c48bd4778d50a5f2617"}, + {file = "junitparser-1.4.1.tar.gz", hash = "sha256:6e67cf080235be7158ce3fe35fa9a327bf577080c02f5c646d4761e513bb2131"}, ] paho-mqtt = [ {file = "paho-mqtt-1.5.0.tar.gz", hash = "sha256:e3d286198baaea195c8b3bc221941d25a3ab0e1507fc1779bdb7473806394be4"}, ] pycparser = [ - {file = "pycparser-2.19.tar.gz", hash = "sha256:a988718abfad80b6b157acce7bf130a30876d27603738ac39f140993246b25b3"}, + {file = "pycparser-2.20-py2.py3-none-any.whl", hash = "sha256:7582ad22678f0fcd81102833f60ef8d0e57288b6b5fb00323d101be910e35705"}, + {file = "pycparser-2.20.tar.gz", hash = "sha256:2d475327684562c3a96cc71adf7dc8c4f0565175cf86b6d7a404ff4c771f15f0"}, ] pyopenssl = [ {file = "pyOpenSSL-18.0.0-py2.py3-none-any.whl", hash = "sha256:26ff56a6b5ecaf3a2a59f132681e2a80afcc76b4f902f612f518f92c2a1bf854"}, @@ -293,14 +290,14 @@ python-dateutil = [ {file = "python_dateutil-2.8.1-py2.py3-none-any.whl", hash = "sha256:75bb3f31ea686f1197762692a9ee6a7550b59fc6ca3a1f4b5d7e32fb98e2da2a"}, ] s3transfer = [ - {file = "s3transfer-0.3.1-py2.py3-none-any.whl", hash = "sha256:80ed96731b3bd77395cd6197246069092015e1124164b2c152c8f741a823dd04"}, - {file = "s3transfer-0.3.1.tar.gz", hash = "sha256:248dffd2de2dfb870c507b412fc22ed37cd3255293e293c395158e7c55fbe5f9"}, + {file = "s3transfer-0.3.3-py2.py3-none-any.whl", hash = "sha256:2482b4259524933a022d59da830f51bd746db62f047d6eb213f2f8855dcb8a13"}, + {file = "s3transfer-0.3.3.tar.gz", hash = "sha256:921a37e2aefc64145e7b73d50c71bb4f26f46e4c9f414dc648c6245ff92cf7db"}, ] six = [ - {file = "six-1.14.0-py2.py3-none-any.whl", hash = "sha256:8f3cd2e254d8f793e7f3d6d9df77b92252b52637291d0f0da013c76ea2724b6c"}, - {file = "six-1.14.0.tar.gz", hash = "sha256:236bdbdce46e6e6a3d61a337c0f8b763ca1e8717c03b369e87a7ec7ce1319c0a"}, + {file = "six-1.15.0-py2.py3-none-any.whl", hash = "sha256:8b74bedcbbbaca38ff6d7491d76f2b06b3592611af620f8426e82dddb04a5ced"}, + {file = "six-1.15.0.tar.gz", hash = "sha256:30639c035cdb23534cd4aa2dd52c3bf48f06e5f4a941509c8bafd8ce11080259"}, ] urllib3 = [ - {file = "urllib3-1.25.7-py2.py3-none-any.whl", hash = "sha256:a8a318824cc77d1fd4b2bec2ded92646630d7fe8619497b142c84a9e6f5a7293"}, - {file = "urllib3-1.25.7.tar.gz", hash = "sha256:f3c5fd51747d450d4dcf6f923c81f78f811aab8205fda64b0aba34a4e48b0745"}, + {file = "urllib3-1.25.10-py2.py3-none-any.whl", hash = "sha256:e7983572181f5e1522d9c98453462384ee92a0be7fac5f1413a1e35c56cc0461"}, + {file = "urllib3-1.25.10.tar.gz", hash = "sha256:91056c15fa70756691db97756772bb1eb9678fa585d9184f24534b100dc60f4a"}, ] diff --git a/tools/ota_e2e_tests/pyproject.toml b/tools/ota_e2e_tests/pyproject.toml index 7a21713bb4d..c388d00dc77 100644 --- a/tools/ota_e2e_tests/pyproject.toml +++ b/tools/ota_e2e_tests/pyproject.toml @@ -8,7 +8,7 @@ license = "MIT" [tool.poetry.dependencies] python = "^3.6" pyserial = "^3.4" -junit-xml = "^1.8" +junitparser = "^1.4.1" boto3 = "^1.9" pyopenssl = "^18.0.0" future = "^0.17.1" From 8242cc7bf9bb46b2b368e03fd4fa685028af7f8a Mon Sep 17 00:00:00 2001 From: Tiangang Song Date: Fri, 14 Aug 2020 18:30:24 -0700 Subject: [PATCH 3/4] Add OtaTest2UpdatesCancel1st test case --- tools/ota_e2e_tests/aws_ota_test/aws_ota_test_case_factory.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/ota_e2e_tests/aws_ota_test/aws_ota_test_case_factory.py b/tools/ota_e2e_tests/aws_ota_test/aws_ota_test_case_factory.py index 4cf1c705bac..e437d706bce 100644 --- a/tools/ota_e2e_tests/aws_ota_test/aws_ota_test_case_factory.py +++ b/tools/ota_e2e_tests/aws_ota_test/aws_ota_test_case_factory.py @@ -26,6 +26,7 @@ from .aws_ota_test_case_greater_version import OtaTestGreaterVersion from .aws_ota_test_case_back_to_back_switch_protocol import OtaTestBackToBackSwitchProtocol from .aws_ota_test_case_default_data_protocol import OtaTestDefaultDataProtocol +from .aws_ota_test_case_2_updates_cancel_1st import OtaTest2UpdatesCancel1st from .aws_ota_test_case_disconnect_cancel_update import OtaTestDisconnectCancelUpdate from .aws_ota_test_case_disconnect_resume import OtaTestDisconnectResume from .aws_ota_test_case_presigned_url_expired import OtaTestPresignedUrlExpired From 815571393b48e73f46eb80280e11e02d709d9c9b Mon Sep 17 00:00:00 2001 From: Tiangang Song Date: Fri, 14 Aug 2020 20:24:37 -0700 Subject: [PATCH 4/4] Save firmware to afr root folder When rebuilding, the whole build folder might get deleted. To preserve the previous build image, copy it to AFR root dir --- .../aws_ota_test/aws_ota_test_case_2_updates_cancel_1st.py | 2 +- .../aws_ota_test/aws_ota_test_case_cancel_then_update.py | 2 +- .../aws_ota_test/aws_ota_test_case_disconnect_cancel_update.py | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/tools/ota_e2e_tests/aws_ota_test/aws_ota_test_case_2_updates_cancel_1st.py b/tools/ota_e2e_tests/aws_ota_test/aws_ota_test_case_2_updates_cancel_1st.py index 3a7a670e4ba..9f9da787d8f 100644 --- a/tools/ota_e2e_tests/aws_ota_test/aws_ota_test_case_2_updates_cancel_1st.py +++ b/tools/ota_e2e_tests/aws_ota_test/aws_ota_test_case_2_updates_cancel_1st.py @@ -59,7 +59,7 @@ def run(self): self._otaProject.buildProject() # Make a copy of the firmware. firmware = Path(self._otaConfig['ota_firmware_file_path']) - first_firmware = firmware.with_name('first' + firmware.suffix) + first_firmware = Path(self._otaProject._projectRootDir) / firmware.name shutil.copy(firmware, first_firmware) # Prepare another image to be updated. self._otaProject.setApplicationVersion(0, 9, 2) diff --git a/tools/ota_e2e_tests/aws_ota_test/aws_ota_test_case_cancel_then_update.py b/tools/ota_e2e_tests/aws_ota_test/aws_ota_test_case_cancel_then_update.py index 43c24f50785..c3ac3e22762 100644 --- a/tools/ota_e2e_tests/aws_ota_test/aws_ota_test_case_cancel_then_update.py +++ b/tools/ota_e2e_tests/aws_ota_test/aws_ota_test_case_cancel_then_update.py @@ -60,7 +60,7 @@ def run(self): self._otaProject.buildProject() # Make a copy of the firmware. firmware = Path(self._otaConfig['ota_firmware_file_path']) - first_firmware = firmware.with_name('first' + firmware.suffix) + first_firmware = Path(self._otaProject._projectRootDir) / firmware.name shutil.copy(firmware, first_firmware) # Prepare another image to be updated later self._otaProject.setApplicationVersion(0, 9, 2) diff --git a/tools/ota_e2e_tests/aws_ota_test/aws_ota_test_case_disconnect_cancel_update.py b/tools/ota_e2e_tests/aws_ota_test/aws_ota_test_case_disconnect_cancel_update.py index 3cb2c80323a..f1faacffc88 100644 --- a/tools/ota_e2e_tests/aws_ota_test/aws_ota_test_case_disconnect_cancel_update.py +++ b/tools/ota_e2e_tests/aws_ota_test/aws_ota_test_case_disconnect_cancel_update.py @@ -77,7 +77,7 @@ def run(self): self._otaProject.buildProject() # Make a copy of the firmware. firmware = Path(self._otaConfig['ota_firmware_file_path']) - first_firmware = firmware.with_name('first' + firmware.suffix) + first_firmware = Path(self._otaProject._projectRootDir) / firmware.name shutil.copy(firmware, first_firmware) # Prepare another image to be updated later self._otaProject.setApplicationVersion(0, 9, 2)