diff --git a/arduino/builder/sketch_test.go b/arduino/builder/sketch_test.go index e6526f6fbc8..409e258d541 100644 --- a/arduino/builder/sketch_test.go +++ b/arduino/builder/sketch_test.go @@ -82,6 +82,48 @@ func TestLoadSketchFolder(t *testing.T) { require.Equal(t, "helper.h", filepath.Base(s.AdditionalFiles[2].Path)) } +func TestLoadSketchFolderSymlink(t *testing.T) { + // pass the path to the sketch folder + symlinkSketchPath := filepath.Join("testdata", t.Name()) + srcSketchPath := t.Name() + "Src" + os.Symlink(srcSketchPath, symlinkSketchPath) + mainFilePath := filepath.Join(symlinkSketchPath, t.Name()+".ino") + s, err := builder.SketchLoad(symlinkSketchPath, "") + require.Nil(t, err) + require.NotNil(t, s) + require.Equal(t, mainFilePath, s.MainFile.Path) + require.Equal(t, symlinkSketchPath, s.LocationPath) + require.Len(t, s.OtherSketchFiles, 2) + require.Equal(t, "old.pde", filepath.Base(s.OtherSketchFiles[0].Path)) + require.Equal(t, "other.ino", filepath.Base(s.OtherSketchFiles[1].Path)) + require.Len(t, s.AdditionalFiles, 3) + require.Equal(t, "header.h", filepath.Base(s.AdditionalFiles[0].Path)) + require.Equal(t, "s_file.S", filepath.Base(s.AdditionalFiles[1].Path)) + require.Equal(t, "helper.h", filepath.Base(s.AdditionalFiles[2].Path)) + + // pass the path to the main file + symlinkSketchPath = mainFilePath + s, err = builder.SketchLoad(symlinkSketchPath, "") + require.Nil(t, err) + require.NotNil(t, s) + require.Equal(t, mainFilePath, s.MainFile.Path) + require.Len(t, s.OtherSketchFiles, 2) + require.Equal(t, "old.pde", filepath.Base(s.OtherSketchFiles[0].Path)) + require.Equal(t, "other.ino", filepath.Base(s.OtherSketchFiles[1].Path)) + require.Len(t, s.AdditionalFiles, 3) + require.Equal(t, "header.h", filepath.Base(s.AdditionalFiles[0].Path)) + require.Equal(t, "s_file.S", filepath.Base(s.AdditionalFiles[1].Path)) + require.Equal(t, "helper.h", filepath.Base(s.AdditionalFiles[2].Path)) +} + +func TestLoadSketchFolderIno(t *testing.T) { + // pass the path to the sketch folder + sketchPath := filepath.Join("testdata", t.Name()) + _, err := builder.SketchLoad(sketchPath, "") + require.Error(t, err) + require.Contains(t, err.Error(), "sketch must not be a directory") +} + func TestLoadSketchFolderWrongMain(t *testing.T) { sketchPath := filepath.Join("testdata", t.Name()) _, err := builder.SketchLoad(sketchPath, "") diff --git a/arduino/builder/testdata/TestLoadSketchFolderIno/TestLoadSketchFolderIno.ino/TestLoadSketchFolder.ino b/arduino/builder/testdata/TestLoadSketchFolderIno/TestLoadSketchFolderIno.ino/TestLoadSketchFolder.ino new file mode 100644 index 00000000000..0d5e0f5ceb9 --- /dev/null +++ b/arduino/builder/testdata/TestLoadSketchFolderIno/TestLoadSketchFolderIno.ino/TestLoadSketchFolder.ino @@ -0,0 +1,7 @@ +void setup() { + +} + +void loop() { + +} \ No newline at end of file diff --git a/arduino/builder/testdata/TestLoadSketchFolderSymlinkSrc/.#sketch.ino b/arduino/builder/testdata/TestLoadSketchFolderSymlinkSrc/.#sketch.ino new file mode 100644 index 00000000000..71048175432 --- /dev/null +++ b/arduino/builder/testdata/TestLoadSketchFolderSymlinkSrc/.#sketch.ino @@ -0,0 +1,2 @@ +void setup() +void loop) } \ No newline at end of file diff --git a/arduino/builder/testdata/TestLoadSketchFolderSymlinkSrc/TestLoadSketchFolderSymlink.ino b/arduino/builder/testdata/TestLoadSketchFolderSymlinkSrc/TestLoadSketchFolderSymlink.ino new file mode 100644 index 00000000000..0d5e0f5ceb9 --- /dev/null +++ b/arduino/builder/testdata/TestLoadSketchFolderSymlinkSrc/TestLoadSketchFolderSymlink.ino @@ -0,0 +1,7 @@ +void setup() { + +} + +void loop() { + +} \ No newline at end of file diff --git a/arduino/builder/testdata/TestLoadSketchFolderSymlinkSrc/doc.txt b/arduino/builder/testdata/TestLoadSketchFolderSymlinkSrc/doc.txt new file mode 100644 index 00000000000..e69de29bb2d diff --git a/arduino/builder/testdata/TestLoadSketchFolderSymlinkSrc/header.h b/arduino/builder/testdata/TestLoadSketchFolderSymlinkSrc/header.h new file mode 100644 index 00000000000..0e7d3b1a6a9 --- /dev/null +++ b/arduino/builder/testdata/TestLoadSketchFolderSymlinkSrc/header.h @@ -0,0 +1 @@ +#define FOO "BAR" \ No newline at end of file diff --git a/arduino/builder/testdata/TestLoadSketchFolderSymlinkSrc/old.pde b/arduino/builder/testdata/TestLoadSketchFolderSymlinkSrc/old.pde new file mode 100644 index 00000000000..e69de29bb2d diff --git a/arduino/builder/testdata/TestLoadSketchFolderSymlinkSrc/other.ino b/arduino/builder/testdata/TestLoadSketchFolderSymlinkSrc/other.ino new file mode 100644 index 00000000000..c426196c017 --- /dev/null +++ b/arduino/builder/testdata/TestLoadSketchFolderSymlinkSrc/other.ino @@ -0,0 +1,3 @@ +String hello() { + return "world"; +} \ No newline at end of file diff --git a/arduino/builder/testdata/TestLoadSketchFolderSymlinkSrc/s_file.S b/arduino/builder/testdata/TestLoadSketchFolderSymlinkSrc/s_file.S new file mode 100644 index 00000000000..e69de29bb2d diff --git a/arduino/builder/testdata/TestLoadSketchFolderSymlinkSrc/src/dont_load_me.ino b/arduino/builder/testdata/TestLoadSketchFolderSymlinkSrc/src/dont_load_me.ino new file mode 100644 index 00000000000..46b07018d09 --- /dev/null +++ b/arduino/builder/testdata/TestLoadSketchFolderSymlinkSrc/src/dont_load_me.ino @@ -0,0 +1,2 @@ +#include +#error "Whattya looking at?" diff --git a/arduino/builder/testdata/TestLoadSketchFolderSymlinkSrc/src/helper.h b/arduino/builder/testdata/TestLoadSketchFolderSymlinkSrc/src/helper.h new file mode 100644 index 00000000000..e69de29bb2d diff --git a/test/test_compile.py b/test/test_compile.py index 08756867e10..ad15f20f719 100644 --- a/test/test_compile.py +++ b/test/test_compile.py @@ -39,7 +39,7 @@ def test_compile_with_simple_sketch(run_command, data_dir): result = run_command("core update-index") assert result.ok - # # Download latest AVR + # Download latest AVR result = run_command("core install arduino:avr") assert result.ok @@ -70,6 +70,62 @@ def test_compile_with_simple_sketch(run_command, data_dir): assert is_message_sequence_in_json_log_traces(expected_trace_sequence, json_log_lines) +def test_compile_with_sketch_with_symlink_selfloop(run_command, data_dir): + # Init the environment explicitly + result = run_command("core update-index") + assert result.ok + + # Download latest AVR + result = run_command("core install arduino:avr") + assert result.ok + + sketch_name = "CompileIntegrationTestSymlinkSelfLoop" + sketch_path = os.path.join(data_dir, sketch_name) + fqbn = "arduino:avr:uno" + + # Create a test sketch + result = run_command("sketch new {}".format(sketch_path)) + assert result.ok + assert "Sketch created in: {}".format(sketch_path) in result.stdout + + # create a symlink that loops on himself + loop_file_path = os.path.join(sketch_path, "loop") + os.symlink(loop_file_path, loop_file_path) + + # Build sketch for arduino:avr:uno + result = run_command( + "compile -b {fqbn} {sketch_path}".format( + fqbn=fqbn, sketch_path=sketch_path)) + # The assertion is a bit relaxed in this case because win behaves differently from macOs and linux + # returning a different error detailed message + assert "Error during sketch processing" in result.stderr + assert not result.ok + + sketch_name = "CompileIntegrationTestSymlinkDirLoop" + sketch_path = os.path.join(data_dir, sketch_name) + fqbn = "arduino:avr:uno" + + # Create a test sketch + result = run_command("sketch new {}".format(sketch_path)) + assert result.ok + assert "Sketch created in: {}".format(sketch_path) in result.stdout + + # create a symlink that loops on the upper level + loop_dir_path = os.path.join(sketch_path, "loop_dir") + os.mkdir(loop_dir_path) + loop_dir_symlink_path = os.path.join(loop_dir_path, "loop_dir_symlink") + os.symlink(loop_dir_path, loop_dir_symlink_path) + + # Build sketch for arduino:avr:uno + result = run_command( + "compile -b {fqbn} {sketch_path}".format( + fqbn=fqbn, sketch_path=sketch_path)) + # The assertion is a bit relaxed also in this case because macOS behaves differently from win and linux: + # the cli does not follow recursively the symlink til breaking + assert "Error during sketch processing" in result.stderr + assert not result.ok + + @pytest.mark.skipif(running_on_ci(), reason="VMs have no serial ports") def test_compile_and_compile_combo(run_command, data_dir): # Init the environment explicitly