Skip to content

Commit 1e8e541

Browse files
committed
feat: add validation for app descriptors and corresponding test cases
1 parent ad54d74 commit 1e8e541

File tree

9 files changed

+120
-0
lines changed

9 files changed

+120
-0
lines changed
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
bricks:
2+
- id: arduino:arduino_cloud
3+
name: Arduino Cloud
4+
description: Connects to Arduino Cloud
5+
variables:
6+
- name: ARDUINO_DEVICE_ID
7+
description: Arduino Cloud Device ID
8+
- name: ARDUINO_SECRET
9+
description: Arduino Cloud Secret
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
name: App with empty bricks
2+
description: App with empty bricks
3+
4+
bricks: []
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
name: App with no required variables
2+
description: App with no required variables
3+
bricks:
4+
- arduino:arduino_cloud
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
name: App only one required variable filled
2+
description: App only one required variable filled
3+
bricks:
4+
- arduino:arduino_cloud:
5+
variables:
6+
ARDUINO_DEVICE_ID: "my-device-id"
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
name: App with no bricks
2+
description: App with no bricks description
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
name: App no existing brick
2+
description: App no existing brick
3+
bricks:
4+
- arduino:not_existing_brick
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
package app
2+
3+
import (
4+
"fmt"
5+
6+
"github.com/arduino/arduino-app-cli/internal/orchestrator/bricksindex"
7+
)
8+
9+
func ValidateAppDescriptor(a AppDescriptor, index *bricksindex.BricksIndex) error {
10+
return validatebricks(a, index)
11+
}
12+
13+
func validatebricks(a AppDescriptor, index *bricksindex.BricksIndex) error {
14+
for _, appBrick := range a.Bricks {
15+
indexBrick, found := index.FindBrickByID(appBrick.ID)
16+
if !found {
17+
return fmt.Errorf("brick %q not found", appBrick.ID)
18+
}
19+
20+
// check the bricks variables inside the app.yaml are valid given a brick definition
21+
for appBrickName := range appBrick.Variables {
22+
_, exist := indexBrick.GetVariable(appBrickName)
23+
if !exist {
24+
return fmt.Errorf("variable %q does not exist on brick %q", appBrickName, indexBrick.ID)
25+
}
26+
}
27+
28+
// check all required variables has a value
29+
for _, indexBrickVariable := range indexBrick.Variables {
30+
if indexBrickVariable.IsRequired() {
31+
if _, exist := appBrick.Variables[indexBrickVariable.Name]; !exist {
32+
return fmt.Errorf("variable %q is required by brick %q", indexBrickVariable.Name, indexBrick.ID)
33+
}
34+
}
35+
}
36+
}
37+
return nil
38+
}
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
package app
2+
3+
import (
4+
"testing"
5+
6+
"github.com/stretchr/testify/assert"
7+
"github.com/stretchr/testify/require"
8+
9+
"github.com/arduino/go-paths-helper"
10+
11+
"github.com/arduino/arduino-app-cli/internal/orchestrator/bricksindex"
12+
)
13+
14+
func TestValidateAppDescriptor(t *testing.T) {
15+
bricksIndex, err := bricksindex.GenerateBricksIndexFromFile(paths.New("testdata/validator"))
16+
require.Nil(t, err)
17+
18+
t.Run("valid app descriptor with no bricks", func(t *testing.T) {
19+
app, err := ParseDescriptorFile(paths.New("testdata/validator/no-bricks-app.yaml"))
20+
require.NoError(t, err)
21+
err = ValidateAppDescriptor(app, bricksIndex)
22+
assert.NoError(t, err)
23+
})
24+
25+
t.Run("valid app descriptor with empty list of bricks", func(t *testing.T) {
26+
app, err := ParseDescriptorFile(paths.New("testdata/validator/empty-bricks-app.yaml"))
27+
require.NoError(t, err)
28+
err = ValidateAppDescriptor(app, bricksIndex)
29+
assert.NoError(t, err)
30+
})
31+
32+
t.Run("invalid app descriptor with missing required variable", func(t *testing.T) {
33+
app, err := ParseDescriptorFile(paths.New("testdata/validator/missing-required-app.yaml"))
34+
require.NoError(t, err)
35+
err = ValidateAppDescriptor(app, bricksIndex)
36+
assert.Equal(t, "variable \"ARDUINO_DEVICE_ID\" is required by brick \"arduino:arduino_cloud\"", err.Error())
37+
})
38+
39+
t.Run("invalid app descriptor with a missing required variable among two", func(t *testing.T) {
40+
app, err := ParseDescriptorFile(paths.New("testdata/validator/mixed-required-app.yaml"))
41+
require.NoError(t, err)
42+
err = ValidateAppDescriptor(app, bricksIndex)
43+
assert.Equal(t, "variable \"ARDUINO_DEVICE_ID\" is required by brick \"arduino:arduino_cloud\"", err.Error())
44+
})
45+
46+
t.Run("invalid app descriptor with not found brick id", func(t *testing.T) {
47+
app, err := ParseDescriptorFile(paths.New("testdata/validator/not-found-brick-app.yaml"))
48+
require.NoError(t, err)
49+
err = ValidateAppDescriptor(app, bricksIndex)
50+
assert.Equal(t, "brick \"arduino:not_existing_brick\" not found", err.Error())
51+
})
52+
53+
}

internal/orchestrator/bricks/testdata/app.golden.yaml

Whitespace-only changes.

0 commit comments

Comments
 (0)