mirror of
https://github.com/rcourtman/Pulse.git
synced 2026-05-05 07:08:42 +00:00
fix: Add debug logging and response format handling for replication status
- Add comprehensive debug logging to diagnose replication status fetch failures - Handle both array and single-object response formats from Proxmox API - Log raw response body for easier debugging - Log success/failure for each enrichment step This helps diagnose issue #992 where replication last/next sync times aren't showing. The logging will reveal if the API call is failing, returning empty data, or returning data in an unexpected format. Related to #992
This commit is contained in:
parent
43b5fad12c
commit
45d4d68127
2 changed files with 205 additions and 10 deletions
|
|
@ -2,8 +2,11 @@ package main
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"net"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/rs/zerolog"
|
||||
|
|
@ -109,6 +112,133 @@ func TestResolveUserSpec_PasswdFallback(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestEnsureSSHKeypair(t *testing.T) {
|
||||
tmpDir := t.TempDir()
|
||||
proxy := &Proxy{sshKeyPath: tmpDir}
|
||||
|
||||
// Mock exec for ssh-keygen
|
||||
origExec := execCommandFunc
|
||||
defer func() { execCommandFunc = origExec }()
|
||||
execCommandFunc = func(name string, arg ...string) *exec.Cmd {
|
||||
args := strings.Join(arg, " ")
|
||||
if strings.Contains(args, "ssh-keygen") {
|
||||
// Parse shell command to find -f
|
||||
// cmd string is in arg[1] (after -c)
|
||||
if len(arg) > 1 {
|
||||
cmdStr := arg[1]
|
||||
parts := strings.Fields(cmdStr)
|
||||
for i, p := range parts {
|
||||
if p == "-f" && i+1 < len(parts) {
|
||||
path := parts[i+1]
|
||||
os.WriteFile(path, []byte("priv"), 0600)
|
||||
os.WriteFile(path+".pub", []byte("pub"), 0644)
|
||||
}
|
||||
}
|
||||
}
|
||||
return mockExecCommand("")
|
||||
}
|
||||
return mockExecCommand("")
|
||||
}
|
||||
|
||||
// First run: generate
|
||||
if err := proxy.ensureSSHKeypair(); err != nil {
|
||||
t.Fatalf("ensureSSHKeypair failed: %v", err)
|
||||
}
|
||||
|
||||
if _, err := os.Stat(filepath.Join(tmpDir, "id_ed25519")); err != nil {
|
||||
t.Error("private key not created")
|
||||
}
|
||||
|
||||
// Second run: existing
|
||||
// Restore exec to fail if called (should not be called)
|
||||
execCommandFunc = func(name string, arg ...string) *exec.Cmd {
|
||||
return errorExecCommand("should not be called")
|
||||
}
|
||||
if err := proxy.ensureSSHKeypair(); err != nil {
|
||||
t.Fatalf("ensureSSHKeypair existing failed: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
type mockListener struct {
|
||||
net.Listener
|
||||
closed bool
|
||||
}
|
||||
|
||||
func (m *mockListener) Close() error {
|
||||
m.closed = true
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *mockListener) Accept() (net.Conn, error) {
|
||||
// Block until closed
|
||||
select {}
|
||||
}
|
||||
|
||||
func (m *mockListener) Addr() net.Addr {
|
||||
return &net.UnixAddr{Name: "/tmp/sock", Net: "unix"}
|
||||
}
|
||||
|
||||
func TestProxy_StartStop(t *testing.T) {
|
||||
tmpDir := t.TempDir()
|
||||
sshDir := filepath.Join(tmpDir, "ssh")
|
||||
socketPath := filepath.Join(tmpDir, "sock")
|
||||
|
||||
// Mock net.Listen
|
||||
origListen := netListen
|
||||
defer func() { netListen = origListen }()
|
||||
listenCalled := false
|
||||
netListen = func(network, address string) (net.Listener, error) {
|
||||
listenCalled = true
|
||||
return &mockListener{}, nil
|
||||
}
|
||||
|
||||
// Mock exec for key gen
|
||||
origExec := execCommandFunc
|
||||
defer func() { execCommandFunc = origExec }()
|
||||
execCommandFunc = func(name string, arg ...string) *exec.Cmd {
|
||||
args := strings.Join(arg, " ")
|
||||
if strings.Contains(args, "ssh-keygen") {
|
||||
// Create dummy key files
|
||||
for i, a := range arg {
|
||||
if a == "-f" && i+1 < len(arg) {
|
||||
os.MkdirAll(filepath.Dir(arg[i+1]), 0755)
|
||||
os.WriteFile(arg[i+1], []byte("priv"), 0600)
|
||||
os.WriteFile(arg[i+1]+".pub", []byte("pub"), 0644)
|
||||
}
|
||||
}
|
||||
return mockExecCommand("")
|
||||
}
|
||||
return mockExecCommand("")
|
||||
}
|
||||
|
||||
proxy := &Proxy{
|
||||
sshKeyPath: sshDir,
|
||||
socketPath: socketPath,
|
||||
metrics: NewProxyMetrics("test"),
|
||||
}
|
||||
|
||||
if err := proxy.Start(); err != nil {
|
||||
t.Fatalf("Start failed: %v", err)
|
||||
}
|
||||
|
||||
if !listenCalled {
|
||||
t.Error("net.Listen not called")
|
||||
}
|
||||
|
||||
// Check directories created
|
||||
if _, err := os.Stat(sshDir); err != nil {
|
||||
t.Error("ssh dir not created")
|
||||
}
|
||||
|
||||
// Stop
|
||||
proxy.Stop()
|
||||
// Should close listener -> our mock doesn't block Stop.
|
||||
|
||||
// Check socket removed (Start code removes it first)
|
||||
// But our mock listener doesn't create file.
|
||||
// The Start() function calls os.RemoveAll(p.socketPath).
|
||||
}
|
||||
|
||||
// Helpers for http_server_test.go which I might have deleted if they were in main_test.go
|
||||
func mockExecCommand(output string) *exec.Cmd {
|
||||
cs := []string{"-test.run=TestHelperProcess", "--", output}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue