Skip to content
Open
Show file tree
Hide file tree
Changes from 45 commits
Commits
Show all changes
48 commits
Select commit Hold shift + click to select a range
b24db69
fix: Copy the bundle to the VM
yejseo01 Nov 27, 2025
eebf9ec
fix: cleanup properly on bundle path
yejseo01 Nov 27, 2025
fd02300
fix: fix CI by migrating the simulator to the VM
yejseo01 Nov 19, 2025
45b8105
fix: stabilize CI
yejseo01 Nov 20, 2025
20afe34
fix: isolate the remoteproc names
yejseo01 Nov 24, 2025
ca87c58
fix: fix log skipping
yejseo01 Nov 24, 2025
fddc63a
fix: setup simulator in non-mounted area
yejseo01 Nov 26, 2025
02f713c
fix: Assert checks filesystem inside VM
yejseo01 Nov 27, 2025
d382711
fix: setup simulator and binaries in unmounted VM area
yejseo01 Nov 27, 2025
f13be98
lint: remove unnecessary print
yejseo01 Nov 27, 2025
2a7835c
fix: don't mount the area!
yejseo01 Nov 27, 2025
1b7f752
fix: improve remoteproc device indexing
yejseo01 Nov 27, 2025
92212d0
fix: remove mount dependency
yejseo01 Nov 27, 2025
b4b1919
fix: remove unused mount directory
yejseo01 Nov 27, 2025
28dde4a
fix: add test helper file
yejseo01 Nov 27, 2025
0f4065e
fix: Make sure that destination folders exist before building binaries
yejseo01 Dec 4, 2025
8168bd2
lint: receive error
yejseo01 Dec 5, 2025
a24fc01
lint: tie same types together in functions
yejseo01 Dec 5, 2025
d2445b5
refactor: Refactor the git process
yejseo01 Dec 5, 2025
c10291d
lint: verbosify function name
yejseo01 Dec 5, 2025
4db0ace
lint: rename function
yejseo01 Dec 5, 2025
880e601
lint: remove unnecessary comment
yejseo01 Dec 5, 2025
8a12116
fix: preserve Stop()'s error if there is any
yejseo01 Dec 5, 2025
efc268c
fix: remove potential lockup
yejseo01 Dec 5, 2025
87abf3e
fix: remove unncessary bits
yejseo01 Dec 5, 2025
1bb529b
fix: Pin the remoteproc-simulator when building
yejseo01 Dec 8, 2025
8f2ee8a
fix: Add assertion
yejseo01 Dec 8, 2025
3db3984
fix: make the detection target message const
yejseo01 Dec 8, 2025
e6451c8
fix: make rootpathPrefix more identifiable
yejseo01 Dec 8, 2025
12e7641
fix: don't use rootpathPrefix as binary dumping area
yejseo01 Dec 8, 2025
ef68f98
fix: retrieve correct number of files in VM dir
yejseo01 Dec 8, 2025
9c585fb
fix: remove simulator installation
yejseo01 Dec 8, 2025
4bc2193
fix: remove simulator installation properly
yejseo01 Dec 8, 2025
3aa6fa0
fix: download artifacts rather than building in CI
yejseo01 Dec 8, 2025
74f98ec
debug: check the architecture
yejseo01 Dec 8, 2025
37ed6b1
lint: remove unnecessary messages
yejseo01 Dec 8, 2025
79d1acc
lint: rename variable
yejseo01 Dec 8, 2025
778ed2c
fix: cleanup properly after the simulator inside the VM
yejseo01 Dec 8, 2025
93ad8cf
fix: remove usage of WithIndex()
yejseo01 Dec 8, 2025
55a26f9
fix: take if statement out of the loop
yejseo01 Dec 8, 2025
6569a68
refactor: cleanup parameter intake of Start()
yejseo01 Dec 8, 2025
1073bfd
lint: remove unused public function
yejseo01 Dec 8, 2025
84a6d9c
lint: pass limavm.Debian not limavm.VM
yejseo01 Dec 8, 2025
46bbba1
feat: implement vm.ReadDir() and use it
yejseo01 Dec 8, 2025
995da7c
fix: remove unnecessary modules
yejseo01 Dec 8, 2025
2cc4bd3
lint: rename variable to match consistency
yejseo01 Dec 9, 2025
684e8ce
fix: remove unnecessary parameters
yejseo01 Dec 9, 2025
3d19d40
fix: rename variable properly
yejseo01 Dec 9, 2025
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
12 changes: 0 additions & 12 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -54,18 +54,6 @@ jobs:
- name: Run fast tests
run: go test -v -race ./internal/...

