package nodecli import ( "bytes" "context" "errors" "io" "net/http" "net/http/httptest" "os" "path/filepath" "strings" "testing" "evobgp/internal/bundle" ) type countingBody struct { io.Reader read int } func (b *countingBody) Read(p []byte) (int, error) { n, e := b.Reader.Read(p) b.read += n return n, e } func (b *countingBody) Close() error { return nil } func TestHTTPBundleBoundKnownAndChunked(t *testing.T) { for _, length := range []int64{-1, 2048} { body := &countingBody{Reader: bytes.NewReader(bytes.Repeat([]byte{'x'}, 2048))} _, err := readHTTPBytes(&http.Response{Body: body, ContentLength: length}, 1024) if !errors.Is(err, bundle.ErrLimit) { t.Fatalf("length=%d limit=%v", length, err) } if body.read > 1025 || (length > 1024 && body.read != 0) { t.Fatalf("unbounded read %d for length %d", body.read, length) } } } func TestLocalBundleSizeBound(t *testing.T) { path := filepath.Join(t.TempDir(), "bundle.tar.gz") if err := os.WriteFile(path, bytes.Repeat([]byte{'x'}, 2048), 0o600); err != nil { t.Fatal(err) } if _, err := readBundleFile(path, bundle.Limits{MaxCompressedBytes: 1024}); !errors.Is(err, bundle.ErrLimit) { t.Fatalf("local input cap: %v", err) } } func TestBundleHTTPMetadataAndDiagnosticsBound(t *testing.T) { server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { switch { case strings.Contains(r.URL.Path, "/revisions/latest"): _, _ = io.WriteString(w, strings.Repeat(" ", 65<<10)) default: w.WriteHeader(http.StatusBadRequest) _, _ = io.WriteString(w, strings.Repeat("x", 64<<10)) } })) defer server.Close() if _, err := fetchLatestRevision(server.URL, "key", "speaker"); !errors.Is(err, bundle.ErrLimit) { t.Fatalf("metadata unbounded: %v", err) } if _, err := fetchBundle(server.URL, "key", "speaker", "revision"); err == nil || len(err.Error()) > 5<<10 { t.Fatalf("diagnostic unbounded: %v", err) } } func TestSyncFetchRespectsCallerCancellation(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) cancel() if _, err := fetchBundleContext(ctx, "http://127.0.0.1:1", "key", "speaker", "revision", bundle.Limits{}); !errors.Is(err, context.Canceled) { t.Fatalf("download ignored cancel: %v", err) } if _, err := fetchLatestRevisionContext(ctx, "http://127.0.0.1:1", "key", "speaker"); !errors.Is(err, context.Canceled) { t.Fatalf("metadata ignored cancel: %v", err) } }