Files
cloud-ip-validator/internal/openstack/client_paging_test.go
T

86 lines
2.4 KiB
Go
Raw Normal View History

package openstack
import (
"context"
"encoding/json"
"fmt"
"net/http"
"net/http/httptest"
"testing"
"time"
"github.com/gophercloud/gophercloud/v2"
)
// TestClientListFreeFloatingIPsAgainstFakeNeutron drives the real Client
// against an httptest server: marker pagination, the `fields` projection, a
// transient 503 that is retried and an empty port_id meaning "free".
func TestClientListFreeFloatingIPsAgainstFakeNeutron(t *testing.T) {
const total = 5
var requests int
failedOnce := false
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
requests++
q := r.URL.Query()
if got := q["fields"]; len(got) != 4 {
t.Errorf("expected 4 fields params, got %v", got)
}
if q.Get("limit") != "2" {
t.Errorf("expected limit=2, got %q", q.Get("limit"))
}
if q.Get("marker") == "id-1" && !failedOnce {
failedOnce = true
http.Error(w, "busy", http.StatusServiceUnavailable)
return
}
start := 0
if m := q.Get("marker"); m != "" {
fmt.Sscanf(m, "id-%d", &start)
start++
}
type fip struct {
ID string `json:"id"`
Addr string `json:"floating_ip_address"`
PortID *string `json:"port_id"`
TenantID string `json:"tenant_id"`
}
var items []fip
for i := start; i < total && len(items) < 2; i++ {
f := fip{ID: fmt.Sprintf("id-%d", i), Addr: fmt.Sprintf("203.0.113.%d", i+1), TenantID: "p"}
if i == 1 {
p := "port-1"
f.PortID = &p
}
items = append(items, f)
}
w.Header().Set("Content-Type", "application/json")
_ = json.NewEncoder(w).Encode(map[string]any{"floatingips": items})
}))
defer srv.Close()
c := &Client{
networking: &gophercloud.ServiceClient{
ProviderClient: &gophercloud.ProviderClient{HTTPClient: *srv.Client()},
Endpoint: srv.URL + "/",
ResourceBase: srv.URL + "/v2.0/",
},
retry: pageRetry{Retries: 3, Sleep: func(context.Context, time.Duration) error { return nil }},
}
var all []FloatingIP
pages, err := c.ListFreeFloatingIPs(context.Background(), 2, func(p []FloatingIP) error {
all = append(all, p...)
return nil
})
if err != nil {
t.Fatalf("list: %v", err)
}
if pages != 3 || len(all) != total {
t.Fatalf("expected 3 pages / 5 fips, got %d / %d", pages, len(all))
}
if all[1].PortID != "port-1" || all[0].PortID != "" || all[4].Address != "203.0.113.5" {
t.Fatalf("unexpected mapping: %+v", all)
}
if requests != 4 { // 3 pages + 1 retried 503
t.Fatalf("expected 4 requests, got %d", requests)
}
}