@@ -23,6 +23,7 @@ import (
2323 "fmt"
2424 "io"
2525 "os"
26+ "runtime"
2627 "strings"
2728 "sync"
2829 "testing"
@@ -204,32 +205,98 @@ func (cli *ArduinoCLI) convertEnvForExecutils(env map[string]string) []string {
204205// InstallMockedSerialDiscovery will replace the already installed serial-discovery
205206// with a mocked one.
206207func (cli * ArduinoCLI ) InstallMockedSerialDiscovery (t * testing.T ) {
208+ fmt .Println (color .BlueString ("<<< Install mocked serial-discovery" ))
209+
207210 // Build mocked serial-discovery
208- mockDir := FindRepositoryRootPath (t ).Join ("internal" , "integrationtest" , " mock_serial_discovery" )
211+ mockDir := FindRepositoryRootPath (t ).Join ("internal" , "mock_serial_discovery" )
209212 gobuild , err := executils .NewProcess (nil , "go" , "build" )
210213 require .NoError (t , err )
211214 gobuild .SetDirFromPath (mockDir )
212215 require .NoError (t , gobuild .Run (), "Building mocked serial-discovery" )
216+ ext := ""
217+ if runtime .GOOS == "windows" {
218+ ext = ".exe"
219+ }
220+ mockBin := mockDir .Join ("mock_serial_discovery" + ext )
221+ require .True (t , mockBin .Exist ())
222+ fmt .Println (color .HiBlackString (" Build of mocked serial-discovery succeeded." ))
213223
214224 // Install it replacing the current serial discovery
215- mockBin := mockDir .Join ("mock_serial_discovery" )
216225 dataDir := cli .DataDir ()
217226 require .NotNil (t , dataDir , "data dir missing" )
218227 serialDiscoveries , err := dataDir .Join ("packages" , "builtin" , "tools" , "serial-discovery" ).ReadDirRecursiveFiltered (
219228 nil , paths .AndFilter (
220- paths .FilterNames ("serial-discovery" ),
229+ paths .FilterNames ("serial-discovery" + ext ),
221230 paths .FilterOutDirectories (),
222231 ),
223232 )
224233 require .NoError (t , err , "scanning data dir for serial-discoveries" )
225234 require .NotEmpty (t , serialDiscoveries , "no serial-discoveries found in data dir" )
226235 for _ , serialDiscovery := range serialDiscoveries {
227236 require .NoError (t , mockBin .CopyTo (serialDiscovery ), "installing mocked serial discovery to %s" , serialDiscovery )
237+ fmt .Println (color .HiBlackString (" Discovery installed in " + serialDiscovery .String ()))
238+ }
239+ }
240+
241+ // InstallMockedSerialMonitor will replace the already installed serial-monitor
242+ // with a mocked one.
243+ func (cli * ArduinoCLI ) InstallMockedSerialMonitor (t * testing.T ) {
244+ fmt .Println (color .BlueString ("<<< Install mocked serial-monitor" ))
245+
246+ // Build mocked serial-monitor
247+ mockDir := FindRepositoryRootPath (t ).Join ("internal" , "mock_serial_monitor" )
248+ gobuild , err := executils .NewProcess (nil , "go" , "build" )
249+ require .NoError (t , err )
250+ gobuild .SetDirFromPath (mockDir )
251+ require .NoError (t , gobuild .Run (), "Building mocked serial-monitor" )
252+ ext := ""
253+ if runtime .GOOS == "windows" {
254+ ext = ".exe"
255+ }
256+ mockBin := mockDir .Join ("mock_serial_monitor" + ext )
257+ require .True (t , mockBin .Exist ())
258+ fmt .Println (color .HiBlackString (" Build of mocked serial-monitor succeeded." ))
259+
260+ // Install it replacing the current serial monitor
261+ dataDir := cli .DataDir ()
262+ require .NotNil (t , dataDir , "data dir missing" )
263+ serialMonitors , err := dataDir .Join ("packages" , "builtin" , "tools" , "serial-monitor" ).ReadDirRecursiveFiltered (
264+ nil , paths .AndFilter (
265+ paths .FilterNames ("serial-monitor" + ext ),
266+ paths .FilterOutDirectories (),
267+ ),
268+ )
269+ require .NoError (t , err , "scanning data dir for serial-monitor" )
270+ require .NotEmpty (t , serialMonitors , "no serial-monitor found in data dir" )
271+ for _ , serialMonitor := range serialMonitors {
272+ require .NoError (t , mockBin .CopyTo (serialMonitor ), "installing mocked serial monitor to %s" , serialMonitor )
273+ fmt .Println (color .HiBlackString (" Monitor installed in " + serialMonitor .String ()))
228274 }
229275}
230276
231277// RunWithCustomEnv executes the given arduino-cli command with the given custom env and returns the output.
232278func (cli * ArduinoCLI ) RunWithCustomEnv (env map [string ]string , args ... string ) ([]byte , []byte , error ) {
279+ var stdoutBuf , stderrBuf bytes.Buffer
280+ err := cli .run (& stdoutBuf , & stderrBuf , nil , env , args ... )
281+
282+ errBuf := stderrBuf .Bytes ()
283+ cli .t .NotContains (string (errBuf ), "panic: runtime error:" , "arduino-cli panicked" )
284+
285+ return stdoutBuf .Bytes (), errBuf , err
286+ }
287+
288+ // RunWithCustomInput executes the given arduino-cli command pushing the given input stream and returns the output.
289+ func (cli * ArduinoCLI ) RunWithCustomInput (in io.Reader , args ... string ) ([]byte , []byte , error ) {
290+ var stdoutBuf , stderrBuf bytes.Buffer
291+ err := cli .run (& stdoutBuf , & stderrBuf , in , cli .cliEnvVars , args ... )
292+
293+ errBuf := stderrBuf .Bytes ()
294+ cli .t .NotContains (string (errBuf ), "panic: runtime error:" , "arduino-cli panicked" )
295+
296+ return stdoutBuf .Bytes (), errBuf , err
297+ }
298+
299+ func (cli * ArduinoCLI ) run (stdoutBuff , stderrBuff io.Writer , stdinBuff io.Reader , env map [string ]string , args ... string ) error {
233300 if cli .cliConfigPath != nil {
234301 args = append ([]string {"--config-file" , cli .cliConfigPath .String ()}, args ... )
235302 }
@@ -240,35 +307,44 @@ func (cli *ArduinoCLI) RunWithCustomEnv(env map[string]string, args ...string) (
240307 cli .t .NoError (err )
241308 stderr , err := cliProc .StderrPipe ()
242309 cli .t .NoError (err )
243- _ , err = cliProc .StdinPipe ()
310+ stdin , err : = cliProc .StdinPipe ()
244311 cli .t .NoError (err )
245312 cliProc .SetDir (cli .WorkingDir ().String ())
246313
247314 cli .t .NoError (cliProc .Start ())
248315
249- var stdoutBuf , stderrBuf bytes.Buffer
250316 var wg sync.WaitGroup
251317 wg .Add (2 )
252318 go func () {
253319 defer wg .Done ()
254- if _ , err := io .Copy (& stdoutBuf , io .TeeReader (stdout , os .Stdout )); err != nil {
320+ if stdoutBuff == nil {
321+ stdoutBuff = io .Discard
322+ }
323+ if _ , err := io .Copy (stdoutBuff , io .TeeReader (stdout , os .Stdout )); err != nil {
255324 fmt .Println (color .HiBlackString ("<<< stdout copy error:" ), err )
256325 }
257326 }()
258327 go func () {
259328 defer wg .Done ()
260- if _ , err := io .Copy (& stderrBuf , io .TeeReader (stderr , os .Stderr )); err != nil {
329+ if stderrBuff == nil {
330+ stderrBuff = io .Discard
331+ }
332+ if _ , err := io .Copy (stderrBuff , io .TeeReader (stderr , os .Stderr )); err != nil {
261333 fmt .Println (color .HiBlackString ("<<< stderr copy error:" ), err )
262334 }
263335 }()
336+ if stdinBuff != nil {
337+ go func () {
338+ if _ , err := io .Copy (stdin , stdinBuff ); err != nil {
339+ fmt .Println (color .HiBlackString ("<<< stdin copy error:" ), err )
340+ }
341+ }()
342+ }
264343 wg .Wait ()
265344 cliErr := cliProc .Wait ()
266345 fmt .Println (color .HiBlackString ("<<< Run completed (err = %v)" , cliErr ))
267346
268- errBuf := stderrBuf .Bytes ()
269- cli .t .NotContains (string (errBuf ), "panic: runtime error:" , "arduino-cli panicked" )
270-
271- return stdoutBuf .Bytes (), errBuf , cliErr
347+ return cliErr
272348}
273349
274350// StartDaemon starts the Arduino CLI daemon. It returns the address of the daemon.
0 commit comments