@@ -20,6 +20,7 @@ import (
20
20
"errors"
21
21
"fmt"
22
22
"io"
23
+ "sync"
23
24
"testing"
24
25
"time"
25
26
@@ -76,3 +77,51 @@ func TestArduinoCliDaemonCompileWithLotOfOutput(t *testing.T) {
76
77
testCompile ()
77
78
testCompile ()
78
79
}
80
+
81
+ func TestInitAndMonitorConcurrency (t * testing.T ) {
82
+ // See: https://github.com/arduino/arduino-cli/issues/2719
83
+
84
+ env , cli := integrationtest .CreateEnvForDaemon (t )
85
+ defer env .CleanUp ()
86
+
87
+ _ , _ , err := cli .Run ("core" , "install" , "arduino:avr" )
88
+ require .NoError (t , err )
89
+
90
+ grpcInst := cli .Create ()
91
+ require .NoError (t , grpcInst .Init ("" , "" , func (ir * commands.InitResponse ) {
92
+ fmt .Printf ("INIT> %v\n " , ir .GetMessage ())
93
+ }))
94
+
95
+ cli .InstallMockedSerialMonitor (t )
96
+
97
+ // Open the serial monitor for 5 seconds
98
+ ctx , cancel := context .WithTimeout (context .Background (), 5 * time .Second )
99
+ defer cancel ()
100
+ mon , err := grpcInst .Monitor (ctx , & commands.Port {
101
+ Address : "/dev/test" ,
102
+ Protocol : "serial" ,
103
+ })
104
+ require .NoError (t , err )
105
+ var monitorCompleted sync.WaitGroup
106
+ monitorCompleted .Add (1 )
107
+ go func () {
108
+ for {
109
+ msg , err := mon .Recv ()
110
+ if err != nil {
111
+ break
112
+ }
113
+ fmt .Println ("MON> " , msg )
114
+ }
115
+ fmt .Println ("MON CLOSED" )
116
+ monitorCompleted .Done ()
117
+ }()
118
+
119
+ // Check that Init completes without blocking when the monitor is open
120
+ start := time .Now ()
121
+ require .NoError (t , grpcInst .Init ("" , "" , func (ir * commands.InitResponse ) {
122
+ fmt .Printf ("INIT> %v\n " , ir .GetMessage ())
123
+ }))
124
+ require .LessOrEqual (t , time .Since (start ), 4 * time .Second )
125
+ cancel ()
126
+ monitorCompleted .Wait ()
127
+ }
0 commit comments