From baa62061c1452dac5f55111ceae76dea5108d1a2 Mon Sep 17 00:00:00 2001 From: Cristian Maglie Date: Wed, 16 Sep 2020 13:56:44 +0200 Subject: [PATCH 1/9] Added more tests for upload --- .../testdata/hardware/alice/avr/boards.txt | 13 ++++ .../testdata/hardware/alice/avr/platform.txt | 21 ++++++ commands/upload/upload_test.go | 74 +++++++++++++++++++ 3 files changed, 108 insertions(+) create mode 100644 commands/upload/testdata/hardware/alice/avr/boards.txt create mode 100644 commands/upload/testdata/hardware/alice/avr/platform.txt diff --git a/commands/upload/testdata/hardware/alice/avr/boards.txt b/commands/upload/testdata/hardware/alice/avr/boards.txt new file mode 100644 index 00000000000..0816367610c --- /dev/null +++ b/commands/upload/testdata/hardware/alice/avr/boards.txt @@ -0,0 +1,13 @@ +board1.name=board1 +board1.conf.board=conf-board1 +board1.upload.tool=one +board1.upload.protocol=protocol +board1.upload.speed=speed + +board1.bootloader.tool=one +board1.bootloader.low_fuses=0xFF +board1.bootloader.high_fuses=0xDE +board1.bootloader.extended_fuses=0xFD +board1.bootloader.unlock_bits=0x3F +board1.bootloader.lock_bits=0x0F +board1.bootloader.file=optiboot/optiboot_atmega328.hex diff --git a/commands/upload/testdata/hardware/alice/avr/platform.txt b/commands/upload/testdata/hardware/alice/avr/platform.txt new file mode 100644 index 00000000000..9ce61aedbe9 --- /dev/null +++ b/commands/upload/testdata/hardware/alice/avr/platform.txt @@ -0,0 +1,21 @@ +name=Upload Test Platform (Alice) +version=1.0.0 + +# Upload test 1 +tools.one.cmd.path=echo +tools.one.conf.general=conf-general + +tools.one.upload.conf=conf-upload +tools.one.upload.params.verbose=verbose +tools.one.upload.params.quiet=quiet +tools.one.upload.params.verify=verify +tools.one.upload.params.noverify=noverify +tools.one.upload.pattern={cmd.path} {conf.board} {conf.general} {upload.conf} {upload.verbose} {upload.verify} {upload.protocol} "{serial.port}" -b{upload.speed} "{build.path}/{build.project_name}.hex" + +# Upload test 2 +tools.one-noport.cmd.path=echo +tools.one-noport.upload.params.verbose=verbose +tools.one-noport.upload.params.quiet=quiet +tools.one-noport.upload.verify=verify +tools.one-noport.upload.params.noverify=noverify +tools.one-noport.upload.pattern={cmd.path} {conf.general} {conf.upload} {upload.verbose} {upload.verify} {build.mcu} {upload.protocol} "{serial.port}" -b{upload.speed} "{build.path}/{build.project_name}.hex" diff --git a/commands/upload/upload_test.go b/commands/upload/upload_test.go index 54f34155e7e..5fae3792f37 100644 --- a/commands/upload/upload_test.go +++ b/commands/upload/upload_test.go @@ -16,10 +16,13 @@ package upload import ( + "bytes" "fmt" + "strings" "testing" "github.com/arduino/arduino-cli/arduino/cores" + "github.com/arduino/arduino-cli/arduino/cores/packagemanager" "github.com/arduino/arduino-cli/arduino/sketches" paths "github.com/arduino/go-paths-helper" "github.com/stretchr/testify/require" @@ -119,3 +122,74 @@ func TestDetermineBuildPathAndSketchName(t *testing.T) { }) } } + +func TestUploadPropertiesComposition(t *testing.T) { + pm := packagemanager.NewPackageManager(nil, nil, nil, nil) + err := pm.LoadHardwareFromDirectory(paths.New("testdata", "hardware")) + require.NoError(t, err) + buildPath1 := paths.New("testdata", "build_path_1") + + type test struct { + importDir *paths.Path + fqbn string + port string + programmer string + burnBootloader bool + expected string + } + + tests := []test{ + // classic upload, requires port + {buildPath1, "alice:avr:board1", "port", "", false, "conf-board1 conf-general conf-upload $$VERBOSE-VERIFY$$ protocol port -bspeed testdata/build_path_1/sketch.ino.hex"}, + } + for i, test := range tests { + t.Run(fmt.Sprintf("SubTest%02d", i), func(t *testing.T) { + outStream := &bytes.Buffer{} + errStream := &bytes.Buffer{} + err := runProgramAction( + pm, + nil, // sketch + "", // importFile + test.importDir.String(), // importDir + test.fqbn, // FQBN + test.port, // port + test.programmer, // programmer + false, // verbose + false, // verify + test.burnBootloader, // burnBootloader + outStream, + errStream, + ) + require.NoError(t, err) + out := strings.TrimSpace(outStream.String()) + require.Equal(t, strings.ReplaceAll(test.expected, "$$VERBOSE-VERIFY$$", "quiet noverify"), out) + }) + t.Run(fmt.Sprintf("SubTest%02d-WithVerifyAndVerbose", i), func(t *testing.T) { + outStream := &bytes.Buffer{} + errStream := &bytes.Buffer{} + err := runProgramAction( + pm, + nil, // sketch + "", // importFile + test.importDir.String(), // importDir + test.fqbn, // FQBN + test.port, // port + test.programmer, // programmer + true, // verbose + true, // verify + test.burnBootloader, // burnBootloader + outStream, + errStream, + ) + require.NoError(t, err) + out := strings.Split(outStream.String(), "\n") + // With verbose enabled, the upload will output 3 lines: + // - the command line that the cli is going to run + // - the output of the command + // - an empty line + // we are interested in the second line + require.Len(t, out, 3) + require.Equal(t, strings.ReplaceAll(test.expected, "$$VERBOSE-VERIFY$$", "verbose verify"), out[1]) + }) + } +} From e81a1f64aa162dca2336cf1d30e567345e13470a Mon Sep 17 00:00:00 2001 From: Cristian Maglie Date: Wed, 16 Sep 2020 15:41:07 +0200 Subject: [PATCH 2/9] Added test for upload without port --- .../testdata/hardware/alice/avr/boards.txt | 17 +++++++++ .../testdata/hardware/alice/avr/platform.txt | 7 ++-- commands/upload/upload_test.go | 36 ++++++++++++------- 3 files changed, 45 insertions(+), 15 deletions(-) diff --git a/commands/upload/testdata/hardware/alice/avr/boards.txt b/commands/upload/testdata/hardware/alice/avr/boards.txt index 0816367610c..93dcf80c9c9 100644 --- a/commands/upload/testdata/hardware/alice/avr/boards.txt +++ b/commands/upload/testdata/hardware/alice/avr/boards.txt @@ -11,3 +11,20 @@ board1.bootloader.extended_fuses=0xFD board1.bootloader.unlock_bits=0x3F board1.bootloader.lock_bits=0x0F board1.bootloader.file=optiboot/optiboot_atmega328.hex + + +board2.name=board2 +board2.conf.board=conf-board1 +board2.upload.tool=one-noport +board2.upload.protocol=protocol +board2.upload.speed=speed + +board2.bootloader.tool=one +board2.bootloader.low_fuses=0xFF +board2.bootloader.high_fuses=0xDE +board2.bootloader.extended_fuses=0xFD +board2.bootloader.unlock_bits=0x3F +board2.bootloader.lock_bits=0x0F +board2.bootloader.file=optiboot/optiboot_atmega328.hex + + diff --git a/commands/upload/testdata/hardware/alice/avr/platform.txt b/commands/upload/testdata/hardware/alice/avr/platform.txt index 9ce61aedbe9..29484caa2ab 100644 --- a/commands/upload/testdata/hardware/alice/avr/platform.txt +++ b/commands/upload/testdata/hardware/alice/avr/platform.txt @@ -4,7 +4,6 @@ version=1.0.0 # Upload test 1 tools.one.cmd.path=echo tools.one.conf.general=conf-general - tools.one.upload.conf=conf-upload tools.one.upload.params.verbose=verbose tools.one.upload.params.quiet=quiet @@ -14,8 +13,10 @@ tools.one.upload.pattern={cmd.path} {conf.board} {conf.general} {upload.conf} {u # Upload test 2 tools.one-noport.cmd.path=echo +tools.one-noport.conf.general=conf-general +tools.one-noport.upload.conf=conf-upload tools.one-noport.upload.params.verbose=verbose tools.one-noport.upload.params.quiet=quiet -tools.one-noport.upload.verify=verify +tools.one-noport.upload.params.verify=verify tools.one-noport.upload.params.noverify=noverify -tools.one-noport.upload.pattern={cmd.path} {conf.general} {conf.upload} {upload.verbose} {upload.verify} {build.mcu} {upload.protocol} "{serial.port}" -b{upload.speed} "{build.path}/{build.project_name}.hex" +tools.one-noport.upload.pattern={cmd.path} {conf.board} {conf.general} {upload.conf} {upload.verbose} {upload.verify} {upload.protocol} -b{upload.speed} "{build.path}/{build.project_name}.hex" diff --git a/commands/upload/upload_test.go b/commands/upload/upload_test.go index 5fae3792f37..06e8b4bea0d 100644 --- a/commands/upload/upload_test.go +++ b/commands/upload/upload_test.go @@ -141,6 +141,10 @@ func TestUploadPropertiesComposition(t *testing.T) { tests := []test{ // classic upload, requires port {buildPath1, "alice:avr:board1", "port", "", false, "conf-board1 conf-general conf-upload $$VERBOSE-VERIFY$$ protocol port -bspeed testdata/build_path_1/sketch.ino.hex"}, + {buildPath1, "alice:avr:board1", "", "", false, "FAIL"}, + // classic upload, no port + {buildPath1, "alice:avr:board2", "port", "", false, "conf-board1 conf-general conf-upload $$VERBOSE-VERIFY$$ protocol -bspeed testdata/build_path_1/sketch.ino.hex"}, + {buildPath1, "alice:avr:board2", "", "", false, "conf-board1 conf-general conf-upload $$VERBOSE-VERIFY$$ protocol -bspeed testdata/build_path_1/sketch.ino.hex"}, } for i, test := range tests { t.Run(fmt.Sprintf("SubTest%02d", i), func(t *testing.T) { @@ -160,9 +164,13 @@ func TestUploadPropertiesComposition(t *testing.T) { outStream, errStream, ) - require.NoError(t, err) - out := strings.TrimSpace(outStream.String()) - require.Equal(t, strings.ReplaceAll(test.expected, "$$VERBOSE-VERIFY$$", "quiet noverify"), out) + if test.expected == "FAIL" { + require.Error(t, err) + } else { + require.NoError(t, err) + out := strings.TrimSpace(outStream.String()) + require.Equal(t, strings.ReplaceAll(test.expected, "$$VERBOSE-VERIFY$$", "quiet noverify"), out) + } }) t.Run(fmt.Sprintf("SubTest%02d-WithVerifyAndVerbose", i), func(t *testing.T) { outStream := &bytes.Buffer{} @@ -181,15 +189,19 @@ func TestUploadPropertiesComposition(t *testing.T) { outStream, errStream, ) - require.NoError(t, err) - out := strings.Split(outStream.String(), "\n") - // With verbose enabled, the upload will output 3 lines: - // - the command line that the cli is going to run - // - the output of the command - // - an empty line - // we are interested in the second line - require.Len(t, out, 3) - require.Equal(t, strings.ReplaceAll(test.expected, "$$VERBOSE-VERIFY$$", "verbose verify"), out[1]) + if test.expected == "FAIL" { + require.Error(t, err) + } else { + require.NoError(t, err) + out := strings.Split(outStream.String(), "\n") + // With verbose enabled, the upload will output 3 lines: + // - the command line that the cli is going to run + // - the output of the command + // - an empty line + // we are interested in the second line + require.Len(t, out, 3) + require.Equal(t, strings.ReplaceAll(test.expected, "$$VERBOSE-VERIFY$$", "verbose verify"), out[1]) + } }) } } From f1a929f8312ea3d3728ed8c7bb624ec17ba712ba Mon Sep 17 00:00:00 2001 From: Cristian Maglie Date: Wed, 16 Sep 2020 15:59:12 +0200 Subject: [PATCH 3/9] Added test for upload without programmer (with and w/o port) --- .../testdata/hardware/alice/avr/boards.txt | 2 -- .../testdata/hardware/alice/avr/platform.txt | 35 +++++++++++++++++++ .../hardware/alice/avr/programmers.txt | 20 +++++++++++ commands/upload/upload_test.go | 10 ++++++ 4 files changed, 65 insertions(+), 2 deletions(-) create mode 100644 commands/upload/testdata/hardware/alice/avr/programmers.txt diff --git a/commands/upload/testdata/hardware/alice/avr/boards.txt b/commands/upload/testdata/hardware/alice/avr/boards.txt index 93dcf80c9c9..db2fe46fe6f 100644 --- a/commands/upload/testdata/hardware/alice/avr/boards.txt +++ b/commands/upload/testdata/hardware/alice/avr/boards.txt @@ -26,5 +26,3 @@ board2.bootloader.extended_fuses=0xFD board2.bootloader.unlock_bits=0x3F board2.bootloader.lock_bits=0x0F board2.bootloader.file=optiboot/optiboot_atmega328.hex - - diff --git a/commands/upload/testdata/hardware/alice/avr/platform.txt b/commands/upload/testdata/hardware/alice/avr/platform.txt index 29484caa2ab..5e4d62d10dd 100644 --- a/commands/upload/testdata/hardware/alice/avr/platform.txt +++ b/commands/upload/testdata/hardware/alice/avr/platform.txt @@ -11,6 +11,13 @@ tools.one.upload.params.verify=verify tools.one.upload.params.noverify=noverify tools.one.upload.pattern={cmd.path} {conf.board} {conf.general} {upload.conf} {upload.verbose} {upload.verify} {upload.protocol} "{serial.port}" -b{upload.speed} "{build.path}/{build.project_name}.hex" +tools.one.program.conf=conf-program +tools.one.program.params.verbose=verbose +tools.one.program.params.quiet=quiet +tools.one.program.params.verify=verify +tools.one.program.params.noverify=noverify +tools.one.program.pattern={cmd.path} {conf.board} {conf.general} {program.conf} {program.verbose} {program.verify} {program.protocol} "{serial.port}" -b{upload.speed} "{build.path}/{build.project_name}.hex" + # Upload test 2 tools.one-noport.cmd.path=echo tools.one-noport.conf.general=conf-general @@ -20,3 +27,31 @@ tools.one-noport.upload.params.quiet=quiet tools.one-noport.upload.params.verify=verify tools.one-noport.upload.params.noverify=noverify tools.one-noport.upload.pattern={cmd.path} {conf.board} {conf.general} {upload.conf} {upload.verbose} {upload.verify} {upload.protocol} -b{upload.speed} "{build.path}/{build.project_name}.hex" + +tools.one-noport.program.conf=conf-program +tools.one-noport.program.params.verbose=verbose +tools.one-noport.program.params.quiet=quiet +tools.one-noport.program.params.verify=verify +tools.one-noport.program.params.noverify=noverify +tools.one-noport.program.pattern={cmd.path} {conf.board} {conf.general} {program.conf} {program.verbose} {program.verify} {program.protocol} -b{upload.speed} "{build.path}/{build.project_name}.hex" + +# Recipes for "tool.one-extra-params" +tools.one-extra-params.cmd.path=echo +tools.one-extra-params.conf.general=conf-general + +tools.one-extra-params.program.conf=conf-program +tools.one-extra-params.program.params.verbose=verbose +tools.one-extra-params.program.params.quiet=quiet +tools.one-extra-params.program.params.verify=verify +tools.one-extra-params.program.params.noverify=noverify +tools.one-extra-params.program.pattern={cmd.path} {conf.board} {conf.general} {program.conf} {program.verbose} {program.verify} {program.protocol} {program.extra_params} -b{upload.speed} "{build.path}/{build.project_name}.hex" + +# Upload with programmer test 1 +tools.two.cmd.path=echo +tools.two.conf.general=conf-general +tools.two.upload.conf=conf-upload +tools.two.upload.params.verbose=verbose +tools.two.upload.params.quiet=quiet +tools.two.upload.params.verify=verify +tools.two.upload.params.noverify=noverify +tools.two.upload.pattern={cmd.path} two {conf.board} {conf.general} {upload.conf} {upload.verbose} {upload.verify} {upload.protocol} "{serial.port}" -b{upload.speed} "{build.path}/{build.project_name}.hex" diff --git a/commands/upload/testdata/hardware/alice/avr/programmers.txt b/commands/upload/testdata/hardware/alice/avr/programmers.txt new file mode 100644 index 00000000000..a7fe184b502 --- /dev/null +++ b/commands/upload/testdata/hardware/alice/avr/programmers.txt @@ -0,0 +1,20 @@ +progr1.name=Programmer 1 +progr1.program.protocol=progprotocol +progr1.program.tool=one +progr1.protocol=genprog1protocol + +progr2.name=Programmer 2 +progr2.program.protocol=prog2protocol +progr2.program.tool=one-noport + +progr3.name=Programmer 3 +progr3.program.protocol=prog3protocol +progr3.program.tool=one-extra-params +progr3.program.extra_params={serial.port} + +progr4.name=Programmer 4 +progr4.program.protocol=prog4protocol +progr4.program.tool=one +progr4.bootloader.protocol=prog4protocol-bootloader +progr4.bootloader.tool=one +progr4.protocol=genprog4protocol diff --git a/commands/upload/upload_test.go b/commands/upload/upload_test.go index 06e8b4bea0d..84dafdff3b4 100644 --- a/commands/upload/upload_test.go +++ b/commands/upload/upload_test.go @@ -145,6 +145,16 @@ func TestUploadPropertiesComposition(t *testing.T) { // classic upload, no port {buildPath1, "alice:avr:board2", "port", "", false, "conf-board1 conf-general conf-upload $$VERBOSE-VERIFY$$ protocol -bspeed testdata/build_path_1/sketch.ino.hex"}, {buildPath1, "alice:avr:board2", "", "", false, "conf-board1 conf-general conf-upload $$VERBOSE-VERIFY$$ protocol -bspeed testdata/build_path_1/sketch.ino.hex"}, + + // upload with programmer, requires port + {buildPath1, "alice:avr:board1", "port", "progr1", false, "conf-board1 conf-general conf-program $$VERBOSE-VERIFY$$ progprotocol port -bspeed testdata/build_path_1/sketch.ino.hex"}, + {buildPath1, "alice:avr:board1", "", "progr1", false, "FAIL"}, + // upload with programmer, no port + {buildPath1, "alice:avr:board1", "port", "progr2", false, "conf-board1 conf-general conf-program $$VERBOSE-VERIFY$$ prog2protocol -bspeed testdata/build_path_1/sketch.ino.hex"}, + {buildPath1, "alice:avr:board1", "", "progr2", false, "conf-board1 conf-general conf-program $$VERBOSE-VERIFY$$ prog2protocol -bspeed testdata/build_path_1/sketch.ino.hex"}, + // upload with programmer, require port through extra params + {buildPath1, "alice:avr:board1", "port", "progr3", false, "conf-board1 conf-general conf-program $$VERBOSE-VERIFY$$ prog3protocol port -bspeed testdata/build_path_1/sketch.ino.hex"}, + {buildPath1, "alice:avr:board1", "", "progr3", false, "FAIL"}, } for i, test := range tests { t.Run(fmt.Sprintf("SubTest%02d", i), func(t *testing.T) { From 53b9c3be40a11701e13877e2e14d4761fe75a693 Mon Sep 17 00:00:00 2001 From: Cristian Maglie Date: Wed, 16 Sep 2020 20:24:46 +0200 Subject: [PATCH 4/9] Added test for burn bootloader --- .../testdata/hardware/alice/avr/boards.txt | 9 +-- .../testdata/hardware/alice/avr/platform.txt | 14 ++++ commands/upload/upload.go | 4 + commands/upload/upload_test.go | 76 +++++++++++++------ 4 files changed, 73 insertions(+), 30 deletions(-) diff --git a/commands/upload/testdata/hardware/alice/avr/boards.txt b/commands/upload/testdata/hardware/alice/avr/boards.txt index db2fe46fe6f..651d9639e88 100644 --- a/commands/upload/testdata/hardware/alice/avr/boards.txt +++ b/commands/upload/testdata/hardware/alice/avr/boards.txt @@ -3,14 +3,9 @@ board1.conf.board=conf-board1 board1.upload.tool=one board1.upload.protocol=protocol board1.upload.speed=speed - board1.bootloader.tool=one -board1.bootloader.low_fuses=0xFF -board1.bootloader.high_fuses=0xDE -board1.bootloader.extended_fuses=0xFD -board1.bootloader.unlock_bits=0x3F -board1.bootloader.lock_bits=0x0F -board1.bootloader.file=optiboot/optiboot_atmega328.hex +board1.bootloader.fuses=0xFF +board1.bootloader.file=niceboot/niceboot.hex board2.name=board2 diff --git a/commands/upload/testdata/hardware/alice/avr/platform.txt b/commands/upload/testdata/hardware/alice/avr/platform.txt index 5e4d62d10dd..79d347470ea 100644 --- a/commands/upload/testdata/hardware/alice/avr/platform.txt +++ b/commands/upload/testdata/hardware/alice/avr/platform.txt @@ -18,6 +18,20 @@ tools.one.program.params.verify=verify tools.one.program.params.noverify=noverify tools.one.program.pattern={cmd.path} {conf.board} {conf.general} {program.conf} {program.verbose} {program.verify} {program.protocol} "{serial.port}" -b{upload.speed} "{build.path}/{build.project_name}.hex" +tools.one.erase.conf=conf-erase +tools.one.erase.params.verbose=verbose +tools.one.erase.params.quiet=quiet +tools.one.erase.params.verify=verify +tools.one.erase.params.noverify=noverify +tools.one.erase.pattern={cmd.path} ERASE {conf.board} {conf.general} {erase.conf} {erase.verbose} {erase.verify} {protocol} "{serial.port}" -b{upload.speed} + +tools.one.bootloader.conf=conf-bootloader +tools.one.bootloader.params.verbose=verbose +tools.one.bootloader.params.quiet=quiet +tools.one.bootloader.params.verify=verify +tools.one.bootloader.params.noverify=noverify +tools.one.bootloader.pattern={cmd.path} BURN {conf.board} {conf.general} {bootloader.conf} {bootloader.verbose} {bootloader.verify} {protocol} "{serial.port}" -b{upload.speed} -F{bootloader.fuses} "{runtime.platform.path}/bootloaders/{bootloader.file}" + # Upload test 2 tools.one-noport.cmd.path=echo tools.one-noport.conf.general=conf-general diff --git a/commands/upload/upload.go b/commands/upload/upload.go index a26bdb6ceff..f26d756e24d 100644 --- a/commands/upload/upload.go +++ b/commands/upload/upload.go @@ -234,9 +234,13 @@ func runProgramAction(pm *packagemanager.PackageManager, if verify { uploadProperties.Set("upload.verify", uploadProperties.Get("upload.params.verify")) uploadProperties.Set("program.verify", uploadProperties.Get("program.params.verify")) + uploadProperties.Set("erase.verify", uploadProperties.Get("erase.params.verify")) + uploadProperties.Set("bootloader.verify", uploadProperties.Get("bootloader.params.verify")) } else { uploadProperties.Set("upload.verify", uploadProperties.Get("upload.params.noverify")) uploadProperties.Set("program.verify", uploadProperties.Get("program.params.noverify")) + uploadProperties.Set("erase.verify", uploadProperties.Get("erase.params.noverify")) + uploadProperties.Set("bootloader.verify", uploadProperties.Get("bootloader.params.noverify")) } if !burnBootloader { diff --git a/commands/upload/upload_test.go b/commands/upload/upload_test.go index 84dafdff3b4..858c24cde01 100644 --- a/commands/upload/upload_test.go +++ b/commands/upload/upload_test.go @@ -136,25 +136,36 @@ func TestUploadPropertiesComposition(t *testing.T) { programmer string burnBootloader bool expected string + expected2 string } + cwdPath, err := paths.Getwd() + require.NoError(t, err) + cwd := cwdPath.String() + tests := []test{ - // classic upload, requires port - {buildPath1, "alice:avr:board1", "port", "", false, "conf-board1 conf-general conf-upload $$VERBOSE-VERIFY$$ protocol port -bspeed testdata/build_path_1/sketch.ino.hex"}, - {buildPath1, "alice:avr:board1", "", "", false, "FAIL"}, - // classic upload, no port - {buildPath1, "alice:avr:board2", "port", "", false, "conf-board1 conf-general conf-upload $$VERBOSE-VERIFY$$ protocol -bspeed testdata/build_path_1/sketch.ino.hex"}, - {buildPath1, "alice:avr:board2", "", "", false, "conf-board1 conf-general conf-upload $$VERBOSE-VERIFY$$ protocol -bspeed testdata/build_path_1/sketch.ino.hex"}, - - // upload with programmer, requires port - {buildPath1, "alice:avr:board1", "port", "progr1", false, "conf-board1 conf-general conf-program $$VERBOSE-VERIFY$$ progprotocol port -bspeed testdata/build_path_1/sketch.ino.hex"}, - {buildPath1, "alice:avr:board1", "", "progr1", false, "FAIL"}, - // upload with programmer, no port - {buildPath1, "alice:avr:board1", "port", "progr2", false, "conf-board1 conf-general conf-program $$VERBOSE-VERIFY$$ prog2protocol -bspeed testdata/build_path_1/sketch.ino.hex"}, - {buildPath1, "alice:avr:board1", "", "progr2", false, "conf-board1 conf-general conf-program $$VERBOSE-VERIFY$$ prog2protocol -bspeed testdata/build_path_1/sketch.ino.hex"}, - // upload with programmer, require port through extra params - {buildPath1, "alice:avr:board1", "port", "progr3", false, "conf-board1 conf-general conf-program $$VERBOSE-VERIFY$$ prog3protocol port -bspeed testdata/build_path_1/sketch.ino.hex"}, - {buildPath1, "alice:avr:board1", "", "progr3", false, "FAIL"}, + // 0: classic upload, requires port + {buildPath1, "alice:avr:board1", "port", "", false, "conf-board1 conf-general conf-upload $$VERBOSE-VERIFY$$ protocol port -bspeed testdata/build_path_1/sketch.ino.hex", ""}, + {buildPath1, "alice:avr:board1", "", "", false, "FAIL", ""}, + // 2: classic upload, no port + {buildPath1, "alice:avr:board2", "port", "", false, "conf-board1 conf-general conf-upload $$VERBOSE-VERIFY$$ protocol -bspeed testdata/build_path_1/sketch.ino.hex", ""}, + {buildPath1, "alice:avr:board2", "", "", false, "conf-board1 conf-general conf-upload $$VERBOSE-VERIFY$$ protocol -bspeed testdata/build_path_1/sketch.ino.hex", ""}, + + // 4: upload with programmer, requires port + {buildPath1, "alice:avr:board1", "port", "progr1", false, "conf-board1 conf-general conf-program $$VERBOSE-VERIFY$$ progprotocol port -bspeed testdata/build_path_1/sketch.ino.hex", ""}, + {buildPath1, "alice:avr:board1", "", "progr1", false, "FAIL", ""}, + // 6: upload with programmer, no port + {buildPath1, "alice:avr:board1", "port", "progr2", false, "conf-board1 conf-general conf-program $$VERBOSE-VERIFY$$ prog2protocol -bspeed testdata/build_path_1/sketch.ino.hex", ""}, + {buildPath1, "alice:avr:board1", "", "progr2", false, "conf-board1 conf-general conf-program $$VERBOSE-VERIFY$$ prog2protocol -bspeed testdata/build_path_1/sketch.ino.hex", ""}, + // 8: upload with programmer, require port through extra params + {buildPath1, "alice:avr:board1", "port", "progr3", false, "conf-board1 conf-general conf-program $$VERBOSE-VERIFY$$ prog3protocol port -bspeed testdata/build_path_1/sketch.ino.hex", ""}, + {buildPath1, "alice:avr:board1", "", "progr3", false, "FAIL", ""}, + + // 10: burn bootloader, require port + {buildPath1, "alice:avr:board1", "port", "", true, "FAIL", ""}, // requires programmer + {buildPath1, "alice:avr:board1", "port", "progr1", true, + "ERASE conf-board1 conf-general conf-erase $$VERBOSE-VERIFY$$ genprog1protocol port -bspeed", + "BURN conf-board1 conf-general conf-bootloader $$VERBOSE-VERIFY$$ genprog1protocol port -bspeed -F0xFF " + cwd + "/testdata/hardware/alice/avr/bootloaders/niceboot/niceboot.hex"}, } for i, test := range tests { t.Run(fmt.Sprintf("SubTest%02d", i), func(t *testing.T) { @@ -178,8 +189,19 @@ func TestUploadPropertiesComposition(t *testing.T) { require.Error(t, err) } else { require.NoError(t, err) - out := strings.TrimSpace(outStream.String()) - require.Equal(t, strings.ReplaceAll(test.expected, "$$VERBOSE-VERIFY$$", "quiet noverify"), out) + out := strings.Split(outStream.String(), "\n") + // With verbose disable, the upload will output at least 2 lines: + // - the output of the command (1 or 2 lines) + // - an empty line + if test.expected2 != "" { + require.Len(t, out, 3) + } else { + require.Len(t, out, 2) + } + require.Equal(t, strings.ReplaceAll(test.expected, "$$VERBOSE-VERIFY$$", "quiet noverify"), out[0]) + if test.expected2 != "" { + require.Equal(t, strings.ReplaceAll(test.expected2, "$$VERBOSE-VERIFY$$", "quiet noverify"), out[1]) + } } }) t.Run(fmt.Sprintf("SubTest%02d-WithVerifyAndVerbose", i), func(t *testing.T) { @@ -204,13 +226,21 @@ func TestUploadPropertiesComposition(t *testing.T) { } else { require.NoError(t, err) out := strings.Split(outStream.String(), "\n") - // With verbose enabled, the upload will output 3 lines: - // - the command line that the cli is going to run - // - the output of the command + // With verbose enabled, the upload will output at least 3 lines: + // - the first command line that the cli is going to run + // - the output of the first command + // - OPTIONAL: the second command line that the cli is going to run + // - OPTIONAL: the output of the second command // - an empty line - // we are interested in the second line - require.Len(t, out, 3) + if test.expected2 != "" { + require.Len(t, out, 5) + } else { + require.Len(t, out, 3) + } require.Equal(t, strings.ReplaceAll(test.expected, "$$VERBOSE-VERIFY$$", "verbose verify"), out[1]) + if test.expected2 != "" { + require.Equal(t, strings.ReplaceAll(test.expected2, "$$VERBOSE-VERIFY$$", "verbose verify"), out[3]) + } } }) } From b598779fe47b14fa8e7b7d81899c3d58cc8e7050 Mon Sep 17 00:00:00 2001 From: Cristian Maglie Date: Wed, 16 Sep 2020 21:34:50 +0200 Subject: [PATCH 5/9] Added test for burn bootloader with bootloader.tool options override --- .../testdata/hardware/alice/avr/platform.txt | 22 +++++++++++++------ .../hardware/alice/avr/programmers.txt | 5 ++--- commands/upload/upload_test.go | 5 +++++ 3 files changed, 22 insertions(+), 10 deletions(-) diff --git a/commands/upload/testdata/hardware/alice/avr/platform.txt b/commands/upload/testdata/hardware/alice/avr/platform.txt index 79d347470ea..4e55d111915 100644 --- a/commands/upload/testdata/hardware/alice/avr/platform.txt +++ b/commands/upload/testdata/hardware/alice/avr/platform.txt @@ -62,10 +62,18 @@ tools.one-extra-params.program.pattern={cmd.path} {conf.board} {conf.general} {p # Upload with programmer test 1 tools.two.cmd.path=echo -tools.two.conf.general=conf-general -tools.two.upload.conf=conf-upload -tools.two.upload.params.verbose=verbose -tools.two.upload.params.quiet=quiet -tools.two.upload.params.verify=verify -tools.two.upload.params.noverify=noverify -tools.two.upload.pattern={cmd.path} two {conf.board} {conf.general} {upload.conf} {upload.verbose} {upload.verify} {upload.protocol} "{serial.port}" -b{upload.speed} "{build.path}/{build.project_name}.hex" +tools.two.conf.general=conf-two-general + +tools.two.erase.conf=conf-two-erase +tools.two.erase.params.verbose=verbose +tools.two.erase.params.quiet=quiet +tools.two.erase.params.verify=verify +tools.two.erase.params.noverify=noverify +tools.two.erase.pattern={cmd.path} ERASE {conf.board} {conf.general} {erase.conf} {erase.verbose} {erase.verify} {bootloader.protocol} "{serial.port}" -b{upload.speed} + +tools.two.bootloader.conf=conf-two-bootloader +tools.two.bootloader.params.verbose=verbose +tools.two.bootloader.params.quiet=quiet +tools.two.bootloader.params.verify=verify +tools.two.bootloader.params.noverify=noverify +tools.two.bootloader.pattern={cmd.path} BURN {conf.board} {conf.general} {bootloader.conf} {bootloader.verbose} {bootloader.verify} {bootloader.protocol} "{serial.port}" -b{upload.speed} -F{bootloader.fuses} "{runtime.platform.path}/bootloaders/{bootloader.file}" diff --git a/commands/upload/testdata/hardware/alice/avr/programmers.txt b/commands/upload/testdata/hardware/alice/avr/programmers.txt index a7fe184b502..cb5fa415154 100644 --- a/commands/upload/testdata/hardware/alice/avr/programmers.txt +++ b/commands/upload/testdata/hardware/alice/avr/programmers.txt @@ -13,8 +13,7 @@ progr3.program.tool=one-extra-params progr3.program.extra_params={serial.port} progr4.name=Programmer 4 -progr4.program.protocol=prog4protocol +progr4.program.protocol=prog4protocol-upload progr4.program.tool=one progr4.bootloader.protocol=prog4protocol-bootloader -progr4.bootloader.tool=one -progr4.protocol=genprog4protocol +progr4.bootloader.tool=two diff --git a/commands/upload/upload_test.go b/commands/upload/upload_test.go index 858c24cde01..e0597cc26cf 100644 --- a/commands/upload/upload_test.go +++ b/commands/upload/upload_test.go @@ -166,6 +166,11 @@ func TestUploadPropertiesComposition(t *testing.T) { {buildPath1, "alice:avr:board1", "port", "progr1", true, "ERASE conf-board1 conf-general conf-erase $$VERBOSE-VERIFY$$ genprog1protocol port -bspeed", "BURN conf-board1 conf-general conf-bootloader $$VERBOSE-VERIFY$$ genprog1protocol port -bspeed -F0xFF " + cwd + "/testdata/hardware/alice/avr/bootloaders/niceboot/niceboot.hex"}, + + // 12: burn bootloader, preferences override from programmers.txt + {buildPath1, "alice:avr:board1", "port", "progr4", true, + "ERASE conf-board1 conf-two-general conf-two-erase $$VERBOSE-VERIFY$$ prog4protocol-bootloader port -bspeed", + "BURN conf-board1 conf-two-general conf-two-bootloader $$VERBOSE-VERIFY$$ prog4protocol-bootloader port -bspeed -F0xFF " + cwd + "/testdata/hardware/alice/avr/bootloaders/niceboot/niceboot.hex"}, } for i, test := range tests { t.Run(fmt.Sprintf("SubTest%02d", i), func(t *testing.T) { From 3dcf2ac99e7653ad7611cefb3f65e542af564cd0 Mon Sep 17 00:00:00 2001 From: Cristian Maglie Date: Thu, 17 Sep 2020 09:43:56 +0200 Subject: [PATCH 6/9] Increased verbosity --- commands/upload/upload_test.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/commands/upload/upload_test.go b/commands/upload/upload_test.go index e0597cc26cf..4106dd3f4e2 100644 --- a/commands/upload/upload_test.go +++ b/commands/upload/upload_test.go @@ -25,6 +25,7 @@ import ( "github.com/arduino/arduino-cli/arduino/cores/packagemanager" "github.com/arduino/arduino-cli/arduino/sketches" paths "github.com/arduino/go-paths-helper" + "github.com/sirupsen/logrus" "github.com/stretchr/testify/require" ) @@ -128,7 +129,7 @@ func TestUploadPropertiesComposition(t *testing.T) { err := pm.LoadHardwareFromDirectory(paths.New("testdata", "hardware")) require.NoError(t, err) buildPath1 := paths.New("testdata", "build_path_1") - + logrus.SetLevel(logrus.TraceLevel) type test struct { importDir *paths.Path fqbn string From 6a224c4da887e9c63e2c63b9958d28dbb83c9e8e Mon Sep 17 00:00:00 2001 From: Cristian Maglie Date: Thu, 17 Sep 2020 09:45:02 +0200 Subject: [PATCH 7/9] Refactored upload procedure to correctly handle bootloader.tool property --- commands/upload/upload.go | 95 ++++++++++++++++++++------------------- 1 file changed, 48 insertions(+), 47 deletions(-) diff --git a/commands/upload/upload.go b/commands/upload/upload.go index f26d756e24d..917865af2f9 100644 --- a/commands/upload/upload.go +++ b/commands/upload/upload.go @@ -117,23 +117,8 @@ func runProgramAction(pm *packagemanager.PackageManager, WithField("buildPlatform", buildPlatform). Tracef("Upload data") - // Load upload tool definitions - var uploadToolName string - var uploadToolPlatform *cores.PlatformRelease + // Extract programmer properties (when specified) var programmer *cores.Programmer - - if burnBootloader { - uploadToolName = boardProperties.Get("bootloader.tool") - uploadToolPlatform = boardPlatform - if uploadToolName == "" { - return fmt.Errorf("cannot get programmer tool: undefined 'bootloader.tool' in boards.txt") - } - logrus. - WithField("uploadToolName", uploadToolName). - WithField("uploadToolPlatform", uploadToolPlatform). - Trace("Upload tool from 'bootloader.tool' property") - } - if programmerID != "" { programmer = boardPlatform.Programmers[programmerID] if programmer == nil { @@ -143,36 +128,54 @@ func runProgramAction(pm *packagemanager.PackageManager, if programmer == nil { return fmt.Errorf("programmer '%s' not available", programmerID) } - uploadToolName = programmer.Properties.Get("program.tool") - uploadToolPlatform = programmer.PlatformRelease - if uploadToolName == "" { - return fmt.Errorf("cannot get programmer tool: undefined 'program.tool' property") + } + + // Determine upload tool + var uploadToolID string + { + toolProperty := "upload.tool" + if burnBootloader { + toolProperty = "bootloader.tool" + } else if programmer != nil { + toolProperty = "program.tool" + } + + // create a temporary configuration only for the selection of upload tool + props := properties.NewMap() + props.Merge(boardPlatform.Properties) + props.Merge(boardPlatform.RuntimeProperties()) + props.Merge(boardProperties) + if programmer != nil { + props.Merge(programmer.Properties) + } + if t, ok := props.GetOk(toolProperty); ok { + uploadToolID = t + } else { + return fmt.Errorf("cannot get programmer tool: undefined '%s' property", toolProperty) } - logrus. - WithField("uploadToolName", uploadToolName). - WithField("uploadToolPlatform", uploadToolPlatform). - Trace("Upload tool from --programmer parameter") + } + + var uploadToolPlatform *cores.PlatformRelease + if programmer != nil { + uploadToolPlatform = programmer.PlatformRelease } else { - uploadToolName = boardProperties.Get("upload.tool") uploadToolPlatform = boardPlatform - if uploadToolName == "" { - return fmt.Errorf("cannot get upload tool: undefined 'upload.tool' property") - } - if split := strings.Split(uploadToolName, ":"); len(split) > 2 { - return fmt.Errorf("invalid 'upload.tool' property: %s", uploadToolName) - } else if len(split) == 2 { - uploadToolName = split[1] - uploadToolPlatform = pm.GetInstalledPlatformRelease( - pm.FindPlatform(&packagemanager.PlatformReference{ - Package: split[0], - PlatformArchitecture: boardPlatform.Platform.Architecture, - }), - ) - } - logrus. - WithField("uploadToolName", uploadToolName). - WithField("uploadToolPlatform", uploadToolPlatform). - Trace("Upload tool") + } + logrus. + WithField("uploadToolID", uploadToolID). + WithField("uploadToolPlatform", uploadToolPlatform). + Trace("Upload tool") + + if split := strings.Split(uploadToolID, ":"); len(split) > 2 { + return fmt.Errorf("invalid 'upload.tool' property: %s", uploadToolID) + } else if len(split) == 2 { + uploadToolID = split[1] + uploadToolPlatform = pm.GetInstalledPlatformRelease( + pm.FindPlatform(&packagemanager.PlatformReference{ + Package: split[0], + PlatformArchitecture: boardPlatform.Platform.Architecture, + }), + ) } // Build configuration for upload @@ -183,9 +186,7 @@ func runProgramAction(pm *packagemanager.PackageManager, uploadProperties.Merge(boardPlatform.Properties) uploadProperties.Merge(boardPlatform.RuntimeProperties()) uploadProperties.Merge(boardProperties) - - uploadToolProperties := uploadProperties.SubTree("tools." + uploadToolName) - uploadProperties.Merge(uploadToolProperties) + uploadProperties.Merge(uploadProperties.SubTree("tools." + uploadToolID)) if programmer != nil { uploadProperties.Merge(programmer.Properties) } @@ -311,7 +312,7 @@ func runProgramAction(pm *packagemanager.PackageManager, } } - // Build recipe for upload + // Run recipes for upload if burnBootloader { if err := runTool("erase.pattern", uploadProperties, outStream, errStream, verbose); err != nil { return fmt.Errorf("chip erase error: %s", err) From 8e8dc57fe84169e3f7fc49bf3bffd2041321f2d3 Mon Sep 17 00:00:00 2001 From: Cristian Maglie Date: Thu, 17 Sep 2020 10:30:13 +0200 Subject: [PATCH 8/9] Handle windows quirks on command output --- commands/upload/upload_test.go | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/commands/upload/upload_test.go b/commands/upload/upload_test.go index 4106dd3f4e2..7252a3af77f 100644 --- a/commands/upload/upload_test.go +++ b/commands/upload/upload_test.go @@ -142,7 +142,7 @@ func TestUploadPropertiesComposition(t *testing.T) { cwdPath, err := paths.Getwd() require.NoError(t, err) - cwd := cwdPath.String() + cwd := strings.ReplaceAll(cwdPath.String(), "\\", "/") tests := []test{ // 0: classic upload, requires port @@ -195,7 +195,9 @@ func TestUploadPropertiesComposition(t *testing.T) { require.Error(t, err) } else { require.NoError(t, err) - out := strings.Split(outStream.String(), "\n") + outFiltered := strings.ReplaceAll(outStream.String(), "\r", "") + outFiltered = strings.ReplaceAll(outFiltered, "\\", "/") + out := strings.Split(outFiltered, "\n") // With verbose disable, the upload will output at least 2 lines: // - the output of the command (1 or 2 lines) // - an empty line @@ -231,7 +233,9 @@ func TestUploadPropertiesComposition(t *testing.T) { require.Error(t, err) } else { require.NoError(t, err) - out := strings.Split(outStream.String(), "\n") + outFiltered := strings.ReplaceAll(outStream.String(), "\r", "") + outFiltered = strings.ReplaceAll(outFiltered, "\\", "/") + out := strings.Split(outFiltered, "\n") // With verbose enabled, the upload will output at least 3 lines: // - the first command line that the cli is going to run // - the output of the first command From 1de32c31fed2d2e5c5fbd0e40758aa1932686f95 Mon Sep 17 00:00:00 2001 From: Cristian Maglie Date: Fri, 16 Oct 2020 11:33:45 +0200 Subject: [PATCH 9/9] Simplified tests --- commands/upload/upload_test.go | 146 ++++++++++++--------------------- 1 file changed, 53 insertions(+), 93 deletions(-) diff --git a/commands/upload/upload_test.go b/commands/upload/upload_test.go index 7252a3af77f..29cc5e6be77 100644 --- a/commands/upload/upload_test.go +++ b/commands/upload/upload_test.go @@ -131,13 +131,13 @@ func TestUploadPropertiesComposition(t *testing.T) { buildPath1 := paths.New("testdata", "build_path_1") logrus.SetLevel(logrus.TraceLevel) type test struct { - importDir *paths.Path - fqbn string - port string - programmer string - burnBootloader bool - expected string - expected2 string + importDir *paths.Path + fqbn string + port string + programmer string + burnBootloader bool + expectedOutput string + expectedOutput2 string } cwdPath, err := paths.Getwd() @@ -146,112 +146,72 @@ func TestUploadPropertiesComposition(t *testing.T) { tests := []test{ // 0: classic upload, requires port - {buildPath1, "alice:avr:board1", "port", "", false, "conf-board1 conf-general conf-upload $$VERBOSE-VERIFY$$ protocol port -bspeed testdata/build_path_1/sketch.ino.hex", ""}, + {buildPath1, "alice:avr:board1", "port", "", false, "conf-board1 conf-general conf-upload $$VERBOSE-VERIFY$$ protocol port -bspeed testdata/build_path_1/sketch.ino.hex\n", ""}, {buildPath1, "alice:avr:board1", "", "", false, "FAIL", ""}, // 2: classic upload, no port - {buildPath1, "alice:avr:board2", "port", "", false, "conf-board1 conf-general conf-upload $$VERBOSE-VERIFY$$ protocol -bspeed testdata/build_path_1/sketch.ino.hex", ""}, - {buildPath1, "alice:avr:board2", "", "", false, "conf-board1 conf-general conf-upload $$VERBOSE-VERIFY$$ protocol -bspeed testdata/build_path_1/sketch.ino.hex", ""}, + {buildPath1, "alice:avr:board2", "port", "", false, "conf-board1 conf-general conf-upload $$VERBOSE-VERIFY$$ protocol -bspeed testdata/build_path_1/sketch.ino.hex\n", ""}, + {buildPath1, "alice:avr:board2", "", "", false, "conf-board1 conf-general conf-upload $$VERBOSE-VERIFY$$ protocol -bspeed testdata/build_path_1/sketch.ino.hex\n", ""}, // 4: upload with programmer, requires port - {buildPath1, "alice:avr:board1", "port", "progr1", false, "conf-board1 conf-general conf-program $$VERBOSE-VERIFY$$ progprotocol port -bspeed testdata/build_path_1/sketch.ino.hex", ""}, + {buildPath1, "alice:avr:board1", "port", "progr1", false, "conf-board1 conf-general conf-program $$VERBOSE-VERIFY$$ progprotocol port -bspeed testdata/build_path_1/sketch.ino.hex\n", ""}, {buildPath1, "alice:avr:board1", "", "progr1", false, "FAIL", ""}, // 6: upload with programmer, no port - {buildPath1, "alice:avr:board1", "port", "progr2", false, "conf-board1 conf-general conf-program $$VERBOSE-VERIFY$$ prog2protocol -bspeed testdata/build_path_1/sketch.ino.hex", ""}, - {buildPath1, "alice:avr:board1", "", "progr2", false, "conf-board1 conf-general conf-program $$VERBOSE-VERIFY$$ prog2protocol -bspeed testdata/build_path_1/sketch.ino.hex", ""}, + {buildPath1, "alice:avr:board1", "port", "progr2", false, "conf-board1 conf-general conf-program $$VERBOSE-VERIFY$$ prog2protocol -bspeed testdata/build_path_1/sketch.ino.hex\n", ""}, + {buildPath1, "alice:avr:board1", "", "progr2", false, "conf-board1 conf-general conf-program $$VERBOSE-VERIFY$$ prog2protocol -bspeed testdata/build_path_1/sketch.ino.hex\n", ""}, // 8: upload with programmer, require port through extra params - {buildPath1, "alice:avr:board1", "port", "progr3", false, "conf-board1 conf-general conf-program $$VERBOSE-VERIFY$$ prog3protocol port -bspeed testdata/build_path_1/sketch.ino.hex", ""}, + {buildPath1, "alice:avr:board1", "port", "progr3", false, "conf-board1 conf-general conf-program $$VERBOSE-VERIFY$$ prog3protocol port -bspeed testdata/build_path_1/sketch.ino.hex\n", ""}, {buildPath1, "alice:avr:board1", "", "progr3", false, "FAIL", ""}, // 10: burn bootloader, require port {buildPath1, "alice:avr:board1", "port", "", true, "FAIL", ""}, // requires programmer {buildPath1, "alice:avr:board1", "port", "progr1", true, - "ERASE conf-board1 conf-general conf-erase $$VERBOSE-VERIFY$$ genprog1protocol port -bspeed", - "BURN conf-board1 conf-general conf-bootloader $$VERBOSE-VERIFY$$ genprog1protocol port -bspeed -F0xFF " + cwd + "/testdata/hardware/alice/avr/bootloaders/niceboot/niceboot.hex"}, + "ERASE conf-board1 conf-general conf-erase $$VERBOSE-VERIFY$$ genprog1protocol port -bspeed\n", + "BURN conf-board1 conf-general conf-bootloader $$VERBOSE-VERIFY$$ genprog1protocol port -bspeed -F0xFF " + cwd + "/testdata/hardware/alice/avr/bootloaders/niceboot/niceboot.hex\n"}, // 12: burn bootloader, preferences override from programmers.txt {buildPath1, "alice:avr:board1", "port", "progr4", true, - "ERASE conf-board1 conf-two-general conf-two-erase $$VERBOSE-VERIFY$$ prog4protocol-bootloader port -bspeed", - "BURN conf-board1 conf-two-general conf-two-bootloader $$VERBOSE-VERIFY$$ prog4protocol-bootloader port -bspeed -F0xFF " + cwd + "/testdata/hardware/alice/avr/bootloaders/niceboot/niceboot.hex"}, + "ERASE conf-board1 conf-two-general conf-two-erase $$VERBOSE-VERIFY$$ prog4protocol-bootloader port -bspeed\n", + "BURN conf-board1 conf-two-general conf-two-bootloader $$VERBOSE-VERIFY$$ prog4protocol-bootloader port -bspeed -F0xFF " + cwd + "/testdata/hardware/alice/avr/bootloaders/niceboot/niceboot.hex\n"}, } + + testRunner := func(t *testing.T, test test, verboseVerify bool) { + outStream := &bytes.Buffer{} + errStream := &bytes.Buffer{} + err := runProgramAction( + pm, + nil, // sketch + "", // importFile + test.importDir.String(), // importDir + test.fqbn, // FQBN + test.port, // port + test.programmer, // programmer + verboseVerify, // verbose + verboseVerify, // verify + test.burnBootloader, // burnBootloader + outStream, + errStream, + ) + verboseVerifyOutput := "verbose verify" + if !verboseVerify { + verboseVerifyOutput = "quiet noverify" + } + if test.expectedOutput == "FAIL" { + require.Error(t, err) + } else { + require.NoError(t, err) + outFiltered := strings.ReplaceAll(outStream.String(), "\r", "") + outFiltered = strings.ReplaceAll(outFiltered, "\\", "/") + require.Contains(t, outFiltered, strings.ReplaceAll(test.expectedOutput, "$$VERBOSE-VERIFY$$", verboseVerifyOutput)) + require.Contains(t, outFiltered, strings.ReplaceAll(test.expectedOutput2, "$$VERBOSE-VERIFY$$", verboseVerifyOutput)) + } + } + for i, test := range tests { t.Run(fmt.Sprintf("SubTest%02d", i), func(t *testing.T) { - outStream := &bytes.Buffer{} - errStream := &bytes.Buffer{} - err := runProgramAction( - pm, - nil, // sketch - "", // importFile - test.importDir.String(), // importDir - test.fqbn, // FQBN - test.port, // port - test.programmer, // programmer - false, // verbose - false, // verify - test.burnBootloader, // burnBootloader - outStream, - errStream, - ) - if test.expected == "FAIL" { - require.Error(t, err) - } else { - require.NoError(t, err) - outFiltered := strings.ReplaceAll(outStream.String(), "\r", "") - outFiltered = strings.ReplaceAll(outFiltered, "\\", "/") - out := strings.Split(outFiltered, "\n") - // With verbose disable, the upload will output at least 2 lines: - // - the output of the command (1 or 2 lines) - // - an empty line - if test.expected2 != "" { - require.Len(t, out, 3) - } else { - require.Len(t, out, 2) - } - require.Equal(t, strings.ReplaceAll(test.expected, "$$VERBOSE-VERIFY$$", "quiet noverify"), out[0]) - if test.expected2 != "" { - require.Equal(t, strings.ReplaceAll(test.expected2, "$$VERBOSE-VERIFY$$", "quiet noverify"), out[1]) - } - } + testRunner(t, test, false) }) t.Run(fmt.Sprintf("SubTest%02d-WithVerifyAndVerbose", i), func(t *testing.T) { - outStream := &bytes.Buffer{} - errStream := &bytes.Buffer{} - err := runProgramAction( - pm, - nil, // sketch - "", // importFile - test.importDir.String(), // importDir - test.fqbn, // FQBN - test.port, // port - test.programmer, // programmer - true, // verbose - true, // verify - test.burnBootloader, // burnBootloader - outStream, - errStream, - ) - if test.expected == "FAIL" { - require.Error(t, err) - } else { - require.NoError(t, err) - outFiltered := strings.ReplaceAll(outStream.String(), "\r", "") - outFiltered = strings.ReplaceAll(outFiltered, "\\", "/") - out := strings.Split(outFiltered, "\n") - // With verbose enabled, the upload will output at least 3 lines: - // - the first command line that the cli is going to run - // - the output of the first command - // - OPTIONAL: the second command line that the cli is going to run - // - OPTIONAL: the output of the second command - // - an empty line - if test.expected2 != "" { - require.Len(t, out, 5) - } else { - require.Len(t, out, 3) - } - require.Equal(t, strings.ReplaceAll(test.expected, "$$VERBOSE-VERIFY$$", "verbose verify"), out[1]) - if test.expected2 != "" { - require.Equal(t, strings.ReplaceAll(test.expected2, "$$VERBOSE-VERIFY$$", "verbose verify"), out[3]) - } - } + testRunner(t, test, true) }) } }