Очередь job получила lease и fencing, телеметрия и прогресс deploy сохраняются, ревизия пишет manifest входов. Обновление префиксов не переписывает неизменённый снимок, большие наборы идут через COPY, а устаревшая ревизия не попадает в deploy. Бандл ноды кэшируется, prune и постановка job больше не держат горячий путь. Co-authored-by: Cursor <[email protected]>
81 lines
2.1 KiB
Go
81 lines
2.1 KiB
Go
package httpapi
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"io"
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"net/url"
|
|
"testing"
|
|
|
|
"evobgp/internal/store"
|
|
)
|
|
|
|
func TestLookupMembershipHTTP(t *testing.T) {
|
|
srv, err := New(Options{InsecureDev: true, SeedDemo: true, BundleSeedHex: testBundleSeed})
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
defer srv.Close()
|
|
tenant, _, modIP, _, _ := srv.Store().DemoIDs()
|
|
mustSetTestAPIKeys(t, srv, "edkey|"+tenant+"|editor")
|
|
|
|
comms, err := srv.Store().ListCommunities(tenant)
|
|
if err != nil || len(comms) == 0 {
|
|
t.Fatal("demo community")
|
|
}
|
|
cid := comms[0].ID
|
|
if _, err := srv.Store().CreateIPRangeEntry(tenant, modIP, &store.IPRangeEntry{
|
|
Prefix: "198.51.100.0/24",
|
|
CommunityID: &cid,
|
|
}); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if err := srv.Store().SetModulePrefixSnapshot(context.Background(), tenant, modIP, "t", []store.PrefixRow{
|
|
{Prefix: "198.51.100.0/24", CommunityID: &cid, Source: "ip_range"},
|
|
}); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
ts := httptest.NewServer(srv.Handler())
|
|
defer ts.Close()
|
|
|
|
req, _ := http.NewRequest(http.MethodGet, ts.URL+"/v1/lookup?q="+url.QueryEscape("198.51.100.7"), nil)
|
|
req.Header.Set("Authorization", "Bearer edkey")
|
|
resp, err := ts.Client().Do(req)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
defer func() { _ = resp.Body.Close() }()
|
|
if resp.StatusCode != http.StatusOK {
|
|
b, _ := io.ReadAll(resp.Body)
|
|
t.Fatalf("status %d: %s", resp.StatusCode, b)
|
|
}
|
|
var body struct {
|
|
Matched bool `json:"matched"`
|
|
MatchCount int `json:"match_count"`
|
|
QueryKind string `json:"query_kind"`
|
|
Matches []struct {
|
|
Layer string `json:"layer"`
|
|
} `json:"matches"`
|
|
}
|
|
if err := json.NewDecoder(resp.Body).Decode(&body); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if !body.Matched || body.QueryKind != "ip" || body.MatchCount < 2 {
|
|
t.Fatalf("unexpected body: %+v", body)
|
|
}
|
|
|
|
reqBad, _ := http.NewRequest(http.MethodGet, ts.URL+"/v1/lookup?q=", nil)
|
|
reqBad.Header.Set("Authorization", "Bearer edkey")
|
|
respBad, err := ts.Client().Do(reqBad)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
defer func() { _ = respBad.Body.Close() }()
|
|
if respBad.StatusCode != http.StatusBadRequest {
|
|
t.Fatalf("empty q: status %d", respBad.StatusCode)
|
|
}
|
|
}
|