From 099fcede3db2be27ce968fac46f287e0d3a5fcdb Mon Sep 17 00:00:00 2001 From: lucarin91 Date: Fri, 5 Dec 2025 12:43:43 +0100 Subject: [PATCH 1/4] fix(pkg/board/remote): adb kill all port use wrong command --- pkg/board/remote/adb/adb.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/board/remote/adb/adb.go b/pkg/board/remote/adb/adb.go index 277aaad3..a4dc7435 100644 --- a/pkg/board/remote/adb/adb.go +++ b/pkg/board/remote/adb/adb.go @@ -132,7 +132,7 @@ func (a *ADBConnection) Forward(ctx context.Context, localPort int, remotePort i } func (a *ADBConnection) ForwardKillAll(ctx context.Context) error { - cmd, err := paths.NewProcess(nil, a.adbPath, "-s", a.host, "killforward-all") + cmd, err := paths.NewProcess(nil, a.adbPath, "-s", a.host, "forward", "--remove-all") if err != nil { return err } From 9adce3e4f37194e357932869f0cea6afb4e00feb Mon Sep 17 00:00:00 2001 From: lucarin91 Date: Fri, 5 Dec 2025 12:46:02 +0100 Subject: [PATCH 2/4] add adb forward test --- adbd.Dockerfile | 6 +- pkg/board/remote/remote_test.go | 130 ++++++++++++++------------------ scripts/pong-server.sh | 7 ++ 3 files changed, 66 insertions(+), 77 deletions(-) create mode 100755 scripts/pong-server.sh diff --git a/adbd.Dockerfile b/adbd.Dockerfile index 75826958..e658b9b4 100644 --- a/adbd.Dockerfile +++ b/adbd.Dockerfile @@ -1,7 +1,7 @@ FROM debian:trixie RUN apt-get update \ - && apt-get install -y --no-install-recommends adbd file ssh sudo \ + && apt-get install -y --no-install-recommends adbd file ssh sudo netcat-traditional \ && apt-get clean \ && rm -rf /var/lib/apt/lists/* @@ -10,7 +10,9 @@ RUN useradd -m --create-home --shell /bin/bash --user-group --groups sudo arduin mkdir /home/arduino/ArduinoApps && \ chown -R arduino:arduino /home/arduino/ArduinoApps +ADD scripts/pong-server.sh /usr/local/bin/pong-server.sh + WORKDIR /home/arduino EXPOSE 22 -CMD ["/bin/sh", "-c", "/usr/sbin/sshd -D & su arduino -c adbd"] +CMD ["/bin/sh", "-c", "/usr/sbin/sshd -D & su arduino -c adbd & pong-server.sh"] diff --git a/pkg/board/remote/remote_test.go b/pkg/board/remote/remote_test.go index c9efa339..ca48e251 100644 --- a/pkg/board/remote/remote_test.go +++ b/pkg/board/remote/remote_test.go @@ -16,19 +16,16 @@ package remote_test import ( - "context" "fmt" + "net" "io" - "os/exec" - "strconv" "strings" "testing" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "github.com/arduino/arduino-app-cli/cmd/feedback" "github.com/arduino/arduino-app-cli/internal/testtools" "github.com/arduino/arduino-app-cli/pkg/board/remote" "github.com/arduino/arduino-app-cli/pkg/board/remote/adb" @@ -123,7 +120,7 @@ func TestRemoteFS(t *testing.T) { } } -func TestSSHShell(t *testing.T) { +func TestRemoteShell(t *testing.T) { name, adbPort, sshPort := testtools.StartAdbDContainer(t) t.Cleanup(func() { testtools.StopAdbDContainer(t, name) }) @@ -187,83 +184,66 @@ func TestSSHShell(t *testing.T) { } -func TestSSHForwarder(t *testing.T) { - name, _, sshPort := testtools.StartAdbDContainer(t) +func TestRemoteForwarder(t *testing.T) { + name, adbPort, sshPort := testtools.StartAdbDContainer(t) t.Cleanup(func() { testtools.StopAdbDContainer(t, name) }) - conn, err := ssh.FromHost("arduino", "arduino", fmt.Sprintf("%s:%s", "localhost", sshPort)) - require.NoError(t, err) - - t.Run("Forward ADB", func(t *testing.T) { - ctx, cancel := context.WithCancel(t.Context()) - defer cancel() - - forwardPort, err := ports.GetAvailable() - require.NoError(t, err) - - err = conn.Forward(ctx, forwardPort, 5555) - if err != nil { - t.Errorf("Forward failed: %v", err) - } - if forwardPort <= 0 || forwardPort > 65535 { - t.Fatalf("invalid port: %d", forwardPort) - } - adb_forwarded_endpoint := fmt.Sprintf("localhost:%s", strconv.Itoa(forwardPort)) + const pongServerPort = 9999 + + remotes := []struct { + name string + conn remote.Forwarder + forwardPort int + }{ + { + name: "adb", + conn: func() remote.Forwarder { + conn, err := adb.FromHost("localhost:"+adbPort, "") + require.NoError(t, err) + return conn + }(), + forwardPort: func() int { + port, err := ports.GetAvailable() + require.NoError(t, err) + return port + }(), + }, + { + name: "ssh", + conn: func() remote.Forwarder { + conn, err := ssh.FromHost("arduino", "arduino", "127.0.0.1:"+sshPort) + require.NoError(t, err) + return conn + }(), + }, + + // We are skipping the local forwarder test, which is just an no op in this case. + } - out, err := exec.Command("adb", "connect", adb_forwarded_endpoint).CombinedOutput() - require.NoError(t, err, "adb connect output: %q", out) + for _, remote := range remotes { + t.Run(remote.name, func(t *testing.T) { + forwardPort, err := ports.GetAvailable() + require.NoError(t, err) - cmd := exec.Command("adb", "-s", adb_forwarded_endpoint, "shell", "echo", "Hello, World!") - out, err = cmd.CombinedOutput() - require.NoError(t, err, "command output: %q", out) - feedback.Printf("Command output:\n%s\n", string(out)) - require.NotNil(t, string(out)) - }) -} + err = remote.conn.Forward(t.Context(), forwardPort, pongServerPort) + assert.NoError(t, err) -func TestSSHKillForwarder(t *testing.T) { - name, _, sshPort := testtools.StartAdbDContainer(t) - t.Cleanup(func() { testtools.StopAdbDContainer(t, name) }) + conn, err := net.Dial("tcp", fmt.Sprintf("localhost:%d", forwardPort)) + require.NoError(t, err) - conn, err := ssh.FromHost("arduino", "arduino", fmt.Sprintf("%s:%s", "localhost", sshPort)) - require.NoError(t, err) + buf := [128]byte{} + n, err := conn.Read(buf[:]) + require.NoError(t, err) + require.Equal(t, "pong", string(buf[:n])) - t.Run("KillAllForwards", func(t *testing.T) { - ctx, cancel := context.WithCancel(t.Context()) - defer cancel() + err = conn.Close() + require.NoError(t, err) - forwardPort, err := ports.GetAvailable() - require.NoError(t, err) + err = remote.conn.ForwardKillAll(t.Context()) + assert.NoError(t, err) - err = conn.Forward(ctx, forwardPort, 5555) - if err != nil { - t.Errorf("Forward failed: %v", err) - } - if forwardPort <= 0 || forwardPort > 65535 { - t.Fatalf("invalid port: %d", forwardPort) - } - adb_forwarded_endpoint := fmt.Sprintf("localhost:%s", strconv.Itoa(forwardPort)) - - out, err := exec.Command("adb", "connect", adb_forwarded_endpoint).CombinedOutput() - require.NoError(t, err, "adb connect output: %q", out) - - cmd := exec.Command("adb", "-s", adb_forwarded_endpoint, "shell", "echo", "Hello, World!") - out, err = cmd.CombinedOutput() - require.NoError(t, err, "command output: %q", out) - feedback.Printf("Command output:\n%s\n", string(out)) - require.NotNil(t, string(out)) - - err = conn.ForwardKillAll(t.Context()) - require.NoError(t, err) - out, err = exec.Command("adb", "disconnect", adb_forwarded_endpoint).CombinedOutput() - require.NoError(t, err, "adb disconnect output: %q", out) - - out, err = exec.Command("adb", "connect", adb_forwarded_endpoint).CombinedOutput() - require.NoError(t, err, "adb connect output: %q", out) - - cmd = exec.Command("adb", "-s", adb_forwarded_endpoint, "shell", "echo", "Hello, World!") - out, err = cmd.CombinedOutput() - require.Error(t, err, "command output: %q", out) - feedback.Printf("Command output:\n%s\n", string(out)) - }) + _, err = net.Dial("tcp", fmt.Sprintf("localhost:%d", forwardPort)) + require.Error(t, err) + }) + } } diff --git a/scripts/pong-server.sh b/scripts/pong-server.sh new file mode 100755 index 00000000..585f79e0 --- /dev/null +++ b/scripts/pong-server.sh @@ -0,0 +1,7 @@ +#!/bin/sh + +PORT=9999 + +while true; do + echo -n "pong" | nc -l -p $PORT +done From b7481d3319ec84e81aaf6d3d453b8c315914d5ca Mon Sep 17 00:00:00 2001 From: lucarin91 Date: Fri, 5 Dec 2025 14:39:42 +0100 Subject: [PATCH 3/4] embed the script in then dockerfile --- adbd.Dockerfile | 11 ++++++++++- scripts/pong-server.sh | 7 ------- 2 files changed, 10 insertions(+), 8 deletions(-) delete mode 100755 scripts/pong-server.sh diff --git a/adbd.Dockerfile b/adbd.Dockerfile index e658b9b4..78e47a41 100644 --- a/adbd.Dockerfile +++ b/adbd.Dockerfile @@ -10,7 +10,16 @@ RUN useradd -m --create-home --shell /bin/bash --user-group --groups sudo arduin mkdir /home/arduino/ArduinoApps && \ chown -R arduino:arduino /home/arduino/ArduinoApps -ADD scripts/pong-server.sh /usr/local/bin/pong-server.sh +RUN cat > /usr/local/bin/pong-server.sh <<'EOF' +#!/bin/sh + +PORT=9999 + +while true; do + echo -n "pong" | nc -l -p $PORT +done +EOF +RUN chmod +x /usr/local/bin/pong-server.sh WORKDIR /home/arduino EXPOSE 22 diff --git a/scripts/pong-server.sh b/scripts/pong-server.sh deleted file mode 100755 index 585f79e0..00000000 --- a/scripts/pong-server.sh +++ /dev/null @@ -1,7 +0,0 @@ -#!/bin/sh - -PORT=9999 - -while true; do - echo -n "pong" | nc -l -p $PORT -done From 958f0a9b1161e9820f91a89d5e96491f09db6f38 Mon Sep 17 00:00:00 2001 From: lucarin91 Date: Fri, 5 Dec 2025 14:46:21 +0100 Subject: [PATCH 4/4] Revert "embed the script in then dockerfile" This reverts commit b7481d3319ec84e81aaf6d3d453b8c315914d5ca. --- adbd.Dockerfile | 11 +---------- scripts/pong-server.sh | 7 +++++++ 2 files changed, 8 insertions(+), 10 deletions(-) create mode 100755 scripts/pong-server.sh diff --git a/adbd.Dockerfile b/adbd.Dockerfile index 78e47a41..e658b9b4 100644 --- a/adbd.Dockerfile +++ b/adbd.Dockerfile @@ -10,16 +10,7 @@ RUN useradd -m --create-home --shell /bin/bash --user-group --groups sudo arduin mkdir /home/arduino/ArduinoApps && \ chown -R arduino:arduino /home/arduino/ArduinoApps -RUN cat > /usr/local/bin/pong-server.sh <<'EOF' -#!/bin/sh - -PORT=9999 - -while true; do - echo -n "pong" | nc -l -p $PORT -done -EOF -RUN chmod +x /usr/local/bin/pong-server.sh +ADD scripts/pong-server.sh /usr/local/bin/pong-server.sh WORKDIR /home/arduino EXPOSE 22 diff --git a/scripts/pong-server.sh b/scripts/pong-server.sh new file mode 100755 index 00000000..585f79e0 --- /dev/null +++ b/scripts/pong-server.sh @@ -0,0 +1,7 @@ +#!/bin/sh + +PORT=9999 + +while true; do + echo -n "pong" | nc -l -p $PORT +done