diff --git a/.github/workflows/check-certificates.yml b/.github/workflows/check-certificates.yml
index 694792dcd..0c80be9c7 100644
--- a/.github/workflows/check-certificates.yml
+++ b/.github/workflows/check-certificates.yml
@@ -6,6 +6,8 @@ on:
push:
paths:
- ".github/workflows/check-certificates.ya?ml"
+ tags-ignore:
+ - '*'
pull_request:
paths:
- ".github/workflows/check-certificates.ya?ml"
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
index 3b2a210d9..0e31abff3 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -286,6 +286,11 @@ jobs:
-k "${{ env.KEYCHAIN_PASSWORD }}" \
"${{ env.KEYCHAIN }}"
+ - name: Install Go
+ uses: actions/setup-go@v5
+ with:
+ go-version: ${{ env.GO_VERSION }}
+
- name: Install gon for code signing
uses: actions/checkout@v4
with:
@@ -309,7 +314,7 @@ jobs:
bundle_id = "cc.arduino.${{ env.PROJECT_NAME }}"
sign {
- application_identity = "Developer ID Application: ARDUINO SA (7KT7ZWMCJT)"
+ application_identity = "Massimo Banzi Apple Key"
deep = true
}
@@ -577,7 +582,7 @@ jobs:
bundle_id = "cc.arduino.${{ env.PROJECT_NAME }}-installer"
sign {
- application_identity = "Developer ID Application: ARDUINO SA (7KT7ZWMCJT)"
+ application_identity = "Massimo Banzi Apple Key"
}
# Ask Gon for zip output to force notarization process to take place.
diff --git a/bufferflow.go b/bufferflow.go
deleted file mode 100644
index a9fef8e51..000000000
--- a/bufferflow.go
+++ /dev/null
@@ -1,23 +0,0 @@
-// Copyright 2022 Arduino SA
-//
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU Affero General Public License as published
-// by the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Affero General Public License for more details.
-//
-// You should have received a copy of the GNU Affero General Public License
-// along with this program. If not, see .
-
-package main
-
-// Bufferflow interface
-type Bufferflow interface {
- Init()
- OnIncomingData(data string) // implement this method
- Close() // implement this method
-}
diff --git a/bufferflow_default.go b/bufferflow_default.go
deleted file mode 100644
index 959737d54..000000000
--- a/bufferflow_default.go
+++ /dev/null
@@ -1,72 +0,0 @@
-// Copyright 2022 Arduino SA
-//
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU Affero General Public License as published
-// by the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Affero General Public License for more details.
-//
-// You should have received a copy of the GNU Affero General Public License
-// along with this program. If not, see .
-
-package main
-
-import (
- "encoding/json"
-
- log "github.com/sirupsen/logrus"
-)
-
-// BufferflowDefault is the default bufferflow, whick means no buffering
-type BufferflowDefault struct {
- port string
- output chan<- []byte
- input chan string
- done chan bool
-}
-
-// NewBufferflowDefault create a new default bufferflow
-func NewBufferflowDefault(port string, output chan<- []byte) *BufferflowDefault {
- return &BufferflowDefault{
- port: port,
- output: output,
- input: make(chan string),
- done: make(chan bool),
- }
-}
-
-// Init will initialize the bufferflow
-func (b *BufferflowDefault) Init() {
- log.Println("Initting default buffer flow (which means no buffering)")
- go b.consumeInput()
-}
-
-func (b *BufferflowDefault) consumeInput() {
-Loop:
- for {
- select {
- case data := <-b.input:
- m := SpPortMessage{b.port, data}
- message, _ := json.Marshal(m)
- b.output <- message
- case <-b.done:
- break Loop //this is required, a simple break statement would only exit the innermost switch statement
- }
- }
- close(b.input) // close the input channel at the end of the computation
-}
-
-// OnIncomingData will forward the data
-func (b *BufferflowDefault) OnIncomingData(data string) {
- b.input <- data
-}
-
-// Close will close the bufferflow
-func (b *BufferflowDefault) Close() {
- b.done <- true
- close(b.done)
-}
diff --git a/bufferflow_timed.go b/bufferflow_timed.go
index 36aaf08bf..6c5fab04a 100644
--- a/bufferflow_timed.go
+++ b/bufferflow_timed.go
@@ -33,8 +33,8 @@ type BufferflowTimed struct {
bufferedOutput string
}
-// NewBufferflowTimed will create a new timed bufferflow
-func NewBufferflowTimed(port string, output chan<- []byte) *BufferflowTimed {
+// NewBufferFlowTimed will create a new timed bufferflow
+func NewBufferFlowTimed(port string, output chan<- []byte) *BufferflowTimed {
return &BufferflowTimed{
port: port,
output: output,
@@ -48,7 +48,7 @@ func NewBufferflowTimed(port string, output chan<- []byte) *BufferflowTimed {
// Init will initialize the bufferflow
func (b *BufferflowTimed) Init() {
- log.Println("Initting timed buffer flow (output once every 16ms)")
+ log.Println("Start consuming from serial port (output once every 16ms)")
go b.consumeInput()
}
diff --git a/bufferflow_timedraw.go b/bufferflow_timedraw.go
deleted file mode 100644
index 08b34cab6..000000000
--- a/bufferflow_timedraw.go
+++ /dev/null
@@ -1,89 +0,0 @@
-// Copyright 2022 Arduino SA
-//
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU Affero General Public License as published
-// by the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Affero General Public License for more details.
-//
-// You should have received a copy of the GNU Affero General Public License
-// along with this program. If not, see .
-
-package main
-
-import (
- "encoding/json"
- "time"
-
- log "github.com/sirupsen/logrus"
-)
-
-// BufferflowTimedRaw sends raw data once every 16ms
-type BufferflowTimedRaw struct {
- port string
- output chan<- []byte
- input chan string
- done chan bool
- ticker *time.Ticker
- bufferedOutputRaw []byte
- sPortRaw string
-}
-
-// NewBufferflowTimedRaw will create a new raw bufferflow
-func NewBufferflowTimedRaw(port string, output chan<- []byte) *BufferflowTimedRaw {
- return &BufferflowTimedRaw{
- port: port,
- output: output,
- input: make(chan string),
- done: make(chan bool),
- ticker: time.NewTicker(16 * time.Millisecond),
- bufferedOutputRaw: nil,
- sPortRaw: "",
- }
-}
-
-// Init will initialize the bufferflow
-func (b *BufferflowTimedRaw) Init() {
- log.Println("Initting timed buffer raw flow (output once every 16ms)")
- go b.consumeInput()
-}
-
-func (b *BufferflowTimedRaw) consumeInput() {
-Loop:
- for {
- select {
- case data := <-b.input: // use the buffer and append data to it
- b.bufferedOutputRaw = append(b.bufferedOutputRaw, []byte(data)...)
- b.sPortRaw = b.port
- case <-b.ticker.C: // after 16ms send the buffered output message
- if b.bufferedOutputRaw != nil {
- m := SpPortMessageRaw{b.sPortRaw, b.bufferedOutputRaw}
- buf, _ := json.Marshal(m)
- // since bufferedOutputRaw is a []byte is base64-encoded by json.Marshal() function automatically
- b.output <- buf
- // reset the buffer and the port
- b.bufferedOutputRaw = nil
- b.sPortRaw = ""
- }
- case <-b.done:
- break Loop //this is required, a simple break statement would only exit the innermost switch statement
- }
- }
- close(b.input)
-}
-
-// OnIncomingData will forward the data
-func (b *BufferflowTimedRaw) OnIncomingData(data string) {
- b.input <- data
-}
-
-// Close will close the bufferflow
-func (b *BufferflowTimedRaw) Close() {
- b.ticker.Stop()
- b.done <- true
- close(b.done)
-}
diff --git a/config/config.go b/config/config.go
index 69d29eeee..50978eb82 100644
--- a/config/config.go
+++ b/config/config.go
@@ -142,3 +142,41 @@ func SetInstallCertsIni(filename string, value string) error {
}
return nil
}
+
+func GetConfigPath() *paths.Path {
+ // Let's handle the config
+ configDir := GetDefaultConfigDir()
+ var configPath *paths.Path
+
+ // see if the env var is defined, if it is take the config from there, this will override the default path
+ if envConfig := os.Getenv("ARDUINO_CREATE_AGENT_CONFIG"); envConfig != "" {
+ configPath = paths.New(envConfig)
+ if configPath.NotExist() {
+ log.Panicf("config from env var %s does not exists", envConfig)
+ }
+ log.Infof("using config from env variable: %s", configPath)
+ } else if defaultConfigPath := configDir.Join("config.ini"); defaultConfigPath.Exist() {
+ // by default take the config from the ~/.arduino-create/config.ini file
+ configPath = defaultConfigPath
+ log.Infof("using config from default: %s", configPath)
+ } else {
+ // Fall back to the old config.ini location
+ src, _ := os.Executable()
+ oldConfigPath := paths.New(src).Parent().Join("config.ini")
+ if oldConfigPath.Exist() {
+ err := oldConfigPath.CopyTo(defaultConfigPath)
+ if err != nil {
+ log.Errorf("cannot copy old %s, to %s, generating new config", oldConfigPath, configPath)
+ } else {
+ configPath = defaultConfigPath
+ log.Infof("copied old %s, to %s", oldConfigPath, configPath)
+ }
+ }
+ }
+ if configPath == nil {
+ configPath = GenerateConfig(configDir)
+ }
+
+ return configPath
+
+}
diff --git a/config/config_test.go b/config/config_test.go
new file mode 100644
index 000000000..76e6988c0
--- /dev/null
+++ b/config/config_test.go
@@ -0,0 +1,61 @@
+package config
+
+import (
+ "fmt"
+ "os"
+ "testing"
+
+ "github.com/arduino/go-paths-helper"
+ "github.com/sirupsen/logrus"
+ "github.com/stretchr/testify/assert"
+)
+
+func TestGetConfigPath(t *testing.T) {
+ t.Run("read config.ini from ARDUINO_CREATE_AGENT_CONFIG", func(t *testing.T) {
+ os.Setenv("ARDUINO_CREATE_AGENT_CONFIG", "./testdata/fromenv/config.ini")
+ defer os.Unsetenv("ARDUINO_CREATE_AGENT_CONFIG")
+ configPath := GetConfigPath()
+ assert.Equal(t, "./testdata/fromenv/config.ini", configPath.String())
+ })
+
+ t.Run("panic if config.ini does not exist", func(t *testing.T) {
+ os.Setenv("ARDUINO_CREATE_AGENT_CONFIG", "./testdata/nonexistent_config.ini")
+ defer os.Unsetenv("ARDUINO_CREATE_AGENT_CONFIG")
+
+ defer func() {
+ if r := recover(); r != nil {
+ entry, ok := r.(*logrus.Entry)
+ if !ok {
+ t.Errorf("Expected panic of type *logrus.Entry but got %T", r)
+ } else {
+ assert.Equal(t, "config from env var ./testdata/nonexistent_config.ini does not exists", entry.Message)
+ }
+ } else {
+ t.Errorf("Expected panic but did not get one")
+ }
+ }()
+
+ GetConfigPath()
+ })
+
+ t.Run("read config.ini from $HOME", func(t *testing.T) {
+ os.Setenv("HOME", "./testdata/home")
+ defer os.Unsetenv("HOME")
+ configPath := GetConfigPath()
+ assert.Equal(t, "testdata/home/.config/ArduinoCreateAgent/config.ini", configPath.String())
+ })
+
+ t.Run("fallback old : read config.ini where the binary is launched", func(t *testing.T) {
+ src, _ := os.Executable()
+ paths.New(src).Parent().Join("config.ini").Create() // create a config.ini in the same directory as the binary
+ // The fallback path is the directory where the binary is launched
+ fmt.Println(src)
+ os.Setenv("HOME", "./testdata/noconfig") // force to not have a config in the home directory
+ defer os.Unsetenv("HOME")
+
+ // expect it creates a config.ini in the same directory as the binary
+ configPath := GetConfigPath()
+ assert.Equal(t, "testdata/home/.config/ArduinoCreateAgent/config.ini", configPath.String())
+ })
+
+}
diff --git a/config/testdata/fromenv/config.ini b/config/testdata/fromenv/config.ini
new file mode 100644
index 000000000..5b31315b9
--- /dev/null
+++ b/config/testdata/fromenv/config.ini
@@ -0,0 +1,8 @@
+gc = std
+hostname = unknown-hostname
+regex = usb|acm|com
+v = true
+appName = CreateAgent/Stable
+updateUrl = https://downloads.arduino.cc/
+origins = https://local.arduino.cc:8000, https://local.arduino.cc:8001, https://create-dev.arduino.cc, https://*.sparklyunicorn.cc, https://*.iot-cloud-arduino-cc.pages.dev, https://cloud.oniudra.cc, https://app.oniudra.cc,https://*.iot-cloud-arduino-cc.pages.dev
+crashreport = false
diff --git a/config/testdata/home/.config/ArduinoCreateAgent/config.ini b/config/testdata/home/.config/ArduinoCreateAgent/config.ini
new file mode 100644
index 000000000..92f231faf
--- /dev/null
+++ b/config/testdata/home/.config/ArduinoCreateAgent/config.ini
@@ -0,0 +1,8 @@
+gc = std
+hostname = unknown-hostname
+regex = usb|acm|com
+v = true
+appName = config-from-home-dir
+updateUrl = https://downloads.arduino.cc/
+origins = https://local.arduino.cc:8000, https://local.arduino.cc:8001, https://*.iot-cloud-arduino-cc.pages.dev
+crashreport = false
diff --git a/config/testdata/noconfig/.config/ArduinoCreateAgent/config.ini b/config/testdata/noconfig/.config/ArduinoCreateAgent/config.ini
new file mode 100644
index 000000000..f63377db5
--- /dev/null
+++ b/config/testdata/noconfig/.config/ArduinoCreateAgent/config.ini
@@ -0,0 +1,10 @@
+gc = std # Type of garbage collection. std = Normal garbage collection allowing system to decide (this has been known to cause a stop the world in the middle of a CNC job which can cause lost responses from the CNC controller and thus stalled jobs. use max instead to solve.), off = let memory grow unbounded (you have to send in the gc command manually to garbage collect or you will run out of RAM eventually), max = Force garbage collection on each recv or send on a serial port (this minimizes stop the world events and thus lost serial responses, but increases CPU usage)
+hostname = unknown-hostname # Override the hostname we get from the OS
+regex = usb|acm|com # Regular expression to filter serial port list
+v = true # show debug logging
+appName = CreateAgent/Stable
+updateUrl = https://downloads.arduino.cc/
+origins = https://local.arduino.cc:8000
+#httpProxy = http://your.proxy:port # Proxy server for HTTP requests
+crashreport = false # enable crashreport logging
+autostartMacOS = true # the Arduino Create Agent is able to start automatically after login on macOS (launchd agent)
\ No newline at end of file
diff --git a/hub.go b/hub.go
index a162dd01a..81a169121 100755
--- a/hub.go
+++ b/hub.go
@@ -58,7 +58,7 @@ var h = hub{
const commands = `{
"Commands": [
"list",
- "open [bufferAlgorithm: ({default}, timed, timedraw)]",
+ "open ",
"(send, sendnobuf, sendraw) ",
"close ",
"restart",
@@ -146,15 +146,13 @@ func checkCmd(m []byte) {
go spErr("Problem converting baud rate " + args[2])
return
}
- // pass in buffer type now as string. if user does not
- // ask for a buffer type pass in empty string
- bufferAlgorithm := "default" // use the default buffer if none is specified
+
+ // Ignore extra "buffer type" param for backward compatibility
if len(args) > 3 {
- // cool. we got a buffer type request
- buftype := strings.Replace(args[3], "\n", "", -1)
- bufferAlgorithm = buftype
+ log.Warn(fmt.Sprintf("Unexpected arguments for the open command. Ignored arguments: '%s'.", args[3:]))
}
- go spHandlerOpen(args[1], baud, bufferAlgorithm)
+
+ go spHandlerOpen(args[1], baud)
} else if strings.HasPrefix(sl, "close") {
diff --git a/main.go b/main.go
index 1ca857b02..a83d7f4c5 100755
--- a/main.go
+++ b/main.go
@@ -22,6 +22,7 @@ import (
_ "embed"
"encoding/json"
"flag"
+ "fmt"
"html/template"
"io"
"os"
@@ -188,38 +189,9 @@ func loop() {
h.broadcastSys <- mapB
}
- // Let's handle the config
- configDir := config.GetDefaultConfigDir()
- var configPath *paths.Path
+ configPath := config.GetConfigPath()
- // see if the env var is defined, if it is take the config from there, this will override the default path
- if envConfig := os.Getenv("ARDUINO_CREATE_AGENT_CONFIG"); envConfig != "" {
- configPath = paths.New(envConfig)
- if configPath.NotExist() {
- log.Panicf("config from env var %s does not exists", envConfig)
- }
- log.Infof("using config from env variable: %s", configPath)
- } else if defaultConfigPath := configDir.Join("config.ini"); defaultConfigPath.Exist() {
- // by default take the config from the ~/.arduino-create/config.ini file
- configPath = defaultConfigPath
- log.Infof("using config from default: %s", configPath)
- } else {
- // Fall back to the old config.ini location
- src, _ := os.Executable()
- oldConfigPath := paths.New(src).Parent().Join("config.ini")
- if oldConfigPath.Exist() {
- err := oldConfigPath.CopyTo(defaultConfigPath)
- if err != nil {
- log.Errorf("cannot copy old %s, to %s, generating new config", oldConfigPath, configPath)
- } else {
- configPath = defaultConfigPath
- log.Infof("copied old %s, to %s", oldConfigPath, configPath)
- }
- }
- }
- if configPath == nil {
- configPath = config.GenerateConfig(configDir)
- }
+ fmt.Println("configPath: ", configPath)
// if the default browser is Safari, prompt the user to install HTTPS certificates
// and eventually install them
diff --git a/serial.go b/serial.go
index 64e5b8f7f..f58414571 100755
--- a/serial.go
+++ b/serial.go
@@ -67,7 +67,7 @@ var sh = serialhub{
func (sh *serialhub) Register(port *serport) {
sh.mu.Lock()
//log.Print("Registering a port: ", p.portConf.Name)
- h.broadcastSys <- []byte("{\"Cmd\":\"Open\",\"Desc\":\"Got register/open on port.\",\"Port\":\"" + port.portConf.Name + "\",\"Baud\":" + strconv.Itoa(port.portConf.Baud) + ",\"BufferType\":\"" + port.BufferType + "\"}")
+ h.broadcastSys <- []byte("{\"Cmd\":\"Open\",\"Desc\":\"Got register/open on port.\",\"Port\":\"" + port.portConf.Name + "\",\"Baud\":" + strconv.Itoa(port.portConf.Baud) + "}")
sh.ports[port] = true
sh.mu.Unlock()
}
diff --git a/serialport.go b/serialport.go
index 0d386bbfc..9a06c7f9c 100755
--- a/serialport.go
+++ b/serialport.go
@@ -22,7 +22,6 @@ import (
"strconv"
"sync/atomic"
"time"
- "unicode/utf8"
log "github.com/sirupsen/logrus"
serial "go.bug.st/serial"
@@ -57,10 +56,7 @@ type serport struct {
// channel containing raw base64 encoded binary data (outbound messages)
sendRaw chan string
- // Do we have an extra channel/thread to watch our buffer?
- BufferType string
- //bufferwatcher *BufferflowDummypause
- bufferwatcher Bufferflow
+ bufferFlow *BufferflowTimed
}
// SpPortMessage is the serial port message
@@ -75,15 +71,13 @@ type SpPortMessageRaw struct {
D []byte // the data, i.e. G0 X0 Y0
}
-func (p *serport) reader(buftype string) {
+func (p *serport) reader() {
timeCheckOpen := time.Now()
- var bufferedCh bytes.Buffer
serialBuffer := make([]byte, 1024)
for {
n, err := p.portIo.Read(serialBuffer)
- bufferPart := serialBuffer[:n]
//if we detect that port is closing, break out of this for{} loop.
if p.isClosing.Load() {
@@ -96,39 +90,8 @@ func (p *serport) reader(buftype string) {
// read can return legitimate bytes as well as an error
// so process the n bytes red, if n > 0
if n > 0 && err == nil {
-
- log.Print("Read " + strconv.Itoa(n) + " bytes ch: " + string(bufferPart[:n]))
-
- data := ""
- switch buftype {
- case "timedraw", "timed":
- data = string(bufferPart[:n])
- // give the data to our bufferflow so it can do it's work
- // to read/translate the data to see if it wants to block
- // writes to the serialport. each bufferflow type will decide
- // this on its own based on its logic
- p.bufferwatcher.OnIncomingData(data)
- case "default": // the bufferbuftype is actually called default 🤷♂️
- // save the left out bytes for the next iteration due to UTF-8 encoding
- bufferPart = append(bufferedCh.Bytes(), bufferPart[:n]...)
- n += len(bufferedCh.Bytes())
- bufferedCh.Reset()
- for i, w := 0, 0; i < n; i += w {
- runeValue, width := utf8.DecodeRune(bufferPart[i:n]) // try to decode the first i bytes in the buffer (UTF8 runes do not have a fixed length)
- if runeValue == utf8.RuneError {
- bufferedCh.Write(bufferPart[i:n])
- break
- }
- if i == n {
- bufferedCh.Reset()
- }
- data += string(runeValue)
- w = width
- }
- p.bufferwatcher.OnIncomingData(data)
- default:
- log.Panicf("unknown buffer type %s", buftype)
- }
+ log.Print("Read " + strconv.Itoa(n) + " bytes ch: " + string(serialBuffer[:n]))
+ p.bufferFlow.OnIncomingData(string(serialBuffer[:n]))
}
// double check that we got characters in the buffer
@@ -273,7 +236,7 @@ func (p *serport) writerRaw() {
h.broadcastSys <- []byte(msgstr)
}
-func spHandlerOpen(portname string, baud int, buftype string) {
+func spHandlerOpen(portname string, baud int) {
log.Print("Inside spHandler")
@@ -312,23 +275,10 @@ func spHandlerOpen(portname string, baud int, buftype string) {
portConf: conf,
portIo: sp,
portName: portname,
- BufferType: buftype}
-
- var bw Bufferflow
-
- switch buftype {
- case "timed":
- bw = NewBufferflowTimed(portname, h.broadcastSys)
- case "timedraw":
- bw = NewBufferflowTimedRaw(portname, h.broadcastSys)
- case "default":
- bw = NewBufferflowDefault(portname, h.broadcastSys)
- default:
- log.Panicf("unknown buffer type: %s", buftype)
}
- bw.Init()
- p.bufferwatcher = bw
+ p.bufferFlow = NewBufferFlowTimed(portname, h.broadcastSys)
+ p.bufferFlow.Init()
sh.Register(p)
defer sh.Unregister(p)
@@ -343,7 +293,7 @@ func spHandlerOpen(portname string, baud int, buftype string) {
// this is thread to send to serial port but with base64 decoding
go p.writerRaw()
- p.reader(buftype)
+ p.reader()
serialPorts.List()
}
@@ -351,7 +301,7 @@ func spHandlerOpen(portname string, baud int, buftype string) {
func (p *serport) Close() {
p.isClosing.Store(true)
- p.bufferwatcher.Close()
+ p.bufferFlow.Close()
p.portIo.Close()
serialPorts.MarkPortAsClosed(p.portName)
serialPorts.List()
diff --git a/tests/test_ws.py b/tests/test_ws.py
index b8004649d..2f3ee9fa5 100644
--- a/tests/test_ws.py
+++ b/tests/test_ws.py
@@ -49,77 +49,28 @@ def test_list(socketio, message):
running_on_ci(),
reason="VMs have no serial ports",
)
-def test_open_serial_default(socketio, serial_port, baudrate, message):
- general_open_serial(socketio, serial_port, baudrate, message, "default")
-
-
-@pytest.mark.skipif(
- running_on_ci(),
- reason="VMs have no serial ports",
-)
-def test_open_serial_timed(socketio, serial_port, baudrate, message):
- general_open_serial(socketio, serial_port, baudrate, message, "timed")
-
-
-@pytest.mark.skipif(
- running_on_ci(),
- reason="VMs have no serial ports",
-)
-def test_open_serial_timedraw(socketio, serial_port, baudrate, message):
- general_open_serial(socketio, serial_port, baudrate, message, "timedraw")
-
+def test_open_serial(socketio, serial_port, baudrate, message):
+ general_open_serial(socketio, serial_port, baudrate, message)
# NOTE run the following tests with a board connected to the PC and with the sketch found in tests/testdata/SerialEcho.ino on it be sure to change serial_address in conftest.py
@pytest.mark.skipif(
running_on_ci(),
reason="VMs have no serial ports",
)
-def test_send_serial_default(socketio, close_port, serial_port, baudrate, message):
- general_send_serial(socketio, close_port, serial_port, baudrate, message, "default")
-
-
-@pytest.mark.skipif(
- running_on_ci(),
- reason="VMs have no serial ports",
-)
-def test_send_serial_timed(socketio, close_port, serial_port, baudrate, message):
- general_send_serial(socketio, close_port, serial_port, baudrate, message, "timed")
+def test_send_serial(socketio, close_port, serial_port, baudrate, message):
+ general_send_serial(socketio, close_port, serial_port, baudrate, message)
@pytest.mark.skipif(
running_on_ci(),
reason="VMs have no serial ports",
)
-def test_send_serial_timedraw(socketio, close_port, serial_port, baudrate, message):
- general_send_serial(socketio, close_port, serial_port, baudrate, message, "timedraw")
+def test_send_emoji_serial(socketio, close_port, serial_port, baudrate, message):
+ general_send_emoji_serial(socketio, close_port, serial_port, baudrate, message)
-@pytest.mark.skipif(
- running_on_ci(),
- reason="VMs have no serial ports",
-)
-def test_send_emoji_serial_default(socketio, close_port, serial_port, baudrate, message):
- general_send_emoji_serial(socketio, close_port, serial_port, baudrate, message, "default")
-
-
-@pytest.mark.skipif(
- running_on_ci(),
- reason="VMs have no serial ports",
-)
-def test_send_emoji_serial_timed(socketio, close_port, serial_port, baudrate, message):
- general_send_emoji_serial(socketio, close_port, serial_port, baudrate, message, "timed")
-
-
-@pytest.mark.skipif(
- running_on_ci(),
- reason="VMs have no serial ports",
-)
-def test_send_emoji_serial_timedraw(socketio, close_port, serial_port, baudrate, message):
- general_send_emoji_serial(socketio, close_port, serial_port, baudrate, message, "timedraw")
-
-
-def general_open_serial(socketio, serial_port, baudrate, message, buffertype):
- open_serial_port(socketio, serial_port, baudrate, message, buffertype)
+def general_open_serial(socketio, serial_port, baudrate, message):
+ open_serial_port(socketio, serial_port, baudrate, message)
# test the closing of the serial port, we are gonna use close_port for the other tests
socketio.emit('command', 'close ' + serial_port)
time.sleep(.2)
@@ -128,8 +79,8 @@ def general_open_serial(socketio, serial_port, baudrate, message, buffertype):
assert any("\"IsOpen\": false," in i for i in message)
-def general_send_serial(socketio, close_port, serial_port, baudrate, message, buffertype):
- open_serial_port(socketio, serial_port, baudrate, message, buffertype)
+def general_send_serial(socketio, close_port, serial_port, baudrate, message):
+ open_serial_port(socketio, serial_port, baudrate, message)
# send the string "ciao" using the serial connection
socketio.emit('command', 'send ' + serial_port + ' ciao')
time.sleep(1)
@@ -137,33 +88,27 @@ def general_send_serial(socketio, close_port, serial_port, baudrate, message, bu
# check if the send command has been registered
assert any("send " + serial_port + " ciao" in i for i in message)
#check if message has been sent back by the connected board
- if buffertype == "timedraw":
- output = decode_output(extract_serial_data(message))
- elif buffertype in ("default", "timed"):
- output = extract_serial_data(message)
+ output = extract_serial_data(message)
assert "ciao" in output
# the serial connection is closed by close_port() fixture: even if in case of test failure
-def general_send_emoji_serial(socketio, close_port, serial_port, baudrate, message, buffertype):
- open_serial_port(socketio, serial_port, baudrate, message, buffertype)
+def general_send_emoji_serial(socketio, close_port, serial_port, baudrate, message):
+ open_serial_port(socketio, serial_port, baudrate, message)
# send a lot of emoji: they can be messed up
socketio.emit('command', 'send ' + serial_port + ' /"🧀🧀🧀🧀🧀🧀🧀🧀🧀🧀/"')
time.sleep(1)
print(message)
# check if the send command has been registered
assert any("send " + serial_port + " /\"🧀🧀🧀🧀🧀🧀🧀🧀🧀🧀/\"" in i for i in message)
- if buffertype == "timedraw":
- output = decode_output(extract_serial_data(message))
- elif buffertype in ("default", "timed"):
- output = extract_serial_data(message)
+ output = extract_serial_data(message)
assert "/\"🧀🧀🧀🧀🧀🧀🧀🧀🧀🧀/\"" in output
# the serial connection is closed by close_port() fixture: even if in case of test failure
-def open_serial_port(socketio, serial_port, baudrate, message, buffertype):
- #open a new serial connection with the specified buffertype
- socketio.emit('command', 'open ' + serial_port + ' ' + baudrate + ' ' + buffertype)
+def open_serial_port(socketio, serial_port, baudrate, message):
+ #open a new serial connection
+ socketio.emit('command', 'open ' + serial_port + ' ' + baudrate)
# give time to the message var to be filled
time.sleep(.5)
print(message)
@@ -176,7 +121,7 @@ def open_serial_port(socketio, serial_port, baudrate, message, buffertype):
reason="VMs have no serial ports",
)
def test_sendraw_serial(socketio, close_port, serial_port, baudrate, message):
- open_serial_port(socketio, serial_port, baudrate, message, "timedraw")
+ open_serial_port(socketio, serial_port, baudrate, message)
#test with bytes
integers = [1, 2, 3, 4, 5]
bytes_array=bytearray(integers)
@@ -202,7 +147,7 @@ def extract_serial_data(msg):
serial_data+=json.loads(i)["D"]
print("serialdata:"+serial_data)
return serial_data
-
+
def decode_output(raw_output):
# print(raw_output)
base64_bytes = raw_output.encode('ascii') #encode rawoutput message into a bytes-like object