Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

fix(pkg/board/remote): adb kill all port use wrong command #147

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
lucarin91 merged 4 commits into arduino:main from lucarin91:fix-forward-kill-all
Dec 5, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions adbd.Dockerfile
View file Open in desktop
Original file line number Diff line number Diff line change
@@ -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/*

Expand All @@ -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"]
2 changes: 1 addition & 1 deletion pkg/board/remote/adb/adb.go
View file Open in desktop
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
Expand Down
130 changes: 55 additions & 75 deletions pkg/board/remote/remote_test.go
View file Open in desktop
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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) })

Expand Down Expand Up @@ -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)
})
}
}
7 changes: 7 additions & 0 deletions scripts/pong-server.sh
View file Open in desktop
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#!/bin/sh

PORT=9999

while true; do
echo -n "pong" | nc -l -p $PORT
done

AltStyle によって変換されたページ (->オリジナル) /