Skip to content

Commit

Permalink
Fix caching for libraries when installation folder differents from Na…
Browse files Browse the repository at this point in the history
…me (#2446)

* Fix caching for libraries when installation folder differents from Name

* Prepare infra to add integration test

* Added integration test

---------

Co-authored-by: Cristian Maglie <c.maglie@arduino.cc>
  • Loading branch information
facchinm and cmaglie committed Dec 4, 2023
1 parent d41da43 commit 5935e45
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 40 deletions.
2 changes: 1 addition & 1 deletion arduino/builder/libraries.go
Original file line number Diff line number Diff line change
Expand Up @@ -245,7 +245,7 @@ func (b *Builder) removeUnusedCompiledLibraries(importedLibraries libraries.List
toLibraryNames := func(libraries []*libraries.Library) []string {
libraryNames := []string{}
for _, library := range libraries {
libraryNames = append(libraryNames, library.Name)
libraryNames = append(libraryNames, library.DirName)
}
return libraryNames
}
Expand Down
98 changes: 59 additions & 39 deletions internal/integrationtest/compile_4/compile_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import (
"cmp"
"encoding/json"
"os/exec"
"regexp"
"slices"
"strings"
"testing"
Expand Down Expand Up @@ -904,56 +905,75 @@ func comparePreprocessGoldenFile(t *testing.T, sketchDir *paths.Path, preprocess
require.Equal(t, buf.String(), strings.ReplaceAll(preprocessedSketch, "\r\n", "\n"))
}

func TestCoreCaching(t *testing.T) {
func TestBuildCaching(t *testing.T) {
env, cli := integrationtest.CreateArduinoCLIWithEnvironment(t)
defer env.CleanUp()

sketchPath, err := paths.New("..", "testdata", "bare_minimum").Abs()
require.NoError(t, err)

// Install Arduino AVR Boards
_, _, err = cli.Run("core", "install", "arduino:avr@1.8.6")
_, _, err := cli.Run("core", "install", "arduino:avr@1.8.6")
require.NoError(t, err)

// Create temporary cache dir
buildCachePath, err := paths.MkTempDir("", "test_build_cache")
require.NoError(t, err)
defer buildCachePath.RemoveAll()
t.Run("CoreCaching", func(t *testing.T) {
sketchPath, err := paths.New("..", "testdata", "bare_minimum").Abs()
require.NoError(t, err)

// Build first time
_, _, err = cli.Run("compile", "-b", "arduino:avr:uno", "--build-cache-path", buildCachePath.String(), sketchPath.String())
require.NoError(t, err)
// Create temporary cache dir
buildCachePath, err := paths.MkTempDir("", "test_build_cache")
require.NoError(t, err)
defer buildCachePath.RemoveAll()

// Find cached core and save timestamp
pathList, err := buildCachePath.ReadDirRecursiveFiltered(nil, paths.FilterPrefixes("core.a"))
require.NoError(t, err)
require.Len(t, pathList, 1)
cachedCoreFile := pathList[0]
lastUsedPath := cachedCoreFile.Parent().Join(".last-used")
require.True(t, lastUsedPath.Exist())
coreStatBefore, err := cachedCoreFile.Stat()
require.NoError(t, err)
// Build first time
_, _, err = cli.Run("compile", "-b", "arduino:avr:uno", "--build-cache-path", buildCachePath.String(), sketchPath.String())
require.NoError(t, err)

// Run build again and check timestamp is unchanged
_, _, err = cli.Run("compile", "-b", "arduino:avr:uno", "--build-cache-path", buildCachePath.String(), sketchPath.String())
require.NoError(t, err)
coreStatAfterRebuild, err := cachedCoreFile.Stat()
require.NoError(t, err)
require.Equal(t, coreStatBefore.ModTime(), coreStatAfterRebuild.ModTime())
// Find cached core and save timestamp
pathList, err := buildCachePath.ReadDirRecursiveFiltered(nil, paths.FilterPrefixes("core.a"))
require.NoError(t, err)
require.Len(t, pathList, 1)
cachedCoreFile := pathList[0]
lastUsedPath := cachedCoreFile.Parent().Join(".last-used")
require.True(t, lastUsedPath.Exist())
coreStatBefore, err := cachedCoreFile.Stat()
require.NoError(t, err)

// Touch a file of the core and check if the builder invalidate the cache
time.Sleep(time.Second)
now := time.Now().Local()
coreFolder := cli.DataDir().Join("packages", "arduino", "hardware", "avr", "1.8.6")
err = coreFolder.Join("cores", "arduino", "Arduino.h").Chtimes(now, now)
require.NoError(t, err)
// Run build again and check timestamp is unchanged
_, _, err = cli.Run("compile", "-b", "arduino:avr:uno", "--build-cache-path", buildCachePath.String(), sketchPath.String())
require.NoError(t, err)
coreStatAfterRebuild, err := cachedCoreFile.Stat()
require.NoError(t, err)
require.Equal(t, coreStatBefore.ModTime(), coreStatAfterRebuild.ModTime())

// Run build again, to verify that the builder rebuilds core.a
_, _, err = cli.Run("compile", "-b", "arduino:avr:uno", "--build-cache-path", buildCachePath.String(), sketchPath.String())
require.NoError(t, err)
coreStatAfterTouch, err := cachedCoreFile.Stat()
require.NoError(t, err)
require.NotEqual(t, coreStatBefore.ModTime(), coreStatAfterTouch.ModTime())
// Touch a file of the core and check if the builder invalidate the cache
time.Sleep(time.Second)
now := time.Now().Local()
coreFolder := cli.DataDir().Join("packages", "arduino", "hardware", "avr", "1.8.6")
err = coreFolder.Join("cores", "arduino", "Arduino.h").Chtimes(now, now)
require.NoError(t, err)

// Run build again, to verify that the builder rebuilds core.a
_, _, err = cli.Run("compile", "-b", "arduino:avr:uno", "--build-cache-path", buildCachePath.String(), sketchPath.String())
require.NoError(t, err)
coreStatAfterTouch, err := cachedCoreFile.Stat()
require.NoError(t, err)
require.NotEqual(t, coreStatBefore.ModTime(), coreStatAfterTouch.ModTime())
})

t.Run("LibraryCacheWithDifferentDirname", func(t *testing.T) {
_, _, err = cli.Run("lib", "install", "Robot IR Remote")
require.NoError(t, err)

// Run first compile
sketchPath, err := paths.New("testdata", "SketchUsingRobotIRRemote").Abs()
require.NoError(t, err)
_, _, err = cli.Run("compile", "-b", "arduino:avr:robotControl", "-v", sketchPath.String())
require.NoError(t, err)

// Run second compile and check that previous build is re-used
out, _, err := cli.Run("compile", "-b", "arduino:avr:robotControl", "-v", sketchPath.String())
require.NoError(t, err)
check := regexp.MustCompile(`(?m)^Using previously compiled file:.*IRremoteTools\.cpp\.o$`)
require.True(t, check.Match(out))
})
}

func TestMergeSketchWithBootloader(t *testing.T) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#include <RobotIRremote.h>

void setup() {
}

void loop() {
}

0 comments on commit 5935e45

Please sign in to comment.