package arduinocli import ( "archive/tar" "compress/gzip" "context" "net/http" "net/http/httptest" "os" "path/filepath" "testing" "github.com/MDietermann/ArduinoArchSetup/internal/config" "github.com/MDietermann/ArduinoArchSetup/internal/module" ) type fakeRunner struct { runCalls [][]string outCalls [][]string coreListOut []byte } func (f *fakeRunner) Run(_ context.Context, name string, args ...string) error { f.runCalls = append(f.runCalls, append([]string{name}, args...)) return nil } func (f *fakeRunner) Output(_ context.Context, name string, args ...string) ([]byte, error) { f.outCalls = append(f.outCalls, append([]string{name}, args...)) if filepath.Base(name) == "arduino-cli" && len(args) >= 2 && args[0] == "core" && args[1] == "list" { return f.coreListOut, nil } return nil, nil } type nop struct{} func (nop) Progress(string, int, int, string) {} func (nop) Log(string, string) {} func makeTarGz(t *testing.T, entries map[string][]byte) string { t.Helper() p := filepath.Join(t.TempDir(), "a.tgz") f, _ := os.Create(p) gz := gzip.NewWriter(f) tw := tar.NewWriter(gz) for name, data := range entries { _ = tw.WriteHeader(&tar.Header{Name: name, Mode: 0o755, Size: int64(len(data))}) _, _ = tw.Write(data) } tw.Close() gz.Close() f.Close() return p } func TestArduinoCLIDownloadsAndInstallsCore(t *testing.T) { home := t.TempDir() t.Setenv("HOME", home) archive := makeTarGz(t, map[string][]byte{"arduino-cli": []byte("#!/bin/sh\n")}) srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { data, _ := os.ReadFile(archive) w.Write(data) })) defer srv.Close() r := &fakeRunner{coreListOut: []byte("ID Installed\n")} m := New(config.ArduinoCLIConfig{ Version: "1.0.0", URL: srv.URL + "/arduino-cli.tgz", Cores: []string{"arduino:avr"}, }, r) st, _ := m.Detect(context.Background()) p, _ := m.Plan(context.Background(), st) if err := m.Apply(context.Background(), p, nop{}); err != nil { t.Fatal(err) } if _, err := os.Stat(filepath.Join(home, ".local", "bin", "arduino-cli")); err != nil { t.Fatalf("binary not installed: %v", err) } sawCore := false for _, c := range r.runCalls { if filepath.Base(c[0]) == "arduino-cli" && len(c) >= 4 && c[1] == "core" && c[2] == "install" && c[3] == "arduino:avr" { sawCore = true } } if !sawCore { t.Fatalf("core install not run; calls=%v", r.runCalls) } } var _ module.Module = Module{}