prober: update runall handler to be generic (#16895)
Update the runall handler to be more generic with an exclude param to exclude multiple probes as the requesters definition. Updates tailscale/corp#27370 Signed-off-by: Mike O'Driscoll <mikeo@tailscale.com>
This commit is contained in:
+4
-1
@@ -18,6 +18,7 @@ import (
|
|||||||
"maps"
|
"maps"
|
||||||
"math/rand"
|
"math/rand"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"slices"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@@ -585,10 +586,12 @@ type RunHandlerAllResponse struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (p *Prober) RunAllHandler(w http.ResponseWriter, r *http.Request) error {
|
func (p *Prober) RunAllHandler(w http.ResponseWriter, r *http.Request) error {
|
||||||
|
excluded := r.URL.Query()["exclude"]
|
||||||
|
|
||||||
probes := make(map[string]*Probe)
|
probes := make(map[string]*Probe)
|
||||||
p.mu.Lock()
|
p.mu.Lock()
|
||||||
for _, probe := range p.probes {
|
for _, probe := range p.probes {
|
||||||
if !probe.IsContinuous() && probe.name != "derpmap-probe" {
|
if !probe.IsContinuous() && !slices.Contains(excluded, probe.name) {
|
||||||
probes[probe.name] = probe
|
probes[probe.name] = probe
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+68
-1
@@ -11,6 +11,7 @@ import (
|
|||||||
"io"
|
"io"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/http/httptest"
|
"net/http/httptest"
|
||||||
|
"net/url"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
@@ -722,7 +723,7 @@ func TestRunAllHandler(t *testing.T) {
|
|||||||
|
|
||||||
mux.Handle("/prober/runall/", tsweb.StdHandler(tsweb.ReturnHandlerFunc(p.RunAllHandler), tsweb.HandlerOptions{}))
|
mux.Handle("/prober/runall/", tsweb.StdHandler(tsweb.ReturnHandlerFunc(p.RunAllHandler), tsweb.HandlerOptions{}))
|
||||||
|
|
||||||
req, err := http.NewRequest("GET", server.URL+"/prober/runall/", nil)
|
req, err := http.NewRequest("GET", server.URL+"/prober/runall", nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("failed to create request: %v", err)
|
t.Fatalf("failed to create request: %v", err)
|
||||||
}
|
}
|
||||||
@@ -757,6 +758,72 @@ func TestRunAllHandler(t *testing.T) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestExcludeInRunAll(t *testing.T) {
|
||||||
|
clk := newFakeTime()
|
||||||
|
p := newForTest(clk.Now, clk.NewTicker).WithOnce(true)
|
||||||
|
|
||||||
|
wantJSONResponse := RunHandlerAllResponse{
|
||||||
|
Results: map[string]RunHandlerResponse{
|
||||||
|
"includedProbe": {
|
||||||
|
ProbeInfo: ProbeInfo{
|
||||||
|
Name: "includedProbe",
|
||||||
|
Interval: probeInterval,
|
||||||
|
Status: ProbeStatusSucceeded,
|
||||||
|
RecentResults: []bool{true, true},
|
||||||
|
},
|
||||||
|
PreviousSuccessRatio: 1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
p.Run("includedProbe", probeInterval, nil, FuncProbe(func(context.Context) error { return nil }))
|
||||||
|
p.Run("excludedProbe", probeInterval, nil, FuncProbe(func(context.Context) error { return nil }))
|
||||||
|
p.Run("excludedOtherProbe", probeInterval, nil, FuncProbe(func(context.Context) error { return nil }))
|
||||||
|
|
||||||
|
mux := http.NewServeMux()
|
||||||
|
server := httptest.NewServer(mux)
|
||||||
|
defer server.Close()
|
||||||
|
|
||||||
|
mux.Handle("/prober/runall", tsweb.StdHandler(tsweb.ReturnHandlerFunc(p.RunAllHandler), tsweb.HandlerOptions{}))
|
||||||
|
|
||||||
|
req, err := http.NewRequest("GET", server.URL+"/prober/runall", nil)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("failed to create request: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Exclude probes with "excluded" in their name
|
||||||
|
req.URL.RawQuery = url.Values{
|
||||||
|
"exclude": []string{"excludedProbe", "excludedOtherProbe"},
|
||||||
|
}.Encode()
|
||||||
|
|
||||||
|
resp, err := http.DefaultClient.Do(req)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("failed to make request: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if resp.StatusCode != http.StatusOK {
|
||||||
|
t.Errorf("unexpected response code: got %d, want %d", resp.StatusCode, http.StatusOK)
|
||||||
|
}
|
||||||
|
|
||||||
|
var gotJSON RunHandlerAllResponse
|
||||||
|
body, err := io.ReadAll(resp.Body)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("failed to read response body: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := json.Unmarshal(body, &gotJSON); err != nil {
|
||||||
|
t.Fatalf("failed to unmarshal JSON response: %v; body: %s", err, body)
|
||||||
|
}
|
||||||
|
|
||||||
|
if resp.Header.Get("Content-Type") != "application/json" {
|
||||||
|
t.Errorf("unexpected content type: got %q, want application/json", resp.Header.Get("Content-Type"))
|
||||||
|
}
|
||||||
|
|
||||||
|
if diff := cmp.Diff(wantJSONResponse, gotJSON, cmpopts.IgnoreFields(ProbeInfo{}, "Start", "End", "Labels", "RecentLatencies")); diff != "" {
|
||||||
|
t.Errorf("unexpected JSON response (-want +got):\n%s", diff)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
type fakeTicker struct {
|
type fakeTicker struct {
|
||||||
ch chan time.Time
|
ch chan time.Time
|
||||||
interval time.Duration
|
interval time.Duration
|
||||||
|
|||||||
Reference in New Issue
Block a user