Skip to content

Commit baf246a

Browse files
committed
Added integration test for library install in bundled directory
1 parent 1e26fdf commit baf246a

File tree

3 files changed

+186
-12
lines changed

3 files changed

+186
-12
lines changed

Diff for: arduino/libraries/librariesmanager/librariesmanager.go

+1
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,7 @@ func NewLibraryManager(indexDir *paths.Path, downloadsDir *paths.Path) *Librarie
118118
// LoadIndex reads a library_index.json from a file and returns
119119
// the corresponding Index structure.
120120
func (lm *LibrariesManager) LoadIndex() error {
121+
logrus.WithField("index", lm.IndexFile).Info("Loading libraries index file")
121122
index, err := librariesindex.LoadIndex(lm.IndexFile)
122123
if err != nil {
123124
lm.Index = librariesindex.EmptyIndex

Diff for: internal/integrationtest/arduino-cli.go

+62-12
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ package integrationtest
1818
import (
1919
"bytes"
2020
"context"
21+
"encoding/json"
2122
"fmt"
2223
"io"
2324
"os"
@@ -27,6 +28,7 @@ import (
2728

2829
"github.com/arduino/arduino-cli/executils"
2930
"github.com/arduino/arduino-cli/rpc/cc/arduino/cli/commands/v1"
31+
"github.com/arduino/arduino-cli/rpc/cc/arduino/cli/settings/v1"
3032
"github.com/arduino/go-paths-helper"
3133
"github.com/fatih/color"
3234
"github.com/stretchr/testify/require"
@@ -36,17 +38,18 @@ import (
3638

3739
// ArduinoCLI is an Arduino CLI client.
3840
type ArduinoCLI struct {
39-
path *paths.Path
40-
t *require.Assertions
41-
proc *executils.Process
42-
cliEnvVars []string
43-
cliConfigPath *paths.Path
44-
stagingDir *paths.Path
45-
dataDir *paths.Path
46-
sketchbookDir *paths.Path
47-
daemonAddr string
48-
daemonConn *grpc.ClientConn
49-
daemonClient commands.ArduinoCoreServiceClient
41+
path *paths.Path
42+
t *require.Assertions
43+
proc *executils.Process
44+
cliEnvVars []string
45+
cliConfigPath *paths.Path
46+
stagingDir *paths.Path
47+
dataDir *paths.Path
48+
sketchbookDir *paths.Path
49+
daemonAddr string
50+
daemonConn *grpc.ClientConn
51+
daemonClient commands.ArduinoCoreServiceClient
52+
daemonSettingsClient settings.SettingsServiceClient
5053
}
5154

5255
// ArduinoCLIConfig is the configuration of the ArduinoCLI client
@@ -171,7 +174,7 @@ func (cli *ArduinoCLI) StartDaemon(verbose bool) string {
171174
cli.t.NoError(err)
172175
cli.daemonConn = conn
173176
cli.daemonClient = commands.NewArduinoCoreServiceClient(conn)
174-
177+
cli.daemonSettingsClient = settings.NewSettingsServiceClient(conn)
175178
return cli.daemonAddr
176179
}
177180

@@ -201,6 +204,17 @@ func (cli *ArduinoCLI) Create() *ArduinoCLIInstance {
201204
}
202205
}
203206

207+
// SetValue calls the "SetValue" gRPC method.
208+
func (cli *ArduinoCLI) SetValue(key, jsonData string) error {
209+
req := &settings.SetValueRequest{
210+
Key: key,
211+
JsonData: jsonData,
212+
}
213+
logCallf(">>> SetValue(%+v)\n", req)
214+
_, err := cli.daemonSettingsClient.SetValue(context.Background(), req)
215+
return err
216+
}
217+
204218
// Init calls the "Init" gRPC method.
205219
func (inst *ArduinoCLIInstance) Init(profile string, sketchPath string, respCB func(*commands.InitResponse)) error {
206220
initReq := &commands.InitRequest{
@@ -277,3 +291,39 @@ func (inst *ArduinoCLIInstance) Compile(ctx context.Context, fqbn, sketchPath st
277291
logCallf(">>> Compile(%v %v)\n", fqbn, sketchPath)
278292
return compileCl, err
279293
}
294+
295+
// LibraryList calls the "LibraryList" gRPC method.
296+
func (inst *ArduinoCLIInstance) LibraryList(ctx context.Context, name, fqbn string, all, updatable bool) (*commands.LibraryListResponse, error) {
297+
req := &commands.LibraryListRequest{
298+
Instance: inst.instance,
299+
Name: name,
300+
Fqbn: fqbn,
301+
All: all,
302+
Updatable: updatable,
303+
}
304+
logCallf(">>> LibraryList(%v) -> ", req)
305+
resp, err := inst.cli.daemonClient.LibraryList(ctx, req)
306+
logCallf("err=%v\n", err)
307+
r, _ := json.MarshalIndent(resp, " ", " ")
308+
logCallf("<<< LibraryList resp: %s\n", string(r))
309+
return resp, err
310+
}
311+
312+
// LibraryInstall calls the "LibraryInstall" gRPC method.
313+
func (inst *ArduinoCLIInstance) LibraryInstall(ctx context.Context, name, version string, noDeps, noOverwrite, installAsBundled bool) (commands.ArduinoCoreService_LibraryInstallClient, error) {
314+
installLocation := commands.LibraryInstallLocation_LIBRARY_INSTALL_LOCATION_USER
315+
if installAsBundled {
316+
installLocation = commands.LibraryInstallLocation_LIBRARY_INSTALL_LOCATION_BUILTIN
317+
}
318+
req := &commands.LibraryInstallRequest{
319+
Instance: inst.instance,
320+
Name: name,
321+
Version: version,
322+
NoDeps: noDeps,
323+
NoOverwrite: noOverwrite,
324+
InstallLocation: installLocation,
325+
}
326+
installCl, err := inst.cli.daemonClient.LibraryInstall(ctx, req)
327+
logCallf(">>> LibraryInstall(%+v)\n", req)
328+
return installCl, err
329+
}
+123
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
// This file is part of arduino-cli.
2+
//
3+
// Copyright 2022 ARDUINO SA (http://www.arduino.cc/)
4+
//
5+
// This software is released under the GNU General Public License version 3,
6+
// which covers the main part of arduino-cli.
7+
// The terms of this license can be found at:
8+
// https://www.gnu.org/licenses/gpl-3.0.en.html
9+
//
10+
// You can be released from the requirements of the above licenses by purchasing
11+
// a commercial license. Buying such a license is mandatory if you want to
12+
// modify or otherwise use the software for commercial activities involving the
13+
// Arduino software without disclosing the source code of your own applications.
14+
// To purchase a commercial license, send an email to [email protected].
15+
16+
package daemon_test
17+
18+
import (
19+
"context"
20+
"fmt"
21+
"io"
22+
"testing"
23+
24+
"github.com/arduino/arduino-cli/rpc/cc/arduino/cli/commands/v1"
25+
"github.com/stretchr/testify/require"
26+
)
27+
28+
func TestDaemonBundleLibInstall(t *testing.T) {
29+
env, cli := createEnvForDaemon(t)
30+
defer env.CleanUp()
31+
32+
grpcInst := cli.Create()
33+
require.NoError(t, grpcInst.Init("", "", func(ir *commands.InitResponse) {
34+
fmt.Printf("INIT> %v\n", ir.GetMessage())
35+
}))
36+
37+
// Install libraries in bundled dir (should fail)
38+
{
39+
instCl, err := grpcInst.LibraryInstall(context.Background(), "Arduino_BuiltIn", "", false, false, true)
40+
require.NoError(t, err)
41+
for {
42+
msg, err := instCl.Recv()
43+
if err == io.EOF {
44+
require.FailNow(t, "LibraryInstall is supposed to fail because builtin libraries directory is not set")
45+
}
46+
if err != nil {
47+
fmt.Println("LIB INSTALL ERROR:", err)
48+
break
49+
}
50+
fmt.Printf("LIB INSTALL> %+v\n", msg)
51+
}
52+
}
53+
54+
// Set builtin libraries dir
55+
builtinLibsDir := cli.DataDir().Join("libraries")
56+
err := cli.SetValue("directories.builtin.libraries", fmt.Sprintf(`"%s"`, builtinLibsDir))
57+
require.NoError(t, err)
58+
59+
// Re-init
60+
require.NoError(t, grpcInst.Init("", "", func(ir *commands.InitResponse) {
61+
fmt.Printf("INIT> %v\n", ir.GetMessage())
62+
}))
63+
64+
// Install libraries in bundled dir
65+
{
66+
instCl, err := grpcInst.LibraryInstall(context.Background(), "Arduino_BuiltIn", "", false, false, true)
67+
require.NoError(t, err)
68+
for {
69+
msg, err := instCl.Recv()
70+
if err == io.EOF {
71+
break
72+
}
73+
require.NoError(t, err)
74+
fmt.Printf("LIB INSTALL> %+v\n", msg)
75+
}
76+
}
77+
78+
// Check if libraries are installed as expected
79+
{
80+
resp, err := grpcInst.LibraryList(context.Background(), "", "", true, false)
81+
require.NoError(t, err)
82+
libsAndLocation := map[string]commands.LibraryLocation{}
83+
for _, lib := range resp.GetInstalledLibraries() {
84+
libsAndLocation[lib.Library.Name] = lib.Library.Location
85+
}
86+
require.Contains(t, libsAndLocation, "Ethernet")
87+
require.Contains(t, libsAndLocation, "SD")
88+
require.Contains(t, libsAndLocation, "Firmata")
89+
require.Equal(t, libsAndLocation["Ethernet"], commands.LibraryLocation_LIBRARY_LOCATION_BUILTIN)
90+
require.Equal(t, libsAndLocation["SD"], commands.LibraryLocation_LIBRARY_LOCATION_BUILTIN)
91+
require.Equal(t, libsAndLocation["Firmata"], commands.LibraryLocation_LIBRARY_LOCATION_BUILTIN)
92+
}
93+
94+
// Install a library in sketchbook to override bundled
95+
{
96+
instCl, err := grpcInst.LibraryInstall(context.Background(), "Ethernet", "", false, false, false)
97+
require.NoError(t, err)
98+
for {
99+
msg, err := instCl.Recv()
100+
if err == io.EOF {
101+
break
102+
}
103+
require.NoError(t, err)
104+
fmt.Printf("LIB INSTALL> %+v\n", msg)
105+
}
106+
}
107+
108+
// Check if libraries are installed as expected
109+
{
110+
resp, err := grpcInst.LibraryList(context.Background(), "", "", true, false)
111+
require.NoError(t, err)
112+
libsAndLocation := map[string]commands.LibraryLocation{}
113+
for _, lib := range resp.GetInstalledLibraries() {
114+
libsAndLocation[lib.Library.Name] = lib.Library.Location
115+
}
116+
require.Contains(t, libsAndLocation, "Ethernet")
117+
require.Contains(t, libsAndLocation, "SD")
118+
require.Contains(t, libsAndLocation, "Firmata")
119+
require.Equal(t, libsAndLocation["Ethernet"], commands.LibraryLocation_LIBRARY_LOCATION_USER)
120+
require.Equal(t, libsAndLocation["SD"], commands.LibraryLocation_LIBRARY_LOCATION_BUILTIN)
121+
require.Equal(t, libsAndLocation["Firmata"], commands.LibraryLocation_LIBRARY_LOCATION_BUILTIN)
122+
}
123+
}

0 commit comments

Comments
 (0)