- name: Download Remoteproc Simulator
uses: robinraju/release-downloader@daf26c55d821e836577a15f77d86ddc078948b05 # v1.12
with:
repository: arm/remoteproc-simulator
tag: 'v0.0.8'
fileName: remoteproc-simulator_*_linux_amd64.tar.gz
out-file-path: remoteproc-simulator
extract: true

- name: Install Remoteproc Simulator
run: echo "$PWD/remoteproc-simulator" >> $GITHUB_PATH

- name: Set up Lima
uses: lima-vm/lima-actions/setup@03b96d61959e83b2c737e44162c3088e81de0886 # v1.0.1
id: lima-actions-setup
Expand Down
4 changes: 2 additions & 2 deletions e2e/limavm/debian.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ type Debian struct {
VM
}

func NewDebian(mountDir string) (Debian, error) {
vm, err := newVM("debian", mountDir)
func NewDebian() (Debian, error) {
vm, err := newVM("debian")
if err != nil {
return Debian{}, err
}
Expand Down
4 changes: 2 additions & 2 deletions e2e/limavm/docker.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ type Docker struct {
VM
}

func NewDocker(mountDir string) (Docker, error) {
vm, err := newVM("docker", mountDir)
func NewDocker() (Docker, error) {
vm, err := newVM("docker")
if err != nil {
return Docker{}, err
}
Expand Down
32 changes: 30 additions & 2 deletions e2e/limavm/limavm.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"os"
"os/exec"
"path/filepath"
"strings"
"testing"

"github.com/arm/remoteproc-runtime/e2e/limavm/scripts"
Expand All @@ -19,8 +20,8 @@ var BinBuildEnv = map[string]string{
"GOOS": "linux",
}

func newVM(template string, mountDir string) (VM, error) {
vmName, err := scripts.PrepareLimaVM(template, mountDir)
func newVM(template string) (VM, error) {
vmName, err := scripts.PrepareLimaVM(template)
return VM{name: vmName}, err
}

Expand Down Expand Up @@ -84,6 +85,29 @@ func (vm VM) RunCommand(name string, args ...string) (stdout, stderr string, err
return stdout, stderr, nil
}

func (vm VM) ReadFileAsString(path string) (string, error) {
stdout, stderr, err := vm.RunCommand("cat", path)
if err != nil {
return "", fmt.Errorf("failed to read file %s: %w\nstderr:\n%s", path, err, stderr)
}
return stdout, nil
}

func (vm VM) ReadDir(path string) ([]string, error) {
stdout, stderr, err := vm.RunCommand("ls", "-1", path)
if err != nil {
return nil, fmt.Errorf("failed to read directory %s: %w\nstderr:\n%s", path, err, stderr)
}
entries := []string{}
for _, line := range strings.Split(stdout, "\n") {
line = strings.TrimSpace(line)
if line != "" {
entries = append(entries, line)
}
}
return entries, nil
}

type Runnable interface {
Run(args ...string) (stdout, stderr string, err error)
}
Expand All @@ -97,6 +121,10 @@ func (b InstalledBin) Run(args ...string) (stdout, stderr string, err error) {
return b.vm.RunCommand(b.pathToBin, args...)
}

func (b InstalledBin) Command(args ...string) *exec.Cmd {
return b.vm.cmd(b.pathToBin, args...)
}

func (b InstalledBin) Path() string {
return b.pathToBin
}
Expand Down
4 changes: 2 additions & 2 deletions e2e/limavm/podman.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ type Podman struct {
VM
}

func NewPodman(mountDir string) (Podman, error) {
vm, err := newVM("podman", mountDir)
func NewPodman() (Podman, error) {
vm, err := newVM("podman")
if err != nil {
return Podman{}, err
}
Expand Down
8 changes: 3 additions & 5 deletions e2e/limavm/scripts/prepare-lima-vm.sh
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,8 @@ TEMPLATE=""
MOUNT_DIR=""

usage() {
echo "Usage: $0 <template> <mount-dir>" >&2
echo "Usage: $0 <template>" >&2
echo " template: Lima template to use (docker or podman)" >&2
echo " mount-dir: Directory attached in the vm" >&2
exit 1
}

Expand All @@ -22,7 +21,7 @@ cleanup_on_failure() {

create_vm() {
echo "Creating Lima VM..." >&2
if ! limactl create --tty=false --name "$VM_NAME" --set ".mounts += [{\"location\":\"$MOUNT_DIR\",\"writable\":true}]" "template://$TEMPLATE"; then
if ! limactl create --tty=false --name "$VM_NAME" "template://$TEMPLATE"; then
echo "Error: Failed to create VM" >&2
exit 1
fi
Expand All @@ -38,12 +37,11 @@ start_vm() {
}

main() {
if [ $# -ne 2 ]; then
if [ $# -ne 1 ]; then
usage
fi

TEMPLATE="$1"
MOUNT_DIR="$2"

VM_NAME="remoteproc-test-vm-$(date +%s)"
echo "Creating VM: $VM_NAME" >&2
Expand Down
4 changes: 2 additions & 2 deletions e2e/limavm/scripts/scripts.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ var (
teardownLimaVMScript = filepath.Join(scriptsDir, "teardown-lima-vm.sh")
)

func PrepareLimaVM(template string, mountDir string) (string, error) {
prepareCmd := exec.Command(prepareLimaVMScript, template, mountDir)
func PrepareLimaVM(template string) (string, error) {
prepareCmd := exec.Command(prepareLimaVMScript, template)
prepareStreamer := runner.NewStreamingCmd(prepareCmd).WithPrefix("prepare-vm")

if err := prepareStreamer.Start(); err != nil {
Expand Down
16 changes: 8 additions & 8 deletions e2e/remoteproc/assert.go
Original file line number Diff line number Diff line change
@@ -1,38 +1,38 @@
package remoteproc

import (
"os"
"path/filepath"
"testing"
"time"

"github.com/arm/remoteproc-runtime/e2e/limavm"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)

func AssertState(t testing.TB, deviceDir string, wantState string) {
func AssertState(t testing.TB, vm limavm.VM, deviceDir, wantState string) {
t.Helper()
const waitFor = 500 * time.Millisecond
const tickEvery = 100 * time.Millisecond
stateFilePath := filepath.Join(deviceDir, "state")
assert.EventuallyWithT(t, func(c *assert.CollectT) {
assertFileContent(c, stateFilePath, wantState)
assertFileContent(c, vm, stateFilePath, wantState)
}, waitFor, tickEvery)
}

func RequireState(t testing.TB, deviceDir string, wantState string) {
func RequireState(t testing.TB, vm limavm.VM, deviceDir, wantState string) {
t.Helper()
const waitFor = 500 * time.Millisecond
const tickEvery = 100 * time.Millisecond
stateFilePath := filepath.Join(deviceDir, "state")
require.EventuallyWithT(t, func(c *assert.CollectT) {
assertFileContent(c, stateFilePath, wantState)
assertFileContent(c, vm, stateFilePath, wantState)
}, waitFor, tickEvery)
}

func assertFileContent(t assert.TestingT, path string, wantContent string) {
gotContent, err := os.ReadFile(path)
func assertFileContent(t assert.TestingT, vm limavm.VM, path, wantContent string) {
gotContent, err := vm.ReadFileAsString(path)
if assert.NoError(t, err) {
assert.Equal(t, wantContent, string(gotContent))
assert.Equal(t, wantContent, gotContent)
}
}
64 changes: 59 additions & 5 deletions e2e/remoteproc/simulator.go
Original file line number Diff line number Diff line change
@@ -1,22 +1,28 @@
package remoteproc

import (
"bufio"
"fmt"
"os/exec"
"io"
"path/filepath"
"strings"
"time"

"github.com/arm/remoteproc-runtime/e2e/limavm"
"github.com/arm/remoteproc-runtime/e2e/runner"
)

type Simulator struct {
vm limavm.InstalledBin
cmd *runner.StreamingCmd
name string
index uint
rootDir string
}

func NewSimulator(rootDir string) *Simulator {
func NewSimulator(vm limavm.InstalledBin, rootDir string) *Simulator {
return &Simulator{
vm: vm,
rootDir: rootDir,
index: 0,
name: "some-cpu",
Expand All @@ -29,20 +35,68 @@ func (r *Simulator) WithName(name string) *Simulator {
}

func (r *Simulator) Start() error {
cmd := exec.Command(
"remoteproc-simulator",
cmd := r.vm.Command(
"--root-dir", r.rootDir,
"--index", fmt.Sprintf("%d", r.index),
"--name", r.name,
)
streamer := runner.NewStreamingCmd(cmd).WithPrefix("remoteproc-simulator")
reader, writer := io.Pipe()
streamer := runner.NewStreamingCmd(cmd).WithPrefix("simulator: " + r.name + ": ").WithAdditionalOutput(writer)
if err := streamer.Start(); err != nil {
return fmt.Errorf("failed to start simulator: %w", err)
}
r.cmd = streamer

if err := r.waitForBoot(15*time.Second, reader); err != nil {
stopError := r.Stop()
if stopError != nil {
return fmt.Errorf("simulator failed to create remoteproc device: %w: %s", err, stopError)
}
return fmt.Errorf("simulator failed to create remoteproc device: %w", err)
}

return nil
}

func (r *Simulator) waitForBoot(waitingTime time.Duration, outputBuf *io.PipeReader) error {
const targetMessage = "Remoteproc initialized at"

deadline := time.Now().Add(waitingTime)
scanner := bufio.NewScanner(outputBuf)
timer := time.NewTimer(time.Until(deadline))
defer timer.Stop()
scanCh := make(chan string)
errCh := make(chan error)

go func() {
for scanner.Scan() {
scanCh <- scanner.Text()
}
if err := scanner.Err(); err != nil {
errCh <- err
} else {
close(scanCh)
}
}()

for {
select {
case <-timer.C:
return fmt.Errorf("timeout waiting for simulator to create remoteproc device")
case line, ok := <-scanCh:
if !ok {
return fmt.Errorf("simulator output closed before remoteproc device was created")
}
if strings.Contains(line, targetMessage) {
_ = outputBuf.Close()
return nil
}
case err := <-errCh:
return fmt.Errorf("scanner error: %w", err)
}
}
}

func (r *Simulator) Stop() error {
if r.cmd != nil {
return r.cmd.Stop()
Expand Down
36 changes: 36 additions & 0 deletions e2e/repo/bin.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"os"
"os/exec"
"path/filepath"
"runtime"
)

func BuildRuntimeBin(binOutDir string, rootPathPrefix string, env map[string]string) (string, error) {
Expand Down Expand Up @@ -72,3 +73,38 @@ func BuildBothBins(binOutDir string, rootPathPrefix string, env map[string]strin

return []string{runtime, shim}, nil
}

func BuildRemoteprocSimulator(binOutDir string, env map[string]string) (string, error) {
const repoDirName = "remoteproc-simulator"
const version = "0.0.8"

artifactURL := fmt.Sprintf(
"https://github.com/arm/remoteproc-simulator/releases/download/v%s/remoteproc-simulator_%s_linux_%s.tar.gz",
version,
version,
runtime.GOARCH,
)

downloader := exec.Command("curl", "-L", "-o", filepath.Join(binOutDir, "simulator.tar.gz"), artifactURL)
downloader.Env = os.Environ()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this and line 95 actually necessary? What environment variables do we need?

for k, v := range env {
downloader.Env = append(downloader.Env, fmt.Sprintf("%s=%s", k, v))
}

if out, err := downloader.CombinedOutput(); err != nil {
return "", fmt.Errorf("failed to download remoteproc-simulator: %s\n%s", err, out)
}

extractor := exec.Command("tar", "-xzf", filepath.Join(binOutDir, "simulator.tar.gz"), "-C", binOutDir)
extractor.Env = os.Environ()
for k, v := range env {
extractor.Env = append(extractor.Env, fmt.Sprintf("%s=%s", k, v))
}

if out, err := extractor.CombinedOutput(); err != nil {
return "", fmt.Errorf("failed to extract remoteproc-simulator: %s\n%s", err, out)
}

simulatorPath := filepath.Join(binOutDir, repoDirName)
return simulatorPath, nil
}
Loading