From 524458d1f6d78f7c4488b9ff67b01634d437ad4c Mon Sep 17 00:00:00 2001 From: Marco Colombo Date: Fri, 10 May 2024 10:34:16 +0200 Subject: [PATCH 1/5] Fix variable overload --- command/ota/massupload.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/command/ota/massupload.go b/command/ota/massupload.go index 0d81ae2e..aec53019 100644 --- a/command/ota/massupload.go +++ b/command/ota/massupload.go @@ -86,7 +86,7 @@ func MassUpload(ctx context.Context, params *MassUploadParams, cred *config.Cred if err != nil { return nil, fmt.Errorf("%s: %w", "cannot create temporary folder", err) } - otaFile := filepath.Join(otaDir, "temp.ota") + otaFile = filepath.Join(otaDir, "temp.ota") defer os.RemoveAll(otaDir) err = Generate(params.File, otaFile, params.FQBN) From a8cc3696f769f30ac3a3727c17513e177d700826 Mon Sep 17 00:00:00 2001 From: Marco Colombo Date: Fri, 10 May 2024 12:11:45 +0200 Subject: [PATCH 2/5] Adding test for ota file generation --- command/ota/massupload.go | 38 ++++++++++++++++++++------------- command/ota/massupload_test.go | 14 ++++++++++++ command/ota/testdata/cloud.bin | Bin 0 -> 92112 bytes 3 files changed, 37 insertions(+), 15 deletions(-) create mode 100755 command/ota/testdata/cloud.bin diff --git a/command/ota/massupload.go b/command/ota/massupload.go index aec53019..1ce800e5 100644 --- a/command/ota/massupload.go +++ b/command/ota/massupload.go @@ -54,6 +54,26 @@ type Result struct { OtaStatus otaapi.Ota } +func buildOtaFile(params *MassUploadParams) (string, error) { + var otaFile string + if params.DoNotApplyHeader { + otaFile = params.File + } else { + otaDir, err := os.MkdirTemp("", "") + if err != nil { + return "", fmt.Errorf("%s: %w", "cannot create temporary folder", err) + } + otaFile = filepath.Join(otaDir, "temp.ota") + defer os.RemoveAll(otaDir) + + err = Generate(params.File, otaFile, params.FQBN) + if err != nil { + return "", fmt.Errorf("%s: %w", "cannot generate .ota file", err) + } + } + return otaFile, nil +} + // MassUpload command is used to mass upload a firmware OTA, // on devices of Arduino IoT Cloud. func MassUpload(ctx context.Context, params *MassUploadParams, cred *config.Credentials) ([]Result, error) { @@ -78,21 +98,9 @@ func MassUpload(ctx context.Context, params *MassUploadParams, cred *config.Cred } // Generate .ota file - var otaFile string - if params.DoNotApplyHeader { - otaFile = params.File - } else { - otaDir, err := os.MkdirTemp("", "") - if err != nil { - return nil, fmt.Errorf("%s: %w", "cannot create temporary folder", err) - } - otaFile = filepath.Join(otaDir, "temp.ota") - defer os.RemoveAll(otaDir) - - err = Generate(params.File, otaFile, params.FQBN) - if err != nil { - return nil, fmt.Errorf("%s: %w", "cannot generate .ota file", err) - } + otaFile, err := buildOtaFile(params) + if err != nil { + return nil, err } iotClient, err := iot.NewClient(cred) diff --git a/command/ota/massupload_test.go b/command/ota/massupload_test.go index bc2856da..9972c298 100644 --- a/command/ota/massupload_test.go +++ b/command/ota/massupload_test.go @@ -10,9 +10,11 @@ import ( otaapi "github.com/arduino/arduino-cloud-cli/internal/ota-api" iotclient "github.com/arduino/iot-client-go" "github.com/gofrs/uuid" + "github.com/stretchr/testify/assert" ) const testFilename = "testdata/empty.bin" +const cloudFirmwareFilename = "testdata/cloud.bin" type deviceUploaderTest struct { deviceOTA func(ctx context.Context, id string, file *os.File, expireMins int) error @@ -119,3 +121,15 @@ func TestValidateDevices(t *testing.T) { t.Errorf("expected 2 invalid devices, but found %d: %v", len(i), i) } } + +func TestValidateBuildOtaFile(t *testing.T) { + + file, err := buildOtaFile(&MassUploadParams{ + File: cloudFirmwareFilename, + DoNotApplyHeader: false, + FQBN: "arduino:samd:nano_33_iot", + }) + assert.Nil(t, err) + assert.NotNil(t, file) + assert.True(t, strings.HasSuffix(file, "temp.ota")) +} diff --git a/command/ota/testdata/cloud.bin b/command/ota/testdata/cloud.bin new file mode 100755 index 0000000000000000000000000000000000000000..0bf2398affb51fafc93d4692d8770d6b7e00e182 GIT binary patch literal 92112 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%0AEaTl5wGMpz64FzW=zHbU)Qg_Q3X)`apY1 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 literal 0 HcmV?d00001 From bc31bd030f6764b95b28ce6c9966a3e2c8b3f7f9 Mon Sep 17 00:00:00 2001 From: Marco Colombo Date: Fri, 10 May 2024 12:13:23 +0200 Subject: [PATCH 3/5] Added test for no header generation --- command/ota/massupload_test.go | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/command/ota/massupload_test.go b/command/ota/massupload_test.go index 9972c298..414e194b 100644 --- a/command/ota/massupload_test.go +++ b/command/ota/massupload_test.go @@ -133,3 +133,15 @@ func TestValidateBuildOtaFile(t *testing.T) { assert.NotNil(t, file) assert.True(t, strings.HasSuffix(file, "temp.ota")) } + +func TestValidateBuildOtaFile_whenNoHeaderIsRequested(t *testing.T) { + + file, err := buildOtaFile(&MassUploadParams{ + File: cloudFirmwareFilename, + DoNotApplyHeader: true, + FQBN: "arduino:samd:nano_33_iot", + }) + assert.Nil(t, err) + assert.NotNil(t, file) + assert.Equal(t, cloudFirmwareFilename, file) +} From b92263d039c6738cae677b6dfd3bc3b929e6d49f Mon Sep 17 00:00:00 2001 From: Marco Colombo Date: Fri, 10 May 2024 12:27:06 +0200 Subject: [PATCH 4/5] Code refactoring --- command/ota/massupload.go | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/command/ota/massupload.go b/command/ota/massupload.go index 1ce800e5..150fe596 100644 --- a/command/ota/massupload.go +++ b/command/ota/massupload.go @@ -21,6 +21,7 @@ import ( "context" "errors" "fmt" + "github.com/sirupsen/logrus" "os" "path/filepath" @@ -54,24 +55,25 @@ type Result struct { OtaStatus otaapi.Ota } -func buildOtaFile(params *MassUploadParams) (string, error) { +func buildOtaFile(params *MassUploadParams) (string, string, error) { var otaFile string + var otaDir string + var err error if params.DoNotApplyHeader { otaFile = params.File } else { - otaDir, err := os.MkdirTemp("", "") + otaDir, err = os.MkdirTemp("", "") if err != nil { - return "", fmt.Errorf("%s: %w", "cannot create temporary folder", err) + return "", "", fmt.Errorf("%s: %w", "cannot create temporary folder", err) } otaFile = filepath.Join(otaDir, "temp.ota") - defer os.RemoveAll(otaDir) err = Generate(params.File, otaFile, params.FQBN) if err != nil { - return "", fmt.Errorf("%s: %w", "cannot generate .ota file", err) + return "", "", fmt.Errorf("%s: %w", "cannot generate .ota file", err) } } - return otaFile, nil + return otaFile, otaDir, nil } // MassUpload command is used to mass upload a firmware OTA, @@ -84,6 +86,7 @@ func MassUpload(ctx context.Context, params *MassUploadParams, cred *config.Cred } // Generate .ota file + logrus.Infoln("Uploading binary", params.File) _, err := os.Stat(params.File) if err != nil { return nil, fmt.Errorf("file %s does not exists: %w", params.File, err) @@ -98,10 +101,13 @@ func MassUpload(ctx context.Context, params *MassUploadParams, cred *config.Cred } // Generate .ota file - otaFile, err := buildOtaFile(params) + otaFile, otaDir, err := buildOtaFile(params) if err != nil { return nil, err } + if otaDir != "" { + defer os.RemoveAll(otaDir) + } iotClient, err := iot.NewClient(cred) if err != nil { @@ -204,6 +210,7 @@ func run(ctx context.Context, uploader otaUploader, otapi otaStatusGetter, ids [ for _, id := range ids { file, err := os.Open(otaFile) if err != nil { + logrus.Error("cannot open ota file:", otaFile) r := Result{ID: id, Err: fmt.Errorf("cannot open ota file")} results = append(results, r) continue @@ -213,6 +220,7 @@ func run(ctx context.Context, uploader otaUploader, otapi otaStatusGetter, ids [ } close(jobs) + logrus.Infoln("Uploading firmware to devices...") for i := 0; i < numConcurrentUploads; i++ { go func() { for job := range jobs { From e104bdb33f12a7417c12cac06ab9bfd6ee916311 Mon Sep 17 00:00:00 2001 From: Marco Colombo Date: Fri, 10 May 2024 12:33:04 +0200 Subject: [PATCH 5/5] Fix test --- command/ota/massupload_test.go | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/command/ota/massupload_test.go b/command/ota/massupload_test.go index 414e194b..476fa7c6 100644 --- a/command/ota/massupload_test.go +++ b/command/ota/massupload_test.go @@ -124,7 +124,7 @@ func TestValidateDevices(t *testing.T) { func TestValidateBuildOtaFile(t *testing.T) { - file, err := buildOtaFile(&MassUploadParams{ + file, tmp, err := buildOtaFile(&MassUploadParams{ File: cloudFirmwareFilename, DoNotApplyHeader: false, FQBN: "arduino:samd:nano_33_iot", @@ -132,11 +132,13 @@ func TestValidateBuildOtaFile(t *testing.T) { assert.Nil(t, err) assert.NotNil(t, file) assert.True(t, strings.HasSuffix(file, "temp.ota")) + assert.NotEmpty(t, tmp) + defer os.RemoveAll(tmp) } func TestValidateBuildOtaFile_whenNoHeaderIsRequested(t *testing.T) { - file, err := buildOtaFile(&MassUploadParams{ + file, tmp, err := buildOtaFile(&MassUploadParams{ File: cloudFirmwareFilename, DoNotApplyHeader: true, FQBN: "arduino:samd:nano_33_iot", @@ -144,4 +146,5 @@ func TestValidateBuildOtaFile_whenNoHeaderIsRequested(t *testing.T) { assert.Nil(t, err) assert.NotNil(t, file) assert.Equal(t, cloudFirmwareFilename, file) + assert.Empty(t, tmp) }