Skip to content

Commit 0054738

Browse files
authored
[skip-changelog] Porting legacy tests to new integration-test infra (part 2...) (#2295)
* Ported legacy TestIncludesToIncludeFolders test * Ported legacy TestIncludesToIncludeFoldersANewLibrary test * Ported legacy TestIncludesToIncludeFoldersDuplicateLibs* test Also improved build options in test
1 parent 8ba101c commit 0054738

File tree

20 files changed

+2022
-161
lines changed

20 files changed

+2022
-161
lines changed

internal/integrationtest/compile_4/compile_test.go

+96-15
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,11 @@ func TestCompileOfProblematicSketches(t *testing.T) {
6363
_, _, err = cli.Run("lib", "install", "CapacitiveSensor@0.5")
6464
require.NoError(t, err)
6565

66+
// Install custom hardware required for tests
67+
customHwDir, err := paths.New("testdata", "user_hardware").Abs()
68+
require.NoError(t, err)
69+
require.NoError(t, customHwDir.CopyDirTo(cli.SketchbookDir().Join("hardware")))
70+
6671
integrationtest.CLISubtests{
6772
{"SketchWithInlineFunction", testBuilderSketchWithInlineFunction},
6873
{"SketchWithConst", testBuilderSketchWithConst},
@@ -97,6 +102,8 @@ func TestCompileOfProblematicSketches(t *testing.T) {
97102
{"SketchWithFunctionPointer", tryBuildAvrLeonardo},
98103
{"USBHostExample", testBuilderUSBHostExample},
99104
{"SketchWithConflictingLibraries", testBuilderSketchWithConflictingLibraries},
105+
{"SketchLibraryProvidesAllIncludes", testBuilderSketchLibraryProvidesAllIncludes},
106+
{"UserHardware", testBuilderWithUserHardware},
100107
}.Run(t, env, cli)
101108
}
102109

@@ -322,8 +329,12 @@ func testBuilderBridgeExample(t *testing.T, env *integrationtest.Environment, cl
322329
require.True(t, buildPath.Join("BridgeExample.ino.hex").Exist())
323330
require.True(t, buildPath.Join("libraries", "Bridge", "Mailbox.cpp.o").Exist())
324331

332+
libs := out.BuilderResult.UsedLibraries
333+
require.Len(t, libs, 1)
334+
require.Equal(t, "Bridge", libs[0].Name)
335+
325336
// Build again...
326-
out2, err2 := tryBuild(t, env, cli, "arduino:avr:leonardo", "no-clean")
337+
out2, err2 := tryBuild(t, env, cli, "arduino:avr:leonardo", &buildOptions{NoClean: true})
327338
require.NoError(t, err2)
328339
buildPath2 := out2.BuilderResult.BuildPath
329340
require.True(t, buildPath2.Join("core", "HardwareSerial.cpp.o").Exist())
@@ -335,7 +346,7 @@ func testBuilderBridgeExample(t *testing.T, env *integrationtest.Environment, cl
335346

336347
t.Run("BuildForSAM", func(t *testing.T) {
337348
// Build again for SAM...
338-
out, err := tryBuild(t, env, cli, "arduino:sam:arduino_due_x_dbg", "all-warnings")
349+
out, err := tryBuild(t, env, cli, "arduino:sam:arduino_due_x_dbg", &buildOptions{AllWarnings: true})
339350
require.NoError(t, err)
340351

341352
buildPath := out.BuilderResult.BuildPath
@@ -358,7 +369,7 @@ func testBuilderBridgeExample(t *testing.T, env *integrationtest.Environment, cl
358369

359370
t.Run("BuildForRedBearAVR", func(t *testing.T) {
360371
// Build again for RedBearLab...
361-
out, err := tryBuild(t, env, cli, "RedBear:avr:blend", "verbose")
372+
out, err := tryBuild(t, env, cli, "RedBear:avr:blend", &buildOptions{Verbose: true})
362373
require.NoError(t, err)
363374
buildPath := out.BuilderResult.BuildPath
364375
require.True(t, buildPath.Join("core", "HardwareSerial.cpp.o").Exist())
@@ -377,7 +388,7 @@ func testBuilderBridgeExample(t *testing.T, env *integrationtest.Environment, cl
377388
require.NoError(t, buildPath.Join("libraries", "SPI").MkdirAll())
378389

379390
// Build again...
380-
_, err = tryBuild(t, env, cli, "arduino:avr:leonardo", "no-clean")
391+
_, err = tryBuild(t, env, cli, "arduino:avr:leonardo", &buildOptions{NoClean: true})
381392
require.NoError(t, err)
382393

383394
require.False(t, buildPath.Join("libraries", "SPI").Exist())
@@ -548,6 +559,52 @@ func testBuilderSketchWithConflictingLibraries(t *testing.T, env *integrationtes
548559
})
549560
}
550561

562+
func testBuilderSketchLibraryProvidesAllIncludes(t *testing.T, env *integrationtest.Environment, cli *integrationtest.ArduinoCLI) {
563+
t.Run("Build", func(t *testing.T) {
564+
// Build
565+
out, err := tryBuild(t, env, cli, "arduino:avr:leonardo")
566+
require.NoError(t, err)
567+
libs := out.BuilderResult.UsedLibraries
568+
slices.SortFunc(libs, func(x, y *builderLibrary) bool { return x.Name < y.Name })
569+
require.Len(t, libs, 2)
570+
require.Equal(t, "ANewLibrary-master", libs[0].Name)
571+
require.Equal(t, "IRremote", libs[1].Name)
572+
})
573+
}
574+
575+
func testBuilderWithUserHardware(t *testing.T, env *integrationtest.Environment, cli *integrationtest.ArduinoCLI) {
576+
coreSPILib, err := cli.SketchbookDir().Join("hardware", "my_avr_platform", "avr", "libraries", "SPI").Abs()
577+
require.NoError(t, err)
578+
sketchPath := coreSPILib.Join("examples", "BarometricPressureSensor", "BarometricPressureSensor.ino")
579+
580+
t.Run("TestIncludesToIncludeFoldersDuplicateLibs", func(t *testing.T) {
581+
out, err := tryBuild(t, env, cli, "my_avr_platform:avr:custom_yun", &buildOptions{
582+
Sketch: sketchPath,
583+
NoTestLibraries: true,
584+
})
585+
require.NoError(t, err)
586+
587+
importedLibraries := out.BuilderResult.UsedLibraries
588+
require.Equal(t, 1, len(importedLibraries))
589+
require.Equal(t, "SPI", importedLibraries[0].Name)
590+
require.True(t, importedLibraries[0].SourceDir.EquivalentTo(coreSPILib))
591+
})
592+
593+
t.Run("TestIncludesToIncludeFoldersDuplicateLibsWithConflictingLibsOutsideOfPlatform", func(t *testing.T) {
594+
SPILib, err := paths.New("testdata", "libraries", "SPI").Abs()
595+
require.NoError(t, err)
596+
out, err := tryBuild(t, env, cli, "my_avr_platform:avr:custom_yun", &buildOptions{
597+
Sketch: sketchPath,
598+
})
599+
require.NoError(t, err)
600+
601+
importedLibraries := out.BuilderResult.UsedLibraries
602+
require.Equal(t, 1, len(importedLibraries))
603+
require.Equal(t, "SPI", importedLibraries[0].Name)
604+
require.True(t, importedLibraries[0].SourceDir.EquivalentTo(SPILib))
605+
})
606+
}
607+
551608
func tryBuildAvrLeonardo(t *testing.T, env *integrationtest.Environment, cli *integrationtest.ArduinoCLI) {
552609
_, err := tryBuild(t, env, cli, "arduino:avr:leonardo")
553610
require.NoError(t, err)
@@ -568,25 +625,49 @@ type builderLibrary struct {
568625
SourceDir *paths.Path `json:"source_dir"`
569626
}
570627

571-
func tryBuild(t *testing.T, env *integrationtest.Environment, cli *integrationtest.ArduinoCLI, fqbn string, options ...string) (*builderOutput, error) {
572-
subTestName := strings.Split(t.Name(), "/")[1]
573-
sketchPath, err := paths.New("testdata", subTestName).Abs()
574-
require.NoError(t, err)
575-
libsPath, err := paths.New("testdata", "libraries").Abs()
576-
require.NoError(t, err)
628+
type buildOptions struct {
629+
Sketch *paths.Path
630+
NoTestLibraries bool
631+
CustomLibPath *paths.Path
632+
NoClean bool
633+
AllWarnings bool
634+
Verbose bool
635+
}
636+
637+
func tryBuild(t *testing.T, env *integrationtest.Environment, cli *integrationtest.ArduinoCLI, fqbn string, optionsArg ...*buildOptions) (*builderOutput, error) {
638+
var options *buildOptions
639+
if len(optionsArg) == 0 {
640+
options = &buildOptions{}
641+
} else {
642+
require.Len(t, optionsArg, 1)
643+
options = optionsArg[0]
644+
}
645+
if options.Sketch == nil {
646+
subTestName := strings.Split(t.Name(), "/")[1]
647+
sketchPath, err := paths.New("testdata", subTestName).Abs()
648+
require.NoError(t, err)
649+
options.Sketch = sketchPath
650+
}
577651
args := []string{
578652
"compile",
579653
"-b", fqbn,
580-
"--libraries", libsPath.String(),
581654
"--format", "json",
582-
sketchPath.String()}
583-
if !slices.Contains(options, "no-clean") {
655+
options.Sketch.String()}
656+
if !options.NoTestLibraries {
657+
libsPath, err := paths.New("testdata", "libraries").Abs()
658+
require.NoError(t, err)
659+
args = append(args, "--libraries", libsPath.String())
660+
}
661+
if options.CustomLibPath != nil {
662+
args = append(args, "--library", options.CustomLibPath.String())
663+
}
664+
if !options.NoClean {
584665
args = append(args, "--clean")
585666
}
586-
if slices.Contains(options, "all-warnings") {
667+
if options.AllWarnings {
587668
args = append(args, "--warnings", "all")
588669
}
589-
if slices.Contains(options, "verbose") {
670+
if options.Verbose {
590671
args = append(args, "-v")
591672
}
592673
jsonOut, _, err := cli.Run(args...)
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
#include <anewlibrary.h>
2-
#include <IRremoteInt.h>
2+
#include <IRremote.h>
33

44
void setup() {}
55
void loop() {}

internal/integrationtest/compile_4/testdata/libraries/ANewLibrary-master/anewlibrary.h

Whitespace-only changes.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,201 @@
1+
/*
2+
* Copyright (c) 2010 by Cristian Maglie <c.maglie@arduino.cc>
3+
* Copyright (c) 2014 by Paul Stoffregen <paul@pjrc.com> (Transaction API)
4+
* Copyright (c) 2014 by Matthijs Kooijman <matthijs@stdin.nl> (SPISettings AVR)
5+
* Copyright (c) 2014 by Andrew J. Kroll <xxxajk@gmail.com> (atomicity fixes)
6+
* SPI Master library for arduino.
7+
*
8+
* This file is free software; you can redistribute it and/or modify
9+
* it under the terms of either the GNU General Public License version 2
10+
* or the GNU Lesser General Public License version 2.1, both as
11+
* published by the Free Software Foundation.
12+
*/
13+
14+
#include "SPI.h"
15+
16+
SPIClass SPI;
17+
18+
uint8_t SPIClass::initialized = 0;
19+
uint8_t SPIClass::interruptMode = 0;
20+
uint8_t SPIClass::interruptMask = 0;
21+
uint8_t SPIClass::interruptSave = 0;
22+
#ifdef SPI_TRANSACTION_MISMATCH_LED
23+
uint8_t SPIClass::inTransactionFlag = 0;
24+
#endif
25+
26+
void SPIClass::begin()
27+
{
28+
uint8_t sreg = SREG;
29+
noInterrupts(); // Protect from a scheduler and prevent transactionBegin
30+
if (!initialized) {
31+
// Set SS to high so a connected chip will be "deselected" by default
32+
uint8_t port = digitalPinToPort(SS);
33+
uint8_t bit = digitalPinToBitMask(SS);
34+
volatile uint8_t *reg = portModeRegister(port);
35+
36+
// if the SS pin is not already configured as an output
37+
// then set it high (to enable the internal pull-up resistor)
38+
if(!(*reg & bit)){
39+
digitalWrite(SS, HIGH);
40+
}
41+
42+
// When the SS pin is set as OUTPUT, it can be used as
43+
// a general purpose output port (it doesn't influence
44+
// SPI operations).
45+
pinMode(SS, OUTPUT);
46+
47+
// Warning: if the SS pin ever becomes a LOW INPUT then SPI
48+
// automatically switches to Slave, so the data direction of
49+
// the SS pin MUST be kept as OUTPUT.
50+
SPCR |= _BV(MSTR);
51+
SPCR |= _BV(SPE);
52+
53+
// Set direction register for SCK and MOSI pin.
54+
// MISO pin automatically overrides to INPUT.
55+
// By doing this AFTER enabling SPI, we avoid accidentally
56+
// clocking in a single bit since the lines go directly
57+
// from "input" to SPI control.
58+
// http://code.google.com/p/arduino/issues/detail?id=888
59+
pinMode(SCK, OUTPUT);
60+
pinMode(MOSI, OUTPUT);
61+
}
62+
initialized++; // reference count
63+
SREG = sreg;
64+
}
65+
66+
void SPIClass::end() {
67+
uint8_t sreg = SREG;
68+
noInterrupts(); // Protect from a scheduler and prevent transactionBegin
69+
// Decrease the reference counter
70+
if (initialized)
71+
initialized--;
72+
// If there are no more references disable SPI
73+
if (!initialized) {
74+
SPCR &= ~_BV(SPE);
75+
interruptMode = 0;
76+
#ifdef SPI_TRANSACTION_MISMATCH_LED
77+
inTransactionFlag = 0;
78+
#endif
79+
}
80+
SREG = sreg;
81+
}
82+
83+
// mapping of interrupt numbers to bits within SPI_AVR_EIMSK
84+
#if defined(__AVR_ATmega32U4__)
85+
#define SPI_INT0_MASK (1<<INT0)
86+
#define SPI_INT1_MASK (1<<INT1)
87+
#define SPI_INT2_MASK (1<<INT2)
88+
#define SPI_INT3_MASK (1<<INT3)
89+
#define SPI_INT4_MASK (1<<INT6)
90+
#elif defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB1286__)
91+
#define SPI_INT0_MASK (1<<INT0)
92+
#define SPI_INT1_MASK (1<<INT1)
93+
#define SPI_INT2_MASK (1<<INT2)
94+
#define SPI_INT3_MASK (1<<INT3)
95+
#define SPI_INT4_MASK (1<<INT4)
96+
#define SPI_INT5_MASK (1<<INT5)
97+
#define SPI_INT6_MASK (1<<INT6)
98+
#define SPI_INT7_MASK (1<<INT7)
99+
#elif defined(EICRA) && defined(EICRB) && defined(EIMSK)
100+
#define SPI_INT0_MASK (1<<INT4)
101+
#define SPI_INT1_MASK (1<<INT5)
102+
#define SPI_INT2_MASK (1<<INT0)
103+
#define SPI_INT3_MASK (1<<INT1)
104+
#define SPI_INT4_MASK (1<<INT2)
105+
#define SPI_INT5_MASK (1<<INT3)
106+
#define SPI_INT6_MASK (1<<INT6)
107+
#define SPI_INT7_MASK (1<<INT7)
108+
#else
109+
#ifdef INT0
110+
#define SPI_INT0_MASK (1<<INT0)
111+
#endif
112+
#ifdef INT1
113+
#define SPI_INT1_MASK (1<<INT1)
114+
#endif
115+
#ifdef INT2
116+
#define SPI_INT2_MASK (1<<INT2)
117+
#endif
118+
#endif
119+
120+
void SPIClass::usingInterrupt(uint8_t interruptNumber)
121+
{
122+
uint8_t mask = 0;
123+
uint8_t sreg = SREG;
124+
noInterrupts(); // Protect from a scheduler and prevent transactionBegin
125+
switch (interruptNumber) {
126+
#ifdef SPI_INT0_MASK
127+
case 0: mask = SPI_INT0_MASK; break;
128+
#endif
129+
#ifdef SPI_INT1_MASK
130+
case 1: mask = SPI_INT1_MASK; break;
131+
#endif
132+
#ifdef SPI_INT2_MASK
133+
case 2: mask = SPI_INT2_MASK; break;
134+
#endif
135+
#ifdef SPI_INT3_MASK
136+
case 3: mask = SPI_INT3_MASK; break;
137+
#endif
138+
#ifdef SPI_INT4_MASK
139+
case 4: mask = SPI_INT4_MASK; break;
140+
#endif
141+
#ifdef SPI_INT5_MASK
142+
case 5: mask = SPI_INT5_MASK; break;
143+
#endif
144+
#ifdef SPI_INT6_MASK
145+
case 6: mask = SPI_INT6_MASK; break;
146+
#endif
147+
#ifdef SPI_INT7_MASK
148+
case 7: mask = SPI_INT7_MASK; break;
149+
#endif
150+
default:
151+
interruptMode = 2;
152+
break;
153+
}
154+
interruptMask |= mask;
155+
if (!interruptMode)
156+
interruptMode = 1;
157+
SREG = sreg;
158+
}
159+
160+
void SPIClass::notUsingInterrupt(uint8_t interruptNumber)
161+
{
162+
// Once in mode 2 we can't go back to 0 without a proper reference count
163+
if (interruptMode == 2)
164+
return;
165+
uint8_t mask = 0;
166+
uint8_t sreg = SREG;
167+
noInterrupts(); // Protect from a scheduler and prevent transactionBegin
168+
switch (interruptNumber) {
169+
#ifdef SPI_INT0_MASK
170+
case 0: mask = SPI_INT0_MASK; break;
171+
#endif
172+
#ifdef SPI_INT1_MASK
173+
case 1: mask = SPI_INT1_MASK; break;
174+
#endif
175+
#ifdef SPI_INT2_MASK
176+
case 2: mask = SPI_INT2_MASK; break;
177+
#endif
178+
#ifdef SPI_INT3_MASK
179+
case 3: mask = SPI_INT3_MASK; break;
180+
#endif
181+
#ifdef SPI_INT4_MASK
182+
case 4: mask = SPI_INT4_MASK; break;
183+
#endif
184+
#ifdef SPI_INT5_MASK
185+
case 5: mask = SPI_INT5_MASK; break;
186+
#endif
187+
#ifdef SPI_INT6_MASK
188+
case 6: mask = SPI_INT6_MASK; break;
189+
#endif
190+
#ifdef SPI_INT7_MASK
191+
case 7: mask = SPI_INT7_MASK; break;
192+
#endif
193+
default:
194+
break;
195+
// this case can't be reached
196+
}
197+
interruptMask &= ~mask;
198+
if (!interruptMask)
199+
interruptMode = 0;
200+
SREG = sreg;
201+
}

0 commit comments

Comments
 (0)