From 6495d208676ec68b7a4ba9b4b18f85e925f43eb0 Mon Sep 17 00:00:00 2001 From: Paolo Calao Date: Mon, 11 Apr 2022 20:34:07 +0200 Subject: [PATCH] Remove useless iot client interface --- command/device/create.go | 2 +- command/device/createlora.go | 2 +- command/device/provision.go | 10 +- command/ota/massupload.go | 20 +- command/ota/massupload_test.go | 42 ++-- command/thing/clone.go | 8 +- internal/iot/client.go | 79 ++---- internal/iot/mocks/Client.go | 440 --------------------------------- internal/template/dashboard.go | 11 +- internal/template/load.go | 7 +- internal/template/load_test.go | 35 ++- 11 files changed, 111 insertions(+), 545 deletions(-) delete mode 100644 internal/iot/mocks/Client.go diff --git a/command/device/create.go b/command/device/create.go index 38f6209c..0c218402 100644 --- a/command/device/create.go +++ b/command/device/create.go @@ -80,7 +80,7 @@ func Create(params *CreateParams) (*DeviceInfo, error) { prov := &provision{ Commander: comm, - Client: iotClient, + cert: iotClient, board: board, id: dev.Id, } diff --git a/command/device/createlora.go b/command/device/createlora.go index f78e019c..b37cf245 100644 --- a/command/device/createlora.go +++ b/command/device/createlora.go @@ -171,7 +171,7 @@ func extractEUI(port string) (string, error) { return eui, nil } -func getDeviceLoraInfo(iotClient iot.Client, loraDev *iotclient.ArduinoLoradevicev1) (*DeviceLoraInfo, error) { +func getDeviceLoraInfo(iotClient *iot.Client, loraDev *iotclient.ArduinoLoradevicev1) (*DeviceLoraInfo, error) { dev, err := iotClient.DeviceShow(loraDev.DeviceId) if err != nil { return nil, fmt.Errorf("cannot retrieve device from the cloud: %w", err) diff --git a/command/device/provision.go b/command/device/provision.go index 0f525522..38408666 100644 --- a/command/device/provision.go +++ b/command/device/provision.go @@ -26,9 +26,9 @@ import ( "github.com/arduino/arduino-cloud-cli/arduino" "github.com/arduino/arduino-cloud-cli/internal/binary" - "github.com/arduino/arduino-cloud-cli/internal/iot" "github.com/arduino/arduino-cloud-cli/internal/serial" "github.com/arduino/go-paths-helper" + iotclient "github.com/arduino/iot-client-go" "github.com/sirupsen/logrus" ) @@ -63,11 +63,15 @@ func downloadProvisioningFile(fqbn string) (string, error) { return p.String(), nil } +type certificateCreator interface { + CertificateCreate(id, csr string) (*iotclient.ArduinoCompressedv2, error) +} + // provision is responsible for running the provisioning // procedures for boards with crypto-chip. type provision struct { arduino.Commander - iot.Client + cert certificateCreator ser *serial.Serial board *board id string @@ -125,7 +129,7 @@ func (p provision) configBoard() error { if err != nil { return err } - cert, err := p.CertificateCreate(p.id, string(csr)) + cert, err := p.cert.CertificateCreate(p.id, string(csr)) if err != nil { return err } diff --git a/command/ota/massupload.go b/command/ota/massupload.go index a9000765..e4ab512c 100644 --- a/command/ota/massupload.go +++ b/command/ota/massupload.go @@ -104,11 +104,15 @@ func MassUpload(params *MassUploadParams) ([]Result, error) { return res, nil } -func idsGivenTags(iotClient iot.Client, tags map[string]string) ([]string, error) { +type deviceLister interface { + DeviceList(tags map[string]string) ([]iotclient.ArduinoDevicev2, error) +} + +func idsGivenTags(lister deviceLister, tags map[string]string) ([]string, error) { if tags == nil { return nil, nil } - devs, err := iotClient.DeviceList(tags) + devs, err := lister.DeviceList(tags) if err != nil { return nil, fmt.Errorf("%s: %w", "cannot retrieve devices from cloud", err) } @@ -119,8 +123,8 @@ func idsGivenTags(iotClient iot.Client, tags map[string]string) ([]string, error return devices, nil } -func validateDevices(iotClient iot.Client, ids []string, fqbn string) (valid []string, invalid []Result, err error) { - devs, err := iotClient.DeviceList(nil) +func validateDevices(lister deviceLister, ids []string, fqbn string) (valid []string, invalid []Result, err error) { + devs, err := lister.DeviceList(nil) if err != nil { return nil, nil, fmt.Errorf("%s: %w", "cannot retrieve devices from cloud", err) } @@ -150,7 +154,11 @@ func validateDevices(iotClient iot.Client, ids []string, fqbn string) (valid []s return valid, invalid, nil } -func run(iotClient iot.Client, ids []string, otaFile string, expiration int) []Result { +type otaUploader interface { + DeviceOTA(id string, file *os.File, expireMins int) error +} + +func run(uploader otaUploader, ids []string, otaFile string, expiration int) []Result { type job struct { id string file *os.File @@ -174,7 +182,7 @@ func run(iotClient iot.Client, ids []string, otaFile string, expiration int) []R for i := 0; i < numConcurrentUploads; i++ { go func() { for job := range jobs { - err := iotClient.DeviceOTA(job.id, job.file, expiration) + err := uploader.DeviceOTA(job.id, job.file, expiration) resCh <- Result{ID: job.id, Err: err} } }() diff --git a/command/ota/massupload_test.go b/command/ota/massupload_test.go index 4c8b6f73..fc83187e 100644 --- a/command/ota/massupload_test.go +++ b/command/ota/massupload_test.go @@ -6,13 +6,19 @@ import ( "strings" "testing" - "github.com/arduino/arduino-cloud-cli/internal/iot/mocks" iotclient "github.com/arduino/iot-client-go" - "github.com/stretchr/testify/mock" ) const testFilename = "testdata/empty.bin" +type deviceUploaderTest struct { + deviceOTA func(id string, file *os.File, expireMins int) error +} + +func (d *deviceUploaderTest) DeviceOTA(id string, file *os.File, expireMins int) error { + return d.deviceOTA(id, file, expireMins) +} + func TestRun(t *testing.T) { var ( failPrefix = "00000000" @@ -23,14 +29,14 @@ func TestRun(t *testing.T) { okID2 = okPrefix + "-003f-42f9-a80c-85a1de36753b" okID3 = okPrefix + "-dac4-4a6a-80a4-698062fe2af5" ) - mockClient := &mocks.Client{} - mockDeviceOTA := func(id string, file *os.File, expireMins int) error { - if strings.Split(id, "-")[0] == failPrefix { - return errors.New("err") - } - return nil + mockClient := &deviceUploaderTest{ + deviceOTA: func(id string, file *os.File, expireMins int) error { + if strings.Split(id, "-")[0] == failPrefix { + return errors.New("err") + } + return nil + }, } - mockClient.On("DeviceOTA", mock.Anything, mock.Anything, mock.Anything).Return(mockDeviceOTA, nil) devs := []string{okID1, failID1, okID2, failID2, okID3} res := run(mockClient, devs, testFilename, 0) @@ -49,6 +55,14 @@ func TestRun(t *testing.T) { } } +type deviceListerTest struct { + list []iotclient.ArduinoDevicev2 +} + +func (d *deviceListerTest) DeviceList(tags map[string]string) ([]iotclient.ArduinoDevicev2, error) { + return d.list, nil +} + func TestValidateDevices(t *testing.T) { var ( correctFQBN = "arduino:samd:nano_33_iot" @@ -60,15 +74,13 @@ func TestValidateDevices(t *testing.T) { idNotFound = "deb17b7f-b39d-47a2-adf3-d26cdf474707" ) - mockClient := &mocks.Client{} - mockDeviceList := func(tags map[string]string) []iotclient.ArduinoDevicev2 { - return []iotclient.ArduinoDevicev2{ + mockDeviceList := deviceListerTest{ + list: []iotclient.ArduinoDevicev2{ {Id: idCorrect1, Fqbn: correctFQBN}, {Id: idCorrect2, Fqbn: correctFQBN}, {Id: idNotValid, Fqbn: wrongFQBN}, - } + }, } - mockClient.On("DeviceList", mock.Anything).Return(mockDeviceList, nil) ids := []string{ idCorrect1, @@ -76,7 +88,7 @@ func TestValidateDevices(t *testing.T) { idCorrect2, idNotValid, } - v, i, err := validateDevices(mockClient, ids, correctFQBN) + v, i, err := validateDevices(&mockDeviceList, ids, correctFQBN) if err != nil { t.Errorf("unexpected error: %s", err.Error()) } diff --git a/command/thing/clone.go b/command/thing/clone.go index c6db7640..cfb27d04 100644 --- a/command/thing/clone.go +++ b/command/thing/clone.go @@ -61,8 +61,12 @@ func Clone(params *CloneParams) (*ThingInfo, error) { return t, nil } -func retrieve(client iot.Client, thingID string) (*iotclient.ThingCreate, error) { - clone, err := client.ThingShow(thingID) +type thingFetcher interface { + ThingShow(id string) (*iotclient.ArduinoThing, error) +} + +func retrieve(fetcher thingFetcher, thingID string) (*iotclient.ThingCreate, error) { + clone, err := fetcher.ThingShow(thingID) if err != nil { return nil, fmt.Errorf("%s: %w", "retrieving the thing to be cloned", err) } diff --git a/internal/iot/client.go b/internal/iot/client.go index 78aba94e..cab6f7ed 100644 --- a/internal/iot/client.go +++ b/internal/iot/client.go @@ -26,41 +26,16 @@ import ( iotclient "github.com/arduino/iot-client-go" ) -// Client can be used to perform actions on Arduino IoT Cloud. -type Client interface { - DeviceCreate(fqbn, name, serial, devType string) (*iotclient.ArduinoDevicev2, error) - DeviceLoraCreate(name, serial, devType, eui, freq string) (*iotclient.ArduinoLoradevicev1, error) - DeviceDelete(id string) error - DeviceList(tags map[string]string) ([]iotclient.ArduinoDevicev2, error) - DeviceShow(id string) (*iotclient.ArduinoDevicev2, error) - DeviceOTA(id string, file *os.File, expireMins int) error - DevicePassSet(id string) (*iotclient.ArduinoDevicev2Pass, error) - DeviceTagsCreate(id string, tags map[string]string) error - DeviceTagsDelete(id string, keys []string) error - LoraFrequencyPlansList() ([]iotclient.ArduinoLorafreqplanv1, error) - CertificateCreate(id, csr string) (*iotclient.ArduinoCompressedv2, error) - ThingCreate(thing *iotclient.ThingCreate, force bool) (*iotclient.ArduinoThing, error) - ThingUpdate(id string, thing *iotclient.ThingUpdate, force bool) error - ThingDelete(id string) error - ThingShow(id string) (*iotclient.ArduinoThing, error) - ThingList(ids []string, device *string, props bool, tags map[string]string) ([]iotclient.ArduinoThing, error) - ThingTagsCreate(id string, tags map[string]string) error - ThingTagsDelete(id string, keys []string) error - DashboardCreate(dashboard *iotclient.Dashboardv2) (*iotclient.ArduinoDashboardv2, error) - DashboardShow(id string) (*iotclient.ArduinoDashboardv2, error) - DashboardDelete(id string) error - DashboardList() ([]iotclient.ArduinoDashboardv2, error) -} - -type client struct { +// Client can perform actions on Arduino IoT Cloud. +type Client struct { ctx context.Context api *iotclient.APIClient } // NewClient returns a new client implementing the Client interface. // It needs a ClientID and SecretID for cloud authentication. -func NewClient(clientID, secretID string) (Client, error) { - cl := &client{} +func NewClient(clientID, secretID string) (*Client, error) { + cl := &Client{} err := cl.setup(clientID, secretID) if err != nil { err = fmt.Errorf("instantiate new iot client: %w", err) @@ -71,7 +46,7 @@ func NewClient(clientID, secretID string) (Client, error) { // DeviceCreate allows to create a new device on Arduino IoT Cloud. // It returns the newly created device, and an error. -func (cl *client) DeviceCreate(fqbn, name, serial, dType string) (*iotclient.ArduinoDevicev2, error) { +func (cl *Client) DeviceCreate(fqbn, name, serial, dType string) (*iotclient.ArduinoDevicev2, error) { payload := iotclient.CreateDevicesV2Payload{ Fqbn: fqbn, Name: name, @@ -88,7 +63,7 @@ func (cl *client) DeviceCreate(fqbn, name, serial, dType string) (*iotclient.Ard // DeviceLoraCreate allows to create a new LoRa device on Arduino IoT Cloud. // It returns the LoRa information about the newly created device, and an error. -func (cl *client) DeviceLoraCreate(name, serial, devType, eui, freq string) (*iotclient.ArduinoLoradevicev1, error) { +func (cl *Client) DeviceLoraCreate(name, serial, devType, eui, freq string) (*iotclient.ArduinoLoradevicev1, error) { payload := iotclient.CreateLoraDevicesV1Payload{ App: "defaultApp", Eui: eui, @@ -108,7 +83,7 @@ func (cl *client) DeviceLoraCreate(name, serial, devType, eui, freq string) (*io // DevicePassSet sets the device password to the one suggested by Arduino IoT Cloud. // Returns the set password. -func (cl *client) DevicePassSet(id string) (*iotclient.ArduinoDevicev2Pass, error) { +func (cl *Client) DevicePassSet(id string) (*iotclient.ArduinoDevicev2Pass, error) { // Fetch suggested password opts := &iotclient.DevicesV2PassGetOpts{SuggestedPassword: optional.NewBool(true)} pass, _, err := cl.api.DevicesV2PassApi.DevicesV2PassGet(cl.ctx, id, opts) @@ -128,7 +103,7 @@ func (cl *client) DevicePassSet(id string) (*iotclient.ArduinoDevicev2Pass, erro // DeviceDelete deletes the device corresponding to the passed ID // from Arduino IoT Cloud. -func (cl *client) DeviceDelete(id string) error { +func (cl *Client) DeviceDelete(id string) error { _, err := cl.api.DevicesV2Api.DevicesV2Delete(cl.ctx, id) if err != nil { err = fmt.Errorf("deleting device: %w", errorDetail(err)) @@ -139,7 +114,7 @@ func (cl *client) DeviceDelete(id string) error { // DeviceList retrieves and returns a list of all Arduino IoT Cloud devices // belonging to the user performing the request. -func (cl *client) DeviceList(tags map[string]string) ([]iotclient.ArduinoDevicev2, error) { +func (cl *Client) DeviceList(tags map[string]string) ([]iotclient.ArduinoDevicev2, error) { opts := &iotclient.DevicesV2ListOpts{} if tags != nil { t := make([]string, 0, len(tags)) @@ -160,7 +135,7 @@ func (cl *client) DeviceList(tags map[string]string) ([]iotclient.ArduinoDevicev // DeviceShow allows to retrieve a specific device, given its id, // from Arduino IoT Cloud. -func (cl *client) DeviceShow(id string) (*iotclient.ArduinoDevicev2, error) { +func (cl *Client) DeviceShow(id string) (*iotclient.ArduinoDevicev2, error) { dev, _, err := cl.api.DevicesV2Api.DevicesV2Show(cl.ctx, id) if err != nil { err = fmt.Errorf("retrieving device, %w", errorDetail(err)) @@ -171,7 +146,7 @@ func (cl *client) DeviceShow(id string) (*iotclient.ArduinoDevicev2, error) { // DeviceOTA performs an OTA upload request to Arduino IoT Cloud, passing // the ID of the device to be updated and the actual file containing the OTA firmware. -func (cl *client) DeviceOTA(id string, file *os.File, expireMins int) error { +func (cl *Client) DeviceOTA(id string, file *os.File, expireMins int) error { opt := &iotclient.DevicesV2OtaUploadOpts{ ExpireInMins: optional.NewInt32(int32(expireMins)), } @@ -184,7 +159,7 @@ func (cl *client) DeviceOTA(id string, file *os.File, expireMins int) error { } // DeviceTagsCreate allows to create or overwrite tags on a device of Arduino IoT Cloud. -func (cl *client) DeviceTagsCreate(id string, tags map[string]string) error { +func (cl *Client) DeviceTagsCreate(id string, tags map[string]string) error { for key, val := range tags { t := iotclient.Tag{Key: key, Value: val} _, err := cl.api.DevicesV2TagsApi.DevicesV2TagsUpsert(cl.ctx, id, t) @@ -198,7 +173,7 @@ func (cl *client) DeviceTagsCreate(id string, tags map[string]string) error { // DeviceTagsDelete deletes the tags of a device of Arduino IoT Cloud, // given the device id and the keys of the tags. -func (cl *client) DeviceTagsDelete(id string, keys []string) error { +func (cl *Client) DeviceTagsDelete(id string, keys []string) error { for _, key := range keys { _, err := cl.api.DevicesV2TagsApi.DevicesV2TagsDelete(cl.ctx, id, key) if err != nil { @@ -211,7 +186,7 @@ func (cl *client) DeviceTagsDelete(id string, keys []string) error { // LoraFrequencyPlansList retrieves and returns the list of all supported // LoRa frequency plans. -func (cl *client) LoraFrequencyPlansList() ([]iotclient.ArduinoLorafreqplanv1, error) { +func (cl *Client) LoraFrequencyPlansList() ([]iotclient.ArduinoLorafreqplanv1, error) { freqs, _, err := cl.api.LoraFreqPlanV1Api.LoraFreqPlanV1List(cl.ctx) if err != nil { err = fmt.Errorf("listing lora frequency plans: %w", errorDetail(err)) @@ -222,7 +197,7 @@ func (cl *client) LoraFrequencyPlansList() ([]iotclient.ArduinoLorafreqplanv1, e // CertificateCreate allows to upload a certificate on Arduino IoT Cloud. // It returns the certificate parameters populated by the cloud. -func (cl *client) CertificateCreate(id, csr string) (*iotclient.ArduinoCompressedv2, error) { +func (cl *Client) CertificateCreate(id, csr string) (*iotclient.ArduinoCompressedv2, error) { cert := iotclient.CreateDevicesV2CertsPayload{ Ca: "Arduino", Csr: csr, @@ -239,7 +214,7 @@ func (cl *client) CertificateCreate(id, csr string) (*iotclient.ArduinoCompresse } // ThingCreate adds a new thing on Arduino IoT Cloud. -func (cl *client) ThingCreate(thing *iotclient.ThingCreate, force bool) (*iotclient.ArduinoThing, error) { +func (cl *Client) ThingCreate(thing *iotclient.ThingCreate, force bool) (*iotclient.ArduinoThing, error) { opt := &iotclient.ThingsV2CreateOpts{Force: optional.NewBool(force)} newThing, _, err := cl.api.ThingsV2Api.ThingsV2Create(cl.ctx, *thing, opt) if err != nil { @@ -249,7 +224,7 @@ func (cl *client) ThingCreate(thing *iotclient.ThingCreate, force bool) (*iotcli } // ThingUpdate updates a thing on Arduino IoT Cloud. -func (cl *client) ThingUpdate(id string, thing *iotclient.ThingUpdate, force bool) error { +func (cl *Client) ThingUpdate(id string, thing *iotclient.ThingUpdate, force bool) error { opt := &iotclient.ThingsV2UpdateOpts{Force: optional.NewBool(force)} _, _, err := cl.api.ThingsV2Api.ThingsV2Update(cl.ctx, id, *thing, opt) if err != nil { @@ -259,7 +234,7 @@ func (cl *client) ThingUpdate(id string, thing *iotclient.ThingUpdate, force boo } // ThingDelete deletes a thing from Arduino IoT Cloud. -func (cl *client) ThingDelete(id string) error { +func (cl *Client) ThingDelete(id string) error { _, err := cl.api.ThingsV2Api.ThingsV2Delete(cl.ctx, id, nil) if err != nil { err = fmt.Errorf("deleting thing: %w", errorDetail(err)) @@ -270,7 +245,7 @@ func (cl *client) ThingDelete(id string) error { // ThingShow allows to retrieve a specific thing, given its id, // from Arduino IoT Cloud. -func (cl *client) ThingShow(id string) (*iotclient.ArduinoThing, error) { +func (cl *Client) ThingShow(id string) (*iotclient.ArduinoThing, error) { thing, _, err := cl.api.ThingsV2Api.ThingsV2Show(cl.ctx, id, nil) if err != nil { err = fmt.Errorf("retrieving thing, %w", errorDetail(err)) @@ -280,7 +255,7 @@ func (cl *client) ThingShow(id string) (*iotclient.ArduinoThing, error) { } // ThingList returns a list of things on Arduino IoT Cloud. -func (cl *client) ThingList(ids []string, device *string, props bool, tags map[string]string) ([]iotclient.ArduinoThing, error) { +func (cl *Client) ThingList(ids []string, device *string, props bool, tags map[string]string) ([]iotclient.ArduinoThing, error) { opts := &iotclient.ThingsV2ListOpts{} opts.ShowProperties = optional.NewBool(props) @@ -310,7 +285,7 @@ func (cl *client) ThingList(ids []string, device *string, props bool, tags map[s } // ThingTagsCreate allows to create or overwrite tags on a thing of Arduino IoT Cloud. -func (cl *client) ThingTagsCreate(id string, tags map[string]string) error { +func (cl *Client) ThingTagsCreate(id string, tags map[string]string) error { for key, val := range tags { t := iotclient.Tag{Key: key, Value: val} _, err := cl.api.ThingsV2TagsApi.ThingsV2TagsUpsert(cl.ctx, id, t) @@ -324,7 +299,7 @@ func (cl *client) ThingTagsCreate(id string, tags map[string]string) error { // ThingTagsDelete deletes the tags of a thing of Arduino IoT Cloud, // given the thing id and the keys of the tags. -func (cl *client) ThingTagsDelete(id string, keys []string) error { +func (cl *Client) ThingTagsDelete(id string, keys []string) error { for _, key := range keys { _, err := cl.api.ThingsV2TagsApi.ThingsV2TagsDelete(cl.ctx, id, key) if err != nil { @@ -336,7 +311,7 @@ func (cl *client) ThingTagsDelete(id string, keys []string) error { } // DashboardCreate adds a new dashboard on Arduino IoT Cloud. -func (cl *client) DashboardCreate(dashboard *iotclient.Dashboardv2) (*iotclient.ArduinoDashboardv2, error) { +func (cl *Client) DashboardCreate(dashboard *iotclient.Dashboardv2) (*iotclient.ArduinoDashboardv2, error) { newDashboard, _, err := cl.api.DashboardsV2Api.DashboardsV2Create(cl.ctx, *dashboard) if err != nil { return nil, fmt.Errorf("%s: %w", "adding new dashboard", errorDetail(err)) @@ -346,7 +321,7 @@ func (cl *client) DashboardCreate(dashboard *iotclient.Dashboardv2) (*iotclient. // DashboardShow allows to retrieve a specific dashboard, given its id, // from Arduino IoT Cloud. -func (cl *client) DashboardShow(id string) (*iotclient.ArduinoDashboardv2, error) { +func (cl *Client) DashboardShow(id string) (*iotclient.ArduinoDashboardv2, error) { dashboard, _, err := cl.api.DashboardsV2Api.DashboardsV2Show(cl.ctx, id) if err != nil { err = fmt.Errorf("retrieving dashboard, %w", errorDetail(err)) @@ -356,7 +331,7 @@ func (cl *client) DashboardShow(id string) (*iotclient.ArduinoDashboardv2, error } // DashboardList returns a list of dashboards on Arduino IoT Cloud. -func (cl *client) DashboardList() ([]iotclient.ArduinoDashboardv2, error) { +func (cl *Client) DashboardList() ([]iotclient.ArduinoDashboardv2, error) { dashboards, _, err := cl.api.DashboardsV2Api.DashboardsV2List(cl.ctx, nil) if err != nil { err = fmt.Errorf("listing dashboards: %w", errorDetail(err)) @@ -366,7 +341,7 @@ func (cl *client) DashboardList() ([]iotclient.ArduinoDashboardv2, error) { } // DashboardDelete deletes a dashboard from Arduino IoT Cloud. -func (cl *client) DashboardDelete(id string) error { +func (cl *Client) DashboardDelete(id string) error { _, err := cl.api.DashboardsV2Api.DashboardsV2Delete(cl.ctx, id) if err != nil { err = fmt.Errorf("deleting dashboard: %w", errorDetail(err)) @@ -375,7 +350,7 @@ func (cl *client) DashboardDelete(id string) error { return nil } -func (cl *client) setup(client, secret string) error { +func (cl *Client) setup(client, secret string) error { // Get the access token in exchange of client_id and client_secret tok, err := token(client, secret) if err != nil { diff --git a/internal/iot/mocks/Client.go b/internal/iot/mocks/Client.go deleted file mode 100644 index 0423159c..00000000 --- a/internal/iot/mocks/Client.go +++ /dev/null @@ -1,440 +0,0 @@ -// Code generated by mockery v0.0.0-dev. DO NOT EDIT. - -package mocks - -import ( - iot "github.com/arduino/iot-client-go" - mock "github.com/stretchr/testify/mock" - - os "os" -) - -// Client is an autogenerated mock type for the Client type -type Client struct { - mock.Mock -} - -// CertificateCreate provides a mock function with given fields: id, csr -func (_m *Client) CertificateCreate(id string, csr string) (*iot.ArduinoCompressedv2, error) { - ret := _m.Called(id, csr) - - var r0 *iot.ArduinoCompressedv2 - if rf, ok := ret.Get(0).(func(string, string) *iot.ArduinoCompressedv2); ok { - r0 = rf(id, csr) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*iot.ArduinoCompressedv2) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func(string, string) error); ok { - r1 = rf(id, csr) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// DashboardCreate provides a mock function with given fields: dashboard -func (_m *Client) DashboardCreate(dashboard *iot.Dashboardv2) (*iot.ArduinoDashboardv2, error) { - ret := _m.Called(dashboard) - - var r0 *iot.ArduinoDashboardv2 - if rf, ok := ret.Get(0).(func(*iot.Dashboardv2) *iot.ArduinoDashboardv2); ok { - r0 = rf(dashboard) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*iot.ArduinoDashboardv2) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func(*iot.Dashboardv2) error); ok { - r1 = rf(dashboard) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// DashboardDelete provides a mock function with given fields: id -func (_m *Client) DashboardDelete(id string) error { - ret := _m.Called(id) - - var r0 error - if rf, ok := ret.Get(0).(func(string) error); ok { - r0 = rf(id) - } else { - r0 = ret.Error(0) - } - - return r0 -} - -// DashboardList provides a mock function with given fields: -func (_m *Client) DashboardList() ([]iot.ArduinoDashboardv2, error) { - ret := _m.Called() - - var r0 []iot.ArduinoDashboardv2 - if rf, ok := ret.Get(0).(func() []iot.ArduinoDashboardv2); ok { - r0 = rf() - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).([]iot.ArduinoDashboardv2) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func() error); ok { - r1 = rf() - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// DashboardShow provides a mock function with given fields: id -func (_m *Client) DashboardShow(id string) (*iot.ArduinoDashboardv2, error) { - ret := _m.Called(id) - - var r0 *iot.ArduinoDashboardv2 - if rf, ok := ret.Get(0).(func(string) *iot.ArduinoDashboardv2); ok { - r0 = rf(id) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*iot.ArduinoDashboardv2) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func(string) error); ok { - r1 = rf(id) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// DeviceCreate provides a mock function with given fields: fqbn, name, serial, devType -func (_m *Client) DeviceCreate(fqbn string, name string, serial string, devType string) (*iot.ArduinoDevicev2, error) { - ret := _m.Called(fqbn, name, serial, devType) - - var r0 *iot.ArduinoDevicev2 - if rf, ok := ret.Get(0).(func(string, string, string, string) *iot.ArduinoDevicev2); ok { - r0 = rf(fqbn, name, serial, devType) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*iot.ArduinoDevicev2) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func(string, string, string, string) error); ok { - r1 = rf(fqbn, name, serial, devType) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// DeviceDelete provides a mock function with given fields: id -func (_m *Client) DeviceDelete(id string) error { - ret := _m.Called(id) - - var r0 error - if rf, ok := ret.Get(0).(func(string) error); ok { - r0 = rf(id) - } else { - r0 = ret.Error(0) - } - - return r0 -} - -// DeviceList provides a mock function with given fields: tags -func (_m *Client) DeviceList(tags map[string]string) ([]iot.ArduinoDevicev2, error) { - ret := _m.Called(tags) - - var r0 []iot.ArduinoDevicev2 - if rf, ok := ret.Get(0).(func(map[string]string) []iot.ArduinoDevicev2); ok { - r0 = rf(tags) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).([]iot.ArduinoDevicev2) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func(map[string]string) error); ok { - r1 = rf(tags) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// DeviceLoraCreate provides a mock function with given fields: name, serial, devType, eui, freq -func (_m *Client) DeviceLoraCreate(name string, serial string, devType string, eui string, freq string) (*iot.ArduinoLoradevicev1, error) { - ret := _m.Called(name, serial, devType, eui, freq) - - var r0 *iot.ArduinoLoradevicev1 - if rf, ok := ret.Get(0).(func(string, string, string, string, string) *iot.ArduinoLoradevicev1); ok { - r0 = rf(name, serial, devType, eui, freq) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*iot.ArduinoLoradevicev1) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func(string, string, string, string, string) error); ok { - r1 = rf(name, serial, devType, eui, freq) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// DeviceOTA provides a mock function with given fields: id, file, expireMins -func (_m *Client) DeviceOTA(id string, file *os.File, expireMins int) error { - ret := _m.Called(id, file, expireMins) - - var r0 error - if rf, ok := ret.Get(0).(func(string, *os.File, int) error); ok { - r0 = rf(id, file, expireMins) - } else { - r0 = ret.Error(0) - } - - return r0 -} - -// DevicePassSet provides a mock function with given fields: id -func (_m *Client) DevicePassSet(id string) (*iot.ArduinoDevicev2Pass, error) { - ret := _m.Called(id) - - var r0 *iot.ArduinoDevicev2Pass - if rf, ok := ret.Get(0).(func(string) *iot.ArduinoDevicev2Pass); ok { - r0 = rf(id) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*iot.ArduinoDevicev2Pass) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func(string) error); ok { - r1 = rf(id) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// DeviceShow provides a mock function with given fields: id -func (_m *Client) DeviceShow(id string) (*iot.ArduinoDevicev2, error) { - ret := _m.Called(id) - - var r0 *iot.ArduinoDevicev2 - if rf, ok := ret.Get(0).(func(string) *iot.ArduinoDevicev2); ok { - r0 = rf(id) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*iot.ArduinoDevicev2) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func(string) error); ok { - r1 = rf(id) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// DeviceTagsCreate provides a mock function with given fields: id, tags -func (_m *Client) DeviceTagsCreate(id string, tags map[string]string) error { - ret := _m.Called(id, tags) - - var r0 error - if rf, ok := ret.Get(0).(func(string, map[string]string) error); ok { - r0 = rf(id, tags) - } else { - r0 = ret.Error(0) - } - - return r0 -} - -// DeviceTagsDelete provides a mock function with given fields: id, keys -func (_m *Client) DeviceTagsDelete(id string, keys []string) error { - ret := _m.Called(id, keys) - - var r0 error - if rf, ok := ret.Get(0).(func(string, []string) error); ok { - r0 = rf(id, keys) - } else { - r0 = ret.Error(0) - } - - return r0 -} - -// LoraFrequencyPlansList provides a mock function with given fields: -func (_m *Client) LoraFrequencyPlansList() ([]iot.ArduinoLorafreqplanv1, error) { - ret := _m.Called() - - var r0 []iot.ArduinoLorafreqplanv1 - if rf, ok := ret.Get(0).(func() []iot.ArduinoLorafreqplanv1); ok { - r0 = rf() - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).([]iot.ArduinoLorafreqplanv1) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func() error); ok { - r1 = rf() - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// ThingCreate provides a mock function with given fields: thing, force -func (_m *Client) ThingCreate(thing *iot.ThingCreate, force bool) (*iot.ArduinoThing, error) { - ret := _m.Called(thing, force) - - var r0 *iot.ArduinoThing - if rf, ok := ret.Get(0).(func(*iot.ThingCreate, bool) *iot.ArduinoThing); ok { - r0 = rf(thing, force) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*iot.ArduinoThing) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func(*iot.ThingCreate, bool) error); ok { - r1 = rf(thing, force) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// ThingDelete provides a mock function with given fields: id -func (_m *Client) ThingDelete(id string) error { - ret := _m.Called(id) - - var r0 error - if rf, ok := ret.Get(0).(func(string) error); ok { - r0 = rf(id) - } else { - r0 = ret.Error(0) - } - - return r0 -} - -// ThingList provides a mock function with given fields: ids, device, props, tags -func (_m *Client) ThingList(ids []string, device *string, props bool, tags map[string]string) ([]iot.ArduinoThing, error) { - ret := _m.Called(ids, device, props, tags) - - var r0 []iot.ArduinoThing - if rf, ok := ret.Get(0).(func([]string, *string, bool, map[string]string) []iot.ArduinoThing); ok { - r0 = rf(ids, device, props, tags) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).([]iot.ArduinoThing) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func([]string, *string, bool, map[string]string) error); ok { - r1 = rf(ids, device, props, tags) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// ThingShow provides a mock function with given fields: id -func (_m *Client) ThingShow(id string) (*iot.ArduinoThing, error) { - ret := _m.Called(id) - - var r0 *iot.ArduinoThing - if rf, ok := ret.Get(0).(func(string) *iot.ArduinoThing); ok { - r0 = rf(id) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*iot.ArduinoThing) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func(string) error); ok { - r1 = rf(id) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// ThingTagsCreate provides a mock function with given fields: id, tags -func (_m *Client) ThingTagsCreate(id string, tags map[string]string) error { - ret := _m.Called(id, tags) - - var r0 error - if rf, ok := ret.Get(0).(func(string, map[string]string) error); ok { - r0 = rf(id, tags) - } else { - r0 = ret.Error(0) - } - - return r0 -} - -// ThingTagsDelete provides a mock function with given fields: id, keys -func (_m *Client) ThingTagsDelete(id string, keys []string) error { - ret := _m.Called(id, keys) - - var r0 error - if rf, ok := ret.Get(0).(func(string, []string) error); ok { - r0 = rf(id, keys) - } else { - r0 = ret.Error(0) - } - - return r0 -} - -// ThingUpdate provides a mock function with given fields: id, thing, force -func (_m *Client) ThingUpdate(id string, thing *iot.ThingUpdate, force bool) error { - ret := _m.Called(id, thing, force) - - var r0 error - if rf, ok := ret.Get(0).(func(string, *iot.ThingUpdate, bool) error); ok { - r0 = rf(id, thing, force) - } else { - r0 = ret.Error(0) - } - - return r0 -} diff --git a/internal/template/dashboard.go b/internal/template/dashboard.go index 4e6f36aa..607cf08e 100644 --- a/internal/template/dashboard.go +++ b/internal/template/dashboard.go @@ -21,7 +21,7 @@ import ( "encoding/json" "fmt" - "github.com/arduino/arduino-cloud-cli/internal/iot" + iotclient "github.com/arduino/iot-client-go" ) type dashboardTemplate struct { @@ -61,10 +61,15 @@ func (v *variableTemplate) MarshalJSON() ([]byte, error) { return json.Marshal(v.VariableID) } +// ThingFetcher wraps the method to fetch a thing given its id. +type ThingFetcher interface { + ThingShow(id string) (*iotclient.ArduinoThing, error) +} + // getVariableID returns the id of a variable, given its name and its thing id. // If the variable is not found, an error is returned. -func getVariableID(thingID string, variableName string, iotClient iot.Client) (string, error) { - thing, err := iotClient.ThingShow(thingID) +func getVariableID(thingID string, variableName string, fetcher ThingFetcher) (string, error) { + thing, err := fetcher.ThingShow(thingID) if err != nil { return "", fmt.Errorf("getting variables of thing %s: %w", thingID, err) } diff --git a/internal/template/load.go b/internal/template/load.go index c10fdebd..9a5c21b7 100644 --- a/internal/template/load.go +++ b/internal/template/load.go @@ -24,7 +24,6 @@ import ( "io/ioutil" "os" - "github.com/arduino/arduino-cloud-cli/internal/iot" iotclient "github.com/arduino/iot-client-go" "github.com/gofrs/uuid" "gopkg.in/yaml.v3" @@ -87,8 +86,8 @@ func LoadThing(file string) (*iotclient.ThingCreate, error) { // LoadDashboard loads a dashboard from a dashboard template file. // It applies the thing overrides specified by the override parameter. -// It requires an iot.Client parameter to retrieve the actual variable id. -func LoadDashboard(file string, override map[string]string, iotClient iot.Client) (*iotclient.Dashboardv2, error) { +// It requires a ThingFetcher to retrieve the actual variable ids. +func LoadDashboard(file string, override map[string]string, thinger ThingFetcher) (*iotclient.Dashboardv2, error) { template := dashboardTemplate{} err := loadTemplate(file, &template) if err != nil { @@ -114,7 +113,7 @@ func LoadDashboard(file string, override map[string]string, iotClient iot.Client if id, ok := override[variable.ThingID]; ok { variable.ThingID = id } - variable.VariableID, err = getVariableID(variable.ThingID, variable.VariableName, iotClient) + variable.VariableID, err = getVariableID(variable.ThingID, variable.VariableName, thinger) if err != nil { return nil, err } diff --git a/internal/template/load_test.go b/internal/template/load_test.go index 3790d09c..01d95bbe 100644 --- a/internal/template/load_test.go +++ b/internal/template/load_test.go @@ -20,11 +20,9 @@ package template import ( "testing" - "github.com/arduino/arduino-cloud-cli/internal/iot/mocks" iotclient "github.com/arduino/iot-client-go" "github.com/gofrs/uuid" "github.com/google/go-cmp/cmp" - "github.com/stretchr/testify/mock" ) const ( @@ -145,26 +143,27 @@ func TestLoadTemplate(t *testing.T) { } } -func TestLoadDashboard(t *testing.T) { - mockClient := &mocks.Client{} - mockThingShow := func(thingID string) *iotclient.ArduinoThing { - if thingID == thingOverriddenID { - return &iotclient.ArduinoThing{ - Properties: []iotclient.ArduinoProperty{ - {Id: switchyOverriddenID, Name: "switchy"}, - }, - } - } +type thingShowTest struct{} + +func (t *thingShowTest) ThingShow(thingID string) (*iotclient.ArduinoThing, error) { + if thingID == thingOverriddenID { return &iotclient.ArduinoThing{ Properties: []iotclient.ArduinoProperty{ - {Id: switchyID, Name: "switchy"}, - {Id: relayID, Name: "relay_2"}, - {Id: blinkSpeedID, Name: "blink_speed"}, + {Id: switchyOverriddenID, Name: "switchy"}, }, - } + }, nil } - mockClient.On("ThingShow", mock.AnythingOfType("string")).Return(mockThingShow, nil) + return &iotclient.ArduinoThing{ + Properties: []iotclient.ArduinoProperty{ + {Id: switchyID, Name: "switchy"}, + {Id: relayID, Name: "relay_2"}, + {Id: blinkSpeedID, Name: "blink_speed"}, + }, + }, nil +} +func TestLoadDashboard(t *testing.T) { + mockThingShow := &thingShowTest{} tests := []struct { name string file string @@ -216,7 +215,7 @@ func TestLoadDashboard(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - got, err := LoadDashboard(tt.file, tt.override, mockClient) + got, err := LoadDashboard(tt.file, tt.override, mockThingShow) if err != nil { t.Errorf("%v", err) }