From 44981a26d8b29524ef6e95dfb0c06cbbb6551764 Mon Sep 17 00:00:00 2001 From: Matteo Pologruto Date: Fri, 30 Sep 2022 12:11:57 +0200 Subject: [PATCH 01/17] Migrate TestCompileWithLibrary from test_compile_part_4.py to compile_part_4_test.go --- .../compile/compile_part_4_test.go | 62 +++++++++++++++++++ test/test_compile_part_4.py | 28 --------- 2 files changed, 62 insertions(+), 28 deletions(-) create mode 100644 internal/integrationtest/compile/compile_part_4_test.go diff --git a/internal/integrationtest/compile/compile_part_4_test.go b/internal/integrationtest/compile/compile_part_4_test.go new file mode 100644 index 00000000000..82943b02f49 --- /dev/null +++ b/internal/integrationtest/compile/compile_part_4_test.go @@ -0,0 +1,62 @@ +// This file is part of arduino-cli. +// +// Copyright 2022 ARDUINO SA (http://www.arduino.cc/) +// +// This software is released under the GNU General Public License version 3, +// which covers the main part of arduino-cli. +// The terms of this license can be found at: +// https://www.gnu.org/licenses/gpl-3.0.en.html +// +// You can be released from the requirements of the above licenses by purchasing +// a commercial license. Buying such a license is mandatory if you want to +// modify or otherwise use the software for commercial activities involving the +// Arduino software without disclosing the source code of your own applications. +// To purchase a commercial license, send an email to license@arduino.cc. + +package compile_test + +import ( + "testing" + + "github.com/arduino/arduino-cli/internal/integrationtest" + "github.com/stretchr/testify/require" + "gopkg.in/src-d/go-git.v4" + "gopkg.in/src-d/go-git.v4/plumbing" +) + +func TestCompileWithLibrary(t *testing.T) { + env, cli := integrationtest.CreateArduinoCLIWithEnvironment(t) + defer env.CleanUp() + + _, _, err := cli.Run("update") + require.NoError(t, err) + + _, _, err = cli.Run("core", "install", "arduino:avr@1.8.3") + require.NoError(t, err) + + sketchName := "CompileSketchWithWiFi101Dependency" + sketchPath := cli.SketchbookDir().Join(sketchName) + fqbn := "arduino:avr:uno" + // Create new sketch and add library include + _, _, err = cli.Run("sketch", "new", sketchPath.String()) + require.NoError(t, err) + sketchFile := sketchPath.Join(sketchName + ".ino") + data, err := sketchFile.ReadFile() + require.NoError(t, err) + data = append([]byte("#include \n"), data...) + err = sketchFile.WriteFile(data) + require.NoError(t, err) + + // Manually installs a library + gitUrl := "https://github.com/arduino-libraries/WiFi101.git" + libPath := cli.SketchbookDir().Join("my-libraries", "WiFi101") + _, err = git.PlainClone(libPath.String(), false, &git.CloneOptions{ + URL: gitUrl, + ReferenceName: plumbing.NewTagReferenceName("0.16.1"), + }) + require.NoError(t, err) + + stdout, _, err := cli.Run("compile", "-b", fqbn, sketchPath.String(), "--library", libPath.String(), "-v") + require.NoError(t, err) + require.Contains(t, string(stdout), "WiFi101") +} diff --git a/test/test_compile_part_4.py b/test/test_compile_part_4.py index 2066811a1d1..13d65e8f234 100644 --- a/test/test_compile_part_4.py +++ b/test/test_compile_part_4.py @@ -50,34 +50,6 @@ def test_compile_manually_installed_platform_using_boards_local_txt(run_command, assert run_command(["compile", "--clean", "-b", fqbn, sketch_path]) -def test_compile_with_library(run_command, data_dir): - assert run_command(["update"]) - - assert run_command(["core", "install", "arduino:avr@1.8.3"]) - - sketch_name = "CompileSketchWithWiFi101Dependency" - sketch_path = Path(data_dir, sketch_name) - fqbn = "arduino:avr:uno" - # Create new sketch and add library include - assert run_command(["sketch", "new", sketch_path]) - sketch_file = sketch_path / f"{sketch_name}.ino" - lines = [] - with open(sketch_file, "r") as f: - lines = f.readlines() - lines = ["#include \n"] + lines - with open(sketch_file, "w") as f: - f.writelines(lines) - - # Manually installs a library - git_url = "https://github.com/arduino-libraries/WiFi101.git" - lib_path = Path(data_dir, "my-libraries", "WiFi101") - assert Repo.clone_from(git_url, lib_path, multi_options=["-b 0.16.1"]) - - res = run_command(["compile", "-b", fqbn, sketch_path, "--library", lib_path, "-v"]) - assert res.ok - assert "WiFi101" in res.stdout - - def test_compile_with_library_priority(run_command, data_dir): assert run_command(["update"]) From c6ea437687fc8b6baf68f88fdde91d2c281455d7 Mon Sep 17 00:00:00 2001 From: Matteo Pologruto Date: Fri, 30 Sep 2022 12:35:40 +0200 Subject: [PATCH 02/17] Migrate TestCompileWithLibraryPriority from test_compile_part_4.py to compile_part_4_test.go --- .../compile/compile_part_4_test.go | 52 +++++++++++++++++++ test/test_compile_part_4.py | 38 -------------- 2 files changed, 52 insertions(+), 38 deletions(-) diff --git a/internal/integrationtest/compile/compile_part_4_test.go b/internal/integrationtest/compile/compile_part_4_test.go index 82943b02f49..30fed43a32d 100644 --- a/internal/integrationtest/compile/compile_part_4_test.go +++ b/internal/integrationtest/compile/compile_part_4_test.go @@ -60,3 +60,55 @@ func TestCompileWithLibrary(t *testing.T) { require.NoError(t, err) require.Contains(t, string(stdout), "WiFi101") } + +func TestCompileWithLibraryPriority(t *testing.T) { + env, cli := integrationtest.CreateArduinoCLIWithEnvironment(t) + defer env.CleanUp() + + _, _, err := cli.Run("update") + require.NoError(t, err) + + _, _, err = cli.Run("core", "install", "arduino:avr@1.8.3") + require.NoError(t, err) + + sketchName := "CompileSketchWithLibraryPriority" + sketchPath := cli.SketchbookDir().Join(sketchName) + fqbn := "arduino:avr:uno" + + // Manually installs a library + gitUrl := "https://github.com/arduino-libraries/WiFi101.git" + manuallyInstalledLibPath := cli.SketchbookDir().Join("my-libraries", "WiFi101") + _, err = git.PlainClone(manuallyInstalledLibPath.String(), false, &git.CloneOptions{ + URL: gitUrl, + ReferenceName: plumbing.NewTagReferenceName("0.16.1"), + }) + require.NoError(t, err) + + // Install the same library we installed manually + _, _, err = cli.Run("lib", "install", "WiFi101") + require.NoError(t, err) + + // Create new sketch and add library include + _, _, err = cli.Run("sketch", "new", sketchPath.String()) + require.NoError(t, err) + sketchFile := sketchPath.Join(sketchName + ".ino") + lines, err := sketchFile.ReadFileAsLines() + require.NoError(t, err) + lines = append([]string{"#include \n"}, lines...) + var data []byte + for _, l := range lines { + data = append(data, []byte(l)...) + } + err = sketchFile.WriteFile(data) + require.NoError(t, err) + + stdout, _, err := cli.Run("compile", "-b", fqbn, sketchPath.String(), "--library", manuallyInstalledLibPath.String(), "-v") + require.NoError(t, err) + cliInstalledLibPath := cli.SketchbookDir().Join("libraries", "WiFi101") + expectedOutput := [3]string{ + "Multiple libraries were found for \"WiFi101.h\"", + " Used: " + manuallyInstalledLibPath.String(), + " Not used: " + cliInstalledLibPath.String(), + } + require.Contains(t, string(stdout), expectedOutput[0]+"\n"+expectedOutput[1]+"\n"+expectedOutput[2]+"\n") +} diff --git a/test/test_compile_part_4.py b/test/test_compile_part_4.py index 13d65e8f234..41718a8a986 100644 --- a/test/test_compile_part_4.py +++ b/test/test_compile_part_4.py @@ -50,44 +50,6 @@ def test_compile_manually_installed_platform_using_boards_local_txt(run_command, assert run_command(["compile", "--clean", "-b", fqbn, sketch_path]) -def test_compile_with_library_priority(run_command, data_dir): - assert run_command(["update"]) - - assert run_command(["core", "install", "arduino:avr@1.8.3"]) - - sketch_name = "CompileSketchWithLibraryPriority" - sketch_path = Path(data_dir, sketch_name) - fqbn = "arduino:avr:uno" - - # Manually installs a library - git_url = "https://github.com/arduino-libraries/WiFi101.git" - manually_install_lib_path = Path(data_dir, "my-libraries", "WiFi101") - assert Repo.clone_from(git_url, manually_install_lib_path, multi_options=["-b 0.16.1"]) - - # Install the same library we installed manually - assert run_command(["lib", "install", "WiFi101"]) - - # Create new sketch and add library include - assert run_command(["sketch", "new", sketch_path]) - sketch_file = sketch_path / f"{sketch_name}.ino" - lines = [] - with open(sketch_file, "r") as f: - lines = f.readlines() - lines = ["#include "] + lines - with open(sketch_file, "w") as f: - f.writelines(lines) - - res = run_command(["compile", "-b", fqbn, sketch_path, "--library", manually_install_lib_path, "-v"]) - assert res.ok - cli_installed_lib_path = Path(data_dir, "libraries", "WiFi101") - expected_output = [ - 'Multiple libraries were found for "WiFi101.h"', - f" Used: {manually_install_lib_path}", - f" Not used: {cli_installed_lib_path}", - ] - assert "\n".join(expected_output) in res.stdout - - def test_recompile_with_different_library(run_command, data_dir): assert run_command(["update"]) From 560baa36a1120f4f9903fd901bf421165a75cc7c Mon Sep 17 00:00:00 2001 From: Matteo Pologruto Date: Fri, 30 Sep 2022 12:53:49 +0200 Subject: [PATCH 03/17] Migrate TestRecompileWithDifferentLibrary from test_compile_part_4.py to compile_part_4_test.go --- .../compile/compile_part_4_test.go | 62 +++++++++++++++++++ test/test_compile_part_4.py | 43 ------------- 2 files changed, 62 insertions(+), 43 deletions(-) diff --git a/internal/integrationtest/compile/compile_part_4_test.go b/internal/integrationtest/compile/compile_part_4_test.go index 30fed43a32d..07a8bceb87d 100644 --- a/internal/integrationtest/compile/compile_part_4_test.go +++ b/internal/integrationtest/compile/compile_part_4_test.go @@ -16,9 +16,13 @@ package compile_test import ( + "crypto/md5" + "encoding/hex" + "strings" "testing" "github.com/arduino/arduino-cli/internal/integrationtest" + "github.com/arduino/go-paths-helper" "github.com/stretchr/testify/require" "gopkg.in/src-d/go-git.v4" "gopkg.in/src-d/go-git.v4/plumbing" @@ -112,3 +116,61 @@ func TestCompileWithLibraryPriority(t *testing.T) { } require.Contains(t, string(stdout), expectedOutput[0]+"\n"+expectedOutput[1]+"\n"+expectedOutput[2]+"\n") } + +func TestRecompileWithDifferentLibrary(t *testing.T) { + env, cli := integrationtest.CreateArduinoCLIWithEnvironment(t) + defer env.CleanUp() + + _, _, err := cli.Run("update") + require.NoError(t, err) + + _, _, err = cli.Run("core", "install", "arduino:avr@1.8.3") + require.NoError(t, err) + + sketchName := "RecompileCompileSketchWithDifferentLibrary" + sketchPath := cli.SketchbookDir().Join(sketchName) + fqbn := "arduino:avr:uno" + + // Install library + _, _, err = cli.Run("lib", "install", "WiFi101") + require.NoError(t, err) + + // Manually installs a library + gitUrl := "https://github.com/arduino-libraries/WiFi101.git" + manuallyInstalledLibPath := cli.SketchbookDir().Join("my-libraries", "WiFi101") + _, err = git.PlainClone(manuallyInstalledLibPath.String(), false, &git.CloneOptions{ + URL: gitUrl, + ReferenceName: plumbing.NewTagReferenceName("0.16.1"), + }) + require.NoError(t, err) + + // Create new sketch and add library include + _, _, err = cli.Run("sketch", "new", sketchPath.String()) + require.NoError(t, err) + sketchFile := sketchPath.Join(sketchName + ".ino") + lines, err := sketchFile.ReadFileAsLines() + require.NoError(t, err) + lines = append([]string{"#include \n"}, lines...) + var data []byte + for _, l := range lines { + data = append(data, []byte(l)...) + } + err = sketchFile.WriteFile(data) + require.NoError(t, err) + + md5 := md5.Sum(([]byte(sketchPath.String()))) + sketchPathMd5 := strings.ToUpper(hex.EncodeToString(md5[:])) + require.NotEmpty(t, sketchPathMd5) + buildDir := paths.TempDir().Join("arduino-sketch-" + sketchPathMd5) + + // Compile sketch using library not managed by CLI + stdout, _, err := cli.Run("compile", "-b", fqbn, "--library", manuallyInstalledLibPath.String(), sketchPath.String(), "-v") + require.NoError(t, err) + objPath := buildDir.Join("libraries", "WiFi101", "WiFi.cpp.o") + require.NotContains(t, string(stdout), "Using previously compiled file: "+objPath.String()) + + // Compile again using library installed from CLI + stdout, _, err = cli.Run("compile", "-b", fqbn, sketchPath.String(), "-v") + require.NoError(t, err) + require.NotContains(t, string(stdout), "Using previously compiled file: "+objPath.String()) +} diff --git a/test/test_compile_part_4.py b/test/test_compile_part_4.py index 41718a8a986..d9e73071073 100644 --- a/test/test_compile_part_4.py +++ b/test/test_compile_part_4.py @@ -50,49 +50,6 @@ def test_compile_manually_installed_platform_using_boards_local_txt(run_command, assert run_command(["compile", "--clean", "-b", fqbn, sketch_path]) -def test_recompile_with_different_library(run_command, data_dir): - assert run_command(["update"]) - - assert run_command(["core", "install", "arduino:avr@1.8.3"]) - - sketch_name = "RecompileCompileSketchWithDifferentLibrary" - sketch_path = Path(data_dir, sketch_name) - fqbn = "arduino:avr:uno" - - # Install library - assert run_command(["lib", "install", "WiFi101"]) - - # Manually installs the same library already installed - git_url = "https://github.com/arduino-libraries/WiFi101.git" - manually_install_lib_path = Path(data_dir, "my-libraries", "WiFi101") - assert Repo.clone_from(git_url, manually_install_lib_path, multi_options=["-b 0.16.1"]) - - # Create new sketch and add library include - assert run_command(["sketch", "new", sketch_path]) - sketch_file = sketch_path / f"{sketch_name}.ino" - lines = [] - with open(sketch_file, "r") as f: - lines = f.readlines() - lines = ["#include "] + lines - with open(sketch_file, "w") as f: - f.writelines(lines) - - sketch_path_md5 = hashlib.md5(bytes(sketch_path)).hexdigest().upper() - build_dir = Path(tempfile.gettempdir(), f"arduino-sketch-{sketch_path_md5}") - - # Compile sketch using library not managed by CLI - res = run_command(["compile", "-b", fqbn, "--library", manually_install_lib_path, sketch_path, "-v"]) - assert res.ok - obj_path = build_dir / "libraries" / "WiFi101" / "WiFi.cpp.o" - assert f"Using previously compiled file: {obj_path}" not in res.stdout - - # Compile again using library installed from CLI - res = run_command(["compile", "-b", fqbn, sketch_path, "-v"]) - assert res.ok - obj_path = build_dir / "libraries" / "WiFi101" / "WiFi.cpp.o" - assert f"Using previously compiled file: {obj_path}" not in res.stdout - - def test_compile_with_conflicting_libraries_include(run_command, data_dir, copy_sketch): assert run_command(["update"]) From 266723eca4dc985b79143db1b4192e6d88b6e03b Mon Sep 17 00:00:00 2001 From: Matteo Pologruto Date: Fri, 30 Sep 2022 14:59:01 +0200 Subject: [PATCH 04/17] Migrate TestCompileWithConflictingLibrariesInclude from test_compile_part_4.py to compile_part_4_test.go --- .../compile/compile_part_4_test.go | 40 +++++++++++++++++++ ...tch_with_conflicting_libraries_include.ino | 0 test/test_compile_part_4.py | 27 ------------- 3 files changed, 40 insertions(+), 27 deletions(-) rename {test => internal/integrationtest}/testdata/sketch_with_conflicting_libraries_include/sketch_with_conflicting_libraries_include.ino (100%) diff --git a/internal/integrationtest/compile/compile_part_4_test.go b/internal/integrationtest/compile/compile_part_4_test.go index 07a8bceb87d..8f857935b12 100644 --- a/internal/integrationtest/compile/compile_part_4_test.go +++ b/internal/integrationtest/compile/compile_part_4_test.go @@ -174,3 +174,43 @@ func TestRecompileWithDifferentLibrary(t *testing.T) { require.NoError(t, err) require.NotContains(t, string(stdout), "Using previously compiled file: "+objPath.String()) } + +func TestCompileWithConflictingLibrariesInclude(t *testing.T) { + env, cli := integrationtest.CreateArduinoCLIWithEnvironment(t) + defer env.CleanUp() + + _, _, err := cli.Run("update") + require.NoError(t, err) + + _, _, err = cli.Run("core", "install", "arduino:avr@1.8.3") + require.NoError(t, err) + + // Installs conflicting libraries + gitUrl := "https://github.com/pstolarz/OneWireNg.git" + oneWireNgLibPath := cli.SketchbookDir().Join("libraries", "onewireng_0_8_1") + _, err = git.PlainClone(oneWireNgLibPath.String(), false, &git.CloneOptions{ + URL: gitUrl, + ReferenceName: plumbing.NewTagReferenceName("0.8.1"), + }) + require.NoError(t, err) + + gitUrl = "https://github.com/PaulStoffregen/OneWire.git" + oneWireLibPath := cli.SketchbookDir().Join("libraries", "onewire_2_3_5") + _, err = git.PlainClone(oneWireLibPath.String(), false, &git.CloneOptions{ + URL: gitUrl, + ReferenceName: plumbing.NewTagReferenceName("v2.3.5"), + }) + require.NoError(t, err) + + sketchPath := cli.CopySketch("sketch_with_conflicting_libraries_include") + fqbn := "arduino:avr:uno" + + stdout, _, err := cli.Run("compile", "-b", fqbn, sketchPath.String(), "--verbose") + require.NoError(t, err) + expectedOutput := [3]string{ + "Multiple libraries were found for \"OneWire.h\"", + " Used: " + oneWireLibPath.String(), + " Not used: " + oneWireNgLibPath.String(), + } + require.Contains(t, string(stdout), expectedOutput[0]+"\n"+expectedOutput[1]+"\n"+expectedOutput[2]+"\n") +} diff --git a/test/testdata/sketch_with_conflicting_libraries_include/sketch_with_conflicting_libraries_include.ino b/internal/integrationtest/testdata/sketch_with_conflicting_libraries_include/sketch_with_conflicting_libraries_include.ino similarity index 100% rename from test/testdata/sketch_with_conflicting_libraries_include/sketch_with_conflicting_libraries_include.ino rename to internal/integrationtest/testdata/sketch_with_conflicting_libraries_include/sketch_with_conflicting_libraries_include.ino diff --git a/test/test_compile_part_4.py b/test/test_compile_part_4.py index d9e73071073..c521efd10af 100644 --- a/test/test_compile_part_4.py +++ b/test/test_compile_part_4.py @@ -50,33 +50,6 @@ def test_compile_manually_installed_platform_using_boards_local_txt(run_command, assert run_command(["compile", "--clean", "-b", fqbn, sketch_path]) -def test_compile_with_conflicting_libraries_include(run_command, data_dir, copy_sketch): - assert run_command(["update"]) - - assert run_command(["core", "install", "arduino:avr@1.8.3"]) - - # Install conflicting libraries - git_url = "https://github.com/pstolarz/OneWireNg.git" - one_wire_ng_lib_path = Path(data_dir, "libraries", "onewireng_0_8_1") - assert Repo.clone_from(git_url, one_wire_ng_lib_path, multi_options=["-b 0.8.1"]) - - git_url = "https://github.com/PaulStoffregen/OneWire.git" - one_wire_lib_path = Path(data_dir, "libraries", "onewire_2_3_5") - assert Repo.clone_from(git_url, one_wire_lib_path, multi_options=["-b v2.3.5"]) - - sketch_path = copy_sketch("sketch_with_conflicting_libraries_include") - fqbn = "arduino:avr:uno" - - res = run_command(["compile", "-b", fqbn, sketch_path, "--verbose"]) - assert res.ok - expected_output = [ - 'Multiple libraries were found for "OneWire.h"', - f" Used: {one_wire_lib_path}", - f" Not used: {one_wire_ng_lib_path}", - ] - assert "\n".join(expected_output) in res.stdout - - def test_compile_with_invalid_build_options_json(run_command, data_dir): assert run_command(["update"]) From 28d10202030715d6b80eec364f602f1561d16b58 Mon Sep 17 00:00:00 2001 From: Matteo Pologruto Date: Fri, 30 Sep 2022 15:19:10 +0200 Subject: [PATCH 05/17] Migrate TestCompileWithInvalidBuildOptionJson from test_compile_part_4.py to compile_part_4_test.go --- .../compile/compile_part_4_test.go | 36 +++++++++++++++++++ test/test_compile_part_4.py | 26 -------------- 2 files changed, 36 insertions(+), 26 deletions(-) diff --git a/internal/integrationtest/compile/compile_part_4_test.go b/internal/integrationtest/compile/compile_part_4_test.go index 8f857935b12..9aad43ef967 100644 --- a/internal/integrationtest/compile/compile_part_4_test.go +++ b/internal/integrationtest/compile/compile_part_4_test.go @@ -214,3 +214,39 @@ func TestCompileWithConflictingLibrariesInclude(t *testing.T) { } require.Contains(t, string(stdout), expectedOutput[0]+"\n"+expectedOutput[1]+"\n"+expectedOutput[2]+"\n") } + +func TestCompileWithInvalidBuildOptionJson(t *testing.T) { + env, cli := integrationtest.CreateArduinoCLIWithEnvironment(t) + defer env.CleanUp() + + _, _, err := cli.Run("update") + require.NoError(t, err) + + _, _, err = cli.Run("core", "install", "arduino:avr@1.8.3") + require.NoError(t, err) + + sketchName := "CompileInvalidBuildOptionsJson" + sketchPath := cli.SketchbookDir().Join(sketchName) + fqbn := "arduino:avr:uno" + + // Create a test sketch + _, _, err = cli.Run("sketch", "new", sketchPath.String()) + require.NoError(t, err) + + // Get the build directory + md5 := md5.Sum(([]byte(sketchPath.String()))) + sketchPathMd5 := strings.ToUpper(hex.EncodeToString(md5[:])) + require.NotEmpty(t, sketchPathMd5) + buildDir := paths.TempDir().Join("arduino-sketch-" + sketchPathMd5) + + _, _, err = cli.Run("compile", "-b", fqbn, sketchPath.String(), "--verbose") + require.NoError(t, err) + + // Breaks the build.options.json file + buildOptionsJson := buildDir.Join("build.options.json") + err = buildOptionsJson.WriteFile([]byte("invalid json")) + require.NoError(t, err) + + _, _, err = cli.Run("compile", "-b", fqbn, sketchPath.String(), "--verbose") + require.NoError(t, err) +} diff --git a/test/test_compile_part_4.py b/test/test_compile_part_4.py index c521efd10af..646326a67cb 100644 --- a/test/test_compile_part_4.py +++ b/test/test_compile_part_4.py @@ -50,32 +50,6 @@ def test_compile_manually_installed_platform_using_boards_local_txt(run_command, assert run_command(["compile", "--clean", "-b", fqbn, sketch_path]) -def test_compile_with_invalid_build_options_json(run_command, data_dir): - assert run_command(["update"]) - - assert run_command(["core", "install", "arduino:avr@1.8.3"]) - - sketch_name = "CompileInvalidBuildOptionsJson" - sketch_path = Path(data_dir, sketch_name) - fqbn = "arduino:avr:uno" - - # Create a test sketch - assert run_command(["sketch", "new", sketch_path]) - - # Get the build directory - sketch_path_md5 = hashlib.md5(bytes(sketch_path)).hexdigest().upper() - build_dir = Path(tempfile.gettempdir(), f"arduino-sketch-{sketch_path_md5}") - - assert run_command(["compile", "-b", fqbn, sketch_path, "--verbose"]) - - # Breaks the build.options.json file - build_options_json = build_dir / "build.options.json" - with open(build_options_json, "w") as f: - f.write("invalid json") - - assert run_command(["compile", "-b", fqbn, sketch_path, "--verbose"]) - - def test_compile_with_esp32_bundled_libraries(run_command, data_dir, copy_sketch): # Some esp cores have have bundled libraries that are optimize for that architecture, # it might happen that if the user has a library with the same name installed conflicts From e072c98f00e645bdc2de7e62f1347a84a1b55158 Mon Sep 17 00:00:00 2001 From: Matteo Pologruto Date: Fri, 30 Sep 2022 15:50:45 +0200 Subject: [PATCH 06/17] Migrate TestCompileWithEsp32BundledLibraries from test_compile_part_4.py to compile_part_4_test.go --- .../compile/compile_part_4_test.go | 46 +++++++++++++++++++ .../sketch_with_sd_library.ino | 0 test/test_compile_part_4.py | 39 ---------------- 3 files changed, 46 insertions(+), 39 deletions(-) rename {test => internal/integrationtest}/testdata/sketch_with_sd_library/sketch_with_sd_library.ino (100%) diff --git a/internal/integrationtest/compile/compile_part_4_test.go b/internal/integrationtest/compile/compile_part_4_test.go index 9aad43ef967..b1c2983fdab 100644 --- a/internal/integrationtest/compile/compile_part_4_test.go +++ b/internal/integrationtest/compile/compile_part_4_test.go @@ -250,3 +250,49 @@ func TestCompileWithInvalidBuildOptionJson(t *testing.T) { _, _, err = cli.Run("compile", "-b", fqbn, sketchPath.String(), "--verbose") require.NoError(t, err) } + +func TestCompileWithEsp32BundledLibraries(t *testing.T) { + // Some esp cores have have bundled libraries that are optimize for that architecture, + // it might happen that if the user has a library with the same name installed conflicts + // can ensue and the wrong library is used for compilation, thus it fails. + // This happens because for "historical" reasons these platform have their "name" key + // in the "library.properties" flag suffixed with "(esp32)" or similar even though that + // doesn't respect the libraries specification. + // https://arduino.github.io/arduino-cli/latest/library-specification/#libraryproperties-file-format + // + // The reason those libraries have these suffixes is to avoid an annoying bug in the Java IDE + // that would have caused the libraries that are both bundled with the core and the Java IDE to be + // always marked as updatable. For more info see: https://github.com/arduino/Arduino/issues/4189 + env, cli := integrationtest.CreateArduinoCLIWithEnvironment(t) + defer env.CleanUp() + + _, _, err := cli.Run("update") + require.NoError(t, err) + + // Update index with esp32 core and install it + url := "https://raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package_esp32_index.json" + coreVersion := "1.0.6" + _, _, err = cli.Run("core", "update-index", "--additional-urls="+url) + require.NoError(t, err) + _, _, err = cli.Run("core", "install", "esp32:esp32@"+coreVersion, "--additional-urls="+url) + require.NoError(t, err) + + // Install a library with the same name as one bundled with the core + _, _, err = cli.Run("lib", "install", "SD") + require.NoError(t, err) + + sketchPath := cli.CopySketch("sketch_with_sd_library") + fqbn := "esp32:esp32:esp32" + + stdout, _, err := cli.Run("compile", "-b", fqbn, sketchPath.String(), "--verbose") + require.Error(t, err) + + coreBundledLibPath := cli.DataDir().Join("packages", "esp32", "hardware", "esp32", coreVersion, "libraries", "SD") + cliInstalledLibPath := cli.SketchbookDir().Join("libraries", "SD") + expectedOutput := [3]string{ + "Multiple libraries were found for \"OneWire.h\"", + " Used: " + coreBundledLibPath.String(), + " Not used: " + cliInstalledLibPath.String(), + } + require.NotContains(t, string(stdout), expectedOutput[0]+"\n"+expectedOutput[1]+"\n"+expectedOutput[2]+"\n") +} diff --git a/test/testdata/sketch_with_sd_library/sketch_with_sd_library.ino b/internal/integrationtest/testdata/sketch_with_sd_library/sketch_with_sd_library.ino similarity index 100% rename from test/testdata/sketch_with_sd_library/sketch_with_sd_library.ino rename to internal/integrationtest/testdata/sketch_with_sd_library/sketch_with_sd_library.ino diff --git a/test/test_compile_part_4.py b/test/test_compile_part_4.py index 646326a67cb..f8abd2ce03a 100644 --- a/test/test_compile_part_4.py +++ b/test/test_compile_part_4.py @@ -50,45 +50,6 @@ def test_compile_manually_installed_platform_using_boards_local_txt(run_command, assert run_command(["compile", "--clean", "-b", fqbn, sketch_path]) -def test_compile_with_esp32_bundled_libraries(run_command, data_dir, copy_sketch): - # Some esp cores have have bundled libraries that are optimize for that architecture, - # it might happen that if the user has a library with the same name installed conflicts - # can ensue and the wrong library is used for compilation, thus it fails. - # This happens because for "historical" reasons these platform have their "name" key - # in the "library.properties" flag suffixed with "(esp32)" or similar even though that - # doesn't respect the libraries specification. - # https://arduino.github.io/arduino-cli/latest/library-specification/#libraryproperties-file-format - # - # The reason those libraries have these suffixes is to avoid an annoying bug in the Java IDE - # that would have caused the libraries that are both bundled with the core and the Java IDE to be - # always marked as updatable. For more info see: https://github.com/arduino/Arduino/issues/4189 - assert run_command(["update"]) - - # Update index with esp32 core and install it - url = "https://raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package_esp32_index.json" - core_version = "1.0.6" - assert run_command(["core", "update-index", f"--additional-urls={url}"]) - assert run_command(["core", "install", f"esp32:esp32@{core_version}", f"--additional-urls={url}"]) - - # Install a library with the same name as one bundled with the core - assert run_command(["lib", "install", "SD"]) - - sketch_path = copy_sketch("sketch_with_sd_library") - fqbn = "esp32:esp32:esp32" - - res = run_command(["compile", "-b", fqbn, sketch_path, "--verbose"]) - assert res.failed - - core_bundled_lib_path = Path(data_dir, "packages", "esp32", "hardware", "esp32", core_version, "libraries", "SD") - cli_installed_lib_path = Path(data_dir, "libraries", "SD") - expected_output = [ - 'Multiple libraries were found for "SD.h"', - f" Used: {core_bundled_lib_path}", - f" Not used: {cli_installed_lib_path}", - ] - assert "\n".join(expected_output) not in res.stdout - - def test_compile_with_esp8266_bundled_libraries(run_command, data_dir, copy_sketch): # Some esp cores have have bundled libraries that are optimize for that architecture, # it might happen that if the user has a library with the same name installed conflicts From 9ca8a7be6e53f242d7d80e71333e69c54578682e Mon Sep 17 00:00:00 2001 From: Matteo Pologruto Date: Fri, 30 Sep 2022 15:57:25 +0200 Subject: [PATCH 07/17] Migrate TestCompileWithEsp8266BundledLibraries from test_compile_part_4.py to compile_part_4_test.go --- .../compile/compile_part_4_test.go | 46 +++++++++++++++++++ test/test_compile_part_4.py | 41 ----------------- 2 files changed, 46 insertions(+), 41 deletions(-) diff --git a/internal/integrationtest/compile/compile_part_4_test.go b/internal/integrationtest/compile/compile_part_4_test.go index b1c2983fdab..ea3cad49570 100644 --- a/internal/integrationtest/compile/compile_part_4_test.go +++ b/internal/integrationtest/compile/compile_part_4_test.go @@ -296,3 +296,49 @@ func TestCompileWithEsp32BundledLibraries(t *testing.T) { } require.NotContains(t, string(stdout), expectedOutput[0]+"\n"+expectedOutput[1]+"\n"+expectedOutput[2]+"\n") } + +func TestCompileWithEsp8266BundledLibraries(t *testing.T) { + // Some esp cores have have bundled libraries that are optimize for that architecture, + // it might happen that if the user has a library with the same name installed conflicts + // can ensue and the wrong library is used for compilation, thus it fails. + // This happens because for "historical" reasons these platform have their "name" key + // in the "library.properties" flag suffixed with "(esp32)" or similar even though that + // doesn't respect the libraries specification. + // https://arduino.github.io/arduino-cli/latest/library-specification/#libraryproperties-file-format + // + // The reason those libraries have these suffixes is to avoid an annoying bug in the Java IDE + // that would have caused the libraries that are both bundled with the core and the Java IDE to be + // always marked as updatable. For more info see: https://github.com/arduino/Arduino/issues/4189 + env, cli := integrationtest.CreateArduinoCLIWithEnvironment(t) + defer env.CleanUp() + + _, _, err := cli.Run("update") + require.NoError(t, err) + + // Update index with esp8266 core and install it + url := "http://arduino.esp8266.com/stable/package_esp8266com_index.json" + coreVersion := "2.7.4" + _, _, err = cli.Run("core", "update-index", "--additional-urls="+url) + require.NoError(t, err) + _, _, err = cli.Run("core", "install", "esp8266:esp8266@"+coreVersion, "--additional-urls="+url) + require.NoError(t, err) + + // Install a library with the same name as one bundled with the core + _, _, err = cli.Run("lib", "install", "SD") + require.NoError(t, err) + + sketchPath := cli.CopySketch("sketch_with_sd_library") + fqbn := "esp8266:esp8266:generic" + + stdout, _, err := cli.Run("compile", "-b", fqbn, sketchPath.String(), "--verbose") + require.Error(t, err) + + coreBundledLibPath := cli.DataDir().Join("packages", "esp8266", "hardware", "esp8266", coreVersion, "libraries", "SD") + cliInstalledLibPath := cli.SketchbookDir().Join("libraries", "SD") + expectedOutput := [3]string{ + "Multiple libraries were found for \"OneWire.h\"", + " Used: " + coreBundledLibPath.String(), + " Not used: " + cliInstalledLibPath.String(), + } + require.NotContains(t, string(stdout), expectedOutput[0]+"\n"+expectedOutput[1]+"\n"+expectedOutput[2]+"\n") +} diff --git a/test/test_compile_part_4.py b/test/test_compile_part_4.py index f8abd2ce03a..2c01c796335 100644 --- a/test/test_compile_part_4.py +++ b/test/test_compile_part_4.py @@ -50,47 +50,6 @@ def test_compile_manually_installed_platform_using_boards_local_txt(run_command, assert run_command(["compile", "--clean", "-b", fqbn, sketch_path]) -def test_compile_with_esp8266_bundled_libraries(run_command, data_dir, copy_sketch): - # Some esp cores have have bundled libraries that are optimize for that architecture, - # it might happen that if the user has a library with the same name installed conflicts - # can ensue and the wrong library is used for compilation, thus it fails. - # This happens because for "historical" reasons these platform have their "name" key - # in the "library.properties" flag suffixed with "(esp32)" or similar even though that - # doesn't respect the libraries specification. - # https://arduino.github.io/arduino-cli/latest/library-specification/#libraryproperties-file-format - # - # The reason those libraries have these suffixes is to avoid an annoying bug in the Java IDE - # that would have caused the libraries that are both bundled with the core and the Java IDE to be - # always marked as updatable. For more info see: https://github.com/arduino/Arduino/issues/4189 - assert run_command(["update"]) - - # Update index with esp8266 core and install it - url = "http://arduino.esp8266.com/stable/package_esp8266com_index.json" - core_version = "2.7.4" - assert run_command(["core", "update-index", f"--additional-urls={url}"]) - assert run_command(["core", "install", f"esp8266:esp8266@{core_version}", f"--additional-urls={url}"]) - - # Install a library with the same name as one bundled with the core - assert run_command(["lib", "install", "SD"]) - - sketch_path = copy_sketch("sketch_with_sd_library") - fqbn = "esp8266:esp8266:generic" - - res = run_command(["compile", "-b", fqbn, sketch_path, "--verbose"]) - assert res.failed - - core_bundled_lib_path = Path( - data_dir, "packages", "esp8266", "hardware", "esp8266", core_version, "libraries", "SD" - ) - cli_installed_lib_path = Path(data_dir, "libraries", "SD") - expected_output = [ - 'Multiple libraries were found for "SD.h"', - f" Used: {core_bundled_lib_path}", - f" Not used: {cli_installed_lib_path}", - ] - assert "\n".join(expected_output) not in res.stdout - - def test_generate_compile_commands_json_resilience(run_command, data_dir, copy_sketch): assert run_command(["update"]) From 116bfd91833d264154615e26a1bd59a8ab45b03f Mon Sep 17 00:00:00 2001 From: Matteo Pologruto Date: Fri, 30 Sep 2022 16:13:53 +0200 Subject: [PATCH 08/17] Migrate TestGenerateCompileCommandsJsonResilience from test_compile_part_4.py to compile_part_4_test.go --- .../compile/compile_part_4_test.go | 24 +++++++++++++++++++ .../sketch_with_missing_include.ino | 0 test/test_compile_part_4.py | 16 ------------- 3 files changed, 24 insertions(+), 16 deletions(-) rename {test => internal/integrationtest}/testdata/sketch_with_missing_include/sketch_with_missing_include.ino (100%) diff --git a/internal/integrationtest/compile/compile_part_4_test.go b/internal/integrationtest/compile/compile_part_4_test.go index ea3cad49570..ea735922570 100644 --- a/internal/integrationtest/compile/compile_part_4_test.go +++ b/internal/integrationtest/compile/compile_part_4_test.go @@ -342,3 +342,27 @@ func TestCompileWithEsp8266BundledLibraries(t *testing.T) { } require.NotContains(t, string(stdout), expectedOutput[0]+"\n"+expectedOutput[1]+"\n"+expectedOutput[2]+"\n") } + +func TestGenerateCompileCommandsJsonResilience(t *testing.T) { + env, cli := integrationtest.CreateArduinoCLIWithEnvironment(t) + defer env.CleanUp() + + _, _, err := cli.Run("update") + require.NoError(t, err) + + // check it didn't fail with esp32@2.0.1 that has a prebuild hook that must run: + // https://github.com/arduino/arduino-cli/issues/1547 + url := "https://raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package_esp32_index.json" + _, _, err = cli.Run("core", "update-index", "--additional-urls="+url) + require.NoError(t, err) + _, _, err = cli.Run("core", "install", "esp32:esp32@2.0.1", "--additional-urls="+url) + require.NoError(t, err) + sketchPath := cli.CopySketch("sketch_simple") + _, _, err = cli.Run("compile", "-b", "esp32:esp32:featheresp32", "--only-compilation-database", sketchPath.String()) + require.NoError(t, err) + + // check it didn't fail on a sketch with a missing include + sketchPath = cli.CopySketch("sketch_with_missing_include") + _, _, err = cli.Run("compile", "-b", "esp32:esp32:featheresp32", "--only-compilation-database", sketchPath.String()) + require.NoError(t, err) +} diff --git a/test/testdata/sketch_with_missing_include/sketch_with_missing_include.ino b/internal/integrationtest/testdata/sketch_with_missing_include/sketch_with_missing_include.ino similarity index 100% rename from test/testdata/sketch_with_missing_include/sketch_with_missing_include.ino rename to internal/integrationtest/testdata/sketch_with_missing_include/sketch_with_missing_include.ino diff --git a/test/test_compile_part_4.py b/test/test_compile_part_4.py index 2c01c796335..456474e9849 100644 --- a/test/test_compile_part_4.py +++ b/test/test_compile_part_4.py @@ -50,22 +50,6 @@ def test_compile_manually_installed_platform_using_boards_local_txt(run_command, assert run_command(["compile", "--clean", "-b", fqbn, sketch_path]) -def test_generate_compile_commands_json_resilience(run_command, data_dir, copy_sketch): - assert run_command(["update"]) - - # check it didn't fail with esp32@2.0.1 that has a prebuild hook that must run: - # https://github.com/arduino/arduino-cli/issues/1547 - url = "https://raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package_esp32_index.json" - assert run_command(["core", "update-index", f"--additional-urls={url}"]) - assert run_command(["core", "install", "esp32:esp32@2.0.1", f"--additional-urls={url}"]) - sketch_path = copy_sketch("sketch_simple") - assert run_command(["compile", "-b", "esp32:esp32:featheresp32", "--only-compilation-database", sketch_path]) - - # check it didn't fail on a sketch with a missing include - sketch_path = copy_sketch("sketch_with_missing_include") - assert run_command(["compile", "-b", "esp32:esp32:featheresp32", "--only-compilation-database", sketch_path]) - - def test_compile_sketch_with_tpp_file_include(run_command, copy_sketch): assert run_command(["update"]) From 53fb57163aa9c98073e8b85bde00626062b25e63 Mon Sep 17 00:00:00 2001 From: Matteo Pologruto Date: Fri, 30 Sep 2022 16:24:36 +0200 Subject: [PATCH 09/17] Migrate TestCompileSketchWithTppFileInclude from test_compile_part_4.py to compile_part_4_test.go --- .../compile/compile_part_4_test.go | 18 ++++++++++++++++++ .../sketch_with_tpp_file_include.ino | 0 .../sketch_with_tpp_file_include/template.tpp | 0 test/test_compile_part_4.py | 13 ------------- 4 files changed, 18 insertions(+), 13 deletions(-) rename {test => internal/integrationtest}/testdata/sketch_with_tpp_file_include/sketch_with_tpp_file_include.ino (100%) rename {test => internal/integrationtest}/testdata/sketch_with_tpp_file_include/template.tpp (100%) diff --git a/internal/integrationtest/compile/compile_part_4_test.go b/internal/integrationtest/compile/compile_part_4_test.go index ea735922570..29a219099f8 100644 --- a/internal/integrationtest/compile/compile_part_4_test.go +++ b/internal/integrationtest/compile/compile_part_4_test.go @@ -366,3 +366,21 @@ func TestGenerateCompileCommandsJsonResilience(t *testing.T) { _, _, err = cli.Run("compile", "-b", "esp32:esp32:featheresp32", "--only-compilation-database", sketchPath.String()) require.NoError(t, err) } + +func TestCompileSketchSketchWithTppFileInclude(t *testing.T) { + env, cli := integrationtest.CreateArduinoCLIWithEnvironment(t) + defer env.CleanUp() + + _, _, err := cli.Run("update") + require.NoError(t, err) + + // Download latest AVR + _, _, err = cli.Run("core", "install", "arduino:avr") + require.NoError(t, err) + + sketchPath := cli.CopySketch("sketch_with_tpp_file_include") + fqbn := "arduino:avr:uno" + + _, _, err = cli.Run("compile", "-b", fqbn, sketchPath.String(), "--verbose") + require.NoError(t, err) +} diff --git a/test/testdata/sketch_with_tpp_file_include/sketch_with_tpp_file_include.ino b/internal/integrationtest/testdata/sketch_with_tpp_file_include/sketch_with_tpp_file_include.ino similarity index 100% rename from test/testdata/sketch_with_tpp_file_include/sketch_with_tpp_file_include.ino rename to internal/integrationtest/testdata/sketch_with_tpp_file_include/sketch_with_tpp_file_include.ino diff --git a/test/testdata/sketch_with_tpp_file_include/template.tpp b/internal/integrationtest/testdata/sketch_with_tpp_file_include/template.tpp similarity index 100% rename from test/testdata/sketch_with_tpp_file_include/template.tpp rename to internal/integrationtest/testdata/sketch_with_tpp_file_include/template.tpp diff --git a/test/test_compile_part_4.py b/test/test_compile_part_4.py index 456474e9849..b55c8ab4860 100644 --- a/test/test_compile_part_4.py +++ b/test/test_compile_part_4.py @@ -50,19 +50,6 @@ def test_compile_manually_installed_platform_using_boards_local_txt(run_command, assert run_command(["compile", "--clean", "-b", fqbn, sketch_path]) -def test_compile_sketch_with_tpp_file_include(run_command, copy_sketch): - assert run_command(["update"]) - - # Download latest AVR - run_command(["core", "install", "arduino:avr"]) - - sketch_name = "sketch_with_tpp_file_include" - sketch_path = copy_sketch(sketch_name) - fqbn = "arduino:avr:uno" - - assert run_command(["compile", "-b", fqbn, sketch_path, "--verbose"]) - - def test_compile_sketch_with_ipp_file_include(run_command, copy_sketch): assert run_command(["update"]) From bfacc8019fbd44a1aa234b16c0d4d7106bf67360 Mon Sep 17 00:00:00 2001 From: Matteo Pologruto Date: Fri, 30 Sep 2022 16:27:36 +0200 Subject: [PATCH 10/17] Migrate TestCompileSketchWithIppFileInclude from test_compile_part_4.py to compile_part_4_test.go --- .../compile/compile_part_4_test.go | 18 ++++++++++++++++++ .../sketch_with_ipp_file_include.ino | 0 .../sketch_with_ipp_file_include/template.ipp | 0 test/test_compile_part_4.py | 13 ------------- 4 files changed, 18 insertions(+), 13 deletions(-) rename {test => internal/integrationtest}/testdata/sketch_with_ipp_file_include/sketch_with_ipp_file_include.ino (100%) rename {test => internal/integrationtest}/testdata/sketch_with_ipp_file_include/template.ipp (100%) diff --git a/internal/integrationtest/compile/compile_part_4_test.go b/internal/integrationtest/compile/compile_part_4_test.go index 29a219099f8..4c7398c21b4 100644 --- a/internal/integrationtest/compile/compile_part_4_test.go +++ b/internal/integrationtest/compile/compile_part_4_test.go @@ -384,3 +384,21 @@ func TestCompileSketchSketchWithTppFileInclude(t *testing.T) { _, _, err = cli.Run("compile", "-b", fqbn, sketchPath.String(), "--verbose") require.NoError(t, err) } + +func TestCompileSketchWithIppFileInclude(t *testing.T) { + env, cli := integrationtest.CreateArduinoCLIWithEnvironment(t) + defer env.CleanUp() + + _, _, err := cli.Run("update") + require.NoError(t, err) + + // Download latest AVR + _, _, err = cli.Run("core", "install", "arduino:avr") + require.NoError(t, err) + + sketchPath := cli.CopySketch("sketch_with_ipp_file_include") + fqbn := "arduino:avr:uno" + + _, _, err = cli.Run("compile", "-b", fqbn, sketchPath.String(), "--verbose") + require.NoError(t, err) +} diff --git a/test/testdata/sketch_with_ipp_file_include/sketch_with_ipp_file_include.ino b/internal/integrationtest/testdata/sketch_with_ipp_file_include/sketch_with_ipp_file_include.ino similarity index 100% rename from test/testdata/sketch_with_ipp_file_include/sketch_with_ipp_file_include.ino rename to internal/integrationtest/testdata/sketch_with_ipp_file_include/sketch_with_ipp_file_include.ino diff --git a/test/testdata/sketch_with_ipp_file_include/template.ipp b/internal/integrationtest/testdata/sketch_with_ipp_file_include/template.ipp similarity index 100% rename from test/testdata/sketch_with_ipp_file_include/template.ipp rename to internal/integrationtest/testdata/sketch_with_ipp_file_include/template.ipp diff --git a/test/test_compile_part_4.py b/test/test_compile_part_4.py index b55c8ab4860..89e769f78e0 100644 --- a/test/test_compile_part_4.py +++ b/test/test_compile_part_4.py @@ -50,19 +50,6 @@ def test_compile_manually_installed_platform_using_boards_local_txt(run_command, assert run_command(["compile", "--clean", "-b", fqbn, sketch_path]) -def test_compile_sketch_with_ipp_file_include(run_command, copy_sketch): - assert run_command(["update"]) - - # Download latest AVR - run_command(["core", "install", "arduino:avr"]) - - sketch_name = "sketch_with_ipp_file_include" - sketch_path = copy_sketch(sketch_name) - fqbn = "arduino:avr:uno" - - assert run_command(["compile", "-b", fqbn, sketch_path, "--verbose"]) - - def test_compile_with_relative_build_path(run_command, data_dir, copy_sketch): assert run_command(["update"]) From 34b9f78b4cdde06619473e354d000e0e5caf4e41 Mon Sep 17 00:00:00 2001 From: Matteo Pologruto Date: Fri, 30 Sep 2022 16:36:38 +0200 Subject: [PATCH 11/17] Migrate TestCompileWithoutUploadAndFqbn from test_compile_part_4.py to compile_part_4_test.go --- .../compile/compile_part_4_test.go | 17 +++++++++++++++++ test/test_compile_part_4.py | 13 ------------- 2 files changed, 17 insertions(+), 13 deletions(-) diff --git a/internal/integrationtest/compile/compile_part_4_test.go b/internal/integrationtest/compile/compile_part_4_test.go index 4c7398c21b4..b5c5588a770 100644 --- a/internal/integrationtest/compile/compile_part_4_test.go +++ b/internal/integrationtest/compile/compile_part_4_test.go @@ -402,3 +402,20 @@ func TestCompileSketchWithIppFileInclude(t *testing.T) { _, _, err = cli.Run("compile", "-b", fqbn, sketchPath.String(), "--verbose") require.NoError(t, err) } + +func TestCompileWithoutUploadAndFqbn(t *testing.T) { + env, cli := integrationtest.CreateArduinoCLIWithEnvironment(t) + defer env.CleanUp() + + _, _, err := cli.Run("update") + require.NoError(t, err) + + // Create a sketch + sketchPath := cli.SketchbookDir().Join("SketchSimple") + _, _, err = cli.Run("sketch", "new", sketchPath.String()) + require.NoError(t, err) + + _, stderr, err := cli.Run("compile", sketchPath.String()) + require.Error(t, err) + require.Contains(t, string(stderr), "Missing FQBN (Fully Qualified Board Name)") +} diff --git a/test/test_compile_part_4.py b/test/test_compile_part_4.py index 89e769f78e0..fe11dd6721e 100644 --- a/test/test_compile_part_4.py +++ b/test/test_compile_part_4.py @@ -83,19 +83,6 @@ def test_compile_with_relative_build_path(run_command, data_dir, copy_sketch): assert "sketch" in built_files -def test_compile_without_upload_and_fqbn(run_command, data_dir): - assert run_command(["update"]) - - # Create a sketch - sketch_name = "SketchSimple" - sketch_path = Path(data_dir, sketch_name) - assert run_command(["sketch", "new", sketch_path]) - - res = run_command(["compile", sketch_path]) - assert res.failed - assert "Missing FQBN (Fully Qualified Board Name)" in res.stderr - - def test_compile_non_installed_platform_with_wrong_packager_and_arch(run_command, data_dir): assert run_command(["update"]) From 2b2f491f68c789e73def6fb83dfb4b9c4c38fb98 Mon Sep 17 00:00:00 2001 From: Matteo Pologruto Date: Fri, 30 Sep 2022 16:42:55 +0200 Subject: [PATCH 12/17] Migrate TestCompileNonInstalledPlatformWithWrongPackagerAndArch from test_compile_part_4.py to compile_part_4_test.go --- .../compile/compile_part_4_test.go | 25 +++++++++++++++++++ test/test_compile_part_4.py | 21 ---------------- 2 files changed, 25 insertions(+), 21 deletions(-) diff --git a/internal/integrationtest/compile/compile_part_4_test.go b/internal/integrationtest/compile/compile_part_4_test.go index b5c5588a770..e5e9a6c9f78 100644 --- a/internal/integrationtest/compile/compile_part_4_test.go +++ b/internal/integrationtest/compile/compile_part_4_test.go @@ -419,3 +419,28 @@ func TestCompileWithoutUploadAndFqbn(t *testing.T) { require.Error(t, err) require.Contains(t, string(stderr), "Missing FQBN (Fully Qualified Board Name)") } + +func TestCompileNonInstalledPlatformWithWrongPackagerAndArch(t *testing.T) { + env, cli := integrationtest.CreateArduinoCLIWithEnvironment(t) + defer env.CleanUp() + + _, _, err := cli.Run("update") + require.NoError(t, err) + + // Create a sketch + sketchPath := cli.SketchbookDir().Join("SketchSimple") + _, _, err = cli.Run("sketch", "new", sketchPath.String()) + require.NoError(t, err) + + // Compile with wrong packager + _, stderr, err := cli.Run("compile", "-b", "wrong:avr:uno", sketchPath.String()) + require.Error(t, err) + require.Contains(t, string(stderr), "Error during build: Platform 'wrong:avr' not found: platform not installed") + require.Contains(t, string(stderr), "Platform wrong:avr is not found in any known index") + + // Compile with wrong arch + _, stderr, err = cli.Run("compile", "-b", "arduino:wrong:uno", sketchPath.String()) + require.Error(t, err) + require.Contains(t, string(stderr), "Error during build: Platform 'arduino:wrong' not found: platform not installed") + require.Contains(t, string(stderr), "Platform arduino:wrong is not found in any known index") +} diff --git a/test/test_compile_part_4.py b/test/test_compile_part_4.py index fe11dd6721e..a1e14cc8f86 100644 --- a/test/test_compile_part_4.py +++ b/test/test_compile_part_4.py @@ -83,27 +83,6 @@ def test_compile_with_relative_build_path(run_command, data_dir, copy_sketch): assert "sketch" in built_files -def test_compile_non_installed_platform_with_wrong_packager_and_arch(run_command, data_dir): - assert run_command(["update"]) - - # Create a sketch - sketch_name = "SketchSimple" - sketch_path = Path(data_dir, sketch_name) - assert run_command(["sketch", "new", sketch_path]) - - # Compile with wrong packager - res = run_command(["compile", "-b", "wrong:avr:uno", sketch_path]) - assert res.failed - assert "Error during build: Platform 'wrong:avr' not found: platform not installed" in res.stderr - assert "Platform wrong:avr is not found in any known index" in res.stderr - - # Compile with wrong arch - res = run_command(["compile", "-b", "arduino:wrong:uno", sketch_path]) - assert res.failed - assert "Error during build: Platform 'arduino:wrong' not found: platform not installed" in res.stderr - assert "Platform arduino:wrong is not found in any known index" in res.stderr - - def test_compile_with_known_platform_not_installed(run_command, data_dir): assert run_command(["update"]) From 79961f1da59bcbc99a3918a5058c37fdc1bf384f Mon Sep 17 00:00:00 2001 From: Matteo Pologruto Date: Fri, 30 Sep 2022 16:45:55 +0200 Subject: [PATCH 13/17] Migrate TestCompileWithKnownPlatformNotInstalled from test_compile_part_4.py to compile_part_4_test.go --- .../compile/compile_part_4_test.go | 20 +++++++++++++++++++ test/test_compile_part_4.py | 16 --------------- 2 files changed, 20 insertions(+), 16 deletions(-) diff --git a/internal/integrationtest/compile/compile_part_4_test.go b/internal/integrationtest/compile/compile_part_4_test.go index e5e9a6c9f78..b253e6907ac 100644 --- a/internal/integrationtest/compile/compile_part_4_test.go +++ b/internal/integrationtest/compile/compile_part_4_test.go @@ -444,3 +444,23 @@ func TestCompileNonInstalledPlatformWithWrongPackagerAndArch(t *testing.T) { require.Contains(t, string(stderr), "Error during build: Platform 'arduino:wrong' not found: platform not installed") require.Contains(t, string(stderr), "Platform arduino:wrong is not found in any known index") } + +func TestCompileWithKnownPlatformNotInstalled(t *testing.T) { + env, cli := integrationtest.CreateArduinoCLIWithEnvironment(t) + defer env.CleanUp() + + _, _, err := cli.Run("update") + require.NoError(t, err) + + // Create a sketch + sketchPath := cli.SketchbookDir().Join("SketchSimple") + _, _, err = cli.Run("sketch", "new", sketchPath.String()) + require.NoError(t, err) + + // Try to compile using a platform found in the index but not installed + _, stderr, err := cli.Run("compile", "-b", "arduino:avr:uno", sketchPath.String()) + require.Error(t, err) + require.Contains(t, string(stderr), "Error during build: Platform 'arduino:avr' not found: platform not installed") + // Verifies command to fix error is shown to user + require.Contains(t, string(stderr), "Try running `arduino-cli core install arduino:avr`") +} diff --git a/test/test_compile_part_4.py b/test/test_compile_part_4.py index a1e14cc8f86..dcebe39c3ad 100644 --- a/test/test_compile_part_4.py +++ b/test/test_compile_part_4.py @@ -83,22 +83,6 @@ def test_compile_with_relative_build_path(run_command, data_dir, copy_sketch): assert "sketch" in built_files -def test_compile_with_known_platform_not_installed(run_command, data_dir): - assert run_command(["update"]) - - # Create a sketch - sketch_name = "SketchSimple" - sketch_path = Path(data_dir, sketch_name) - assert run_command(["sketch", "new", sketch_path]) - - # Try to compile using a platform found in the index but not installed - res = run_command(["compile", "-b", "arduino:avr:uno", sketch_path]) - assert res.failed - assert "Error during build: Platform 'arduino:avr' not found: platform not installed" in res.stderr - # Verifies command to fix error is shown to user - assert "Try running `arduino-cli core install arduino:avr`" in res.stderr - - def test_compile_with_fake_secure_boot_core(run_command, data_dir): assert run_command(["update"]) From 0e32825cac6bf94da6d3a70aeb124080e97a67a7 Mon Sep 17 00:00:00 2001 From: Matteo Pologruto Date: Wed, 5 Oct 2022 15:27:14 +0200 Subject: [PATCH 14/17] Migrate TestCompileManuallyInstalledPlatformUsingBoardsLocalTxt from test_compile_part_4.py to compile_part_4_test.go --- .../compile/compile_part_4_test.go | 40 +++++++++++++++++++ test/test_compile_part_4.py | 30 -------------- 2 files changed, 40 insertions(+), 30 deletions(-) diff --git a/internal/integrationtest/compile/compile_part_4_test.go b/internal/integrationtest/compile/compile_part_4_test.go index b253e6907ac..bfa2564c74a 100644 --- a/internal/integrationtest/compile/compile_part_4_test.go +++ b/internal/integrationtest/compile/compile_part_4_test.go @@ -28,6 +28,46 @@ import ( "gopkg.in/src-d/go-git.v4/plumbing" ) +func TestCompileManuallyInstalledPlatformUsingBoardsLocalTxt(t *testing.T) { + env, cli := integrationtest.CreateArduinoCLIWithEnvironment(t) + defer env.CleanUp() + + _, _, err := cli.Run("update") + require.NoError(t, err) + + sketchName := "CompileSketchManuallyInstalledPlatformUsingBoardsLocalTxt" + sketchPath := cli.SketchbookDir().Join(sketchName) + fqbn := "arduino-beta-development:avr:nessuno" + _, _, err = cli.Run("sketch", "new", sketchPath.String()) + require.NoError(t, err) + + // Manually installs a core in sketchbooks hardware folder + gitUrl := "https://github.com/arduino/ArduinoCore-avr.git" + repoDir := cli.SketchbookDir().Join("hardware", "arduino-beta-development", "avr") + _, err = git.PlainClone(repoDir.String(), false, &git.CloneOptions{ + URL: gitUrl, + ReferenceName: plumbing.NewTagReferenceName("1.8.3"), + }) + require.NoError(t, err) + + // Installs also the same core via CLI so all the necessary tools are installed + _, _, err = cli.Run("core", "install", "arduino:avr@1.8.3") + require.NoError(t, err) + + // Verifies compilation fails because board doesn't exist + _, stderr, err := cli.Run("compile", "--clean", "-b", fqbn, sketchPath.String()) + require.Error(t, err) + require.Contains(t, string(stderr), "Error during build: Error resolving FQBN: board arduino-beta-development:avr:nessuno not found") + + // Use custom boards.local.txt with made arduino:avr:nessuno board + boardsLocalTxt := repoDir.Join("boards.local.txt") + err = paths.New("..", "testdata", "boards.local.txt").CopyTo(boardsLocalTxt) + require.NoError(t, err) + + _, _, err = cli.Run("compile", "--clean", "-b", fqbn, sketchPath.String()) + require.NoError(t, err) +} + func TestCompileWithLibrary(t *testing.T) { env, cli := integrationtest.CreateArduinoCLIWithEnvironment(t) defer env.CleanUp() diff --git a/test/test_compile_part_4.py b/test/test_compile_part_4.py index dcebe39c3ad..7f8c5ec8955 100644 --- a/test/test_compile_part_4.py +++ b/test/test_compile_part_4.py @@ -20,36 +20,6 @@ from pathlib import Path -def test_compile_manually_installed_platform_using_boards_local_txt(run_command, data_dir): - assert run_command(["update"]) - - sketch_name = "CompileSketchManuallyInstalledPlatformUsingBoardsLocalTxt" - sketch_path = Path(data_dir, sketch_name) - fqbn = "arduino-beta-development:avr:nessuno" - assert run_command(["sketch", "new", sketch_path]) - - # Manually installs a core in sketchbooks hardware folder - git_url = "https://github.com/arduino/ArduinoCore-avr.git" - repo_dir = Path(data_dir, "hardware", "arduino-beta-development", "avr") - assert Repo.clone_from(git_url, repo_dir, multi_options=["-b 1.8.3"]) - - # Installs also the same core via CLI so all the necessary tools are installed - assert run_command(["core", "install", "arduino:avr@1.8.3"]) - - # Verifies compilation fails because board doesn't exist - res = run_command(["compile", "--clean", "-b", fqbn, sketch_path]) - assert res.failed - assert ( - "Error during build: Error resolving FQBN: board arduino-beta-development:avr:nessuno not found" in res.stderr - ) - - # Use custom boards.local.txt with made arduino:avr:nessuno board - boards_local_txt = Path(repo_dir, "boards.local.txt") - shutil.copyfile(Path(__file__).parent / "testdata" / "boards.local.txt", boards_local_txt) - - assert run_command(["compile", "--clean", "-b", fqbn, sketch_path]) - - def test_compile_with_relative_build_path(run_command, data_dir, copy_sketch): assert run_command(["update"]) From 9cc05acd3b412c6904ca0bc20c16def23d81f5a9 Mon Sep 17 00:00:00 2001 From: Matteo Pologruto Date: Wed, 5 Oct 2022 16:23:12 +0200 Subject: [PATCH 15/17] Migrate TestCompileWithRelativeBuildPath from test_compile_part_4.py to compile_part_4_test.go --- .../compile/compile_part_4_test.go | 40 +++++++++++++++++++ test/test_compile_part_4.py | 33 --------------- 2 files changed, 40 insertions(+), 33 deletions(-) diff --git a/internal/integrationtest/compile/compile_part_4_test.go b/internal/integrationtest/compile/compile_part_4_test.go index bfa2564c74a..b000b89472f 100644 --- a/internal/integrationtest/compile/compile_part_4_test.go +++ b/internal/integrationtest/compile/compile_part_4_test.go @@ -443,6 +443,46 @@ func TestCompileSketchWithIppFileInclude(t *testing.T) { require.NoError(t, err) } +func TestCompileWithRelativeBuildPath(t *testing.T) { + env, cli := integrationtest.CreateArduinoCLIWithEnvironment(t) + defer env.CleanUp() + + _, _, err := cli.Run("update") + require.NoError(t, err) + + _, _, err = cli.Run("core", "install", "arduino:avr@1.8.3") + require.NoError(t, err) + + sketchName := "sketch_simple" + sketchPath := cli.CopySketch(sketchName) + fqbn := "arduino:avr:uno" + + buildPath := paths.New("..").Join("build_path") + workingDir := cli.SketchbookDir().Join("working_dir") + err = workingDir.Mkdir() + require.NoError(t, err) + cli.SetWorkingDir(workingDir) + _, _, err = cli.Run("compile", "-b", fqbn, "--build-path", buildPath.String(), sketchPath.String(), "-v") + require.NoError(t, err) + cli.SetWorkingDir(env.RootDir()) + + absoluteBuildPath := cli.SketchbookDir().Join("build_path") + builtFiles, err := absoluteBuildPath.ReadDir() + require.NoError(t, err) + require.Contains(t, builtFiles[8].String(), sketchName+".ino.eep") + require.Contains(t, builtFiles[9].String(), sketchName+".ino.elf") + require.Contains(t, builtFiles[10].String(), sketchName+".ino.hex") + require.Contains(t, builtFiles[11].String(), sketchName+".ino.with_bootloader.bin") + require.Contains(t, builtFiles[12].String(), sketchName+".ino.with_bootloader.hex") + require.Contains(t, builtFiles[0].String(), "build.options.json") + require.Contains(t, builtFiles[1].String(), "compile_commands.json") + require.Contains(t, builtFiles[2].String(), "core") + require.Contains(t, builtFiles[3].String(), "includes.cache") + require.Contains(t, builtFiles[4].String(), "libraries") + require.Contains(t, builtFiles[6].String(), "preproc") + require.Contains(t, builtFiles[7].String(), "sketch") +} + func TestCompileWithoutUploadAndFqbn(t *testing.T) { env, cli := integrationtest.CreateArduinoCLIWithEnvironment(t) defer env.CleanUp() diff --git a/test/test_compile_part_4.py b/test/test_compile_part_4.py index 7f8c5ec8955..9b03a72a37a 100644 --- a/test/test_compile_part_4.py +++ b/test/test_compile_part_4.py @@ -20,39 +20,6 @@ from pathlib import Path -def test_compile_with_relative_build_path(run_command, data_dir, copy_sketch): - assert run_command(["update"]) - - run_command(["core", "install", "arduino:avr@1.8.3"]) - - sketch_name = "sketch_simple" - sketch_path = copy_sketch(sketch_name) - fqbn = "arduino:avr:uno" - - build_path = Path("..", "build_path") - working_dir = Path(data_dir, "working_dir") - working_dir.mkdir() - assert run_command( - ["compile", "-b", fqbn, "--build-path", build_path, sketch_path, "-v"], - custom_working_dir=working_dir, - ) - - absolute_build_path = Path(data_dir, "build_path") - built_files = [f.name for f in absolute_build_path.glob("*")] - assert f"{sketch_name}.ino.eep" in built_files - assert f"{sketch_name}.ino.elf" in built_files - assert f"{sketch_name}.ino.hex" in built_files - assert f"{sketch_name}.ino.with_bootloader.bin" in built_files - assert f"{sketch_name}.ino.with_bootloader.hex" in built_files - assert "build.options.json" in built_files - assert "compile_commands.json" in built_files - assert "core" in built_files - assert "includes.cache" in built_files - assert "libraries" in built_files - assert "preproc" in built_files - assert "sketch" in built_files - - def test_compile_with_fake_secure_boot_core(run_command, data_dir): assert run_command(["update"]) From d145c30d8f013b4b542f34d8108959e61b68b7ed Mon Sep 17 00:00:00 2001 From: Matteo Pologruto Date: Thu, 6 Oct 2022 12:13:00 +0200 Subject: [PATCH 16/17] Migrate TestCompileWithFakeSecureBootCore to compile_part_4_test.go and delete test_compile_part_4.py --- .../compile/compile_part_4_test.go | 86 +++++++++++++++ .../boards.local.txt | 11 ++ .../platform.local.txt | 8 ++ test/test_compile_part_4.py | 104 ------------------ 4 files changed, 105 insertions(+), 104 deletions(-) create mode 100644 internal/integrationtest/testdata/platform_with_secure_boot/boards.local.txt create mode 100644 internal/integrationtest/testdata/platform_with_secure_boot/platform.local.txt delete mode 100644 test/test_compile_part_4.py diff --git a/internal/integrationtest/compile/compile_part_4_test.go b/internal/integrationtest/compile/compile_part_4_test.go index b000b89472f..aa197246a37 100644 --- a/internal/integrationtest/compile/compile_part_4_test.go +++ b/internal/integrationtest/compile/compile_part_4_test.go @@ -544,3 +544,89 @@ func TestCompileWithKnownPlatformNotInstalled(t *testing.T) { // Verifies command to fix error is shown to user require.Contains(t, string(stderr), "Try running `arduino-cli core install arduino:avr`") } + +func TestCompileWithFakeSecureBootCore(t *testing.T) { + env, cli := integrationtest.CreateArduinoCLIWithEnvironment(t) + defer env.CleanUp() + + _, _, err := cli.Run("update") + require.NoError(t, err) + + _, _, err = cli.Run("core", "install", "arduino:avr@1.8.3") + require.NoError(t, err) + + sketchName := "SketchSimple" + sketchPath := cli.SketchbookDir().Join(sketchName) + fqbn := "arduino:avr:uno" + + _, _, err = cli.Run("sketch", "new", sketchPath.String()) + require.NoError(t, err) + + // Verifies compilation works + _, _, err = cli.Run("compile", "--clean", "-b", fqbn, sketchPath.String()) + require.NoError(t, err) + + // Overrides default platform adding secure_boot support using platform.local.txt + avrPlatformPath := cli.DataDir().Join("packages", "arduino", "hardware", "avr", "1.8.3", "platform.local.txt") + testPlatformName := "platform_with_secure_boot" + err = paths.New("..", "testdata", testPlatformName, "platform.local.txt").CopyTo(avrPlatformPath) + require.NoError(t, err) + + // Overrides default board adding secure boot support using board.local.txt + avrBoardPath := cli.DataDir().Join("packages", "arduino", "hardware", "avr", "1.8.3", "boards.local.txt") + err = paths.New("..", "testdata", testPlatformName, "boards.local.txt").CopyTo(avrBoardPath) + require.NoError(t, err) + + // Verifies compilation works with secure boot disabled + stdout, _, err := cli.Run("compile", "--clean", "-b", fqbn+":security=none", sketchPath.String(), "-v") + require.NoError(t, err) + require.Contains(t, string(stdout), "echo exit") + + // Verifies compilation works with secure boot enabled + stdout, _, err = cli.Run("compile", "--clean", "-b", fqbn+":security=sien", sketchPath.String(), "-v") + require.NoError(t, err) + require.Contains(t, string(stdout), "Default_Keys/default-signing-key.pem") + require.Contains(t, string(stdout), "Default_Keys/default-encrypt-key.pem") + + // Verifies compilation does not work with secure boot enabled and using only one flag + _, stderr, err := cli.Run( + "compile", + "--clean", + "-b", + fqbn+":security=sien", + sketchPath.String(), + "--keys-keychain", + cli.SketchbookDir().String(), + "-v", + ) + require.Error(t, err) + require.Contains(t, string(stderr), "Flag --sign-key is mandatory when used in conjunction with flag --keys-keychain") + + // Verifies compilation works with secure boot enabled and when overriding the sign key and encryption key used + keysDir := cli.SketchbookDir().Join("keys_dir") + err = keysDir.Mkdir() + require.NoError(t, err) + signKeyPath := keysDir.Join("my-sign-key.pem") + err = signKeyPath.WriteFile([]byte{}) + require.NoError(t, err) + encryptKeyPath := cli.SketchbookDir().Join("my-encrypt-key.pem") + err = encryptKeyPath.WriteFile([]byte{}) + require.NoError(t, err) + stdout, _, err = cli.Run( + "compile", + "--clean", + "-b", + fqbn+":security=sien", + sketchPath.String(), + "--keys-keychain", + keysDir.String(), + "--sign-key", + "my-sign-key.pem", + "--encrypt-key", + "my-encrypt-key.pem", + "-v", + ) + require.NoError(t, err) + require.Contains(t, string(stdout), "my-sign-key.pem") + require.Contains(t, string(stdout), "my-encrypt-key.pem") +} diff --git a/internal/integrationtest/testdata/platform_with_secure_boot/boards.local.txt b/internal/integrationtest/testdata/platform_with_secure_boot/boards.local.txt new file mode 100644 index 00000000000..e1d30e681b6 --- /dev/null +++ b/internal/integrationtest/testdata/platform_with_secure_boot/boards.local.txt @@ -0,0 +1,11 @@ +menu.security=Security setting + +uno.menu.security.none=None +uno.menu.security.sien=Signature + Encryption + +uno.menu.security.sien.build.postbuild.cmd="{tools.imgtool.cmd}" {tools.imgtool.flags} +uno.menu.security.none.build.postbuild.cmd="{tools.imgtool.cmd}" exit + +uno.menu.security.sien.build.keys.keychain={runtime.hardware.path}/Default_Keys +uno.menu.security.sien.build.keys.sign_key=default-signing-key.pem +uno.menu.security.sien.build.keys.encrypt_key=default-encrypt-key.pem diff --git a/internal/integrationtest/testdata/platform_with_secure_boot/platform.local.txt b/internal/integrationtest/testdata/platform_with_secure_boot/platform.local.txt new file mode 100644 index 00000000000..320de131bf0 --- /dev/null +++ b/internal/integrationtest/testdata/platform_with_secure_boot/platform.local.txt @@ -0,0 +1,8 @@ +## Create output secure image (bin file) +recipe.hooks.objcopy.postobjcopy.1.pattern={build.postbuild.cmd} +# +# IMGTOOL +# + +tools.imgtool.cmd=echo +tools.imgtool.flags=sign --key "{build.keys.keychain}/{build.keys.sign_key}" --encrypt "{build.keys.keychain}/{build.keys.encrypt_key}" "{build.path}/{build.project_name}.bin" "{build.path}/{build.project_name}.bin" --align {build.alignment} --max-align {build.alignment} --version {build.version} --header-size {build.header_size} --pad-header --slot-size {build.slot_size} \ No newline at end of file diff --git a/test/test_compile_part_4.py b/test/test_compile_part_4.py deleted file mode 100644 index 9b03a72a37a..00000000000 --- a/test/test_compile_part_4.py +++ /dev/null @@ -1,104 +0,0 @@ -# This file is part of arduino-cli. -# -# Copyright 2020 ARDUINO SA (http://www.arduino.cc/) -# -# This software is released under the GNU General Public License version 3, -# which covers the main part of arduino-cli. -# The terms of this license can be found at: -# https://www.gnu.org/licenses/gpl-3.0.en.html -# -# You can be released from the requirements of the above licenses by purchasing -# a commercial license. Buying such a license is mandatory if you want to modify or -# otherwise use the software for commercial activities involving the Arduino -# software without disclosing the source code of your own applications. To purchase -# a commercial license, send an email to license@arduino.cc. - -import tempfile -import hashlib -import shutil -from git import Repo -from pathlib import Path - - -def test_compile_with_fake_secure_boot_core(run_command, data_dir): - assert run_command(["update"]) - - assert run_command(["core", "install", "arduino:avr@1.8.3"]) - - sketch_name = "SketchSimple" - sketch_path = Path(data_dir, sketch_name) - fqbn = "arduino:avr:uno" - - assert run_command(["sketch", "new", sketch_path]) - - # Verifies compilation works - assert run_command(["compile", "--clean", "-b", fqbn, sketch_path]) - - # Overrides default platform adding secure_boot support using platform.local.txt - avr_platform_path = Path(data_dir, "packages", "arduino", "hardware", "avr", "1.8.3", "platform.local.txt") - test_platform_name = "platform_with_secure_boot" - shutil.copyfile( - Path(__file__).parent / "testdata" / test_platform_name / "platform.local.txt", - avr_platform_path, - ) - - # Overrides default board adding secure boot support using board.local.txt - avr_board_path = Path(data_dir, "packages", "arduino", "hardware", "avr", "1.8.3", "boards.local.txt") - shutil.copyfile( - Path(__file__).parent / "testdata" / test_platform_name / "boards.local.txt", - avr_board_path, - ) - - # Verifies compilation works with secure boot disabled - res = run_command(["compile", "--clean", "-b", fqbn + ":security=none", sketch_path, "-v"]) - assert res.ok - assert "echo exit" in res.stdout - - # Verifies compilation works with secure boot enabled - res = run_command(["compile", "--clean", "-b", fqbn + ":security=sien", sketch_path, "-v"]) - assert res.ok - assert "Default_Keys/default-signing-key.pem" in res.stdout - assert "Default_Keys/default-encrypt-key.pem" in res.stdout - - # Verifies compilation does not work with secure boot enabled and using only one flag - res = run_command( - [ - "compile", - "--clean", - "-b", - fqbn + ":security=sien", - sketch_path, - "--keys-keychain", - data_dir, - "-v", - ] - ) - assert res.failed - assert "Flag --sign-key is mandatory when used in conjunction with flag --keys-keychain" in res.stderr - - # Verifies compilation works with secure boot enabled and when overriding the sign key and encryption key used - keys_dir = Path(data_dir, "keys_dir") - keys_dir.mkdir() - sign_key_path = Path(keys_dir, "my-sign-key.pem") - sign_key_path.touch() - encrypt_key_path = Path(keys_dir, "my-encrypt-key.pem") - encrypt_key_path.touch() - res = run_command( - [ - "compile", - "--clean", - "-b", - fqbn + ":security=sien", - sketch_path, - "--keys-keychain", - keys_dir, - "--sign-key", - "my-sign-key.pem", - "--encrypt-key", - "my-encrypt-key.pem", - "-v", - ] - ) - assert res.ok - assert "my-sign-key.pem" in res.stdout - assert "my-encrypt-key.pem" in res.stdout From 517a54e045c3bb4f6572fbebda74c83fa2e7c09c Mon Sep 17 00:00:00 2001 From: Matteo Pologruto Date: Fri, 14 Oct 2022 15:37:46 +0200 Subject: [PATCH 17/17] Rearrange compile tests to share the same environment --- .../compile/compile_part_4_test.go | 632 ------------------ .../integrationtest/compile/compile_test.go | 569 ++++++++++++++++ 2 files changed, 569 insertions(+), 632 deletions(-) delete mode 100644 internal/integrationtest/compile/compile_part_4_test.go diff --git a/internal/integrationtest/compile/compile_part_4_test.go b/internal/integrationtest/compile/compile_part_4_test.go deleted file mode 100644 index aa197246a37..00000000000 --- a/internal/integrationtest/compile/compile_part_4_test.go +++ /dev/null @@ -1,632 +0,0 @@ -// This file is part of arduino-cli. -// -// Copyright 2022 ARDUINO SA (http://www.arduino.cc/) -// -// This software is released under the GNU General Public License version 3, -// which covers the main part of arduino-cli. -// The terms of this license can be found at: -// https://www.gnu.org/licenses/gpl-3.0.en.html -// -// You can be released from the requirements of the above licenses by purchasing -// a commercial license. Buying such a license is mandatory if you want to -// modify or otherwise use the software for commercial activities involving the -// Arduino software without disclosing the source code of your own applications. -// To purchase a commercial license, send an email to license@arduino.cc. - -package compile_test - -import ( - "crypto/md5" - "encoding/hex" - "strings" - "testing" - - "github.com/arduino/arduino-cli/internal/integrationtest" - "github.com/arduino/go-paths-helper" - "github.com/stretchr/testify/require" - "gopkg.in/src-d/go-git.v4" - "gopkg.in/src-d/go-git.v4/plumbing" -) - -func TestCompileManuallyInstalledPlatformUsingBoardsLocalTxt(t *testing.T) { - env, cli := integrationtest.CreateArduinoCLIWithEnvironment(t) - defer env.CleanUp() - - _, _, err := cli.Run("update") - require.NoError(t, err) - - sketchName := "CompileSketchManuallyInstalledPlatformUsingBoardsLocalTxt" - sketchPath := cli.SketchbookDir().Join(sketchName) - fqbn := "arduino-beta-development:avr:nessuno" - _, _, err = cli.Run("sketch", "new", sketchPath.String()) - require.NoError(t, err) - - // Manually installs a core in sketchbooks hardware folder - gitUrl := "https://github.com/arduino/ArduinoCore-avr.git" - repoDir := cli.SketchbookDir().Join("hardware", "arduino-beta-development", "avr") - _, err = git.PlainClone(repoDir.String(), false, &git.CloneOptions{ - URL: gitUrl, - ReferenceName: plumbing.NewTagReferenceName("1.8.3"), - }) - require.NoError(t, err) - - // Installs also the same core via CLI so all the necessary tools are installed - _, _, err = cli.Run("core", "install", "arduino:avr@1.8.3") - require.NoError(t, err) - - // Verifies compilation fails because board doesn't exist - _, stderr, err := cli.Run("compile", "--clean", "-b", fqbn, sketchPath.String()) - require.Error(t, err) - require.Contains(t, string(stderr), "Error during build: Error resolving FQBN: board arduino-beta-development:avr:nessuno not found") - - // Use custom boards.local.txt with made arduino:avr:nessuno board - boardsLocalTxt := repoDir.Join("boards.local.txt") - err = paths.New("..", "testdata", "boards.local.txt").CopyTo(boardsLocalTxt) - require.NoError(t, err) - - _, _, err = cli.Run("compile", "--clean", "-b", fqbn, sketchPath.String()) - require.NoError(t, err) -} - -func TestCompileWithLibrary(t *testing.T) { - env, cli := integrationtest.CreateArduinoCLIWithEnvironment(t) - defer env.CleanUp() - - _, _, err := cli.Run("update") - require.NoError(t, err) - - _, _, err = cli.Run("core", "install", "arduino:avr@1.8.3") - require.NoError(t, err) - - sketchName := "CompileSketchWithWiFi101Dependency" - sketchPath := cli.SketchbookDir().Join(sketchName) - fqbn := "arduino:avr:uno" - // Create new sketch and add library include - _, _, err = cli.Run("sketch", "new", sketchPath.String()) - require.NoError(t, err) - sketchFile := sketchPath.Join(sketchName + ".ino") - data, err := sketchFile.ReadFile() - require.NoError(t, err) - data = append([]byte("#include \n"), data...) - err = sketchFile.WriteFile(data) - require.NoError(t, err) - - // Manually installs a library - gitUrl := "https://github.com/arduino-libraries/WiFi101.git" - libPath := cli.SketchbookDir().Join("my-libraries", "WiFi101") - _, err = git.PlainClone(libPath.String(), false, &git.CloneOptions{ - URL: gitUrl, - ReferenceName: plumbing.NewTagReferenceName("0.16.1"), - }) - require.NoError(t, err) - - stdout, _, err := cli.Run("compile", "-b", fqbn, sketchPath.String(), "--library", libPath.String(), "-v") - require.NoError(t, err) - require.Contains(t, string(stdout), "WiFi101") -} - -func TestCompileWithLibraryPriority(t *testing.T) { - env, cli := integrationtest.CreateArduinoCLIWithEnvironment(t) - defer env.CleanUp() - - _, _, err := cli.Run("update") - require.NoError(t, err) - - _, _, err = cli.Run("core", "install", "arduino:avr@1.8.3") - require.NoError(t, err) - - sketchName := "CompileSketchWithLibraryPriority" - sketchPath := cli.SketchbookDir().Join(sketchName) - fqbn := "arduino:avr:uno" - - // Manually installs a library - gitUrl := "https://github.com/arduino-libraries/WiFi101.git" - manuallyInstalledLibPath := cli.SketchbookDir().Join("my-libraries", "WiFi101") - _, err = git.PlainClone(manuallyInstalledLibPath.String(), false, &git.CloneOptions{ - URL: gitUrl, - ReferenceName: plumbing.NewTagReferenceName("0.16.1"), - }) - require.NoError(t, err) - - // Install the same library we installed manually - _, _, err = cli.Run("lib", "install", "WiFi101") - require.NoError(t, err) - - // Create new sketch and add library include - _, _, err = cli.Run("sketch", "new", sketchPath.String()) - require.NoError(t, err) - sketchFile := sketchPath.Join(sketchName + ".ino") - lines, err := sketchFile.ReadFileAsLines() - require.NoError(t, err) - lines = append([]string{"#include \n"}, lines...) - var data []byte - for _, l := range lines { - data = append(data, []byte(l)...) - } - err = sketchFile.WriteFile(data) - require.NoError(t, err) - - stdout, _, err := cli.Run("compile", "-b", fqbn, sketchPath.String(), "--library", manuallyInstalledLibPath.String(), "-v") - require.NoError(t, err) - cliInstalledLibPath := cli.SketchbookDir().Join("libraries", "WiFi101") - expectedOutput := [3]string{ - "Multiple libraries were found for \"WiFi101.h\"", - " Used: " + manuallyInstalledLibPath.String(), - " Not used: " + cliInstalledLibPath.String(), - } - require.Contains(t, string(stdout), expectedOutput[0]+"\n"+expectedOutput[1]+"\n"+expectedOutput[2]+"\n") -} - -func TestRecompileWithDifferentLibrary(t *testing.T) { - env, cli := integrationtest.CreateArduinoCLIWithEnvironment(t) - defer env.CleanUp() - - _, _, err := cli.Run("update") - require.NoError(t, err) - - _, _, err = cli.Run("core", "install", "arduino:avr@1.8.3") - require.NoError(t, err) - - sketchName := "RecompileCompileSketchWithDifferentLibrary" - sketchPath := cli.SketchbookDir().Join(sketchName) - fqbn := "arduino:avr:uno" - - // Install library - _, _, err = cli.Run("lib", "install", "WiFi101") - require.NoError(t, err) - - // Manually installs a library - gitUrl := "https://github.com/arduino-libraries/WiFi101.git" - manuallyInstalledLibPath := cli.SketchbookDir().Join("my-libraries", "WiFi101") - _, err = git.PlainClone(manuallyInstalledLibPath.String(), false, &git.CloneOptions{ - URL: gitUrl, - ReferenceName: plumbing.NewTagReferenceName("0.16.1"), - }) - require.NoError(t, err) - - // Create new sketch and add library include - _, _, err = cli.Run("sketch", "new", sketchPath.String()) - require.NoError(t, err) - sketchFile := sketchPath.Join(sketchName + ".ino") - lines, err := sketchFile.ReadFileAsLines() - require.NoError(t, err) - lines = append([]string{"#include \n"}, lines...) - var data []byte - for _, l := range lines { - data = append(data, []byte(l)...) - } - err = sketchFile.WriteFile(data) - require.NoError(t, err) - - md5 := md5.Sum(([]byte(sketchPath.String()))) - sketchPathMd5 := strings.ToUpper(hex.EncodeToString(md5[:])) - require.NotEmpty(t, sketchPathMd5) - buildDir := paths.TempDir().Join("arduino-sketch-" + sketchPathMd5) - - // Compile sketch using library not managed by CLI - stdout, _, err := cli.Run("compile", "-b", fqbn, "--library", manuallyInstalledLibPath.String(), sketchPath.String(), "-v") - require.NoError(t, err) - objPath := buildDir.Join("libraries", "WiFi101", "WiFi.cpp.o") - require.NotContains(t, string(stdout), "Using previously compiled file: "+objPath.String()) - - // Compile again using library installed from CLI - stdout, _, err = cli.Run("compile", "-b", fqbn, sketchPath.String(), "-v") - require.NoError(t, err) - require.NotContains(t, string(stdout), "Using previously compiled file: "+objPath.String()) -} - -func TestCompileWithConflictingLibrariesInclude(t *testing.T) { - env, cli := integrationtest.CreateArduinoCLIWithEnvironment(t) - defer env.CleanUp() - - _, _, err := cli.Run("update") - require.NoError(t, err) - - _, _, err = cli.Run("core", "install", "arduino:avr@1.8.3") - require.NoError(t, err) - - // Installs conflicting libraries - gitUrl := "https://github.com/pstolarz/OneWireNg.git" - oneWireNgLibPath := cli.SketchbookDir().Join("libraries", "onewireng_0_8_1") - _, err = git.PlainClone(oneWireNgLibPath.String(), false, &git.CloneOptions{ - URL: gitUrl, - ReferenceName: plumbing.NewTagReferenceName("0.8.1"), - }) - require.NoError(t, err) - - gitUrl = "https://github.com/PaulStoffregen/OneWire.git" - oneWireLibPath := cli.SketchbookDir().Join("libraries", "onewire_2_3_5") - _, err = git.PlainClone(oneWireLibPath.String(), false, &git.CloneOptions{ - URL: gitUrl, - ReferenceName: plumbing.NewTagReferenceName("v2.3.5"), - }) - require.NoError(t, err) - - sketchPath := cli.CopySketch("sketch_with_conflicting_libraries_include") - fqbn := "arduino:avr:uno" - - stdout, _, err := cli.Run("compile", "-b", fqbn, sketchPath.String(), "--verbose") - require.NoError(t, err) - expectedOutput := [3]string{ - "Multiple libraries were found for \"OneWire.h\"", - " Used: " + oneWireLibPath.String(), - " Not used: " + oneWireNgLibPath.String(), - } - require.Contains(t, string(stdout), expectedOutput[0]+"\n"+expectedOutput[1]+"\n"+expectedOutput[2]+"\n") -} - -func TestCompileWithInvalidBuildOptionJson(t *testing.T) { - env, cli := integrationtest.CreateArduinoCLIWithEnvironment(t) - defer env.CleanUp() - - _, _, err := cli.Run("update") - require.NoError(t, err) - - _, _, err = cli.Run("core", "install", "arduino:avr@1.8.3") - require.NoError(t, err) - - sketchName := "CompileInvalidBuildOptionsJson" - sketchPath := cli.SketchbookDir().Join(sketchName) - fqbn := "arduino:avr:uno" - - // Create a test sketch - _, _, err = cli.Run("sketch", "new", sketchPath.String()) - require.NoError(t, err) - - // Get the build directory - md5 := md5.Sum(([]byte(sketchPath.String()))) - sketchPathMd5 := strings.ToUpper(hex.EncodeToString(md5[:])) - require.NotEmpty(t, sketchPathMd5) - buildDir := paths.TempDir().Join("arduino-sketch-" + sketchPathMd5) - - _, _, err = cli.Run("compile", "-b", fqbn, sketchPath.String(), "--verbose") - require.NoError(t, err) - - // Breaks the build.options.json file - buildOptionsJson := buildDir.Join("build.options.json") - err = buildOptionsJson.WriteFile([]byte("invalid json")) - require.NoError(t, err) - - _, _, err = cli.Run("compile", "-b", fqbn, sketchPath.String(), "--verbose") - require.NoError(t, err) -} - -func TestCompileWithEsp32BundledLibraries(t *testing.T) { - // Some esp cores have have bundled libraries that are optimize for that architecture, - // it might happen that if the user has a library with the same name installed conflicts - // can ensue and the wrong library is used for compilation, thus it fails. - // This happens because for "historical" reasons these platform have their "name" key - // in the "library.properties" flag suffixed with "(esp32)" or similar even though that - // doesn't respect the libraries specification. - // https://arduino.github.io/arduino-cli/latest/library-specification/#libraryproperties-file-format - // - // The reason those libraries have these suffixes is to avoid an annoying bug in the Java IDE - // that would have caused the libraries that are both bundled with the core and the Java IDE to be - // always marked as updatable. For more info see: https://github.com/arduino/Arduino/issues/4189 - env, cli := integrationtest.CreateArduinoCLIWithEnvironment(t) - defer env.CleanUp() - - _, _, err := cli.Run("update") - require.NoError(t, err) - - // Update index with esp32 core and install it - url := "https://raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package_esp32_index.json" - coreVersion := "1.0.6" - _, _, err = cli.Run("core", "update-index", "--additional-urls="+url) - require.NoError(t, err) - _, _, err = cli.Run("core", "install", "esp32:esp32@"+coreVersion, "--additional-urls="+url) - require.NoError(t, err) - - // Install a library with the same name as one bundled with the core - _, _, err = cli.Run("lib", "install", "SD") - require.NoError(t, err) - - sketchPath := cli.CopySketch("sketch_with_sd_library") - fqbn := "esp32:esp32:esp32" - - stdout, _, err := cli.Run("compile", "-b", fqbn, sketchPath.String(), "--verbose") - require.Error(t, err) - - coreBundledLibPath := cli.DataDir().Join("packages", "esp32", "hardware", "esp32", coreVersion, "libraries", "SD") - cliInstalledLibPath := cli.SketchbookDir().Join("libraries", "SD") - expectedOutput := [3]string{ - "Multiple libraries were found for \"OneWire.h\"", - " Used: " + coreBundledLibPath.String(), - " Not used: " + cliInstalledLibPath.String(), - } - require.NotContains(t, string(stdout), expectedOutput[0]+"\n"+expectedOutput[1]+"\n"+expectedOutput[2]+"\n") -} - -func TestCompileWithEsp8266BundledLibraries(t *testing.T) { - // Some esp cores have have bundled libraries that are optimize for that architecture, - // it might happen that if the user has a library with the same name installed conflicts - // can ensue and the wrong library is used for compilation, thus it fails. - // This happens because for "historical" reasons these platform have their "name" key - // in the "library.properties" flag suffixed with "(esp32)" or similar even though that - // doesn't respect the libraries specification. - // https://arduino.github.io/arduino-cli/latest/library-specification/#libraryproperties-file-format - // - // The reason those libraries have these suffixes is to avoid an annoying bug in the Java IDE - // that would have caused the libraries that are both bundled with the core and the Java IDE to be - // always marked as updatable. For more info see: https://github.com/arduino/Arduino/issues/4189 - env, cli := integrationtest.CreateArduinoCLIWithEnvironment(t) - defer env.CleanUp() - - _, _, err := cli.Run("update") - require.NoError(t, err) - - // Update index with esp8266 core and install it - url := "http://arduino.esp8266.com/stable/package_esp8266com_index.json" - coreVersion := "2.7.4" - _, _, err = cli.Run("core", "update-index", "--additional-urls="+url) - require.NoError(t, err) - _, _, err = cli.Run("core", "install", "esp8266:esp8266@"+coreVersion, "--additional-urls="+url) - require.NoError(t, err) - - // Install a library with the same name as one bundled with the core - _, _, err = cli.Run("lib", "install", "SD") - require.NoError(t, err) - - sketchPath := cli.CopySketch("sketch_with_sd_library") - fqbn := "esp8266:esp8266:generic" - - stdout, _, err := cli.Run("compile", "-b", fqbn, sketchPath.String(), "--verbose") - require.Error(t, err) - - coreBundledLibPath := cli.DataDir().Join("packages", "esp8266", "hardware", "esp8266", coreVersion, "libraries", "SD") - cliInstalledLibPath := cli.SketchbookDir().Join("libraries", "SD") - expectedOutput := [3]string{ - "Multiple libraries were found for \"OneWire.h\"", - " Used: " + coreBundledLibPath.String(), - " Not used: " + cliInstalledLibPath.String(), - } - require.NotContains(t, string(stdout), expectedOutput[0]+"\n"+expectedOutput[1]+"\n"+expectedOutput[2]+"\n") -} - -func TestGenerateCompileCommandsJsonResilience(t *testing.T) { - env, cli := integrationtest.CreateArduinoCLIWithEnvironment(t) - defer env.CleanUp() - - _, _, err := cli.Run("update") - require.NoError(t, err) - - // check it didn't fail with esp32@2.0.1 that has a prebuild hook that must run: - // https://github.com/arduino/arduino-cli/issues/1547 - url := "https://raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package_esp32_index.json" - _, _, err = cli.Run("core", "update-index", "--additional-urls="+url) - require.NoError(t, err) - _, _, err = cli.Run("core", "install", "esp32:esp32@2.0.1", "--additional-urls="+url) - require.NoError(t, err) - sketchPath := cli.CopySketch("sketch_simple") - _, _, err = cli.Run("compile", "-b", "esp32:esp32:featheresp32", "--only-compilation-database", sketchPath.String()) - require.NoError(t, err) - - // check it didn't fail on a sketch with a missing include - sketchPath = cli.CopySketch("sketch_with_missing_include") - _, _, err = cli.Run("compile", "-b", "esp32:esp32:featheresp32", "--only-compilation-database", sketchPath.String()) - require.NoError(t, err) -} - -func TestCompileSketchSketchWithTppFileInclude(t *testing.T) { - env, cli := integrationtest.CreateArduinoCLIWithEnvironment(t) - defer env.CleanUp() - - _, _, err := cli.Run("update") - require.NoError(t, err) - - // Download latest AVR - _, _, err = cli.Run("core", "install", "arduino:avr") - require.NoError(t, err) - - sketchPath := cli.CopySketch("sketch_with_tpp_file_include") - fqbn := "arduino:avr:uno" - - _, _, err = cli.Run("compile", "-b", fqbn, sketchPath.String(), "--verbose") - require.NoError(t, err) -} - -func TestCompileSketchWithIppFileInclude(t *testing.T) { - env, cli := integrationtest.CreateArduinoCLIWithEnvironment(t) - defer env.CleanUp() - - _, _, err := cli.Run("update") - require.NoError(t, err) - - // Download latest AVR - _, _, err = cli.Run("core", "install", "arduino:avr") - require.NoError(t, err) - - sketchPath := cli.CopySketch("sketch_with_ipp_file_include") - fqbn := "arduino:avr:uno" - - _, _, err = cli.Run("compile", "-b", fqbn, sketchPath.String(), "--verbose") - require.NoError(t, err) -} - -func TestCompileWithRelativeBuildPath(t *testing.T) { - env, cli := integrationtest.CreateArduinoCLIWithEnvironment(t) - defer env.CleanUp() - - _, _, err := cli.Run("update") - require.NoError(t, err) - - _, _, err = cli.Run("core", "install", "arduino:avr@1.8.3") - require.NoError(t, err) - - sketchName := "sketch_simple" - sketchPath := cli.CopySketch(sketchName) - fqbn := "arduino:avr:uno" - - buildPath := paths.New("..").Join("build_path") - workingDir := cli.SketchbookDir().Join("working_dir") - err = workingDir.Mkdir() - require.NoError(t, err) - cli.SetWorkingDir(workingDir) - _, _, err = cli.Run("compile", "-b", fqbn, "--build-path", buildPath.String(), sketchPath.String(), "-v") - require.NoError(t, err) - cli.SetWorkingDir(env.RootDir()) - - absoluteBuildPath := cli.SketchbookDir().Join("build_path") - builtFiles, err := absoluteBuildPath.ReadDir() - require.NoError(t, err) - require.Contains(t, builtFiles[8].String(), sketchName+".ino.eep") - require.Contains(t, builtFiles[9].String(), sketchName+".ino.elf") - require.Contains(t, builtFiles[10].String(), sketchName+".ino.hex") - require.Contains(t, builtFiles[11].String(), sketchName+".ino.with_bootloader.bin") - require.Contains(t, builtFiles[12].String(), sketchName+".ino.with_bootloader.hex") - require.Contains(t, builtFiles[0].String(), "build.options.json") - require.Contains(t, builtFiles[1].String(), "compile_commands.json") - require.Contains(t, builtFiles[2].String(), "core") - require.Contains(t, builtFiles[3].String(), "includes.cache") - require.Contains(t, builtFiles[4].String(), "libraries") - require.Contains(t, builtFiles[6].String(), "preproc") - require.Contains(t, builtFiles[7].String(), "sketch") -} - -func TestCompileWithoutUploadAndFqbn(t *testing.T) { - env, cli := integrationtest.CreateArduinoCLIWithEnvironment(t) - defer env.CleanUp() - - _, _, err := cli.Run("update") - require.NoError(t, err) - - // Create a sketch - sketchPath := cli.SketchbookDir().Join("SketchSimple") - _, _, err = cli.Run("sketch", "new", sketchPath.String()) - require.NoError(t, err) - - _, stderr, err := cli.Run("compile", sketchPath.String()) - require.Error(t, err) - require.Contains(t, string(stderr), "Missing FQBN (Fully Qualified Board Name)") -} - -func TestCompileNonInstalledPlatformWithWrongPackagerAndArch(t *testing.T) { - env, cli := integrationtest.CreateArduinoCLIWithEnvironment(t) - defer env.CleanUp() - - _, _, err := cli.Run("update") - require.NoError(t, err) - - // Create a sketch - sketchPath := cli.SketchbookDir().Join("SketchSimple") - _, _, err = cli.Run("sketch", "new", sketchPath.String()) - require.NoError(t, err) - - // Compile with wrong packager - _, stderr, err := cli.Run("compile", "-b", "wrong:avr:uno", sketchPath.String()) - require.Error(t, err) - require.Contains(t, string(stderr), "Error during build: Platform 'wrong:avr' not found: platform not installed") - require.Contains(t, string(stderr), "Platform wrong:avr is not found in any known index") - - // Compile with wrong arch - _, stderr, err = cli.Run("compile", "-b", "arduino:wrong:uno", sketchPath.String()) - require.Error(t, err) - require.Contains(t, string(stderr), "Error during build: Platform 'arduino:wrong' not found: platform not installed") - require.Contains(t, string(stderr), "Platform arduino:wrong is not found in any known index") -} - -func TestCompileWithKnownPlatformNotInstalled(t *testing.T) { - env, cli := integrationtest.CreateArduinoCLIWithEnvironment(t) - defer env.CleanUp() - - _, _, err := cli.Run("update") - require.NoError(t, err) - - // Create a sketch - sketchPath := cli.SketchbookDir().Join("SketchSimple") - _, _, err = cli.Run("sketch", "new", sketchPath.String()) - require.NoError(t, err) - - // Try to compile using a platform found in the index but not installed - _, stderr, err := cli.Run("compile", "-b", "arduino:avr:uno", sketchPath.String()) - require.Error(t, err) - require.Contains(t, string(stderr), "Error during build: Platform 'arduino:avr' not found: platform not installed") - // Verifies command to fix error is shown to user - require.Contains(t, string(stderr), "Try running `arduino-cli core install arduino:avr`") -} - -func TestCompileWithFakeSecureBootCore(t *testing.T) { - env, cli := integrationtest.CreateArduinoCLIWithEnvironment(t) - defer env.CleanUp() - - _, _, err := cli.Run("update") - require.NoError(t, err) - - _, _, err = cli.Run("core", "install", "arduino:avr@1.8.3") - require.NoError(t, err) - - sketchName := "SketchSimple" - sketchPath := cli.SketchbookDir().Join(sketchName) - fqbn := "arduino:avr:uno" - - _, _, err = cli.Run("sketch", "new", sketchPath.String()) - require.NoError(t, err) - - // Verifies compilation works - _, _, err = cli.Run("compile", "--clean", "-b", fqbn, sketchPath.String()) - require.NoError(t, err) - - // Overrides default platform adding secure_boot support using platform.local.txt - avrPlatformPath := cli.DataDir().Join("packages", "arduino", "hardware", "avr", "1.8.3", "platform.local.txt") - testPlatformName := "platform_with_secure_boot" - err = paths.New("..", "testdata", testPlatformName, "platform.local.txt").CopyTo(avrPlatformPath) - require.NoError(t, err) - - // Overrides default board adding secure boot support using board.local.txt - avrBoardPath := cli.DataDir().Join("packages", "arduino", "hardware", "avr", "1.8.3", "boards.local.txt") - err = paths.New("..", "testdata", testPlatformName, "boards.local.txt").CopyTo(avrBoardPath) - require.NoError(t, err) - - // Verifies compilation works with secure boot disabled - stdout, _, err := cli.Run("compile", "--clean", "-b", fqbn+":security=none", sketchPath.String(), "-v") - require.NoError(t, err) - require.Contains(t, string(stdout), "echo exit") - - // Verifies compilation works with secure boot enabled - stdout, _, err = cli.Run("compile", "--clean", "-b", fqbn+":security=sien", sketchPath.String(), "-v") - require.NoError(t, err) - require.Contains(t, string(stdout), "Default_Keys/default-signing-key.pem") - require.Contains(t, string(stdout), "Default_Keys/default-encrypt-key.pem") - - // Verifies compilation does not work with secure boot enabled and using only one flag - _, stderr, err := cli.Run( - "compile", - "--clean", - "-b", - fqbn+":security=sien", - sketchPath.String(), - "--keys-keychain", - cli.SketchbookDir().String(), - "-v", - ) - require.Error(t, err) - require.Contains(t, string(stderr), "Flag --sign-key is mandatory when used in conjunction with flag --keys-keychain") - - // Verifies compilation works with secure boot enabled and when overriding the sign key and encryption key used - keysDir := cli.SketchbookDir().Join("keys_dir") - err = keysDir.Mkdir() - require.NoError(t, err) - signKeyPath := keysDir.Join("my-sign-key.pem") - err = signKeyPath.WriteFile([]byte{}) - require.NoError(t, err) - encryptKeyPath := cli.SketchbookDir().Join("my-encrypt-key.pem") - err = encryptKeyPath.WriteFile([]byte{}) - require.NoError(t, err) - stdout, _, err = cli.Run( - "compile", - "--clean", - "-b", - fqbn+":security=sien", - sketchPath.String(), - "--keys-keychain", - keysDir.String(), - "--sign-key", - "my-sign-key.pem", - "--encrypt-key", - "my-encrypt-key.pem", - "-v", - ) - require.NoError(t, err) - require.Contains(t, string(stdout), "my-sign-key.pem") - require.Contains(t, string(stdout), "my-encrypt-key.pem") -} diff --git a/internal/integrationtest/compile/compile_test.go b/internal/integrationtest/compile/compile_test.go index a349ec6b78c..de1e9c2e626 100644 --- a/internal/integrationtest/compile/compile_test.go +++ b/internal/integrationtest/compile/compile_test.go @@ -65,6 +65,9 @@ func TestCompile(t *testing.T) { {"OnlyCompilationDatabaseFlag", compileOnlyCompilationDatabaseFlag}, {"UsingPlatformLocalTxt", compileUsingPlatformLocalTxt}, {"UsingBoardsLocalTxt", compileUsingBoardsLocalTxt}, + {"WithInvalidBuildOptionJson", compileWithInvalidBuildOptionJson}, + {"WithRelativeBuildPath", compileWithRelativeBuildPath}, + {"WithFakeSecureBootCore", compileWithFakeSecureBootCore}, }.Run(t, env, cli) } @@ -957,3 +960,569 @@ func TestCompileManuallyInstalledPlatformUsingPlatformLocalTxt(t *testing.T) { require.Error(t, err) require.Contains(t, string(stderr), "my-compiler-that-does-not-exist") } + +func compileWithInvalidBuildOptionJson(t *testing.T, env *integrationtest.Environment, cli *integrationtest.ArduinoCLI) { + sketchName := "CompileInvalidBuildOptionsJson" + sketchPath := cli.SketchbookDir().Join(sketchName) + defer sketchPath.RemoveAll() + fqbn := "arduino:avr:uno" + + // Create a test sketch + _, _, err := cli.Run("sketch", "new", sketchPath.String()) + require.NoError(t, err) + + // Get the build directory + md5 := md5.Sum(([]byte(sketchPath.String()))) + sketchPathMd5 := strings.ToUpper(hex.EncodeToString(md5[:])) + require.NotEmpty(t, sketchPathMd5) + buildDir := paths.TempDir().Join("arduino-sketch-" + sketchPathMd5) + + _, _, err = cli.Run("compile", "-b", fqbn, sketchPath.String(), "--verbose") + require.NoError(t, err) + + // Breaks the build.options.json file + buildOptionsJson := buildDir.Join("build.options.json") + err = buildOptionsJson.WriteFile([]byte("invalid json")) + require.NoError(t, err) + + _, _, err = cli.Run("compile", "-b", fqbn, sketchPath.String(), "--verbose") + require.NoError(t, err) +} + +func compileWithRelativeBuildPath(t *testing.T, env *integrationtest.Environment, cli *integrationtest.ArduinoCLI) { + sketchName := "sketch_simple" + sketchPath := cli.CopySketch(sketchName) + defer sketchPath.RemoveAll() + fqbn := "arduino:avr:uno" + + buildPath := paths.New("..").Join("build_path") + newWorkingDir := cli.SketchbookDir().Join("working_dir") + err := newWorkingDir.Mkdir() + require.NoError(t, err) + defer newWorkingDir.RemoveAll() + cli.SetWorkingDir(newWorkingDir) + _, _, err = cli.Run("compile", "-b", fqbn, "--build-path", buildPath.String(), sketchPath.String(), "-v") + require.NoError(t, err) + cli.SetWorkingDir(env.RootDir()) + + absoluteBuildPath := cli.SketchbookDir().Join("build_path") + builtFiles, err := absoluteBuildPath.ReadDir() + require.NoError(t, err) + require.Contains(t, builtFiles[8].String(), sketchName+".ino.eep") + require.Contains(t, builtFiles[9].String(), sketchName+".ino.elf") + require.Contains(t, builtFiles[10].String(), sketchName+".ino.hex") + require.Contains(t, builtFiles[11].String(), sketchName+".ino.with_bootloader.bin") + require.Contains(t, builtFiles[12].String(), sketchName+".ino.with_bootloader.hex") + require.Contains(t, builtFiles[0].String(), "build.options.json") + require.Contains(t, builtFiles[1].String(), "compile_commands.json") + require.Contains(t, builtFiles[2].String(), "core") + require.Contains(t, builtFiles[3].String(), "includes.cache") + require.Contains(t, builtFiles[4].String(), "libraries") + require.Contains(t, builtFiles[6].String(), "preproc") + require.Contains(t, builtFiles[7].String(), "sketch") +} + +func compileWithFakeSecureBootCore(t *testing.T, env *integrationtest.Environment, cli *integrationtest.ArduinoCLI) { + sketchName := "SketchSimple" + sketchPath := cli.SketchbookDir().Join(sketchName) + defer sketchPath.RemoveAll() + fqbn := "arduino:avr:uno" + + _, _, err := cli.Run("sketch", "new", sketchPath.String()) + require.NoError(t, err) + + // Verifies compilation works + _, _, err = cli.Run("compile", "--clean", "-b", fqbn, sketchPath.String()) + require.NoError(t, err) + + // Overrides default platform adding secure_boot support using platform.local.txt + avrPlatformPath := cli.DataDir().Join("packages", "arduino", "hardware", "avr", "1.8.5", "platform.local.txt") + defer avrPlatformPath.Remove() + testPlatformName := "platform_with_secure_boot" + err = paths.New("..", "testdata", testPlatformName, "platform.local.txt").CopyTo(avrPlatformPath) + require.NoError(t, err) + + // Overrides default board adding secure boot support using board.local.txt + avrBoardPath := cli.DataDir().Join("packages", "arduino", "hardware", "avr", "1.8.5", "boards.local.txt") + defer avrBoardPath.Remove() + err = paths.New("..", "testdata", testPlatformName, "boards.local.txt").CopyTo(avrBoardPath) + require.NoError(t, err) + + // Verifies compilation works with secure boot disabled + stdout, _, err := cli.Run("compile", "--clean", "-b", fqbn+":security=none", sketchPath.String(), "-v") + require.NoError(t, err) + require.Contains(t, string(stdout), "echo exit") + + // Verifies compilation works with secure boot enabled + stdout, _, err = cli.Run("compile", "--clean", "-b", fqbn+":security=sien", sketchPath.String(), "-v") + require.NoError(t, err) + require.Contains(t, string(stdout), "Default_Keys/default-signing-key.pem") + require.Contains(t, string(stdout), "Default_Keys/default-encrypt-key.pem") + + // Verifies compilation does not work with secure boot enabled and using only one flag + _, stderr, err := cli.Run( + "compile", + "--clean", + "-b", + fqbn+":security=sien", + sketchPath.String(), + "--keys-keychain", + cli.SketchbookDir().String(), + "-v", + ) + require.Error(t, err) + require.Contains(t, string(stderr), "Flag --sign-key is mandatory when used in conjunction with flag --keys-keychain") + + // Verifies compilation works with secure boot enabled and when overriding the sign key and encryption key used + keysDir := cli.SketchbookDir().Join("keys_dir") + err = keysDir.Mkdir() + require.NoError(t, err) + signKeyPath := keysDir.Join("my-sign-key.pem") + err = signKeyPath.WriteFile([]byte{}) + require.NoError(t, err) + encryptKeyPath := cli.SketchbookDir().Join("my-encrypt-key.pem") + err = encryptKeyPath.WriteFile([]byte{}) + require.NoError(t, err) + stdout, _, err = cli.Run( + "compile", + "--clean", + "-b", + fqbn+":security=sien", + sketchPath.String(), + "--keys-keychain", + keysDir.String(), + "--sign-key", + "my-sign-key.pem", + "--encrypt-key", + "my-encrypt-key.pem", + "-v", + ) + require.NoError(t, err) + require.Contains(t, string(stdout), "my-sign-key.pem") + require.Contains(t, string(stdout), "my-encrypt-key.pem") +} + +func TestCompilePart4(t *testing.T) { + env, cli := integrationtest.CreateArduinoCLIWithEnvironment(t) + defer env.CleanUp() + + _, _, err := cli.Run("update") + require.NoError(t, err) + + _, _, err = cli.Run("core", "install", "arduino:avr@1.8.3") + require.NoError(t, err) + + // Manually installs a library + gitUrl := "https://github.com/arduino-libraries/WiFi101.git" + libPath := cli.SketchbookDir().Join("my-libraries", "WiFi101") + _, err = git.PlainClone(libPath.String(), false, &git.CloneOptions{ + URL: gitUrl, + ReferenceName: plumbing.NewTagReferenceName("0.16.1"), + }) + require.NoError(t, err) + + integrationtest.CLISubtests{ + {"WithLibrary", compileWithLibrary}, + {"WithLibraryPriority", compileWithLibraryPriority}, + {"WithDifferentLibrary", recompileWithDifferentLibrary}, + }.Run(t, env, cli) +} + +func compileWithLibrary(t *testing.T, env *integrationtest.Environment, cli *integrationtest.ArduinoCLI) { + sketchName := "CompileSketchWithWiFi101Dependency" + sketchPath := cli.SketchbookDir().Join(sketchName) + defer sketchPath.RemoveAll() + fqbn := "arduino:avr:uno" + + libPath := cli.SketchbookDir().Join("my-libraries", "WiFi101") + + // Create new sketch and add library include + _, _, err := cli.Run("sketch", "new", sketchPath.String()) + require.NoError(t, err) + sketchFile := sketchPath.Join(sketchName + ".ino") + data, err := sketchFile.ReadFile() + require.NoError(t, err) + data = append([]byte("#include \n"), data...) + err = sketchFile.WriteFile(data) + require.NoError(t, err) + + stdout, _, err := cli.Run("compile", "-b", fqbn, sketchPath.String(), "--library", libPath.String(), "-v") + require.NoError(t, err) + require.Contains(t, string(stdout), "WiFi101") +} + +func compileWithLibraryPriority(t *testing.T, env *integrationtest.Environment, cli *integrationtest.ArduinoCLI) { + sketchName := "CompileSketchWithLibraryPriority" + sketchPath := cli.SketchbookDir().Join(sketchName) + defer sketchPath.RemoveAll() + fqbn := "arduino:avr:uno" + + manuallyInstalledLibPath := cli.SketchbookDir().Join("my-libraries", "WiFi101") + + // Install the same library we installed manually + _, _, err := cli.Run("lib", "install", "WiFi101") + require.NoError(t, err) + defer cli.SketchbookDir().Join("libraries").RemoveAll() + + // Create new sketch and add library include + _, _, err = cli.Run("sketch", "new", sketchPath.String()) + require.NoError(t, err) + sketchFile := sketchPath.Join(sketchName + ".ino") + lines, err := sketchFile.ReadFileAsLines() + require.NoError(t, err) + lines = append([]string{"#include \n"}, lines...) + var data []byte + for _, l := range lines { + data = append(data, []byte(l)...) + } + err = sketchFile.WriteFile(data) + require.NoError(t, err) + + stdout, _, err := cli.Run("compile", "-b", fqbn, sketchPath.String(), "--library", manuallyInstalledLibPath.String(), "-v") + require.NoError(t, err) + cliInstalledLibPath := cli.SketchbookDir().Join("libraries", "WiFi101") + expectedOutput := [3]string{ + "Multiple libraries were found for \"WiFi101.h\"", + " Used: " + manuallyInstalledLibPath.String(), + " Not used: " + cliInstalledLibPath.String(), + } + require.Contains(t, string(stdout), expectedOutput[0]+"\n"+expectedOutput[1]+"\n"+expectedOutput[2]+"\n") +} + +func recompileWithDifferentLibrary(t *testing.T, env *integrationtest.Environment, cli *integrationtest.ArduinoCLI) { + sketchName := "RecompileCompileSketchWithDifferentLibrary" + sketchPath := cli.SketchbookDir().Join(sketchName) + defer sketchPath.RemoveAll() + fqbn := "arduino:avr:uno" + + // Install library + _, _, err := cli.Run("lib", "install", "WiFi101") + require.NoError(t, err) + defer cli.SketchbookDir().Join("libraries").RemoveAll() + + manuallyInstalledLibPath := cli.SketchbookDir().Join("my-libraries", "WiFi101") + + // Create new sketch and add library include + _, _, err = cli.Run("sketch", "new", sketchPath.String()) + require.NoError(t, err) + sketchFile := sketchPath.Join(sketchName + ".ino") + lines, err := sketchFile.ReadFileAsLines() + require.NoError(t, err) + lines = append([]string{"#include \n"}, lines...) + var data []byte + for _, l := range lines { + data = append(data, []byte(l)...) + } + err = sketchFile.WriteFile(data) + require.NoError(t, err) + + md5 := md5.Sum(([]byte(sketchPath.String()))) + sketchPathMd5 := strings.ToUpper(hex.EncodeToString(md5[:])) + require.NotEmpty(t, sketchPathMd5) + buildDir := paths.TempDir().Join("arduino-sketch-" + sketchPathMd5) + + // Compile sketch using library not managed by CLI + stdout, _, err := cli.Run("compile", "-b", fqbn, "--library", manuallyInstalledLibPath.String(), sketchPath.String(), "-v") + require.NoError(t, err) + objPath := buildDir.Join("libraries", "WiFi101", "WiFi.cpp.o") + require.NotContains(t, string(stdout), "Using previously compiled file: "+objPath.String()) + + // Compile again using library installed from CLI + stdout, _, err = cli.Run("compile", "-b", fqbn, sketchPath.String(), "-v") + require.NoError(t, err) + require.NotContains(t, string(stdout), "Using previously compiled file: "+objPath.String()) +} + +func TestCompileManuallyInstalledPlatformUsingBoardsLocalTxt(t *testing.T) { + env, cli := integrationtest.CreateArduinoCLIWithEnvironment(t) + defer env.CleanUp() + + _, _, err := cli.Run("update") + require.NoError(t, err) + + sketchName := "CompileSketchManuallyInstalledPlatformUsingBoardsLocalTxt" + sketchPath := cli.SketchbookDir().Join(sketchName) + fqbn := "arduino-beta-development:avr:nessuno" + _, _, err = cli.Run("sketch", "new", sketchPath.String()) + require.NoError(t, err) + + // Manually installs a core in sketchbooks hardware folder + gitUrl := "https://github.com/arduino/ArduinoCore-avr.git" + repoDir := cli.SketchbookDir().Join("hardware", "arduino-beta-development", "avr") + _, err = git.PlainClone(repoDir.String(), false, &git.CloneOptions{ + URL: gitUrl, + ReferenceName: plumbing.NewTagReferenceName("1.8.3"), + }) + require.NoError(t, err) + + // Installs also the same core via CLI so all the necessary tools are installed + _, _, err = cli.Run("core", "install", "arduino:avr@1.8.3") + require.NoError(t, err) + + // Verifies compilation fails because board doesn't exist + _, stderr, err := cli.Run("compile", "--clean", "-b", fqbn, sketchPath.String()) + require.Error(t, err) + require.Contains(t, string(stderr), "Error during build: Error resolving FQBN: board arduino-beta-development:avr:nessuno not found") + + // Use custom boards.local.txt with made arduino:avr:nessuno board + boardsLocalTxt := repoDir.Join("boards.local.txt") + err = paths.New("..", "testdata", "boards.local.txt").CopyTo(boardsLocalTxt) + require.NoError(t, err) + + _, _, err = cli.Run("compile", "--clean", "-b", fqbn, sketchPath.String()) + require.NoError(t, err) +} + +func TestCompileWithConflictingLibrariesInclude(t *testing.T) { + env, cli := integrationtest.CreateArduinoCLIWithEnvironment(t) + defer env.CleanUp() + + _, _, err := cli.Run("update") + require.NoError(t, err) + + _, _, err = cli.Run("core", "install", "arduino:avr@1.8.3") + require.NoError(t, err) + + // Installs conflicting libraries + gitUrl := "https://github.com/pstolarz/OneWireNg.git" + oneWireNgLibPath := cli.SketchbookDir().Join("libraries", "onewireng_0_8_1") + _, err = git.PlainClone(oneWireNgLibPath.String(), false, &git.CloneOptions{ + URL: gitUrl, + ReferenceName: plumbing.NewTagReferenceName("0.8.1"), + }) + require.NoError(t, err) + + gitUrl = "https://github.com/PaulStoffregen/OneWire.git" + oneWireLibPath := cli.SketchbookDir().Join("libraries", "onewire_2_3_5") + _, err = git.PlainClone(oneWireLibPath.String(), false, &git.CloneOptions{ + URL: gitUrl, + ReferenceName: plumbing.NewTagReferenceName("v2.3.5"), + }) + require.NoError(t, err) + + sketchPath := cli.CopySketch("sketch_with_conflicting_libraries_include") + fqbn := "arduino:avr:uno" + + stdout, _, err := cli.Run("compile", "-b", fqbn, sketchPath.String(), "--verbose") + require.NoError(t, err) + expectedOutput := [3]string{ + "Multiple libraries were found for \"OneWire.h\"", + " Used: " + oneWireLibPath.String(), + " Not used: " + oneWireNgLibPath.String(), + } + require.Contains(t, string(stdout), expectedOutput[0]+"\n"+expectedOutput[1]+"\n"+expectedOutput[2]+"\n") +} + +func TestCompileWithEsp32BundledLibraries(t *testing.T) { + // Some esp cores have have bundled libraries that are optimize for that architecture, + // it might happen that if the user has a library with the same name installed conflicts + // can ensue and the wrong library is used for compilation, thus it fails. + // This happens because for "historical" reasons these platform have their "name" key + // in the "library.properties" flag suffixed with "(esp32)" or similar even though that + // doesn't respect the libraries specification. + // https://arduino.github.io/arduino-cli/latest/library-specification/#libraryproperties-file-format + // + // The reason those libraries have these suffixes is to avoid an annoying bug in the Java IDE + // that would have caused the libraries that are both bundled with the core and the Java IDE to be + // always marked as updatable. For more info see: https://github.com/arduino/Arduino/issues/4189 + env, cli := integrationtest.CreateArduinoCLIWithEnvironment(t) + defer env.CleanUp() + + _, _, err := cli.Run("update") + require.NoError(t, err) + + // Update index with esp32 core and install it + url := "https://raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package_esp32_index.json" + coreVersion := "1.0.6" + _, _, err = cli.Run("core", "update-index", "--additional-urls="+url) + require.NoError(t, err) + _, _, err = cli.Run("core", "install", "esp32:esp32@"+coreVersion, "--additional-urls="+url) + require.NoError(t, err) + + // Install a library with the same name as one bundled with the core + _, _, err = cli.Run("lib", "install", "SD") + require.NoError(t, err) + + sketchPath := cli.CopySketch("sketch_with_sd_library") + fqbn := "esp32:esp32:esp32" + + stdout, _, err := cli.Run("compile", "-b", fqbn, sketchPath.String(), "--verbose") + require.Error(t, err) + + coreBundledLibPath := cli.DataDir().Join("packages", "esp32", "hardware", "esp32", coreVersion, "libraries", "SD") + cliInstalledLibPath := cli.SketchbookDir().Join("libraries", "SD") + expectedOutput := [3]string{ + "Multiple libraries were found for \"OneWire.h\"", + " Used: " + coreBundledLibPath.String(), + " Not used: " + cliInstalledLibPath.String(), + } + require.NotContains(t, string(stdout), expectedOutput[0]+"\n"+expectedOutput[1]+"\n"+expectedOutput[2]+"\n") +} + +func TestCompileWithEsp8266BundledLibraries(t *testing.T) { + // Some esp cores have have bundled libraries that are optimize for that architecture, + // it might happen that if the user has a library with the same name installed conflicts + // can ensue and the wrong library is used for compilation, thus it fails. + // This happens because for "historical" reasons these platform have their "name" key + // in the "library.properties" flag suffixed with "(esp32)" or similar even though that + // doesn't respect the libraries specification. + // https://arduino.github.io/arduino-cli/latest/library-specification/#libraryproperties-file-format + // + // The reason those libraries have these suffixes is to avoid an annoying bug in the Java IDE + // that would have caused the libraries that are both bundled with the core and the Java IDE to be + // always marked as updatable. For more info see: https://github.com/arduino/Arduino/issues/4189 + env, cli := integrationtest.CreateArduinoCLIWithEnvironment(t) + defer env.CleanUp() + + _, _, err := cli.Run("update") + require.NoError(t, err) + + // Update index with esp8266 core and install it + url := "http://arduino.esp8266.com/stable/package_esp8266com_index.json" + coreVersion := "2.7.4" + _, _, err = cli.Run("core", "update-index", "--additional-urls="+url) + require.NoError(t, err) + _, _, err = cli.Run("core", "install", "esp8266:esp8266@"+coreVersion, "--additional-urls="+url) + require.NoError(t, err) + + // Install a library with the same name as one bundled with the core + _, _, err = cli.Run("lib", "install", "SD") + require.NoError(t, err) + + sketchPath := cli.CopySketch("sketch_with_sd_library") + fqbn := "esp8266:esp8266:generic" + + stdout, _, err := cli.Run("compile", "-b", fqbn, sketchPath.String(), "--verbose") + require.Error(t, err) + + coreBundledLibPath := cli.DataDir().Join("packages", "esp8266", "hardware", "esp8266", coreVersion, "libraries", "SD") + cliInstalledLibPath := cli.SketchbookDir().Join("libraries", "SD") + expectedOutput := [3]string{ + "Multiple libraries were found for \"OneWire.h\"", + " Used: " + coreBundledLibPath.String(), + " Not used: " + cliInstalledLibPath.String(), + } + require.NotContains(t, string(stdout), expectedOutput[0]+"\n"+expectedOutput[1]+"\n"+expectedOutput[2]+"\n") +} + +func TestGenerateCompileCommandsJsonResilience(t *testing.T) { + env, cli := integrationtest.CreateArduinoCLIWithEnvironment(t) + defer env.CleanUp() + + _, _, err := cli.Run("update") + require.NoError(t, err) + + // check it didn't fail with esp32@2.0.1 that has a prebuild hook that must run: + // https://github.com/arduino/arduino-cli/issues/1547 + url := "https://raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package_esp32_index.json" + _, _, err = cli.Run("core", "update-index", "--additional-urls="+url) + require.NoError(t, err) + _, _, err = cli.Run("core", "install", "esp32:esp32@2.0.1", "--additional-urls="+url) + require.NoError(t, err) + sketchPath := cli.CopySketch("sketch_simple") + _, _, err = cli.Run("compile", "-b", "esp32:esp32:featheresp32", "--only-compilation-database", sketchPath.String()) + require.NoError(t, err) + + // check it didn't fail on a sketch with a missing include + sketchPath = cli.CopySketch("sketch_with_missing_include") + _, _, err = cli.Run("compile", "-b", "esp32:esp32:featheresp32", "--only-compilation-database", sketchPath.String()) + require.NoError(t, err) +} + +func TestCompileSketchSketchWithTppFileInclude(t *testing.T) { + env, cli := integrationtest.CreateArduinoCLIWithEnvironment(t) + defer env.CleanUp() + + _, _, err := cli.Run("update") + require.NoError(t, err) + + // Download latest AVR + _, _, err = cli.Run("core", "install", "arduino:avr") + require.NoError(t, err) + + sketchPath := cli.CopySketch("sketch_with_tpp_file_include") + fqbn := "arduino:avr:uno" + + _, _, err = cli.Run("compile", "-b", fqbn, sketchPath.String(), "--verbose") + require.NoError(t, err) +} + +func TestCompileSketchWithIppFileInclude(t *testing.T) { + env, cli := integrationtest.CreateArduinoCLIWithEnvironment(t) + defer env.CleanUp() + + _, _, err := cli.Run("update") + require.NoError(t, err) + + // Download latest AVR + _, _, err = cli.Run("core", "install", "arduino:avr") + require.NoError(t, err) + + sketchPath := cli.CopySketch("sketch_with_ipp_file_include") + fqbn := "arduino:avr:uno" + + _, _, err = cli.Run("compile", "-b", fqbn, sketchPath.String(), "--verbose") + require.NoError(t, err) +} + +func TestCompileWithoutUploadAndFqbn(t *testing.T) { + env, cli := integrationtest.CreateArduinoCLIWithEnvironment(t) + defer env.CleanUp() + + _, _, err := cli.Run("update") + require.NoError(t, err) + + // Create a sketch + sketchPath := cli.SketchbookDir().Join("SketchSimple") + _, _, err = cli.Run("sketch", "new", sketchPath.String()) + require.NoError(t, err) + + _, stderr, err := cli.Run("compile", sketchPath.String()) + require.Error(t, err) + require.Contains(t, string(stderr), "Missing FQBN (Fully Qualified Board Name)") +} + +func TestCompileNonInstalledPlatformWithWrongPackagerAndArch(t *testing.T) { + env, cli := integrationtest.CreateArduinoCLIWithEnvironment(t) + defer env.CleanUp() + + _, _, err := cli.Run("update") + require.NoError(t, err) + + // Create a sketch + sketchPath := cli.SketchbookDir().Join("SketchSimple") + _, _, err = cli.Run("sketch", "new", sketchPath.String()) + require.NoError(t, err) + + // Compile with wrong packager + _, stderr, err := cli.Run("compile", "-b", "wrong:avr:uno", sketchPath.String()) + require.Error(t, err) + require.Contains(t, string(stderr), "Error during build: Platform 'wrong:avr' not found: platform not installed") + require.Contains(t, string(stderr), "Platform wrong:avr is not found in any known index") + + // Compile with wrong arch + _, stderr, err = cli.Run("compile", "-b", "arduino:wrong:uno", sketchPath.String()) + require.Error(t, err) + require.Contains(t, string(stderr), "Error during build: Platform 'arduino:wrong' not found: platform not installed") + require.Contains(t, string(stderr), "Platform arduino:wrong is not found in any known index") +} + +func TestCompileWithKnownPlatformNotInstalled(t *testing.T) { + env, cli := integrationtest.CreateArduinoCLIWithEnvironment(t) + defer env.CleanUp() + + _, _, err := cli.Run("update") + require.NoError(t, err) + + // Create a sketch + sketchPath := cli.SketchbookDir().Join("SketchSimple") + _, _, err = cli.Run("sketch", "new", sketchPath.String()) + require.NoError(t, err) + + // Try to compile using a platform found in the index but not installed + _, stderr, err := cli.Run("compile", "-b", "arduino:avr:uno", sketchPath.String()) + require.Error(t, err) + require.Contains(t, string(stderr), "Error during build: Platform 'arduino:avr' not found: platform not installed") + // Verifies command to fix error is shown to user + require.Contains(t, string(stderr), "Try running `arduino-cli core install arduino:avr`") +}