You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

61 lines
1.7 KiB

package operation
import (
"bytes"
"context"
"io"
"net/http"
"net/http/httptest"
"testing"
"time"
)
// Test that Upload respects request context timeout and does not hang indefinitely
func TestUploadTimesOutOnStalledConnectionViaContext(t *testing.T) {
// Create a test server that stalls and never writes a response
ts := httptest.NewUnstartedServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
// Do not read the body and do not write a response; just stall
select {
case <-time.After(10 * time.Second):
case <-r.Context().Done():
// Proactively close the underlying connection to avoid server Close delay
if hj, ok := w.(http.Hijacker); ok {
if conn, _, err := hj.Hijack(); err == nil {
_ = conn.Close()
}
}
}
}))
// Make the server's own timeouts aggressive so Close does not block long
ts.Config.ReadTimeout = 200 * time.Millisecond
ts.Config.WriteTimeout = 200 * time.Millisecond
ts.Config.IdleTimeout = 200 * time.Millisecond
ts.Start()
defer ts.Close()
u, err := NewUploader()
if err != nil {
t.Fatalf("failed to create uploader: %v", err)
}
// Short timeout to make the test fast
ctx, cancel := context.WithTimeout(context.Background(), 200*time.Millisecond)
defer cancel()
data := bytes.Repeat([]byte("a"), 1024)
// Call the lower-level upload to avoid internal retries and keep test fast
_, err = u.upload_content(ctx, func(w io.Writer) error {
_, writeErr := w.Write(data)
return writeErr
}, len(data), &UploadOption{
UploadUrl: ts.URL + "/upload",
Filename: "test.bin",
MimeType: "application/octet-stream",
})
if err == nil {
t.Fatalf("expected timeout error, got nil")
}
}