From c10727ec7f0b29f5ffc1813e97975e2184739b1f Mon Sep 17 00:00:00 2001 From: Cristian Maglie Date: Thu, 6 Oct 2022 14:42:14 +0200 Subject: [PATCH 1/8] Integrated 'go.bug.st/testsuite' It doesn't make much sense to keep it separate in a different library --- go.mod | 5 +- go.sum | 2 - internal/integrationtest/arduino-cli.go | 11 +-- .../integrationtest/daemon/daemon_test.go | 5 +- internal/integrationtest/environment.go | 85 +++++++++++++++++++ internal/integrationtest/http_server.go | 53 ++++++++++++ 6 files changed, 144 insertions(+), 17 deletions(-) create mode 100644 internal/integrationtest/environment.go create mode 100644 internal/integrationtest/http_server.go diff --git a/go.mod b/go.mod index 18cbec0bb80..88efc524700 100644 --- a/go.mod +++ b/go.mod @@ -57,10 +57,7 @@ require ( gopkg.in/yaml.v2 v2.4.0 ) -require ( - go.bug.st/testifyjson v1.1.1 - go.bug.st/testsuite v0.1.0 -) +require go.bug.st/testifyjson v1.1.1 require ( github.com/cpuguy83/go-md2man/v2 v2.0.0 // indirect diff --git a/go.sum b/go.sum index c048463cd5a..fbc748b209c 100644 --- a/go.sum +++ b/go.sum @@ -376,8 +376,6 @@ go.bug.st/serial.v1 v0.0.0-20180827123349-5f7892a7bb45 h1:mACY1anK6HNCZtm/DK2Rf2 go.bug.st/serial.v1 v0.0.0-20180827123349-5f7892a7bb45/go.mod h1:dRSl/CVCTf56CkXgJMDOdSwNfo2g1orOGE/gBGdvjZw= go.bug.st/testifyjson v1.1.1 h1:nHotIMK151LF3vYsU/b2RaoVaWCgrf2kvQeGNoZkGaA= go.bug.st/testifyjson v1.1.1/go.mod h1:nZyy2icFbv3OE3zW3mGVOnC/GhWgb93LRu+29n2tJlI= -go.bug.st/testsuite v0.1.0 h1:oX4zdIB62+G5A0Kq4dja7Vy8tDiKqKVhhxkzhpMGgog= -go.bug.st/testsuite v0.1.0/go.mod h1:xCIDf97kf9USoz960Foy3CoquwhQmfuFRNh9git70as= go.etcd.io/etcd/api/v3 v3.5.0/go.mod h1:cbVKeC6lCfl7j/8jBhAK6aIYO9XOjdptoxU/nLQcPvs= go.etcd.io/etcd/client/pkg/v3 v3.5.0/go.mod h1:IJHfcCEKxYu1Os13ZdwCwIUTUVGYTSAM3YSwc9/Ac1g= go.etcd.io/etcd/client/v2 v2.305.0/go.mod h1:h9puh54ZTgAKtEbut2oe9P4L/oqKCVB6xsXlzd7alYQ= diff --git a/internal/integrationtest/arduino-cli.go b/internal/integrationtest/arduino-cli.go index 8bfdc066392..deee05dfb6c 100644 --- a/internal/integrationtest/arduino-cli.go +++ b/internal/integrationtest/arduino-cli.go @@ -33,14 +33,9 @@ import ( "github.com/arduino/go-paths-helper" "github.com/fatih/color" "github.com/stretchr/testify/require" - "go.bug.st/testsuite" "google.golang.org/grpc" ) -func init() { - testsuite.ProjectName = "cli" -} - // FindRepositoryRootPath returns the repository root path func FindRepositoryRootPath(t *testing.T) *paths.Path { repoRootPath, err := paths.Getwd() @@ -54,8 +49,8 @@ func FindRepositoryRootPath(t *testing.T) *paths.Path { // CreateArduinoCLIWithEnvironment performs the minimum amount of actions // to build the default test environment. -func CreateArduinoCLIWithEnvironment(t *testing.T) (*testsuite.Environment, *ArduinoCLI) { - env := testsuite.NewEnvironment(t) +func CreateArduinoCLIWithEnvironment(t *testing.T) (*Environment, *ArduinoCLI) { + env := NewEnvironment(t) cli := NewArduinoCliWithinEnvironment(env, &ArduinoCLIConfig{ ArduinoCLIPath: FindRepositoryRootPath(t).Join("arduino-cli"), @@ -89,7 +84,7 @@ type ArduinoCLIConfig struct { } // NewArduinoCliWithinEnvironment creates a new Arduino CLI client inside the given environment. -func NewArduinoCliWithinEnvironment(env *testsuite.Environment, config *ArduinoCLIConfig) *ArduinoCLI { +func NewArduinoCliWithinEnvironment(env *Environment, config *ArduinoCLIConfig) *ArduinoCLI { color.NoColor = false cli := &ArduinoCLI{ path: config.ArduinoCLIPath, diff --git a/internal/integrationtest/daemon/daemon_test.go b/internal/integrationtest/daemon/daemon_test.go index a399b960b06..b868483155f 100644 --- a/internal/integrationtest/daemon/daemon_test.go +++ b/internal/integrationtest/daemon/daemon_test.go @@ -20,14 +20,13 @@ import ( "github.com/arduino/arduino-cli/internal/integrationtest" "github.com/stretchr/testify/require" - "go.bug.st/testsuite" ) // createEnvForDaemon performs the minimum required operations to start the arduino-cli daemon. // It returns a testsuite.Environment and an ArduinoCLI client to perform the integration tests. // The Environment must be disposed by calling the CleanUp method via defer. -func createEnvForDaemon(t *testing.T) (*testsuite.Environment, *integrationtest.ArduinoCLI) { - env := testsuite.NewEnvironment(t) +func createEnvForDaemon(t *testing.T) (*integrationtest.Environment, *integrationtest.ArduinoCLI) { + env := integrationtest.NewEnvironment(t) cli := integrationtest.NewArduinoCliWithinEnvironment(env, &integrationtest.ArduinoCLIConfig{ ArduinoCLIPath: integrationtest.FindRepositoryRootPath(t).Join("arduino-cli"), diff --git a/internal/integrationtest/environment.go b/internal/integrationtest/environment.go new file mode 100644 index 00000000000..4171ad2ba3e --- /dev/null +++ b/internal/integrationtest/environment.go @@ -0,0 +1,85 @@ +// 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 integrationtest + +import ( + "testing" + + "github.com/arduino/go-paths-helper" + "github.com/stretchr/testify/require" +) + +// ProjectName is the prefix used in the test temp files +var ProjectName = "cli" + +// Environment is a test environment for the test suite. +type Environment struct { + rootDir *paths.Path + downloadsDir *paths.Path + t *testing.T + cleanUp func() +} + +// SharedDir returns the shared downloads directory. +func SharedDir(t *testing.T, id string) *paths.Path { + downloadsDir := paths.TempDir().Join(ProjectName + "-" + id) + require.NoError(t, downloadsDir.MkdirAll()) + return downloadsDir +} + +// NewEnvironment creates a new test environment. +func NewEnvironment(t *testing.T) *Environment { + downloadsDir := SharedDir(t, "downloads") + rootDir, err := paths.MkTempDir("", ProjectName) + require.NoError(t, err) + return &Environment{ + rootDir: rootDir, + downloadsDir: downloadsDir, + t: t, + cleanUp: func() { + require.NoError(t, rootDir.RemoveAll()) + }, + } +} + +// RegisterCleanUpCallback adds a clean up function to the clean up chain +func (e *Environment) RegisterCleanUpCallback(newCleanUp func()) { + previousCleanUp := e.cleanUp + e.cleanUp = func() { + newCleanUp() + previousCleanUp() + } +} + +// CleanUp removes the test environment. +func (e *Environment) CleanUp() { + e.cleanUp() +} + +// RootDir returns the root dir of the environment. +func (e *Environment) RootDir() *paths.Path { + return e.rootDir +} + +// SharedDownloadsDir return the shared directory for downloads +func (e *Environment) SharedDownloadsDir() *paths.Path { + return e.downloadsDir +} + +// T returns the testing environment +func (e *Environment) T() *testing.T { + return e.t +} diff --git a/internal/integrationtest/http_server.go b/internal/integrationtest/http_server.go new file mode 100644 index 00000000000..951845e900c --- /dev/null +++ b/internal/integrationtest/http_server.go @@ -0,0 +1,53 @@ +// 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 integrationtest + +import ( + "fmt" + "net/http" + "net/url" + + "github.com/arduino/go-paths-helper" + "github.com/stretchr/testify/require" +) + +// HTTPServeFile spawn an http server that serve a single file. The server +// is started on the given port. The URL to the file and a cleanup function are returned. +func (env *Environment) HTTPServeFile(port uint16, path *paths.Path) *url.URL { + mux := http.NewServeMux() + mux.HandleFunc("/"+path.Base(), func(w http.ResponseWriter, r *http.Request) { + http.ServeFile(w, r, path.String()) + }) + server := &http.Server{ + Addr: fmt.Sprintf(":%d", port), + Handler: mux, + } + + t := env.T() + fileURL, err := url.Parse(fmt.Sprintf("http://127.0.0.1:%d/%s", port, path.Base())) + require.NoError(t, err) + + go func() { + err := server.ListenAndServe() + require.Equal(t, err, http.ErrServerClosed) + }() + + env.RegisterCleanUpCallback(func() { + server.Close() + }) + + return fileURL +} From 0fd789d54b205f2df05b1a7afebd32aa9806fcd1 Mon Sep 17 00:00:00 2001 From: Cristian Maglie Date: Fri, 7 Oct 2022 15:20:01 +0200 Subject: [PATCH 2/8] Do not use shared download dir for 'cache clean' command tests --- internal/integrationtest/arduino-cli.go | 7 ++++++- internal/integrationtest/cache/cache_test.go | 7 +++++-- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/internal/integrationtest/arduino-cli.go b/internal/integrationtest/arduino-cli.go index deee05dfb6c..721b5841e45 100644 --- a/internal/integrationtest/arduino-cli.go +++ b/internal/integrationtest/arduino-cli.go @@ -47,13 +47,18 @@ func FindRepositoryRootPath(t *testing.T) *paths.Path { return repoRootPath } +// FindArduinoCLIPath returns the path to the arduino-cli executable +func FindArduinoCLIPath(t *testing.T) *paths.Path { + return FindRepositoryRootPath(t).Join("arduino-cli") +} + // CreateArduinoCLIWithEnvironment performs the minimum amount of actions // to build the default test environment. func CreateArduinoCLIWithEnvironment(t *testing.T) (*Environment, *ArduinoCLI) { env := NewEnvironment(t) cli := NewArduinoCliWithinEnvironment(env, &ArduinoCLIConfig{ - ArduinoCLIPath: FindRepositoryRootPath(t).Join("arduino-cli"), + ArduinoCLIPath: FindArduinoCLIPath(t), UseSharedStagingFolder: true, }) diff --git a/internal/integrationtest/cache/cache_test.go b/internal/integrationtest/cache/cache_test.go index 9a24ce2dab0..7ad7fe6dc4b 100644 --- a/internal/integrationtest/cache/cache_test.go +++ b/internal/integrationtest/cache/cache_test.go @@ -23,8 +23,11 @@ import ( ) func TestCacheClean(t *testing.T) { - // Clean the cache under arduino caching file directory which is "/staging" - env, cli := integrationtest.CreateArduinoCLIWithEnvironment(t) + // This test do not use shared download directory becuase it will be cleaned up with 'cache clean' command + env := integrationtest.NewEnvironment(t) + cli := integrationtest.NewArduinoCliWithinEnvironment(env, &integrationtest.ArduinoCLIConfig{ + ArduinoCLIPath: integrationtest.FindArduinoCLIPath(t), + }) defer env.CleanUp() _, _, err := cli.Run("cache", "clean") From c784da74b1168cc918702a0e6e9a335acecab161 Mon Sep 17 00:00:00 2001 From: Cristian Maglie Date: Fri, 7 Oct 2022 15:20:48 +0200 Subject: [PATCH 3/8] Added method to get cli download dir --- internal/integrationtest/arduino-cli.go | 5 +++++ internal/integrationtest/config/config_test.go | 8 ++++---- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/internal/integrationtest/arduino-cli.go b/internal/integrationtest/arduino-cli.go index 721b5841e45..12f8b8d928e 100644 --- a/internal/integrationtest/arduino-cli.go +++ b/internal/integrationtest/arduino-cli.go @@ -137,6 +137,11 @@ func (cli *ArduinoCLI) WorkingDir() *paths.Path { return cli.workingDir } +// DownloadDir returns the download directory +func (cli *ArduinoCLI) DownloadDir() *paths.Path { + return cli.stagingDir +} + // CopySketch copies a sketch inside the testing environment and returns its path func (cli *ArduinoCLI) CopySketch(sketchName string) *paths.Path { p, err := paths.Getwd() diff --git a/internal/integrationtest/config/config_test.go b/internal/integrationtest/config/config_test.go index 4b773969d83..ba395e210ed 100644 --- a/internal/integrationtest/config/config_test.go +++ b/internal/integrationtest/config/config_test.go @@ -50,7 +50,7 @@ func TestInitWithExistingCustomConfig(t *testing.T) { require.Equal(t, config["board_manager"]["additional_urls"].([]interface{})[0].(string), "https://example.com") require.Equal(t, config["daemon"]["port"].(string), "50051") require.Equal(t, config["directories"]["data"].(string), cli.DataDir().String()) - require.Equal(t, config["directories"]["downloads"].(string), env.SharedDownloadsDir().String()) + require.Equal(t, config["directories"]["downloads"].(string), cli.DownloadDir().String()) require.Equal(t, config["directories"]["user"].(string), cli.SketchbookDir().String()) require.Empty(t, config["logging"]["file"]) require.Equal(t, config["logging"]["format"].(string), "text") @@ -71,7 +71,7 @@ func TestInitWithExistingCustomConfig(t *testing.T) { require.Empty(t, config["board_manager"]["additional_urls"]) require.Equal(t, config["daemon"]["port"].(string), "50051") require.Equal(t, config["directories"]["data"].(string), cli.DataDir().String()) - require.Equal(t, config["directories"]["downloads"].(string), env.SharedDownloadsDir().String()) + require.Equal(t, config["directories"]["downloads"].(string), cli.DownloadDir().String()) require.Equal(t, config["directories"]["user"].(string), cli.SketchbookDir().String()) require.Empty(t, config["logging"]["file"]) require.Equal(t, config["logging"]["format"].(string), "text") @@ -96,7 +96,7 @@ func TestInitOverwriteExistingCustomFile(t *testing.T) { require.Equal(t, config["board_manager"]["additional_urls"].([]interface{})[0].(string), "https://example.com") require.Equal(t, config["daemon"]["port"].(string), "50051") require.Equal(t, config["directories"]["data"].(string), cli.DataDir().String()) - require.Equal(t, config["directories"]["downloads"].(string), env.SharedDownloadsDir().String()) + require.Equal(t, config["directories"]["downloads"].(string), cli.DownloadDir().String()) require.Equal(t, config["directories"]["user"].(string), cli.SketchbookDir().String()) require.Empty(t, config["logging"]["file"]) require.Equal(t, config["logging"]["format"].(string), "text") @@ -115,7 +115,7 @@ func TestInitOverwriteExistingCustomFile(t *testing.T) { require.Empty(t, config["board_manager"]["additional_urls"]) require.Equal(t, config["daemon"]["port"].(string), "50051") require.Equal(t, config["directories"]["data"].(string), cli.DataDir().String()) - require.Equal(t, config["directories"]["downloads"].(string), env.SharedDownloadsDir().String()) + require.Equal(t, config["directories"]["downloads"].(string), cli.DownloadDir().String()) require.Equal(t, config["directories"]["user"].(string), cli.SketchbookDir().String()) require.Empty(t, config["logging"]["file"]) require.Equal(t, config["logging"]["format"].(string), "text") From 1048cebd0df94ccb2d42adc96af8c3bf8aa33695 Mon Sep 17 00:00:00 2001 From: Cristian Maglie Date: Fri, 7 Oct 2022 15:38:38 +0200 Subject: [PATCH 4/8] Create infra for sharing directories between tests --- arduino/discovery/discovery_client/go.sum | 1 - client_example/go.sum | 1 - docsgen/go.sum | 1 - go.mod | 5 +- go.sum | 1 + internal/integrationtest/arduino-cli.go | 6 +- internal/integrationtest/environment.go | 13 +--- internal/integrationtest/shared_directory.go | 67 ++++++++++++++++++++ 8 files changed, 80 insertions(+), 15 deletions(-) create mode 100644 internal/integrationtest/shared_directory.go diff --git a/arduino/discovery/discovery_client/go.sum b/arduino/discovery/discovery_client/go.sum index 09c4fe481bc..c9b311020f6 100644 --- a/arduino/discovery/discovery_client/go.sum +++ b/arduino/discovery/discovery_client/go.sum @@ -315,7 +315,6 @@ go.bug.st/relaxed-semver v0.9.0/go.mod h1:ug0/W/RPYUjliE70Ghxg77RDHmPxqpo7SHV16i go.bug.st/serial v1.3.2/go.mod h1:jDkjqASf/qSjmaOxHSHljwUQ6eHo/ZX/bxJLQqSlvZg= go.bug.st/serial.v1 v0.0.0-20180827123349-5f7892a7bb45/go.mod h1:dRSl/CVCTf56CkXgJMDOdSwNfo2g1orOGE/gBGdvjZw= go.bug.st/testifyjson v1.1.1/go.mod h1:nZyy2icFbv3OE3zW3mGVOnC/GhWgb93LRu+29n2tJlI= -go.bug.st/testsuite v0.1.0/go.mod h1:xCIDf97kf9USoz960Foy3CoquwhQmfuFRNh9git70as= go.etcd.io/etcd/api/v3 v3.5.0/go.mod h1:cbVKeC6lCfl7j/8jBhAK6aIYO9XOjdptoxU/nLQcPvs= go.etcd.io/etcd/client/pkg/v3 v3.5.0/go.mod h1:IJHfcCEKxYu1Os13ZdwCwIUTUVGYTSAM3YSwc9/Ac1g= go.etcd.io/etcd/client/v2 v2.305.0/go.mod h1:h9puh54ZTgAKtEbut2oe9P4L/oqKCVB6xsXlzd7alYQ= diff --git a/client_example/go.sum b/client_example/go.sum index 4db2fe0ef52..183613fdabf 100644 --- a/client_example/go.sum +++ b/client_example/go.sum @@ -297,7 +297,6 @@ go.bug.st/relaxed-semver v0.9.0/go.mod h1:ug0/W/RPYUjliE70Ghxg77RDHmPxqpo7SHV16i go.bug.st/serial v1.3.2/go.mod h1:jDkjqASf/qSjmaOxHSHljwUQ6eHo/ZX/bxJLQqSlvZg= go.bug.st/serial.v1 v0.0.0-20180827123349-5f7892a7bb45/go.mod h1:dRSl/CVCTf56CkXgJMDOdSwNfo2g1orOGE/gBGdvjZw= go.bug.st/testifyjson v1.1.1/go.mod h1:nZyy2icFbv3OE3zW3mGVOnC/GhWgb93LRu+29n2tJlI= -go.bug.st/testsuite v0.1.0/go.mod h1:xCIDf97kf9USoz960Foy3CoquwhQmfuFRNh9git70as= go.etcd.io/etcd/api/v3 v3.5.0/go.mod h1:cbVKeC6lCfl7j/8jBhAK6aIYO9XOjdptoxU/nLQcPvs= go.etcd.io/etcd/client/pkg/v3 v3.5.0/go.mod h1:IJHfcCEKxYu1Os13ZdwCwIUTUVGYTSAM3YSwc9/Ac1g= go.etcd.io/etcd/client/v2 v2.305.0/go.mod h1:h9puh54ZTgAKtEbut2oe9P4L/oqKCVB6xsXlzd7alYQ= diff --git a/docsgen/go.sum b/docsgen/go.sum index a6a5f8dac52..39263575145 100644 --- a/docsgen/go.sum +++ b/docsgen/go.sum @@ -373,7 +373,6 @@ go.bug.st/serial v1.3.2/go.mod h1:jDkjqASf/qSjmaOxHSHljwUQ6eHo/ZX/bxJLQqSlvZg= go.bug.st/serial.v1 v0.0.0-20180827123349-5f7892a7bb45 h1:mACY1anK6HNCZtm/DK2Rf2ZPHggVqeB0+7rY9Gl6wyI= go.bug.st/serial.v1 v0.0.0-20180827123349-5f7892a7bb45/go.mod h1:dRSl/CVCTf56CkXgJMDOdSwNfo2g1orOGE/gBGdvjZw= go.bug.st/testifyjson v1.1.1/go.mod h1:nZyy2icFbv3OE3zW3mGVOnC/GhWgb93LRu+29n2tJlI= -go.bug.st/testsuite v0.1.0/go.mod h1:xCIDf97kf9USoz960Foy3CoquwhQmfuFRNh9git70as= go.etcd.io/etcd/api/v3 v3.5.0/go.mod h1:cbVKeC6lCfl7j/8jBhAK6aIYO9XOjdptoxU/nLQcPvs= go.etcd.io/etcd/client/pkg/v3 v3.5.0/go.mod h1:IJHfcCEKxYu1Os13ZdwCwIUTUVGYTSAM3YSwc9/Ac1g= go.etcd.io/etcd/client/v2 v2.305.0/go.mod h1:h9puh54ZTgAKtEbut2oe9P4L/oqKCVB6xsXlzd7alYQ= diff --git a/go.mod b/go.mod index 88efc524700..afcf258f819 100644 --- a/go.mod +++ b/go.mod @@ -57,7 +57,10 @@ require ( gopkg.in/yaml.v2 v2.4.0 ) -require go.bug.st/testifyjson v1.1.1 +require ( + github.com/rogpeppe/go-internal v1.3.0 + go.bug.st/testifyjson v1.1.1 +) require ( github.com/cpuguy83/go-md2man/v2 v2.0.0 // indirect diff --git a/go.sum b/go.sum index fbc748b209c..213b3cee5f4 100644 --- a/go.sum +++ b/go.sum @@ -310,6 +310,7 @@ github.com/rifflock/lfshook v0.0.0-20180920164130-b9218ef580f5/go.mod h1:GEXHk5H github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY= github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= +github.com/rogpeppe/go-internal v1.3.0 h1:RR9dF3JtopPvtkroDZuVD7qquD0bnHlKSqaQhgwt8yk= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/russross/blackfriday/v2 v2.0.1 h1:lPqVAte+HuHNfhJ/0LC98ESWRz8afy9tM/0RK8m9o+Q= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= diff --git a/internal/integrationtest/arduino-cli.go b/internal/integrationtest/arduino-cli.go index 12f8b8d928e..f7ba53601cb 100644 --- a/internal/integrationtest/arduino-cli.go +++ b/internal/integrationtest/arduino-cli.go @@ -100,7 +100,11 @@ func NewArduinoCliWithinEnvironment(env *Environment, config *ArduinoCLIConfig) workingDir: env.RootDir(), } if config.UseSharedStagingFolder { - cli.stagingDir = env.SharedDownloadsDir() + sharedDir := env.SharedDownloadsDir() + cli.stagingDir = sharedDir.Lock() + env.RegisterCleanUpCallback(func() { + sharedDir.Unlock() + }) } cli.cliEnvVars = map[string]string{ diff --git a/internal/integrationtest/environment.go b/internal/integrationtest/environment.go index 4171ad2ba3e..7607dcf1570 100644 --- a/internal/integrationtest/environment.go +++ b/internal/integrationtest/environment.go @@ -28,21 +28,14 @@ var ProjectName = "cli" // Environment is a test environment for the test suite. type Environment struct { rootDir *paths.Path - downloadsDir *paths.Path + downloadsDir *SharedDir t *testing.T cleanUp func() } -// SharedDir returns the shared downloads directory. -func SharedDir(t *testing.T, id string) *paths.Path { - downloadsDir := paths.TempDir().Join(ProjectName + "-" + id) - require.NoError(t, downloadsDir.MkdirAll()) - return downloadsDir -} - // NewEnvironment creates a new test environment. func NewEnvironment(t *testing.T) *Environment { - downloadsDir := SharedDir(t, "downloads") + downloadsDir := NewSharedDir(t, "downloads") rootDir, err := paths.MkTempDir("", ProjectName) require.NoError(t, err) return &Environment{ @@ -75,7 +68,7 @@ func (e *Environment) RootDir() *paths.Path { } // SharedDownloadsDir return the shared directory for downloads -func (e *Environment) SharedDownloadsDir() *paths.Path { +func (e *Environment) SharedDownloadsDir() *SharedDir { return e.downloadsDir } diff --git a/internal/integrationtest/shared_directory.go b/internal/integrationtest/shared_directory.go new file mode 100644 index 00000000000..3ebad74a183 --- /dev/null +++ b/internal/integrationtest/shared_directory.go @@ -0,0 +1,67 @@ +// 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 integrationtest + +import ( + "sync" + "testing" + + "github.com/arduino/go-paths-helper" + "github.com/rogpeppe/go-internal/lockedfile" + "github.com/stretchr/testify/require" +) + +// SharedDir is a directory that is shared between multiple tests. +type SharedDir struct { + dir *paths.Path + t *testing.T + mux sync.Mutex + fileLock *lockedfile.File +} + +// Lock locks the shared directory for exclusive access and return the path to the directory. +func (d *SharedDir) Lock() *paths.Path { + d.mux.Lock() + defer d.mux.Unlock() + if d.fileLock != nil { + panic("SharedDir already locked") + } + fileLock, err := lockedfile.Create(d.dir.Join(".lock").String()) + require.NoError(d.t, err) + d.fileLock = fileLock + return d.dir +} + +// Unlock unlocks the shared directory. +func (d *SharedDir) Unlock() { + d.mux.Lock() + defer d.mux.Unlock() + if d.fileLock == nil { + panic("SharedDir already unlocked") + } + require.NoError(d.t, d.fileLock.Close()) + d.fileLock = nil +} + +// NewSharedDir creates a new shared directory. +func NewSharedDir(t *testing.T, id string) *SharedDir { + dir := paths.TempDir().Join(ProjectName + "-" + id) + require.NoError(t, dir.MkdirAll()) + return &SharedDir{ + dir: dir, + t: t, + } +} From 8c7a08a0b94e60bfb4785266a1c7e8a0f5790f3a Mon Sep 17 00:00:00 2001 From: Cristian Maglie Date: Fri, 7 Oct 2022 15:38:56 +0200 Subject: [PATCH 5/8] Slighlty improved test output --- internal/integrationtest/main/main_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/integrationtest/main/main_test.go b/internal/integrationtest/main/main_test.go index 376501924dc..c2b94fc1a4b 100644 --- a/internal/integrationtest/main/main_test.go +++ b/internal/integrationtest/main/main_test.go @@ -46,7 +46,7 @@ func TestVersion(t *testing.T) { require.NoError(t, err) require.Contains(t, string(stdout), "Version:") require.Contains(t, string(stdout), "Commit:") - require.Empty(t, stderr) + require.Empty(t, string(stderr)) // Checks if "version --format json" has a json as an output stdout, _, err = cli.Run("version", "--format", "json") From 0c8938e8ecaf0e3d612ed53aa166087cf56868d3 Mon Sep 17 00:00:00 2001 From: Cristian Maglie Date: Fri, 7 Oct 2022 15:39:43 +0200 Subject: [PATCH 6/8] Non-parallel testing is no longer required --- Taskfile.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/Taskfile.yml b/Taskfile.yml index 786fe627e7e..8aa4ac4fe1c 100755 --- a/Taskfile.yml +++ b/Taskfile.yml @@ -95,12 +95,10 @@ tasks: - task: go:build dir: '{{default "./" .GO_MODULE_PATH}}' cmds: - # "-p 1" will not run test in parallel, this is required for integration tests - | go test \ -v \ -short \ - -p 1 \ -run '{{default ".*" .GO_TEST_REGEX}}' \ {{default "-timeout 15m -coverpkg=./... -covermode=atomic" .GO_TEST_FLAGS}} \ -coverprofile=coverage_unit.txt \ From 1cb8d07937f64fef59248c45262d19a0cfcad801 Mon Sep 17 00:00:00 2001 From: Cristian Maglie Date: Fri, 7 Oct 2022 16:18:17 +0200 Subject: [PATCH 7/8] Add more time to complete tests --- Taskfile.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Taskfile.yml b/Taskfile.yml index 8aa4ac4fe1c..9d24febc3b1 100755 --- a/Taskfile.yml +++ b/Taskfile.yml @@ -100,7 +100,7 @@ tasks: -v \ -short \ -run '{{default ".*" .GO_TEST_REGEX}}' \ - {{default "-timeout 15m -coverpkg=./... -covermode=atomic" .GO_TEST_FLAGS}} \ + {{default "-timeout 20m -coverpkg=./... -covermode=atomic" .GO_TEST_FLAGS}} \ -coverprofile=coverage_unit.txt \ {{default .DEFAULT_GO_PACKAGES .GO_PACKAGES}} \ {{.TEST_LDFLAGS}} From 77094fad77931a321a4d1981824d1b08e7068f3b Mon Sep 17 00:00:00 2001 From: Cristian Maglie Date: Mon, 10 Oct 2022 12:25:32 +0200 Subject: [PATCH 8/8] Update internal/integrationtest/cache/cache_test.go Co-authored-by: MatteoPologruto <109663225+MatteoPologruto@users.noreply.github.com> --- internal/integrationtest/cache/cache_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/integrationtest/cache/cache_test.go b/internal/integrationtest/cache/cache_test.go index 7ad7fe6dc4b..49e94736981 100644 --- a/internal/integrationtest/cache/cache_test.go +++ b/internal/integrationtest/cache/cache_test.go @@ -23,7 +23,7 @@ import ( ) func TestCacheClean(t *testing.T) { - // This test do not use shared download directory becuase it will be cleaned up with 'cache clean' command + // This test should not use shared download directory because it will be cleaned up with 'cache clean' command env := integrationtest.NewEnvironment(t) cli := integrationtest.NewArduinoCliWithinEnvironment(env, &integrationtest.ArduinoCLIConfig{ ArduinoCLIPath: integrationtest.FindArduinoCLIPath(t),