From 68ad6501c5583ffa072b09e641eb000527a202b6 Mon Sep 17 00:00:00 2001 From: dido18 Date: Tue, 4 Nov 2025 16:22:09 +0100 Subject: [PATCH 01/20] fix(bricks): overwrite the variables of an app --- internal/orchestrator/bricks/bricks.go | 1 - internal/orchestrator/bricks/bricks_test.go | 56 +++++++++++++++++++ .../bricks/testdata/bricks-list.yaml | 15 +++++ .../bricks/testdata/my-app/app.yaml | 9 +++ .../bricks/testdata/my-app/python/main.py | 2 + 5 files changed, 82 insertions(+), 1 deletion(-) create mode 100644 internal/orchestrator/bricks/bricks_test.go create mode 100644 internal/orchestrator/bricks/testdata/bricks-list.yaml create mode 100644 internal/orchestrator/bricks/testdata/my-app/app.yaml create mode 100644 internal/orchestrator/bricks/testdata/my-app/python/main.py diff --git a/internal/orchestrator/bricks/bricks.go b/internal/orchestrator/bricks/bricks.go index 4e08b2c2..628a0da6 100644 --- a/internal/orchestrator/bricks/bricks.go +++ b/internal/orchestrator/bricks/bricks.go @@ -204,7 +204,6 @@ func (s *Service) BrickCreate( if _, exist := req.Variables[brickVar.Name]; !exist { return errors.New("variable does not exist") } - return errors.New("variable default value cannot be empty") } } diff --git a/internal/orchestrator/bricks/bricks_test.go b/internal/orchestrator/bricks/bricks_test.go new file mode 100644 index 00000000..77ca9d01 --- /dev/null +++ b/internal/orchestrator/bricks/bricks_test.go @@ -0,0 +1,56 @@ +// This file is part of arduino-app-cli. +// +// Copyright 2025 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-app-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 bricks + +import ( + "fmt" + "math/rand" + "testing" + + "github.com/stretchr/testify/require" + "go.bug.st/f" + + "github.com/arduino/arduino-app-cli/internal/orchestrator/app" + "github.com/arduino/arduino-app-cli/internal/orchestrator/bricksindex" + "github.com/arduino/go-paths-helper" +) + +func TestOverrideBrickVariablesOfApp(t *testing.T) { + bricksIndex, err := bricksindex.GenerateBricksIndexFromFile(paths.New("testdata")) + require.Nil(t, err) + brickService := NewService(nil, bricksIndex, nil) + + deviceID := fmt.Sprintf("my-device-id-%x", rand.Int()) + secret := fmt.Sprintf("my-device-secret-%x", rand.Int()) + + req := BrickCreateUpdateRequest{ + ID: "arduino:arduino_cloud", + Variables: map[string]string{ + "ARDUINO_DEVICE_ID": deviceID, + "ARDUINO_SECRET": secret, + }, + } + + err = brickService.BrickCreate(req, f.Must(app.Load("./testdata/my-app"))) + require.Nil(t, err) + + after, err := app.Load("./testdata/my-app") + require.Nil(t, err) + require.Len(t, after.Descriptor.Bricks, 1) + require.Equal(t, "arduino:arduino_cloud", after.Descriptor.Bricks[0].ID) + require.Equal(t, deviceID, after.Descriptor.Bricks[0].Variables["ARDUINO_DEVICE_ID"]) + require.Equal(t, secret, after.Descriptor.Bricks[0].Variables["ARDUINO_SECRET"]) +} diff --git a/internal/orchestrator/bricks/testdata/bricks-list.yaml b/internal/orchestrator/bricks/testdata/bricks-list.yaml new file mode 100644 index 00000000..1cccaa17 --- /dev/null +++ b/internal/orchestrator/bricks/testdata/bricks-list.yaml @@ -0,0 +1,15 @@ +bricks: +- id: arduino:arduino_cloud + name: Arduino Cloud + description: Connects to Arduino Cloud + require_container: false + require_model: false + require_devices: false + mount_devices_into_container: false + ports: [] + category: null + variables: + - name: ARDUINO_DEVICE_ID + description: Arduino Cloud Device ID + - name: ARDUINO_SECRET + description: Arduino Cloud Secret diff --git a/internal/orchestrator/bricks/testdata/my-app/app.yaml b/internal/orchestrator/bricks/testdata/my-app/app.yaml new file mode 100644 index 00000000..e1f6202c --- /dev/null +++ b/internal/orchestrator/bricks/testdata/my-app/app.yaml @@ -0,0 +1,9 @@ +name: Copy of Blinking LED from Arduino Cloud +description: Control the LED from the Arduino IoT Cloud using RPC calls +ports: [] +bricks: +- arduino:arduino_cloud: + variables: + ARDUINO_DEVICE_ID: my-device-id-79c4b05ef7b6a39 + ARDUINO_SECRET: my-device-secret-43f4a190b1ffb8ce +icon: ☁️ diff --git a/internal/orchestrator/bricks/testdata/my-app/python/main.py b/internal/orchestrator/bricks/testdata/my-app/python/main.py new file mode 100644 index 00000000..a6e3f970 --- /dev/null +++ b/internal/orchestrator/bricks/testdata/my-app/python/main.py @@ -0,0 +1,2 @@ +def main(): + # empty file From d1e01fe444c3d39ce685773c84089d1a2d94fde1 Mon Sep 17 00:00:00 2001 From: dido18 Date: Tue, 4 Nov 2025 17:08:42 +0100 Subject: [PATCH 02/20] feat(bricks): enhance error messages and add tests for BrickCreate functionality --- go.mod | 5 +- go.sum | 6 +++ internal/orchestrator/bricks/bricks.go | 13 ++--- internal/orchestrator/bricks/bricks_test.go | 48 +++++++++++++++++++ .../bricks/testdata/bricks-list.yaml | 10 ++++ .../bricks/testdata/my-app/app.yaml | 1 + 6 files changed, 72 insertions(+), 11 deletions(-) diff --git a/go.mod b/go.mod index be40aceb..083d8282 100644 --- a/go.mod +++ b/go.mod @@ -129,7 +129,7 @@ require ( github.com/fsnotify/fsnotify v1.9.0 // indirect github.com/fvbommel/sortorder v1.1.0 // indirect github.com/fxamacker/cbor/v2 v2.7.0 // indirect - github.com/getkin/kin-openapi v0.132.0 // indirect + github.com/getkin/kin-openapi v0.133.0 // indirect github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect github.com/go-git/go-billy/v5 v5.6.2 // indirect github.com/go-git/go-git/v5 v5.16.2 // indirect @@ -206,7 +206,7 @@ require ( github.com/morikuni/aec v1.0.0 // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f // indirect - github.com/oapi-codegen/oapi-codegen/v2 v2.5.0 // indirect + github.com/oapi-codegen/oapi-codegen/v2 v2.5.1 // indirect github.com/oasdiff/yaml v0.0.0-20250309154309-f31be36b4037 // indirect github.com/oasdiff/yaml3 v0.0.0-20250309153720-d2182401db90 // indirect github.com/opencontainers/go-digest v1.0.0 // indirect @@ -257,6 +257,7 @@ require ( github.com/ulikunitz/xz v0.5.15 // indirect github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect github.com/vmware-labs/yaml-jsonpath v0.3.2 // indirect + github.com/woodsbury/decimal128 v1.3.0 // indirect github.com/x448/float16 v0.8.4 // indirect github.com/xanzy/ssh-agent v0.3.3 // indirect github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb // indirect diff --git a/go.sum b/go.sum index 98b1009f..11b23f35 100644 --- a/go.sum +++ b/go.sum @@ -312,6 +312,8 @@ github.com/fxamacker/cbor/v2 v2.7.0 h1:iM5WgngdRBanHcxugY4JySA0nk1wZorNOpTgCMedv github.com/fxamacker/cbor/v2 v2.7.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXEeXQVeNoDQ= github.com/getkin/kin-openapi v0.132.0 h1:3ISeLMsQzcb5v26yeJrBcdTCEQTag36ZjaGk7MIRUwk= github.com/getkin/kin-openapi v0.132.0/go.mod h1:3OlG51PCYNsPByuiMB0t4fjnNlIDnaEDsjiKUV8nL58= +github.com/getkin/kin-openapi v0.133.0 h1:pJdmNohVIJ97r4AUFtEXRXwESr8b0bD721u/Tz6k8PQ= +github.com/getkin/kin-openapi v0.133.0/go.mod h1:boAciF6cXk5FhPqe/NQeBTeenbjqU4LhWBf09ILVvWE= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/gliderlabs/ssh v0.3.8 h1:a4YXD1V7xMF9g5nTkdfnja3Sxy1PVDCj1Zg4Wb8vY6c= github.com/gliderlabs/ssh v0.3.8/go.mod h1:xYoytBv1sV0aL3CavoDuJIQNURXkkfPA/wxQ1pL1fAU= @@ -678,6 +680,8 @@ github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= github.com/oapi-codegen/oapi-codegen/v2 v2.5.0 h1:iJvF8SdB/3/+eGOXEpsWkD8FQAHj6mqkb6Fnsoc8MFU= github.com/oapi-codegen/oapi-codegen/v2 v2.5.0/go.mod h1:fwlMxUEMuQK5ih9aymrxKPQqNm2n8bdLk1ppjH+lr9w= +github.com/oapi-codegen/oapi-codegen/v2 v2.5.1 h1:5vHNY1uuPBRBWqB2Dp0G7YB03phxLQZupZTIZaeorjc= +github.com/oapi-codegen/oapi-codegen/v2 v2.5.1/go.mod h1:ro0npU1BWkcGpCgGD9QwPp44l5OIZ94tB3eabnT7DjQ= github.com/oapi-codegen/runtime v1.1.1 h1:EXLHh0DXIJnWhdRPN2w4MXAzFyE4CskzhNLUmtpMYro= github.com/oapi-codegen/runtime v1.1.1/go.mod h1:SK9X900oXmPWilYR5/WKPzt3Kqxn/uS/+lbpREv+eCg= github.com/oasdiff/yaml v0.0.0-20250309154309-f31be36b4037 h1:G7ERwszslrBzRxj//JalHPu/3yz+De2J+4aLtSRlHiY= @@ -909,6 +913,8 @@ github.com/warthog618/go-gpiocdev v0.9.1 h1:pwHPaqjJfhCipIQl78V+O3l9OKHivdRDdmgX github.com/warthog618/go-gpiocdev v0.9.1/go.mod h1:dN3e3t/S2aSNC+hgigGE/dBW8jE1ONk9bDSEYfoPyl8= github.com/warthog618/go-gpiosim v0.1.1 h1:MRAEv+T+itmw+3GeIGpQJBfanUVyg0l3JCTwHtwdre4= github.com/warthog618/go-gpiosim v0.1.1/go.mod h1:YXsnB+I9jdCMY4YAlMSRrlts25ltjmuIsrnoUrBLdqU= +github.com/woodsbury/decimal128 v1.3.0 h1:8pffMNWIlC0O5vbyHWFZAt5yWvWcrHA+3ovIIjVWss0= +github.com/woodsbury/decimal128 v1.3.0/go.mod h1:C5UTmyTjW3JftjUFzOVhC20BEQa2a4ZKOB5I6Zjb+ds= github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM= github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg= github.com/xanzy/ssh-agent v0.3.3 h1:+/15pJfg/RsTxqYcX6fHqOXZwwMP+2VyYWJeWM2qQFM= diff --git a/internal/orchestrator/bricks/bricks.go b/internal/orchestrator/bricks/bricks.go index 628a0da6..27386185 100644 --- a/internal/orchestrator/bricks/bricks.go +++ b/internal/orchestrator/bricks/bricks.go @@ -186,23 +186,23 @@ func (s *Service) BrickCreate( ) error { brick, present := s.bricksIndex.FindBrickByID(req.ID) if !present { - return fmt.Errorf("brick not found with id %s", req.ID) + return fmt.Errorf("brick '%s' not found", req.ID) } for name, reqValue := range req.Variables { value, exist := brick.GetVariable(name) if !exist { - return errors.New("variable does not exist") + return fmt.Errorf("variable '%s' does not exist on brick '%s'", name, brick.ID) } if value.DefaultValue == "" && reqValue == "" { - return errors.New("variable default value cannot be empty") + return fmt.Errorf("variable '%s' cannot be empty", name) } } for _, brickVar := range brick.Variables { if brickVar.DefaultValue == "" { if _, exist := req.Variables[brickVar.Name]; !exist { - return errors.New("variable does not exist") + return fmt.Errorf("required variable '%s' is mandatory", brickVar.Name) } } } @@ -226,25 +226,20 @@ func (s *Service) BrickCreate( if idx == -1 { return fmt.Errorf("model %s does not exsist", *req.Model) } - brickInstance.Model = models[idx].ID } brickInstance.Variables = req.Variables if brickIndex == -1 { - appCurrent.Descriptor.Bricks = append(appCurrent.Descriptor.Bricks, brickInstance) - } else { appCurrent.Descriptor.Bricks[brickIndex] = brickInstance - } err := appCurrent.Save() if err != nil { return fmt.Errorf("cannot save brick instance with id %s", req.ID) } - return nil } diff --git a/internal/orchestrator/bricks/bricks_test.go b/internal/orchestrator/bricks/bricks_test.go index 77ca9d01..e49d6b38 100644 --- a/internal/orchestrator/bricks/bricks_test.go +++ b/internal/orchestrator/bricks/bricks_test.go @@ -28,6 +28,54 @@ import ( "github.com/arduino/go-paths-helper" ) +func TestBrickCreate(t *testing.T) { + bricksIndex, err := bricksindex.GenerateBricksIndexFromFile(paths.New("testdata")) + require.Nil(t, err) + brickService := NewService(nil, bricksIndex, nil) + + t.Run("fails if brick id does not exist", func(t *testing.T) { + err = brickService.BrickCreate(BrickCreateUpdateRequest{ID: "not-existing-id"}, f.Must(app.Load("./testdata/my-app"))) + require.Error(t, err) + require.Equal(t, "brick 'not-existing-id' not found", err.Error()) + }) + + t.Run("fails if the requestes variable is not present in the brick definition", func(t *testing.T) { + req := BrickCreateUpdateRequest{ID: "arduino:arduino_cloud", Variables: map[string]string{ + "NON_EXISTING_VARIABLE": "some-value", + }} + err = brickService.BrickCreate(req, f.Must(app.Load("./testdata/my-app"))) + require.Error(t, err) + require.Equal(t, "variable 'NON_EXISTING_VARIABLE' does not exist on brick 'arduino:arduino_cloud'", err.Error()) + }) + + t.Run("fails if a required variable is set empty", func(t *testing.T) { + req := BrickCreateUpdateRequest{ID: "arduino:arduino_cloud", Variables: map[string]string{ + "ARDUINO_DEVICE_ID": "", + "ARDUINO_SECRET": "a-secret-a", + }} + err = brickService.BrickCreate(req, f.Must(app.Load("./testdata/my-app"))) + require.Error(t, err) + require.Equal(t, "variable 'ARDUINO_DEVICE_ID' cannot be empty", err.Error()) + }) + + t.Run("fails if a mandatory variable is not present in the request", func(t *testing.T) { + req := BrickCreateUpdateRequest{ID: "arduino:arduino_cloud", Variables: map[string]string{ + "ARDUINO_SECRET": "a-secret-a", + }} + err = brickService.BrickCreate(req, f.Must(app.Load("./testdata/my-app"))) + require.Error(t, err) + require.Equal(t, "required variable 'ARDUINO_DEVICE_ID' is mandatory", err.Error()) + }) + + t.Run("the brick is added if it does not exist in the app", func(t *testing.T) { + req := BrickCreateUpdateRequest{ID: "arduino:dbstorage_sqlstore"} + // TODO: find a better way to test if the brick has been added to the app.yaml + // Currently we only check that there is no error since the app.yaml is populated with the brick at every test execution. + err = brickService.BrickCreate(req, f.Must(app.Load("./testdata/my-app"))) + require.Nil(t, err) + }) +} + func TestOverrideBrickVariablesOfApp(t *testing.T) { bricksIndex, err := bricksindex.GenerateBricksIndexFromFile(paths.New("testdata")) require.Nil(t, err) diff --git a/internal/orchestrator/bricks/testdata/bricks-list.yaml b/internal/orchestrator/bricks/testdata/bricks-list.yaml index 1cccaa17..8e3114d6 100644 --- a/internal/orchestrator/bricks/testdata/bricks-list.yaml +++ b/internal/orchestrator/bricks/testdata/bricks-list.yaml @@ -13,3 +13,13 @@ bricks: description: Arduino Cloud Device ID - name: ARDUINO_SECRET description: Arduino Cloud Secret +- id: arduino:dbstorage_sqlstore + name: Database - SQL + description: Simplified database storage layer for Arduino sensor data using SQLite + local database. + require_container: false + require_model: false + require_devices: false + mount_devices_into_container: false + ports: [] + category: storage diff --git a/internal/orchestrator/bricks/testdata/my-app/app.yaml b/internal/orchestrator/bricks/testdata/my-app/app.yaml index e1f6202c..5cbcef26 100644 --- a/internal/orchestrator/bricks/testdata/my-app/app.yaml +++ b/internal/orchestrator/bricks/testdata/my-app/app.yaml @@ -6,4 +6,5 @@ bricks: variables: ARDUINO_DEVICE_ID: my-device-id-79c4b05ef7b6a39 ARDUINO_SECRET: my-device-secret-43f4a190b1ffb8ce +- arduino:dbstorage_sqlstore: {} icon: ☁️ From c5799986b3cbd15fcfb748a1e470a7af977d887a Mon Sep 17 00:00:00 2001 From: dido18 Date: Wed, 5 Nov 2025 14:37:58 +0100 Subject: [PATCH 03/20] feat(tests): update BrickCreate tests and add dummy app configurations --- internal/orchestrator/bricks/bricks_test.go | 25 +++++++++++-------- .../orchestrator/bricks/testdata/.gitignore | 1 + .../testdata/{my-app => dummy-app}/app.yaml | 0 .../{my-app => dummy-app}/python/main.py | 0 .../bricks/testdata/my-app.override/app.yaml | 9 +++++++ .../testdata/my-app.override/python/main.py | 2 ++ .../bricks/testdata/my-app.source/app.yaml | 6 +++++ .../testdata/my-app.source/python/main.py | 2 ++ 8 files changed, 34 insertions(+), 11 deletions(-) create mode 100644 internal/orchestrator/bricks/testdata/.gitignore rename internal/orchestrator/bricks/testdata/{my-app => dummy-app}/app.yaml (100%) rename internal/orchestrator/bricks/testdata/{my-app => dummy-app}/python/main.py (100%) create mode 100644 internal/orchestrator/bricks/testdata/my-app.override/app.yaml create mode 100644 internal/orchestrator/bricks/testdata/my-app.override/python/main.py create mode 100644 internal/orchestrator/bricks/testdata/my-app.source/app.yaml create mode 100644 internal/orchestrator/bricks/testdata/my-app.source/python/main.py diff --git a/internal/orchestrator/bricks/bricks_test.go b/internal/orchestrator/bricks/bricks_test.go index e49d6b38..70dc7d9a 100644 --- a/internal/orchestrator/bricks/bricks_test.go +++ b/internal/orchestrator/bricks/bricks_test.go @@ -16,8 +16,6 @@ package bricks import ( - "fmt" - "math/rand" "testing" "github.com/stretchr/testify/require" @@ -34,7 +32,7 @@ func TestBrickCreate(t *testing.T) { brickService := NewService(nil, bricksIndex, nil) t.Run("fails if brick id does not exist", func(t *testing.T) { - err = brickService.BrickCreate(BrickCreateUpdateRequest{ID: "not-existing-id"}, f.Must(app.Load("./testdata/my-app"))) + err = brickService.BrickCreate(BrickCreateUpdateRequest{ID: "not-existing-id"}, f.Must(app.Load("testdata/dummy-app"))) require.Error(t, err) require.Equal(t, "brick 'not-existing-id' not found", err.Error()) }) @@ -43,7 +41,7 @@ func TestBrickCreate(t *testing.T) { req := BrickCreateUpdateRequest{ID: "arduino:arduino_cloud", Variables: map[string]string{ "NON_EXISTING_VARIABLE": "some-value", }} - err = brickService.BrickCreate(req, f.Must(app.Load("./testdata/my-app"))) + err = brickService.BrickCreate(req, f.Must(app.Load("testdata/dummy-app"))) require.Error(t, err) require.Equal(t, "variable 'NON_EXISTING_VARIABLE' does not exist on brick 'arduino:arduino_cloud'", err.Error()) }) @@ -53,7 +51,7 @@ func TestBrickCreate(t *testing.T) { "ARDUINO_DEVICE_ID": "", "ARDUINO_SECRET": "a-secret-a", }} - err = brickService.BrickCreate(req, f.Must(app.Load("./testdata/my-app"))) + err = brickService.BrickCreate(req, f.Must(app.Load("testdata/dummy-app"))) require.Error(t, err) require.Equal(t, "variable 'ARDUINO_DEVICE_ID' cannot be empty", err.Error()) }) @@ -62,7 +60,7 @@ func TestBrickCreate(t *testing.T) { req := BrickCreateUpdateRequest{ID: "arduino:arduino_cloud", Variables: map[string]string{ "ARDUINO_SECRET": "a-secret-a", }} - err = brickService.BrickCreate(req, f.Must(app.Load("./testdata/my-app"))) + err = brickService.BrickCreate(req, f.Must(app.Load("testdata/dummy-app"))) require.Error(t, err) require.Equal(t, "required variable 'ARDUINO_DEVICE_ID' is mandatory", err.Error()) }) @@ -71,18 +69,23 @@ func TestBrickCreate(t *testing.T) { req := BrickCreateUpdateRequest{ID: "arduino:dbstorage_sqlstore"} // TODO: find a better way to test if the brick has been added to the app.yaml // Currently we only check that there is no error since the app.yaml is populated with the brick at every test execution. - err = brickService.BrickCreate(req, f.Must(app.Load("./testdata/my-app"))) + err = brickService.BrickCreate(req, f.Must(app.Load("testdata/dummy-app"))) require.Nil(t, err) }) } func TestOverrideBrickVariablesOfApp(t *testing.T) { + appWithOverride := paths.New("testdata/my-app.override") + appWithOverride.RemoveAll() + + err := paths.New("testdata/my-app.source").CopyDirTo(appWithOverride) + require.Nil(t, err) bricksIndex, err := bricksindex.GenerateBricksIndexFromFile(paths.New("testdata")) require.Nil(t, err) brickService := NewService(nil, bricksIndex, nil) - deviceID := fmt.Sprintf("my-device-id-%x", rand.Int()) - secret := fmt.Sprintf("my-device-secret-%x", rand.Int()) + deviceID := "this-is-a-device-id" + secret := "this-is-a-secret" req := BrickCreateUpdateRequest{ ID: "arduino:arduino_cloud", @@ -92,10 +95,10 @@ func TestOverrideBrickVariablesOfApp(t *testing.T) { }, } - err = brickService.BrickCreate(req, f.Must(app.Load("./testdata/my-app"))) + err = brickService.BrickCreate(req, f.Must(app.Load("testdata/my-app.override"))) require.Nil(t, err) - after, err := app.Load("./testdata/my-app") + after, err := app.Load("testdata/my-app.override") require.Nil(t, err) require.Len(t, after.Descriptor.Bricks, 1) require.Equal(t, "arduino:arduino_cloud", after.Descriptor.Bricks[0].ID) diff --git a/internal/orchestrator/bricks/testdata/.gitignore b/internal/orchestrator/bricks/testdata/.gitignore new file mode 100644 index 00000000..a3d0b3ac --- /dev/null +++ b/internal/orchestrator/bricks/testdata/.gitignore @@ -0,0 +1 @@ +my-app.override/ diff --git a/internal/orchestrator/bricks/testdata/my-app/app.yaml b/internal/orchestrator/bricks/testdata/dummy-app/app.yaml similarity index 100% rename from internal/orchestrator/bricks/testdata/my-app/app.yaml rename to internal/orchestrator/bricks/testdata/dummy-app/app.yaml diff --git a/internal/orchestrator/bricks/testdata/my-app/python/main.py b/internal/orchestrator/bricks/testdata/dummy-app/python/main.py similarity index 100% rename from internal/orchestrator/bricks/testdata/my-app/python/main.py rename to internal/orchestrator/bricks/testdata/dummy-app/python/main.py diff --git a/internal/orchestrator/bricks/testdata/my-app.override/app.yaml b/internal/orchestrator/bricks/testdata/my-app.override/app.yaml new file mode 100644 index 00000000..c9d9dd67 --- /dev/null +++ b/internal/orchestrator/bricks/testdata/my-app.override/app.yaml @@ -0,0 +1,9 @@ +name: Copy of Blinking LED from Arduino Cloud +description: Control the LED from the Arduino IoT Cloud using RPC calls +ports: [] +bricks: +- arduino:arduino_cloud: + variables: + ARDUINO_DEVICE_ID: this-is-a-device-id + ARDUINO_SECRET: this-is-a-secret +icon: ☁️ diff --git a/internal/orchestrator/bricks/testdata/my-app.override/python/main.py b/internal/orchestrator/bricks/testdata/my-app.override/python/main.py new file mode 100644 index 00000000..a6e3f970 --- /dev/null +++ b/internal/orchestrator/bricks/testdata/my-app.override/python/main.py @@ -0,0 +1,2 @@ +def main(): + # empty file diff --git a/internal/orchestrator/bricks/testdata/my-app.source/app.yaml b/internal/orchestrator/bricks/testdata/my-app.source/app.yaml new file mode 100644 index 00000000..06322d99 --- /dev/null +++ b/internal/orchestrator/bricks/testdata/my-app.source/app.yaml @@ -0,0 +1,6 @@ +name: Copy of Blinking LED from Arduino Cloud +description: Control the LED from the Arduino IoT Cloud using RPC calls +ports: [] +bricks: +- arduino:arduino_cloud: +icon: ☁️ diff --git a/internal/orchestrator/bricks/testdata/my-app.source/python/main.py b/internal/orchestrator/bricks/testdata/my-app.source/python/main.py new file mode 100644 index 00000000..a6e3f970 --- /dev/null +++ b/internal/orchestrator/bricks/testdata/my-app.source/python/main.py @@ -0,0 +1,2 @@ +def main(): + # empty file From 34b6e0e25522ce0420d57634b09cbd01a814e98b Mon Sep 17 00:00:00 2001 From: dido18 Date: Wed, 5 Nov 2025 14:41:03 +0100 Subject: [PATCH 04/20] fix(tests): correct error handling in TestOverrideBrickVariablesOfApp --- internal/orchestrator/bricks/bricks_test.go | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/internal/orchestrator/bricks/bricks_test.go b/internal/orchestrator/bricks/bricks_test.go index 70dc7d9a..27d58b7a 100644 --- a/internal/orchestrator/bricks/bricks_test.go +++ b/internal/orchestrator/bricks/bricks_test.go @@ -21,9 +21,10 @@ import ( "github.com/stretchr/testify/require" "go.bug.st/f" + "github.com/arduino/go-paths-helper" + "github.com/arduino/arduino-app-cli/internal/orchestrator/app" "github.com/arduino/arduino-app-cli/internal/orchestrator/bricksindex" - "github.com/arduino/go-paths-helper" ) func TestBrickCreate(t *testing.T) { @@ -76,9 +77,10 @@ func TestBrickCreate(t *testing.T) { func TestOverrideBrickVariablesOfApp(t *testing.T) { appWithOverride := paths.New("testdata/my-app.override") - appWithOverride.RemoveAll() + err := appWithOverride.RemoveAll() + require.Nil(t, err) - err := paths.New("testdata/my-app.source").CopyDirTo(appWithOverride) + err = paths.New("testdata/my-app.source").CopyDirTo(appWithOverride) require.Nil(t, err) bricksIndex, err := bricksindex.GenerateBricksIndexFromFile(paths.New("testdata")) require.Nil(t, err) From 190f0792bc9ec2225a65e3ea04365969f24c2117 Mon Sep 17 00:00:00 2001 From: dido18 Date: Wed, 5 Nov 2025 15:07:55 +0100 Subject: [PATCH 05/20] fix(go.sum): remove outdated dependencies for kin-openapi and oapi-codegen --- go.sum | 4 ---- 1 file changed, 4 deletions(-) diff --git a/go.sum b/go.sum index 11b23f35..1f1f015e 100644 --- a/go.sum +++ b/go.sum @@ -310,8 +310,6 @@ github.com/fvbommel/sortorder v1.1.0 h1:fUmoe+HLsBTctBDoaBwpQo5N+nrCp8g/BjKb/6ZQ github.com/fvbommel/sortorder v1.1.0/go.mod h1:uk88iVf1ovNn1iLfgUVU2F9o5eO30ui720w+kxuqRs0= github.com/fxamacker/cbor/v2 v2.7.0 h1:iM5WgngdRBanHcxugY4JySA0nk1wZorNOpTgCMedv5E= github.com/fxamacker/cbor/v2 v2.7.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXEeXQVeNoDQ= -github.com/getkin/kin-openapi v0.132.0 h1:3ISeLMsQzcb5v26yeJrBcdTCEQTag36ZjaGk7MIRUwk= -github.com/getkin/kin-openapi v0.132.0/go.mod h1:3OlG51PCYNsPByuiMB0t4fjnNlIDnaEDsjiKUV8nL58= github.com/getkin/kin-openapi v0.133.0 h1:pJdmNohVIJ97r4AUFtEXRXwESr8b0bD721u/Tz6k8PQ= github.com/getkin/kin-openapi v0.133.0/go.mod h1:boAciF6cXk5FhPqe/NQeBTeenbjqU4LhWBf09ILVvWE= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= @@ -678,8 +676,6 @@ github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLA github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= -github.com/oapi-codegen/oapi-codegen/v2 v2.5.0 h1:iJvF8SdB/3/+eGOXEpsWkD8FQAHj6mqkb6Fnsoc8MFU= -github.com/oapi-codegen/oapi-codegen/v2 v2.5.0/go.mod h1:fwlMxUEMuQK5ih9aymrxKPQqNm2n8bdLk1ppjH+lr9w= github.com/oapi-codegen/oapi-codegen/v2 v2.5.1 h1:5vHNY1uuPBRBWqB2Dp0G7YB03phxLQZupZTIZaeorjc= github.com/oapi-codegen/oapi-codegen/v2 v2.5.1/go.mod h1:ro0npU1BWkcGpCgGD9QwPp44l5OIZ94tB3eabnT7DjQ= github.com/oapi-codegen/runtime v1.1.1 h1:EXLHh0DXIJnWhdRPN2w4MXAzFyE4CskzhNLUmtpMYro= From d27a951d23b82ac1dbce34871c1522ccee569091 Mon Sep 17 00:00:00 2001 From: Davide Date: Wed, 5 Nov 2025 16:30:57 +0100 Subject: [PATCH 06/20] Update internal/orchestrator/bricks/bricks_test.go Co-authored-by: Luca Rinaldi --- internal/orchestrator/bricks/bricks_test.go | 1 - 1 file changed, 1 deletion(-) diff --git a/internal/orchestrator/bricks/bricks_test.go b/internal/orchestrator/bricks/bricks_test.go index 27d58b7a..08d1ed9a 100644 --- a/internal/orchestrator/bricks/bricks_test.go +++ b/internal/orchestrator/bricks/bricks_test.go @@ -20,7 +20,6 @@ import ( "github.com/stretchr/testify/require" "go.bug.st/f" - "github.com/arduino/go-paths-helper" "github.com/arduino/arduino-app-cli/internal/orchestrator/app" From d2eefb4a2a7eab214204436040895da243c705fa Mon Sep 17 00:00:00 2001 From: Davide Date: Wed, 5 Nov 2025 16:31:08 +0100 Subject: [PATCH 07/20] Update internal/orchestrator/bricks/testdata/my-app.override/app.yaml Co-authored-by: Luca Rinaldi --- internal/orchestrator/bricks/testdata/my-app.override/app.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/orchestrator/bricks/testdata/my-app.override/app.yaml b/internal/orchestrator/bricks/testdata/my-app.override/app.yaml index c9d9dd67..561f7e43 100644 --- a/internal/orchestrator/bricks/testdata/my-app.override/app.yaml +++ b/internal/orchestrator/bricks/testdata/my-app.override/app.yaml @@ -1,9 +1,9 @@ name: Copy of Blinking LED from Arduino Cloud description: Control the LED from the Arduino IoT Cloud using RPC calls +icon: ☁️ ports: [] bricks: - arduino:arduino_cloud: variables: ARDUINO_DEVICE_ID: this-is-a-device-id ARDUINO_SECRET: this-is-a-secret -icon: ☁️ From 13e77f0ca8b52e75eaca75feaf76f811f0fde69b Mon Sep 17 00:00:00 2001 From: Davide Date: Wed, 5 Nov 2025 16:31:16 +0100 Subject: [PATCH 08/20] Update internal/orchestrator/bricks/testdata/dummy-app/app.yaml Co-authored-by: Luca Rinaldi --- internal/orchestrator/bricks/testdata/dummy-app/app.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/internal/orchestrator/bricks/testdata/dummy-app/app.yaml b/internal/orchestrator/bricks/testdata/dummy-app/app.yaml index 5cbcef26..e49ccfca 100644 --- a/internal/orchestrator/bricks/testdata/dummy-app/app.yaml +++ b/internal/orchestrator/bricks/testdata/dummy-app/app.yaml @@ -1,10 +1,10 @@ name: Copy of Blinking LED from Arduino Cloud description: Control the LED from the Arduino IoT Cloud using RPC calls +icon: ☁️ ports: [] bricks: - arduino:arduino_cloud: variables: ARDUINO_DEVICE_ID: my-device-id-79c4b05ef7b6a39 ARDUINO_SECRET: my-device-secret-43f4a190b1ffb8ce -- arduino:dbstorage_sqlstore: {} -icon: ☁️ +- arduino:dbstorage_sqlstore From d770c4b6aca1d19a1a365ac04e5305c5d94201fb Mon Sep 17 00:00:00 2001 From: Davide Date: Wed, 5 Nov 2025 16:31:25 +0100 Subject: [PATCH 09/20] Update internal/orchestrator/bricks/testdata/my-app.source/app.yaml Co-authored-by: Luca Rinaldi --- internal/orchestrator/bricks/testdata/my-app.source/app.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/internal/orchestrator/bricks/testdata/my-app.source/app.yaml b/internal/orchestrator/bricks/testdata/my-app.source/app.yaml index 06322d99..98a0a48c 100644 --- a/internal/orchestrator/bricks/testdata/my-app.source/app.yaml +++ b/internal/orchestrator/bricks/testdata/my-app.source/app.yaml @@ -1,6 +1,6 @@ name: Copy of Blinking LED from Arduino Cloud description: Control the LED from the Arduino IoT Cloud using RPC calls +icon: ☁️ ports: [] bricks: -- arduino:arduino_cloud: -icon: ☁️ +- arduino:arduino_cloud From af3b76bdd3a510e9434a7a40639d8f3aa0bb3436 Mon Sep 17 00:00:00 2001 From: dido18 Date: Wed, 5 Nov 2025 16:32:34 +0100 Subject: [PATCH 10/20] delete: remove unused override files for my-app --- .../bricks/testdata/my-app.override/app.yaml | 9 --------- .../bricks/testdata/my-app.override/python/main.py | 2 -- 2 files changed, 11 deletions(-) delete mode 100644 internal/orchestrator/bricks/testdata/my-app.override/app.yaml delete mode 100644 internal/orchestrator/bricks/testdata/my-app.override/python/main.py diff --git a/internal/orchestrator/bricks/testdata/my-app.override/app.yaml b/internal/orchestrator/bricks/testdata/my-app.override/app.yaml deleted file mode 100644 index 561f7e43..00000000 --- a/internal/orchestrator/bricks/testdata/my-app.override/app.yaml +++ /dev/null @@ -1,9 +0,0 @@ -name: Copy of Blinking LED from Arduino Cloud -description: Control the LED from the Arduino IoT Cloud using RPC calls -icon: ☁️ -ports: [] -bricks: -- arduino:arduino_cloud: - variables: - ARDUINO_DEVICE_ID: this-is-a-device-id - ARDUINO_SECRET: this-is-a-secret diff --git a/internal/orchestrator/bricks/testdata/my-app.override/python/main.py b/internal/orchestrator/bricks/testdata/my-app.override/python/main.py deleted file mode 100644 index a6e3f970..00000000 --- a/internal/orchestrator/bricks/testdata/my-app.override/python/main.py +++ /dev/null @@ -1,2 +0,0 @@ -def main(): - # empty file From 56124d40ca2202c378735cf309061b65f51dd5e5 Mon Sep 17 00:00:00 2001 From: dido18 Date: Wed, 5 Nov 2025 16:33:24 +0100 Subject: [PATCH 11/20] Update main function in main.py to remove empty comment --- .../orchestrator/bricks/testdata/my-app.source/python/main.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/orchestrator/bricks/testdata/my-app.source/python/main.py b/internal/orchestrator/bricks/testdata/my-app.source/python/main.py index a6e3f970..336e825c 100644 --- a/internal/orchestrator/bricks/testdata/my-app.source/python/main.py +++ b/internal/orchestrator/bricks/testdata/my-app.source/python/main.py @@ -1,2 +1,2 @@ def main(): - # empty file + pass From 52feffd107529789a1dae24857697cb269f580e3 Mon Sep 17 00:00:00 2001 From: dido18 Date: Wed, 5 Nov 2025 16:35:57 +0100 Subject: [PATCH 12/20] go mod revert --- go.mod | 5 ++--- go.sum | 10 ++++------ 2 files changed, 6 insertions(+), 9 deletions(-) diff --git a/go.mod b/go.mod index 083d8282..be40aceb 100644 --- a/go.mod +++ b/go.mod @@ -129,7 +129,7 @@ require ( github.com/fsnotify/fsnotify v1.9.0 // indirect github.com/fvbommel/sortorder v1.1.0 // indirect github.com/fxamacker/cbor/v2 v2.7.0 // indirect - github.com/getkin/kin-openapi v0.133.0 // indirect + github.com/getkin/kin-openapi v0.132.0 // indirect github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect github.com/go-git/go-billy/v5 v5.6.2 // indirect github.com/go-git/go-git/v5 v5.16.2 // indirect @@ -206,7 +206,7 @@ require ( github.com/morikuni/aec v1.0.0 // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f // indirect - github.com/oapi-codegen/oapi-codegen/v2 v2.5.1 // indirect + github.com/oapi-codegen/oapi-codegen/v2 v2.5.0 // indirect github.com/oasdiff/yaml v0.0.0-20250309154309-f31be36b4037 // indirect github.com/oasdiff/yaml3 v0.0.0-20250309153720-d2182401db90 // indirect github.com/opencontainers/go-digest v1.0.0 // indirect @@ -257,7 +257,6 @@ require ( github.com/ulikunitz/xz v0.5.15 // indirect github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect github.com/vmware-labs/yaml-jsonpath v0.3.2 // indirect - github.com/woodsbury/decimal128 v1.3.0 // indirect github.com/x448/float16 v0.8.4 // indirect github.com/xanzy/ssh-agent v0.3.3 // indirect github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb // indirect diff --git a/go.sum b/go.sum index 1f1f015e..98b1009f 100644 --- a/go.sum +++ b/go.sum @@ -310,8 +310,8 @@ github.com/fvbommel/sortorder v1.1.0 h1:fUmoe+HLsBTctBDoaBwpQo5N+nrCp8g/BjKb/6ZQ github.com/fvbommel/sortorder v1.1.0/go.mod h1:uk88iVf1ovNn1iLfgUVU2F9o5eO30ui720w+kxuqRs0= github.com/fxamacker/cbor/v2 v2.7.0 h1:iM5WgngdRBanHcxugY4JySA0nk1wZorNOpTgCMedv5E= github.com/fxamacker/cbor/v2 v2.7.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXEeXQVeNoDQ= -github.com/getkin/kin-openapi v0.133.0 h1:pJdmNohVIJ97r4AUFtEXRXwESr8b0bD721u/Tz6k8PQ= -github.com/getkin/kin-openapi v0.133.0/go.mod h1:boAciF6cXk5FhPqe/NQeBTeenbjqU4LhWBf09ILVvWE= +github.com/getkin/kin-openapi v0.132.0 h1:3ISeLMsQzcb5v26yeJrBcdTCEQTag36ZjaGk7MIRUwk= +github.com/getkin/kin-openapi v0.132.0/go.mod h1:3OlG51PCYNsPByuiMB0t4fjnNlIDnaEDsjiKUV8nL58= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/gliderlabs/ssh v0.3.8 h1:a4YXD1V7xMF9g5nTkdfnja3Sxy1PVDCj1Zg4Wb8vY6c= github.com/gliderlabs/ssh v0.3.8/go.mod h1:xYoytBv1sV0aL3CavoDuJIQNURXkkfPA/wxQ1pL1fAU= @@ -676,8 +676,8 @@ github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLA github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= -github.com/oapi-codegen/oapi-codegen/v2 v2.5.1 h1:5vHNY1uuPBRBWqB2Dp0G7YB03phxLQZupZTIZaeorjc= -github.com/oapi-codegen/oapi-codegen/v2 v2.5.1/go.mod h1:ro0npU1BWkcGpCgGD9QwPp44l5OIZ94tB3eabnT7DjQ= +github.com/oapi-codegen/oapi-codegen/v2 v2.5.0 h1:iJvF8SdB/3/+eGOXEpsWkD8FQAHj6mqkb6Fnsoc8MFU= +github.com/oapi-codegen/oapi-codegen/v2 v2.5.0/go.mod h1:fwlMxUEMuQK5ih9aymrxKPQqNm2n8bdLk1ppjH+lr9w= github.com/oapi-codegen/runtime v1.1.1 h1:EXLHh0DXIJnWhdRPN2w4MXAzFyE4CskzhNLUmtpMYro= github.com/oapi-codegen/runtime v1.1.1/go.mod h1:SK9X900oXmPWilYR5/WKPzt3Kqxn/uS/+lbpREv+eCg= github.com/oasdiff/yaml v0.0.0-20250309154309-f31be36b4037 h1:G7ERwszslrBzRxj//JalHPu/3yz+De2J+4aLtSRlHiY= @@ -909,8 +909,6 @@ github.com/warthog618/go-gpiocdev v0.9.1 h1:pwHPaqjJfhCipIQl78V+O3l9OKHivdRDdmgX github.com/warthog618/go-gpiocdev v0.9.1/go.mod h1:dN3e3t/S2aSNC+hgigGE/dBW8jE1ONk9bDSEYfoPyl8= github.com/warthog618/go-gpiosim v0.1.1 h1:MRAEv+T+itmw+3GeIGpQJBfanUVyg0l3JCTwHtwdre4= github.com/warthog618/go-gpiosim v0.1.1/go.mod h1:YXsnB+I9jdCMY4YAlMSRrlts25ltjmuIsrnoUrBLdqU= -github.com/woodsbury/decimal128 v1.3.0 h1:8pffMNWIlC0O5vbyHWFZAt5yWvWcrHA+3ovIIjVWss0= -github.com/woodsbury/decimal128 v1.3.0/go.mod h1:C5UTmyTjW3JftjUFzOVhC20BEQa2a4ZKOB5I6Zjb+ds= github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM= github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg= github.com/xanzy/ssh-agent v0.3.3 h1:+/15pJfg/RsTxqYcX6fHqOXZwwMP+2VyYWJeWM2qQFM= From 079fddaa05382539a31439b861f9ced84f694d04 Mon Sep 17 00:00:00 2001 From: dido18 Date: Wed, 5 Nov 2025 16:39:24 +0100 Subject: [PATCH 13/20] fix: reorder import statements in bricks_test.go for consistency --- internal/orchestrator/bricks/bricks_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/orchestrator/bricks/bricks_test.go b/internal/orchestrator/bricks/bricks_test.go index 08d1ed9a..c03a2dc6 100644 --- a/internal/orchestrator/bricks/bricks_test.go +++ b/internal/orchestrator/bricks/bricks_test.go @@ -18,9 +18,9 @@ package bricks import ( "testing" + "github.com/arduino/go-paths-helper" "github.com/stretchr/testify/require" "go.bug.st/f" - "github.com/arduino/go-paths-helper" "github.com/arduino/arduino-app-cli/internal/orchestrator/app" "github.com/arduino/arduino-app-cli/internal/orchestrator/bricksindex" From 9655a60d589a47b695e9dd3d63cf80c4c0c2ab4a Mon Sep 17 00:00:00 2001 From: Davide Date: Wed, 5 Nov 2025 17:34:25 +0100 Subject: [PATCH 14/20] Update internal/orchestrator/bricks/testdata/dummy-app/python/main.py Co-authored-by: Luca Rinaldi --- internal/orchestrator/bricks/testdata/dummy-app/python/main.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/orchestrator/bricks/testdata/dummy-app/python/main.py b/internal/orchestrator/bricks/testdata/dummy-app/python/main.py index a6e3f970..336e825c 100644 --- a/internal/orchestrator/bricks/testdata/dummy-app/python/main.py +++ b/internal/orchestrator/bricks/testdata/dummy-app/python/main.py @@ -1,2 +1,2 @@ def main(): - # empty file + pass From 8066017105562f4676a6c902220cbb886da0e53f Mon Sep 17 00:00:00 2001 From: dido18 Date: Thu, 6 Nov 2025 09:24:22 +0100 Subject: [PATCH 15/20] refactor: update test cases for brick creation and variable overrides; clean up test data --- internal/orchestrator/bricks/bricks_test.go | 74 ++++++++++--------- .../orchestrator/bricks/testdata/.gitignore | 2 +- .../bricks/testdata/dummy-app/app.yaml | 6 +- .../bricks/testdata/my-app.source/app.yaml | 6 -- .../testdata/my-app.source/python/main.py | 2 - 5 files changed, 41 insertions(+), 49 deletions(-) delete mode 100644 internal/orchestrator/bricks/testdata/my-app.source/app.yaml delete mode 100644 internal/orchestrator/bricks/testdata/my-app.source/python/main.py diff --git a/internal/orchestrator/bricks/bricks_test.go b/internal/orchestrator/bricks/bricks_test.go index c03a2dc6..de71734c 100644 --- a/internal/orchestrator/bricks/bricks_test.go +++ b/internal/orchestrator/bricks/bricks_test.go @@ -66,43 +66,47 @@ func TestBrickCreate(t *testing.T) { }) t.Run("the brick is added if it does not exist in the app", func(t *testing.T) { + tempDummyApp := paths.New("testdata/dummy-app.temp") + err := tempDummyApp.RemoveAll() + require.Nil(t, err) + require.Nil(t, paths.New("testdata/dummy-app").CopyDirTo(tempDummyApp)) + req := BrickCreateUpdateRequest{ID: "arduino:dbstorage_sqlstore"} - // TODO: find a better way to test if the brick has been added to the app.yaml - // Currently we only check that there is no error since the app.yaml is populated with the brick at every test execution. - err = brickService.BrickCreate(req, f.Must(app.Load("testdata/dummy-app"))) + err = brickService.BrickCreate(req, f.Must(app.Load(tempDummyApp.String()))) require.Nil(t, err) + after, err := app.Load(tempDummyApp.String()) + require.Nil(t, err) + require.Len(t, after.Descriptor.Bricks, 2) + require.Equal(t, "arduino:dbstorage_sqlstore", after.Descriptor.Bricks[1].ID) }) -} - -func TestOverrideBrickVariablesOfApp(t *testing.T) { - appWithOverride := paths.New("testdata/my-app.override") - err := appWithOverride.RemoveAll() - require.Nil(t, err) - - err = paths.New("testdata/my-app.source").CopyDirTo(appWithOverride) - require.Nil(t, err) - bricksIndex, err := bricksindex.GenerateBricksIndexFromFile(paths.New("testdata")) - require.Nil(t, err) - brickService := NewService(nil, bricksIndex, nil) - - deviceID := "this-is-a-device-id" - secret := "this-is-a-secret" - - req := BrickCreateUpdateRequest{ - ID: "arduino:arduino_cloud", - Variables: map[string]string{ - "ARDUINO_DEVICE_ID": deviceID, - "ARDUINO_SECRET": secret, - }, - } - - err = brickService.BrickCreate(req, f.Must(app.Load("testdata/my-app.override"))) - require.Nil(t, err) + t.Run("the variables of a brick are updated", func(t *testing.T) { + tempDummyApp := paths.New("testdata/dummy-app.brick-override.temp") + err := tempDummyApp.RemoveAll() + require.Nil(t, err) + err = paths.New("testdata/dummy-app").CopyDirTo(tempDummyApp) + require.Nil(t, err) + bricksIndex, err := bricksindex.GenerateBricksIndexFromFile(paths.New("testdata")) + require.Nil(t, err) + brickService := NewService(nil, bricksIndex, nil) + + deviceID := "this-is-a-device-id" + secret := "this-is-a-secret" + req := BrickCreateUpdateRequest{ + ID: "arduino:arduino_cloud", + Variables: map[string]string{ + "ARDUINO_DEVICE_ID": deviceID, + "ARDUINO_SECRET": secret, + }, + } + + err = brickService.BrickCreate(req, f.Must(app.Load(tempDummyApp.String()))) + require.Nil(t, err) - after, err := app.Load("testdata/my-app.override") - require.Nil(t, err) - require.Len(t, after.Descriptor.Bricks, 1) - require.Equal(t, "arduino:arduino_cloud", after.Descriptor.Bricks[0].ID) - require.Equal(t, deviceID, after.Descriptor.Bricks[0].Variables["ARDUINO_DEVICE_ID"]) - require.Equal(t, secret, after.Descriptor.Bricks[0].Variables["ARDUINO_SECRET"]) + after, err := app.Load(tempDummyApp.String()) + require.Nil(t, err) + require.Len(t, after.Descriptor.Bricks, 1) + require.Equal(t, "arduino:arduino_cloud", after.Descriptor.Bricks[0].ID) + require.Equal(t, deviceID, after.Descriptor.Bricks[0].Variables["ARDUINO_DEVICE_ID"]) + require.Equal(t, secret, after.Descriptor.Bricks[0].Variables["ARDUINO_SECRET"]) + }) } diff --git a/internal/orchestrator/bricks/testdata/.gitignore b/internal/orchestrator/bricks/testdata/.gitignore index a3d0b3ac..d4685d62 100644 --- a/internal/orchestrator/bricks/testdata/.gitignore +++ b/internal/orchestrator/bricks/testdata/.gitignore @@ -1 +1 @@ -my-app.override/ +*.temp \ No newline at end of file diff --git a/internal/orchestrator/bricks/testdata/dummy-app/app.yaml b/internal/orchestrator/bricks/testdata/dummy-app/app.yaml index e49ccfca..281821c6 100644 --- a/internal/orchestrator/bricks/testdata/dummy-app/app.yaml +++ b/internal/orchestrator/bricks/testdata/dummy-app/app.yaml @@ -3,8 +3,4 @@ description: Control the LED from the Arduino IoT Cloud using RPC calls icon: ☁️ ports: [] bricks: -- arduino:arduino_cloud: - variables: - ARDUINO_DEVICE_ID: my-device-id-79c4b05ef7b6a39 - ARDUINO_SECRET: my-device-secret-43f4a190b1ffb8ce -- arduino:dbstorage_sqlstore +- arduino:arduino_cloud: \ No newline at end of file diff --git a/internal/orchestrator/bricks/testdata/my-app.source/app.yaml b/internal/orchestrator/bricks/testdata/my-app.source/app.yaml deleted file mode 100644 index 98a0a48c..00000000 --- a/internal/orchestrator/bricks/testdata/my-app.source/app.yaml +++ /dev/null @@ -1,6 +0,0 @@ -name: Copy of Blinking LED from Arduino Cloud -description: Control the LED from the Arduino IoT Cloud using RPC calls -icon: ☁️ -ports: [] -bricks: -- arduino:arduino_cloud diff --git a/internal/orchestrator/bricks/testdata/my-app.source/python/main.py b/internal/orchestrator/bricks/testdata/my-app.source/python/main.py deleted file mode 100644 index 336e825c..00000000 --- a/internal/orchestrator/bricks/testdata/my-app.source/python/main.py +++ /dev/null @@ -1,2 +0,0 @@ -def main(): - pass From 1ada20ca83893a25295d1cdbedfbca9cdcdc0464 Mon Sep 17 00:00:00 2001 From: Davide Date: Thu, 6 Nov 2025 10:40:08 +0100 Subject: [PATCH 16/20] Update internal/orchestrator/bricks/bricks.go Co-authored-by: Luca Rinaldi --- internal/orchestrator/bricks/bricks.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/orchestrator/bricks/bricks.go b/internal/orchestrator/bricks/bricks.go index 27386185..0b93e7a8 100644 --- a/internal/orchestrator/bricks/bricks.go +++ b/internal/orchestrator/bricks/bricks.go @@ -186,7 +186,7 @@ func (s *Service) BrickCreate( ) error { brick, present := s.bricksIndex.FindBrickByID(req.ID) if !present { - return fmt.Errorf("brick '%s' not found", req.ID) + return fmt.Errorf("brick %q not found", req.ID) } for name, reqValue := range req.Variables { From 53e7443a05f4cbde0f4b437fd885ae7b8d54f0a9 Mon Sep 17 00:00:00 2001 From: Davide Date: Thu, 6 Nov 2025 10:40:46 +0100 Subject: [PATCH 17/20] Update internal/orchestrator/bricks/bricks.go Co-authored-by: Luca Rinaldi --- internal/orchestrator/bricks/bricks.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/orchestrator/bricks/bricks.go b/internal/orchestrator/bricks/bricks.go index 0b93e7a8..230d8d26 100644 --- a/internal/orchestrator/bricks/bricks.go +++ b/internal/orchestrator/bricks/bricks.go @@ -192,7 +192,7 @@ func (s *Service) BrickCreate( for name, reqValue := range req.Variables { value, exist := brick.GetVariable(name) if !exist { - return fmt.Errorf("variable '%s' does not exist on brick '%s'", name, brick.ID) + return fmt.Errorf("variable %q does not exist on brick %q", name, brick.ID) } if value.DefaultValue == "" && reqValue == "" { return fmt.Errorf("variable '%s' cannot be empty", name) From a00c7054b6cd05c37be80fc8e5c1d201db8229dc Mon Sep 17 00:00:00 2001 From: Davide Date: Thu, 6 Nov 2025 10:40:55 +0100 Subject: [PATCH 18/20] Update internal/orchestrator/bricks/bricks.go Co-authored-by: Luca Rinaldi --- internal/orchestrator/bricks/bricks.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/orchestrator/bricks/bricks.go b/internal/orchestrator/bricks/bricks.go index 230d8d26..30f4462b 100644 --- a/internal/orchestrator/bricks/bricks.go +++ b/internal/orchestrator/bricks/bricks.go @@ -195,7 +195,7 @@ func (s *Service) BrickCreate( return fmt.Errorf("variable %q does not exist on brick %q", name, brick.ID) } if value.DefaultValue == "" && reqValue == "" { - return fmt.Errorf("variable '%s' cannot be empty", name) + return fmt.Errorf("variable %q cannot be empty", name) } } From e1f746bb483dc90cda1cd8d0a3d3acdcd90eb2a4 Mon Sep 17 00:00:00 2001 From: Davide Date: Thu, 6 Nov 2025 10:41:02 +0100 Subject: [PATCH 19/20] Update internal/orchestrator/bricks/bricks.go Co-authored-by: Luca Rinaldi --- internal/orchestrator/bricks/bricks.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/orchestrator/bricks/bricks.go b/internal/orchestrator/bricks/bricks.go index 30f4462b..7e53bcd4 100644 --- a/internal/orchestrator/bricks/bricks.go +++ b/internal/orchestrator/bricks/bricks.go @@ -202,7 +202,7 @@ func (s *Service) BrickCreate( for _, brickVar := range brick.Variables { if brickVar.DefaultValue == "" { if _, exist := req.Variables[brickVar.Name]; !exist { - return fmt.Errorf("required variable '%s' is mandatory", brickVar.Name) + return fmt.Errorf("required variable %q is mandatory", brickVar.Name) } } } From b06ff397bcd642f72623c21a16dfa63287da42f6 Mon Sep 17 00:00:00 2001 From: dido18 Date: Thu, 6 Nov 2025 10:41:46 +0100 Subject: [PATCH 20/20] fix: update error messages in BrickCreate tests for consistency --- internal/orchestrator/bricks/bricks_test.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/internal/orchestrator/bricks/bricks_test.go b/internal/orchestrator/bricks/bricks_test.go index de71734c..b5a93173 100644 --- a/internal/orchestrator/bricks/bricks_test.go +++ b/internal/orchestrator/bricks/bricks_test.go @@ -34,7 +34,7 @@ func TestBrickCreate(t *testing.T) { t.Run("fails if brick id does not exist", func(t *testing.T) { err = brickService.BrickCreate(BrickCreateUpdateRequest{ID: "not-existing-id"}, f.Must(app.Load("testdata/dummy-app"))) require.Error(t, err) - require.Equal(t, "brick 'not-existing-id' not found", err.Error()) + require.Equal(t, "brick \"not-existing-id\" not found", err.Error()) }) t.Run("fails if the requestes variable is not present in the brick definition", func(t *testing.T) { @@ -43,7 +43,7 @@ func TestBrickCreate(t *testing.T) { }} err = brickService.BrickCreate(req, f.Must(app.Load("testdata/dummy-app"))) require.Error(t, err) - require.Equal(t, "variable 'NON_EXISTING_VARIABLE' does not exist on brick 'arduino:arduino_cloud'", err.Error()) + require.Equal(t, "variable \"NON_EXISTING_VARIABLE\" does not exist on brick \"arduino:arduino_cloud\"", err.Error()) }) t.Run("fails if a required variable is set empty", func(t *testing.T) { @@ -53,7 +53,7 @@ func TestBrickCreate(t *testing.T) { }} err = brickService.BrickCreate(req, f.Must(app.Load("testdata/dummy-app"))) require.Error(t, err) - require.Equal(t, "variable 'ARDUINO_DEVICE_ID' cannot be empty", err.Error()) + require.Equal(t, "variable \"ARDUINO_DEVICE_ID\" cannot be empty", err.Error()) }) t.Run("fails if a mandatory variable is not present in the request", func(t *testing.T) { @@ -62,7 +62,7 @@ func TestBrickCreate(t *testing.T) { }} err = brickService.BrickCreate(req, f.Must(app.Load("testdata/dummy-app"))) require.Error(t, err) - require.Equal(t, "required variable 'ARDUINO_DEVICE_ID' is mandatory", err.Error()) + require.Equal(t, "required variable \"ARDUINO_DEVICE_ID\" is mandatory", err.Error()) }) t.Run("the brick is added if it does not exist in the app", func(t *testing.T) {