mirror of
https://github.com/portainer/portainer.git
synced 2025-07-24 15:59:41 +02:00
feat(support): collect system info bundle to assist support troubleshooting [r8s-157] (#154)
This commit is contained in:
parent
17648d12fe
commit
783ab253af
17 changed files with 1367 additions and 440 deletions
164
pkg/networking/diagnostics_test.go
Normal file
164
pkg/networking/diagnostics_test.go
Normal file
|
@ -0,0 +1,164 @@
|
|||
package networking
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
// Response structs for each function
|
||||
type dnsResponse struct {
|
||||
Operation string `json:"operation"`
|
||||
ResolvedIPs []string `json:"resolved_ips"`
|
||||
RemoteAddr string `json:"remote_address"`
|
||||
ConnectedAt string `json:"connected_at"`
|
||||
Status string `json:"status"`
|
||||
}
|
||||
|
||||
type telnetResponse struct {
|
||||
Operation string `json:"operation"`
|
||||
LocalAddr string `json:"local_address"`
|
||||
RemoteAddr string `json:"remote_address"`
|
||||
Network string `json:"network"`
|
||||
Status string `json:"status"`
|
||||
ConnectedAt string `json:"connected_at"`
|
||||
}
|
||||
|
||||
type proxyResponse struct {
|
||||
Operation string `json:"operation"`
|
||||
LocalAddr string `json:"local_address"`
|
||||
RemoteAddr string `json:"remote_address"`
|
||||
Network string `json:"network"`
|
||||
Status string `json:"status"`
|
||||
ConnectedAt string `json:"connected_at"`
|
||||
}
|
||||
|
||||
func TestProbeDNSConnection(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
host string
|
||||
wantSuccess bool
|
||||
statusContains string
|
||||
}{
|
||||
{
|
||||
name: "Valid domain",
|
||||
host: "https://api.portainer.io",
|
||||
wantSuccess: true,
|
||||
statusContains: "dns lookup successful",
|
||||
},
|
||||
{
|
||||
name: "Invalid domain",
|
||||
host: "https://nonexistent.domain.invalid",
|
||||
wantSuccess: false,
|
||||
statusContains: "dns lookup failed",
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
response := ProbeDNSConnection(tt.host)
|
||||
|
||||
var result dnsResponse
|
||||
if err := json.Unmarshal([]byte(response), &result); err != nil {
|
||||
t.Fatalf("Invalid JSON response: %v", err)
|
||||
}
|
||||
|
||||
if !strings.Contains(result.Status, tt.statusContains) {
|
||||
t.Errorf("Status should contain '%s', got: %s", tt.statusContains, result.Status)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestProbeTelnetConnection(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
url string
|
||||
wantSuccess bool
|
||||
statusContains string
|
||||
}{
|
||||
{
|
||||
name: "Valid connection",
|
||||
url: "https://api.portainer.io",
|
||||
wantSuccess: true,
|
||||
statusContains: "connected to",
|
||||
},
|
||||
{
|
||||
name: "Invalid port",
|
||||
url: "https://api.portainer.io:99999",
|
||||
wantSuccess: false,
|
||||
statusContains: "failed to connect",
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
response := ProbeTelnetConnection(tt.url)
|
||||
|
||||
var result telnetResponse
|
||||
if err := json.Unmarshal([]byte(response), &result); err != nil {
|
||||
t.Fatalf("Invalid JSON response: %v", err)
|
||||
}
|
||||
|
||||
validateCommonFields(t, result.Operation, "telnet connection", result.ConnectedAt)
|
||||
if !strings.Contains(result.Status, tt.statusContains) {
|
||||
t.Errorf("Status should contain '%s', got: %s", tt.statusContains, result.Status)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestDetectProxy(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
url string
|
||||
wantSuccess bool
|
||||
statusContains string
|
||||
}{
|
||||
{
|
||||
name: "Valid URL",
|
||||
url: "https://api.portainer.io",
|
||||
wantSuccess: true,
|
||||
statusContains: "proxy",
|
||||
},
|
||||
{
|
||||
name: "Invalid URL",
|
||||
url: "https://nonexistent.domain.invalid",
|
||||
wantSuccess: false,
|
||||
statusContains: "failed to make request",
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
response := DetectProxy(tt.url)
|
||||
|
||||
var result proxyResponse
|
||||
if err := json.Unmarshal([]byte(response), &result); err != nil {
|
||||
t.Fatalf("Invalid JSON response: %v", err)
|
||||
}
|
||||
|
||||
validateCommonFields(t, result.Operation, "proxy detection", result.ConnectedAt)
|
||||
if result.Network != "https" {
|
||||
t.Errorf("Expected network https, got %s", result.Network)
|
||||
}
|
||||
if !strings.Contains(result.Status, tt.statusContains) {
|
||||
t.Errorf("Status should contain '%s', got: %s", tt.statusContains, result.Status)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// Helper function to validate common fields across all responses
|
||||
func validateCommonFields(t *testing.T, operation, expectedOperation, connectedAt string) {
|
||||
t.Helper()
|
||||
|
||||
if operation != expectedOperation {
|
||||
t.Errorf("Expected operation '%s', got '%s'", expectedOperation, operation)
|
||||
}
|
||||
|
||||
if _, err := time.Parse(time.RFC3339, connectedAt); err != nil {
|
||||
t.Errorf("Invalid connected_at timestamp: %v", err)
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue