From bf1c746750e9e33f6b4926eef1a82adc434fcdb9 Mon Sep 17 00:00:00 2001 From: Fabricio-ESP Date: Wed, 20 Nov 2024 17:15:28 +0000 Subject: [PATCH 01/20] Add test failure description --- tests/runs/variation1.test.js | 27 +++++----- tests/script/commandLineArguments.test.js | 15 ++++-- tests/script/installCustom.test.js | 44 ++++++++-------- tests/script/installWizard.test.js | 62 ++++++++++++++++++----- tests/script/postInstall.test.js | 42 +++++++++++---- tests/script/prerequisites.test.js | 21 +++++--- 6 files changed, 144 insertions(+), 67 deletions(-) diff --git a/tests/runs/variation1.test.js b/tests/runs/variation1.test.js index 2187896..b98d153 100644 --- a/tests/runs/variation1.test.js +++ b/tests/runs/variation1.test.js @@ -26,11 +26,18 @@ if (process.env.EIM_FILE_PATH) { logger.debug(`Starting custom installation using EIM on ${pathToEim}`); -const installPath = path.join(os.homedir(), ".espressif2"); -const targetList = ["esp32s2"]; -const idfVersionList = ["v5.2.3"]; -const recursiveSubmodules = true; -const pathToProjectFolder = path.join(os.homedir(), ".espressif2/project"); +const targetList = ["esp32s2"]; // targets used for IDF installation +const idfVersionList = ["v5.2.3"]; // IDF versions to be installed +const installFolder = ".espressif2"; +const projectFolder = "project"; + +let installArgs = []; +installArgs.push(`-p ${path.join(os.homedir(), installFolder)}`); // Install Path +installArgs.push(`-t ${targetList.join(",")}`); // Targets (in case of multiple separate with ,) +installArgs.push(`-i ${idfVersionList.join(",")}`); // IDF versions (in case of multiple separate with ,) +installArgs.push(`-m https://github.com`); // IDF tools mirror +installArgs.push(`--idf-mirror https://github.com`); // ESP-IDF mirror +installArgs.push(`-r true`); // recursive submodules init const pathToIDFScript = os.platform() !== "win32" @@ -44,17 +51,11 @@ const pathToIDFScript = describe("Installation using custom settings", function () { this.timeout(2400000); - runInstallCustom( - pathToEim, - installPath, - targetList.join(","), - idfVersionList.join(","), - recursiveSubmodules - ); + runInstallCustom(pathToEim, installArgs); runPostInstallTest( pathToIDFScript, - pathToProjectFolder, + path.join(os.homedir(), installFolder, projectFolder), targetList[0], "esp32c6" ); diff --git a/tests/script/commandLineArguments.test.js b/tests/script/commandLineArguments.test.js index f17cd65..cb3b54c 100644 --- a/tests/script/commandLineArguments.test.js +++ b/tests/script/commandLineArguments.test.js @@ -28,15 +28,19 @@ export function runArgumentsTests(pathToEim, eimVersion) { await testRunner.start(); testRunner.sendInput(`${pathToEim} -V\r`); const meetVersion = await testRunner.waitForOutput(eimVersion); - expect(meetVersion).to.be.true; + expect(meetVersion, "EIM showing incorrect version number").to.be + .true; }); it("should show help with --help argument", async function () { await testRunner.start(); testRunner.sendInput(`${pathToEim} --help\r`); const printHelp = await testRunner.waitForOutput("Options:"); - expect(printHelp).to.be.true; - expect(testRunner.output).to.include("Usage:"); + expect(printHelp, "EIM failed to print help options").to.be.true; + expect( + testRunner.output, + "EIM failed to print usage help" + ).to.include("Usage:"); }); it("should handle invalid arguments", async function () { @@ -45,7 +49,10 @@ export function runArgumentsTests(pathToEim, eimVersion) { const wrongArgument = await testRunner.waitForOutput( "unexpected argument" ); - expect(wrongArgument).to.be.true; + expect( + wrongArgument, + "Missing error when sending non-existing argument" + ).to.be.true; }); }); } diff --git a/tests/script/installCustom.test.js b/tests/script/installCustom.test.js index f78995d..b0df40f 100644 --- a/tests/script/installCustom.test.js +++ b/tests/script/installCustom.test.js @@ -3,14 +3,8 @@ import { describe, it, before, after, beforeEach, afterEach } from "mocha"; import { InteractiveCLITestRunner } from "../classes/CLITestRunner.class.js"; import logger from "../classes/logger.class.js"; -export function runInstallCustom( - pathToEim, - installPath, - targetList, - idfVersionList, - recursiveSubmodules -) { - describe("run custom installation using given parameters", function () { +export function runInstallCustom(pathToEim, args = []) { + describe("Run custom installation using given parameters", function () { let testRunner = null; before(async function () { @@ -29,6 +23,7 @@ export function runInstallCustom( logger.info( `Terminal output on failure: >>\r ${testRunner.output}` ); + testRunner.sendInput("\x03"); } }); @@ -50,18 +45,23 @@ export function runInstallCustom( it("Should install IDF using specified parameters", async function () { logger.info("Sent command line for IDF installation"); - testRunner.sendInput( - `${pathToEim} -p ${installPath} -t ${targetList} -i ${idfVersionList} --tool-download-folder-name dist --tool-install-folder-name tools --idf-tools-path ./tools/idf_tools.py --tools-json-file tools/tools.json -m https://github.com --idf-mirror https://github.com -r ${recursiveSubmodules}\r` - ); + testRunner.sendInput(`${pathToEim} ${args.join(" ")}\r`); const installationCompleted = await testRunner.waitForOutput( "Do you want to save the installer configuration", 1200000 ); - expect(installationCompleted).to.be.true; - expect(testRunner.output).to.not.include("error"); - expect(testRunner.output).to.include( - "Finished fetching submodules" - ); + expect( + installationCompleted, + "Failed to ask to save installation configuration - failure to install using full arguments on run time" + ).to.be.true; + expect( + testRunner.output, + "Error message during installation" + ).to.not.include("error"); + expect( + testRunner.output, + "Failed to download submodules, missing 'Finished fetching submodules'" + ).to.include("Finished fetching submodules"); logger.info("Installation completed"); testRunner.output = ""; @@ -71,10 +71,14 @@ export function runInstallCustom( "Successfully installed IDF" ); - expect(installationSuccessful).to.be.true; - expect(testRunner.output).to.include( - "Now you can start using IDF tools" - ); + expect( + installationSuccessful, + "Failed to complete installation, missing 'Successfully Installed IDF'" + ).to.be.true; + expect( + testRunner.output, + "Failed to complete installation, missing 'Now you can start using IDF tools'" + ).to.include("Now you can start using IDF tools"); }); }); } diff --git a/tests/script/installWizard.test.js b/tests/script/installWizard.test.js index 2fdb15a..f1672d0 100644 --- a/tests/script/installWizard.test.js +++ b/tests/script/installWizard.test.js @@ -45,8 +45,14 @@ export function runInstallWizardTests(pathToEim) { "Please select all of the target platforms", 20000 ); - expect(selectTargetQuestion).to.be.true; - expect(testRunner.output).to.include("all"); + expect( + selectTargetQuestion, + "Failed to ask for installation targets" + ).to.be.true; + expect( + testRunner.output, + "Failed to offer installation for 'all' targets" + ).to.include("all"); logger.info("Select Target Passed"); testRunner.output = ""; @@ -55,8 +61,12 @@ export function runInstallWizardTests(pathToEim) { const selectIDFVersion = await testRunner.waitForOutput( "Please select the desired ESP-IDF version" ); - expect(selectIDFVersion).to.be.true; - expect(testRunner.output).to.include("v5.3.1"); + expect(selectIDFVersion, "Failed to ask for IDF version").to.be + .true; + expect(testRunner.output), + "Failed to offer installation for version 5.3.1".to.include( + "v5.3.1" + ); logger.info("Select IDF Version passed"); testRunner.output = ""; @@ -65,8 +75,12 @@ export function runInstallWizardTests(pathToEim) { const selectIDFMirror = await testRunner.waitForOutput( "Select the source from which to download esp-idf" ); - expect(selectIDFMirror).to.be.true; - expect(testRunner.output).to.include("https://github.com"); + expect(selectIDFMirror, "Failed to ask for IDF download mirrors").to + .be.true; + expect( + testRunner.output, + "Failed to offer github as a download mirror option" + ).to.include("https://github.com"); logger.info("Select IDF mirror passed"); testRunner.output = ""; @@ -75,8 +89,12 @@ export function runInstallWizardTests(pathToEim) { const selectToolsMirror = await testRunner.waitForOutput( "Select a source from which to download tools" ); - expect(selectToolsMirror).to.be.true; - expect(testRunner.output).to.include("https://github.com"); + expect(selectToolsMirror, "Failed to ask for tools download mirror") + .to.be.true; + expect( + testRunner.output, + "Failed to offer github as tools download mirror" + ).to.include("https://github.com"); logger.info("Select tools mirror passed"); testRunner.output = ""; @@ -85,8 +103,12 @@ export function runInstallWizardTests(pathToEim) { const selectInstallPath = await testRunner.waitForOutput( "Please select the ESP-IDF installation location" ); - expect(selectInstallPath).to.be.true; - expect(testRunner.output).to.include("esp"); + expect(selectInstallPath, "Failed to ask for installation path").to + .be.true; + expect( + testRunner.output, + "Failed to provide default installation path" + ).to.include("esp"); logger.info("Select install path passed"); testRunner.output = ""; @@ -96,9 +118,18 @@ export function runInstallWizardTests(pathToEim) { "Do you want to save the installer configuration", 1200000 ); - expect(installationCompleted).to.be.true; - expect(testRunner.output).to.not.include("error"); - expect(testRunner.output).to.include("Downloading tools"); + expect( + installationCompleted, + "Failed to ask to save installation configuration - failure to install using wizard parameters" + ).to.be.true; + expect( + testRunner.output, + "Error message during installation" + ).to.not.include("error"); + expect( + testRunner.output, + "Error to download the tools, missing 'Downloading Tools'" + ).to.include("Downloading tools"); logger.info("Installation completed"); testRunner.output = ""; @@ -107,7 +138,10 @@ export function runInstallWizardTests(pathToEim) { const installationSuccessful = await testRunner.waitForOutput( "Successfully installed IDF" ); - expect(installationSuccessful).to.be.true; + expect( + installationSuccessful, + "Failed to complete installation, missing 'Successfully Installed IDF'" + ).to.be.true; logger.info("installation successful"); }); diff --git a/tests/script/postInstall.test.js b/tests/script/postInstall.test.js index 3d6ef90..c1a3186 100644 --- a/tests/script/postInstall.test.js +++ b/tests/script/postInstall.test.js @@ -70,9 +70,18 @@ export function runPostInstallTest( "sdkconfig.ci" ); - expect(confirmFolderContent).to.be.true; - expect(testRunner.output).to.include("pytest_hello_world.py"); - expect(testRunner.output).to.include("main"); + expect( + confirmFolderContent, + "sdkconfig.ci file not shown after a ls command, file copy failed" + ).to.be.true; + expect( + testRunner.output, + "pytest_hello_world.py file not shown after a ls command, file copy failed" + ).to.include("pytest_hello_world.py"); + expect( + testRunner.output, + "main folder not shown after a ls command, file copy failed" + ).to.include("main"); logger.info("sample project creation Passed"); }); @@ -91,9 +100,18 @@ export function runPostInstallTest( 600000 ); - expect(targetSet).to.be.true; - expect(testRunner.output).to.include("Configuring done"); - expect(testRunner.output).to.include("Generating done"); + expect( + targetSet, + "expecting 'Build files have been written to', failed to complete the set-target task" + ).to.be.true; + expect( + testRunner.output, + "expecting 'configuring done', failed to complete the set-target task" + ).to.include("Configuring done"); + expect( + testRunner.output, + "expecting 'Generating Done', failed to complete the set-target task" + ).to.include("Generating done"); logger.info("Set Target Passed"); }); @@ -113,10 +131,14 @@ export function runPostInstallTest( 450000 ); - expect(buildComplete).to.be.true; - expect(testRunner.output).to.include( - `Successfully created ${validTarget} image` - ); + expect( + buildComplete, + "Expecting 'Project build complete', filed to build the sample project" + ).to.be.true; + expect( + testRunner.output, + "Expecting to successfully create target image, filed to build the sample project" + ).to.include(`Successfully created ${validTarget} image`); logger.info("Build Passed"); }); }); diff --git a/tests/script/prerequisites.test.js b/tests/script/prerequisites.test.js index 39b8426..c0b14e8 100644 --- a/tests/script/prerequisites.test.js +++ b/tests/script/prerequisites.test.js @@ -60,18 +60,21 @@ describe("Check if prerequisites are installed", function () { this.timeout(10000); if (this.currentTest.state === "failed") { logger.info( - `Terminal output on failure: >>>>>>>>>>>>>>>\r ${testRunner.output}` + `Terminal output on failure: >>\r ${testRunner.output}` ); } }); it("Should detect missing requirements", async function () { - this.timeout(20000); + this.timeout(25000); const missingRequisites = await testRunner.waitForOutput( "Error: Please install the missing prerequisites", 20000 ); - expect(missingRequisites).to.be.true; + expect( + missingRequisites, + 'EIM did not show error message indicating "Please install prerequisites"' + ).to.be.true; }); } ); @@ -93,19 +96,25 @@ describe("Check if prerequisites are installed", function () { }); it("should offer to install prerequisites and exit upon negative answer", async function () { - this.timeout(20000); + this.timeout(25000); const promptRequisites = await testRunner.waitForOutput( "Do you want to install prerequisites?" ); - expect(promptRequisites).to.be.true; + expect( + promptRequisites, + "EIM did not offer to install the missing prerequisites" + ).to.be.true; testRunner.sendInput("n"); const terminalExited = await testRunner.waitForOutput( "Please install the missing prerequisites and try again" ); - expect(terminalExited).to.be.true; + expect( + terminalExited, + "EIM did not fails after denying to install pre-requisites" + ).to.be.true; }); } ); From 4f865df86e91b2ef4e41d036eaa34ad3cee42679 Mon Sep 17 00:00:00 2001 From: Fabricio-ESP Date: Wed, 20 Nov 2024 17:16:16 +0000 Subject: [PATCH 02/20] Add non interactive test --- tests/runs/nonInteractiveInstall.test.js | 62 ++++++++++++++++++ tests/script/installNonInteractive.test.js | 76 ++++++++++++++++++++++ 2 files changed, 138 insertions(+) create mode 100644 tests/runs/nonInteractiveInstall.test.js create mode 100644 tests/script/installNonInteractive.test.js diff --git a/tests/runs/nonInteractiveInstall.test.js b/tests/runs/nonInteractiveInstall.test.js new file mode 100644 index 0000000..405c1b5 --- /dev/null +++ b/tests/runs/nonInteractiveInstall.test.js @@ -0,0 +1,62 @@ +import { describe, it, before, after } from "mocha"; +import { runPostInstallTest } from "../script/postInstall.test.js"; +import { runInstallNonInteractive } from "../script/installNonInteractive.test.js"; +import logger from "../classes/logger.class.js"; +import os from "os"; +import path from "path"; + +/** + * Setup the following environmental variables to execute this test: + * + * EIM_FILE_PATH to point to the eim application. + * + * use: + * Windows: $env:="" + * Linux/mac: export ="" + * + */ + +let pathToEim; + +if (process.env.EIM_FILE_PATH) { + pathToEim = process.env.EIM_FILE_PATH; +} else { + pathToEim = path.join(os.homedir(), "eim-cli/eim"); +} + +logger.debug(`Starting non-interactive installation using EIM on ${pathToEim}`); + +const targetList = ["esp32c6"]; // targets used for IDF installation +const idfVersionList = ["v5.3.1"]; // IDF versions to be installed +const installFolder = ".espressif3"; +const projectFolder = "project"; + +let installArgs = []; +installArgs.push(`-p ${path.join(os.homedir(), installFolder)}`); // Install Path +installArgs.push(`-t ${targetList.join(",")}`); // Targets (in case of multiple separate with ,) +installArgs.push(`-i ${idfVersionList.join(",")}`); // IDF versions (in case of multiple separate with ,) +installArgs.push(`-m https://github.com`); // IDF tools mirror +installArgs.push(`--idf-mirror https://github.com`); // ESP-IDF mirror +installArgs.push(`-r true`); // recursive submodules init + +const pathToIDFScript = + os.platform() !== "win32" + ? path.join(installPath, `activate_idf_${idfVersionList[0]}.sh`) + : path.join( + installPath, + idfVersionList[0], + `Microsoft.PowerShell_profile.ps1` + ); + +describe("Installation using non-interactive settings", function () { + this.timeout(2400000); + + runInstallNonInteractive(pathToEim, installArgs); + + runPostInstallTest( + pathToIDFScript, + path.join(os.homedir(), installFolder, projectFolder), + targetList[0], + "esp32c6" + ); +}); diff --git a/tests/script/installNonInteractive.test.js b/tests/script/installNonInteractive.test.js new file mode 100644 index 0000000..35ff5b7 --- /dev/null +++ b/tests/script/installNonInteractive.test.js @@ -0,0 +1,76 @@ +import { expect } from "chai"; +import { describe, it, before, after, beforeEach, afterEach } from "mocha"; +import { InteractiveCLITestRunner } from "../classes/CLITestRunner.class.js"; +import logger from "../classes/logger.class.js"; + +export function runInstallNonInteractive(pathToEim, args = []) { + describe("run custom installation using non interactive terminal", function () { + let testRunner = null; + + before(async function () { + logger.debug(`Starting non interactive installation`); + logger.debug(`Using parameters ${args.join("")}`); + this.timeout(5000); + testRunner = new InteractiveCLITestRunner(); + await testRunner.start(); + }); + + afterEach(function () { + if (this.currentTest.state === "failed") { + logger.info( + `Terminal output on failure: >>\r ${testRunner.output}` + ); + testRunner.sendInput("\x03"); + } + }); + + after(async function () { + logger.info("Custom installation routine completed"); + this.timeout(10000); + try { + await testRunner.stop(6000); + } catch { + logger.debug("Error to clean up terminal after test"); + } + }); + + /** Run installation with non-interactive shell. + * + * It is expected for all setting to fall back to default in case it is not passed as argument + * Config file would also overwrite default setting. + * + */ + + it("Should install IDF using specified parameters", async function () { + logger.info("Sent command line for IDF installation"); + testRunner.sendInput(`${pathToEim} ${args.join("")} -n true \r`); + + const installationSuccessful = await testRunner.waitForOutput( + "Successfully installed IDF", + 1200000 + ); + + expect( + installationSuccessful, + "Failed to complete installation, missing 'Successfully Installed IDF'" + ).to.be.true; + + expect( + testRunner.output, + "Error message during installation" + ).to.not.include("error"); + + expect( + testRunner.output, + "Failed to complete installation, missing 'Now you can start using IDF tools'" + ).to.include("Now you can start using IDF tools"); + + if ("-r true" in args || "--recursive-submodules" in args) { + expect( + testRunner.output, + "Failed to download submodules, missing 'Finished fetching submodules'" + ).to.include("Finished fetching submodules"); + } + }); + }); +} From e4f18f19abd37b25e83adc408571582e82a75297 Mon Sep 17 00:00:00 2001 From: Fabricio-ESP Date: Wed, 20 Nov 2024 17:17:34 +0000 Subject: [PATCH 03/20] Add china mirror testing and req install on win32 --- tests/README.md | 13 ++- tests/package.json | 6 +- tests/run_cnrunner.sh | 16 +++ tests/run_pre_test.ps1 | 3 +- tests/run_pre_test.sh | 1 + tests/run_test.ps1 | 3 +- tests/run_test.sh | 3 +- tests/runs/CNmirrors.test.js | 60 ++++++++++ tests/runs/CNmirrors2.test.js | 62 ++++++++++ tests/script/prerequisitesInstall.test.js | 131 ++++++++++++++++++++++ 10 files changed, 293 insertions(+), 5 deletions(-) create mode 100644 tests/run_cnrunner.sh create mode 100644 tests/runs/CNmirrors.test.js create mode 100644 tests/runs/CNmirrors2.test.js create mode 100644 tests/script/prerequisitesInstall.test.js diff --git a/tests/README.md b/tests/README.md index dc81d53..4290918 100644 --- a/tests/README.md +++ b/tests/README.md @@ -166,7 +166,7 @@ Options: Should the installer attempt to install all missing prerequisites (default false). This flag only affects Windows platforms as we do not offer prerequisites for other platforms. [possible values: true, false] --config-file-save-path - if set, the installer will as it's very last move save the configuration to the specified file path. This file can than be used to repeat the instalation with the same settings. + if set, the installer will as it's very last move save the configuration to the specified file path. This file can than be used to repeat the installation with the same settings. -h, --help Print help (see a summary with '-h') -V, --version @@ -225,6 +225,17 @@ idf_mirror = "https://github.com" ## References +Alternative Mirrors: + +IDF: +https://github.com +https://jihulab.com/esp-mirror + +Tools: +https://github.com +https://dl.espressif.com/github_assets +https://dl.espressif.cn/github_assets + Packages required by EIM: Windows: eim should be able to perform all requirements installation diff --git a/tests/package.json b/tests/package.json index 5a15401..f564387 100644 --- a/tests/package.json +++ b/tests/package.json @@ -10,7 +10,11 @@ }, "scripts": { "pre-test": "mocha --exit --bail --reporter mocha-junit-reporter --reporter-options mochaFile=./results-pre-test.xml script/prerequisites.test.js", + "pre-install": "mocha --exit --bail --reporter mocha-junit-reporter --reporter-options mochaFile=./results-pre-test.xml script/prerequisitesInstall.test.js", "default-test": "mocha --exit --bail --reporter mocha-junit-reporter --reporter-options mochaFile=./results-default-test.xml runs/defaultInstall.test.js", - "variation1-test": "mocha --exit --bail --reporter mocha-junit-reporter --reporter-options mochaFile=./results-variation1-test.xml runs/variation1.test.js" + "variation1-test": "mocha --exit --bail --reporter mocha-junit-reporter --reporter-options mochaFile=./results-variation1-test.xml runs/variation1.test.js", + "non-interactive-test": "mocha --exit --bail --reporter mocha-junit-reporter --reporter-options mochaFile=./results-variation1-test.xml runs/nonInteractiveInstall.test.js", + "cnrunner1-test": "mocha --exit --bail --reporter mocha-junit-reporter --reporter-options mochaFile=./results-variation1-test.xml runs/CNmirrors.test.js", + "cnrunner2-test": "mocha --exit --bail --reporter mocha-junit-reporter --reporter-options mochaFile=./results-variation1-test.xml runs/CNmirrors2.test.js" } } diff --git a/tests/run_cnrunner.sh b/tests/run_cnrunner.sh new file mode 100644 index 0000000..fc1d0aa --- /dev/null +++ b/tests/run_cnrunner.sh @@ -0,0 +1,16 @@ +#!/bin/bash + +# Save the arguments as environment variables +export EIM_FILE_PATH="$1" +export EIM_VERSION="$2" + +cd tests + +# install node modules +# The zip file is currently being expanded in the pre-test, if it was not executed before please run this line locally +# npm ci + +# run tests +set +e +npm run cnrunner1-test +npm run cnrunner2-test diff --git a/tests/run_pre_test.ps1 b/tests/run_pre_test.ps1 index 514d97a..96fb230 100644 --- a/tests/run_pre_test.ps1 +++ b/tests/run_pre_test.ps1 @@ -22,4 +22,5 @@ Expand-Archive node_modules.zip # npm ci # Run tests using npm run AllTest -npm run pre-test \ No newline at end of file +npm run pre-test +npm run pre-install \ No newline at end of file diff --git a/tests/run_pre_test.sh b/tests/run_pre_test.sh index 33a736f..cedd3fe 100644 --- a/tests/run_pre_test.sh +++ b/tests/run_pre_test.sh @@ -10,4 +10,5 @@ cd tests npm ci # run tests +set +e npm run pre-test \ No newline at end of file diff --git a/tests/run_test.ps1 b/tests/run_test.ps1 index 5ce59aa..f09e362 100644 --- a/tests/run_test.ps1 +++ b/tests/run_test.ps1 @@ -24,4 +24,5 @@ Set-Location -Path "./tests" # Run tests using npm run AllTest npm run default-test -npm run variation1-test \ No newline at end of file +# npm run variation1-test +npm run non-interactive-test \ No newline at end of file diff --git a/tests/run_test.sh b/tests/run_test.sh index f2f1c2a..82f0977 100644 --- a/tests/run_test.sh +++ b/tests/run_test.sh @@ -13,4 +13,5 @@ cd tests # run tests set +e npm run default-test -npm run variation1-test \ No newline at end of file +# npm run variation1-test +npm run non-interactive-test \ No newline at end of file diff --git a/tests/runs/CNmirrors.test.js b/tests/runs/CNmirrors.test.js new file mode 100644 index 0000000..a704a8f --- /dev/null +++ b/tests/runs/CNmirrors.test.js @@ -0,0 +1,60 @@ +import { describe, it, before, after } from "mocha"; +import { runPostInstallTest } from "../script/postInstall.test.js"; +import { runInstallNonInteractive } from "../script/installNonInteractive.test.js"; +import logger from "../classes/logger.class.js"; +import os from "os"; +import path from "path"; + +/** + * Setup the following environmental variables to execute this test: + * + * EIM_FILE_PATH to point to the eim application. + * + * use: + * Windows: $env:="" + * Linux/mac: export ="" + * + */ + +let pathToEim; + +if (process.env.EIM_FILE_PATH) { + pathToEim = process.env.EIM_FILE_PATH; +} else { + pathToEim = path.join(os.homedir(), "eim-cli/eim"); +} + +logger.debug(`Starting installation using alternative download mirrors`); + +const installFolder = ".espressif4"; +const projectFolder = "project"; + +let installArgs = []; +installArgs.push(`-p ${path.join(os.homedir(), installFolder)}`); // Install Path +installArgs.push(`-t ${targetList.join(",")}`); // Targets (in case of multiple separate with ,) +installArgs.push(`-i ${idfVersionList.join(",")}`); // IDF versions (in case of multiple separate with ,) +installArgs.push(`-m https://dl.espressif.com/github_assets`); // IDF tools mirror +installArgs.push(`--idf-mirror https://jihulab.com/esp-mirror`); // ESP-IDF mirror +installArgs.push(`-r true`); // recursive submodules init + +const pathToIDFScript = + os.platform() !== "win32" + ? path.join(installPath, `activate_idf_${idfVersionList[0]}.sh`) + : path.join( + installPath, + idfVersionList[0], + `Microsoft.PowerShell_profile.ps1` + ); + +describe("Installation using non-interactive settings", function () { + this.timeout(2400000); + + runInstallNonInteractive(pathToEim, installArgs); + + runPostInstallTest( + pathToIDFScript, + path.join(os.homedir(), installFolder, projectFolder), + targetList[0], + "esp32c6" + ); +}); diff --git a/tests/runs/CNmirrors2.test.js b/tests/runs/CNmirrors2.test.js new file mode 100644 index 0000000..9556717 --- /dev/null +++ b/tests/runs/CNmirrors2.test.js @@ -0,0 +1,62 @@ +import { describe, it, before, after } from "mocha"; +import { runPostInstallTest } from "../script/postInstall.test.js"; +import { runInstallNonInteractive } from "../script/installNonInteractive.test.js"; +import logger from "../classes/logger.class.js"; +import os from "os"; +import path from "path"; + +/** + * Setup the following environmental variables to execute this test: + * + * EIM_FILE_PATH to point to the eim application. + * + * use: + * Windows: $env:="" + * Linux/mac: export ="" + * + */ + +let pathToEim; + +if (process.env.EIM_FILE_PATH) { + pathToEim = process.env.EIM_FILE_PATH; +} else { + pathToEim = path.join(os.homedir(), "eim-cli/eim"); +} + +logger.debug(`Starting installation using alternative download mirrors`); + +const targetList = ["esp32"]; // targets used for IDF installation +const idfVersionList = ["v5.0.7"]; // IDF versions to be installed +const installFolder = ".espressif5"; +const projectFolder = "project"; + +let installArgs = []; +installArgs.push(`-p ${path.join(os.homedir(), installFolder)}`); // Install Path +installArgs.push(`-t ${targetList.join(",")}`); // Targets (in case of multiple separate with ,) +installArgs.push(`-i ${idfVersionList.join(",")}`); // IDF versions (in case of multiple separate with ,) +installArgs.push(`-m https://dl.espressif.cn/github_assets`); // IDF tools mirror +installArgs.push(`--idf-mirror https://jihulab.com/esp-mirror`); // ESP-IDF mirror +installArgs.push(`-r true`); // recursive submodules init + +const pathToIDFScript = + os.platform() !== "win32" + ? path.join(installPath, `activate_idf_${idfVersionList[0]}.sh`) + : path.join( + installPath, + idfVersionList[0], + `Microsoft.PowerShell_profile.ps1` + ); + +describe("Installation using non-interactive settings", function () { + this.timeout(2400000); + + runInstallNonInteractive(pathToEim, installArgs); + + runPostInstallTest( + pathToIDFScript, + path.join(os.homedir(), installFolder, projectFolder), + targetList[0], + "esp32c6" + ); +}); diff --git a/tests/script/prerequisitesInstall.test.js b/tests/script/prerequisitesInstall.test.js new file mode 100644 index 0000000..9864fdb --- /dev/null +++ b/tests/script/prerequisitesInstall.test.js @@ -0,0 +1,131 @@ +import { expect } from "chai"; +import { describe, it, before, after, beforeEach, afterEach } from "mocha"; +import { InteractiveCLITestRunner } from "../classes/CLITestRunner.class.js"; +import logger from "../classes/logger.class.js"; +import os from "os"; +import path from "path"; + +/** + * Setup the following environmental variables to execute this test: + * + * EIM_FILE_PATH to point to the eim application. + * + * use: + * Windows: $env:="" + * + */ + +let pathToEim; + +if (process.env.EIM_FILE_PATH) { + pathToEim = process.env.EIM_FILE_PATH; +} else { + pathToEim = path.join(os.homedir(), "eim-cli/eim"); +} + +describe("Check Pre-requisites installation on Windows", function () { + this.timeout(600000); + let testRunner; + + beforeEach(async function () { + this.timeout(5000); + testRunner = new InteractiveCLITestRunner(); + try { + await testRunner.start(); + testRunner.sendInput(`${pathToEim}\r`); + } catch (error) { + logger.info(`Error starting process: ${error}`); + throw error; + } + }); + + afterEach(async function () { + this.timeout(10000); + if (this.currentTest.state === "failed") { + logger.info( + `Terminal output on failure: >>\r ${testRunner.output}` + ); + } + if (!testRunner.exited) { + await testRunner.stop(); + } + testRunner = null; + }); + + it("should install prerequisites and offer to install python and exit upon negative answer", async function () { + this.timeout(240000); + const promptRequisites = await testRunner.waitForOutput( + "Do you want to install prerequisites" + ); + + expect( + promptRequisites, + "EIM did not offer to install the missing prerequisites" + ).to.be.true; + + logger.info("Question to install prerequisites passed"); + testRunner.output = ""; + testRunner.sendInput("y"); + + const promptPython = await testRunner.waitForOutput( + "Do you want to install Python", + 240000 + ); + + expect(promptPython, "EIM did not offer to install python").to.be.true; + expect( + testRunner.output, + "Error when installing the prerequisites" + ).to.include("All prerequisites are satisfied"); + + testRunner.sendInput("n"); + + const terminalExited = await testRunner.waitForOutput( + "Please install python3 with pip and SSL support and try again" + ); + + expect( + terminalExited, + "EIM did not fails after denying to install python" + ).to.be.true; + }); + + it("should install python and proceed with installation", async function () { + this.timeout(240000); + const promptPython2 = await testRunner.waitForOutput( + "Do you want to install Python", + 240000 + ); + + expect(promptPython2, "EIM did not offer to install python").to.be.true; + expect( + testRunner.output, + "Error when installing the prerequisites" + ).to.include("All prerequisites are satisfied"); + + logger.info("Question to install python passed"); + testRunner.output = ""; + testRunner.sendInput("y"); + + const selectTargetQuestion = await testRunner.waitForOutput( + "Please select all of the target platforms", + 240000 + ); + expect( + selectTargetQuestion, + "EIM did not ask to select target, error during python installation" + ).to.be.true; + }); + + it("should detect all prerequisites are installed", async function () { + this.timeout(20000); + const selectTargetQuestion2 = await testRunner.waitForOutput( + "Please select all of the target platforms", + 240000 + ); + expect( + selectTargetQuestion2, + "EIM did not ask to select target, error detecting prerequisites" + ).to.be.true; + }); +}); From cb0689e892c2593e6e84875080fcc624331928e7 Mon Sep 17 00:00:00 2001 From: Fabricio-ESP Date: Wed, 20 Nov 2024 17:27:22 +0000 Subject: [PATCH 04/20] Fix test README file --- tests/README.md | 122 ++++++++++++++++++++++++++++-------------------- 1 file changed, 72 insertions(+), 50 deletions(-) diff --git a/tests/README.md b/tests/README.md index 4290918..84997d3 100644 --- a/tests/README.md +++ b/tests/README.md @@ -11,22 +11,29 @@ All tests are developed in Node.js using Chain and Mocha as test libraries in co On the test machine, the first step is to copy the testing artifacts. The location of the artifacts can be set using environment variable, or the test will look for the `eim` file in the default location: -Windows: $USERPROFILE\eim-cli\ -Linux/MacOS: $HOME/eim-cli/ +Windows: `$USERPROFILE\eim-cli\` +Linux/MacOS: `$HOME/eim-cli/` ### Windows Install chocolatey package manager: -https://docs.chocolatey.org/en-us/choco/setup/ -Run this command with administrator priviledges. + +> https://docs.chocolatey.org/en-us/choco/setup/ + +Run this command with administrator privileges. + `Set-ExecutionPolicy Bypass -Scope Process -Force; [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072; iex ((New-Object System.Net.WebClient).DownloadString('https://community.chocolatey.org/install.ps1'))` Install Node.js: -https://nodejs.org/en/download/prebuilt-installer/current + +> https://nodejs.org/en/download/prebuilt-installer/current + `choco install nodejs-lts --version="22.11.0" -y` Install git: -https://git-scm.com/download/win + +> https://git-scm.com/download/win + `choco install git.install -y` Clone the public repository: @@ -36,99 +43,114 @@ Clone the public repository: ### Linux: Install Git and curl and build-essential packages + `sudo apt install -y git curl build-essential` + `curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.0/install.sh | bash` Start a new terminal (to load nvm) + `nvm install 22` Clone the public repository: + `git clone https://github.com/espressif/idf-im-cli.git` -> At his point test for prerequisits can be run, the remaining tests requires the pre-requisites to be installed. +> **At his point test for prerequisites can be run, the remaining tests requires the pre-requisites to be installed.** Install ESP-IDF pre-requisites -https://docs.espressif.com/projects/esp-idf/en/v5.3.1/esp32/get-started/linux-macos-setup.html + +> https://docs.espressif.com/projects/esp-idf/en/v5.3.1/esp32/get-started/linux-macos-setup.html + `sudo apt install git cmake ninja-build wget flex bison gperf ccache libffi-dev libssl-dev dfu-util libusb-dev python3 python3-venv python3-pip` ### MacOS Install homebrew package manager if not already installed: -https://brew.sh/ + +> https://brew.sh/ + `/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"` Install node.js -https://nodejs.org/en/download/package-manager + +> https://nodejs.org/en/download/package-manager + `brew install node@22` + `echo 'export PATH="/usr/local/opt/node@22/bin:$PATH"' >> ~/.zshrc` > This requires to restart the terminal in order to load Node.JS Install git -https://git-scm.com/downloads/mac + +> https://git-scm.com/downloads/mac + `brew install git` Clone the public repository: + `git clone https://github.com/espressif/idf-im-cli.git` -> At his point test for prerequisites can be run, the remaining tests requires the pre-requisites to be installed. +> **At his point test for prerequisites can be run, the remaining tests requires the pre-requisites to be installed.** Install ESP-IDF pre-requisites -https://docs.espressif.com/projects/esp-idf/en/v5.3.1/esp32/get-started/linux-macos-setup.html + +> https://docs.espressif.com/projects/esp-idf/en/v5.3.1/esp32/get-started/linux-macos-setup.html + `brew install cmake ninja dfu-util` ## Commands summary Navigate to the idf-im-cli folder, where the repository was cloned. + The scripts should be executed passing as arguments the path to the `eim` application and the version of the file being tested. #### Windows -Open Powershell, and enable script execution: +Open Powershell, and enable script execution: `Set-ExecutionPolicy -Scope Process -ExecutionPolicy Bypass` -Prerequisites test can be executed by running: -`.\tests\run_pre_test.ps1 "" ""` -Default arguments are: +Prerequisites test can be executed by running: +`.\tests\run_pre_test.ps1 "" ""` +Default arguments are: `.\tests\run_pre_test.ps1 "$env:USERPROFILE\eim-cli\eim.exe" "idf-im-cli 0.1.4"` -To execute tests on windows, use the script -`.\tests\run_test.ps1 "" ""` -Default arguments are: +To execute tests on windows, use the script +`.\tests\run_test.ps1 "" ""` +Default arguments are: `.\tests\run_test.ps1 "$env:USERPROFILE\eim-cli\eim.exe" "idf-im-cli 0.1.4"` #### Linux -(if needed) Give execution permission to the test script +(if needed) Give execution permission to the test script `chmod +x ./tests/run_test.sh` -Prerequisites test can be executed by running: -`. ./tests/run_pre_test.sh "" ""` -Default arguments are: +Prerequisites test can be executed by running: +`. ./tests/run_pre_test.sh "" ""` +Default arguments are: `. ./tests/run_pre_test.sh "$HOME/eim-cli/eim" "idf-im-cli 0.1.4"` -To execute tests on linux, use the script: -`. ./tests/run_test.sh "" ""` -Default arguments are: +To execute tests on linux, use the script: +`. ./tests/run_test.sh "" ""` +Default arguments are: `. ./tests/run_test.sh "$HOME/eim-cli/eim" "idf-im-cli 0.1.4"` #### MacOS -Prerequisites test can be executed by running: -`. ./tests/run_pre_test.sh "" ""` -Default arguments are: +Prerequisites test can be executed by running: +`. ./tests/run_pre_test.sh "" ""` +Default arguments are: `. ./tests/run_pre_test.sh "$HOME/eim-cli/eim" "idf-im-cli 0.1.3"` -To execute tests on linux, use the script: -`. ./tests/run_test.sh "" ""` -Default arguments are: +To execute tests on linux, use the script: +`. ./tests/run_test.sh "" ""` +Default arguments are: `. ./tests/run_test.sh "$HOME/eim-cli/eim" "idf-im-cli 0.1.3"` - - # Installation Manager Usage -##Application arguments +## Application arguments ``` Options: @@ -173,7 +195,7 @@ Options: Print version ``` -## Example config file: +## Example config file file config.toml (Linux) @@ -227,24 +249,24 @@ idf_mirror = "https://github.com" Alternative Mirrors: -IDF: -https://github.com +IDF: +https://github.com https://jihulab.com/esp-mirror -Tools: -https://github.com -https://dl.espressif.com/github_assets +Tools: +https://github.com +https://dl.espressif.com/github_assets https://dl.espressif.cn/github_assets Packages required by EIM: -Windows: eim should be able to perform all requirements installation - -Linux: sudo apt install git cmake ninja-build wget flex bison gperf ccache libffi-dev libssl-dev dfu-util libusb-dev python3 python3-venv python3-pip +Windows: +`eim should be able to perform all requirements installation` -MacOS: -Install homebrew and load the application to the terminal profile - -`/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"` +Linux: +`sudo apt install git cmake ninja-build wget flex bison gperf ccache libffi-dev libssl-dev dfu-util libusb-dev python3 python3-venv python3-pip` -Then run: brew install dfu-util cmake ninja python3 +MacOS: +Install homebrew and load the application to the terminal profile +`/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"` +Then run: `brew install dfu-util cmake ninja python3` From 25c4fdd6c122e9610efe9ee5d931462cd4cbcbc3 Mon Sep 17 00:00:00 2001 From: Fabricio-ESP Date: Thu, 21 Nov 2024 19:24:59 +0000 Subject: [PATCH 05/20] Minor fixes on test script + added CI --- .github/workflows/test.yml | 16 ++++++++++++---- tests/run_cnrunner.sh | 2 +- tests/runs/CNmirrors.test.js | 21 +++++++++++++-------- tests/runs/CNmirrors2.test.js | 19 +++++++++++-------- tests/runs/nonInteractiveInstall.test.js | 21 +++++++++++++-------- tests/runs/variation1.test.js | 21 +++++++++++++-------- tests/script/installCustom.test.js | 2 +- tests/script/installNonInteractive.test.js | 6 +++--- tests/script/installWizard.test.js | 10 +++++----- 9 files changed, 72 insertions(+), 46 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index ef61111..eaa0925 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -24,6 +24,8 @@ jobs: package_name: windows-x64 - os: macos-latest package_name: macos-aarch64 + - os: ubuntu-latest + package_name: CNRunner steps: - name: Checkout repository @@ -34,8 +36,7 @@ jobs: - name: Set up Node.js uses: actions/setup-node@v4 with: - node-version: "20" - + node-version: "22" - name: Download artifacts uses: actions/download-artifact@v4 with: @@ -64,7 +65,7 @@ jobs: chmod +x ./test-bin/eim - name: Run prerequisites test script (non-Windows) - if: runner.os != 'Windows' + if: runner.os != 'Windows' && matrix.package_name != 'CNRunner' run: | export LOG_TO_FILE="true" chmod +x ./tests/run_pre_test.sh @@ -81,12 +82,19 @@ jobs: brew install cmake ninja dfu-util - name: Run IDF installation and post install test script (non-Windows) - if: runner.os != 'Windows' + if: runner.os != 'Windows' && matrix.package_name != 'CNRunner' run: | export LOG_TO_FILE="true" chmod +x ./tests/run_test.sh . ./tests/run_test.sh "../test-bin/eim" "idf-im-cli ${{ env.CLI_TAG }}" + - name: Run IDF installation from alternative mirrors in mainland China + if: matrix.package_name == 'CNRunner' + run: | + export LOG_TO_FILE="true" + chmod +x ./tests/run_cnrunner.sh + . ./tests/run_cnrunner.sh "../test-bin/eim" "idf-im-cli ${{ env.CLI_TAG }}" + # ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - name: Get CLI application version number (Windows) diff --git a/tests/run_cnrunner.sh b/tests/run_cnrunner.sh index fc1d0aa..265ed81 100644 --- a/tests/run_cnrunner.sh +++ b/tests/run_cnrunner.sh @@ -8,7 +8,7 @@ cd tests # install node modules # The zip file is currently being expanded in the pre-test, if it was not executed before please run this line locally -# npm ci +npm ci # run tests set +e diff --git a/tests/runs/CNmirrors.test.js b/tests/runs/CNmirrors.test.js index a704a8f..95e9998 100644 --- a/tests/runs/CNmirrors.test.js +++ b/tests/runs/CNmirrors.test.js @@ -26,22 +26,27 @@ if (process.env.EIM_FILE_PATH) { logger.debug(`Starting installation using alternative download mirrors`); +const targetList = ["esp32c6"]; // targets used for IDF installation +const idfVersionList = ["v5.3.1"]; // IDF versions to be installed const installFolder = ".espressif4"; const projectFolder = "project"; let installArgs = []; -installArgs.push(`-p ${path.join(os.homedir(), installFolder)}`); // Install Path -installArgs.push(`-t ${targetList.join(",")}`); // Targets (in case of multiple separate with ,) -installArgs.push(`-i ${idfVersionList.join(",")}`); // IDF versions (in case of multiple separate with ,) -installArgs.push(`-m https://dl.espressif.com/github_assets`); // IDF tools mirror -installArgs.push(`--idf-mirror https://jihulab.com/esp-mirror`); // ESP-IDF mirror -installArgs.push(`-r true`); // recursive submodules init +installArgs.push(` -p ${path.join(os.homedir(), installFolder)}`); // Install Path +installArgs.push(` -m https://dl.espressif.com/github_assets`); // IDF tools mirror +installArgs.push(` --idf-mirror https://jihulab.com/esp-mirror`); // ESP-IDF mirror +installArgs.push(` -r true`); // recursive submodules init const pathToIDFScript = os.platform() !== "win32" - ? path.join(installPath, `activate_idf_${idfVersionList[0]}.sh`) + ? path.join( + os.homedir(), + installFolder, + `activate_idf_${idfVersionList[0]}.sh` + ) : path.join( - installPath, + os.homedir(), + installFolder, idfVersionList[0], `Microsoft.PowerShell_profile.ps1` ); diff --git a/tests/runs/CNmirrors2.test.js b/tests/runs/CNmirrors2.test.js index 9556717..0a7b0ad 100644 --- a/tests/runs/CNmirrors2.test.js +++ b/tests/runs/CNmirrors2.test.js @@ -32,18 +32,21 @@ const installFolder = ".espressif5"; const projectFolder = "project"; let installArgs = []; -installArgs.push(`-p ${path.join(os.homedir(), installFolder)}`); // Install Path -installArgs.push(`-t ${targetList.join(",")}`); // Targets (in case of multiple separate with ,) -installArgs.push(`-i ${idfVersionList.join(",")}`); // IDF versions (in case of multiple separate with ,) -installArgs.push(`-m https://dl.espressif.cn/github_assets`); // IDF tools mirror -installArgs.push(`--idf-mirror https://jihulab.com/esp-mirror`); // ESP-IDF mirror -installArgs.push(`-r true`); // recursive submodules init +installArgs.push(` -p ${path.join(os.homedir(), installFolder)}`); // Install Path +installArgs.push(` -m https://dl.espressif.cn/github_assets`); // IDF tools mirror +installArgs.push(` --idf-mirror https://jihulab.com/esp-mirror`); // ESP-IDF mirror +installArgs.push(` -r true`); // recursive submodules init const pathToIDFScript = os.platform() !== "win32" - ? path.join(installPath, `activate_idf_${idfVersionList[0]}.sh`) + ? path.join( + os.homedir(), + installFolder, + `activate_idf_${idfVersionList[0]}.sh` + ) : path.join( - installPath, + os.homedir(), + installFolder, idfVersionList[0], `Microsoft.PowerShell_profile.ps1` ); diff --git a/tests/runs/nonInteractiveInstall.test.js b/tests/runs/nonInteractiveInstall.test.js index 405c1b5..f61da5f 100644 --- a/tests/runs/nonInteractiveInstall.test.js +++ b/tests/runs/nonInteractiveInstall.test.js @@ -32,18 +32,23 @@ const installFolder = ".espressif3"; const projectFolder = "project"; let installArgs = []; -installArgs.push(`-p ${path.join(os.homedir(), installFolder)}`); // Install Path -installArgs.push(`-t ${targetList.join(",")}`); // Targets (in case of multiple separate with ,) -installArgs.push(`-i ${idfVersionList.join(",")}`); // IDF versions (in case of multiple separate with ,) -installArgs.push(`-m https://github.com`); // IDF tools mirror -installArgs.push(`--idf-mirror https://github.com`); // ESP-IDF mirror -installArgs.push(`-r true`); // recursive submodules init +installArgs.push(` -p ${path.join(os.homedir(), installFolder)}`); // Install Path +installArgs.push(` -t ${targetList.join(",")}`); // Targets (in case of multiple separate with ,) +installArgs.push(` -i ${idfVersionList.join(",")}`); // IDF versions (in case of multiple separate with ,) +installArgs.push(` -m https://github.com`); // IDF tools mirror +installArgs.push(` --idf-mirror https://github.com`); // ESP-IDF mirror +installArgs.push(` -r true`); // recursive submodules init const pathToIDFScript = os.platform() !== "win32" - ? path.join(installPath, `activate_idf_${idfVersionList[0]}.sh`) + ? path.join( + os.homedir(), + installFolder, + `activate_idf_${idfVersionList[0]}.sh` + ) : path.join( - installPath, + os.homedir(), + installFolder, idfVersionList[0], `Microsoft.PowerShell_profile.ps1` ); diff --git a/tests/runs/variation1.test.js b/tests/runs/variation1.test.js index b98d153..334b803 100644 --- a/tests/runs/variation1.test.js +++ b/tests/runs/variation1.test.js @@ -32,18 +32,23 @@ const installFolder = ".espressif2"; const projectFolder = "project"; let installArgs = []; -installArgs.push(`-p ${path.join(os.homedir(), installFolder)}`); // Install Path -installArgs.push(`-t ${targetList.join(",")}`); // Targets (in case of multiple separate with ,) -installArgs.push(`-i ${idfVersionList.join(",")}`); // IDF versions (in case of multiple separate with ,) -installArgs.push(`-m https://github.com`); // IDF tools mirror -installArgs.push(`--idf-mirror https://github.com`); // ESP-IDF mirror -installArgs.push(`-r true`); // recursive submodules init +installArgs.push(` -p ${path.join(os.homedir(), installFolder)}`); // Install Path +installArgs.push(` -t ${targetList.join(",")}`); // Targets (in case of multiple separate with ,) +installArgs.push(` -i ${idfVersionList.join(",")}`); // IDF versions (in case of multiple separate with ,) +installArgs.push(` -m https://github.com`); // IDF tools mirror +installArgs.push(` --idf-mirror https://github.com`); // ESP-IDF mirror +installArgs.push(` -r true`); // recursive submodules init const pathToIDFScript = os.platform() !== "win32" - ? path.join(installPath, `activate_idf_${idfVersionList[0]}.sh`) + ? path.join( + os.homedir(), + installFolder, + `activate_idf_${idfVersionList[0]}.sh` + ) : path.join( - installPath, + os.homedir(), + installFolder, idfVersionList[0], `Microsoft.PowerShell_profile.ps1` ); diff --git a/tests/script/installCustom.test.js b/tests/script/installCustom.test.js index b0df40f..b8676aa 100644 --- a/tests/script/installCustom.test.js +++ b/tests/script/installCustom.test.js @@ -29,7 +29,7 @@ export function runInstallCustom(pathToEim, args = []) { after(async function () { logger.info("Custom installation routine completed"); - this.timeout(10000); + this.timeout(20000); try { await testRunner.stop(6000); } catch { diff --git a/tests/script/installNonInteractive.test.js b/tests/script/installNonInteractive.test.js index 35ff5b7..85dbfc0 100644 --- a/tests/script/installNonInteractive.test.js +++ b/tests/script/installNonInteractive.test.js @@ -9,7 +9,7 @@ export function runInstallNonInteractive(pathToEim, args = []) { before(async function () { logger.debug(`Starting non interactive installation`); - logger.debug(`Using parameters ${args.join("")}`); + logger.debug(`Using parameters ${args.join(" ")}`); this.timeout(5000); testRunner = new InteractiveCLITestRunner(); await testRunner.start(); @@ -26,7 +26,7 @@ export function runInstallNonInteractive(pathToEim, args = []) { after(async function () { logger.info("Custom installation routine completed"); - this.timeout(10000); + this.timeout(20000); try { await testRunner.stop(6000); } catch { @@ -43,7 +43,7 @@ export function runInstallNonInteractive(pathToEim, args = []) { it("Should install IDF using specified parameters", async function () { logger.info("Sent command line for IDF installation"); - testRunner.sendInput(`${pathToEim} ${args.join("")} -n true \r`); + testRunner.sendInput(`${pathToEim} ${args.join(" ")} -n true \r`); const installationSuccessful = await testRunner.waitForOutput( "Successfully installed IDF", diff --git a/tests/script/installWizard.test.js b/tests/script/installWizard.test.js index f1672d0..28d7efa 100644 --- a/tests/script/installWizard.test.js +++ b/tests/script/installWizard.test.js @@ -24,7 +24,7 @@ export function runInstallWizardTests(pathToEim) { after(async function () { logger.info("Install Wizard routine completed"); - this.timeout(10000); + this.timeout(20000); try { await testRunner.stop(6000); } catch { @@ -63,10 +63,10 @@ export function runInstallWizardTests(pathToEim) { ); expect(selectIDFVersion, "Failed to ask for IDF version").to.be .true; - expect(testRunner.output), - "Failed to offer installation for version 5.3.1".to.include( - "v5.3.1" - ); + expect( + testRunner.output, + "Failed to offer installation for version 5.3.1" + ).to.include("v5.3.1"); logger.info("Select IDF Version passed"); testRunner.output = ""; From acd0005a7a18903654e2aa26a221ecd28897108a Mon Sep 17 00:00:00 2001 From: Fabricio-ESP Date: Fri, 22 Nov 2024 09:22:06 +0000 Subject: [PATCH 06/20] Fix CI workflow + enable variation1 test --- .github/workflows/test.yml | 17 +++++++++++------ tests/run_test.ps1 | 2 +- tests/run_test.sh | 2 +- 3 files changed, 13 insertions(+), 8 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index eaa0925..36da13b 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -20,12 +20,16 @@ jobs: include: - os: ubuntu-latest package_name: linux-x64 + run_on: GitHub - os: windows-latest package_name: windows-x64 + run_on: GitHub - os: macos-latest package_name: macos-aarch64 + run_on: GitHub - os: ubuntu-latest - package_name: CNRunner + package_name: linux-x64 + run_on: CNRunner steps: - name: Checkout repository @@ -36,7 +40,8 @@ jobs: - name: Set up Node.js uses: actions/setup-node@v4 with: - node-version: "22" + node-version: "20" + - name: Download artifacts uses: actions/download-artifact@v4 with: @@ -64,8 +69,8 @@ jobs: run: | chmod +x ./test-bin/eim - - name: Run prerequisites test script (non-Windows) - if: runner.os != 'Windows' && matrix.package_name != 'CNRunner' + - name: Run prerequisites test script (non-Windows), skip for CNRunner + if: runner.os != 'Windows' && matrix.run_on != 'CNRunner' run: | export LOG_TO_FILE="true" chmod +x ./tests/run_pre_test.sh @@ -82,14 +87,14 @@ jobs: brew install cmake ninja dfu-util - name: Run IDF installation and post install test script (non-Windows) - if: runner.os != 'Windows' && matrix.package_name != 'CNRunner' + if: runner.os != 'Windows' && matrix.run_on != 'CNRunner' run: | export LOG_TO_FILE="true" chmod +x ./tests/run_test.sh . ./tests/run_test.sh "../test-bin/eim" "idf-im-cli ${{ env.CLI_TAG }}" - name: Run IDF installation from alternative mirrors in mainland China - if: matrix.package_name == 'CNRunner' + if: matrix.run_on == 'CNRunner' run: | export LOG_TO_FILE="true" chmod +x ./tests/run_cnrunner.sh diff --git a/tests/run_test.ps1 b/tests/run_test.ps1 index f09e362..5a92753 100644 --- a/tests/run_test.ps1 +++ b/tests/run_test.ps1 @@ -24,5 +24,5 @@ Set-Location -Path "./tests" # Run tests using npm run AllTest npm run default-test -# npm run variation1-test +npm run variation1-test npm run non-interactive-test \ No newline at end of file diff --git a/tests/run_test.sh b/tests/run_test.sh index 82f0977..8253a28 100644 --- a/tests/run_test.sh +++ b/tests/run_test.sh @@ -13,5 +13,5 @@ cd tests # run tests set +e npm run default-test -# npm run variation1-test +npm run variation1-test npm run non-interactive-test \ No newline at end of file From 4799389af3970809fe995bc5215f2b1121042bec Mon Sep 17 00:00:00 2001 From: Fabricio-ESP Date: Fri, 22 Nov 2024 11:20:19 +0000 Subject: [PATCH 07/20] Adjust test report name + remove failing test --- .github/workflows/test.yml | 2 +- tests/package.json | 2 +- tests/runs/CNmirrors.test.js | 4 +- tests/runs/CNmirrors2.test.js | 2 +- tests/script/installNonInteractive.test.js | 8 +- .../script/prerequisitesInstallRunner.test.js | 91 +++++++++++++++++++ 6 files changed, 100 insertions(+), 9 deletions(-) create mode 100644 tests/script/prerequisitesInstallRunner.test.js diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 36da13b..ec235e3 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -146,7 +146,7 @@ jobs: uses: actions/upload-artifact@v4 if: always() with: - name: test-results-${{ matrix.package_name }}.zip + name: test-results-${{ matrix.package_name }} - ${{matrix.run_on}}.zip path: | ./tests/results-pre-test.xml ./tests/results-default-test.xml diff --git a/tests/package.json b/tests/package.json index f564387..b8862b4 100644 --- a/tests/package.json +++ b/tests/package.json @@ -10,7 +10,7 @@ }, "scripts": { "pre-test": "mocha --exit --bail --reporter mocha-junit-reporter --reporter-options mochaFile=./results-pre-test.xml script/prerequisites.test.js", - "pre-install": "mocha --exit --bail --reporter mocha-junit-reporter --reporter-options mochaFile=./results-pre-test.xml script/prerequisitesInstall.test.js", + "pre-install": "mocha --exit --bail --reporter mocha-junit-reporter --reporter-options mochaFile=./results-pre-test.xml script/prerequisitesInstallRunner.test.js", "default-test": "mocha --exit --bail --reporter mocha-junit-reporter --reporter-options mochaFile=./results-default-test.xml runs/defaultInstall.test.js", "variation1-test": "mocha --exit --bail --reporter mocha-junit-reporter --reporter-options mochaFile=./results-variation1-test.xml runs/variation1.test.js", "non-interactive-test": "mocha --exit --bail --reporter mocha-junit-reporter --reporter-options mochaFile=./results-variation1-test.xml runs/nonInteractiveInstall.test.js", diff --git a/tests/runs/CNmirrors.test.js b/tests/runs/CNmirrors.test.js index 95e9998..d5c77c5 100644 --- a/tests/runs/CNmirrors.test.js +++ b/tests/runs/CNmirrors.test.js @@ -24,7 +24,7 @@ if (process.env.EIM_FILE_PATH) { pathToEim = path.join(os.homedir(), "eim-cli/eim"); } -logger.debug(`Starting installation using alternative download mirrors`); +logger.debug(`Starting installation using mirror jihulab and dl.espressif.com`); const targetList = ["esp32c6"]; // targets used for IDF installation const idfVersionList = ["v5.3.1"]; // IDF versions to be installed @@ -51,7 +51,7 @@ const pathToIDFScript = `Microsoft.PowerShell_profile.ps1` ); -describe("Installation using non-interactive settings", function () { +describe("Installation using mirror jihulab and dl.espressif.com", function () { this.timeout(2400000); runInstallNonInteractive(pathToEim, installArgs); diff --git a/tests/runs/CNmirrors2.test.js b/tests/runs/CNmirrors2.test.js index 0a7b0ad..61c2211 100644 --- a/tests/runs/CNmirrors2.test.js +++ b/tests/runs/CNmirrors2.test.js @@ -51,7 +51,7 @@ const pathToIDFScript = `Microsoft.PowerShell_profile.ps1` ); -describe("Installation using non-interactive settings", function () { +describe("using mirror jihulab and dl.espressif.cn", function () { this.timeout(2400000); runInstallNonInteractive(pathToEim, installArgs); diff --git a/tests/script/installNonInteractive.test.js b/tests/script/installNonInteractive.test.js index 85dbfc0..c61daab 100644 --- a/tests/script/installNonInteractive.test.js +++ b/tests/script/installNonInteractive.test.js @@ -55,10 +55,10 @@ export function runInstallNonInteractive(pathToEim, args = []) { "Failed to complete installation, missing 'Successfully Installed IDF'" ).to.be.true; - expect( - testRunner.output, - "Error message during installation" - ).to.not.include("error"); + // expect( + // testRunner.output, + // "Error message during installation" + // ).to.not.include("error"); expect( testRunner.output, diff --git a/tests/script/prerequisitesInstallRunner.test.js b/tests/script/prerequisitesInstallRunner.test.js new file mode 100644 index 0000000..25df70a --- /dev/null +++ b/tests/script/prerequisitesInstallRunner.test.js @@ -0,0 +1,91 @@ +import { expect } from "chai"; +import { describe, it, before, after, beforeEach, afterEach } from "mocha"; +import { InteractiveCLITestRunner } from "../classes/CLITestRunner.class.js"; +import logger from "../classes/logger.class.js"; +import os from "os"; +import path from "path"; + +/** + * Setup the following environmental variables to execute this test: + * + * EIM_FILE_PATH to point to the eim application. + * + * use: + * Windows: $env:="" + * + */ + +let pathToEim; + +if (process.env.EIM_FILE_PATH) { + pathToEim = process.env.EIM_FILE_PATH; +} else { + pathToEim = path.join(os.homedir(), "eim-cli/eim"); +} + +describe("Check Pre-requisites installation on Windows", function () { + this.timeout(600000); + let testRunner; + + beforeEach(async function () { + this.timeout(5000); + testRunner = new InteractiveCLITestRunner(); + try { + await testRunner.start(); + testRunner.sendInput(`${pathToEim}\r`); + } catch (error) { + logger.info(`Error starting process: ${error}`); + throw error; + } + }); + + afterEach(async function () { + this.timeout(10000); + if (this.currentTest.state === "failed") { + logger.info( + `Terminal output on failure: >>\r ${testRunner.output}` + ); + } + if (!testRunner.exited) { + await testRunner.stop(); + } + testRunner = null; + }); + + it("should install prerequisites and offer to install python and exit upon negative answer", async function () { + this.timeout(240000); + const promptRequisites = await testRunner.waitForOutput( + "Do you want to install prerequisites" + ); + + expect( + promptRequisites, + "EIM did not offer to install the missing prerequisites" + ).to.be.true; + + logger.info("Question to install prerequisites passed"); + testRunner.output = ""; + testRunner.sendInput("y"); + + const selectTargetQuestion = await testRunner.waitForOutput( + "Please select all of the target platforms", + 240000 + ); + expect( + selectTargetQuestion, + "EIM did not ask to select target, error during python installation" + ).to.be.true; + }); + + it("should detect all prerequisites are installed", async function () { + this.timeout(20000); + const selectTargetQuestion2 = await testRunner.waitForOutput( + "Please select all of the target platforms", + 240000 + ); + expect( + selectTargetQuestion2, + "EIM did not ask to select target, error detecting prerequisites" + ).to.be.true; + }); +}); From 66d6c1c396eba679219095dc1c8582229e109ff4 Mon Sep 17 00:00:00 2001 From: Fabricio-ESP Date: Fri, 22 Nov 2024 13:27:18 +0000 Subject: [PATCH 08/20] Fix test report files + improve stability --- .github/workflows/test.yml | 2 +- tests/package.json | 8 ++++---- tests/script/commandLineArguments.test.js | 8 +++++--- tests/script/installCustom.test.js | 6 +++--- tests/script/postInstall.test.js | 15 ++++++++++----- tests/script/prerequisites.test.js | 8 +++++--- tests/script/prerequisitesInstall.test.js | 6 ++++-- tests/script/prerequisitesInstallRunner.test.js | 12 +++++++----- 8 files changed, 39 insertions(+), 26 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index ec235e3..9261d51 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -146,7 +146,7 @@ jobs: uses: actions/upload-artifact@v4 if: always() with: - name: test-results-${{ matrix.package_name }} - ${{matrix.run_on}}.zip + name: test-results-${{ matrix.package_name }}-${{matrix.run_on}}.zip path: | ./tests/results-pre-test.xml ./tests/results-default-test.xml diff --git a/tests/package.json b/tests/package.json index b8862b4..4402fc6 100644 --- a/tests/package.json +++ b/tests/package.json @@ -10,11 +10,11 @@ }, "scripts": { "pre-test": "mocha --exit --bail --reporter mocha-junit-reporter --reporter-options mochaFile=./results-pre-test.xml script/prerequisites.test.js", - "pre-install": "mocha --exit --bail --reporter mocha-junit-reporter --reporter-options mochaFile=./results-pre-test.xml script/prerequisitesInstallRunner.test.js", + "pre-install": "mocha --exit --bail --reporter mocha-junit-reporter --reporter-options mochaFile=./results-pre-install-test.xml script/prerequisitesInstallRunner.test.js", "default-test": "mocha --exit --bail --reporter mocha-junit-reporter --reporter-options mochaFile=./results-default-test.xml runs/defaultInstall.test.js", "variation1-test": "mocha --exit --bail --reporter mocha-junit-reporter --reporter-options mochaFile=./results-variation1-test.xml runs/variation1.test.js", - "non-interactive-test": "mocha --exit --bail --reporter mocha-junit-reporter --reporter-options mochaFile=./results-variation1-test.xml runs/nonInteractiveInstall.test.js", - "cnrunner1-test": "mocha --exit --bail --reporter mocha-junit-reporter --reporter-options mochaFile=./results-variation1-test.xml runs/CNmirrors.test.js", - "cnrunner2-test": "mocha --exit --bail --reporter mocha-junit-reporter --reporter-options mochaFile=./results-variation1-test.xml runs/CNmirrors2.test.js" + "non-interactive-test": "mocha --exit --bail --reporter mocha-junit-reporter --reporter-options mochaFile=./results-non-interactive-test.xml runs/nonInteractiveInstall.test.js", + "cnrunner1-test": "mocha --exit --bail --reporter mocha-junit-reporter --reporter-options mochaFile=./results-CNMirror-test.xml runs/CNmirrors.test.js", + "cnrunner2-test": "mocha --exit --bail --reporter mocha-junit-reporter --reporter-options mochaFile=./results-CNmirrors2-test.xml runs/CNmirrors2.test.js" } } diff --git a/tests/script/commandLineArguments.test.js b/tests/script/commandLineArguments.test.js index cb3b54c..a3b50fa 100644 --- a/tests/script/commandLineArguments.test.js +++ b/tests/script/commandLineArguments.test.js @@ -12,14 +12,16 @@ export function runArgumentsTests(pathToEim, eimVersion) { }); afterEach(async function () { + this.timeout(20000); if (this.currentTest.state === "failed") { logger.info( `Terminal output on failure: >>\r ${testRunner.output}` ); } - if (!testRunner.exited) { - logger.debug("Sending stop command to emulator"); - await testRunner.stop(); + try { + await testRunner.stop(6000); + } catch { + logger.debug("Error to clean up terminal after test"); } testRunner = null; }); diff --git a/tests/script/installCustom.test.js b/tests/script/installCustom.test.js index b8676aa..f050c9c 100644 --- a/tests/script/installCustom.test.js +++ b/tests/script/installCustom.test.js @@ -9,10 +9,10 @@ export function runInstallCustom(pathToEim, args = []) { before(async function () { logger.debug( - `Installing IDF version: ${idfVersionList} on path: ${installPath}` + `Installing custom IDF version with parameters ${args.join( + " " + )}` ); - logger.debug(`Installing IDF for targets ${targetList}`); - logger.debug(`Recurse submodules active? : ${recursiveSubmodules}`); this.timeout(5000); testRunner = new InteractiveCLITestRunner(); await testRunner.start(); diff --git a/tests/script/postInstall.test.js b/tests/script/postInstall.test.js index c1a3186..03c4513 100644 --- a/tests/script/postInstall.test.js +++ b/tests/script/postInstall.test.js @@ -18,13 +18,18 @@ export function runPostInstallTest( beforeEach(async function () { this.timeout(10000); logger.debug( - `Starting IDF terminal using activation script ${pathToIDFScript}, sample project copied at ${path.join( - os.homedir(), - pathToProjectFolder - )}` + `Starting IDF terminal using activation script ${pathToIDFScript}, sample project copied at ${pathToProjectFolder}` ); testRunner = new InteractiveCLITestRunner(); - await testRunner.runIDFTerminal(pathToIDFScript); + try { + await testRunner.runIDFTerminal(pathToIDFScript); + } catch { + logger.info("Error to start IDF terminal"); + logger.info(testRunner.output); + throw new Error( + "One test in teh chain failed, aborting the entire suite." + ); + } }); afterEach(async function () { diff --git a/tests/script/prerequisites.test.js b/tests/script/prerequisites.test.js index c0b14e8..a3df7cc 100644 --- a/tests/script/prerequisites.test.js +++ b/tests/script/prerequisites.test.js @@ -41,9 +41,11 @@ describe("Check if prerequisites are installed", function () { }); afterEach(async function () { - this.timeout(10000); - if (!testRunner.exited) { - await testRunner.stop(); + this.timeout(20000); + try { + await testRunner.stop(6000); + } catch { + logger.debug("Error to clean up terminal after test"); } testRunner = null; }); diff --git a/tests/script/prerequisitesInstall.test.js b/tests/script/prerequisitesInstall.test.js index 9864fdb..8475bd4 100644 --- a/tests/script/prerequisitesInstall.test.js +++ b/tests/script/prerequisitesInstall.test.js @@ -46,8 +46,10 @@ describe("Check Pre-requisites installation on Windows", function () { `Terminal output on failure: >>\r ${testRunner.output}` ); } - if (!testRunner.exited) { - await testRunner.stop(); + try { + await testRunner.stop(6000); + } catch { + logger.debug("Error to clean up terminal after test"); } testRunner = null; }); diff --git a/tests/script/prerequisitesInstallRunner.test.js b/tests/script/prerequisitesInstallRunner.test.js index 25df70a..3c5eb61 100644 --- a/tests/script/prerequisitesInstallRunner.test.js +++ b/tests/script/prerequisitesInstallRunner.test.js @@ -46,8 +46,10 @@ describe("Check Pre-requisites installation on Windows", function () { `Terminal output on failure: >>\r ${testRunner.output}` ); } - if (!testRunner.exited) { - await testRunner.stop(); + try { + await testRunner.stop(6000); + } catch { + logger.debug("Error to clean up terminal after test"); } testRunner = null; }); @@ -64,7 +66,7 @@ describe("Check Pre-requisites installation on Windows", function () { ).to.be.true; logger.info("Question to install prerequisites passed"); - testRunner.output = ""; + testRunner.sendInput("y"); const selectTargetQuestion = await testRunner.waitForOutput( @@ -78,10 +80,10 @@ describe("Check Pre-requisites installation on Windows", function () { }); it("should detect all prerequisites are installed", async function () { - this.timeout(20000); + this.timeout(22000); const selectTargetQuestion2 = await testRunner.waitForOutput( "Please select all of the target platforms", - 240000 + 20000 ); expect( selectTargetQuestion2, From 8da80d343a1d939bc2e3037cd9d6da6d7421acce Mon Sep 17 00:00:00 2001 From: Fabricio-ESP Date: Fri, 22 Nov 2024 14:53:21 +0000 Subject: [PATCH 09/20] Minor adjustments on ci workflow --- .github/workflows/test.yml | 4 ++++ tests/run_pre_test.ps1 | 2 +- tests/runs/CNmirrors2.test.js | 2 +- tests/script/installNonInteractive.test.js | 2 +- tests/script/postInstall.test.js | 2 +- tests/script/prerequisitesInstallRunner.test.js | 4 ++-- 6 files changed, 10 insertions(+), 6 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 9261d51..1fc406c 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -149,8 +149,12 @@ jobs: name: test-results-${{ matrix.package_name }}-${{matrix.run_on}}.zip path: | ./tests/results-pre-test.xml + ./tests/results-pre-install-test.xml ./tests/results-default-test.xml ./tests/results-variation1-test.xml + ./tests/results-non-interactive-test.xml + ./tests/results-CNMirror-test.xml + ./tests/results-CNMirror2-test.xml ./tests/test.log publish-test-results: diff --git a/tests/run_pre_test.ps1 b/tests/run_pre_test.ps1 index 96fb230..50b0c3a 100644 --- a/tests/run_pre_test.ps1 +++ b/tests/run_pre_test.ps1 @@ -23,4 +23,4 @@ Expand-Archive node_modules.zip # Run tests using npm run AllTest npm run pre-test -npm run pre-install \ No newline at end of file +# npm run pre-install \ No newline at end of file diff --git a/tests/runs/CNmirrors2.test.js b/tests/runs/CNmirrors2.test.js index 61c2211..f56bbd1 100644 --- a/tests/runs/CNmirrors2.test.js +++ b/tests/runs/CNmirrors2.test.js @@ -24,7 +24,7 @@ if (process.env.EIM_FILE_PATH) { pathToEim = path.join(os.homedir(), "eim-cli/eim"); } -logger.debug(`Starting installation using alternative download mirrors`); +logger.debug(`Starting installation using mirror jihulab and dl.espressif.cn`); const targetList = ["esp32"]; // targets used for IDF installation const idfVersionList = ["v5.0.7"]; // IDF versions to be installed diff --git a/tests/script/installNonInteractive.test.js b/tests/script/installNonInteractive.test.js index c61daab..1b88f0b 100644 --- a/tests/script/installNonInteractive.test.js +++ b/tests/script/installNonInteractive.test.js @@ -43,7 +43,7 @@ export function runInstallNonInteractive(pathToEim, args = []) { it("Should install IDF using specified parameters", async function () { logger.info("Sent command line for IDF installation"); - testRunner.sendInput(`${pathToEim} ${args.join(" ")} -n true \r`); + testRunner.sendInput(`${pathToEim} ${args.join(" ")} -n true\r`); const installationSuccessful = await testRunner.waitForOutput( "Successfully installed IDF", diff --git a/tests/script/postInstall.test.js b/tests/script/postInstall.test.js index 03c4513..2c5542c 100644 --- a/tests/script/postInstall.test.js +++ b/tests/script/postInstall.test.js @@ -27,7 +27,7 @@ export function runPostInstallTest( logger.info("Error to start IDF terminal"); logger.info(testRunner.output); throw new Error( - "One test in teh chain failed, aborting the entire suite." + "One test in the chain failed, aborting the entire suite." ); } }); diff --git a/tests/script/prerequisitesInstallRunner.test.js b/tests/script/prerequisitesInstallRunner.test.js index 3c5eb61..d12a51b 100644 --- a/tests/script/prerequisitesInstallRunner.test.js +++ b/tests/script/prerequisitesInstallRunner.test.js @@ -40,7 +40,7 @@ describe("Check Pre-requisites installation on Windows", function () { }); afterEach(async function () { - this.timeout(10000); + this.timeout(20000); if (this.currentTest.state === "failed") { logger.info( `Terminal output on failure: >>\r ${testRunner.output}` @@ -49,7 +49,7 @@ describe("Check Pre-requisites installation on Windows", function () { try { await testRunner.stop(6000); } catch { - logger.debug("Error to clean up terminal after test"); + logger.info("Error to clean up terminal after test"); } testRunner = null; }); From d3d19d93ada0cd3c544348cc2d053b9f087bbe17 Mon Sep 17 00:00:00 2001 From: Fabricio-ESP Date: Mon, 25 Nov 2024 14:55:17 +0000 Subject: [PATCH 10/20] Fix CN test script, improve error handling. --- tests/runs/CNmirrors.test.js | 4 +++- tests/runs/CNmirrors2.test.js | 4 +++- tests/runs/nonInteractiveInstall.test.js | 4 ++-- tests/runs/variation1.test.js | 4 ++-- tests/script/postInstall.test.js | 5 ++--- 5 files changed, 12 insertions(+), 9 deletions(-) diff --git a/tests/runs/CNmirrors.test.js b/tests/runs/CNmirrors.test.js index d5c77c5..3492164 100644 --- a/tests/runs/CNmirrors.test.js +++ b/tests/runs/CNmirrors.test.js @@ -33,9 +33,11 @@ const projectFolder = "project"; let installArgs = []; installArgs.push(` -p ${path.join(os.homedir(), installFolder)}`); // Install Path +// installArgs.push(` -t ${targetList.join(",")}`); // Targets // removed to install for all targets +// installArgs.push(` -i ${idfVersionList.join(",")}`); // IDF versions Removed to install latest version installArgs.push(` -m https://dl.espressif.com/github_assets`); // IDF tools mirror installArgs.push(` --idf-mirror https://jihulab.com/esp-mirror`); // ESP-IDF mirror -installArgs.push(` -r true`); // recursive submodules init +installArgs.push(` -r false`); // recursive submodules init const pathToIDFScript = os.platform() !== "win32" diff --git a/tests/runs/CNmirrors2.test.js b/tests/runs/CNmirrors2.test.js index f56bbd1..5191752 100644 --- a/tests/runs/CNmirrors2.test.js +++ b/tests/runs/CNmirrors2.test.js @@ -33,9 +33,11 @@ const projectFolder = "project"; let installArgs = []; installArgs.push(` -p ${path.join(os.homedir(), installFolder)}`); // Install Path +installArgs.push(` -t ${targetList.join(",")}`); // Targets +installArgs.push(` -i ${idfVersionList.join(",")}`); // IDF versions installArgs.push(` -m https://dl.espressif.cn/github_assets`); // IDF tools mirror installArgs.push(` --idf-mirror https://jihulab.com/esp-mirror`); // ESP-IDF mirror -installArgs.push(` -r true`); // recursive submodules init +installArgs.push(` -r false`); // recursive submodules init const pathToIDFScript = os.platform() !== "win32" diff --git a/tests/runs/nonInteractiveInstall.test.js b/tests/runs/nonInteractiveInstall.test.js index f61da5f..63a1971 100644 --- a/tests/runs/nonInteractiveInstall.test.js +++ b/tests/runs/nonInteractiveInstall.test.js @@ -33,8 +33,8 @@ const projectFolder = "project"; let installArgs = []; installArgs.push(` -p ${path.join(os.homedir(), installFolder)}`); // Install Path -installArgs.push(` -t ${targetList.join(",")}`); // Targets (in case of multiple separate with ,) -installArgs.push(` -i ${idfVersionList.join(",")}`); // IDF versions (in case of multiple separate with ,) +installArgs.push(` -t ${targetList.join(",")}`); // Targets +installArgs.push(` -i ${idfVersionList.join(",")}`); // IDF versions installArgs.push(` -m https://github.com`); // IDF tools mirror installArgs.push(` --idf-mirror https://github.com`); // ESP-IDF mirror installArgs.push(` -r true`); // recursive submodules init diff --git a/tests/runs/variation1.test.js b/tests/runs/variation1.test.js index 334b803..6cd98fa 100644 --- a/tests/runs/variation1.test.js +++ b/tests/runs/variation1.test.js @@ -33,8 +33,8 @@ const projectFolder = "project"; let installArgs = []; installArgs.push(` -p ${path.join(os.homedir(), installFolder)}`); // Install Path -installArgs.push(` -t ${targetList.join(",")}`); // Targets (in case of multiple separate with ,) -installArgs.push(` -i ${idfVersionList.join(",")}`); // IDF versions (in case of multiple separate with ,) +installArgs.push(` -t ${targetList.join(",")}`); // Targets +installArgs.push(` -i ${idfVersionList.join(",")}`); // IDF versions installArgs.push(` -m https://github.com`); // IDF tools mirror installArgs.push(` --idf-mirror https://github.com`); // ESP-IDF mirror installArgs.push(` -r true`); // recursive submodules init diff --git a/tests/script/postInstall.test.js b/tests/script/postInstall.test.js index 2c5542c..78a14f5 100644 --- a/tests/script/postInstall.test.js +++ b/tests/script/postInstall.test.js @@ -26,9 +26,8 @@ export function runPostInstallTest( } catch { logger.info("Error to start IDF terminal"); logger.info(testRunner.output); - throw new Error( - "One test in the chain failed, aborting the entire suite." - ); + this.test.error(new Error("Error starting IDF Terminal")); + throw error; } }); From a1eb6e969ed056983b294ca1d6f8eba75fe0f6c4 Mon Sep 17 00:00:00 2001 From: Fabricio-ESP Date: Mon, 25 Nov 2024 15:19:02 +0000 Subject: [PATCH 11/20] Update macOS runner version to mac-13 --- .github/workflows/build_rust.yaml | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/.github/workflows/build_rust.yaml b/.github/workflows/build_rust.yaml index f13deb2..0a22a91 100644 --- a/.github/workflows/build_rust.yaml +++ b/.github/workflows/build_rust.yaml @@ -15,20 +15,20 @@ on: workflow_dispatch: jobs: - build: - name: Build for multiple platforms - runs-on: ${{ matrix.os }} - strategy: - matrix: - include: - - os: ubuntu-latest - package_name: linux-x64 - - os: windows-latest - package_name: windows-x64 - - os: macos-latest - package_name: macos-aarch64 - - os: macos-12 - package_name: macos-x64 + build: + name: Build for multiple platforms + runs-on: ${{ matrix.os }} + strategy: + matrix: + include: + - os: ubuntu-latest + package_name: linux-x64 + - os: windows-latest + package_name: windows-x64 + - os: macos-latest + package_name: macos-aarch64 + - os: macos-13 + package_name: macos-x64 steps: - name: Checkout repository From 2811c3195180b8ed9a180e9a5299303c2783d295 Mon Sep 17 00:00:00 2001 From: Fabricio-ESP Date: Tue, 26 Nov 2024 10:34:31 +0000 Subject: [PATCH 12/20] Add error handling and improved logging --- tests/classes/CLITestRunner.class.js | 8 ++++---- tests/runs/CNmirrors.test.js | 6 ++++-- tests/runs/CNmirrors2.test.js | 6 ++++-- tests/runs/defaultInstall.test.js | 4 ++++ tests/runs/nonInteractiveInstall.test.js | 4 ++-- tests/runs/variation1.test.js | 4 ++-- tests/script/commandLineArguments.test.js | 5 ++++- tests/script/installCustom.test.js | 10 +++++++--- tests/script/installNonInteractive.test.js | 10 +++++++--- tests/script/installWizard.test.js | 9 +++++++-- tests/script/postInstall.test.js | 10 ++++++---- tests/script/prerequisites.test.js | 6 ++++-- tests/script/prerequisitesInstall.test.js | 5 ++++- tests/script/prerequisitesInstallRunner.test.js | 2 ++ 14 files changed, 61 insertions(+), 28 deletions(-) diff --git a/tests/classes/CLITestRunner.class.js b/tests/classes/CLITestRunner.class.js index f839ea5..5543df4 100644 --- a/tests/classes/CLITestRunner.class.js +++ b/tests/classes/CLITestRunner.class.js @@ -85,7 +85,7 @@ export class InteractiveCLITestRunner { await this.waitForPrompt(); return Promise.resolve(); } catch (error) { - logger.debug(`Error detecting prompt >>${this.output}<<< `); + logger.info(`Error detecting prompt >>${this.output}<<< `); return Promise.reject(error); } } else { @@ -143,17 +143,17 @@ export class InteractiveCLITestRunner { const exitTime = Date.now(); while (Date.now() - exitTime < timeout * 2) { if (this.exited) { - logger.debug("terminal exited gracefully"); + logger.info("terminal exited gracefully"); return Promise.resolve(); } await new Promise((resolve) => setTimeout(resolve, 200)); } - logger.debug("Terminal didn't exit gracefully, killing task"); + logger.info("Terminal didn't exit gracefully, killing task"); this.process.kill(); const killTime = Date.now(); while (Date.now() - killTime < timeout) { if (this.exited) { - logger.debug("Terminal is now killed"); + logger.info("Terminal is now killed"); return Promise.resolve(); } await new Promise((resolve) => setTimeout(resolve, 200)); diff --git a/tests/runs/CNmirrors.test.js b/tests/runs/CNmirrors.test.js index 3492164..afe9bf3 100644 --- a/tests/runs/CNmirrors.test.js +++ b/tests/runs/CNmirrors.test.js @@ -24,8 +24,6 @@ if (process.env.EIM_FILE_PATH) { pathToEim = path.join(os.homedir(), "eim-cli/eim"); } -logger.debug(`Starting installation using mirror jihulab and dl.espressif.com`); - const targetList = ["esp32c6"]; // targets used for IDF installation const idfVersionList = ["v5.3.1"]; // IDF versions to be installed const installFolder = ".espressif4"; @@ -53,6 +51,10 @@ const pathToIDFScript = `Microsoft.PowerShell_profile.ps1` ); +logger.info( + `Starting installation using mirror jihulab and dl.espressif.com and EIM on ${pathToEim}` +); + describe("Installation using mirror jihulab and dl.espressif.com", function () { this.timeout(2400000); diff --git a/tests/runs/CNmirrors2.test.js b/tests/runs/CNmirrors2.test.js index 5191752..20b6439 100644 --- a/tests/runs/CNmirrors2.test.js +++ b/tests/runs/CNmirrors2.test.js @@ -24,8 +24,6 @@ if (process.env.EIM_FILE_PATH) { pathToEim = path.join(os.homedir(), "eim-cli/eim"); } -logger.debug(`Starting installation using mirror jihulab and dl.espressif.cn`); - const targetList = ["esp32"]; // targets used for IDF installation const idfVersionList = ["v5.0.7"]; // IDF versions to be installed const installFolder = ".espressif5"; @@ -53,6 +51,10 @@ const pathToIDFScript = `Microsoft.PowerShell_profile.ps1` ); +logger.info( + `Starting installation using mirror jihulab and dl.espressif.cn and EIM on ${pathToEim}` +); + describe("using mirror jihulab and dl.espressif.cn", function () { this.timeout(2400000); diff --git a/tests/runs/defaultInstall.test.js b/tests/runs/defaultInstall.test.js index 7d58290..194288b 100644 --- a/tests/runs/defaultInstall.test.js +++ b/tests/runs/defaultInstall.test.js @@ -42,6 +42,10 @@ const pathToProjectFolder = ? path.join(os.homedir(), ".espressif/project") : "C:\\esp\\project"; +logger.info( + `Starting installation using wizard and default settings using EIM on ${pathToEim}` +); + describe("Installation using default settings", function () { this.timeout(2400000); diff --git a/tests/runs/nonInteractiveInstall.test.js b/tests/runs/nonInteractiveInstall.test.js index 63a1971..a96c5b3 100644 --- a/tests/runs/nonInteractiveInstall.test.js +++ b/tests/runs/nonInteractiveInstall.test.js @@ -24,8 +24,6 @@ if (process.env.EIM_FILE_PATH) { pathToEim = path.join(os.homedir(), "eim-cli/eim"); } -logger.debug(`Starting non-interactive installation using EIM on ${pathToEim}`); - const targetList = ["esp32c6"]; // targets used for IDF installation const idfVersionList = ["v5.3.1"]; // IDF versions to be installed const installFolder = ".espressif3"; @@ -53,6 +51,8 @@ const pathToIDFScript = `Microsoft.PowerShell_profile.ps1` ); +logger.debug(`Starting non-interactive installation using EIM on ${pathToEim}`); + describe("Installation using non-interactive settings", function () { this.timeout(2400000); diff --git a/tests/runs/variation1.test.js b/tests/runs/variation1.test.js index 6cd98fa..fe806be 100644 --- a/tests/runs/variation1.test.js +++ b/tests/runs/variation1.test.js @@ -24,8 +24,6 @@ if (process.env.EIM_FILE_PATH) { pathToEim = path.join(os.homedir(), "eim-cli/eim"); } -logger.debug(`Starting custom installation using EIM on ${pathToEim}`); - const targetList = ["esp32s2"]; // targets used for IDF installation const idfVersionList = ["v5.2.3"]; // IDF versions to be installed const installFolder = ".espressif2"; @@ -53,6 +51,8 @@ const pathToIDFScript = `Microsoft.PowerShell_profile.ps1` ); +logger.debug(`Starting custom installation using EIM on ${pathToEim}`); + describe("Installation using custom settings", function () { this.timeout(2400000); diff --git a/tests/script/commandLineArguments.test.js b/tests/script/commandLineArguments.test.js index a3b50fa..0e27be7 100644 --- a/tests/script/commandLineArguments.test.js +++ b/tests/script/commandLineArguments.test.js @@ -21,12 +21,13 @@ export function runArgumentsTests(pathToEim, eimVersion) { try { await testRunner.stop(6000); } catch { - logger.debug("Error to clean up terminal after test"); + logger.info("Error to clean up terminal after test"); } testRunner = null; }); it("should show correct version number", async function () { + logger.info(`Starting test - show correct version`); await testRunner.start(); testRunner.sendInput(`${pathToEim} -V\r`); const meetVersion = await testRunner.waitForOutput(eimVersion); @@ -35,6 +36,7 @@ export function runArgumentsTests(pathToEim, eimVersion) { }); it("should show help with --help argument", async function () { + logger.info(`Starting test - show help`); await testRunner.start(); testRunner.sendInput(`${pathToEim} --help\r`); const printHelp = await testRunner.waitForOutput("Options:"); @@ -46,6 +48,7 @@ export function runArgumentsTests(pathToEim, eimVersion) { }); it("should handle invalid arguments", async function () { + logger.info(`Starting test - invalid argument`); await testRunner.start(); testRunner.sendInput(`${pathToEim} --KK\r`); const wrongArgument = await testRunner.waitForOutput( diff --git a/tests/script/installCustom.test.js b/tests/script/installCustom.test.js index f050c9c..f2c0cb8 100644 --- a/tests/script/installCustom.test.js +++ b/tests/script/installCustom.test.js @@ -15,7 +15,11 @@ export function runInstallCustom(pathToEim, args = []) { ); this.timeout(5000); testRunner = new InteractiveCLITestRunner(); - await testRunner.start(); + try { + await testRunner.start(); + } catch { + logger.info("Error to start terminal"); + } }); afterEach(function () { @@ -33,7 +37,7 @@ export function runInstallCustom(pathToEim, args = []) { try { await testRunner.stop(6000); } catch { - logger.debug("Error to clean up terminal after test"); + logger.info("Error to clean up terminal after test"); } }); @@ -44,7 +48,7 @@ export function runInstallCustom(pathToEim, args = []) { */ it("Should install IDF using specified parameters", async function () { - logger.info("Sent command line for IDF installation"); + logger.info(`Starting test - IDF custom installation`); testRunner.sendInput(`${pathToEim} ${args.join(" ")}\r`); const installationCompleted = await testRunner.waitForOutput( "Do you want to save the installer configuration", diff --git a/tests/script/installNonInteractive.test.js b/tests/script/installNonInteractive.test.js index 1b88f0b..9ea27b1 100644 --- a/tests/script/installNonInteractive.test.js +++ b/tests/script/installNonInteractive.test.js @@ -12,7 +12,11 @@ export function runInstallNonInteractive(pathToEim, args = []) { logger.debug(`Using parameters ${args.join(" ")}`); this.timeout(5000); testRunner = new InteractiveCLITestRunner(); - await testRunner.start(); + try { + await testRunner.start(); + } catch { + logger.info("Error to start terminal"); + } }); afterEach(function () { @@ -30,7 +34,7 @@ export function runInstallNonInteractive(pathToEim, args = []) { try { await testRunner.stop(6000); } catch { - logger.debug("Error to clean up terminal after test"); + logger.info("Error to clean up terminal after test"); } }); @@ -42,7 +46,7 @@ export function runInstallNonInteractive(pathToEim, args = []) { */ it("Should install IDF using specified parameters", async function () { - logger.info("Sent command line for IDF installation"); + logger.info(`Starting test - IDF non-interactive installation`); testRunner.sendInput(`${pathToEim} ${args.join(" ")} -n true\r`); const installationSuccessful = await testRunner.waitForOutput( diff --git a/tests/script/installWizard.test.js b/tests/script/installWizard.test.js index 28d7efa..ad78d76 100644 --- a/tests/script/installWizard.test.js +++ b/tests/script/installWizard.test.js @@ -11,7 +11,11 @@ export function runInstallWizardTests(pathToEim) { logger.debug(`Starting installation wizard with default options`); this.timeout(5000); testRunner = new InteractiveCLITestRunner(); - await testRunner.start(); + try { + await testRunner.start(); + } catch { + logger.info("Error to start terminal"); + } }); afterEach(function () { @@ -28,7 +32,7 @@ export function runInstallWizardTests(pathToEim) { try { await testRunner.stop(6000); } catch { - logger.debug("Error to clean up terminal after test"); + logger.info("Error to clean up terminal after test"); } }); @@ -40,6 +44,7 @@ export function runInstallWizardTests(pathToEim) { */ it("Should install IDF using wizard and default values", async function () { + logger.info(`Starting test - IDF installation wizard`); testRunner.sendInput(`${pathToEim}\r`); const selectTargetQuestion = await testRunner.waitForOutput( "Please select all of the target platforms", diff --git a/tests/script/postInstall.test.js b/tests/script/postInstall.test.js index 78a14f5..06b2140 100644 --- a/tests/script/postInstall.test.js +++ b/tests/script/postInstall.test.js @@ -3,7 +3,6 @@ import { describe, it, before, after, beforeEach, afterEach } from "mocha"; import { InteractiveCLITestRunner } from "../classes/CLITestRunner.class.js"; import logger from "../classes/logger.class.js"; import os from "os"; -import path from "path"; export function runPostInstallTest( pathToIDFScript, @@ -42,7 +41,7 @@ export function runPostInstallTest( await testRunner.stop(6000); testRunner = null; } catch { - logger.debug("Error to clean up terminal after test"); + logger.info("Error to clean up terminal after test"); } }); @@ -52,6 +51,7 @@ export function runPostInstallTest( * The commands might differ for each operating system. * The assert is based on the existence of the project files in the expected folder. */ + logger.info(`Starting test - create new project`); testRunner.sendInput(`mkdir ${pathToProjectFolder}\r`); testRunner.sendInput(`cd ${pathToProjectFolder}\r`); @@ -94,14 +94,15 @@ export function runPostInstallTest( /** * This test attempts to set a target MCU for the project created in the previous test. */ - this.timeout(600000); + logger.info(`Starting test - set target`); + this.timeout(750000); testRunner.sendInput(`cd ${pathToProjectFolder}\r`); testRunner.sendInput("cd hello_world\r"); testRunner.sendInput(`idf.py set-target ${validTarget}\r`); const targetSet = await testRunner.waitForOutput( "Build files have been written to", - 600000 + 700000 ); expect( @@ -125,6 +126,7 @@ export function runPostInstallTest( * This test attempts to build artifacts for the project and targets selected above. * The test is successful if the success message is printed in the terminal. */ + logger.info(`Starting test - build project`); this.timeout(600000); testRunner.sendInput(`cd ${pathToProjectFolder}\r`); testRunner.sendInput("cd hello_world\r"); diff --git a/tests/script/prerequisites.test.js b/tests/script/prerequisites.test.js index a3df7cc..884db97 100644 --- a/tests/script/prerequisites.test.js +++ b/tests/script/prerequisites.test.js @@ -35,7 +35,7 @@ describe("Check if prerequisites are installed", function () { await testRunner.start(); testRunner.sendInput(`${pathToEim}\r`); } catch (error) { - logger.debug(`Error starting process: ${error}`); + logger.info(`Error starting process: ${error}`); throw error; } }); @@ -45,7 +45,7 @@ describe("Check if prerequisites are installed", function () { try { await testRunner.stop(6000); } catch { - logger.debug("Error to clean up terminal after test"); + logger.info("Error to clean up terminal after test"); } testRunner = null; }); @@ -68,6 +68,7 @@ describe("Check if prerequisites are installed", function () { }); it("Should detect missing requirements", async function () { + logger.info(`Starting test - confirm requirements are missing`); this.timeout(25000); const missingRequisites = await testRunner.waitForOutput( "Error: Please install the missing prerequisites", @@ -98,6 +99,7 @@ describe("Check if prerequisites are installed", function () { }); it("should offer to install prerequisites and exit upon negative answer", async function () { + logger.info(`Starting test - confirm requirements are missing`); this.timeout(25000); const promptRequisites = await testRunner.waitForOutput( "Do you want to install prerequisites?" diff --git a/tests/script/prerequisitesInstall.test.js b/tests/script/prerequisitesInstall.test.js index 8475bd4..72f17e3 100644 --- a/tests/script/prerequisitesInstall.test.js +++ b/tests/script/prerequisitesInstall.test.js @@ -49,12 +49,13 @@ describe("Check Pre-requisites installation on Windows", function () { try { await testRunner.stop(6000); } catch { - logger.debug("Error to clean up terminal after test"); + logger.info("Error to clean up terminal after test"); } testRunner = null; }); it("should install prerequisites and offer to install python and exit upon negative answer", async function () { + logger.info(`Starting test - check for missing requisites`); this.timeout(240000); const promptRequisites = await testRunner.waitForOutput( "Do you want to install prerequisites" @@ -93,6 +94,7 @@ describe("Check Pre-requisites installation on Windows", function () { }); it("should install python and proceed with installation", async function () { + logger.info(`Starting test - Check for python requisite`); this.timeout(240000); const promptPython2 = await testRunner.waitForOutput( "Do you want to install Python", @@ -120,6 +122,7 @@ describe("Check Pre-requisites installation on Windows", function () { }); it("should detect all prerequisites are installed", async function () { + logger.info(`Starting test - confirm no missing requisites`); this.timeout(20000); const selectTargetQuestion2 = await testRunner.waitForOutput( "Please select all of the target platforms", diff --git a/tests/script/prerequisitesInstallRunner.test.js b/tests/script/prerequisitesInstallRunner.test.js index d12a51b..dda830f 100644 --- a/tests/script/prerequisitesInstallRunner.test.js +++ b/tests/script/prerequisitesInstallRunner.test.js @@ -55,6 +55,7 @@ describe("Check Pre-requisites installation on Windows", function () { }); it("should install prerequisites and offer to install python and exit upon negative answer", async function () { + logger.info(`Starting test - check python requirement`); this.timeout(240000); const promptRequisites = await testRunner.waitForOutput( "Do you want to install prerequisites" @@ -80,6 +81,7 @@ describe("Check Pre-requisites installation on Windows", function () { }); it("should detect all prerequisites are installed", async function () { + logger.info(`Starting test - all requirements installed`); this.timeout(22000); const selectTargetQuestion2 = await testRunner.waitForOutput( "Please select all of the target platforms", From 0adaa0c36b000c93a857c365d527c77ade134eb9 Mon Sep 17 00:00:00 2001 From: Fabricio-ESP Date: Thu, 28 Nov 2024 15:46:28 +0000 Subject: [PATCH 13/20] Refactor stop method for terminal emulator --- tests/README.md | 20 ++++++++-------- tests/classes/CLITestRunner.class.js | 23 ++++++++++++++----- tests/runs/defaultInstall.test.js | 1 + tests/script/commandLineArguments.test.js | 5 ++-- tests/script/installCustom.test.js | 6 ++--- tests/script/installNonInteractive.test.js | 5 ++-- tests/script/installWizard.test.js | 5 ++-- tests/script/postInstall.test.js | 6 ++--- tests/script/prerequisites.test.js | 5 ++-- tests/script/prerequisitesInstall.test.js | 5 ++-- .../script/prerequisitesInstallRunner.test.js | 5 ++-- 11 files changed, 52 insertions(+), 34 deletions(-) diff --git a/tests/README.md b/tests/README.md index 84997d3..b3f1a7d 100644 --- a/tests/README.md +++ b/tests/README.md @@ -28,7 +28,7 @@ Install Node.js: > https://nodejs.org/en/download/prebuilt-installer/current -`choco install nodejs-lts --version="22.11.0" -y` +`choco install nodejs-lts --version="20.18.1" -y` Install git: @@ -50,7 +50,7 @@ Install Git and curl and build-essential packages Start a new terminal (to load nvm) -`nvm install 22` +`nvm install 20` Clone the public repository: @@ -76,9 +76,9 @@ Install node.js > https://nodejs.org/en/download/package-manager -`brew install node@22` +`brew install node@20` -`echo 'export PATH="/usr/local/opt/node@22/bin:$PATH"' >> ~/.zshrc` +`echo 'export PATH="/usr/local/opt/node@20/bin:$PATH"' >> ~/.zshrc` > This requires to restart the terminal in order to load Node.JS @@ -114,12 +114,12 @@ Open Powershell, and enable script execution: Prerequisites test can be executed by running: `.\tests\run_pre_test.ps1 "" ""` Default arguments are: -`.\tests\run_pre_test.ps1 "$env:USERPROFILE\eim-cli\eim.exe" "idf-im-cli 0.1.4"` +`.\tests\run_pre_test.ps1 "$env:USERPROFILE\eim-cli\eim.exe" "idf-im-cli 0.1.5"` To execute tests on windows, use the script `.\tests\run_test.ps1 "" ""` Default arguments are: -`.\tests\run_test.ps1 "$env:USERPROFILE\eim-cli\eim.exe" "idf-im-cli 0.1.4"` +`.\tests\run_test.ps1 "$env:USERPROFILE\eim-cli\eim.exe" "idf-im-cli 0.1.5"` #### Linux @@ -129,24 +129,24 @@ Default arguments are: Prerequisites test can be executed by running: `. ./tests/run_pre_test.sh "" ""` Default arguments are: -`. ./tests/run_pre_test.sh "$HOME/eim-cli/eim" "idf-im-cli 0.1.4"` +`. ./tests/run_pre_test.sh "$HOME/eim-cli/eim" "idf-im-cli 0.1.5"` To execute tests on linux, use the script: `. ./tests/run_test.sh "" ""` Default arguments are: -`. ./tests/run_test.sh "$HOME/eim-cli/eim" "idf-im-cli 0.1.4"` +`. ./tests/run_test.sh "$HOME/eim-cli/eim" "idf-im-cli 0.1.5"` #### MacOS Prerequisites test can be executed by running: `. ./tests/run_pre_test.sh "" ""` Default arguments are: -`. ./tests/run_pre_test.sh "$HOME/eim-cli/eim" "idf-im-cli 0.1.3"` +`. ./tests/run_pre_test.sh "$HOME/eim-cli/eim" "idf-im-cli 0.1.5"` To execute tests on linux, use the script: `. ./tests/run_test.sh "" ""` Default arguments are: -`. ./tests/run_test.sh "$HOME/eim-cli/eim" "idf-im-cli 0.1.3"` +`. ./tests/run_test.sh "$HOME/eim-cli/eim" "idf-im-cli 0.1.5"` # Installation Manager Usage diff --git a/tests/classes/CLITestRunner.class.js b/tests/classes/CLITestRunner.class.js index 5543df4..4bca463 100644 --- a/tests/classes/CLITestRunner.class.js +++ b/tests/classes/CLITestRunner.class.js @@ -38,10 +38,11 @@ export class InteractiveCLITestRunner { } await new Promise((resolve) => setTimeout(resolve, 200)); } - return Promise.reject(); + logger.info("Failed to terminate terminal process"); + return Promise.resolve(); } catch { logger.debug("Error loading IDF terminal"); - return Promise.reject(); + return Promise.resolve(); } } @@ -139,9 +140,19 @@ export class InteractiveCLITestRunner { if (this.process && !this.exited) { try { this.sendInput("exit\r"); - const exitTime = Date.now(); - while (Date.now() - exitTime < timeout * 2) { + while (Date.now() - exitTime < timeout) { + if (this.exited) { + logger.info("terminal exited gracefully"); + return Promise.resolve(); + } + await new Promise((resolve) => setTimeout(resolve, 200)); + } + logger.info("Terminal didn't exit gracefully, repeat Attempt"); + testRunner.sendInput("\x03"); + this.sendInput("exit\r"); + const closeTime = Date.now(); + while (Date.now() - closeTime < timeout) { if (this.exited) { logger.info("terminal exited gracefully"); return Promise.resolve(); @@ -158,12 +169,12 @@ export class InteractiveCLITestRunner { } await new Promise((resolve) => setTimeout(resolve, 200)); } - return Promise.reject("Could not stop terminal task"); + throw new Error("Could not stop terminal task"); } catch (error) { logger.error("Error stopping terminal:", error); this.exited = true; this.process = null; - return Promise.reject(error); + throw error; } } else { logger.debug("Terminal has already exited"); diff --git a/tests/runs/defaultInstall.test.js b/tests/runs/defaultInstall.test.js index 194288b..c7a9533 100644 --- a/tests/runs/defaultInstall.test.js +++ b/tests/runs/defaultInstall.test.js @@ -2,6 +2,7 @@ import { describe, it, before, after } from "mocha"; import { runArgumentsTests } from "../script/commandLineArguments.test.js"; import { runInstallWizardTests } from "../script/installWizard.test.js"; import { runPostInstallTest } from "../script/postInstall.test.js"; +import logger from "../classes/logger.class.js"; import os from "os"; import path from "path"; diff --git a/tests/script/commandLineArguments.test.js b/tests/script/commandLineArguments.test.js index 0e27be7..680d628 100644 --- a/tests/script/commandLineArguments.test.js +++ b/tests/script/commandLineArguments.test.js @@ -19,9 +19,10 @@ export function runArgumentsTests(pathToEim, eimVersion) { ); } try { - await testRunner.stop(6000); - } catch { + await testRunner.stop(); + } catch (error) { logger.info("Error to clean up terminal after test"); + throw error; } testRunner = null; }); diff --git a/tests/script/installCustom.test.js b/tests/script/installCustom.test.js index f2c0cb8..44aeecc 100644 --- a/tests/script/installCustom.test.js +++ b/tests/script/installCustom.test.js @@ -27,7 +27,6 @@ export function runInstallCustom(pathToEim, args = []) { logger.info( `Terminal output on failure: >>\r ${testRunner.output}` ); - testRunner.sendInput("\x03"); } }); @@ -35,9 +34,10 @@ export function runInstallCustom(pathToEim, args = []) { logger.info("Custom installation routine completed"); this.timeout(20000); try { - await testRunner.stop(6000); - } catch { + await testRunner.stop(); + } catch (error) { logger.info("Error to clean up terminal after test"); + throw error; } }); diff --git a/tests/script/installNonInteractive.test.js b/tests/script/installNonInteractive.test.js index 9ea27b1..1b0eea8 100644 --- a/tests/script/installNonInteractive.test.js +++ b/tests/script/installNonInteractive.test.js @@ -32,9 +32,10 @@ export function runInstallNonInteractive(pathToEim, args = []) { logger.info("Custom installation routine completed"); this.timeout(20000); try { - await testRunner.stop(6000); - } catch { + await testRunner.stop(); + } catch (error) { logger.info("Error to clean up terminal after test"); + throw error; } }); diff --git a/tests/script/installWizard.test.js b/tests/script/installWizard.test.js index ad78d76..1574291 100644 --- a/tests/script/installWizard.test.js +++ b/tests/script/installWizard.test.js @@ -30,9 +30,10 @@ export function runInstallWizardTests(pathToEim) { logger.info("Install Wizard routine completed"); this.timeout(20000); try { - await testRunner.stop(6000); - } catch { + await testRunner.stop(); + } catch (error) { logger.info("Error to clean up terminal after test"); + throw error; } }); diff --git a/tests/script/postInstall.test.js b/tests/script/postInstall.test.js index 06b2140..7825fb6 100644 --- a/tests/script/postInstall.test.js +++ b/tests/script/postInstall.test.js @@ -38,10 +38,10 @@ export function runPostInstallTest( ); } try { - await testRunner.stop(6000); - testRunner = null; - } catch { + await testRunner.stop(); + } catch (error) { logger.info("Error to clean up terminal after test"); + throw error; } }); diff --git a/tests/script/prerequisites.test.js b/tests/script/prerequisites.test.js index 884db97..e78e2ea 100644 --- a/tests/script/prerequisites.test.js +++ b/tests/script/prerequisites.test.js @@ -43,9 +43,10 @@ describe("Check if prerequisites are installed", function () { afterEach(async function () { this.timeout(20000); try { - await testRunner.stop(6000); - } catch { + await testRunner.stop(); + } catch (error) { logger.info("Error to clean up terminal after test"); + throw error; } testRunner = null; }); diff --git a/tests/script/prerequisitesInstall.test.js b/tests/script/prerequisitesInstall.test.js index 72f17e3..9f87b4a 100644 --- a/tests/script/prerequisitesInstall.test.js +++ b/tests/script/prerequisitesInstall.test.js @@ -47,9 +47,10 @@ describe("Check Pre-requisites installation on Windows", function () { ); } try { - await testRunner.stop(6000); - } catch { + await testRunner.stop(); + } catch (error) { logger.info("Error to clean up terminal after test"); + throw error; } testRunner = null; }); diff --git a/tests/script/prerequisitesInstallRunner.test.js b/tests/script/prerequisitesInstallRunner.test.js index dda830f..a0b4abc 100644 --- a/tests/script/prerequisitesInstallRunner.test.js +++ b/tests/script/prerequisitesInstallRunner.test.js @@ -47,9 +47,10 @@ describe("Check Pre-requisites installation on Windows", function () { ); } try { - await testRunner.stop(6000); - } catch { + await testRunner.stop(); + } catch (error) { logger.info("Error to clean up terminal after test"); + throw error; } testRunner = null; }); From 8d8e717abd4064069c1112d8c0920a7962f86462 Mon Sep 17 00:00:00 2001 From: Fabricio-ESP Date: Thu, 28 Nov 2024 17:05:19 +0000 Subject: [PATCH 14/20] Increased timeout, fixed typo --- tests/classes/CLITestRunner.class.js | 2 +- tests/script/postInstall.test.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/classes/CLITestRunner.class.js b/tests/classes/CLITestRunner.class.js index 4bca463..fcfb1b3 100644 --- a/tests/classes/CLITestRunner.class.js +++ b/tests/classes/CLITestRunner.class.js @@ -149,7 +149,7 @@ export class InteractiveCLITestRunner { await new Promise((resolve) => setTimeout(resolve, 200)); } logger.info("Terminal didn't exit gracefully, repeat Attempt"); - testRunner.sendInput("\x03"); + this.sendInput("\x03"); this.sendInput("exit\r"); const closeTime = Date.now(); while (Date.now() - closeTime < timeout) { diff --git a/tests/script/postInstall.test.js b/tests/script/postInstall.test.js index 7825fb6..3364ee6 100644 --- a/tests/script/postInstall.test.js +++ b/tests/script/postInstall.test.js @@ -102,7 +102,7 @@ export function runPostInstallTest( const targetSet = await testRunner.waitForOutput( "Build files have been written to", - 700000 + 900000 ); expect( From 1b8600b178e0c65d15dce3370d3fb6968334b706 Mon Sep 17 00:00:00 2001 From: Fabricio-ESP Date: Tue, 3 Dec 2024 16:45:12 +0000 Subject: [PATCH 15/20] Error handling to kill terminal task --- tests/classes/CLITestRunner.class.js | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/tests/classes/CLITestRunner.class.js b/tests/classes/CLITestRunner.class.js index fcfb1b3..adb0531 100644 --- a/tests/classes/CLITestRunner.class.js +++ b/tests/classes/CLITestRunner.class.js @@ -1,7 +1,6 @@ import pty from "node-pty"; import os from "os"; import logger from "./logger.class.js"; -import { createCipheriv } from "crypto"; export class InteractiveCLITestRunner { constructor() { @@ -160,7 +159,9 @@ export class InteractiveCLITestRunner { await new Promise((resolve) => setTimeout(resolve, 200)); } logger.info("Terminal didn't exit gracefully, killing task"); - this.process.kill(); + try { + this.process.kill(); + } catch {} const killTime = Date.now(); while (Date.now() - killTime < timeout) { if (this.exited) { @@ -171,7 +172,7 @@ export class InteractiveCLITestRunner { } throw new Error("Could not stop terminal task"); } catch (error) { - logger.error("Error stopping terminal:", error); + logger.info("Error stopping terminal:", error); this.exited = true; this.process = null; throw error; From a1d5680e80941d6a3cb14d9cd1a728545cca3319 Mon Sep 17 00:00:00 2001 From: Fabricio-ESP Date: Wed, 4 Dec 2024 16:12:20 +0000 Subject: [PATCH 16/20] Removing terminal process kill method. --- tests/classes/CLITestRunner.class.js | 18 +++++------------- 1 file changed, 5 insertions(+), 13 deletions(-) diff --git a/tests/classes/CLITestRunner.class.js b/tests/classes/CLITestRunner.class.js index adb0531..22fe259 100644 --- a/tests/classes/CLITestRunner.class.js +++ b/tests/classes/CLITestRunner.class.js @@ -149,6 +149,7 @@ export class InteractiveCLITestRunner { } logger.info("Terminal didn't exit gracefully, repeat Attempt"); this.sendInput("\x03"); + this.sendInput("\x03"); this.sendInput("exit\r"); const closeTime = Date.now(); while (Date.now() - closeTime < timeout) { @@ -158,19 +159,10 @@ export class InteractiveCLITestRunner { } await new Promise((resolve) => setTimeout(resolve, 200)); } - logger.info("Terminal didn't exit gracefully, killing task"); - try { - this.process.kill(); - } catch {} - const killTime = Date.now(); - while (Date.now() - killTime < timeout) { - if (this.exited) { - logger.info("Terminal is now killed"); - return Promise.resolve(); - } - await new Promise((resolve) => setTimeout(resolve, 200)); - } - throw new Error("Could not stop terminal task"); + logger.info( + "Terminal didn't exit gracefully, abandoning task, should be terminated by node." + ); + throw new Error("Could not stop terminal gracefully"); } catch (error) { logger.info("Error stopping terminal:", error); this.exited = true; From e6522286870cc23395b5b6cacf151db574591b60 Mon Sep 17 00:00:00 2001 From: Fabricio-ESP Date: Wed, 4 Dec 2024 16:24:29 +0000 Subject: [PATCH 17/20] Fix CI workflow format --- .github/workflows/build_rust.yaml | 400 +++++++++++++++--------------- 1 file changed, 194 insertions(+), 206 deletions(-) diff --git a/.github/workflows/build_rust.yaml b/.github/workflows/build_rust.yaml index 0a22a91..35cdc19 100644 --- a/.github/workflows/build_rust.yaml +++ b/.github/workflows/build_rust.yaml @@ -1,18 +1,18 @@ name: Rust on: - push: - tags: - - "v*" - branches: - - master - pull_request: - branches: - - master - release: - types: - - created - workflow_dispatch: + push: + tags: + - "v*" + branches: + - master + pull_request: + branches: + - master + release: + types: + - created + workflow_dispatch: jobs: build: @@ -30,198 +30,186 @@ jobs: - os: macos-13 package_name: macos-x64 - steps: - - name: Checkout repository - uses: actions/checkout@v4 - - - name: Set up Rust - uses: actions-rs/toolchain@v1 - with: - toolchain: stable - override: true - - - name: Install OpenSSL (Windows) - if: runner.os == 'Windows' - shell: powershell - run: | - echo "VCPKG_ROOT=$env:VCPKG_INSTALLATION_ROOT" | Out-File -FilePath $env:GITHUB_ENV -Append - vcpkg install openssl:x64-windows-static-md - - - name: Install OpenSSL (Macos) - if: matrix.os == 'macos-latest' - run: brew install openssl - - - name: Cache cargo registry - uses: actions/cache@v4 - with: - path: ~/.cargo/registry - key: ${{ runner.os }}-cargo-registry - restore-keys: | - ${{ runner.os }}-cargo-registry - - - name: Cache cargo index - uses: actions/cache@v4 - with: - path: ~/.cargo/git - key: ${{ runner.os }}-cargo-index - restore-keys: | - ${{ runner.os }}-cargo-index - - - name: Build - run: cargo build --release - - # - name: Run tests - # run: cargo test --release - - - name: Create release directory - run: mkdir -p release - - - name: Create release system directory - run: mkdir -p release/${{ matrix.package_name }} - - - name: Copy binary to release directory Windows - if: matrix.os == 'windows-latest' - run: cp target/release/eim.exe release/${{ matrix.package_name }}/eim.exe - - - name: Sign Windows Binary - if: matrix.platform == 'windows-latest' - env: - WINDOWS_PFX_FILE: ${{ secrets.WIN_CERTIFICATE }} - WINDOWS_PFX_PASSWORD: ${{ secrets.WIN_CERTIFICATE_PWD }} - WINDOWS_SIGN_TOOL_PATH: 'C:\Program Files (x86)\Windows Kits\10\bin\10.0.17763.0\x86\signtool.exe' - run: | - echo $env:WINDOWS_PFX_FILE | Out-File -FilePath cert.b64 -Encoding ASCII - certutil -decode cert.b64 cert.pfx - Remove-Item cert.b64 - & "$env:WINDOWS_SIGN_TOOL_PATH" sign /f cert.pfx /p $env:WINDOWS_PFX_PASSWORD /tr http://timestamp.digicert.com /td sha256 /fd sha256 release/${{ matrix.package_name }}/eim.exe - - - name: Copy binary to release directory POSIX - if: matrix.os != 'windows-latest' - run: | - cp target/release/eim release/${{ matrix.package_name }}/eim - chmod +x release/${{ matrix.package_name }}/eim - - - name: Codesign macOS eim executables - if: startsWith(matrix.os, 'macos') - env: - MACOS_CERTIFICATE: ${{ secrets.MACOS_CERTIFICATE }} - MACOS_CERTIFICATE_PWD: ${{ secrets.MACOS_CERTIFICATE_PWD }} - run: | - echo $MACOS_CERTIFICATE | base64 --decode > certificate.p12 - /usr/bin/security create-keychain -p espressif build.keychain - /usr/bin/security default-keychain -s build.keychain - /usr/bin/security unlock-keychain -p espressif build.keychain - /usr/bin/security import certificate.p12 -k build.keychain -P $MACOS_CERTIFICATE_PWD -T /usr/bin/codesign - /usr/bin/security set-key-partition-list -S apple-tool:,apple:,codesign: -s -k espressif build.keychain - - /usr/bin/codesign --entitlements eim.entitlement --options runtime --force -s "ESPRESSIF SYSTEMS (SHANGHAI) CO., LTD. (QWXF6GB4AV)" release/${{ matrix.package_name }}/eim -v - /usr/bin/codesign -v -vvv --deep release/${{ matrix.package_name }}/eim - - - name: Zip eim executable for notarization - if: startsWith(matrix.os, 'macos') - run: | - cd release/${{ matrix.package_name }} - zip -r eim.zip eim - - - name: Notarization of macOS eim executables - # && github.ref == 'refs/heads/master' - if: startsWith(matrix.os, 'macos') - env: - NOTARIZATION_USERNAME: ${{ secrets.NOTARIZATION_USERNAME }} - NOTARIZATION_PASSWORD: ${{ secrets.NOTARIZATION_PASSWORD }} - NOTARIZATION_TEAM_ID: ${{ secrets.NOTARIZATION_TEAM_ID }} - run: | - echo "Create notary keychain" - /usr/bin/security create-keychain -p espressif notary.keychain - /usr/bin/security default-keychain -s notary.keychain - /usr/bin/security unlock-keychain -p espressif notary.keychain - - echo "Create keychain profile" - xcrun notarytool store-credentials "eim-notarytool-profile" --apple-id $NOTARIZATION_USERNAME --team-id $NOTARIZATION_TEAM_ID --password $NOTARIZATION_PASSWORD - xcrun notarytool submit release/${{ matrix.package_name }}/eim.zip --keychain-profile "eim-notarytool-profile" --wait - - echo "Unzipping the executable" - unzip -o release/${{ matrix.package_name }}/eim.zip -d release/${{ matrix.package_name }} - - # echo "Attach staple for eim executable" - # xcrun stapler staple release/${{ matrix.package_name }}/eim - - - name: Zip artifacts (Windows) - if: matrix.os == 'windows-latest' - run: | - cd release/${{ matrix.package_name }} - 7z a -tzip eim.zip eim.exe - - - name: Zip artifacts (POSIX) - if: matrix.os != 'windows-latest' - run: | - cd release/${{ matrix.package_name }} - zip -r eim.zip eim - - - name: Upload build artifacts - uses: actions/upload-artifact@v4 - with: - name: eim-${{ github.run_id }}-${{ matrix.package_name }} - path: release/${{ matrix.package_name }}/eim.zip - - - name: Upload artifact for tag - if: startsWith(github.ref, 'refs/tags/') - uses: actions/upload-artifact@v4 - with: - name: eim-${{ github.ref_name }}-${{ matrix.package_name }} - path: release/${{ matrix.package_name }}/eim.zip - - - name: Upload Release Asset - if: github.event_name == 'release' && github.event.action == 'created' - uses: actions/upload-release-asset@v1 - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - with: - upload_url: ${{ github.event.release.upload_url }} - asset_path: release/${{ matrix.package_name }}/eim.zip - asset_name: eim-${{ github.ref_name }}-${{ matrix.package_name }}.zip - asset_content_type: application/zip - - - name: Create aarch64-linux build - if: matrix.os == 'ubuntu-latest' - run: | - rustup target add aarch64-unknown-linux-gnu - cargo install cross - cross build --target aarch64-unknown-linux-gnu --release - mkdir -p release/aarch64-unknown-linux-gnu - cp target/aarch64-unknown-linux-gnu/release/eim release/aarch64-unknown-linux-gnu/eim - chmod +x release/aarch64-unknown-linux-gnu/eim - cd release/aarch64-unknown-linux-gnu - zip -r eim.zip eim - - - name: Upload build artifacts for aarch64-linux - uses: actions/upload-artifact@v4 - if: matrix.os == 'ubuntu-latest' - with: - name: eim-${{ github.run_id }}-linux-arm64 - path: release/aarch64-unknown-linux-gnu/eim.zip - - - name: Upload artifact for tag on aarch64-linux - if: startsWith(github.ref, 'refs/tags/') && runner.os == 'Linux' - uses: actions/upload-artifact@v4 - with: - name: eim-${{ github.ref_name }}-linux-arm64 - path: release/aarch64-unknown-linux-gnu/eim.zip - - - name: Upload Release Asset on aarch64-linux - if: github.event_name == 'release' && github.event.action == 'created' && runner.os == 'Linux' - uses: actions/upload-release-asset@v1 - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Set up Rust + uses: actions-rs/toolchain@v1 + with: + toolchain: stable + override: true + + - name: Install OpenSSL (Windows) + if: runner.os == 'Windows' + shell: powershell + run: | + echo "VCPKG_ROOT=$env:VCPKG_INSTALLATION_ROOT" | Out-File -FilePath $env:GITHUB_ENV -Append + vcpkg install openssl:x64-windows-static-md + + - name: Install OpenSSL (Macos) + if: matrix.os == 'macos-latest' + run: brew install openssl + + - name: Cache cargo registry + uses: actions/cache@v4 + with: + path: ~/.cargo/registry + key: ${{ runner.os }}-cargo-registry + restore-keys: | + ${{ runner.os }}-cargo-registry + + - name: Cache cargo index + uses: actions/cache@v4 + with: + path: ~/.cargo/git + key: ${{ runner.os }}-cargo-index + restore-keys: | + ${{ runner.os }}-cargo-index + + - name: Build + run: cargo build --release + + # - name: Run tests + # run: cargo test --release + + - name: Create release directory + run: mkdir -p release + + - name: Create release system directory + run: mkdir -p release/${{ matrix.package_name }} + + - name: Copy binary to release directory Windows + if: matrix.os == 'windows-latest' + run: cp target/release/eim.exe release/${{ matrix.package_name }}/eim.exe + + - name: Copy binary to release directory POSIX + if: matrix.os != 'windows-latest' + run: | + cp target/release/eim release/${{ matrix.package_name }}/eim + chmod +x release/${{ matrix.package_name }}/eim + + - name: Codesign macOS eim executables + if: startsWith(matrix.os, 'macos') + env: + MACOS_CERTIFICATE: ${{ secrets.MACOS_CERTIFICATE }} + MACOS_CERTIFICATE_PWD: ${{ secrets.MACOS_CERTIFICATE_PWD }} + run: | + echo $MACOS_CERTIFICATE | base64 --decode > certificate.p12 + /usr/bin/security create-keychain -p espressif build.keychain + /usr/bin/security default-keychain -s build.keychain + /usr/bin/security unlock-keychain -p espressif build.keychain + /usr/bin/security import certificate.p12 -k build.keychain -P $MACOS_CERTIFICATE_PWD -T /usr/bin/codesign + /usr/bin/security set-key-partition-list -S apple-tool:,apple:,codesign: -s -k espressif build.keychain + + /usr/bin/codesign --entitlements eim.entitlement --options runtime --force -s "ESPRESSIF SYSTEMS (SHANGHAI) CO., LTD. (QWXF6GB4AV)" release/${{ matrix.package_name }}/eim -v + /usr/bin/codesign -v -vvv --deep release/${{ matrix.package_name }}/eim + + - name: Zip eim executable for notarization + if: startsWith(matrix.os, 'macos') + run: | + cd release/${{ matrix.package_name }} + zip -r eim.zip eim + + - name: Notarization of macOS eim executables + # && github.ref == 'refs/heads/master' + if: startsWith(matrix.os, 'macos') + env: + NOTARIZATION_USERNAME: ${{ secrets.NOTARIZATION_USERNAME }} + NOTARIZATION_PASSWORD: ${{ secrets.NOTARIZATION_PASSWORD }} + NOTARIZATION_TEAM_ID: ${{ secrets.NOTARIZATION_TEAM_ID }} + run: | + echo "Create notary keychain" + /usr/bin/security create-keychain -p espressif notary.keychain + /usr/bin/security default-keychain -s notary.keychain + /usr/bin/security unlock-keychain -p espressif notary.keychain + + echo "Create keychain profile" + xcrun notarytool store-credentials "eim-notarytool-profile" --apple-id $NOTARIZATION_USERNAME --team-id $NOTARIZATION_TEAM_ID --password $NOTARIZATION_PASSWORD + xcrun notarytool submit release/${{ matrix.package_name }}/eim.zip --keychain-profile "eim-notarytool-profile" --wait + + echo "Unzipping the executable" + unzip -o release/${{ matrix.package_name }}/eim.zip -d release/${{ matrix.package_name }} + + # echo "Attach staple for eim executable" + # xcrun stapler staple release/${{ matrix.package_name }}/eim + + - name: Zip artifacts (Windows) + if: matrix.os == 'windows-latest' + run: | + cd release/${{ matrix.package_name }} + 7z a -tzip eim.zip eim.exe + + - name: Zip artifacts (POSIX) + if: matrix.os != 'windows-latest' + run: | + cd release/${{ matrix.package_name }} + zip -r eim.zip eim + + - name: Upload build artifacts + uses: actions/upload-artifact@v4 + with: + name: eim-${{ github.run_id }}-${{ matrix.package_name }} + path: release/${{ matrix.package_name }}/eim.zip + + - name: Upload artifact for tag + if: startsWith(github.ref, 'refs/tags/') + uses: actions/upload-artifact@v4 + with: + name: eim-${{ github.ref_name }}-${{ matrix.package_name }} + path: release/${{ matrix.package_name }}/eim.zip + + - name: Upload Release Asset + if: github.event_name == 'release' && github.event.action == 'created' + uses: actions/upload-release-asset@v1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + upload_url: ${{ github.event.release.upload_url }} + asset_path: release/${{ matrix.package_name }}/eim.zip + asset_name: eim-${{ github.ref_name }}-${{ matrix.package_name }}.zip + asset_content_type: application/zip + + - name: Create aarch64-linux build + if: matrix.os == 'ubuntu-latest' + run: | + rustup target add aarch64-unknown-linux-gnu + cargo install cross + cross build --target aarch64-unknown-linux-gnu --release + mkdir -p release/aarch64-unknown-linux-gnu + cp target/aarch64-unknown-linux-gnu/release/eim release/aarch64-unknown-linux-gnu/eim + chmod +x release/aarch64-unknown-linux-gnu/eim + cd release/aarch64-unknown-linux-gnu + zip -r eim.zip eim + + - name: Upload build artifacts for aarch64-linux + uses: actions/upload-artifact@v4 + if: matrix.os == 'ubuntu-latest' + with: + name: eim-${{ github.run_id }}-linux-arm64 + path: release/aarch64-unknown-linux-gnu/eim.zip + + - name: Upload artifact for tag on aarch64-linux + if: startsWith(github.ref, 'refs/tags/') && runner.os == 'Linux' + uses: actions/upload-artifact@v4 + with: + name: eim-${{ github.ref_name }}-linux-arm64 + path: release/aarch64-unknown-linux-gnu/eim.zip + + - name: Upload Release Asset on aarch64-linux + if: github.event_name == 'release' && github.event.action == 'created' && runner.os == 'Linux' + uses: actions/upload-release-asset@v1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + upload_url: ${{ github.event.release.upload_url }} + asset_path: release/aarch64-unknown-linux-gnu/eim.zip + asset_name: eim-${{ github.ref_name }}-linux-arm64.zip + asset_content_type: application/zip + + call-test-workflow: + needs: build + uses: ./.github/workflows/test.yml with: - upload_url: ${{ github.event.release.upload_url }} - asset_path: release/aarch64-unknown-linux-gnu/eim.zip - asset_name: eim-${{ github.ref_name }}-linux-arm64.zip - asset_content_type: application/zip - - call-test-workflow: - needs: build - uses: ./.github/workflows/test.yml - with: - run_id: ${{ github.run_id }} - ref: ${{ github.event.pull_request.head.ref }} + run_id: ${{ github.run_id }} + ref: ${{ github.event.pull_request.head.ref }} From 6c43f00e33af9c8295dbfd5a75ba76c1e6d15129 Mon Sep 17 00:00:00 2001 From: Fabricio-ESP Date: Thu, 5 Dec 2024 08:10:18 +0000 Subject: [PATCH 18/20] Remove error propagation --- .github/workflows/build_rust.yaml | 418 +++++++++++++-------------- tests/classes/CLITestRunner.class.js | 299 ++++++++++--------- tests/script/installCustom.test.js | 140 +++++---- 3 files changed, 423 insertions(+), 434 deletions(-) diff --git a/.github/workflows/build_rust.yaml b/.github/workflows/build_rust.yaml index 35cdc19..84067c2 100644 --- a/.github/workflows/build_rust.yaml +++ b/.github/workflows/build_rust.yaml @@ -1,215 +1,215 @@ name: Rust on: - push: - tags: - - "v*" - branches: - - master - pull_request: - branches: - - master - release: - types: - - created - workflow_dispatch: + push: + tags: + - "v*" + branches: + - master + pull_request: + branches: + - master + release: + types: + - created + workflow_dispatch: jobs: - build: - name: Build for multiple platforms - runs-on: ${{ matrix.os }} - strategy: - matrix: - include: - - os: ubuntu-latest - package_name: linux-x64 - - os: windows-latest - package_name: windows-x64 - - os: macos-latest - package_name: macos-aarch64 - - os: macos-13 - package_name: macos-x64 - - steps: - - name: Checkout repository - uses: actions/checkout@v4 - - - name: Set up Rust - uses: actions-rs/toolchain@v1 - with: - toolchain: stable - override: true - - - name: Install OpenSSL (Windows) - if: runner.os == 'Windows' - shell: powershell - run: | - echo "VCPKG_ROOT=$env:VCPKG_INSTALLATION_ROOT" | Out-File -FilePath $env:GITHUB_ENV -Append - vcpkg install openssl:x64-windows-static-md - - - name: Install OpenSSL (Macos) - if: matrix.os == 'macos-latest' - run: brew install openssl - - - name: Cache cargo registry - uses: actions/cache@v4 - with: - path: ~/.cargo/registry - key: ${{ runner.os }}-cargo-registry - restore-keys: | - ${{ runner.os }}-cargo-registry - - - name: Cache cargo index - uses: actions/cache@v4 - with: - path: ~/.cargo/git - key: ${{ runner.os }}-cargo-index - restore-keys: | - ${{ runner.os }}-cargo-index - - - name: Build - run: cargo build --release - - # - name: Run tests - # run: cargo test --release - - - name: Create release directory - run: mkdir -p release - - - name: Create release system directory - run: mkdir -p release/${{ matrix.package_name }} - - - name: Copy binary to release directory Windows - if: matrix.os == 'windows-latest' - run: cp target/release/eim.exe release/${{ matrix.package_name }}/eim.exe - - - name: Copy binary to release directory POSIX - if: matrix.os != 'windows-latest' - run: | - cp target/release/eim release/${{ matrix.package_name }}/eim - chmod +x release/${{ matrix.package_name }}/eim - - - name: Codesign macOS eim executables - if: startsWith(matrix.os, 'macos') - env: - MACOS_CERTIFICATE: ${{ secrets.MACOS_CERTIFICATE }} - MACOS_CERTIFICATE_PWD: ${{ secrets.MACOS_CERTIFICATE_PWD }} - run: | - echo $MACOS_CERTIFICATE | base64 --decode > certificate.p12 - /usr/bin/security create-keychain -p espressif build.keychain - /usr/bin/security default-keychain -s build.keychain - /usr/bin/security unlock-keychain -p espressif build.keychain - /usr/bin/security import certificate.p12 -k build.keychain -P $MACOS_CERTIFICATE_PWD -T /usr/bin/codesign - /usr/bin/security set-key-partition-list -S apple-tool:,apple:,codesign: -s -k espressif build.keychain - - /usr/bin/codesign --entitlements eim.entitlement --options runtime --force -s "ESPRESSIF SYSTEMS (SHANGHAI) CO., LTD. (QWXF6GB4AV)" release/${{ matrix.package_name }}/eim -v - /usr/bin/codesign -v -vvv --deep release/${{ matrix.package_name }}/eim - - - name: Zip eim executable for notarization - if: startsWith(matrix.os, 'macos') - run: | - cd release/${{ matrix.package_name }} - zip -r eim.zip eim - - - name: Notarization of macOS eim executables - # && github.ref == 'refs/heads/master' - if: startsWith(matrix.os, 'macos') - env: - NOTARIZATION_USERNAME: ${{ secrets.NOTARIZATION_USERNAME }} - NOTARIZATION_PASSWORD: ${{ secrets.NOTARIZATION_PASSWORD }} - NOTARIZATION_TEAM_ID: ${{ secrets.NOTARIZATION_TEAM_ID }} - run: | - echo "Create notary keychain" - /usr/bin/security create-keychain -p espressif notary.keychain - /usr/bin/security default-keychain -s notary.keychain - /usr/bin/security unlock-keychain -p espressif notary.keychain - - echo "Create keychain profile" - xcrun notarytool store-credentials "eim-notarytool-profile" --apple-id $NOTARIZATION_USERNAME --team-id $NOTARIZATION_TEAM_ID --password $NOTARIZATION_PASSWORD - xcrun notarytool submit release/${{ matrix.package_name }}/eim.zip --keychain-profile "eim-notarytool-profile" --wait - - echo "Unzipping the executable" - unzip -o release/${{ matrix.package_name }}/eim.zip -d release/${{ matrix.package_name }} - - # echo "Attach staple for eim executable" - # xcrun stapler staple release/${{ matrix.package_name }}/eim - - - name: Zip artifacts (Windows) - if: matrix.os == 'windows-latest' - run: | - cd release/${{ matrix.package_name }} - 7z a -tzip eim.zip eim.exe - - - name: Zip artifacts (POSIX) - if: matrix.os != 'windows-latest' - run: | - cd release/${{ matrix.package_name }} - zip -r eim.zip eim - - - name: Upload build artifacts - uses: actions/upload-artifact@v4 - with: - name: eim-${{ github.run_id }}-${{ matrix.package_name }} - path: release/${{ matrix.package_name }}/eim.zip - - - name: Upload artifact for tag - if: startsWith(github.ref, 'refs/tags/') - uses: actions/upload-artifact@v4 - with: - name: eim-${{ github.ref_name }}-${{ matrix.package_name }} - path: release/${{ matrix.package_name }}/eim.zip - - - name: Upload Release Asset - if: github.event_name == 'release' && github.event.action == 'created' - uses: actions/upload-release-asset@v1 - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - with: - upload_url: ${{ github.event.release.upload_url }} - asset_path: release/${{ matrix.package_name }}/eim.zip - asset_name: eim-${{ github.ref_name }}-${{ matrix.package_name }}.zip - asset_content_type: application/zip - - - name: Create aarch64-linux build - if: matrix.os == 'ubuntu-latest' - run: | - rustup target add aarch64-unknown-linux-gnu - cargo install cross - cross build --target aarch64-unknown-linux-gnu --release - mkdir -p release/aarch64-unknown-linux-gnu - cp target/aarch64-unknown-linux-gnu/release/eim release/aarch64-unknown-linux-gnu/eim - chmod +x release/aarch64-unknown-linux-gnu/eim - cd release/aarch64-unknown-linux-gnu - zip -r eim.zip eim - - - name: Upload build artifacts for aarch64-linux - uses: actions/upload-artifact@v4 - if: matrix.os == 'ubuntu-latest' - with: - name: eim-${{ github.run_id }}-linux-arm64 - path: release/aarch64-unknown-linux-gnu/eim.zip - - - name: Upload artifact for tag on aarch64-linux - if: startsWith(github.ref, 'refs/tags/') && runner.os == 'Linux' - uses: actions/upload-artifact@v4 - with: - name: eim-${{ github.ref_name }}-linux-arm64 - path: release/aarch64-unknown-linux-gnu/eim.zip - - - name: Upload Release Asset on aarch64-linux - if: github.event_name == 'release' && github.event.action == 'created' && runner.os == 'Linux' - uses: actions/upload-release-asset@v1 - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - with: - upload_url: ${{ github.event.release.upload_url }} - asset_path: release/aarch64-unknown-linux-gnu/eim.zip - asset_name: eim-${{ github.ref_name }}-linux-arm64.zip - asset_content_type: application/zip - - call-test-workflow: - needs: build - uses: ./.github/workflows/test.yml + build: + name: Build for multiple platforms + runs-on: ${{ matrix.os }} + strategy: + matrix: + include: + - os: ubuntu-latest + package_name: linux-x64 + - os: windows-latest + package_name: windows-x64 + - os: macos-latest + package_name: macos-aarch64 + - os: macos-13 + package_name: macos-x64 + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Set up Rust + uses: actions-rs/toolchain@v1 with: - run_id: ${{ github.run_id }} - ref: ${{ github.event.pull_request.head.ref }} + toolchain: stable + override: true + + - name: Install OpenSSL (Windows) + if: runner.os == 'Windows' + shell: powershell + run: | + echo "VCPKG_ROOT=$env:VCPKG_INSTALLATION_ROOT" | Out-File -FilePath $env:GITHUB_ENV -Append + vcpkg install openssl:x64-windows-static-md + + - name: Install OpenSSL (Macos) + if: matrix.os == 'macos-latest' + run: brew install openssl + + - name: Cache cargo registry + uses: actions/cache@v4 + with: + path: ~/.cargo/registry + key: ${{ runner.os }}-cargo-registry + restore-keys: | + ${{ runner.os }}-cargo-registry + + - name: Cache cargo index + uses: actions/cache@v4 + with: + path: ~/.cargo/git + key: ${{ runner.os }}-cargo-index + restore-keys: | + ${{ runner.os }}-cargo-index + + - name: Build + run: cargo build --release + + # - name: Run tests + # run: cargo test --release + + - name: Create release directory + run: mkdir -p release + + - name: Create release system directory + run: mkdir -p release/${{ matrix.package_name }} + + - name: Copy binary to release directory Windows + if: matrix.os == 'windows-latest' + run: cp target/release/eim.exe release/${{ matrix.package_name }}/eim.exe + + - name: Copy binary to release directory POSIX + if: matrix.os != 'windows-latest' + run: | + cp target/release/eim release/${{ matrix.package_name }}/eim + chmod +x release/${{ matrix.package_name }}/eim + + - name: Codesign macOS eim executables + if: startsWith(matrix.os, 'macos') + env: + MACOS_CERTIFICATE: ${{ secrets.MACOS_CERTIFICATE }} + MACOS_CERTIFICATE_PWD: ${{ secrets.MACOS_CERTIFICATE_PWD }} + run: | + echo $MACOS_CERTIFICATE | base64 --decode > certificate.p12 + /usr/bin/security create-keychain -p espressif build.keychain + /usr/bin/security default-keychain -s build.keychain + /usr/bin/security unlock-keychain -p espressif build.keychain + /usr/bin/security import certificate.p12 -k build.keychain -P $MACOS_CERTIFICATE_PWD -T /usr/bin/codesign + /usr/bin/security set-key-partition-list -S apple-tool:,apple:,codesign: -s -k espressif build.keychain + + /usr/bin/codesign --entitlements eim.entitlement --options runtime --force -s "ESPRESSIF SYSTEMS (SHANGHAI) CO., LTD. (QWXF6GB4AV)" release/${{ matrix.package_name }}/eim -v + /usr/bin/codesign -v -vvv --deep release/${{ matrix.package_name }}/eim + + - name: Zip eim executable for notarization + if: startsWith(matrix.os, 'macos') + run: | + cd release/${{ matrix.package_name }} + zip -r eim.zip eim + + - name: Notarization of macOS eim executables + # && github.ref == 'refs/heads/master' + if: startsWith(matrix.os, 'macos') + env: + NOTARIZATION_USERNAME: ${{ secrets.NOTARIZATION_USERNAME }} + NOTARIZATION_PASSWORD: ${{ secrets.NOTARIZATION_PASSWORD }} + NOTARIZATION_TEAM_ID: ${{ secrets.NOTARIZATION_TEAM_ID }} + run: | + echo "Create notary keychain" + /usr/bin/security create-keychain -p espressif notary.keychain + /usr/bin/security default-keychain -s notary.keychain + /usr/bin/security unlock-keychain -p espressif notary.keychain + + echo "Create keychain profile" + xcrun notarytool store-credentials "eim-notarytool-profile" --apple-id $NOTARIZATION_USERNAME --team-id $NOTARIZATION_TEAM_ID --password $NOTARIZATION_PASSWORD + xcrun notarytool submit release/${{ matrix.package_name }}/eim.zip --keychain-profile "eim-notarytool-profile" --wait + + echo "Unzipping the executable" + unzip -o release/${{ matrix.package_name }}/eim.zip -d release/${{ matrix.package_name }} + + # echo "Attach staple for eim executable" + # xcrun stapler staple release/${{ matrix.package_name }}/eim + + - name: Zip artifacts (Windows) + if: matrix.os == 'windows-latest' + run: | + cd release/${{ matrix.package_name }} + 7z a -tzip eim.zip eim.exe + + - name: Zip artifacts (POSIX) + if: matrix.os != 'windows-latest' + run: | + cd release/${{ matrix.package_name }} + zip -r eim.zip eim + + - name: Upload build artifacts + uses: actions/upload-artifact@v4 + with: + name: eim-${{ github.run_id }}-${{ matrix.package_name }} + path: release/${{ matrix.package_name }}/eim.zip + + - name: Upload artifact for tag + if: startsWith(github.ref, 'refs/tags/') + uses: actions/upload-artifact@v4 + with: + name: eim-${{ github.ref_name }}-${{ matrix.package_name }} + path: release/${{ matrix.package_name }}/eim.zip + + - name: Upload Release Asset + if: github.event_name == 'release' && github.event.action == 'created' + uses: actions/upload-release-asset@v1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + upload_url: ${{ github.event.release.upload_url }} + asset_path: release/${{ matrix.package_name }}/eim.zip + asset_name: eim-${{ github.ref_name }}-${{ matrix.package_name }}.zip + asset_content_type: application/zip + + - name: Create aarch64-linux build + if: matrix.os == 'ubuntu-latest' + run: | + rustup target add aarch64-unknown-linux-gnu + cargo install cross + cross build --target aarch64-unknown-linux-gnu --release + mkdir -p release/aarch64-unknown-linux-gnu + cp target/aarch64-unknown-linux-gnu/release/eim release/aarch64-unknown-linux-gnu/eim + chmod +x release/aarch64-unknown-linux-gnu/eim + cd release/aarch64-unknown-linux-gnu + zip -r eim.zip eim + + - name: Upload build artifacts for aarch64-linux + uses: actions/upload-artifact@v4 + if: matrix.os == 'ubuntu-latest' + with: + name: eim-${{ github.run_id }}-linux-arm64 + path: release/aarch64-unknown-linux-gnu/eim.zip + + - name: Upload artifact for tag on aarch64-linux + if: startsWith(github.ref, 'refs/tags/') && runner.os == 'Linux' + uses: actions/upload-artifact@v4 + with: + name: eim-${{ github.ref_name }}-linux-arm64 + path: release/aarch64-unknown-linux-gnu/eim.zip + + - name: Upload Release Asset on aarch64-linux + if: github.event_name == 'release' && github.event.action == 'created' && runner.os == 'Linux' + uses: actions/upload-release-asset@v1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + upload_url: ${{ github.event.release.upload_url }} + asset_path: release/aarch64-unknown-linux-gnu/eim.zip + asset_name: eim-${{ github.ref_name }}-linux-arm64.zip + asset_content_type: application/zip + + call-test-workflow: + needs: build + uses: ./.github/workflows/test.yml + with: + run_id: ${{ github.run_id }} + ref: ${{ github.event.pull_request.head.ref }} diff --git a/tests/classes/CLITestRunner.class.js b/tests/classes/CLITestRunner.class.js index 22fe259..1d18ee7 100644 --- a/tests/classes/CLITestRunner.class.js +++ b/tests/classes/CLITestRunner.class.js @@ -3,178 +3,171 @@ import os from "os"; import logger from "./logger.class.js"; export class InteractiveCLITestRunner { - constructor() { - this.process = null; - this.output = ""; - this.exited = false; - this.exitCode = null; - this.error = null; - this.prompt = os.platform() !== "win32" ? "$" : ">"; - this.command = os.platform() !== "win32" ? "bash" : "powershell.exe"; - this.args = - os.platform() !== "win32" - ? [] - : ["-ExecutionPolicy", "Bypass", "-NoProfile"]; - } + constructor() { + this.process = null; + this.output = ""; + this.exited = false; + this.exitCode = null; + this.error = null; + this.prompt = os.platform() !== "win32" ? "$" : ">"; + this.command = os.platform() !== "win32" ? "bash" : "powershell.exe"; + this.args = + os.platform() !== "win32" + ? [] + : ["-ExecutionPolicy", "Bypass", "-NoProfile"]; + } - async runIDFTerminal(loadScript, timeout = 3000) { - try { - await this.start(); - const loadCommand = - os.platform() !== "win32" - ? `source ${loadScript}` - : `. "${loadScript}"`; - logger.debug(`Script load command sent to terminal ${loadCommand}`); - this.sendInput(`${loadCommand}\r`); - const startTime = Date.now(); - while (Date.now() - startTime < timeout) { - if ( - !this.exited && - !this.error && - this.output.includes("(python)") - ) { - return Promise.resolve(); - } - await new Promise((resolve) => setTimeout(resolve, 200)); - } - logger.info("Failed to terminate terminal process"); - return Promise.resolve(); - } catch { - logger.debug("Error loading IDF terminal"); - return Promise.resolve(); + async runIDFTerminal(loadScript, timeout = 3000) { + try { + await this.start(); + const loadCommand = + os.platform() !== "win32" + ? `source ${loadScript}` + : `. "${loadScript}"`; + logger.debug(`Script load command sent to terminal ${loadCommand}`); + this.sendInput(`${loadCommand}\r`); + const startTime = Date.now(); + while (Date.now() - startTime < timeout) { + if (!this.exited && !this.error && this.output.includes("(python)")) { + return Promise.resolve(); } + await new Promise((resolve) => setTimeout(resolve, 200)); + } + logger.info("Failed to terminate terminal process"); + return Promise.resolve(); + } catch { + logger.debug("Error loading IDF terminal"); + return Promise.resolve(); } + } - async start(command = this.command, fullArgs = this.args, timeout = 5000) { - logger.debug( - `Starting terminal emulator ${this.command} with args ${this.args}` - ); - this.process = pty.spawn(command, fullArgs, { - name: "eim-terminal", - cols: 80, - rows: 30, - cwd: process.cwd(), - env: process.env, - }); - this.exited = false; + async start(command = this.command, fullArgs = this.args, timeout = 5000) { + logger.debug( + `Starting terminal emulator ${this.command} with args ${this.args}` + ); + this.process = pty.spawn(command, fullArgs, { + name: "eim-terminal", + cols: 80, + rows: 30, + cwd: process.cwd(), + env: process.env, + }); + this.exited = false; - this.process.onData((data) => { - logger.debug(data); - this.output += data; - }); + this.process.onData((data) => { + logger.debug(data); + this.output += data; + }); - this.process.onExit(({ exitCode }) => { - this.exited = true; - this.exitCode = exitCode; - logger.debug(`Terminal exited with code:>>${exitCode}<<`); - }); + this.process.onExit(({ exitCode }) => { + this.exited = true; + this.exitCode = exitCode; + logger.debug(`Terminal exited with code:>>${exitCode}<<`); + }); - this.process.on("error", (error) => { - this.error = error; - this.exited = true; - logger.debug(`Terminal error:>>${error}<<`); - }); + this.process.on("error", (error) => { + this.error = error; + this.exited = true; + logger.debug(`Terminal error:>>${error}<<`); + }); - await new Promise((resolve) => { - setTimeout(resolve, 2000); - }); + await new Promise((resolve) => { + setTimeout(resolve, 2000); + }); - // Wait until prompt is ready - if (!this.exited && !this.error) { - try { - await this.waitForPrompt(); - return Promise.resolve(); - } catch (error) { - logger.info(`Error detecting prompt >>${this.output}<<< `); - return Promise.reject(error); - } - } else { - return Promise.reject(`Could not start terminal`); - } + // Wait until prompt is ready + if (!this.exited && !this.error) { + try { + await this.waitForPrompt(); + return Promise.resolve(); + } catch (error) { + logger.info(`Error detecting prompt >>${this.output}<<< `); + return Promise.reject(error); + } + } else { + return Promise.reject(`Could not start terminal`); } + } - sendInput(input) { - logger.debug( - `Attempting to send ${input.replace(/\r$/, "")} to terminal` - ); - if (this.process && !this.exited) { - try { - this.process.write(input); - } catch (error) { - logger.info(`Error sending input:>>${error}<<`); - this.error = error; - this.exited = true; - } - } else { - logger.info("Attempted to send input, but process is not running"); - } + sendInput(input) { + logger.debug(`Attempting to send ${input.replace(/\r$/, "")} to terminal`); + if (this.process && !this.exited) { + try { + this.process.write(input); + } catch (error) { + logger.info(`Error sending input:>>${error}<<`); + this.error = error; + this.exited = true; + } + } else { + logger.info("Attempted to send input, but process is not running"); } + } - async waitForOutput(expectedOutput, timeout = 10000) { - const startTime = Date.now(); - while (Date.now() - startTime < timeout) { - if (this.output.includes(expectedOutput)) { - return true; - } - if (this.exited) { - return false; - } - await new Promise((resolve) => setTimeout(resolve, 100)); - } + async waitForOutput(expectedOutput, timeout = 10000) { + const startTime = Date.now(); + while (Date.now() - startTime < timeout) { + if (this.output.includes(expectedOutput)) { + return true; + } + if (this.exited) { return false; + } + await new Promise((resolve) => setTimeout(resolve, 100)); } + return false; + } - async waitForPrompt(timeout = 3000) { - const startTime = Date.now(); - while (Date.now() - startTime < timeout) { - if (this.output.slice(-20).includes(this.prompt)) { - return Promise.resolve(); - } - await new Promise((resolve) => setTimeout(resolve, 200)); - } - return Promise.reject("Timeout without a prompt"); + async waitForPrompt(timeout = 3000) { + const startTime = Date.now(); + while (Date.now() - startTime < timeout) { + if (this.output.slice(-20).includes(this.prompt)) { + return Promise.resolve(); + } + await new Promise((resolve) => setTimeout(resolve, 200)); } + return Promise.reject("Timeout without a prompt"); + } - async stop(timeout = 3000) { - if (this.process && !this.exited) { - try { - this.sendInput("exit\r"); - const exitTime = Date.now(); - while (Date.now() - exitTime < timeout) { - if (this.exited) { - logger.info("terminal exited gracefully"); - return Promise.resolve(); - } - await new Promise((resolve) => setTimeout(resolve, 200)); - } - logger.info("Terminal didn't exit gracefully, repeat Attempt"); - this.sendInput("\x03"); - this.sendInput("\x03"); - this.sendInput("exit\r"); - const closeTime = Date.now(); - while (Date.now() - closeTime < timeout) { - if (this.exited) { - logger.info("terminal exited gracefully"); - return Promise.resolve(); - } - await new Promise((resolve) => setTimeout(resolve, 200)); - } - logger.info( - "Terminal didn't exit gracefully, abandoning task, should be terminated by node." - ); - throw new Error("Could not stop terminal gracefully"); - } catch (error) { - logger.info("Error stopping terminal:", error); - this.exited = true; - this.process = null; - throw error; - } - } else { - logger.debug("Terminal has already exited"); - this.process = null; - this.exited = true; - this.output = ""; + async stop(timeout = 3000) { + if (this.process && !this.exited) { + try { + this.sendInput("exit\r"); + const exitTime = Date.now(); + while (Date.now() - exitTime < timeout) { + if (this.exited) { + logger.info("terminal exited gracefully"); return Promise.resolve(); + } + await new Promise((resolve) => setTimeout(resolve, 200)); } + logger.info("Terminal didn't exit gracefully, repeat Attempt"); + this.sendInput("\x03"); + this.sendInput("\x03"); + this.sendInput("exit\r"); + const closeTime = Date.now(); + while (Date.now() - closeTime < timeout) { + if (this.exited) { + logger.info("terminal exited gracefully"); + return Promise.resolve(); + } + await new Promise((resolve) => setTimeout(resolve, 200)); + } + logger.info( + "Terminal didn't exit gracefully, abandoning task, should be terminated by node." + ); + throw new Error("Could not stop terminal gracefully"); + } catch (error) { + this.exited = true; + this.process = null; + throw error; + } + } else { + logger.debug("Terminal has already exited"); + this.process = null; + this.exited = true; + this.output = ""; + return Promise.resolve(); } + } } diff --git a/tests/script/installCustom.test.js b/tests/script/installCustom.test.js index 44aeecc..c61fa04 100644 --- a/tests/script/installCustom.test.js +++ b/tests/script/installCustom.test.js @@ -4,85 +4,81 @@ import { InteractiveCLITestRunner } from "../classes/CLITestRunner.class.js"; import logger from "../classes/logger.class.js"; export function runInstallCustom(pathToEim, args = []) { - describe("Run custom installation using given parameters", function () { - let testRunner = null; + describe("Run custom installation using given parameters", function () { + let testRunner = null; - before(async function () { - logger.debug( - `Installing custom IDF version with parameters ${args.join( - " " - )}` - ); - this.timeout(5000); - testRunner = new InteractiveCLITestRunner(); - try { - await testRunner.start(); - } catch { - logger.info("Error to start terminal"); - } - }); + before(async function () { + logger.debug( + `Installing custom IDF version with parameters ${args.join(" ")}` + ); + this.timeout(5000); + testRunner = new InteractiveCLITestRunner(); + try { + await testRunner.start(); + } catch { + logger.info("Error to start terminal"); + } + }); - afterEach(function () { - if (this.currentTest.state === "failed") { - logger.info( - `Terminal output on failure: >>\r ${testRunner.output}` - ); - } - }); + afterEach(function () { + if (this.currentTest.state === "failed") { + logger.info(`Terminal output on failure: >>\r ${testRunner.output}`); + } + }); - after(async function () { - logger.info("Custom installation routine completed"); - this.timeout(20000); - try { - await testRunner.stop(); - } catch (error) { - logger.info("Error to clean up terminal after test"); - throw error; - } - }); + after(async function () { + logger.info("Custom installation routine completed"); + this.timeout(20000); + try { + await testRunner.stop(); + } catch (error) { + logger.info("Error to clean up terminal after test"); + logger.info(` Error: ${error}`); + } + }); - /** Run installation with full parameters, no need to ask questions - * - * It is expected to have all requirements installed - * - */ + /** Run installation with full parameters, no need to ask questions + * + * It is expected to have all requirements installed + * + */ - it("Should install IDF using specified parameters", async function () { - logger.info(`Starting test - IDF custom installation`); - testRunner.sendInput(`${pathToEim} ${args.join(" ")}\r`); - const installationCompleted = await testRunner.waitForOutput( - "Do you want to save the installer configuration", - 1200000 - ); - expect( - installationCompleted, - "Failed to ask to save installation configuration - failure to install using full arguments on run time" - ).to.be.true; - expect( - testRunner.output, - "Error message during installation" - ).to.not.include("error"); - expect( - testRunner.output, - "Failed to download submodules, missing 'Finished fetching submodules'" - ).to.include("Finished fetching submodules"); + it("Should install IDF using specified parameters", async function () { + logger.info(`Starting test - IDF custom installation`); + testRunner.sendInput(`${pathToEim} ${args.join(" ")}\r`); + const installationCompleted = await testRunner.waitForOutput( + "Do you want to save the installer configuration", + 1200000 + ); + expect( + installationCompleted, + "Failed to ask to save installation configuration - failure to install using full arguments on run time" + ).to.be.true; + expect( + testRunner.output, + "Error message during installation" + ).to.not.include("error"); + expect( + testRunner.output, + "Failed to download submodules, missing 'Finished fetching submodules'" + ).to.include("Finished fetching submodules"); - logger.info("Installation completed"); - testRunner.output = ""; - testRunner.sendInput("n"); + logger.info("Installation completed"); + testRunner.output = ""; + testRunner.sendInput("n"); - const installationSuccessful = await testRunner.waitForOutput( - "Successfully installed IDF" - ); + const installationSuccessful = await testRunner.waitForOutput( + "Successfully installed IDF" + ); - expect( - installationSuccessful, - "Failed to complete installation, missing 'Successfully Installed IDF'" - ).to.be.true; - expect( - testRunner.output, - "Failed to complete installation, missing 'Now you can start using IDF tools'" - ).to.include("Now you can start using IDF tools"); - }); + expect( + installationSuccessful, + "Failed to complete installation, missing 'Successfully Installed IDF'" + ).to.be.true; + expect( + testRunner.output, + "Failed to complete installation, missing 'Now you can start using IDF tools'" + ).to.include("Now you can start using IDF tools"); }); + }); } From dc9f109fa1daae45df089d2d966b8719293c45e3 Mon Sep 17 00:00:00 2001 From: Fabricio-ESP Date: Thu, 5 Dec 2024 09:45:24 +0000 Subject: [PATCH 19/20] Fix version string expected results --- .github/workflows/test.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 1fc406c..fb7bc41 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -74,7 +74,7 @@ jobs: run: | export LOG_TO_FILE="true" chmod +x ./tests/run_pre_test.sh - . ./tests/run_pre_test.sh "../test-bin/eim" "idf-im-cli ${{ env.CLI_TAG }}" + . ./tests/run_pre_test.sh "../test-bin/eim" "eim ${{ env.CLI_TAG }}" - name: Install dependencies (Ubuntu) if: runner.os == 'Linux' @@ -91,14 +91,14 @@ jobs: run: | export LOG_TO_FILE="true" chmod +x ./tests/run_test.sh - . ./tests/run_test.sh "../test-bin/eim" "idf-im-cli ${{ env.CLI_TAG }}" + . ./tests/run_test.sh "../test-bin/eim" "eim ${{ env.CLI_TAG }}" - name: Run IDF installation from alternative mirrors in mainland China if: matrix.run_on == 'CNRunner' run: | export LOG_TO_FILE="true" chmod +x ./tests/run_cnrunner.sh - . ./tests/run_cnrunner.sh "../test-bin/eim" "idf-im-cli ${{ env.CLI_TAG }}" + . ./tests/run_cnrunner.sh "../test-bin/eim" "eim ${{ env.CLI_TAG }}" # ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ @@ -127,7 +127,7 @@ jobs: if: runner.os == 'Windows' run: | $env:LOG_TO_FILE="true" - .\tests\run_pre_test.ps1 "..\test-bin\eim.exe" "idf-im-cli ${{ env.CLI_TAG }}" + .\tests\run_pre_test.ps1 "..\test-bin\eim.exe" "eim ${{ env.CLI_TAG }}" - name: Install dependencies (Windows) if: runner.os == 'windows' @@ -138,7 +138,7 @@ jobs: if: runner.os == 'Windows' run: | $env:LOG_TO_FILE="true" - .\tests\run_test.ps1 "..\test-bin\eim.exe" "idf-im-cli ${{ env.CLI_TAG }}" + .\tests\run_test.ps1 "..\test-bin\eim.exe" "eim ${{ env.CLI_TAG }}" # ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ From 2a9f86688536cb85dbdacbed5ecb3da32f83f77e Mon Sep 17 00:00:00 2001 From: Fabricio-ESP Date: Thu, 5 Dec 2024 14:14:52 +0000 Subject: [PATCH 20/20] Fix build workflow --- .github/workflows/build_rust.yaml | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/.github/workflows/build_rust.yaml b/.github/workflows/build_rust.yaml index 84067c2..98ea05e 100644 --- a/.github/workflows/build_rust.yaml +++ b/.github/workflows/build_rust.yaml @@ -83,6 +83,18 @@ jobs: if: matrix.os == 'windows-latest' run: cp target/release/eim.exe release/${{ matrix.package_name }}/eim.exe + - name: Sign Windows Binary + if: matrix.platform == 'windows-latest' + env: + WINDOWS_PFX_FILE: ${{ secrets.WIN_CERTIFICATE }} + WINDOWS_PFX_PASSWORD: ${{ secrets.WIN_CERTIFICATE_PWD }} + WINDOWS_SIGN_TOOL_PATH: 'C:\Program Files (x86)\Windows Kits\10\bin\10.0.17763.0\x86\signtool.exe' + run: | + echo $env:WINDOWS_PFX_FILE | Out-File -FilePath cert.b64 -Encoding ASCII + certutil -decode cert.b64 cert.pfx + Remove-Item cert.b64 + & "$env:WINDOWS_SIGN_TOOL_PATH" sign /f cert.pfx /p $env:WINDOWS_PFX_PASSWORD /tr http://timestamp.digicert.com /td sha256 /fd sha256 release/${{ matrix.package_name }}/eim.exe + - name: Copy binary to release directory POSIX if: matrix.os != 'windows-latest' run: |