Skip to content

Commit 4022ef6

Browse files
authored
Adding more test coverage for mass upload use case (#152)
* Fix variable overload * Adding test for ota file generation * Added test for no header generation * Code refactoring * Fix test
1 parent 01df93b commit 4022ef6

File tree

3 files changed

+59
-14
lines changed

3 files changed

+59
-14
lines changed

command/ota/massupload.go

Lines changed: 30 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import (
2121
"context"
2222
"errors"
2323
"fmt"
24+
"github.com/sirupsen/logrus"
2425
"os"
2526
"path/filepath"
2627

@@ -54,6 +55,27 @@ type Result struct {
5455
OtaStatus otaapi.Ota
5556
}
5657

58+
func buildOtaFile(params *MassUploadParams) (string, string, error) {
59+
var otaFile string
60+
var otaDir string
61+
var err error
62+
if params.DoNotApplyHeader {
63+
otaFile = params.File
64+
} else {
65+
otaDir, err = os.MkdirTemp("", "")
66+
if err != nil {
67+
return "", "", fmt.Errorf("%s: %w", "cannot create temporary folder", err)
68+
}
69+
otaFile = filepath.Join(otaDir, "temp.ota")
70+
71+
err = Generate(params.File, otaFile, params.FQBN)
72+
if err != nil {
73+
return "", "", fmt.Errorf("%s: %w", "cannot generate .ota file", err)
74+
}
75+
}
76+
return otaFile, otaDir, nil
77+
}
78+
5779
// MassUpload command is used to mass upload a firmware OTA,
5880
// on devices of Arduino IoT Cloud.
5981
func MassUpload(ctx context.Context, params *MassUploadParams, cred *config.Credentials) ([]Result, error) {
@@ -64,6 +86,7 @@ func MassUpload(ctx context.Context, params *MassUploadParams, cred *config.Cred
6486
}
6587

6688
// Generate .ota file
89+
logrus.Infoln("Uploading binary", params.File)
6790
_, err := os.Stat(params.File)
6891
if err != nil {
6992
return nil, fmt.Errorf("file %s does not exists: %w", params.File, err)
@@ -78,21 +101,12 @@ func MassUpload(ctx context.Context, params *MassUploadParams, cred *config.Cred
78101
}
79102

80103
// Generate .ota file
81-
var otaFile string
82-
if params.DoNotApplyHeader {
83-
otaFile = params.File
84-
} else {
85-
otaDir, err := os.MkdirTemp("", "")
86-
if err != nil {
87-
return nil, fmt.Errorf("%s: %w", "cannot create temporary folder", err)
88-
}
89-
otaFile := filepath.Join(otaDir, "temp.ota")
104+
otaFile, otaDir, err := buildOtaFile(params)
105+
if err != nil {
106+
return nil, err
107+
}
108+
if otaDir != "" {
90109
defer os.RemoveAll(otaDir)
91-
92-
err = Generate(params.File, otaFile, params.FQBN)
93-
if err != nil {
94-
return nil, fmt.Errorf("%s: %w", "cannot generate .ota file", err)
95-
}
96110
}
97111

98112
iotClient, err := iot.NewClient(cred)
@@ -196,6 +210,7 @@ func run(ctx context.Context, uploader otaUploader, otapi otaStatusGetter, ids [
196210
for _, id := range ids {
197211
file, err := os.Open(otaFile)
198212
if err != nil {
213+
logrus.Error("cannot open ota file:", otaFile)
199214
r := Result{ID: id, Err: fmt.Errorf("cannot open ota file")}
200215
results = append(results, r)
201216
continue
@@ -205,6 +220,7 @@ func run(ctx context.Context, uploader otaUploader, otapi otaStatusGetter, ids [
205220
}
206221
close(jobs)
207222

223+
logrus.Infoln("Uploading firmware to devices...")
208224
for i := 0; i < numConcurrentUploads; i++ {
209225
go func() {
210226
for job := range jobs {

command/ota/massupload_test.go

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,11 @@ import (
1010
otaapi "github.com/arduino/arduino-cloud-cli/internal/ota-api"
1111
iotclient "github.com/arduino/iot-client-go"
1212
"github.com/gofrs/uuid"
13+
"github.com/stretchr/testify/assert"
1314
)
1415

1516
const testFilename = "testdata/empty.bin"
17+
const cloudFirmwareFilename = "testdata/cloud.bin"
1618

1719
type deviceUploaderTest struct {
1820
deviceOTA func(ctx context.Context, id string, file *os.File, expireMins int) error
@@ -119,3 +121,30 @@ func TestValidateDevices(t *testing.T) {
119121
t.Errorf("expected 2 invalid devices, but found %d: %v", len(i), i)
120122
}
121123
}
124+
125+
func TestValidateBuildOtaFile(t *testing.T) {
126+
127+
file, tmp, err := buildOtaFile(&MassUploadParams{
128+
File: cloudFirmwareFilename,
129+
DoNotApplyHeader: false,
130+
FQBN: "arduino:samd:nano_33_iot",
131+
})
132+
assert.Nil(t, err)
133+
assert.NotNil(t, file)
134+
assert.True(t, strings.HasSuffix(file, "temp.ota"))
135+
assert.NotEmpty(t, tmp)
136+
defer os.RemoveAll(tmp)
137+
}
138+
139+
func TestValidateBuildOtaFile_whenNoHeaderIsRequested(t *testing.T) {
140+
141+
file, tmp, err := buildOtaFile(&MassUploadParams{
142+
File: cloudFirmwareFilename,
143+
DoNotApplyHeader: true,
144+
FQBN: "arduino:samd:nano_33_iot",
145+
})
146+
assert.Nil(t, err)
147+
assert.NotNil(t, file)
148+
assert.Equal(t, cloudFirmwareFilename, file)
149+
assert.Empty(t, tmp)
150+
}

command/ota/testdata/cloud.bin

90 KB
Binary file not shown.

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy