Skip to content

Commit c264066

Browse files
committed
refactor: improve error messages for brick update and validation processes
1 parent ee2db2d commit c264066

File tree

3 files changed

+102
-10
lines changed

3 files changed

+102
-10
lines changed

internal/orchestrator/bricks/bricks.go

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -282,13 +282,13 @@ func (s *Service) BrickCreate(
282282
if !exist {
283283
return fmt.Errorf("variable %q does not exist on brick %q", name, brick.ID)
284284
}
285-
if value.DefaultValue == "" && reqValue == "" {
286-
return fmt.Errorf("variable %q cannot be empty", name)
285+
if value.IsRequired() && reqValue == "" {
286+
return fmt.Errorf("requried variable %q cannot be empty", name)
287287
}
288288
}
289289

290290
for _, brickVar := range brick.Variables {
291-
if brickVar.DefaultValue == "" {
291+
if brickVar.IsRequired() {
292292
if _, exist := req.Variables[brickVar.Name]; !exist {
293293
slog.Warn("[Skip] a required variable is not set by user", "variable", brickVar.Name, "brick", brickVar.Name)
294294
}
@@ -335,9 +335,13 @@ func (s *Service) BrickUpdate(
335335
req BrickCreateUpdateRequest,
336336
appCurrent app.ArduinoApp,
337337
) error {
338+
_, present := s.bricksIndex.FindBrickByID(req.ID)
339+
if !present {
340+
return fmt.Errorf("brick %q not found into the brick index", req.ID)
341+
}
338342
index := slices.IndexFunc(appCurrent.Descriptor.Bricks, func(b app.Brick) bool { return b.ID == req.ID })
339343
if index == -1 {
340-
return fmt.Errorf("brick not found with id %s", req.ID)
344+
return fmt.Errorf("brick %q not found into the bricks of the app", req.ID)
341345
}
342346
brickID := appCurrent.Descriptor.Bricks[index].ID
343347
brickVariables := appCurrent.Descriptor.Bricks[index].Variables
@@ -356,15 +360,16 @@ func (s *Service) BrickUpdate(
356360
}
357361
brick, present := s.bricksIndex.FindBrickByID(brickID)
358362
if !present {
359-
return fmt.Errorf("brick not found with id %s", brickID)
363+
return fmt.Errorf("brick %q not found in the brick index", brickID)
360364
}
365+
361366
for name, updateValue := range req.Variables {
362367
value, exist := brick.GetVariable(name)
363368
if !exist {
364-
return errors.New("variable does not exist")
369+
return fmt.Errorf("variable %q does not exist on brick %q", name, brick.ID)
365370
}
366-
if value.DefaultValue == "" && updateValue == "" {
367-
return errors.New("variable default value cannot be empty")
371+
if value.IsRequired() && updateValue == "" {
372+
return fmt.Errorf("required variable %q cannot be empty", name)
368373
}
369374
updated := false
370375
for _, v := range brickVariables {
@@ -374,12 +379,19 @@ func (s *Service) BrickUpdate(
374379
break
375380
}
376381
}
377-
378382
if !updated {
379383
brickVariables[name] = updateValue
380384
}
381385
}
382386

387+
for _, brickVar := range brick.Variables {
388+
if brickVar.IsRequired() {
389+
if _, exist := req.Variables[brickVar.Name]; !exist {
390+
return fmt.Errorf("required variable %q must be set", brickVar.Name)
391+
}
392+
}
393+
}
394+
383395
appCurrent.Descriptor.Bricks[index].Model = brickModel
384396
appCurrent.Descriptor.Bricks[index].Variables = brickVariables
385397

internal/orchestrator/bricks/bricks_test.go

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,86 @@ import (
2626
"github.com/arduino/arduino-app-cli/internal/orchestrator/bricksindex"
2727
)
2828

29+
func TestUdateBrick(t *testing.T) {
30+
bricksIndex, err := bricksindex.GenerateBricksIndexFromFile(paths.New("testdata"))
31+
require.Nil(t, err)
32+
brickService := NewService(nil, bricksIndex, nil)
33+
34+
t.Run("fails if brick id does not exist into brick index", func(t *testing.T) {
35+
err = brickService.BrickUpdate(BrickCreateUpdateRequest{ID: "not-existing-id"}, f.Must(app.Load("testdata/dummy-app")))
36+
require.Error(t, err)
37+
require.Equal(t, "brick \"not-existing-id\" not found into the brick index", err.Error())
38+
})
39+
40+
t.Run("fails if brick id is present into the index but not in the app ", func(t *testing.T) {
41+
err = brickService.BrickUpdate(BrickCreateUpdateRequest{ID: "arduino:dbstorage_sqlstore"}, f.Must(app.Load("testdata/dummy-app")))
42+
require.Error(t, err)
43+
require.Equal(t, "brick \"not-existing-id\" not found into app descriptor", err.Error())
44+
})
45+
46+
t.Run("fails if the updated variable is not present in the brick definition", func(t *testing.T) {
47+
req := BrickCreateUpdateRequest{ID: "arduino:arduino_cloud", Variables: map[string]string{
48+
"NON_EXISTING_VARIABLE": "some-value",
49+
}}
50+
err = brickService.BrickUpdate(req, f.Must(app.Load("testdata/dummy-app")))
51+
require.Error(t, err)
52+
require.Equal(t, "variable \"NON_EXISTING_VARIABLE\" does not exist on brick \"arduino:arduino_cloud\"", err.Error())
53+
})
54+
55+
t.Run("fails if a required variable is set empty", func(t *testing.T) {
56+
req := BrickCreateUpdateRequest{ID: "arduino:arduino_cloud", Variables: map[string]string{
57+
"ARDUINO_DEVICE_ID": "",
58+
"ARDUINO_SECRET": "a-secret-a",
59+
}}
60+
err = brickService.BrickUpdate(req, f.Must(app.Load("testdata/dummy-app")))
61+
require.Error(t, err)
62+
require.Equal(t, "required variable \"ARDUINO_DEVICE_ID\" cannot be empty", err.Error())
63+
})
64+
65+
t.Run("fails if a mandatory variable is not present", func(t *testing.T) {
66+
tempDummyApp := paths.New("testdata/dummy-app.temp")
67+
err := tempDummyApp.RemoveAll()
68+
require.Nil(t, err)
69+
require.Nil(t, paths.New("testdata/dummy-app").CopyDirTo(tempDummyApp))
70+
71+
req := BrickCreateUpdateRequest{ID: "arduino:arduino_cloud", Variables: map[string]string{
72+
"ARDUINO_SECRET": "a-secret-a",
73+
}}
74+
err = brickService.BrickUpdate(req, f.Must(app.Load(tempDummyApp.String())))
75+
require.Error(t, err)
76+
require.Equal(t, "required variable \"ARDUINO_DEVICE_ID\" must be set", err.Error())
77+
})
78+
79+
t.Run("update the variables of a brick correctly", func(t *testing.T) {
80+
tempDummyApp := paths.New("testdata/dummy-app.brick-override.temp")
81+
require.Nil(t, tempDummyApp.RemoveAll())
82+
require.Nil(t, paths.New("testdata/dummy-app").CopyDirTo(tempDummyApp))
83+
bricksIndex, err := bricksindex.GenerateBricksIndexFromFile(paths.New("testdata"))
84+
require.Nil(t, err)
85+
brickService := NewService(nil, bricksIndex, nil)
86+
87+
deviceID := "updated-device-id"
88+
secret := "updated-secret"
89+
req := BrickCreateUpdateRequest{
90+
ID: "arduino:arduino_cloud",
91+
Variables: map[string]string{
92+
"ARDUINO_DEVICE_ID": deviceID,
93+
"ARDUINO_SECRET": secret,
94+
},
95+
}
96+
97+
err = brickService.BrickUpdate(req, f.Must(app.Load(tempDummyApp.String())))
98+
require.Nil(t, err)
99+
100+
after, err := app.Load(tempDummyApp.String())
101+
require.Nil(t, err)
102+
require.Len(t, after.Descriptor.Bricks, 1)
103+
require.Equal(t, "arduino:arduino_cloud", after.Descriptor.Bricks[0].ID)
104+
require.Equal(t, deviceID, after.Descriptor.Bricks[0].Variables["ARDUINO_DEVICE_ID"])
105+
require.Equal(t, secret, after.Descriptor.Bricks[0].Variables["ARDUINO_SECRET"])
106+
})
107+
108+
}
29109
func TestBrickCreate(t *testing.T) {
30110
bricksIndex, err := bricksindex.GenerateBricksIndexFromFile(paths.New("testdata"))
31111
require.Nil(t, err)
@@ -90,6 +170,7 @@ func TestBrickCreate(t *testing.T) {
90170
require.Len(t, after.Descriptor.Bricks, 2)
91171
require.Equal(t, "arduino:dbstorage_sqlstore", after.Descriptor.Bricks[1].ID)
92172
})
173+
93174
t.Run("the variables of a brick are updated", func(t *testing.T) {
94175
tempDummyApp := paths.New("testdata/dummy-app.brick-override.temp")
95176
err := tempDummyApp.RemoveAll()

internal/orchestrator/orchestrator.go

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -452,7 +452,6 @@ func RestartApp(
452452
return func(yield func(StreamMessage) bool) {
453453
ctx, cancel := context.WithCancel(ctx)
454454
defer cancel()
455-
456455
runningApp, err := getRunningApp(ctx, docker.Client())
457456
if err != nil {
458457
yield(StreamMessage{error: err})

0 commit comments

Comments
 (0)