mirror of
https://github.com/rcourtman/Pulse.git
synced 2026-10-27 14:07:31 +00:00
b5444cf8bf
The vSphere Activity tab titled every vCenter event with its class name
("HostConnectedEvent", "HostProfileAppliedEvent"), and its When column
clipped the time on every row at most widths.
Pulse never asked vCenter for the readable message: QueryEvents leaves
out fullFormattedMessage unless the filter sets disableFullMessage, so
on a real vCenter the drawer's Message row was always empty too. The
client now sends disableFullMessage: false, and the provider titles an
event change with that message, falling back to the class. That also
gives Patrol's change context a readable reason. The page model prefers
the message for rows stored before this change, and keeps the class as
an Event type row in the drawer and in search.
When now reads as an age ("1d ago"), as Kubernetes events do, with the
exact time on hover and in the drawer. A vCenter time before 2000 (its
unset marker) still shows as "-". The Activity table moves from the
date-time registry rule to the relative-time rule.
107 lines
3.0 KiB
Go
107 lines
3.0 KiB
Go
package vmware
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"io"
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"strings"
|
|
"testing"
|
|
"time"
|
|
)
|
|
|
|
func writeVIJSONResponse(w http.ResponseWriter, payload any) {
|
|
w.Header().Set("Content-Type", "application/json")
|
|
_ = json.NewEncoder(w).Encode(payload)
|
|
}
|
|
|
|
// The vSphere VI JSON API documents a `_typeName` discriminator on request data
|
|
// objects. A bare ManagedObjectReference is accepted without one, but the
|
|
// composite argument objects (PerfQuerySpec, PerfMetricId, EventFilterSpec and
|
|
// its nested EventFilterSpecByEntity) are rejected with HTTP 500 when the
|
|
// discriminator is absent. These tests pin the exact request bodies that
|
|
// vCenter 8.0.3 rejected for issue #2070.
|
|
|
|
func newVIJSONRequestClient(t *testing.T, handler http.Handler) (*Client, func()) {
|
|
t.Helper()
|
|
server := httptest.NewTLSServer(handler)
|
|
client, err := NewClient(ClientConfig{
|
|
Host: server.URL,
|
|
Username: "admin",
|
|
Password: "secret",
|
|
InsecureSkipVerify: true,
|
|
Timeout: 5 * time.Second,
|
|
})
|
|
if err != nil {
|
|
server.Close()
|
|
t.Fatalf("NewClient: %v", err)
|
|
}
|
|
return client, server.Close
|
|
}
|
|
|
|
func TestQueryPerfRequestCarriesTypeNameDiscriminators(t *testing.T) {
|
|
var raw []byte
|
|
mux := http.NewServeMux()
|
|
mux.HandleFunc("/sdk/vim25/9.0.0.0/PerformanceManager/PerformanceManager/QueryPerf", func(w http.ResponseWriter, r *http.Request) {
|
|
raw, _ = io.ReadAll(r.Body)
|
|
writeVIJSONResponse(w, []map[string]any{})
|
|
})
|
|
client, closeServer := newVIJSONRequestClient(t, mux)
|
|
defer closeServer()
|
|
|
|
_, err := client.queryPerfMetrics(
|
|
context.Background(),
|
|
"9.0.0.0",
|
|
"vi-session",
|
|
"PerformanceManager",
|
|
"HostSystem",
|
|
"host-101",
|
|
20,
|
|
[]viJSONPerfMetricID{{CounterID: 1, Instance: ""}},
|
|
)
|
|
if err != nil {
|
|
t.Fatalf("queryPerfMetrics: %v", err)
|
|
}
|
|
|
|
body := string(raw)
|
|
for _, want := range []string{
|
|
`"_typeName":"PerfQuerySpec"`,
|
|
`"_typeName":"ManagedObjectReference"`,
|
|
`"_typeName":"PerfMetricId"`,
|
|
} {
|
|
if !strings.Contains(body, want) {
|
|
t.Fatalf("QueryPerf request %s missing %s", body, want)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestQueryEventsRequestCarriesTypeNameDiscriminators(t *testing.T) {
|
|
var raw []byte
|
|
mux := http.NewServeMux()
|
|
mux.HandleFunc("/sdk/vim25/9.0.0.0/EventManager/EventManager/QueryEvents", func(w http.ResponseWriter, r *http.Request) {
|
|
raw, _ = io.ReadAll(r.Body)
|
|
writeVIJSONResponse(w, []map[string]any{})
|
|
})
|
|
client, closeServer := newVIJSONRequestClient(t, mux)
|
|
defer closeServer()
|
|
|
|
_, err := client.collectRecentEvents(context.Background(), "9.0.0.0", "vi-session", "EventManager", "Network", "network-14")
|
|
if err != nil {
|
|
t.Fatalf("collectRecentEvents: %v", err)
|
|
}
|
|
|
|
body := string(raw)
|
|
for _, want := range []string{
|
|
`"_typeName":"EventFilterSpec"`,
|
|
`"_typeName":"EventFilterSpecByEntity"`,
|
|
`"_typeName":"ManagedObjectReference"`,
|
|
// Unset, vCenter leaves out every event's readable message.
|
|
`"disableFullMessage":false`,
|
|
} {
|
|
if !strings.Contains(body, want) {
|
|
t.Fatalf("QueryEvents request %s missing %s", body, want)
|
|
}
|
|
}
|
|
}
|