package tools import ( "context" "errors" "os" "path/filepath" "strings" "testing" ) func TestPingReportsExecutionErrorsAndNoReply(t *testing.T) { dir := t.TempDir() t.Setenv("PATH", dir) m := NewManager() if _, err := m.RunPing(context.Background(), PingRequest{Target: "192.0.2.1"}); err == nil { t.Fatal("missing ping binary reported as timeout") } path := filepath.Join(dir, "ping") if err := os.WriteFile(path, []byte("#!/bin/sh\nprintf 'ping: invalid option\\n'\nexit 2\n"), 0755); err != nil { t.Fatal(err) } if _, err := m.RunPing(context.Background(), PingRequest{Target: "192.0.2.1"}); err == nil || !strings.Contains(err.Error(), "invalid option") { t.Fatalf("execution error: %v", err) } if err := os.WriteFile(path, []byte("#!/bin/sh\nprintf '1 packets transmitted, 0 received, 100%% packet loss\\n'\nexit 1\n"), 0755); err != nil { t.Fatal(err) } resp, err := m.RunPing(context.Background(), PingRequest{Target: "192.0.2.1", Count: 1}) if err != nil || resp.Status != "timeout" || resp.PacketLossPct != 100 { t.Fatalf("no reply: %+v %v", resp, err) } if _, err := m.RunPing(context.Background(), PingRequest{Target: "192.0.2.1", Interface: "bad interface"}); err == nil { t.Fatal("invalid interface ignored") } } func TestStreamPingReportsExecutionError(t *testing.T) { dir := t.TempDir() t.Setenv("PATH", dir) if err := os.WriteFile(filepath.Join(dir, "ping"), []byte("#!/bin/sh\nprintf 'ping: invalid option\\n'\nexit 2\n"), 0755); err != nil { t.Fatal(err) } var events []PingStreamEvent err := NewManager().StreamPing(context.Background(), PingRequest{Target: "192.0.2.1"}, func(e PingStreamEvent) { events = append(events, e) }) if err == nil { t.Fatal("ping process failure ignored") } for _, event := range events { if event.Type == "done" { t.Fatal("reported completion after execution failure") } } if err = NewManager().StreamPing(context.Background(), PingRequest{Target: "192.0.2.1", Interface: "bad interface"}, func(PingStreamEvent) {}); err == nil { t.Fatal("invalid interface accepted") } } func TestPingHonorsCanceledContext(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) cancel() _, err := NewManager().RunPing(ctx, PingRequest{Target: "192.0.2.1"}) if !errors.Is(err, context.Canceled) { t.Fatalf("expected canceled context, got %v", err) } }